diff --git a/.env.example.complete b/.env.example.complete
index ebebaf9e3..6c773f601 100644
--- a/.env.example.complete
+++ b/.env.example.complete
@@ -395,6 +395,19 @@ ALLOWED_IFRAME_HOSTS=null
# Current host and source for the "DRAWIO" setting will be auto-appended to the sources configured.
ALLOWED_IFRAME_SOURCES="https://*.draw.io https://*.youtube.com https://*.youtube-nocookie.com https://*.vimeo.com"
+# A list of sources/hostnames that can be loaded as CSS styles within BookStack.
+# Space separated if multiple. BookStack host domain is auto-inferred.
+# Defaults to a permissive set if not provided.
+# Example: ALLOWED_STYLE_SOURCES="https://fonts.googleapis.com"
+ALLOWED_STYLE_SOURCES=null
+
+# A list of sources/hostnames that can be loaded as image content within BookStack.
+# Space separated if multiple. BookStack host domain is auto-inferred, in addition to
+# data and blob images, due to their use for various functionality.
+# Defaults to a permissive set if not provided.
+# Example: ALLOWED_IMAGE_SOURCES="https://images.example.com"
+ALLOWED_IMAGE_SOURCES=null
+
# A list of the sources/hostnames that can be reached by application SSR calls.
# This is used wherever users can provide URLs/hosts in-platform, like for webhooks.
# Host-specific functionality (usually controlled via other options) like auth
diff --git a/.forgejo/CODE_OF_CONDUCT.md b/.forgejo/CODE_OF_CONDUCT.md
new file mode 100644
index 000000000..7a0265672
--- /dev/null
+++ b/.forgejo/CODE_OF_CONDUCT.md
@@ -0,0 +1,2 @@
+Please find our community rules on our website here:
+https://www.bookstackapp.com/about/community-rules/
\ No newline at end of file
diff --git a/.forgejo/FUNDING.yml b/.forgejo/FUNDING.yml
new file mode 100644
index 000000000..5c50c3f69
--- /dev/null
+++ b/.forgejo/FUNDING.yml
@@ -0,0 +1,4 @@
+# These are supported funding model platforms
+
+github: [ssddanbrown]
+ko_fi: ssddanbrown
diff --git a/.github/ISSUE_TEMPLATE/api_request.yml b/.forgejo/ISSUE_TEMPLATE/api_request.yml
similarity index 94%
rename from .github/ISSUE_TEMPLATE/api_request.yml
rename to .forgejo/ISSUE_TEMPLATE/api_request.yml
index def952c52..c68d26258 100644
--- a/.github/ISSUE_TEMPLATE/api_request.yml
+++ b/.forgejo/ISSUE_TEMPLATE/api_request.yml
@@ -1,6 +1,6 @@
name: New API Endpoint or API Ability
description: Request a new endpoint or API feature be added
-labels: [":nut_and_bolt: API Request"]
+labels: ["Type/API Request"]
body:
- type: textarea
id: feature
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.forgejo/ISSUE_TEMPLATE/bug_report.yml
similarity index 98%
rename from .github/ISSUE_TEMPLATE/bug_report.yml
rename to .forgejo/ISSUE_TEMPLATE/bug_report.yml
index d301826c9..9e4173cc7 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.yml
+++ b/.forgejo/ISSUE_TEMPLATE/bug_report.yml
@@ -1,6 +1,6 @@
name: Bug Report
description: Create a report to help us fix bugs & issues in existing supported functionality
-labels: [":bug: Bug"]
+labels: ["Type/Bug Report"]
body:
- type: markdown
attributes:
diff --git a/.forgejo/ISSUE_TEMPLATE/config.yml b/.forgejo/ISSUE_TEMPLATE/config.yml
new file mode 100644
index 000000000..a72fb1ef4
--- /dev/null
+++ b/.forgejo/ISSUE_TEMPLATE/config.yml
@@ -0,0 +1,13 @@
+blank_issues_enabled: false
+contact_links:
+ - name: Community Forum Support
+ url: https://community.bookstackapp.com
+ about: Get support by talking with the BookStack team & community.
+
+ - name: Debugging & Common Issues
+ url: https://www.bookstackapp.com/docs/admin/debugging/
+ about: Find details on how to debug issues and view common issues with their resolutions.
+
+ - name: Official Support Plans
+ url: https://www.bookstackapp.com/support/
+ about: View our official support plans that offer assured support for business.
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.forgejo/ISSUE_TEMPLATE/feature_request.yml
similarity index 72%
rename from .github/ISSUE_TEMPLATE/feature_request.yml
rename to .forgejo/ISSUE_TEMPLATE/feature_request.yml
index 0ebb8e72f..0d799d0a7 100644
--- a/.github/ISSUE_TEMPLATE/feature_request.yml
+++ b/.forgejo/ISSUE_TEMPLATE/feature_request.yml
@@ -1,6 +1,6 @@
name: Feature Request
description: Request a new feature or idea to be added to BookStack
-labels: [":hammer: Feature Request"]
+labels: ["Type/Feature Request"]
body:
- type: textarea
id: description
@@ -33,7 +33,7 @@ body:
attributes:
label: Have you searched for an existing open/closed issue?
description: |
- To help us keep these issues under control, please ensure you have first [searched our issue list](https://github.com/BookStackApp/BookStack/issues?q=is%3Aissue) for any existing issues that cover the fundamental benefit/goal of your request.
+ To help us keep these issues under control, please ensure you have first [searched our issue list](https://codeberg.org/bookstack/bookstack/issues) for any existing issues that cover the fundamental benefit/goal of your request.
options:
- label: I have searched for existing issues and none cover my fundamental request
required: true
@@ -56,3 +56,13 @@ body:
description: Add any other context or screenshots about the feature request here.
validations:
required: false
+ - type: checkboxes
+ id: ai-thoughts
+ attributes:
+ label: Have you used generative AI/LLMs to create any thoughts in this request?
+ description: |
+ We ask that no machine generated thoughts or ideas are provided, to avoid us spending time considering the ideas
+ of a machine instead of a human. Further guidance on this can be found [in the BookStack community rules](https://www.bookstackapp.com/about/community-rules/#use-of-llmsai).
+ options:
+ - label: This request only contains the thoughts & ideas of a human
+ required: true
diff --git a/.github/ISSUE_TEMPLATE/language_request.yml b/.forgejo/ISSUE_TEMPLATE/language_request.yml
similarity index 96%
rename from .github/ISSUE_TEMPLATE/language_request.yml
rename to .forgejo/ISSUE_TEMPLATE/language_request.yml
index fad9ef1e8..b86fb08e8 100644
--- a/.github/ISSUE_TEMPLATE/language_request.yml
+++ b/.forgejo/ISSUE_TEMPLATE/language_request.yml
@@ -1,6 +1,6 @@
name: Language Request
description: Request a new language to be added to Crowdin for you to translate
-labels: [":earth_africa: Translations"]
+labels: ["Focus: Translations"]
assignees:
- ssddanbrown
body:
diff --git a/.github/ISSUE_TEMPLATE/support_request.yml b/.forgejo/ISSUE_TEMPLATE/support_request.yml
similarity index 89%
rename from .github/ISSUE_TEMPLATE/support_request.yml
rename to .forgejo/ISSUE_TEMPLATE/support_request.yml
index ae808a0b6..fde4aad71 100644
--- a/.github/ISSUE_TEMPLATE/support_request.yml
+++ b/.forgejo/ISSUE_TEMPLATE/support_request.yml
@@ -1,6 +1,6 @@
name: Support Request
description: Request support for a specific problem you have not been able to solve yourself
-labels: [":dog2: Support"]
+labels: ["Type/Support"]
body:
- type: checkboxes
id: useddocs
@@ -15,11 +15,11 @@ body:
- type: checkboxes
id: searchissue
attributes:
- label: Searched GitHub Issues
+ label: Searched Existing Issues
description: |
- I have searched for the issue and potential resolutions within the [project's GitHub issue list](https://github.com/BookStackApp/BookStack/issues)
+ I have searched for the issue and potential resolutions within the [project's issue list](https://codeberg.org/bookstack/bookstack/issues)
options:
- - label: I have searched GitHub for the issue.
+ - label: I have searched for the issue.
required: true
- type: textarea
id: scenario
diff --git a/.github/ISSUE_TEMPLATE/z_blank_request.yml b/.forgejo/ISSUE_TEMPLATE/z_blank_request.yml
similarity index 100%
rename from .github/ISSUE_TEMPLATE/z_blank_request.yml
rename to .forgejo/ISSUE_TEMPLATE/z_blank_request.yml
diff --git a/.github/SECURITY.md b/.forgejo/SECURITY.md
similarity index 60%
rename from .github/SECURITY.md
rename to .forgejo/SECURITY.md
index 12e5fe04c..5c044c946 100644
--- a/.github/SECURITY.md
+++ b/.forgejo/SECURITY.md
@@ -2,7 +2,7 @@
## Supported Versions
-Only the [latest version](https://github.com/BookStackApp/BookStack/releases) of BookStack is supported.
+Only the [latest version](https://codeberg.org/bookstack/bookstack/releases) of BookStack is supported.
We generally don't support older versions of BookStack due to maintenance effort and
since we aim to provide a fairly stable upgrade path for new versions.
@@ -12,16 +12,14 @@ If you'd like to be notified of new potential security concerns you can [sign-up
## Reporting a Vulnerability
-If you've found an issue that likely has no impact to existing users (For example, in a development-only branch)
-feel free to raise it via a standard GitHub bug report issue.
+If you've found an issue that likely has no impact to existing users (For example, an issue only in the development branch)
+feel free to raise it via a standard Codeberg bug report issue.
If the issue could have a security impact to BookStack instances,
-please directly contact the lead maintainer [@ssddanbrown](https://github.com/ssddanbrown).
-You will need to log in to be able to see the email address on the [GitHub profile page](https://github.com/ssddanbrown).
-Alternatively you can send a DM via Mastodon to [@danb@fosstodon.org](https://fosstodon.org/@danb).
+please directly contact the lead maintainer via email Dan Brown using the [details found here](https://www.bookstackapp.com/links/contact/).
Please be patient while the vulnerability is being reviewed. Deploying the fix to address the vulnerability
can often take a little time due to the amount of preparation required, to ensure the vulnerability has
been covered, and to create the content required to adequately notify the user-base.
-Thank you for keeping BookStack instances safe!
+Thank you for keeping BookStack instances safe!
\ No newline at end of file
diff --git a/.forgejo/pull_request_template.md b/.forgejo/pull_request_template.md
new file mode 100644
index 000000000..70f105874
--- /dev/null
+++ b/.forgejo/pull_request_template.md
@@ -0,0 +1,11 @@
+## Details
+
+
+
+
+## Checklist
+
+
+
+- [ ] I have read the [BookStack community rules](https://www.bookstackapp.com/about/community-rules/).
+- [ ] This PR does not feature significant use of LLM/AI generation as per the community rules above.
diff --git a/.github/workflows/analyse-php.yml b/.forgejo/workflows/analyse-php.yml
similarity index 64%
rename from .github/workflows/analyse-php.yml
rename to .forgejo/workflows/analyse-php.yml
index 647835aeb..8975d6e52 100644
--- a/.github/workflows/analyse-php.yml
+++ b/.forgejo/workflows/analyse-php.yml
@@ -1,6 +1,7 @@
name: analyse-php
on:
+ workflow_dispatch:
push:
paths:
- '**.php'
@@ -11,14 +12,16 @@ on:
jobs:
build:
if: ${{ github.ref != 'refs/heads/l10n_development' }}
- runs-on: ubuntu-24.04
+ runs-on: docker
+ container:
+ image: docker.io/library/node:24-trixie
steps:
- - uses: actions/checkout@v4
+ - uses: https://code.forgejo.org/actions/checkout@v6
- name: Setup PHP
- uses: shivammathur/setup-php@v2
+ uses: https://github.com/shivammathur/setup-php@v2
with:
- php-version: 8.3
+ php-version: 8.5
extensions: gd, mbstring, json, curl, xml, mysql, ldap
- name: Get Composer Cache Directory
@@ -27,14 +30,16 @@ jobs:
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
- name: Cache composer packages
- uses: actions/cache@v4
+ uses: https://code.forgejo.org/actions/cache@v5
with:
path: ${{ steps.composer-cache.outputs.dir }}
- key: ${{ runner.os }}-composer-8.3
+ key: ${{ runner.os }}-composer-8.5
restore-keys: ${{ runner.os }}-composer-
- name: Install composer dependencies
run: composer install --prefer-dist --no-interaction --ansi
+ env:
+ COMPOSER_AUTH: '{"github-oauth": {"github.com": "${{ secrets.GH_TOKEN }}"}}'
- name: Run static analysis check
run: composer check-static
diff --git a/.github/workflows/lint-js.yml b/.forgejo/workflows/lint-js.yml
similarity index 67%
rename from .github/workflows/lint-js.yml
rename to .forgejo/workflows/lint-js.yml
index 9aceea2a2..5cacec67a 100644
--- a/.github/workflows/lint-js.yml
+++ b/.forgejo/workflows/lint-js.yml
@@ -1,6 +1,7 @@
name: lint-js
on:
+ workflow_dispatch:
push:
paths:
- '**.js'
@@ -13,9 +14,11 @@ on:
jobs:
build:
if: ${{ github.ref != 'refs/heads/l10n_development' }}
- runs-on: ubuntu-24.04
+ runs-on: docker
+ container:
+ image: docker.io/library/node:24-trixie
steps:
- - uses: actions/checkout@v4
+ - uses: https://code.forgejo.org/actions/checkout@v6
- name: Install NPM deps
run: npm ci
diff --git a/.github/workflows/lint-php.yml b/.forgejo/workflows/lint-php.yml
similarity index 55%
rename from .github/workflows/lint-php.yml
rename to .forgejo/workflows/lint-php.yml
index cb9dedcb2..b409c62e2 100644
--- a/.github/workflows/lint-php.yml
+++ b/.forgejo/workflows/lint-php.yml
@@ -1,6 +1,7 @@
name: lint-php
on:
+ workflow_dispatch:
push:
paths:
- '**.php'
@@ -11,14 +12,16 @@ on:
jobs:
build:
if: ${{ github.ref != 'refs/heads/l10n_development' }}
- runs-on: ubuntu-24.04
+ runs-on: docker
+ container:
+ image: docker.io/library/node:24-trixie
steps:
- - uses: actions/checkout@v4
+ - uses: https://code.forgejo.org/actions/checkout@v6
- name: Setup PHP
- uses: shivammathur/setup-php@v2
+ uses: https://github.com/shivammathur/setup-php@v2
with:
- php-version: 8.3
+ php-version: 8.5
tools: phpcs
- name: Run formatting check
diff --git a/.forgejo/workflows/sync-translations.yml b/.forgejo/workflows/sync-translations.yml
new file mode 100644
index 000000000..a0c09ba8f
--- /dev/null
+++ b/.forgejo/workflows/sync-translations.yml
@@ -0,0 +1,33 @@
+name: Crowdin Action
+
+on:
+ push:
+ branches: [ development ]
+ paths:
+ - 'lang/**.php'
+ schedule:
+ - cron: '30 4 * * *'
+ workflow_dispatch:
+
+jobs:
+ synchronize-with-crowdin:
+ runs-on: docker
+ container:
+ image: docker.io/library/node:24-trixie
+
+ steps:
+ - name: Checkout
+ uses: https://code.forgejo.org/actions/checkout@v6
+
+ - name: crowdin action
+ uses: https://github.com/crowdin/github-action@v2
+ with:
+ upload_sources: true
+ upload_translations: false
+ download_translations: true
+ localization_branch_name: l10n_development
+ create_pull_request: false
+ github_base_url: codeberg.org
+ env:
+ CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }}
+ CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
\ No newline at end of file
diff --git a/.github/workflows/test-js.yml b/.forgejo/workflows/test-js.yml
similarity index 68%
rename from .github/workflows/test-js.yml
rename to .forgejo/workflows/test-js.yml
index 13f9a8a98..d3e8467fe 100644
--- a/.github/workflows/test-js.yml
+++ b/.forgejo/workflows/test-js.yml
@@ -1,6 +1,7 @@
name: test-js
on:
+ workflow_dispatch:
push:
paths:
- '**.js'
@@ -15,9 +16,11 @@ on:
jobs:
build:
if: ${{ github.ref != 'refs/heads/l10n_development' }}
- runs-on: ubuntu-24.04
+ runs-on: docker
+ container:
+ image: docker.io/library/node:24-trixie
steps:
- - uses: actions/checkout@v4
+ - uses: https://code.forgejo.org/actions/checkout@v6
- name: Install NPM deps
run: npm ci
@@ -26,4 +29,4 @@ jobs:
run: npm run ts:lint
- name: Run JavaScript tests
- run: npm run test
\ No newline at end of file
+ run: npm run test:ci
\ No newline at end of file
diff --git a/.github/workflows/test-migrations.yml b/.forgejo/workflows/test-migrations.yml
similarity index 59%
rename from .github/workflows/test-migrations.yml
rename to .forgejo/workflows/test-migrations.yml
index 80075c3f7..e969d3e47 100644
--- a/.github/workflows/test-migrations.yml
+++ b/.forgejo/workflows/test-migrations.yml
@@ -1,6 +1,7 @@
name: test-migrations
on:
+ workflow_dispatch:
push:
paths:
- '**.php'
@@ -13,15 +14,25 @@ on:
jobs:
build:
if: ${{ github.ref != 'refs/heads/l10n_development' }}
- runs-on: ubuntu-24.04
+ runs-on: docker
+ container:
+ image: docker.io/library/node:24-trixie
strategy:
matrix:
php: ['8.2', '8.3', '8.4', '8.5']
+ services:
+ mysql:
+ image: docker.io/library/mariadb:12.2.2-noble
+ env:
+ MARIADB_USER: bookstack-test
+ MARIADB_PASSWORD: bookstack-test
+ MARIADB_DATABASE: bookstack-test
+ MARIADB_ROOT_PASSWORD: password
steps:
- - uses: actions/checkout@v4
+ - uses: https://code.forgejo.org/actions/checkout@v6
- name: Setup PHP
- uses: shivammathur/setup-php@v2
+ uses: https://github.com/shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
extensions: gd, mbstring, json, curl, xml, mysql, ldap
@@ -32,34 +43,31 @@ jobs:
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
- name: Cache composer packages
- uses: actions/cache@v4
+ uses: https://code.forgejo.org/actions/cache@v5
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ matrix.php }}
restore-keys: ${{ runner.os }}-composer-
- - name: Start MySQL
- run: |
- sudo systemctl start mysql
-
- - name: Create database & user
- run: |
- mysql -uroot -proot -e 'CREATE DATABASE IF NOT EXISTS `bookstack-test`;'
- mysql -uroot -proot -e "CREATE USER 'bookstack-test'@'localhost' IDENTIFIED WITH mysql_native_password BY 'bookstack-test';"
- mysql -uroot -proot -e "GRANT ALL ON \`bookstack-test\`.* TO 'bookstack-test'@'localhost';"
- mysql -uroot -proot -e 'FLUSH PRIVILEGES;'
-
- name: Install composer dependencies
run: composer install --prefer-dist --no-interaction --ansi
+ env:
+ COMPOSER_AUTH: '{"github-oauth": {"github.com": "${{ secrets.GH_TOKEN }}"}}'
- name: Start migration test
+ env:
+ TEST_DATABASE_URL: 'mysql://bookstack-test:bookstack-test@mysql/bookstack-test'
run: |
php${{ matrix.php }} artisan migrate --force -n --database=mysql_testing
- name: Start migration:rollback test
+ env:
+ TEST_DATABASE_URL: 'mysql://bookstack-test:bookstack-test@mysql/bookstack-test'
run: |
php${{ matrix.php }} artisan migrate:rollback --force -n --database=mysql_testing
- name: Start migration rerun test
+ env:
+ TEST_DATABASE_URL: 'mysql://bookstack-test:bookstack-test@mysql/bookstack-test'
run: |
php${{ matrix.php }} artisan migrate --force -n --database=mysql_testing
diff --git a/.github/workflows/test-php.yml b/.forgejo/workflows/test-php.yml
similarity index 55%
rename from .github/workflows/test-php.yml
rename to .forgejo/workflows/test-php.yml
index 5f4c16caf..06a6de276 100644
--- a/.github/workflows/test-php.yml
+++ b/.forgejo/workflows/test-php.yml
@@ -1,6 +1,7 @@
name: test-php
on:
+ workflow_dispatch:
push:
paths:
- '**.php'
@@ -13,18 +14,38 @@ on:
jobs:
build:
if: ${{ github.ref != 'refs/heads/l10n_development' }}
- runs-on: ubuntu-24.04
+ runs-on: docker
+ container:
+ image: docker.io/setupphp/node:noble
strategy:
matrix:
php: ['8.2', '8.3', '8.4', '8.5']
+ env:
+ phpextensions: gd, mbstring, json, curl, xml, mysql, ldap, gmp
+ phpextensioncachekey: cache-v1
steps:
- - uses: actions/checkout@v4
+ - uses: https://code.forgejo.org/actions/checkout@v6
- - name: Setup PHP
- uses: shivammathur/setup-php@v2
+ - name: Setup cache environment
+ id: extcache
+ uses: https://github.com/shivammathur/cache-extensions@v1
with:
php-version: ${{ matrix.php }}
- extensions: gd, mbstring, json, curl, xml, mysql, ldap, gmp
+ extensions: ${{ env.phpextensions }}
+ key: ${{ env.phpextensioncachekey }}
+
+ - name: Cache extensions
+ uses: https://code.forgejo.org/actions/cache@v5
+ with:
+ path: ${{ steps.extcache.outputs.dir }}
+ key: ${{ steps.extcache.outputs.key }}
+ restore-keys: ${{ steps.extcache.outputs.key }}
+
+ - name: Setup PHP
+ uses: https://github.com/shivammathur/setup-php@v2
+ with:
+ php-version: ${{ matrix.php }}
+ extensions: ${{ env.phpextensions }}
- name: Get Composer Cache Directory
id: composer-cache
@@ -32,30 +53,36 @@ jobs:
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
- name: Cache composer packages
- uses: actions/cache@v4
+ uses: https://code.forgejo.org/actions/cache@v5
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ matrix.php }}
restore-keys: ${{ runner.os }}-composer-
- - name: Start Database
+ - name: Install composer dependencies
+ run: composer install --prefer-dist --no-interaction --ansi
+ env:
+ COMPOSER_AUTH: '{"github-oauth": {"github.com": "${{ secrets.GH_TOKEN }}"}}'
+
+ - name: Start MySQL
run: |
sudo systemctl start mysql
- - name: Setup Database
+ - name: Create database & user
run: |
mysql -uroot -proot -e 'CREATE DATABASE IF NOT EXISTS `bookstack-test`;'
mysql -uroot -proot -e "CREATE USER 'bookstack-test'@'localhost' IDENTIFIED WITH mysql_native_password BY 'bookstack-test';"
mysql -uroot -proot -e "GRANT ALL ON \`bookstack-test\`.* TO 'bookstack-test'@'localhost';"
mysql -uroot -proot -e 'FLUSH PRIVILEGES;'
- - name: Install composer dependencies
- run: composer install --prefer-dist --no-interaction --ansi
-
- name: Migrate and seed the database
+ env:
+ TEST_DATABASE_URL: 'mysql://bookstack-test:bookstack-test@localhost/bookstack-test'
run: |
php${{ matrix.php }} artisan migrate --force -n --database=mysql_testing
php${{ matrix.php }} artisan db:seed --force -n --class=DummyContentSeeder --database=mysql_testing
- name: Run PHP tests
+ env:
+ TEST_DATABASE_URL: 'mysql://bookstack-test:bookstack-test@localhost/bookstack-test'
run: php${{ matrix.php }} ./vendor/bin/phpunit
diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md
index 2c6317af6..7a0265672 100644
--- a/.github/CODE_OF_CONDUCT.md
+++ b/.github/CODE_OF_CONDUCT.md
@@ -1,84 +1,2 @@
-# Contributor Covenant Code of Conduct
-
-## Our Pledge
-
-In the interest of fostering an open and welcoming environment, we as
-contributors and maintainers pledge to making participation in our project and
-our community a harassment-free experience for everyone, regardless of age, body
-size, disability, ethnicity, gender identity and expression, level of experience,
-education, socio-economic status, nationality, personal appearance, race,
-religion, or sexual identity and orientation.
-
-## Our Standards
-
-Examples of behavior that contributes to creating a positive environment
-include:
-
-* Being respectful of differing viewpoints and experiences
-* Gracefully accepting constructive criticism
-* Focusing on what is best for the community
-* Showing empathy towards other community members
-
-Examples of unacceptable behavior by participants include:
-
-* The use of sexualized language or imagery and unwelcome sexual attention or
- advances
-* Trolling, insulting/derogatory comments, and personal or political attacks
-* Public or private harassment
-* Publishing others' private information, such as a physical or electronic
- address, without explicit permission
-* Other conduct which could reasonably be considered inappropriate in a
- professional setting
-
-### Project Maintainer Standards
-
-Project maintainers should generally follow these additional standards:
-
-* Avoid using a negative or harsh tone in communication, Even if the other party
-is being negative themselves.
-* When providing criticism, try to make it constructive to lead the other person
-down the correct path.
-* Keep the [project definition](https://github.com/BookStackApp/BookStack#project-definition)
-in mind when deciding what's in scope of the Project.
-
-## Our Responsibilities
-
-Project maintainers are responsible for clarifying the standards of acceptable
-behavior and are expected to take appropriate and fair corrective action in
-response to any instances of unacceptable behavior. In addition, Project
-maintainers are responsible for following the standards themselves.
-
-Project maintainers have the right and responsibility to remove, edit, or
-reject comments, commits, code, wiki edits, issues, and other contributions
-that are not aligned to this Code of Conduct, or to ban temporarily or
-permanently any contributor for other behaviors that they deem inappropriate,
-threatening, offensive, or harmful.
-
-## Scope
-
-This Code of Conduct applies both within project spaces and in public spaces
-when an individual is representing the project or its community. Examples of
-representing a project or community include using an official project e-mail
-address, posting via an official social media account, or acting as an appointed
-representative at an online or offline event. Representation of a project may be
-further defined and clarified by project maintainers.
-
-## Enforcement
-
-Instances of abusive, harassing, or otherwise unacceptable behavior may be
-reported by contacting the project team at the email address shown on [the profile here](https://github.com/ssddanbrown). All
-complaints will be reviewed and investigated and will result in a response that
-is deemed necessary and appropriate to the circumstances. The project team is
-obligated to maintain confidentiality with regard to the reporter of an incident.
-Further details of specific enforcement policies may be posted separately.
-
-Project maintainers who do not follow or enforce the Code of Conduct in good
-faith may face temporary or permanent repercussions as determined by other
-members of the project's leadership.
-
-## Attribution
-
-This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
-available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
-
-[homepage]: https://www.contributor-covenant.org
+Please find our community rules on our website here:
+https://www.bookstackapp.com/about/community-rules/
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
index 019667388..0cd657d7a 100644
--- a/.github/ISSUE_TEMPLATE/config.yml
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -1,8 +1,8 @@
blank_issues_enabled: false
contact_links:
- - name: Discord Chat Support
- url: https://discord.gg/ztkBqR2
- about: Realtime support & chat with the BookStack community and the team.
+ - name: Open Issues Here Instead
+ url: https://codeberg.org/bookstack/bookstack/issues
+ about: This project has migrated to Codeberg, please open issues there instead.
- name: Debugging & Common Issues
url: https://www.bookstackapp.com/docs/admin/debugging/
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
new file mode 100644
index 000000000..c185f3280
--- /dev/null
+++ b/.github/pull_request_template.md
@@ -0,0 +1,10 @@
+**Warning:**
+
+This project has migrated to Codeberg:
+https://codeberg.org/bookstack/bookstack
+
+Please open pull requests here instead.
+
+ANY PULL REQUESTS OPENED HERE WILL BE CLOSED WITHOUT COMMENT OR MERGE.
+
+---
\ No newline at end of file
diff --git a/.github/translators.txt b/.github/translators.txt
index 037887bcc..cae26547b 100644
--- a/.github/translators.txt
+++ b/.github/translators.txt
@@ -533,7 +533,14 @@ JanDziaslo :: Polish
Charllys Fernandes (CharllysFernandes) :: Portuguese, Brazilian
Ilgiz Zigangirov (inov8) :: Russian
Max Israelsson (Blezie) :: Swedish
-Skiddybison5924 (chris-devel0per) :: German
+Skiddybison5924 (chris-devel0per) :: German Informal; German
Veyilla Nightwhisper (Veyilla) :: German
João Barbosa (hypeedd) :: Portuguese
Abcdefg Hijklmn (collatek) :: Korean
+Suthep Yonphimai (tomztt) :: Thai
+MrClock (MrClock8163) :: Hungarian
+Elena0875 :: Russian
+FelixFrizzy :: German
+Pedro de Mattia (pdmtt) :: Portuguese, Brazilian
+lonestan :: Russian
+Paul Kernstock (kernstock) :: German
diff --git a/.gitignore b/.gitignore
index e0cc32295..7683324c3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,7 @@
/node_modules
/.vscode
/composer
+/composer.phar
/coverage
Homestead.yaml
.env
diff --git a/app/Access/Controllers/ForgotPasswordController.php b/app/Access/Controllers/ForgotPasswordController.php
index 36dd97755..e8127e617 100644
--- a/app/Access/Controllers/ForgotPasswordController.php
+++ b/app/Access/Controllers/ForgotPasswordController.php
@@ -45,11 +45,11 @@ class ForgotPasswordController extends Controller
);
if ($response === Password::RESET_LINK_SENT) {
- $this->logActivity(ActivityType::AUTH_PASSWORD_RESET, $request->get('email'));
+ $this->logActivity(ActivityType::AUTH_PASSWORD_RESET, $request->input('email'));
}
if (in_array($response, [Password::RESET_LINK_SENT, Password::INVALID_USER, Password::RESET_THROTTLED])) {
- $message = trans('auth.reset_password_sent', ['email' => $request->get('email')]);
+ $message = trans('auth.reset_password_sent', ['email' => $request->input('email')]);
$this->showSuccessNotification($message);
return redirect('/password/email')->with('status', trans($response));
diff --git a/app/Access/Controllers/LoginController.php b/app/Access/Controllers/LoginController.php
index ce872ba88..4694f22e4 100644
--- a/app/Access/Controllers/LoginController.php
+++ b/app/Access/Controllers/LoginController.php
@@ -32,12 +32,12 @@ class LoginController extends Controller
{
$socialDrivers = $this->socialDriverManager->getActive();
$authMethod = config('auth.method');
- $preventInitiation = $request->get('prevent_auto_init') === 'true';
+ $preventInitiation = $request->input('prevent_auto_init') === 'true';
if ($request->has('email')) {
session()->flashInput([
- 'email' => $request->get('email'),
- 'password' => (config('app.env') === 'demo') ? $request->get('password', '') : '',
+ 'email' => $request->input('email'),
+ 'password' => (config('app.env') === 'demo') ? $request->input('password', '') : '',
]);
}
@@ -62,7 +62,7 @@ class LoginController extends Controller
public function login(Request $request)
{
$this->validateLogin($request);
- $username = $request->get($this->username());
+ $username = $request->input($this->username());
// Check login throttling attempts to see if they've gone over the limit
if ($this->hasTooManyLoginAttempts($request)) {
diff --git a/app/Access/Controllers/MfaBackupCodesController.php b/app/Access/Controllers/MfaBackupCodesController.php
index 6ab3e1d14..b81e79097 100644
--- a/app/Access/Controllers/MfaBackupCodesController.php
+++ b/app/Access/Controllers/MfaBackupCodesController.php
@@ -96,7 +96,7 @@ class MfaBackupCodesController extends Controller
],
]);
- $updatedCodes = $codeService->removeInputCodeFromSet($request->get('code'), $codes);
+ $updatedCodes = $codeService->removeInputCodeFromSet($request->input('code'), $codes);
MfaValue::upsertWithValue($user, MfaValue::METHOD_BACKUP_CODES, $updatedCodes);
$mfaSession->markVerifiedForUser($user);
diff --git a/app/Access/Controllers/MfaController.php b/app/Access/Controllers/MfaController.php
index c9100ef91..181cfc0b8 100644
--- a/app/Access/Controllers/MfaController.php
+++ b/app/Access/Controllers/MfaController.php
@@ -51,14 +51,14 @@ class MfaController extends Controller
*/
public function verify(Request $request)
{
- $desiredMethod = $request->get('method');
+ $desiredMethod = $request->input('method');
$userMethods = $this->currentOrLastAttemptedUser()
->mfaValues()
->get(['id', 'method'])
->groupBy('method');
// Basic search for the default option for a user.
- // (Prioritises totp over backup codes)
+ // (Prioritises TOTP over backup codes)
$method = $userMethods->has($desiredMethod) ? $desiredMethod : $userMethods->keys()->sort()->reverse()->first();
$otherMethods = $userMethods->keys()->filter(function ($userMethod) use ($method) {
return $method !== $userMethod;
diff --git a/app/Access/Controllers/ResetPasswordController.php b/app/Access/Controllers/ResetPasswordController.php
index 3af65d17f..e81c98b28 100644
--- a/app/Access/Controllers/ResetPasswordController.php
+++ b/app/Access/Controllers/ResetPasswordController.php
@@ -48,7 +48,7 @@ class ResetPasswordController extends Controller
// Here we will attempt to reset the user's password. If it is successful we
// will update the password on an actual user model and persist it to the
- // database. Otherwise we will parse the error and return the response.
+ // database. Otherwise, we will parse the error and return the response.
$credentials = $request->only('email', 'password', 'password_confirmation', 'token');
$response = Password::broker()->reset($credentials, function (User $user, string $password) {
$user->password = Hash::make($password);
@@ -63,7 +63,7 @@ class ResetPasswordController extends Controller
// redirect them back to where they came from with their error message.
return $response === Password::PASSWORD_RESET
? $this->sendResetResponse()
- : $this->sendResetFailedResponse($request, $response, $request->get('token'));
+ : $this->sendResetFailedResponse($request, $response, $request->input('token'));
}
/**
diff --git a/app/Access/Controllers/Saml2Controller.php b/app/Access/Controllers/Saml2Controller.php
index 6f802370e..39598b143 100644
--- a/app/Access/Controllers/Saml2Controller.php
+++ b/app/Access/Controllers/Saml2Controller.php
@@ -78,7 +78,7 @@ class Saml2Controller extends Controller
*/
public function startAcs(Request $request)
{
- $samlResponse = $request->get('SAMLResponse', null);
+ $samlResponse = $request->input('SAMLResponse', null);
if (empty($samlResponse)) {
$this->showErrorNotification(trans('errors.saml_fail_authed', ['system' => config('saml2.name')]));
@@ -100,7 +100,7 @@ class Saml2Controller extends Controller
*/
public function processAcs(Request $request)
{
- $acsId = $request->get('id', null);
+ $acsId = $request->input('id', null);
$cacheKey = 'saml2_acs:' . $acsId;
$samlResponse = null;
diff --git a/app/Access/Controllers/SocialController.php b/app/Access/Controllers/SocialController.php
index 07f57062d..5a090c7ca 100644
--- a/app/Access/Controllers/SocialController.php
+++ b/app/Access/Controllers/SocialController.php
@@ -67,7 +67,7 @@ class SocialController extends Controller
if ($request->has('error') && $request->has('error_description')) {
throw new SocialSignInException(trans('errors.social_login_bad_response', [
'socialAccount' => $socialDriver,
- 'error' => $request->get('error_description'),
+ 'error' => $request->input('error_description'),
]), '/login');
}
diff --git a/app/Access/Controllers/UserInviteController.php b/app/Access/Controllers/UserInviteController.php
index 9ee05b84f..091b68e55 100644
--- a/app/Access/Controllers/UserInviteController.php
+++ b/app/Access/Controllers/UserInviteController.php
@@ -67,7 +67,7 @@ class UserInviteController extends Controller
}
$user = $this->userRepo->getById($userId);
- $user->password = Hash::make($request->get('password'));
+ $user->password = Hash::make($request->input('password'));
$user->email_confirmed = true;
$user->save();
diff --git a/app/Access/EmailConfirmationService.php b/app/Access/EmailConfirmationService.php
index 1a5156d3e..e950c5504 100644
--- a/app/Access/EmailConfirmationService.php
+++ b/app/Access/EmailConfirmationService.php
@@ -5,6 +5,7 @@ namespace BookStack\Access;
use BookStack\Access\Notifications\ConfirmEmailNotification;
use BookStack\Exceptions\ConfirmationEmailException;
use BookStack\Users\Models\User;
+use Exception;
class EmailConfirmationService extends UserTokenService
{
@@ -16,6 +17,7 @@ class EmailConfirmationService extends UserTokenService
* Also removes any existing old ones.
*
* @throws ConfirmationEmailException
+ * @throws Exception
*/
public function sendConfirmation(User $user): void
{
diff --git a/app/Access/LoginService.php b/app/Access/LoginService.php
index f089f5ba9..769290c16 100644
--- a/app/Access/LoginService.php
+++ b/app/Access/LoginService.php
@@ -71,7 +71,7 @@ class LoginService
}
$lastLoginDetails = $this->getLastLoginAttemptDetails();
- $this->login($user, $lastLoginDetails['method'], $lastLoginDetails['remember'] ?? false);
+ $this->login($user, $lastLoginDetails['method'], $lastLoginDetails['remember']);
}
/**
diff --git a/app/Access/Mfa/MfaValue.php b/app/Access/Mfa/MfaValue.php
index dd3e04618..b0f08e826 100644
--- a/app/Access/Mfa/MfaValue.php
+++ b/app/Access/Mfa/MfaValue.php
@@ -48,17 +48,16 @@ class MfaValue extends Model
}
/**
- * Easily get the decrypted MFA value for the given user and method.
+ * Get the decrypted MFA value for the given user and method.
*/
public static function getValueForUser(User $user, string $method): ?string
{
- /** @var MfaValue $mfaVal */
$mfaVal = static::query()
->where('user_id', '=', $user->id)
->where('method', '=', $method)
->first();
- return $mfaVal ? $mfaVal->getValue() : null;
+ return $mfaVal?->getValue();
}
/**
diff --git a/app/Access/Oidc/OidcJwtSigningKey.php b/app/Access/Oidc/OidcJwtSigningKey.php
index 3dab3e442..3edba12b3 100644
--- a/app/Access/Oidc/OidcJwtSigningKey.php
+++ b/app/Access/Oidc/OidcJwtSigningKey.php
@@ -9,10 +9,7 @@ use phpseclib3\Math\BigInteger;
class OidcJwtSigningKey
{
- /**
- * @var PublicKey
- */
- protected $key;
+ protected PublicKey $key;
/**
* Can be created either from a JWK parameter array or local file path to load a certificate from.
@@ -20,15 +17,13 @@ class OidcJwtSigningKey
* 'file:///var/www/cert.pem'
* ['kty' => 'RSA', 'alg' => 'RS256', 'n' => 'abc123...'].
*
- * @param array|string $jwkOrKeyPath
- *
* @throws OidcInvalidKeyException
*/
- public function __construct($jwkOrKeyPath)
+ public function __construct(array|string $jwkOrKeyPath)
{
if (is_array($jwkOrKeyPath)) {
$this->loadFromJwkArray($jwkOrKeyPath);
- } elseif (is_string($jwkOrKeyPath) && strpos($jwkOrKeyPath, 'file://') === 0) {
+ } elseif (str_starts_with($jwkOrKeyPath, 'file://')) {
$this->loadFromPath($jwkOrKeyPath);
} else {
throw new OidcInvalidKeyException('Unexpected type of key value provided');
@@ -38,7 +33,7 @@ class OidcJwtSigningKey
/**
* @throws OidcInvalidKeyException
*/
- protected function loadFromPath(string $path)
+ protected function loadFromPath(string $path): void
{
try {
$key = PublicKeyLoader::load(
@@ -58,7 +53,7 @@ class OidcJwtSigningKey
/**
* @throws OidcInvalidKeyException
*/
- protected function loadFromJwkArray(array $jwk)
+ protected function loadFromJwkArray(array $jwk): void
{
// 'alg' is optional for a JWK, but we will still attempt to validate if
// it exists otherwise presume it will be compatible.
@@ -82,7 +77,7 @@ class OidcJwtSigningKey
throw new OidcInvalidKeyException('A "n" parameter on the provided key is expected');
}
- $n = strtr($jwk['n'] ?? '', '-_', '+/');
+ $n = strtr($jwk['n'], '-_', '+/');
try {
$key = PublicKeyLoader::load([
diff --git a/app/Access/Oidc/OidcJwtWithClaims.php b/app/Access/Oidc/OidcJwtWithClaims.php
index 06c04d81e..9d7eeead1 100644
--- a/app/Access/Oidc/OidcJwtWithClaims.php
+++ b/app/Access/Oidc/OidcJwtWithClaims.php
@@ -102,12 +102,12 @@ class OidcJwtWithClaims implements ProvidesClaims
protected function validateTokenStructure(): void
{
foreach (['header', 'payload'] as $prop) {
- if (empty($this->$prop) || !is_array($this->$prop)) {
+ if (empty($this->$prop)) {
throw new OidcInvalidTokenException("Could not parse out a valid {$prop} within the provided token");
}
}
- if (empty($this->signature) || !is_string($this->signature)) {
+ if (empty($this->signature)) {
throw new OidcInvalidTokenException('Could not parse out a valid signature within the provided token');
}
}
diff --git a/app/Access/Oidc/OidcUserDetails.php b/app/Access/Oidc/OidcUserDetails.php
index 7a422a58d..b1736f97d 100644
--- a/app/Access/Oidc/OidcUserDetails.php
+++ b/app/Access/Oidc/OidcUserDetails.php
@@ -39,7 +39,7 @@ class OidcUserDetails
): void {
$this->externalId = $claims->getClaim($idClaim) ?? $this->externalId;
$this->email = $claims->getClaim('email') ?? $this->email;
- $this->name = static::getUserDisplayName($displayNameClaims, $claims) ?? $this->name;
+ $this->name = static::getUserDisplayName($displayNameClaims, $claims) ?: $this->name;
$this->groups = static::getUserGroups($groupsClaim, $claims) ?? $this->groups;
$this->picture = static::getPicture($claims) ?: $this->picture;
}
diff --git a/app/Access/Saml2Service.php b/app/Access/Saml2Service.php
index 106a7a229..5572d2104 100644
--- a/app/Access/Saml2Service.php
+++ b/app/Access/Saml2Service.php
@@ -266,7 +266,7 @@ class Saml2Service
/**
* Extract the details of a user from a SAML response.
*
- * @return array{external_id: string, name: string, email: string, saml_id: string}
+ * @return array{external_id: string, name: string, email: string|null, saml_id: string}
*/
protected function getUserDetails(string $samlID, $samlAttributes): array
{
@@ -357,7 +357,7 @@ class Saml2Service
]);
}
- if ($userDetails['email'] === null) {
+ if (empty($userDetails['email'])) {
throw new SamlException(trans('errors.saml_no_email_address'));
}
diff --git a/app/Access/SocialAuthService.php b/app/Access/SocialAuthService.php
index c3c20587d..bdcfb45c8 100644
--- a/app/Access/SocialAuthService.php
+++ b/app/Access/SocialAuthService.php
@@ -117,14 +117,14 @@ class SocialAuthService
}
// When a user is logged in and the social account exists and is already linked to the current user.
- if ($isLoggedIn && $socialAccount !== null && $socialAccount->user->id === $currentUser->id) {
+ if ($isLoggedIn && $socialAccount->user->id === $currentUser->id) {
session()->flash('error', trans('errors.social_account_existing', ['socialAccount' => $titleCaseDriver]));
return redirect('/my-account/auth#social_accounts');
}
// When a user is logged in, A social account exists but the users do not match.
- if ($isLoggedIn && $socialAccount !== null && $socialAccount->user->id != $currentUser->id) {
+ if ($isLoggedIn && $socialAccount->user->id != $currentUser->id) {
session()->flash('error', trans('errors.social_account_already_used_existing', ['socialAccount' => $titleCaseDriver]));
return redirect('/my-account/auth#social_accounts');
diff --git a/app/Activity/ActivityType.php b/app/Activity/ActivityType.php
index a7f129f71..64532de17 100644
--- a/app/Activity/ActivityType.php
+++ b/app/Activity/ActivityType.php
@@ -46,6 +46,7 @@ class ActivityType
const USER_CREATE = 'user_create';
const USER_UPDATE = 'user_update';
const USER_DELETE = 'user_delete';
+ const USER_MFA_RESET = 'user_mfa_reset';
const API_TOKEN_CREATE = 'api_token_create';
const API_TOKEN_UPDATE = 'api_token_update';
diff --git a/app/Activity/Controllers/AuditLogController.php b/app/Activity/Controllers/AuditLogController.php
index c4f9b91ed..ed1421c0d 100644
--- a/app/Activity/Controllers/AuditLogController.php
+++ b/app/Activity/Controllers/AuditLogController.php
@@ -17,19 +17,19 @@ class AuditLogController extends Controller
$this->checkPermission(Permission::SettingsManage);
$this->checkPermission(Permission::UsersManage);
- $sort = $request->get('sort', 'activity_date');
- $order = $request->get('order', 'desc');
+ $sort = $request->input('sort', 'activity_date');
+ $order = $request->input('order', 'desc');
$listOptions = (new SimpleListOptions('', $sort, $order))->withSortOptions([
'created_at' => trans('settings.audit_table_date'),
'type' => trans('settings.audit_table_event'),
]);
$filters = [
- 'event' => $request->get('event', ''),
- 'date_from' => $request->get('date_from', ''),
- 'date_to' => $request->get('date_to', ''),
- 'user' => $request->get('user', ''),
- 'ip' => $request->get('ip', ''),
+ 'event' => $request->input('event', ''),
+ 'date_from' => $request->input('date_from', ''),
+ 'date_to' => $request->input('date_to', ''),
+ 'user' => $request->input('user', ''),
+ 'ip' => $request->input('ip', ''),
];
$query = Activity::query()
diff --git a/app/Activity/Controllers/FavouriteController.php b/app/Activity/Controllers/FavouriteController.php
index deeb4b0af..65bae276d 100644
--- a/app/Activity/Controllers/FavouriteController.php
+++ b/app/Activity/Controllers/FavouriteController.php
@@ -20,7 +20,7 @@ class FavouriteController extends Controller
public function index(Request $request, QueryTopFavourites $topFavourites)
{
$viewCount = 20;
- $page = intval($request->get('page', 1));
+ $page = intval($request->input('page', 1));
$favourites = $topFavourites->run($viewCount + 1, (($page - 1) * $viewCount));
$hasMoreLink = ($favourites->count() > $viewCount) ? url('/favourites?page=' . ($page + 1)) : null;
diff --git a/app/Activity/Controllers/TagApiController.php b/app/Activity/Controllers/TagApiController.php
new file mode 100644
index 000000000..f5c5e95d4
--- /dev/null
+++ b/app/Activity/Controllers/TagApiController.php
@@ -0,0 +1,68 @@
+ [
+ 'name' => ['required', 'string'],
+ ],
+ ];
+ }
+
+ /**
+ * Get a list of tag names used in the system.
+ * Only the name field can be used in filters.
+ */
+ public function listNames(): JsonResponse
+ {
+ $tagQuery = $this->tagRepo
+ ->queryWithTotalsForApi('');
+
+ return $this->apiListingResponse($tagQuery, [
+ 'name', 'values', 'usages', 'page_count', 'chapter_count', 'book_count', 'shelf_count',
+ ], [], [
+ 'name'
+ ]);
+ }
+
+ /**
+ * Get a list of tag values, which have been set for the given tag name,
+ * which must be provided as a query parameter on the request.
+ * Only the value field can be used in filters.
+ */
+ public function listValues(Request $request): JsonResponse
+ {
+ $data = $this->validate($request, $this->rules()['listValues']);
+ $name = $data['name'];
+
+ $tagQuery = $this->tagRepo->queryWithTotalsForApi($name);
+
+ return $this->apiListingResponse($tagQuery, [
+ 'name', 'value', 'usages', 'page_count', 'chapter_count', 'book_count', 'shelf_count',
+ ], [], [
+ 'value',
+ ]);
+ }
+}
diff --git a/app/Activity/Controllers/TagController.php b/app/Activity/Controllers/TagController.php
index 0af8835ca..b57c79825 100644
--- a/app/Activity/Controllers/TagController.php
+++ b/app/Activity/Controllers/TagController.php
@@ -24,9 +24,9 @@ class TagController extends Controller
'usages' => trans('entities.tags_usages'),
]);
- $nameFilter = $request->get('name', '');
+ $nameFilter = $request->input('name', '');
$tags = $this->tagRepo
- ->queryWithTotals($listOptions, $nameFilter)
+ ->queryWithTotalsForList($listOptions, $nameFilter)
->paginate(50)
->appends(array_filter(array_merge($listOptions->getPaginationAppends(), [
'name' => $nameFilter,
@@ -46,7 +46,7 @@ class TagController extends Controller
*/
public function getNameSuggestions(Request $request)
{
- $searchTerm = $request->get('search', '');
+ $searchTerm = $request->input('search', '');
$suggestions = $this->tagRepo->getNameSuggestions($searchTerm);
return response()->json($suggestions);
@@ -57,8 +57,8 @@ class TagController extends Controller
*/
public function getValueSuggestions(Request $request)
{
- $searchTerm = $request->get('search', '');
- $tagName = $request->get('name', '');
+ $searchTerm = $request->input('search', '');
+ $tagName = $request->input('name', '');
$suggestions = $this->tagRepo->getValueSuggestions($searchTerm, $tagName);
return response()->json($suggestions);
diff --git a/app/Activity/Models/Comment.php b/app/Activity/Models/Comment.php
index ab7d91772..3faa76657 100644
--- a/app/Activity/Models/Comment.php
+++ b/app/Activity/Models/Comment.php
@@ -9,6 +9,7 @@ use BookStack\Users\Models\HasCreatorAndUpdater;
use BookStack\Users\Models\OwnableInterface;
use BookStack\Util\HtmlContentFilter;
use BookStack\Util\HtmlContentFilterConfig;
+use BookStack\Util\HtmlToPlainText;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
@@ -87,6 +88,12 @@ class Comment extends Model implements Loggable, OwnableInterface
return $filter->filterString($this->html ?? '');
}
+ public function getPlainText(): string
+ {
+ $converter = new HtmlToPlainText();
+ return $converter->convert($this->html ?? '');
+ }
+
public function jointPermissions(): HasMany
{
return $this->hasMany(JointPermission::class, 'entity_id', 'commentable_id')
diff --git a/app/Activity/Notifications/Messages/CommentCreationNotification.php b/app/Activity/Notifications/Messages/CommentCreationNotification.php
index 30d0ffa2b..d739f4aab 100644
--- a/app/Activity/Notifications/Messages/CommentCreationNotification.php
+++ b/app/Activity/Notifications/Messages/CommentCreationNotification.php
@@ -24,7 +24,7 @@ class CommentCreationNotification extends BaseActivityNotification
$locale->trans('notifications.detail_page_name') => new EntityLinkMessageLine($page),
$locale->trans('notifications.detail_page_path') => $this->buildPagePathLine($page, $notifiable),
$locale->trans('notifications.detail_commenter') => $this->user->name,
- $locale->trans('notifications.detail_comment') => strip_tags($comment->html),
+ $locale->trans('notifications.detail_comment') => $comment->getPlainText(),
]);
return $this->newMailMessage($locale)
diff --git a/app/Activity/Notifications/Messages/CommentMentionNotification.php b/app/Activity/Notifications/Messages/CommentMentionNotification.php
index de9e71963..4c8ee5bab 100644
--- a/app/Activity/Notifications/Messages/CommentMentionNotification.php
+++ b/app/Activity/Notifications/Messages/CommentMentionNotification.php
@@ -24,7 +24,7 @@ class CommentMentionNotification extends BaseActivityNotification
$locale->trans('notifications.detail_page_name') => new EntityLinkMessageLine($page),
$locale->trans('notifications.detail_page_path') => $this->buildPagePathLine($page, $notifiable),
$locale->trans('notifications.detail_commenter') => $this->user->name,
- $locale->trans('notifications.detail_comment') => strip_tags($comment->html),
+ $locale->trans('notifications.detail_comment') => $comment->getPlainText(),
]);
return $this->newMailMessage($locale)
diff --git a/app/Activity/Notifications/NotificationManager.php b/app/Activity/Notifications/NotificationManager.php
index 8a6c26ffb..38da2c552 100644
--- a/app/Activity/Notifications/NotificationManager.php
+++ b/app/Activity/Notifications/NotificationManager.php
@@ -15,14 +15,14 @@ use BookStack\Users\Models\User;
class NotificationManager
{
/**
- * @var class-string hello hello hello hello hello hello hello Hello there is text here Hello there is text here hello world Hello World First Second New
This documentation covers use of the REST API. {{ trans('entities.books_sort_desc') }} {{ trans('entities.books_sort_desc') }} {{ trans('entities.books_sort_auto_sort_creation_hint') }} {{ trans('settings.sorting_book_default_desc') }} {{ trans('settings.sorting_book_default_desc') }} {{ trans('settings.users_mfa_reset_desc') }} My new comment My new comment response Contenta Contenta Contenta Contenta Boldtext hi
A már létező megjegyzések el lesznek rejtve.',
+ 'app_disable_comments' => 'Hozzászólások letiltása',
+ 'app_disable_comments_toggle' => 'Hozzászólások letiltása',
+ 'app_disable_comments_desc' => 'Hozzászólások letiltása az alkalmazás összes oldalán.
A már létező hozzászólások el lesznek rejtve.',
// Color settings
'color_scheme' => 'Alkalmazás színséma',
- 'color_scheme_desc' => 'Állítsd be a színeket az alkalmazás felhasználói felületén. A színeket külön-külön lehet konfigurálni a sötét és a világos módokhoz, hogy a legjobban illeszkedjenek a témához, és biztosítsák az olvashatóságot.',
- 'ui_colors_desc' => 'Állítsa be az alkalmazás elsődleges színét és alapértelmezett hivatkozási színét. Az elsődleges színt főként a fejléc szalaghirdetéséhez, a gombokhoz és a felület díszítéséhez használják. Az alapértelmezett hivatkozásszín a szöveges hivatkozásokhoz és műveletekhez használatos, mind az írott tartalomban, mind az alkalmazás felületén.',
+ 'color_scheme_desc' => 'Állítsa be az alkalmazás felhasználói felületének színeit. A színeket külön-külön lehet konfigurálni a sötét és a világos módokhoz, hogy a legjobban illeszkedjenek a témához, és biztosítsák az olvashatóságot.',
+ 'ui_colors_desc' => 'Állítsa be az alkalmazás elsődleges színét és az alapértelmezett hivatkozási színt. Az elsődleges színt főként a fejléc szalag, a gombok és egyéb díszítőelemek használják. Az alapértelmezett hivatkozás szín a szöveges hivatkozásokhoz és műveletekhez használatos, mind az írott tartalomban, mind az alkalmazás felhasználói felületén.',
'app_color' => 'Elsődleges szín',
'link_color' => 'Alapértelmezett link szín',
- 'content_colors_desc' => 'Beállítja az elemek színét az oldalszervezési hierarchiában. Az olvashatóság szempontjából javasolt az alapértelmezés szerinti színhez hasonló fényerősséget választani.',
+ 'content_colors_desc' => 'Állítsa be az elemek színeit az oldal hierarchiában. Az olvashatóság érdekében javasolt az alapértelmezett színekhez hasonló világosságú színeket választani.',
'bookshelf_color' => 'Polc színe',
'book_color' => 'Könyv színe',
'chapter_color' => 'Fejezet színe',
@@ -64,65 +64,65 @@ return [
'reg_settings' => 'Regisztráció',
'reg_enable' => 'Regisztráció engedélyezése',
'reg_enable_toggle' => 'Regisztráció engedélyezése',
- 'reg_enable_desc' => 'Ha a regisztráció engedélyezett, akkor a felhasználó képes lesz bejelentkezni mint az alkalmazás egy felhasználója. Regisztráció után egy egyszerű, alapértelmezés szerinti felhasználói szerepkör lesz hozzárendelve.',
+ 'reg_enable_desc' => 'Ha a regisztráció engedélyezve van, akkor látogatók regisztrálhatják saját magukat az alkalmazásba. Az új felhasználókhoz az alapértelmezett felhasználói szerepkör kerül hozzárendelésre.',
'reg_default_role' => 'Regisztráció utáni alapértelmezett felhasználói szerepkör',
- 'reg_enable_external_warning' => 'A fenti beállítási lehetőség nincs használatban, ha külső LDAP vagy SAML hitelesítés aktív. A nem létező tagok felhasználói fiókjai automatikusan létrejönnek ha a használatban lévő külső rendszeren sikeres a hitelesítés.',
- 'reg_email_confirmation' => 'Email megerősítés',
- 'reg_email_confirmation_toggle' => 'Email megerősítés szükséges',
- 'reg_confirm_email_desc' => 'Ha a tartomány korlátozás be van állítva, akkor email megerősítés szükséges és ez a beállítás figyelmen kívül lesz hagyva.',
- 'reg_confirm_restrict_domain' => 'Tartomány korlátozás',
- 'reg_confirm_restrict_domain_desc' => 'Azoknak az email tartományoknak a vesszővel elválasztott listája, melyekre a regisztráció korlátozva lesz. A felhasználók egy emailt fognak kapni, hogy megerősítsék az email címüket mielőtt használni kezdhetnék az alkalmazást.
Fontos tudni, hogy a felhasználók a sikeres regisztráció után megváltoztathatják az email címüket.',
+ 'reg_enable_external_warning' => 'A fenti beállítási lehetőség figyelmen kívül van hagyva, ha külső LDAP vagy SAML hitelesítés aktív. A nem létező tagok felhasználói fiókjai automatikusan létrejönnek ha a használatban lévő külső rendszeren sikeres a hitelesítés.',
+ 'reg_email_confirmation' => 'Email megerősítése',
+ 'reg_email_confirmation_toggle' => 'Email megerősítése szükséges',
+ 'reg_confirm_email_desc' => 'Ha a domain korlátozás be van állítva, akkor az email megerősítése kötelező, és ez a beállítás figyelmen kívül van hagyva.',
+ 'reg_confirm_restrict_domain' => 'Domain korlátozás',
+ 'reg_confirm_restrict_domain_desc' => 'Adja meg azon email domain-eket vesszővel tagolt listaként, amikre a regisztrációt korlátozni szeretné. A felhasználók egy emailt fognak kapni, hogy megerősítsék az email címüket mielőtt használni kezdhetnék az alkalmazást.
Fontos tudni, hogy a felhasználók a sikeres regisztráció után megváltoztathatják az email címüket.',
'reg_confirm_restrict_domain_placeholder' => 'Nincs beállítva korlátozás',
// Sorting Settings
- 'sorting' => 'Lists & Sorting',
- 'sorting_book_default' => 'Default Book Sort Rule',
- 'sorting_book_default_desc' => 'Select the default sort rule to apply to new books. This won\'t affect existing books, and can be overridden per-book.',
- 'sorting_rules' => 'Sort Rules',
- 'sorting_rules_desc' => 'These are predefined sorting operations which can be applied to content in the system.',
- 'sort_rule_assigned_to_x_books' => 'Assigned to :count Book|Assigned to :count Books',
- 'sort_rule_create' => 'Create Sort Rule',
- 'sort_rule_edit' => 'Edit Sort Rule',
- 'sort_rule_delete' => 'Delete Sort Rule',
- 'sort_rule_delete_desc' => 'Remove this sort rule from the system. Books using this sort will revert to manual sorting.',
- 'sort_rule_delete_warn_books' => 'This sort rule is currently used on :count book(s). Are you sure you want to delete this?',
- 'sort_rule_delete_warn_default' => 'This sort rule is currently used as the default for books. Are you sure you want to delete this?',
- 'sort_rule_details' => 'Sort Rule Details',
- 'sort_rule_details_desc' => 'Set a name for this sort rule, which will appear in lists when users are selecting a sort.',
- 'sort_rule_operations' => 'Sort Operations',
- 'sort_rule_operations_desc' => 'Configure the sort actions to be performed by moving them from the list of available operations. Upon use, the operations will be applied in order, from top to bottom. Any changes made here will be applied to all assigned books upon save.',
- 'sort_rule_available_operations' => 'Available Operations',
- 'sort_rule_available_operations_empty' => 'No operations remaining',
- 'sort_rule_configured_operations' => 'Configured Operations',
- 'sort_rule_configured_operations_empty' => 'Drag/add operations from the "Available Operations" list',
- 'sort_rule_op_asc' => '(Asc)',
- 'sort_rule_op_desc' => '(Desc)',
- 'sort_rule_op_name' => 'Name - Alphabetical',
- 'sort_rule_op_name_numeric' => 'Name - Numeric',
- 'sort_rule_op_created_date' => 'Created Date',
- 'sort_rule_op_updated_date' => 'Updated Date',
- 'sort_rule_op_chapters_first' => 'Chapters First',
- 'sort_rule_op_chapters_last' => 'Chapters Last',
- 'sorting_page_limits' => 'Per-Page Display Limits',
- 'sorting_page_limits_desc' => 'Set how many items to show per-page in various lists within the system. Typically a lower amount will be more performant, while a higher amount avoids the need to click through multiple pages. Using a multiple of 6 is recommended.',
+ 'sorting' => 'Listák és rendezés',
+ 'sorting_book_default' => 'Alapértelmezett könyv rendezési szabály',
+ 'sorting_book_default_desc' => 'Válassza ki az új könyvekre alkalmazandó alapértelmezett rendezési szabályt. Ez nem fogja befolyásolni a már létező könyveket, és könyvenként felülbírálható.',
+ 'sorting_rules' => 'Rendezési szabályok',
+ 'sorting_rules_desc' => 'Ezek előre meghatározott rendezési szabályok, amelyek alkalmazhatók a rendszerben található tartalomra.',
+ 'sort_rule_assigned_to_x_books' => 'Hozzárendelve :count könyvhöz|Hozzárendelve :count könyvhöz',
+ 'sort_rule_create' => 'Rendezési szabály létrehozása',
+ 'sort_rule_edit' => 'Rendezési szabály szerkesztése',
+ 'sort_rule_delete' => 'Rendezési szabály törlése',
+ 'sort_rule_delete_desc' => 'Eltávolítja ezt a rendezési szabályt a rendszerből. A jelenleg ezt használó könyvek vissza lesznek állítva kézi rendezésre.',
+ 'sort_rule_delete_warn_books' => 'Ez a rendezési szabály :count könyvön van használva. Biztosan törli?',
+ 'sort_rule_delete_warn_default' => 'Ez a rendezési szabály jelenleg az alapértelmezett az új könyvekhez. Biztosan törli?',
+ 'sort_rule_details' => 'Rendezési szabály részletei',
+ 'sort_rule_details_desc' => 'Állítson be egy nevet a rendezési szabálynak, amely megjelenik majd a rendezési listákban.',
+ 'sort_rule_operations' => 'Rendezési műveletek',
+ 'sort_rule_operations_desc' => 'Állítsa be rendezési műveleteket az elemek átmozgatásával az elérhető műveletek listájából. A műveletek mindig fentről lefelé haladva kerülnek végrehajtásra. Mentéskor minden itt végzett változtatás az összes hozzárendelt könyvre érvényesítve lesz.',
+ 'sort_rule_available_operations' => 'Elérhető műveletek',
+ 'sort_rule_available_operations_empty' => 'Nincs több művelet',
+ 'sort_rule_configured_operations' => 'Beállított műveletek',
+ 'sort_rule_configured_operations_empty' => 'Húzzon/adjon hozzá műveleteket az "Elérhető műveletek" listáról',
+ 'sort_rule_op_asc' => '(Növekvő)',
+ 'sort_rule_op_desc' => '(Csökkenő)',
+ 'sort_rule_op_name' => 'Név - betűrend',
+ 'sort_rule_op_name_numeric' => 'Név - számsorrend',
+ 'sort_rule_op_created_date' => 'Létrehozás dátuma',
+ 'sort_rule_op_updated_date' => 'Frissítés dátuma',
+ 'sort_rule_op_chapters_first' => 'Fejezetek elől',
+ 'sort_rule_op_chapters_last' => 'Fejezetek hátul',
+ 'sorting_page_limits' => 'Oldalankénti megjelenítési limitek',
+ 'sorting_page_limits_desc' => 'Állítsa be oldalanként mennyi elem kerüljön megjelenítésre a rendszer külöböző listáiban. Általában a kisebb mennyiség jobb teljesítményhez vezet, nagyobb mennyiségnél nem kell annyi oldalon végigmenni. Ajánlott a 6 egyik többszörösét használni.',
// Maintenance settings
'maint' => 'Karbantartás',
- 'maint_image_cleanup' => 'Képek tisztítása',
+ 'maint_image_cleanup' => 'Képek kitakarítása',
'maint_image_cleanup_desc' => 'Végigolvassa az oldalakat és a tartalmak változatait, hogy leellenőrizze jelenleg mely képek és rajzok vannak használatban, és mely képek szerepelnek többször. A futtatása előtt feltétlen készíteni kell egy teljes adatbázis és lemezkép mentést.',
'maint_delete_images_only_in_revisions' => 'Törölje azokat a képeket is, amelyek csak a régi oldalverziókban léteznek',
- 'maint_image_cleanup_run' => 'Tisztítás futtatása',
- 'maint_image_cleanup_warning' => ':count potenciálisan nem használt képet találtam. Biztosan törölhetőek ezek a képek?',
+ 'maint_image_cleanup_run' => 'Takarítás futtatása',
+ 'maint_image_cleanup_warning' => ':count potenciálisan nem használt kép van. Biztosan törölni szeretné ezeket a képeket?',
'maint_image_cleanup_success' => ':count potenciálisan nem használt kép megtalálva és törölve!',
'maint_image_cleanup_nothing_found' => 'Nincsenek nem használt képek, semmi sem lett törölve!',
- 'maint_send_test_email' => 'Teszt e-mail küldése',
+ 'maint_send_test_email' => 'Teszt email küldése',
'maint_send_test_email_desc' => 'Ez elküld egy teszt emailt a profilban megadott email címre.',
- 'maint_send_test_email_run' => 'Teszt e-mail küldése',
- 'maint_send_test_email_success' => 'Email elküldve :address címre',
- 'maint_send_test_email_mail_subject' => 'Teszt e-mail',
+ 'maint_send_test_email_run' => 'Teszt email küldése',
+ 'maint_send_test_email_success' => 'Email elküldve a(z) :address címre',
+ 'maint_send_test_email_mail_subject' => 'Teszt email',
'maint_send_test_email_mail_greeting' => 'Az email kézbesítés működőképesnek tűnik!',
'maint_send_test_email_mail_text' => 'Gratulálunk! Mivel ez az email figyelmeztetés megérkezett az email beállítások megfelelőek.',
- 'maint_recycle_bin_desc' => 'A törölt polcok, könyvek, fejezetek és oldalak a lomtárba kerülnek, így visszaállíthatók vagy véglegesen törölhetők. A rendszer konfigurációtól függően egy idő után a lomtárban lévő régebbi elemek automatikusan eltávolíthatók.',
+ 'maint_recycle_bin_desc' => 'A törölt polcok, könyvek, fejezetek és oldalak a lomtárba kerülnek, így visszaállíthatók vagy véglegesen törölhetők. A rendszer konfigurációtól függően egy idő után a lomtárban lévő régebbi elemek automatikusan eltávolításra kerülhetnek.',
'maint_recycle_bin_open' => 'Lomtár megnyitása',
'maint_regen_references' => 'Referenciák újragenerálása',
'maint_regen_references_desc' => 'Ez a művelet újraépíti az adatbázison belüli elemek közötti hivatkozási indexet. Ez általában automatikusan történik, de ez a művelet hasznos lehet régi vagy nem hivatalos módszerekkel hozzáadott tartalom indexeléséhez.',
@@ -144,7 +144,7 @@ return [
'recycle_bin_destroy_confirm' => 'Ez a művelet véglegesen törli ezt az elemet a rendszerből az alább felsorolt összes alárendelt elemmel együtt, és nem fogja tudni visszaállítani ezt a tartalmat. Biztosan véglegesen törli ezt az elemet?',
'recycle_bin_destroy_list' => 'Megsemmisítendő elemek',
'recycle_bin_restore_list' => 'Visszaállítandó elemek',
- 'recycle_bin_restore_confirm' => 'Ez a művelet visszaállítja a törölt elemet, beleértve az utódelemeket is, az eredeti helyükre. Ha az eredeti helyet azóta törölték, és most a lomtárban van, akkor a szülőelemet is vissza kell állítani.',
+ 'recycle_bin_restore_confirm' => 'Ez a művelet visszaállítja a törölt elemet, beleértve az alárendelt elemeket is, az eredeti helyükre. Ha az eredeti helyet azóta törölték, és most a lomtárban van, akkor a tartalmazó elemet is vissza kell állítani.',
'recycle_bin_restore_deleted_parent' => 'Ennek az elemnek a szülője is törölve lett. Ezek mindaddig törölve maradnak, amíg az adott szülőt is vissza nem állítják.',
'recycle_bin_restore_parent' => 'Szűlő visszaállítása',
'recycle_bin_destroy_notification' => 'Összesen :count elemet törölt a lomtárból.',
@@ -160,7 +160,7 @@ return [
'audit_table_user' => 'Felhasználó',
'audit_table_event' => 'Esemény',
'audit_table_related' => 'Kapcsolódó elem vagy részlet',
- 'audit_table_ip' => 'IP Cím',
+ 'audit_table_ip' => 'IP cím',
'audit_table_date' => 'Tevékenység időpontja',
'audit_date_from' => 'Kezdő dátum',
'audit_date_to' => 'Végdátum',
@@ -168,45 +168,46 @@ return [
// Role Settings
'roles' => 'Szerepkörök',
'role_user_roles' => 'Felhasználói szerepkörök',
- 'roles_index_desc' => 'A szerepkörök a felhasználók csoportosítására és rendszerengedélyek biztosítására szolgálnak tagjaiknak. Ha egy felhasználó több szerepkör tagja, a megadott jogosultságok halmozódnak, és a felhasználó örökli az összes képességet.',
+ 'roles_index_desc' => 'A szerepkörök a felhasználók csoportosítására és rendszerengedélyek biztosítására szolgálnak. Ha egy felhasználó több szerepkör tagja, a megadott jogosultságok halmozódnak, és a felhasználó örökli az összes képességet.',
'roles_x_users_assigned' => ':count hozzárendelt felhasználó|:count hozzárendelt felhasználó',
'roles_x_permissions_provided' => ':count jogosultság|:count jogosultság',
'roles_assigned_users' => 'Hozzárendelt felhasználók',
'roles_permissions_provided' => 'Megadott jogosultságok',
'role_create' => 'Új szerepkör létrehozása',
'role_delete' => 'Szerepkör törlése',
- 'role_delete_confirm' => 'Ez törölni fogja \':roleName\' szerepkört.',
- 'role_delete_users_assigned' => 'Ehhez a szerepkörhöz :userCount felhasználó van hozzárendelve. Ha a felhasználókat át kell helyezni ebből a szerepkörből, akkor ki kell választani egy új szerepkört.',
- 'role_delete_no_migration' => "Nincs felhasználó áthelyezés",
- 'role_delete_sure' => 'Biztosan törölhető ez a szerepkör?',
+ 'role_delete_confirm' => 'Ez törölni fogja a(z) \':roleName\' szerepkört.',
+ 'role_delete_users_assigned' => 'Ehhez a szerepkörhöz :userCount felhasználó van hozzárendelve. Ha át szeretné helyezni a felhasználókat egy másik szerepkörbe, akkor válasszon egy új szerepkört az alábbi listából.',
+ 'role_delete_no_migration' => "Ne helyezze át a felhasználókat",
+ 'role_delete_sure' => 'Biztosan törli ezt a szerepkört?',
'role_edit' => 'Szerepkör szerkesztése',
'role_details' => 'Szerepkör részletei',
'role_name' => 'Szerepkör neve',
'role_desc' => 'Szerepkör rövid leírása',
- 'role_mfa_enforced' => 'Kétlépcsős hitelesítés megkövetelése',
+ 'role_mfa_enforced' => 'Többlépcsős hitelesítés megkövetelése',
'role_external_auth_id' => 'Külső hitelesítés azonosítók',
'role_system' => 'Rendszer jogosultságok',
'role_manage_users' => 'Felhasználók kezelése',
- 'role_manage_roles' => 'Szerepkörök és szerepkör engedélyek kezelése',
+ 'role_manage_roles' => 'Szerepkörök és jogosultságok kezelése',
'role_manage_entity_permissions' => 'Minden könyv, fejezet és oldalengedély kezelése',
'role_manage_own_entity_permissions' => 'Saját könyv, fejezet és oldalak engedélyeinek kezelése',
'role_manage_page_templates' => 'Oldalsablonok kezelése',
'role_access_api' => 'Hozzáférés a rendszer API-hoz',
'role_manage_settings' => 'Alkalmazás beállításainak kezelése',
'role_export_content' => 'Tartalom exportálása',
- 'role_import_content' => 'Import content',
+ 'role_import_content' => 'Tartalom importálása',
'role_editor_change' => 'Oldalszerkesztő módosítása',
'role_notifications' => 'Értesítések fogadása és kezelése',
- 'role_permission_note_users_and_roles' => 'These permissions will technically also provide visibility & searching of users & roles in the system.',
- 'role_asset' => 'Eszköz jogosultságok',
+ 'role_permission_note_users_and_roles' => 'Ezek a jogosultságok gyakorlatilag megtekintést és felhasználó/szerepkör keresést is lehetővé fognak tenni.',
+ 'role_asset' => 'Tartalom jogosultságok',
'roles_system_warning' => 'Ne feledje, hogy a fenti három engedély bármelyikéhez való hozzáférés lehetővé teszi a felhasználó számára, hogy módosítsa saját vagy a rendszerben mások jogosultságait. Csak megbízható felhasználókhoz rendeljen szerepeket ezekkel az engedélyekkel.',
- 'role_asset_desc' => 'Ezek a jogosultságok vezérlik az alapértelmezés szerinti hozzáférést a rendszerben található eszközökhöz. A könyvek, fejezetek és oldalak jogosultságai felülírják ezeket a jogosultságokat.',
- 'role_asset_admins' => 'Az adminisztrátorok automatikusan hozzáférést kapnak minden tartalomhoz, de ezek a beállítások megjeleníthetnek vagy elrejthetnek felhasználói felület beállításokat.',
+ 'role_asset_desc' => 'Ezek a jogosultságok vezérlik az alapértelmezés szerinti hozzáférést a rendszerben található tartalomhoz. A könyvek, fejezetek és oldalak jogosultságai felülírják ezeket a jogosultságokat.',
+ 'role_asset_admins' => 'Az adminisztrátorok automatikusan hozzáférést kapnak minden tartalomhoz, de ezek a beállítások megjeleníthetnek vagy elrejthetnek beállításokat a felhasználói felületen.',
'role_asset_image_view_note' => 'Ez a képkezelőn belüli láthatóságra vonatkozik. A feltöltött képfájlok tényleges elérése a rendszerkép tárolási beállításától függ.',
- 'role_asset_users_note' => 'These permissions will technically also provide visibility & searching of users in the system.',
+ 'role_asset_users_note' => 'Ezek a jogosultságok gyakorlatilag megtekintést és felhasználó keresést is lehetővé fognak tenni.',
'role_all' => 'Összes',
'role_own' => 'Saját',
- 'role_controlled_by_asset' => 'Az általuk feltöltött eszköz által ellenőrzött',
+ 'role_controlled_by_asset' => 'A feltöltött tartalom beállításaitól függ',
+ 'role_controlled_by_page_delete' => 'Az oldal törlési jogosultságoktól függ',
'role_save' => 'Szerepkör mentése',
'role_users' => 'Felhasználók ebben a szerepkörben',
'role_users_none' => 'Jelenleg nincsenek felhasználók hozzárendelve ehhez a szerepkörhöz',
@@ -219,72 +220,75 @@ return [
'users_search' => 'Felhasználók keresése',
'users_latest_activity' => 'Legújabb tevékenység',
'users_details' => 'Felhasználó részletei',
- 'users_details_desc' => 'Egy megjelenítendő név és email cím beállítása ennek a felhasználónak. Az email cím az alkalmazásba történő bejelentkezéshez lesz használva.',
- 'users_details_desc_no_email' => 'Egy megjelenítendő név beállítása ennek a felhasználónak amiről mások felismerik.',
+ 'users_details_desc' => 'Megjelenítendő név és email cím beállítása ennek a felhasználónak. Az email cím az alkalmazásba történő bejelentkezéshez lesz használva.',
+ 'users_details_desc_no_email' => 'Megjelenítendő név beállítása ennek a felhasználónak, amiről mások felismerik.',
'users_role' => 'Felhasználói szerepkörök',
- 'users_role_desc' => 'A felhasználó melyik szerepkörhöz lesz rendelve. Ha a felhasználó több szerepkörhöz van rendelve, akkor ezeknek a szerepköröknek a jogosultságai összeadódnak, és a a felhasználó a hozzárendelt szerepkörök minden képességét megkapja.',
+ 'users_role_desc' => 'Felhasználó szerepköreinek kiválasztása. Ha a felhasználó több szerepkörhöz van rendelve, akkor ezeknek a szerepköröknek a jogosultságai összeadódnak, és a a felhasználó a hozzárendelt szerepkörök minden képességét megkapja.',
'users_password' => 'Felhasználó jelszava',
'users_password_desc' => 'Az alkalmazásba bejelentkezéshez használható jelszó beállítása. Legalább 8 karakter hosszúnak kell lennie.',
- 'users_send_invite_text' => 'Lehetséges egy meghívó emailt küldeni ennek a felhasználónak ami lehetővé teszi, hogy beállíthassa a saját jelszavát. Máskülönben a jelszót az erre jogosult felhasználónak kell beállítania.',
+ 'users_send_invite_text' => 'Dönthet úgy, hogy meghívó emailt küld ennek a felhasználónak, így az beállíthatja saját jelszavát. Ellenkező esetben Ön is beállíthat egy jelszót neki.',
'users_send_invite_option' => 'Felhasználó meghívó levél küldése',
'users_external_auth_id' => 'Külső hitelesítés azonosítója',
- 'users_external_auth_id_desc' => 'Ha külső hitelesítési rendszer van használatban (például SAML2, OIDC vagy LDAP), ez az az azonosító, amely a BookStack felhasználót a hitelesítési rendszerfiókhoz kapcsolja. Ha az alapértelmezett e-mail alapú hitelesítést használja, figyelmen kívül hagyhatja ezt a mezőt.',
+ 'users_external_auth_id_desc' => 'Ha külső hitelesítési rendszer van használatban (például SAML2, OIDC vagy LDAP), ez az az azonosító, amely a BookStack felhasználót a hitelesítési rendszerfiókhoz kapcsolja. Ha az alapértelmezett email alapú hitelesítést használja, figyelmen kívül hagyhatja ezt a mezőt.',
'users_password_warning' => 'Csak akkor töltse ki az alábbi mezőt, ha módosítani szeretné ennek a felhasználónak a jelszavát.',
- 'users_system_public' => 'Ez a felhasználó bármelyik, a példányt megtekintő felhasználót képviseli. Nem lehet vele bejelentkezni de automatikusan hozzá lesz rendelve.',
+ 'users_system_public' => 'Ez a felhasználó bármelyik, az alkalmazást megtekintő látogatót képviseli. Nem lehet vele bejelentkezni de automatikusan hozzá lesz rendelve.',
'users_delete' => 'Felhasználó törlése',
'users_delete_named' => ':userName felhasználó törlése',
'users_delete_warning' => '\':userName\' felhasználó teljesen törölve lesz a rendszerből.',
- 'users_delete_confirm' => 'Biztosan törölhető ez a felhasználó?',
+ 'users_delete_confirm' => 'Biztosan törli ezt a felhasználót?',
'users_migrate_ownership' => 'Tulajdonjog átruházása',
'users_migrate_ownership_desc' => 'Válasszon itt egy felhasználót, ha azt szeretné, hogy egy másik felhasználó legyen a tulajdonosa az összes, jelenleg a felhasználó tulajdonában lévő elemnek.',
'users_none_selected' => 'Nincs felhasználó kiválasztva',
'users_edit' => 'Felhasználó szerkesztése',
'users_edit_profile' => 'Profil szerkesztése',
- 'users_avatar' => 'Avatar használata',
- 'users_avatar_desc' => 'A felhasználót ábrázoló kép kiválasztása. Kb. 256px méretű négyzetes képnek kell lennie.',
+ 'users_avatar' => 'Felhasználó profilképe',
+ 'users_avatar_desc' => 'Válasszon ki egy képet, ami ehhez a felhasználóhoz fog tartozni. Négyzetes, körülbelül 256 pixel széles képnek kell lennie.',
'users_preferred_language' => 'Előnyben részesített nyelv',
'users_preferred_language_desc' => 'Ez a beállítás megváltoztatja az alkalmazás felhasználói felületén használt nyelvet. Nincs hatása a felhasználók által létrehozott tartalomra.',
- 'users_social_accounts' => 'Közösségi fiókok',
+ 'users_social_accounts' => 'Közösségi média fiókok',
'users_social_accounts_desc' => 'Tekintse meg a felhasználó csatlakoztatott közösségi fiókjainak állapotát. A közösségi fiókok az elsődleges hitelesítési rendszer mellett használhatók a rendszerhez való hozzáféréshez.',
- 'users_social_accounts_info' => 'Itt lehet egyéb fiókokat hozzákapcsolni a gyorsabb és könnyebb bejelentkezés érdekében. Itt olyan fiókot lehet lecsatlakoztatni, melynek korábban nem volt engedélyezett hozzáférése. Visszavonja a hozzáférést a csatlakoztatott szociális fiók profilbeállításaiból.',
+ 'users_social_accounts_info' => 'Itt kapcsolhat össze külső fiókokat a gyorsabb és egyszerűbb bejelentkezés érdekében. Egy összekapcsolás megszüntetése itt, nem vonja vissza a már korábban engedélyezett hozzáférést. Vonja vissza a hozzáférést a külső fiók profil beállításaiban.',
'users_social_connect' => 'Fiók csatlakoztatása',
'users_social_disconnect' => 'Fiók lecsatlakoztatása',
'users_social_status_connected' => 'Csatlakozva',
'users_social_status_disconnected' => 'Lecsatlakozva',
'users_social_connected' => ':socialAccount fiók sikeresen csatlakoztatva a profilhoz.',
'users_social_disconnected' => ':socialAccount fiók sikeresen lecsatlakoztatva a profilról.',
- 'users_api_tokens' => 'API vezérjelek',
- 'users_api_tokens_desc' => 'A BookStack REST API-val történő hitelesítéshez használt hozzáférési token létrehozása és kezelése. Az API engedélyeit azon a felhasználón keresztül kezelik, akihez a token tartozik.',
- 'users_api_tokens_none' => 'Ehhez a felhasználóhoz nincsenek létrehozva API vezérjelek',
- 'users_api_tokens_create' => 'Vezérjel létrehozása',
+ 'users_api_tokens' => 'API kulcsok',
+ 'users_api_tokens_desc' => 'A BookStack REST API-val történő hitelesítéshez használt hozzáférési kulcs létrehozása és kezelése. Az API engedélyeit azon a felhasználón keresztül kezelik, akihez a token tartozik.',
+ 'users_api_tokens_none' => 'Ehhez a felhasználóhoz nincsenek létrehozva API kulcsok',
+ 'users_api_tokens_create' => 'Kulcs létrehozása',
'users_api_tokens_expires' => 'Lejárat',
'users_api_tokens_docs' => 'API dokumentáció',
- 'users_mfa' => 'Többfaktoros hitelesítés',
+ 'users_mfa' => 'Többlépcsős hitelesítés',
'users_mfa_desc' => 'Állítsa be a többlépcsős azonosítást egy extra biztonsági rétegként a felhasználói fiókjához.',
- 'users_mfa_x_methods' => ':count metódus konfigurálva|:count metódus konfigurálva',
+ 'users_mfa_x_methods' => ':count mód beállítva|:count mód beállítva',
'users_mfa_configure' => 'Módszer beállítása',
+ 'users_mfa_reset' => 'Többlépcsős azonosítási módok alaphelyzetbe állítása',
+ 'users_mfa_reset_desc' => 'Ez alaphelyzetbe fogja állítani a felhasználónak az összes beállított többlépcsős azonosítási módját. Ha valamelyik a szerepkörük előírja a többlépcsős azonosítást, akkor a következő bejelentkezésnél fel lesznek szólítva egy új beállítására.',
+ 'users_mfa_reset_confirm' => 'Biztos benne, hogy alaphelyzetbe szeretné állítani ennek a felhasználónak a többlépcsős azonosítási módjait?',
// API Tokens
- 'user_api_token_create' => 'API vezérjel létrehozása',
+ 'user_api_token_create' => 'API kulcs létrehozása',
'user_api_token_name' => 'Név',
- 'user_api_token_name_desc' => 'Adjon a tokennek egy olvasható nevet, hogy a jövőben emlékeztessen a tervezett céljára.',
+ 'user_api_token_name_desc' => 'Adjon a kulcsnak egy olvasható nevet, hogy a jövőben emlékeztessen a tervezett céljára.',
'user_api_token_expiry' => 'Lejárati dátum',
- 'user_api_token_expiry_desc' => 'Dátum megadása ameddig a vezérjel érvényes. Ez után a dátum után az ezzel a vezérjellel történő kérések nem fognak működni. Üresen hagyva a lejárati idő 100 évre lesz beállítva.',
- 'user_api_token_create_secret_message' => 'Közvetlenül a token létrehozása után egy „Token ID” és „Token Secret” generálódik és jelenik meg. A Secret csak egyszer jelenik meg, ezért a folytatás előtt másolja át az értéket egy biztonságos helyre.',
- 'user_api_token' => 'API vezérjel',
- 'user_api_token_id' => 'Vezérjel azonosító',
- 'user_api_token_id_desc' => 'Ez egy nem szerkeszthető, a rendszer által létrehozott azonosító ehhez a vezérjelhez amire API kérésekben lehet szükség.',
- 'user_api_token_secret' => 'Vezérjel titkos kódja',
- 'user_api_token_secret_desc' => 'Ez egy rendszer által generált "secret" ehhez a tokenhez, amelyet meg kell adni az API-kérésekben. Ez csak most jelenik meg, ezért másolja ezt az értéket egy biztonságos helyre.',
- 'user_api_token_created' => 'Vezérjel létrehozva :timeAgo',
- 'user_api_token_updated' => 'Vezérjel frissítve :timeAgo',
- 'user_api_token_delete' => 'Vezérjel törlése',
- 'user_api_token_delete_warning' => '\':tokenName\' nevű API vezérjel teljesen törölve lesz a rendszerből.',
- 'user_api_token_delete_confirm' => 'Biztosan törölhető ez az API vezérjel?',
+ 'user_api_token_expiry_desc' => 'Dátum ameddig a kulcs érvényes. Ez után a dátum után az ezzel a kulccsal történő kérések nem fognak működni. Üresen hagyva a lejárati idő 100 évre lesz beállítva.',
+ 'user_api_token_create_secret_message' => 'Közvetlenül a kulcs létrehozása után egy „Kulcs azonosító” és „Titkos kód” generálódik és jelenik meg. A titkos kód csak egyszer jelenik meg, ezért a folytatás előtt másolja át az értéket egy biztonságos helyre.',
+ 'user_api_token' => 'API kulcs',
+ 'user_api_token_id' => 'Kulcs azonosító',
+ 'user_api_token_id_desc' => 'Ez egy nem szerkeszthető, a rendszer által létrehozott azonosító ehhez a kulcshoz, amire API kérésekben lehet szükség.',
+ 'user_api_token_secret' => 'Kulcs titkos kódja',
+ 'user_api_token_secret_desc' => 'Ez egy rendszer által generált "titok" ehhez a kulcshoz, amelyet meg kell adni az API-kérésekben. Ez csak most jelenik meg, ezért másolja ezt az értéket egy biztonságos helyre.',
+ 'user_api_token_created' => 'Kulcs létrehozva :timeAgo',
+ 'user_api_token_updated' => 'Kulcs frissítve :timeAgo',
+ 'user_api_token_delete' => 'Kulcs törlése',
+ 'user_api_token_delete_warning' => '\':tokenName\' nevű API kulcs teljesen törölve lesz a rendszerből.',
+ 'user_api_token_delete_confirm' => 'Biztosan törli ezt az API kulcsot?',
// Webhooks
'webhooks' => 'Webhook-ok',
- 'webhooks_index_desc' => 'A webhookok segítségével adatokat küldhetünk külső URL-ekre, amikor bizonyos műveletek és események történnek a rendszeren belül, ami lehetővé teszi az eseményalapú integrációt külső platformokkal, például üzenetküldő vagy értesítési rendszerekkel.',
+ 'webhooks_index_desc' => 'A webhookok segítségével adatokat küldhet külső URL-ekre, amikor bizonyos műveletek és események történnek a rendszeren belül. Ez lehetővé teszi az eseményalapú integrációt külső platformokkal, például üzenetküldő vagy értesítési rendszerekkel.',
'webhooks_x_trigger_events' => ':count kiváltó esemény|:count kiváltó esemény',
'webhooks_create' => 'Új webhook létrehozása',
'webhooks_none_created' => 'Még nincs létrehozva egy webhook sem.',
@@ -302,19 +306,19 @@ return [
'webhooks_active' => 'Webhook aktív',
'webhook_events_table_header' => 'Események',
'webhooks_delete' => 'Webhook törlése',
- 'webhooks_delete_warning' => 'Ezzel a \':webhookName\' nevű webhookot teljesen törli a rendszerből.',
+ 'webhooks_delete_warning' => 'Ezzel a(z) \':webhookName\' nevű webhookot teljesen törli a rendszerből.',
'webhooks_delete_confirm' => 'Biztosan törli ezt a webhookot?',
'webhooks_format_example' => 'Webhook formátum példa',
- 'webhooks_format_example_desc' => 'A Webhook-adatok POST-kérésként kerülnek elküldésre a konfigurált végponthoz JSON-ként az alábbi formátumban. A "related_item" és az "url" tulajdonság nem kötelező, és az aktivált esemény típusától függ.',
+ 'webhooks_format_example_desc' => 'A Webhook-adatok POST-kérésként kerülnek elküldésre a beállított végponthoz JSON-ként az alábbi formátumban. A "related_item" és az "url" tulajdonság nem kötelező, és az aktivált esemény típusától függ.',
'webhooks_status' => 'Webhook állapota',
'webhooks_last_called' => 'Utolsó hívás:',
'webhooks_last_errored' => 'Utolsó hiba:',
'webhooks_last_error_message' => 'Utolsó hibaüzenet:',
// Licensing
- 'licenses' => 'Licenszek',
+ 'licenses' => 'Licencek',
'licenses_desc' => 'Ez az oldal a BookStack licencinformációit részletezi, a BookStackben használt projekteken és könyvtárakon kívül. Sok felsorolt projekt csak fejlesztési környezetben használható.',
- 'licenses_bookstack' => 'BookStack Licensz',
+ 'licenses_bookstack' => 'BookStack licenc',
'licenses_php' => 'PHP könyvtár licencek',
'licenses_js' => 'JavaScript könyvtár licencek',
'licenses_other' => 'Egyéb licencek',
@@ -363,6 +367,7 @@ return [
'sk' => 'Slovensky',
'sl' => 'Slovenščina',
'sv' => 'Svenska',
+ 'th' => 'ภาษาไทย',
'tr' => 'Türkçe',
'uk' => 'Українська',
'uz' => 'O‘zbekcha',
diff --git a/lang/hu/validation.php b/lang/hu/validation.php
index b740ca0c6..ec6f68fe2 100644
--- a/lang/hu/validation.php
+++ b/lang/hu/validation.php
@@ -8,56 +8,56 @@
return [
// Standard laravel validation lines
- 'accepted' => ':attribute elfogadott kell legyen.',
- 'active_url' => ':attribute nem érvényes webcím.',
- 'after' => ':attribute dátumnak :date utáninak kell lennie.',
- 'alpha' => ':attribute csak betűket tartalmazhat.',
- 'alpha_dash' => ':attribute csak betűket, számokat és kötőjeleket tartalmazhat.',
- 'alpha_num' => ':attribute csak betűket és számokat tartalmazhat.',
- 'array' => ':attribute tömb kell legyen.',
+ 'accepted' => 'A(z) :attribute elfogadott kell legyen.',
+ 'active_url' => 'A(z) :attribute nem egy érvényes URL.',
+ 'after' => 'A(z) :attribute objektumnak egy :date utáni dátumnak kell lennie.',
+ 'alpha' => 'A(z) :attribute csak betűket tartalmazhat.',
+ 'alpha_dash' => 'A(z) :attribute csak betűket, számokat, kötőjeleket és alávonásokat tartalmazhat.',
+ 'alpha_num' => 'A(z) :attribute csak betűket és számokat tartalmazhat.',
+ 'array' => 'A(z) :attribute tömb kell legyen.',
'backup_codes' => 'A megadott kód érvénytelen, vagy már felhasználták.',
- 'before' => ':attribute dátumnak :date előttinek kell lennie.',
+ 'before' => 'A(z) :attribute objektumnak egy :date előtti dátumnak kell lennie.',
'between' => [
- 'numeric' => ':attribute értékének :min és :max között kell lennie.',
- 'file' => ':attribute értékének :min és :max kilobájt között kell lennie.',
- 'string' => ':attribute hosszának :min és :max karakter között kell lennie.',
- 'array' => ':attribute mennyiségének :min és :max elem között kell lennie.',
+ 'numeric' => 'A(z) :attribute értékének :min és :max között kell lennie.',
+ 'file' => 'A(z) :attribute értékének :min és :max kB között kell lennie.',
+ 'string' => 'A(z) :attribute hosszának :min és :max karakter között kell lennie.',
+ 'array' => 'A(z) :attribute tömbnek :min és :max közötti elemszámának kell lennie.',
],
- 'boolean' => ':attribute mezőnek igaznak vagy hamisnak kell lennie.',
- 'confirmed' => ':attribute megerősítés nem egyezik.',
- 'date' => ':attribute nem érvényes dátum.',
- 'date_format' => ':attribute nem egyezik :format formátummal.',
- 'different' => ':attribute és :other értékének különböznie kell.',
- 'digits' => ':attribute :digits számból kell álljon.',
- 'digits_between' => ':attribute hosszának :min és :max számjegy között kell lennie.',
- 'email' => ':attribute érvényes email cím kell legyen.',
- 'ends_with' => ':attribute attribútumnak a következők egyikével kell végződnie: :values',
- 'file' => 'A(z) :attribute érvényes fájlnak kell lennie.',
- 'filled' => ':attribute mező kötelező.',
+ 'boolean' => 'A(z) :attribute mezőnek igaznak vagy hamisnak kell lennie.',
+ 'confirmed' => 'A(z) :attribute megerősítés nem egyezik.',
+ 'date' => 'A(z) :attribute nem egy érvényes dátum.',
+ 'date_format' => 'A(z) :attribute nem egyezik a(z) :format formátummal.',
+ 'different' => 'A(z) :attribute és :other értékének különböznie kell.',
+ 'digits' => 'A(z) :attribute :digits számjegyből kell álljon.',
+ 'digits_between' => 'A(z) :attribute hosszának :min és :max számjegy között kell lennie.',
+ 'email' => 'A(z) :attribute érvényes email cím kell legyen.',
+ 'ends_with' => 'A(z) :attribute értékének a következők egyikével kell végződnie: :values',
+ 'file' => 'A(z) :attribute érvényes fájl kell legyen.',
+ 'filled' => 'A(z) :attribute mező kötelező.',
'gt' => [
- 'numeric' => ':attribute nagyobb kell, hogy legyen, mint :value.',
- 'file' => ':attribute nagyobb kell, hogy legyen, mint :value kilobájt.',
- 'string' => ':attribute nagyobb kell legyen mint :value karakter.',
- 'array' => ':attribute több, mint :value elemet kell, hogy tartalmazzon.',
+ 'numeric' => 'A(z) :attribute nagyobb kell, hogy legyen, mint :value.',
+ 'file' => 'A(z) :attribute nagyobb kell, hogy legyen, mint :value kB.',
+ 'string' => 'A(z) :attribute hosszabb kell legyen mint :value karakter.',
+ 'array' => 'A(z) :attribute több, mint :value elemet kell, hogy tartalmazzon.',
],
'gte' => [
- 'numeric' => ':attribute attribútumnak :value értéknél nagyobbnak vagy vele egyenlőnek kell lennie.',
- 'file' => 'A(z) :attribute mérete nem lehet kevesebb, mint :value kilobájt.',
- 'string' => 'A(z) :attribute nagyobbnak, vagy egyenlőnek kell lennie, mint a :value karakter.',
- 'array' => 'A(z) :attribute rendelkezzen :value vagy több elemmel.',
+ 'numeric' => 'A(z) :attribute számnak :value értéknél nagyobbnak vagy vele egyenlőnek kell lennie.',
+ 'file' => 'A(z) :attribute mérete nem lehet kevesebb, mint :value kB.',
+ 'string' => 'A(z) :attribute szövegnek legalább :value karakter hosszúnak kell lennie.',
+ 'array' => 'A(z) :attribute tömbnek :value vagy több elemmel kell rendelkeznie.',
],
'exists' => 'A kiválasztott :attribute érvénytelen.',
- 'image' => ':attribute kép kell legyen.',
- 'image_extension' => 'A :attribute kép kiterjesztése érvényes és támogatott kell legyen.',
+ 'image' => 'A(z) :attribute kép kell legyen.',
+ 'image_extension' => 'A(z) :attribute kép kiterjesztése érvényes és támogatott kell legyen.',
'in' => 'A kiválasztott :attribute érvénytelen.',
- 'integer' => ':attribute egész szám kell legyen.',
- 'ip' => ':attribute érvényes IP cím kell legyen.',
- 'ipv4' => 'A(z) :attribute érvényes IPv4 címnek kell lennie.',
- 'ipv6' => 'A(z) :attribute érvényes IPv6 címnek kell lennie.',
- 'json' => 'A(z) :attribute érvényes JSON stringnek kell lennie.',
+ 'integer' => 'A(z) :attribute egész szám kell legyen.',
+ 'ip' => 'A(z) :attribute érvényes IP cím kell legyen.',
+ 'ipv4' => 'A(z) :attribute érvényes IPv4 cím kell legyen.',
+ 'ipv6' => 'A(z) :attribute érvényes IPv6 cím kell legyen.',
+ 'json' => 'A(z) :attribute érvényes JSON szöveg kell legyen.',
'lt' => [
- 'numeric' => 'A(z) :attribute kisebb kell, hogy legyen, mint :value.',
- 'file' => 'A(z) :attribute kevesebbnek kell lennie, mint :value kilobájt.',
+ 'numeric' => 'A(z) :attribute szám kisebb kell, hogy legyen, mint :value.',
+ 'file' => 'A(z) :attribute fájlnak kisebbnek kell lennie, mint :value kB.',
'string' => 'A(z) :attribute rövidebb kell, hogy legyen, mint :value karakter.',
'array' => 'A(z) :attribute kevesebb, mint :value elemet kell, hogy tartalmazzon.',
],
@@ -69,47 +69,47 @@ return [
],
'max' => [
'numeric' => ':attribute nem lehet nagyobb mint :max.',
- 'file' => ':attribute nem lehet nagyobb mint :max kilobájt.',
- 'string' => ':attribute nem lehet nagyobb mint :max karakter.',
- 'array' => ':attribute mennyisége nem lehet több mint :max elem.',
+ 'file' => 'A(z) :attribute nem lehet nagyobb, mint :max kB.',
+ 'string' => 'A(z) :attribute nem lehet hosszabb, mint :max karakter.',
+ 'array' => 'A(z) :attribute nem tartalmazhat több, mint :max elemet.',
],
- 'mimes' => 'A :attribute típusa csak :values lehet.',
+ 'mimes' => 'A(z) :attribute típusa csak :values lehet.',
'min' => [
- 'numeric' => ':attribute legalább :min kell legyen.',
- 'file' => ':attribute legalább :min kilobájt kell legyen.',
- 'string' => ':attribute legalább :min karakter kell legyen.',
- 'array' => ':attribute legalább :min elem kell legyen.',
+ 'numeric' => 'A(z) :attribute legalább :min kell legyen.',
+ 'file' => 'A(z) :attribute legalább :min kB kell legyen.',
+ 'string' => 'A(z) :attribute legalább :min karakter kell legyen.',
+ 'array' => 'A(z) :attribute legalább :min elemet kell tartalmazzon.',
],
'not_in' => 'A kiválasztott :attribute érvénytelen.',
- 'not_regex' => ':attribute formátuma érvénytelen.',
- 'numeric' => ':attribute szám kell legyen.',
- 'regex' => ':attribute formátuma érvénytelen.',
- 'required' => ':attribute mező kötelező.',
- 'required_if' => ':attribute mező kötelező ha :other értéke :value.',
- 'required_with' => ':attribute mező kötelező ha :values be van állítva.',
- 'required_with_all' => ':attribute mező kötelező ha van :value.',
- 'required_without' => ':attribute mező kötelező ha :values nincs beállítva.',
- 'required_without_all' => ':attribute mező kötelező ha egyik :values sincs beállítva.',
- 'same' => ':attribute és :other értékének egyeznie kell.',
+ 'not_regex' => 'A(z) :attribute formátuma érvénytelen.',
+ 'numeric' => 'A(z) :attribute szám kell legyen.',
+ 'regex' => 'A(z) :attribute formátuma érvénytelen.',
+ 'required' => 'A(z) :attribute mező kötelező.',
+ 'required_if' => 'A(z) :attribute mező kötelező ha :other értéke :value.',
+ 'required_with' => 'A(z) :attribute mező kötelező ha :values be van állítva.',
+ 'required_with_all' => 'A(z) :attribute mező kötelező ha :values be van állítva.',
+ 'required_without' => 'A(z) :attribute mező kötelező ha :values nincs beállítva.',
+ 'required_without_all' => 'A(z) :attribute mező kötelező ha egyik :values sincs beállítva.',
+ 'same' => 'A(z) :attribute és :other értékének egyeznie kell.',
'safe_url' => 'Előfordulhat, hogy a megadott link nem biztonságos.',
'size' => [
- 'numeric' => ':attribute :size méretű kell legyen.',
- 'file' => ':attribute :size kilobájt méretű kell legyen.',
- 'string' => ':attribute :size karakter kell legyen.',
- 'array' => ':attribute : size elemet kell tartalmazzon.',
+ 'numeric' => 'A(z) :attribute :size méretű kell legyen.',
+ 'file' => 'A(z) :attribute :size kB méretű kell legyen.',
+ 'string' => 'A(z) :attribute :size karakter kell legyen.',
+ 'array' => 'A(z) :attribute :size elemet kell tartalmazzon.',
],
- 'string' => ':attribute karaktersorozatnak kell legyen.',
- 'timezone' => ':attribute érvényes zóna kell legyen.',
+ 'string' => 'A(z) :attribute szöveg kell legyen.',
+ 'timezone' => 'A(z) :attribute érvényes időzóna kell legyen.',
'totp' => 'A megadott kód érvénytelen vagy lejárt.',
- 'unique' => ':attribute már elkészült.',
- 'url' => ':attribute formátuma érvénytelen.',
- 'uploaded' => 'A fájlt nem lehet feltölteni. A kiszolgáló nem fogad el ilyen méretű fájlokat.',
+ 'unique' => 'A(z) :attribute már foglalt.',
+ 'url' => 'A(z) :attribute formátuma érvénytelen.',
+ 'uploaded' => 'A fájlt nem lehet feltölteni. A szerver nem fogad el ilyen méretű fájlokat.',
- 'zip_file' => 'The :attribute needs to reference a file within the ZIP.',
- 'zip_file_size' => 'The file :attribute must not exceed :size MB.',
- 'zip_file_mime' => 'The :attribute needs to reference a file of type :validTypes, found :foundType.',
- 'zip_model_expected' => 'Data object expected but ":type" found.',
- 'zip_unique' => 'The :attribute must be unique for the object type within the ZIP.',
+ 'zip_file' => 'A(z) :attribute egy a ZIP fájlban található fájlra kell, hogy hivatkozzon',
+ 'zip_file_size' => 'A(z) :attribute fájl nem haladhatja meg a :size MB méretet.',
+ 'zip_file_mime' => 'A(z) :attribute egy :validTypes típusú fájlra kell, hogy hivatkozzon, a :foundType helyett.',
+ 'zip_model_expected' => 'Adat objektum helyett ":type" lett találva.',
+ 'zip_unique' => 'A(z) :attribute egyedi kell hogy legyen a ZIP fájlban az adott objektum típushoz.',
// Custom validation lines
'custom' => [
diff --git a/lang/id/activities.php b/lang/id/activities.php
index 6e1583a94..db32fcf64 100644
--- a/lang/id/activities.php
+++ b/lang/id/activities.php
@@ -99,6 +99,8 @@ return [
'user_update_notification' => 'Pengguna berhasil diperbarui',
'user_delete' => 'pengguna yang dihapus',
'user_delete_notification' => 'Pengguna berhasil dihapus',
+ 'user_mfa_reset' => 'reset MFA for user',
+ 'user_mfa_reset_notification' => 'Multi-factor authentication methods reset',
// API Tokens
'api_token_create' => 'API token yang dibuat',
diff --git a/lang/id/auth.php b/lang/id/auth.php
index 6af60ca80..a5653ede6 100644
--- a/lang/id/auth.php
+++ b/lang/id/auth.php
@@ -8,6 +8,7 @@ return [
'failed' => 'Kredensial tidak cocok dengan catatan kami.',
'throttle' => 'Terlalu banyak upaya masuk. Silahkan mencoba lagi dalam :seconds detik.',
+ 'mfa_throttle' => 'Too many multi-factor verification attempts. Please try again in :seconds seconds.',
// Login & Register
'sign_up' => 'Daftar',
diff --git a/lang/id/entities.php b/lang/id/entities.php
index 2f9329925..a423ef39c 100644
--- a/lang/id/entities.php
+++ b/lang/id/entities.php
@@ -173,6 +173,7 @@ return [
'books_sort_desc' => 'Move chapters and pages within a book to reorganise its contents. Other books can be added which allows easy moving of chapters and pages between books. Optionally an auto sort rule can be set to automatically sort this book\'s contents upon changes.',
'books_sort_auto_sort' => 'Auto Sort Option',
'books_sort_auto_sort_active' => 'Auto Sort Active: :sortName',
+ 'books_sort_auto_sort_creation_hint' => 'Auto sort option rules can be created in the "Lists & Sorting" settings area by a user with the relevant permissions.',
'books_sort_named' => 'Sortir Buku :bookName',
'books_sort_name' => 'Diurutkan berdasarkan nama',
'books_sort_created' => 'Urutkan berdasarkan Tanggal Dibuat',
@@ -330,6 +331,9 @@ return [
// Editor Sidebar
'toggle_sidebar' => 'Toggle Sidebar',
+ 'page_contents' => 'Page Contents',
+ 'page_contents_none' => 'No headings were found in the page content.',
+ 'page_contents_info' => 'The contents menu is generated from any heading formats used in the page.',
'page_tags' => 'Halaman Tag',
'chapter_tags' => 'Bab Tag',
'book_tags' => 'Tag Buku',
diff --git a/lang/id/settings.php b/lang/id/settings.php
index 8bdd99e68..5d7853147 100644
--- a/lang/id/settings.php
+++ b/lang/id/settings.php
@@ -207,6 +207,7 @@ return [
'role_all' => 'Semua',
'role_own' => 'Sendiri',
'role_controlled_by_asset' => 'Dikendalikan oleh aset tempat mereka diunggah',
+ 'role_controlled_by_page_delete' => 'Controlled by page delete permissions',
'role_save' => 'Simpan Peran',
'role_users' => 'Peran berhasil diperbarui',
'role_users_none' => 'Saat ini tidak ada pengguna yang ditugaskan untuk peran ini',
@@ -263,6 +264,9 @@ return [
'users_mfa_desc' => 'Setup multi-factor authentication as an extra layer of security for your user account.',
'users_mfa_x_methods' => ':count method configured|:count methods configured',
'users_mfa_configure' => 'Configure Methods',
+ 'users_mfa_reset' => 'Reset Multi-Factor Authentication Methods',
+ 'users_mfa_reset_desc' => 'This will reset and clear all configured multi-factor authentication methods for this user. If multi-factor authentication is required by any of their roles, they\'ll be prompted to configure new methods on their next login.',
+ 'users_mfa_reset_confirm' => 'Are you sure you want to reset multi-factor authentication for this user?',
// API Tokens
'user_api_token_create' => 'Buat Token API',
@@ -363,6 +367,7 @@ return [
'sk' => 'Slovensky',
'sl' => 'Slovenščina',
'sv' => 'Svenska',
+ 'th' => 'ภาษาไทย',
'tr' => 'Türkçe',
'uk' => 'Українська',
'uz' => 'O‘zbekcha',
diff --git a/lang/is/activities.php b/lang/is/activities.php
index e70aa2567..7056e633c 100644
--- a/lang/is/activities.php
+++ b/lang/is/activities.php
@@ -99,6 +99,8 @@ return [
'user_update_notification' => 'Tókst að uppfæra notanda',
'user_delete' => 'eyddur notandi',
'user_delete_notification' => 'Tókst að eyða notanda',
+ 'user_mfa_reset' => 'reset MFA for user',
+ 'user_mfa_reset_notification' => 'Multi-factor authentication methods reset',
// API Tokens
'api_token_create' => 'API token búið til',
diff --git a/lang/is/auth.php b/lang/is/auth.php
index c5e7ce4f1..9b779aec7 100644
--- a/lang/is/auth.php
+++ b/lang/is/auth.php
@@ -8,6 +8,7 @@ return [
'failed' => 'Þeesi auðkenning er ekki á skrá.',
'throttle' => 'Of margar tilraunir til innskráningar. Reyndu aftur eftir :seconds sekúndur.',
+ 'mfa_throttle' => 'Too many multi-factor verification attempts. Please try again in :seconds seconds.',
// Login & Register
'sign_up' => 'Nýskrá',
diff --git a/lang/is/entities.php b/lang/is/entities.php
index 4308835c7..8735a18ae 100644
--- a/lang/is/entities.php
+++ b/lang/is/entities.php
@@ -173,6 +173,7 @@ return [
'books_sort_desc' => 'Move chapters and pages within a book to reorganise its contents. Other books can be added which allows easy moving of chapters and pages between books. Optionally an auto sort rule can be set to automatically sort this book\'s contents upon changes.',
'books_sort_auto_sort' => 'Auto Sort Option',
'books_sort_auto_sort_active' => 'Auto Sort Active: :sortName',
+ 'books_sort_auto_sort_creation_hint' => 'Auto sort option rules can be created in the "Lists & Sorting" settings area by a user with the relevant permissions.',
'books_sort_named' => 'Raða bók :bookName',
'books_sort_name' => 'Raða eftir nafni',
'books_sort_created' => 'Raða eftir skráningar dagsetningu',
@@ -330,6 +331,9 @@ return [
// Editor Sidebar
'toggle_sidebar' => 'Toggle Sidebar',
+ 'page_contents' => 'Page Contents',
+ 'page_contents_none' => 'No headings were found in the page content.',
+ 'page_contents_info' => 'The contents menu is generated from any heading formats used in the page.',
'page_tags' => 'Page Tags',
'chapter_tags' => 'Chapter Tags',
'book_tags' => 'Book Tags',
diff --git a/lang/is/settings.php b/lang/is/settings.php
index b1f21ac10..cabe31917 100644
--- a/lang/is/settings.php
+++ b/lang/is/settings.php
@@ -207,6 +207,7 @@ return [
'role_all' => 'Allt',
'role_own' => 'Eigin',
'role_controlled_by_asset' => 'Controlled by the asset they are uploaded to',
+ 'role_controlled_by_page_delete' => 'Controlled by page delete permissions',
'role_save' => 'Vista hlutverk',
'role_users' => 'Notendur í þessu hlutverki',
'role_users_none' => 'Engir notendur eru eins og er í þessu hlutverki',
@@ -263,6 +264,9 @@ return [
'users_mfa_desc' => 'Setup multi-factor authentication as an extra layer of security for your user account.',
'users_mfa_x_methods' => ':count method configured|:count methods configured',
'users_mfa_configure' => 'Configure Methods',
+ 'users_mfa_reset' => 'Reset Multi-Factor Authentication Methods',
+ 'users_mfa_reset_desc' => 'This will reset and clear all configured multi-factor authentication methods for this user. If multi-factor authentication is required by any of their roles, they\'ll be prompted to configure new methods on their next login.',
+ 'users_mfa_reset_confirm' => 'Are you sure you want to reset multi-factor authentication for this user?',
// API Tokens
'user_api_token_create' => 'Búa til API tóka',
@@ -363,6 +367,7 @@ return [
'sk' => 'Slovensky',
'sl' => 'Slovenščina',
'sv' => 'Svenska',
+ 'th' => 'ภาษาไทย',
'tr' => 'Türkçe',
'uk' => 'Українська',
'uz' => 'O‘zbekcha',
diff --git a/lang/it/activities.php b/lang/it/activities.php
index d682ccca6..e0dba5403 100644
--- a/lang/it/activities.php
+++ b/lang/it/activities.php
@@ -99,6 +99,8 @@ return [
'user_update_notification' => 'Utente aggiornato con successo',
'user_delete' => 'ha eliminato un utente',
'user_delete_notification' => 'Utente rimosso con successo',
+ 'user_mfa_reset' => 'resetta MFA per l\'utente',
+ 'user_mfa_reset_notification' => 'Metodi di autenticazione multi-fattore reimpostati',
// API Tokens
'api_token_create' => 'ha creato un token API',
diff --git a/lang/it/auth.php b/lang/it/auth.php
index 9191ecba7..3dd5e1ec6 100644
--- a/lang/it/auth.php
+++ b/lang/it/auth.php
@@ -8,6 +8,7 @@ return [
'failed' => 'Credenziali errate.',
'throttle' => 'Troppi tentativi di login. Riprova in :seconds secondi.',
+ 'mfa_throttle' => 'Troppi tentativi di verifica multi-fattore. Riprova tra :seconds secondi.',
// Login & Register
'sign_up' => 'Registrati',
diff --git a/lang/it/entities.php b/lang/it/entities.php
index eb9868973..89e1cd988 100644
--- a/lang/it/entities.php
+++ b/lang/it/entities.php
@@ -173,6 +173,7 @@ return [
'books_sort_desc' => 'Spostare i capitoli e le pagine di un libro per riorganizzarne il contenuto. Possono essere aggiunti altri libri che permettono di spostare facilmente capitoli e pagine tra i libri. Opzionalmente una regola di ordinamento automatico può essere impostata per ordinare automaticamente i contenuti di questo libro in caso di modifiche.',
'books_sort_auto_sort' => 'Opzione Ordinamento Automatico',
'books_sort_auto_sort_active' => 'Ordinamento Automatico Attivo: :sortName',
+ 'books_sort_auto_sort_creation_hint' => 'Auto sort option rules can be created in the "Lists & Sorting" settings area by a user with the relevant permissions.',
'books_sort_named' => 'Ordina il libro :bookName',
'books_sort_name' => 'Ordina per Nome',
'books_sort_created' => 'Ordina per Data di creazione',
@@ -330,6 +331,9 @@ return [
// Editor Sidebar
'toggle_sidebar' => 'Attiva/disattiva barra laterale',
+ 'page_contents' => 'Page Contents',
+ 'page_contents_none' => 'No headings were found in the page content.',
+ 'page_contents_info' => 'The contents menu is generated from any heading formats used in the page.',
'page_tags' => 'Tag pagina',
'chapter_tags' => 'Tag capitolo',
'book_tags' => 'Tag libro',
diff --git a/lang/it/settings.php b/lang/it/settings.php
index 2b5819b2a..3b8681840 100644
--- a/lang/it/settings.php
+++ b/lang/it/settings.php
@@ -207,6 +207,7 @@ return [
'role_all' => 'Tutti',
'role_own' => 'Propri',
'role_controlled_by_asset' => 'Controllato dall\'entità in cui sono caricati',
+ 'role_controlled_by_page_delete' => 'Controllato dai permessi di cancellazione della pagina',
'role_save' => 'Salva ruolo',
'role_users' => 'Utenti in questo ruolo',
'role_users_none' => 'Nessun utente assegnato a questo ruolo',
@@ -263,6 +264,9 @@ return [
'users_mfa_desc' => 'Imposta l\'autenticazione multi-fattore come misura di sicurezza aggiuntiva per il tuo account.',
'users_mfa_x_methods' => ':count metodo configurato|:count metodi configurati',
'users_mfa_configure' => 'Configura metodi',
+ 'users_mfa_reset' => 'Reimposta Metodi Di Autenticazione Multi-Fattore',
+ 'users_mfa_reset_desc' => 'Questo ripristinerà e cancellerà tutti i metodi di autenticazione multi-fattore configurati per questo utente. Se l\'autenticazione multi-fattore è richiesta da uno qualsiasi dei loro ruoli, sarà richiesto loro di configurare nuovi metodi al loro prossimo accesso.',
+ 'users_mfa_reset_confirm' => 'Sei sicuro di voler resettare l\'autenticazione multi-fattore per questo utente?',
// API Tokens
'user_api_token_create' => 'Crea token API',
@@ -363,6 +367,7 @@ return [
'sk' => 'Sloveno',
'sl' => 'Sloveno',
'sv' => 'Svedese',
+ 'th' => 'ภาษาไทย',
'tr' => 'Turco',
'uk' => 'Ucraino',
'uz' => 'O‘zbekcha',
diff --git a/lang/ja/activities.php b/lang/ja/activities.php
index 6f55098bb..25ded1d49 100644
--- a/lang/ja/activities.php
+++ b/lang/ja/activities.php
@@ -99,6 +99,8 @@ return [
'user_update_notification' => 'ユーザーを更新しました',
'user_delete' => 'がユーザを削除',
'user_delete_notification' => 'ユーザーを削除しました',
+ 'user_mfa_reset' => 'reset MFA for user',
+ 'user_mfa_reset_notification' => 'Multi-factor authentication methods reset',
// API Tokens
'api_token_create' => 'がAPIトークンを作成',
diff --git a/lang/ja/auth.php b/lang/ja/auth.php
index 077c31ac8..b4ee5f4ac 100644
--- a/lang/ja/auth.php
+++ b/lang/ja/auth.php
@@ -8,6 +8,7 @@ return [
'failed' => 'この資格情報は登録されていません。',
'throttle' => 'ログイン試行回数が制限を超えました。:seconds秒後に再試行してください。',
+ 'mfa_throttle' => 'Too many multi-factor verification attempts. Please try again in :seconds seconds.',
// Login & Register
'sign_up' => '新規登録',
diff --git a/lang/ja/entities.php b/lang/ja/entities.php
index 551a2e496..eaaddf5b3 100644
--- a/lang/ja/entities.php
+++ b/lang/ja/entities.php
@@ -173,6 +173,7 @@ return [
'books_sort_desc' => 'ブック内のチャプタおよびページを移動して内容を再編成できます。他のブックを並べて、ブック間でチャプタやページを簡単に移動することもできます。オプションで自動ソートルールを設定すると、変更時にブックの内容を自動的にソートすることができます。',
'books_sort_auto_sort' => '自動ソートオプション',
'books_sort_auto_sort_active' => '自動ソート有効: :sortName',
+ 'books_sort_auto_sort_creation_hint' => 'Auto sort option rules can be created in the "Lists & Sorting" settings area by a user with the relevant permissions.',
'books_sort_named' => 'ブック「:bookName」を並べ替え',
'books_sort_name' => '名前で並べ替え',
'books_sort_created' => '作成日で並べ替え',
@@ -331,6 +332,9 @@ return [
// Editor Sidebar
'toggle_sidebar' => 'サイドバーの切り替え',
+ 'page_contents' => 'Page Contents',
+ 'page_contents_none' => 'No headings were found in the page content.',
+ 'page_contents_info' => 'The contents menu is generated from any heading formats used in the page.',
'page_tags' => 'タグ',
'chapter_tags' => 'チャプターのタグ',
'book_tags' => 'ブックのタグ',
diff --git a/lang/ja/settings.php b/lang/ja/settings.php
index 378e3a774..95f33f340 100644
--- a/lang/ja/settings.php
+++ b/lang/ja/settings.php
@@ -207,6 +207,7 @@ return [
'role_all' => '全て',
'role_own' => '自身',
'role_controlled_by_asset' => 'このアセットに対し、右記の操作を許可:',
+ 'role_controlled_by_page_delete' => 'Controlled by page delete permissions',
'role_save' => '役割を保存',
'role_users' => 'この役割を持つユーザー',
'role_users_none' => 'この役割が付与されたユーザーはいません',
@@ -263,6 +264,9 @@ return [
'users_mfa_desc' => 'アカウントのセキュリティを強化するために、多要素認証を設定してください。',
'users_mfa_x_methods' => ':count個の手段が設定されています|:count個の手段が設定されています',
'users_mfa_configure' => '手段を設定',
+ 'users_mfa_reset' => 'Reset Multi-Factor Authentication Methods',
+ 'users_mfa_reset_desc' => 'This will reset and clear all configured multi-factor authentication methods for this user. If multi-factor authentication is required by any of their roles, they\'ll be prompted to configure new methods on their next login.',
+ 'users_mfa_reset_confirm' => 'Are you sure you want to reset multi-factor authentication for this user?',
// API Tokens
'user_api_token_create' => 'APIトークンの作成',
@@ -363,6 +367,7 @@ return [
'sk' => 'Slovensky',
'sl' => 'Slovenščina',
'sv' => 'Svenska',
+ 'th' => 'ภาษาไทย',
'tr' => 'Türkçe',
'uk' => 'Українська',
'uz' => 'O‘zbekcha',
diff --git a/lang/ka/activities.php b/lang/ka/activities.php
index 35730fd77..07304a562 100644
--- a/lang/ka/activities.php
+++ b/lang/ka/activities.php
@@ -99,6 +99,8 @@ return [
'user_update_notification' => 'User successfully updated',
'user_delete' => 'deleted user',
'user_delete_notification' => 'User successfully removed',
+ 'user_mfa_reset' => 'reset MFA for user',
+ 'user_mfa_reset_notification' => 'Multi-factor authentication methods reset',
// API Tokens
'api_token_create' => 'created API token',
diff --git a/lang/ka/auth.php b/lang/ka/auth.php
index 57f0cb5c6..47be4ea72 100644
--- a/lang/ka/auth.php
+++ b/lang/ka/auth.php
@@ -8,6 +8,7 @@ return [
'failed' => 'These credentials do not match our records.',
'throttle' => 'Too many login attempts. Please try again in :seconds seconds.',
+ 'mfa_throttle' => 'Too many multi-factor verification attempts. Please try again in :seconds seconds.',
// Login & Register
'sign_up' => 'Sign up',
diff --git a/lang/ka/entities.php b/lang/ka/entities.php
index 74c50be3b..58c00ec4b 100644
--- a/lang/ka/entities.php
+++ b/lang/ka/entities.php
@@ -173,6 +173,7 @@ return [
'books_sort_desc' => 'Move chapters and pages within a book to reorganise its contents. Other books can be added which allows easy moving of chapters and pages between books. Optionally an auto sort rule can be set to automatically sort this book\'s contents upon changes.',
'books_sort_auto_sort' => 'Auto Sort Option',
'books_sort_auto_sort_active' => 'Auto Sort Active: :sortName',
+ 'books_sort_auto_sort_creation_hint' => 'Auto sort option rules can be created in the "Lists & Sorting" settings area by a user with the relevant permissions.',
'books_sort_named' => 'Sort Book :bookName',
'books_sort_name' => 'Sort by Name',
'books_sort_created' => 'Sort by Created Date',
@@ -330,6 +331,9 @@ return [
// Editor Sidebar
'toggle_sidebar' => 'Toggle Sidebar',
+ 'page_contents' => 'Page Contents',
+ 'page_contents_none' => 'No headings were found in the page content.',
+ 'page_contents_info' => 'The contents menu is generated from any heading formats used in the page.',
'page_tags' => 'Page Tags',
'chapter_tags' => 'Chapter Tags',
'book_tags' => 'Book Tags',
diff --git a/lang/ka/settings.php b/lang/ka/settings.php
index c4d1eb136..d03024a89 100644
--- a/lang/ka/settings.php
+++ b/lang/ka/settings.php
@@ -207,6 +207,7 @@ return [
'role_all' => 'All',
'role_own' => 'Own',
'role_controlled_by_asset' => 'Controlled by the asset they are uploaded to',
+ 'role_controlled_by_page_delete' => 'Controlled by page delete permissions',
'role_save' => 'Save Role',
'role_users' => 'Users in this role',
'role_users_none' => 'No users are currently assigned to this role',
@@ -263,6 +264,9 @@ return [
'users_mfa_desc' => 'Setup multi-factor authentication as an extra layer of security for your user account.',
'users_mfa_x_methods' => ':count method configured|:count methods configured',
'users_mfa_configure' => 'Configure Methods',
+ 'users_mfa_reset' => 'Reset Multi-Factor Authentication Methods',
+ 'users_mfa_reset_desc' => 'This will reset and clear all configured multi-factor authentication methods for this user. If multi-factor authentication is required by any of their roles, they\'ll be prompted to configure new methods on their next login.',
+ 'users_mfa_reset_confirm' => 'Are you sure you want to reset multi-factor authentication for this user?',
// API Tokens
'user_api_token_create' => 'Create API Token',
@@ -363,6 +367,7 @@ return [
'sk' => 'Slovensky',
'sl' => 'Slovenščina',
'sv' => 'Svenska',
+ 'th' => 'ภาษาไทย',
'tr' => 'Türkçe',
'uk' => 'Українська',
'uz' => 'O‘zbekcha',
diff --git a/lang/ko/activities.php b/lang/ko/activities.php
index 061b7fb1e..e011523fa 100644
--- a/lang/ko/activities.php
+++ b/lang/ko/activities.php
@@ -99,6 +99,8 @@ return [
'user_update_notification' => '사용자가 업데이트되었습니다',
'user_delete' => '사용자 삭제',
'user_delete_notification' => '사용자가 삭제되었습니다',
+ 'user_mfa_reset' => 'reset MFA for user',
+ 'user_mfa_reset_notification' => 'Multi-factor authentication methods reset',
// API Tokens
'api_token_create' => '생성된 API 토큰',
diff --git a/lang/ko/auth.php b/lang/ko/auth.php
index af9129f14..9e93c8846 100644
--- a/lang/ko/auth.php
+++ b/lang/ko/auth.php
@@ -8,6 +8,7 @@ return [
'failed' => '자격 증명이 기록과 일치하지 않습니다.',
'throttle' => '로그인 시도가 너무 많습니다. :seconds초 후에 다시 시도해주세요.',
+ 'mfa_throttle' => 'Too many multi-factor verification attempts. Please try again in :seconds seconds.',
// Login & Register
'sign_up' => '가입',
diff --git a/lang/ko/entities.php b/lang/ko/entities.php
index 44809d99f..838aebd7a 100644
--- a/lang/ko/entities.php
+++ b/lang/ko/entities.php
@@ -173,6 +173,7 @@ return [
'books_sort_desc' => '책 내의 챕터와 페이지를 이동하여 콘텐츠를 재구성할 수 있습니다. 다른 책들을 추가하여 책 간의 챕터와 페이지를 쉽게 이동할 수 있습니다. 선택적으로 자동 정렬 규칙을 설정하여 변경 시 이 책의 콘텐츠를 자동으로 정렬할 수 있습니다.',
'books_sort_auto_sort' => '자동 정렬 옵션',
'books_sort_auto_sort_active' => '현재 설정된 자동 정렬: :sortName',
+ 'books_sort_auto_sort_creation_hint' => 'Auto sort option rules can be created in the "Lists & Sorting" settings area by a user with the relevant permissions.',
'books_sort_named' => ':bookName 정렬',
'books_sort_name' => '제목',
'books_sort_created' => '만든 날짜',
@@ -330,6 +331,9 @@ return [
// Editor Sidebar
'toggle_sidebar' => '사이드바 토글',
+ 'page_contents' => 'Page Contents',
+ 'page_contents_none' => 'No headings were found in the page content.',
+ 'page_contents_info' => 'The contents menu is generated from any heading formats used in the page.',
'page_tags' => '페이지 태그',
'chapter_tags' => '장 태그',
'book_tags' => '책 태그',
diff --git a/lang/ko/settings.php b/lang/ko/settings.php
index 97af673c6..90d501a7c 100644
--- a/lang/ko/settings.php
+++ b/lang/ko/settings.php
@@ -207,6 +207,7 @@ return [
'role_all' => '모든 항목',
'role_own' => '직접 만든 항목',
'role_controlled_by_asset' => '저마다 다름',
+ 'role_controlled_by_page_delete' => 'Controlled by page delete permissions',
'role_save' => '저장',
'role_users' => '이 역할을 가진 사용자들',
'role_users_none' => '역할이 부여된 사용자가 없습니다.',
@@ -263,6 +264,9 @@ return [
'users_mfa_desc' => '추가 보안 계층으로 다중 인증을 설정합니다.',
'users_mfa_x_methods' => ':count 설정함|:count 설정함',
'users_mfa_configure' => '설정',
+ 'users_mfa_reset' => 'Reset Multi-Factor Authentication Methods',
+ 'users_mfa_reset_desc' => 'This will reset and clear all configured multi-factor authentication methods for this user. If multi-factor authentication is required by any of their roles, they\'ll be prompted to configure new methods on their next login.',
+ 'users_mfa_reset_confirm' => 'Are you sure you want to reset multi-factor authentication for this user?',
// API Tokens
'user_api_token_create' => 'API 토큰 만들기',
@@ -363,6 +367,7 @@ return [
'sk' => 'Slovensky',
'sl' => 'Slovenščina',
'sv' => 'Svenska',
+ 'th' => 'ภาษาไทย',
'tr' => 'Türkçe',
'uk' => 'Українська',
'uz' => 'O‘zbekcha',
diff --git a/lang/ku/activities.php b/lang/ku/activities.php
index 4362fc029..e9344a3d4 100644
--- a/lang/ku/activities.php
+++ b/lang/ku/activities.php
@@ -99,6 +99,8 @@ return [
'user_update_notification' => 'User successfully updated',
'user_delete' => 'deleted user',
'user_delete_notification' => 'User successfully removed',
+ 'user_mfa_reset' => 'reset MFA for user',
+ 'user_mfa_reset_notification' => 'Multi-factor authentication methods reset',
// API Tokens
'api_token_create' => 'created API token',
diff --git a/lang/ku/auth.php b/lang/ku/auth.php
index 369e06f93..5597683ae 100644
--- a/lang/ku/auth.php
+++ b/lang/ku/auth.php
@@ -8,6 +8,7 @@ return [
'failed' => 'ئەم بەکارهێنەرە نەدۆزرایەوە.',
'throttle' => 'Too many login attempts. Please try again in :seconds seconds.',
+ 'mfa_throttle' => 'Too many multi-factor verification attempts. Please try again in :seconds seconds.',
// Login & Register
'sign_up' => 'Sign up',
diff --git a/lang/ku/entities.php b/lang/ku/entities.php
index 74c50be3b..58c00ec4b 100644
--- a/lang/ku/entities.php
+++ b/lang/ku/entities.php
@@ -173,6 +173,7 @@ return [
'books_sort_desc' => 'Move chapters and pages within a book to reorganise its contents. Other books can be added which allows easy moving of chapters and pages between books. Optionally an auto sort rule can be set to automatically sort this book\'s contents upon changes.',
'books_sort_auto_sort' => 'Auto Sort Option',
'books_sort_auto_sort_active' => 'Auto Sort Active: :sortName',
+ 'books_sort_auto_sort_creation_hint' => 'Auto sort option rules can be created in the "Lists & Sorting" settings area by a user with the relevant permissions.',
'books_sort_named' => 'Sort Book :bookName',
'books_sort_name' => 'Sort by Name',
'books_sort_created' => 'Sort by Created Date',
@@ -330,6 +331,9 @@ return [
// Editor Sidebar
'toggle_sidebar' => 'Toggle Sidebar',
+ 'page_contents' => 'Page Contents',
+ 'page_contents_none' => 'No headings were found in the page content.',
+ 'page_contents_info' => 'The contents menu is generated from any heading formats used in the page.',
'page_tags' => 'Page Tags',
'chapter_tags' => 'Chapter Tags',
'book_tags' => 'Book Tags',
diff --git a/lang/ku/settings.php b/lang/ku/settings.php
index c4d1eb136..d03024a89 100644
--- a/lang/ku/settings.php
+++ b/lang/ku/settings.php
@@ -207,6 +207,7 @@ return [
'role_all' => 'All',
'role_own' => 'Own',
'role_controlled_by_asset' => 'Controlled by the asset they are uploaded to',
+ 'role_controlled_by_page_delete' => 'Controlled by page delete permissions',
'role_save' => 'Save Role',
'role_users' => 'Users in this role',
'role_users_none' => 'No users are currently assigned to this role',
@@ -263,6 +264,9 @@ return [
'users_mfa_desc' => 'Setup multi-factor authentication as an extra layer of security for your user account.',
'users_mfa_x_methods' => ':count method configured|:count methods configured',
'users_mfa_configure' => 'Configure Methods',
+ 'users_mfa_reset' => 'Reset Multi-Factor Authentication Methods',
+ 'users_mfa_reset_desc' => 'This will reset and clear all configured multi-factor authentication methods for this user. If multi-factor authentication is required by any of their roles, they\'ll be prompted to configure new methods on their next login.',
+ 'users_mfa_reset_confirm' => 'Are you sure you want to reset multi-factor authentication for this user?',
// API Tokens
'user_api_token_create' => 'Create API Token',
@@ -363,6 +367,7 @@ return [
'sk' => 'Slovensky',
'sl' => 'Slovenščina',
'sv' => 'Svenska',
+ 'th' => 'ภาษาไทย',
'tr' => 'Türkçe',
'uk' => 'Українська',
'uz' => 'O‘zbekcha',
diff --git a/lang/lt/activities.php b/lang/lt/activities.php
index a808171bb..0d08d41ea 100644
--- a/lang/lt/activities.php
+++ b/lang/lt/activities.php
@@ -99,6 +99,8 @@ return [
'user_update_notification' => 'User successfully updated',
'user_delete' => 'deleted user',
'user_delete_notification' => 'User successfully removed',
+ 'user_mfa_reset' => 'reset MFA for user',
+ 'user_mfa_reset_notification' => 'Multi-factor authentication methods reset',
// API Tokens
'api_token_create' => 'created API token',
diff --git a/lang/lt/auth.php b/lang/lt/auth.php
index a2f7f4668..8a91f2104 100644
--- a/lang/lt/auth.php
+++ b/lang/lt/auth.php
@@ -8,6 +8,7 @@ return [
'failed' => 'Šie įgaliojimai neatitinka mūsų įrašų.',
'throttle' => 'Per daug prisijungimo bandymų. Prašome pabandyti dar kartą po :seconds sekundžių.',
+ 'mfa_throttle' => 'Too many multi-factor verification attempts. Please try again in :seconds seconds.',
// Login & Register
'sign_up' => 'Užsiregistruoti',
diff --git a/lang/lt/entities.php b/lang/lt/entities.php
index 6c4472d85..6bf86635a 100644
--- a/lang/lt/entities.php
+++ b/lang/lt/entities.php
@@ -173,6 +173,7 @@ return [
'books_sort_desc' => 'Move chapters and pages within a book to reorganise its contents. Other books can be added which allows easy moving of chapters and pages between books. Optionally an auto sort rule can be set to automatically sort this book\'s contents upon changes.',
'books_sort_auto_sort' => 'Auto Sort Option',
'books_sort_auto_sort_active' => 'Auto Sort Active: :sortName',
+ 'books_sort_auto_sort_creation_hint' => 'Auto sort option rules can be created in the "Lists & Sorting" settings area by a user with the relevant permissions.',
'books_sort_named' => 'Rūšiuoti knygą :bookName',
'books_sort_name' => 'Rūšiuoti pagal vardą',
'books_sort_created' => 'Rūšiuoti pagal sukūrimo datą',
@@ -330,6 +331,9 @@ return [
// Editor Sidebar
'toggle_sidebar' => 'Toggle Sidebar',
+ 'page_contents' => 'Page Contents',
+ 'page_contents_none' => 'No headings were found in the page content.',
+ 'page_contents_info' => 'The contents menu is generated from any heading formats used in the page.',
'page_tags' => 'Puslapio žymos',
'chapter_tags' => 'Skyriaus žymos',
'book_tags' => 'Knygos žymos',
diff --git a/lang/lt/settings.php b/lang/lt/settings.php
index f797e567e..96ee2beba 100644
--- a/lang/lt/settings.php
+++ b/lang/lt/settings.php
@@ -207,6 +207,7 @@ return [
'role_all' => 'Visi',
'role_own' => 'Nuosavi',
'role_controlled_by_asset' => 'Kontroliuojami nuosavybės, į kurią yra įkelti',
+ 'role_controlled_by_page_delete' => 'Controlled by page delete permissions',
'role_save' => 'Išsaugoti vaidmenį',
'role_users' => 'Naudotojai šiame vaidmenyje',
'role_users_none' => 'Šiuo metu prie šio vaidmens nėra priskirta naudotojų',
@@ -263,6 +264,9 @@ return [
'users_mfa_desc' => 'Setup multi-factor authentication as an extra layer of security for your user account.',
'users_mfa_x_methods' => ':count method configured|:count methods configured',
'users_mfa_configure' => 'Configure Methods',
+ 'users_mfa_reset' => 'Reset Multi-Factor Authentication Methods',
+ 'users_mfa_reset_desc' => 'This will reset and clear all configured multi-factor authentication methods for this user. If multi-factor authentication is required by any of their roles, they\'ll be prompted to configure new methods on their next login.',
+ 'users_mfa_reset_confirm' => 'Are you sure you want to reset multi-factor authentication for this user?',
// API Tokens
'user_api_token_create' => 'Sukurti API sąsajos prieigos raktą',
@@ -363,6 +367,7 @@ return [
'sk' => 'Slovensky',
'sl' => 'Slovenščina',
'sv' => 'Svenska',
+ 'th' => 'ภาษาไทย',
'tr' => 'Türkçe',
'uk' => 'Українська',
'uz' => 'O‘zbekcha',
diff --git a/lang/lv/activities.php b/lang/lv/activities.php
index 38d9ae217..8f9025170 100644
--- a/lang/lv/activities.php
+++ b/lang/lv/activities.php
@@ -99,6 +99,8 @@ return [
'user_update_notification' => 'Lietotājs veiksmīgi atjaunināts',
'user_delete' => 'dzēsa lietotāju',
'user_delete_notification' => 'Lietotājs veiksmīgi dzēsts',
+ 'user_mfa_reset' => 'reset MFA for user',
+ 'user_mfa_reset_notification' => 'Multi-factor authentication methods reset',
// API Tokens
'api_token_create' => 'izveidoja API žetonu',
diff --git a/lang/lv/auth.php b/lang/lv/auth.php
index 71b92ac01..462ce110f 100644
--- a/lang/lv/auth.php
+++ b/lang/lv/auth.php
@@ -8,6 +8,7 @@ return [
'failed' => 'Šie reģistrācijas dati neatbilst mūsu ierakstiem.',
'throttle' => 'Pārāk daudz pieteikšanās mēģinājumu. Lūdzu, mēģiniet vēlreiz pēc :seconds seconds.',
+ 'mfa_throttle' => 'Too many multi-factor verification attempts. Please try again in :seconds seconds.',
// Login & Register
'sign_up' => 'Reģistrēties',
diff --git a/lang/lv/entities.php b/lang/lv/entities.php
index 5f921048e..dccab4bd1 100644
--- a/lang/lv/entities.php
+++ b/lang/lv/entities.php
@@ -173,6 +173,7 @@ return [
'books_sort_desc' => 'Move chapters and pages within a book to reorganise its contents. Other books can be added which allows easy moving of chapters and pages between books. Optionally an auto sort rule can be set to automatically sort this book\'s contents upon changes.',
'books_sort_auto_sort' => 'Auto Sort Option',
'books_sort_auto_sort_active' => 'Auto Sort Active: :sortName',
+ 'books_sort_auto_sort_creation_hint' => 'Auto sort option rules can be created in the "Lists & Sorting" settings area by a user with the relevant permissions.',
'books_sort_named' => 'Kārtot grāmatu :bookName',
'books_sort_name' => 'Kārtot pēc nosaukuma',
'books_sort_created' => 'Kārtot pēc izveidošanas datuma',
@@ -330,6 +331,9 @@ return [
// Editor Sidebar
'toggle_sidebar' => 'Pārslēgt sānjoslu',
+ 'page_contents' => 'Page Contents',
+ 'page_contents_none' => 'No headings were found in the page content.',
+ 'page_contents_info' => 'The contents menu is generated from any heading formats used in the page.',
'page_tags' => 'Lapas birkas',
'chapter_tags' => 'Nodaļas birkas',
'book_tags' => 'Grāmatas birkas',
diff --git a/lang/lv/settings.php b/lang/lv/settings.php
index 9dc6bf402..886e0ef0a 100644
--- a/lang/lv/settings.php
+++ b/lang/lv/settings.php
@@ -207,6 +207,7 @@ return [
'role_all' => 'Visi',
'role_own' => 'Savi',
'role_controlled_by_asset' => 'Kontrolē resurss, uz ko tie ir augšupielādēti',
+ 'role_controlled_by_page_delete' => 'Controlled by page delete permissions',
'role_save' => 'Saglabāt grupu',
'role_users' => 'Lietotāji šajā grupā',
'role_users_none' => 'Pagaidām neviens lietotājs nav pievienots šai grupai',
@@ -263,6 +264,9 @@ return [
'users_mfa_desc' => 'Iestati vairākfaktoru autentifikāciju kā papildus drošības līmeni tavam lietotāja kontam.',
'users_mfa_x_methods' => ':count metode iestatīta|:count metodes iestatītas',
'users_mfa_configure' => 'Iestatīt metodes',
+ 'users_mfa_reset' => 'Reset Multi-Factor Authentication Methods',
+ 'users_mfa_reset_desc' => 'This will reset and clear all configured multi-factor authentication methods for this user. If multi-factor authentication is required by any of their roles, they\'ll be prompted to configure new methods on their next login.',
+ 'users_mfa_reset_confirm' => 'Are you sure you want to reset multi-factor authentication for this user?',
// API Tokens
'user_api_token_create' => 'Izveidot API žetonu',
@@ -363,6 +367,7 @@ return [
'sk' => 'Slovensky',
'sl' => 'Slovenščina',
'sv' => 'Svenska',
+ 'th' => 'ภาษาไทย',
'tr' => 'Türkçe',
'uk' => 'Українська',
'uz' => 'O‘zbekcha',
diff --git a/lang/nb/activities.php b/lang/nb/activities.php
index fd4de5321..771f5438b 100644
--- a/lang/nb/activities.php
+++ b/lang/nb/activities.php
@@ -100,6 +100,8 @@ return [
'user_update_notification' => 'Brukeren ble oppdatert',
'user_delete' => 'slettet bruker',
'user_delete_notification' => 'Brukeren ble fjernet',
+ 'user_mfa_reset' => 'reset MFA for user',
+ 'user_mfa_reset_notification' => 'Multi-factor authentication methods reset',
// API Tokens
'api_token_create' => 'opprettet API-nøkkel',
diff --git a/lang/nb/auth.php b/lang/nb/auth.php
index 125e6daf5..f345f691a 100644
--- a/lang/nb/auth.php
+++ b/lang/nb/auth.php
@@ -8,6 +8,7 @@ return [
'failed' => 'Disse detaljene samsvarer ikke med det vi har på bok.',
'throttle' => 'For mange forsøk, prøv igjen om :seconds sekunder.',
+ 'mfa_throttle' => 'Too many multi-factor verification attempts. Please try again in :seconds seconds.',
// Login & Register
'sign_up' => 'Registrer deg',
diff --git a/lang/nb/entities.php b/lang/nb/entities.php
index cf0fdffde..0e9070e53 100644
--- a/lang/nb/entities.php
+++ b/lang/nb/entities.php
@@ -173,6 +173,7 @@ return [
'books_sort_desc' => 'Flytt kapitler og sider innen en bok for å reorganisere innholdet. Andre bøker kan legges til, noe som gjør det enkelt å flytte kapitler og sider mellom bøkene. Valgfritt kan en automatisk sorteringsregel settes for å automatisk sortere innholdet i denne boken ved endringer.',
'books_sort_auto_sort' => 'Automatisk sorteringsalternativ',
'books_sort_auto_sort_active' => 'Automatisk sortering aktiv: :sortName',
+ 'books_sort_auto_sort_creation_hint' => 'Auto sort option rules can be created in the "Lists & Sorting" settings area by a user with the relevant permissions.',
'books_sort_named' => 'Omorganisér :bookName (bok)',
'books_sort_name' => 'Sorter på navn',
'books_sort_created' => 'Sorter på opprettet dato',
@@ -330,6 +331,9 @@ return [
// Editor Sidebar
'toggle_sidebar' => 'Bytt sidestolpe',
+ 'page_contents' => 'Page Contents',
+ 'page_contents_none' => 'No headings were found in the page content.',
+ 'page_contents_info' => 'The contents menu is generated from any heading formats used in the page.',
'page_tags' => 'Sidemerker',
'chapter_tags' => 'Kapittelmerker',
'book_tags' => 'Bokmerker',
diff --git a/lang/nb/settings.php b/lang/nb/settings.php
index 5fcaaaca6..1cc5d8e02 100644
--- a/lang/nb/settings.php
+++ b/lang/nb/settings.php
@@ -207,6 +207,7 @@ return [
'role_all' => 'Alle',
'role_own' => 'Egne',
'role_controlled_by_asset' => 'Kontrollert av eiendelen de er lastet opp til',
+ 'role_controlled_by_page_delete' => 'Controlled by page delete permissions',
'role_save' => 'Lagre rolle',
'role_users' => 'Kontoholdere med denne rollen',
'role_users_none' => 'Ingen kontoholdere er gitt denne rollen',
@@ -263,6 +264,9 @@ return [
'users_mfa_desc' => 'Konfigurer flerfaktorautentisering som et ekstra lag med sikkerhet for din konto.',
'users_mfa_x_methods' => ':count metode konfigurert|:count metoder konfigurert',
'users_mfa_configure' => 'Konfigurer metoder',
+ 'users_mfa_reset' => 'Reset Multi-Factor Authentication Methods',
+ 'users_mfa_reset_desc' => 'This will reset and clear all configured multi-factor authentication methods for this user. If multi-factor authentication is required by any of their roles, they\'ll be prompted to configure new methods on their next login.',
+ 'users_mfa_reset_confirm' => 'Are you sure you want to reset multi-factor authentication for this user?',
// API Tokens
'user_api_token_create' => 'Opprett API-nøkkel',
@@ -363,6 +367,7 @@ return [
'sk' => 'Slovensky',
'sl' => 'Slovenščina',
'sv' => 'Svenska',
+ 'th' => 'ภาษาไทย',
'tr' => 'Türkçe',
'uk' => 'Українська',
'uz' => 'O‘zbekcha',
diff --git a/lang/ne/activities.php b/lang/ne/activities.php
index 4b4edf7be..24c2b948a 100644
--- a/lang/ne/activities.php
+++ b/lang/ne/activities.php
@@ -99,6 +99,8 @@ return [
'user_update_notification' => 'प्रयोगकर्ता सफलतापूर्वक अद्यावधिक गरियो',
'user_delete' => 'प्रयोगकर्ता हटाइयो',
'user_delete_notification' => 'प्रयोगकर्ता सफलतापूर्वक हटाइयो',
+ 'user_mfa_reset' => 'reset MFA for user',
+ 'user_mfa_reset_notification' => 'Multi-factor authentication methods reset',
// API Tokens
'api_token_create' => 'API टोकन सिर्जना गरियो',
diff --git a/lang/ne/auth.php b/lang/ne/auth.php
index cd875a226..378f2dea2 100644
--- a/lang/ne/auth.php
+++ b/lang/ne/auth.php
@@ -8,6 +8,7 @@ return [
'failed' => 'यी प्रमाणिकरण जानकारी हाम्रो अभिलेखसँग मेल खाँदैन।',
'throttle' => 'लगइन प्रयासहरूको संख्या धेरै भएको छ। कृपया :seconds सेकेन्ड पछि पुनः प्रयास गर्नुहोस्।',
+ 'mfa_throttle' => 'Too many multi-factor verification attempts. Please try again in :seconds seconds.',
// Login & Register
'sign_up' => 'साइन अप गर्नुहोस्',
diff --git a/lang/ne/entities.php b/lang/ne/entities.php
index 88b202dee..f51c265c5 100644
--- a/lang/ne/entities.php
+++ b/lang/ne/entities.php
@@ -173,6 +173,7 @@ return [
'books_sort_desc' => 'पुस्तकमा अध्यायहरू र पृष्ठहरूलाई पुनः व्यवस्थित गर्नका लागि सार्नुहोस्। अन्य पुस्तकहरू थप्न सकिन्छ जसले अध्याय र पृष्ठहरूलाई पुस्तकहरू बीच सजिलै सर्न मद्दत गर्दछ। वैकल्पिक रूपमा एक स्वचालित वर्गीकरण नियम सेट गर्न सकिन्छ जसले पुस्तकको सामग्रीहरू परिवर्तन भएपछि स्वत: वर्गीकृत गर्छ।',
'books_sort_auto_sort' => 'स्वचालित वर्गीकरण विकल्प',
'books_sort_auto_sort_active' => 'स्वचालित वर्गीकरण सक्रिय: :sortName',
+ 'books_sort_auto_sort_creation_hint' => 'Auto sort option rules can be created in the "Lists & Sorting" settings area by a user with the relevant permissions.',
'books_sort_named' => 'पुस्तक :bookName को वर्गीकरण गर्नुहोस्',
'books_sort_name' => 'नाम अनुसार वर्गीकृत गर्नुहोस्',
'books_sort_created' => 'सिर्जना मितिअनुसार वर्गीकृत गर्नुहोस्',
@@ -330,6 +331,9 @@ return [
// Editor Sidebar
'toggle_sidebar' => 'साइडबार टगल गर्नुहोस्',
+ 'page_contents' => 'Page Contents',
+ 'page_contents_none' => 'No headings were found in the page content.',
+ 'page_contents_info' => 'The contents menu is generated from any heading formats used in the page.',
'page_tags' => 'पाना ट्यागहरू',
'chapter_tags' => 'अध्याय ट्यागहरू',
'book_tags' => 'पुस्तक ट्यागहरू',
diff --git a/lang/ne/settings.php b/lang/ne/settings.php
index dbc7d8e9f..549a4dc8b 100644
--- a/lang/ne/settings.php
+++ b/lang/ne/settings.php
@@ -207,6 +207,7 @@ return [
'role_all' => 'सबै',
'role_own' => 'आफ्नो',
'role_controlled_by_asset' => 'अपलोड गरिएको सम्पत्तिले नियन्त्रण गरेको',
+ 'role_controlled_by_page_delete' => 'Controlled by page delete permissions',
'role_save' => 'भूमिका सुरक्षित गर्नुहोस्',
'role_users' => 'यस भूमिकाका प्रयोगकर्ताहरू',
'role_users_none' => 'यो भूमिकामा हाल कुनै प्रयोगकर्ता छैन',
@@ -263,6 +264,9 @@ return [
'users_mfa_desc' => 'तपाईंको प्रयोगकर्ता खाताको लागि थप सुरक्षा तहको रूपमा बहु-फ्याक्टर प्रमाणीकरण सेटअप गर्नुहोस्।',
'users_mfa_x_methods' => ':count विधि सेटअप गरिएको|:count विधिहरू सेटअप गरिएको',
'users_mfa_configure' => 'विधिहरू सेटअप गर्नुहोस्',
+ 'users_mfa_reset' => 'Reset Multi-Factor Authentication Methods',
+ 'users_mfa_reset_desc' => 'This will reset and clear all configured multi-factor authentication methods for this user. If multi-factor authentication is required by any of their roles, they\'ll be prompted to configure new methods on their next login.',
+ 'users_mfa_reset_confirm' => 'Are you sure you want to reset multi-factor authentication for this user?',
// API Tokens
'user_api_token_create' => 'API टोकन सिर्जना गर्नुहोस्',
@@ -363,6 +367,7 @@ return [
'sk' => 'Slovensky',
'sl' => 'Slovenščina',
'sv' => 'Svenska',
+ 'th' => 'ภาษาไทย',
'tr' => 'Türkçe',
'uk' => 'Українська',
'uz' => 'O‘zbekcha',
diff --git a/lang/nl/activities.php b/lang/nl/activities.php
index 230c7a58b..55356966d 100644
--- a/lang/nl/activities.php
+++ b/lang/nl/activities.php
@@ -99,6 +99,8 @@ return [
'user_update_notification' => 'Gebruiker succesvol bijgewerkt',
'user_delete' => 'verwijderde gebruiker',
'user_delete_notification' => 'Gebruiker succesvol verwijderd',
+ 'user_mfa_reset' => 'reset MFA for user',
+ 'user_mfa_reset_notification' => 'Multi-factor authentication methods reset',
// API Tokens
'api_token_create' => 'API-token aangemaakt',
diff --git a/lang/nl/auth.php b/lang/nl/auth.php
index 12c6b6c7b..49d04dd4f 100644
--- a/lang/nl/auth.php
+++ b/lang/nl/auth.php
@@ -8,6 +8,7 @@ return [
'failed' => 'Deze inloggegevens zijn niet bij ons bekend.',
'throttle' => 'Te veel inlogpogingen! Probeer het opnieuw na :seconds seconden.',
+ 'mfa_throttle' => 'Too many multi-factor verification attempts. Please try again in :seconds seconds.',
// Login & Register
'sign_up' => 'Registreer',
diff --git a/lang/nl/entities.php b/lang/nl/entities.php
index b9be1f42b..e90aff575 100644
--- a/lang/nl/entities.php
+++ b/lang/nl/entities.php
@@ -173,6 +173,7 @@ return [
'books_sort_desc' => 'Verplaats hoofdstukken en pagina\'s door het boek om ze te organiseren. Andere boeken kunnen worden toegevoegd zodat hoofdstukken en pagina\'s gemakkelijk tussen boeken kunnen worden verplaatst. Het is mogelijk om een automatische sorteerregel in te stellen die de inhoud zal sorteren bij wijzigingen.',
'books_sort_auto_sort' => 'Automatisch Sorteren',
'books_sort_auto_sort_active' => 'Automatisch Sorteren Actief: :sortName',
+ 'books_sort_auto_sort_creation_hint' => 'Auto sort option rules can be created in the "Lists & Sorting" settings area by a user with the relevant permissions.',
'books_sort_named' => 'Sorteer boek :bookName',
'books_sort_name' => 'Sorteren op naam',
'books_sort_created' => 'Sorteren op datum van aanmaken',
@@ -330,6 +331,9 @@ return [
// Editor Sidebar
'toggle_sidebar' => 'Zijbalk Tonen/Verbergen',
+ 'page_contents' => 'Page Contents',
+ 'page_contents_none' => 'No headings were found in the page content.',
+ 'page_contents_info' => 'The contents menu is generated from any heading formats used in the page.',
'page_tags' => 'Pagina Labels',
'chapter_tags' => 'Hoofdstuk Labels',
'book_tags' => 'Boek Labels',
diff --git a/lang/nl/settings.php b/lang/nl/settings.php
index c8d071119..9b0fe5ad1 100644
--- a/lang/nl/settings.php
+++ b/lang/nl/settings.php
@@ -207,6 +207,7 @@ return [
'role_all' => 'Alles',
'role_own' => 'Eigen',
'role_controlled_by_asset' => 'Gecontroleerd door de asset waar deze is geüpload',
+ 'role_controlled_by_page_delete' => 'Controlled by page delete permissions',
'role_save' => 'Rol Opslaan',
'role_users' => 'Gebruikers in deze rol',
'role_users_none' => 'Geen enkele gebruiker heeft deze rol',
@@ -263,6 +264,9 @@ return [
'users_mfa_desc' => 'Stel meervoudige verificatie in als extra beveiligingslaag voor je gebruikersaccount.',
'users_mfa_x_methods' => ':count methode geconfigureerd|:count methoden geconfigureerd',
'users_mfa_configure' => 'Configureer methoden',
+ 'users_mfa_reset' => 'Reset Multi-Factor Authentication Methods',
+ 'users_mfa_reset_desc' => 'This will reset and clear all configured multi-factor authentication methods for this user. If multi-factor authentication is required by any of their roles, they\'ll be prompted to configure new methods on their next login.',
+ 'users_mfa_reset_confirm' => 'Are you sure you want to reset multi-factor authentication for this user?',
// API Tokens
'user_api_token_create' => 'API-token aanmaken',
@@ -363,6 +367,7 @@ return [
'sk' => 'Slovensky (Slowaaks)',
'sl' => 'Slovenščina (Sloveens)',
'sv' => 'Svenska (Zweeds)',
+ 'th' => 'ภาษาไทย',
'tr' => 'Türkçe (Turks)',
'uk' => 'Українська (Oekraïens)',
'uz' => 'Oezbeeks',
diff --git a/lang/nn/activities.php b/lang/nn/activities.php
index f87aadc66..fa934bf45 100644
--- a/lang/nn/activities.php
+++ b/lang/nn/activities.php
@@ -99,6 +99,8 @@ return [
'user_update_notification' => 'Brukaren vart oppdatert',
'user_delete' => 'sletta brukar',
'user_delete_notification' => 'Brukaren vart fjerna',
+ 'user_mfa_reset' => 'reset MFA for user',
+ 'user_mfa_reset_notification' => 'Multi-factor authentication methods reset',
// API Tokens
'api_token_create' => 'opprett API-nøkkel',
diff --git a/lang/nn/auth.php b/lang/nn/auth.php
index 5da686eaa..7e53aaee0 100644
--- a/lang/nn/auth.php
+++ b/lang/nn/auth.php
@@ -8,6 +8,7 @@ return [
'failed' => 'Desse detaljane samsvarar ikkje med det me har på bok.',
'throttle' => 'For mange forsøk, prøv på nytt om :seconds sekunder.',
+ 'mfa_throttle' => 'Too many multi-factor verification attempts. Please try again in :seconds seconds.',
// Login & Register
'sign_up' => 'Registrer deg',
diff --git a/lang/nn/entities.php b/lang/nn/entities.php
index 4c75d5019..878e2ef0f 100644
--- a/lang/nn/entities.php
+++ b/lang/nn/entities.php
@@ -173,6 +173,7 @@ return [
'books_sort_desc' => 'Move chapters and pages within a book to reorganise its contents. Other books can be added which allows easy moving of chapters and pages between books. Optionally an auto sort rule can be set to automatically sort this book\'s contents upon changes.',
'books_sort_auto_sort' => 'Auto Sort Option',
'books_sort_auto_sort_active' => 'Auto Sort Active: :sortName',
+ 'books_sort_auto_sort_creation_hint' => 'Auto sort option rules can be created in the "Lists & Sorting" settings area by a user with the relevant permissions.',
'books_sort_named' => 'Omorganiser :bookName',
'books_sort_name' => 'Sorter på namn',
'books_sort_created' => 'Sorter på oppretta dato',
@@ -330,6 +331,9 @@ return [
// Editor Sidebar
'toggle_sidebar' => 'Vis/gøym sidepanelet',
+ 'page_contents' => 'Page Contents',
+ 'page_contents_none' => 'No headings were found in the page content.',
+ 'page_contents_info' => 'The contents menu is generated from any heading formats used in the page.',
'page_tags' => 'Sidemerker',
'chapter_tags' => 'Kapittelmerker',
'book_tags' => 'Bokmerker',
diff --git a/lang/nn/settings.php b/lang/nn/settings.php
index e4b6e6af9..087098332 100644
--- a/lang/nn/settings.php
+++ b/lang/nn/settings.php
@@ -207,6 +207,7 @@ return [
'role_all' => 'Alle',
'role_own' => 'Egne',
'role_controlled_by_asset' => 'Kontrollert av eiendelen de er lastet opp til',
+ 'role_controlled_by_page_delete' => 'Controlled by page delete permissions',
'role_save' => 'Lagre rolle',
'role_users' => 'Kontoholdere med denne rollen',
'role_users_none' => 'Ingen kontoholdere er gitt denne rollen',
@@ -263,6 +264,9 @@ return [
'users_mfa_desc' => 'Konfigurer flerfaktorautentisering som eit ekstra lag med tryggleik for din konto.',
'users_mfa_x_methods' => ':count metode konfigurert|:count metoder konfigurert',
'users_mfa_configure' => 'Konfigurer metoder',
+ 'users_mfa_reset' => 'Reset Multi-Factor Authentication Methods',
+ 'users_mfa_reset_desc' => 'This will reset and clear all configured multi-factor authentication methods for this user. If multi-factor authentication is required by any of their roles, they\'ll be prompted to configure new methods on their next login.',
+ 'users_mfa_reset_confirm' => 'Are you sure you want to reset multi-factor authentication for this user?',
// API Tokens
'user_api_token_create' => 'Opprett API-nøkkel',
@@ -363,6 +367,7 @@ return [
'sk' => 'Slovensky',
'sl' => 'Slovenščina',
'sv' => 'Svenska',
+ 'th' => 'ภาษาไทย',
'tr' => 'Türkçe',
'uk' => 'Українська',
'uz' => 'O‘zbekcha',
diff --git a/lang/pl/activities.php b/lang/pl/activities.php
index 323b7035e..00687187d 100644
--- a/lang/pl/activities.php
+++ b/lang/pl/activities.php
@@ -99,6 +99,8 @@ return [
'user_update_notification' => 'Użytkownik zaktualizowany pomyślnie',
'user_delete' => 'usunięto użytkownika',
'user_delete_notification' => 'Użytkownik pomyślnie usunięty',
+ 'user_mfa_reset' => 'reset MFA for user',
+ 'user_mfa_reset_notification' => 'Multi-factor authentication methods reset',
// API Tokens
'api_token_create' => 'utworzono token API',
diff --git a/lang/pl/auth.php b/lang/pl/auth.php
index 445f8198a..7b4997a6c 100644
--- a/lang/pl/auth.php
+++ b/lang/pl/auth.php
@@ -8,6 +8,7 @@ return [
'failed' => 'Wprowadzone poświadczenia są nieprawidłowe.',
'throttle' => 'Zbyt wiele prób logowania. Spróbuj ponownie za :seconds s.',
+ 'mfa_throttle' => 'Too many multi-factor verification attempts. Please try again in :seconds seconds.',
// Login & Register
'sign_up' => 'Zarejestruj się',
diff --git a/lang/pl/entities.php b/lang/pl/entities.php
index f3ad807af..ea0ac7367 100644
--- a/lang/pl/entities.php
+++ b/lang/pl/entities.php
@@ -173,6 +173,7 @@ return [
'books_sort_desc' => 'Move chapters and pages within a book to reorganise its contents. Other books can be added which allows easy moving of chapters and pages between books. Optionally an auto sort rule can be set to automatically sort this book\'s contents upon changes.',
'books_sort_auto_sort' => 'Opcja automatycznego sortowania',
'books_sort_auto_sort_active' => 'Automatyczne sortowanie aktywne: :sortName',
+ 'books_sort_auto_sort_creation_hint' => 'Auto sort option rules can be created in the "Lists & Sorting" settings area by a user with the relevant permissions.',
'books_sort_named' => 'Sortuj książkę :bookName',
'books_sort_name' => 'Sortuj według nazwy',
'books_sort_created' => 'Sortuj według daty utworzenia',
@@ -330,6 +331,9 @@ return [
// Editor Sidebar
'toggle_sidebar' => 'Przełącz pasek boczny',
+ 'page_contents' => 'Page Contents',
+ 'page_contents_none' => 'No headings were found in the page content.',
+ 'page_contents_info' => 'The contents menu is generated from any heading formats used in the page.',
'page_tags' => 'Tagi strony',
'chapter_tags' => 'Tagi rozdziału',
'book_tags' => 'Tagi książki',
diff --git a/lang/pl/settings.php b/lang/pl/settings.php
index 775d4f25d..bfa6339d5 100644
--- a/lang/pl/settings.php
+++ b/lang/pl/settings.php
@@ -207,6 +207,7 @@ return [
'role_all' => 'Wszyscy',
'role_own' => 'Własne',
'role_controlled_by_asset' => 'Kontrolowane przez zasób, do którego zostały udostępnione',
+ 'role_controlled_by_page_delete' => 'Controlled by page delete permissions',
'role_save' => 'Zapisz rolę',
'role_users' => 'Użytkownicy w tej roli',
'role_users_none' => 'Brak użytkowników zapisanych do tej roli',
@@ -263,6 +264,9 @@ return [
'users_mfa_desc' => 'Skonfiguruj uwierzytelnianie wieloskładnikowe jako dodatkową warstwę bezpieczeństwa dla swojego konta użytkownika.',
'users_mfa_x_methods' => ':count metoda skonfigurowana|:count metody skonfigurowane',
'users_mfa_configure' => 'Konfiguruj metody',
+ 'users_mfa_reset' => 'Reset Multi-Factor Authentication Methods',
+ 'users_mfa_reset_desc' => 'This will reset and clear all configured multi-factor authentication methods for this user. If multi-factor authentication is required by any of their roles, they\'ll be prompted to configure new methods on their next login.',
+ 'users_mfa_reset_confirm' => 'Are you sure you want to reset multi-factor authentication for this user?',
// API Tokens
'user_api_token_create' => 'Utwórz klucz API',
@@ -363,6 +367,7 @@ return [
'sk' => 'Slovensky',
'sl' => 'Slovenščina',
'sv' => 'Svenska',
+ 'th' => 'ภาษาไทย',
'tr' => 'Türkçe',
'uk' => 'Українська',
'uz' => 'O‘zbekcha',
diff --git a/lang/pt/activities.php b/lang/pt/activities.php
index 33d9e2ca6..e2ed42c71 100644
--- a/lang/pt/activities.php
+++ b/lang/pt/activities.php
@@ -99,6 +99,8 @@ return [
'user_update_notification' => 'Utilizador atualizado com sucesso',
'user_delete' => 'utilizador eliminado',
'user_delete_notification' => 'Utilizador removido com sucesso',
+ 'user_mfa_reset' => 'reset MFA for user',
+ 'user_mfa_reset_notification' => 'Multi-factor authentication methods reset',
// API Tokens
'api_token_create' => 'token API criado',
diff --git a/lang/pt/auth.php b/lang/pt/auth.php
index 8807e1a87..453b20168 100644
--- a/lang/pt/auth.php
+++ b/lang/pt/auth.php
@@ -8,6 +8,7 @@ return [
'failed' => 'Estas credenciais não coincidem com os nossos registos.',
'throttle' => 'Demasiadas tentativas de acesso. Tente novamente em :seconds segundos.',
+ 'mfa_throttle' => 'Too many multi-factor verification attempts. Please try again in :seconds seconds.',
// Login & Register
'sign_up' => 'Registar',
diff --git a/lang/pt/entities.php b/lang/pt/entities.php
index e882c79d0..3bdaeb12c 100644
--- a/lang/pt/entities.php
+++ b/lang/pt/entities.php
@@ -173,6 +173,7 @@ return [
'books_sort_desc' => 'Mova capítulos e páginas de um livro para reorganizar o seu conteúdo. É possível acrescentar outros livros, o que permite uma movimentação fácil de capítulos e páginas entre livros. Opcionalmente, uma regra de organização automática pode ser definida para classificar automaticamente o conteúdo deste livro após alterações.',
'books_sort_auto_sort' => '',
'books_sort_auto_sort_active' => 'Auto Sort Active: :sortName',
+ 'books_sort_auto_sort_creation_hint' => 'Auto sort option rules can be created in the "Lists & Sorting" settings area by a user with the relevant permissions.',
'books_sort_named' => 'Ordenar Livro :bookName',
'books_sort_name' => 'Ordenar por Nome',
'books_sort_created' => 'Ordenar por Data de Criação',
@@ -330,6 +331,9 @@ return [
// Editor Sidebar
'toggle_sidebar' => 'Alternar barra lateral',
+ 'page_contents' => 'Page Contents',
+ 'page_contents_none' => 'No headings were found in the page content.',
+ 'page_contents_info' => 'The contents menu is generated from any heading formats used in the page.',
'page_tags' => 'Etiquetas de Página',
'chapter_tags' => 'Etiquetas do Capítulo',
'book_tags' => 'Etiquetas do Livro',
diff --git a/lang/pt/settings.php b/lang/pt/settings.php
index a59335b7c..1488db87a 100644
--- a/lang/pt/settings.php
+++ b/lang/pt/settings.php
@@ -207,6 +207,7 @@ return [
'role_all' => 'Todos',
'role_own' => 'Próprio',
'role_controlled_by_asset' => 'Controlado pelo ativo para o qual eles são enviados',
+ 'role_controlled_by_page_delete' => 'Controlled by page delete permissions',
'role_save' => 'Guardar Cargo',
'role_users' => 'Utilizadores com este cargo',
'role_users_none' => 'Nenhum utilizador está atualmente vinculado a este cargo',
@@ -263,6 +264,9 @@ return [
'users_mfa_desc' => 'Configure a autenticação multi-fatores como uma camada extra de segurança para sua conta de utilizador.',
'users_mfa_x_methods' => ':count método configurado|:count métodos configurados',
'users_mfa_configure' => 'Configurar Métodos',
+ 'users_mfa_reset' => 'Reset Multi-Factor Authentication Methods',
+ 'users_mfa_reset_desc' => 'This will reset and clear all configured multi-factor authentication methods for this user. If multi-factor authentication is required by any of their roles, they\'ll be prompted to configure new methods on their next login.',
+ 'users_mfa_reset_confirm' => 'Are you sure you want to reset multi-factor authentication for this user?',
// API Tokens
'user_api_token_create' => 'Criar Token de API',
@@ -363,6 +367,7 @@ return [
'sk' => 'Slovensky',
'sl' => 'Slovenščina',
'sv' => 'Svenska',
+ 'th' => 'ภาษาไทย',
'tr' => 'Türkçe',
'uk' => 'Українська',
'uz' => 'O‘zbekcha',
diff --git a/lang/pt_BR/activities.php b/lang/pt_BR/activities.php
index 2a2d173c7..e9069564f 100644
--- a/lang/pt_BR/activities.php
+++ b/lang/pt_BR/activities.php
@@ -99,6 +99,8 @@ return [
'user_update_notification' => 'Usuário atualizado com sucesso',
'user_delete' => 'usuário excluído',
'user_delete_notification' => 'Usuário removido com sucesso',
+ 'user_mfa_reset' => 'reset MFA for user',
+ 'user_mfa_reset_notification' => 'Multi-factor authentication methods reset',
// API Tokens
'api_token_create' => 'token de API criado',
diff --git a/lang/pt_BR/auth.php b/lang/pt_BR/auth.php
index b5fd974aa..dfcc47da6 100644
--- a/lang/pt_BR/auth.php
+++ b/lang/pt_BR/auth.php
@@ -8,6 +8,7 @@ return [
'failed' => 'As credenciais fornecidas não puderam ser validadas em nossos registros.',
'throttle' => 'Muitas tentativas de login. Por favor, tente novamente em :seconds segundos.',
+ 'mfa_throttle' => 'Too many multi-factor verification attempts. Please try again in :seconds seconds.',
// Login & Register
'sign_up' => 'Criar Conta',
@@ -89,7 +90,7 @@ return [
'mfa_setup_action' => 'Configurações',
'mfa_backup_codes_usage_limit_warning' => 'Você tem menos de 5 códigos de backup restantes, Por favor, gere e armazene um novo conjunto antes de esgotar suas opções de códigos de backup para evitar estar bloqueado para fora da sua conta.',
'mfa_option_totp_title' => 'Aplicativo Móvel',
- 'mfa_option_totp_desc' => 'Para usar a autenticação multi-fator, você precisará de um aplicativo móvel que suporte TOTP como o Google Authenticator, Authy ou o Microsoft Authenticator.',
+ 'mfa_option_totp_desc' => 'Para usar a autenticação multi-fator, você precisará de um aplicativo móvel que suporte TOTP como o Google Authenticator, Authy, Microsoft Authenticator ou Proton Authenticator.',
'mfa_option_backup_codes_title' => 'Códigos de backup',
'mfa_option_backup_codes_desc' => 'Gera um conjunto de códigos de backup de uso único que você inserirá no login para verificar sua identidade. Certifique-se de armazená-los em um local seguro e protegido.',
'mfa_gen_confirm_and_enable' => 'Confirmar e habilitar',
diff --git a/lang/pt_BR/entities.php b/lang/pt_BR/entities.php
index 5a948c8dc..7fa0b50c1 100644
--- a/lang/pt_BR/entities.php
+++ b/lang/pt_BR/entities.php
@@ -173,6 +173,7 @@ return [
'books_sort_desc' => 'Mova capítulos e páginas de um livro para reorganizar seu conteúdo. É possível acrescentar outros livros, o que permite uma movimentação fácil de capítulos e páginas entre livros. Opcionalmente, uma regra de ordenação automática pode ser definida para ordenar automaticamente o conteúdo deste livro após alterações.',
'books_sort_auto_sort' => 'Opção de ordenação automática',
'books_sort_auto_sort_active' => 'Ordenação automática ativa: :sortName',
+ 'books_sort_auto_sort_creation_hint' => 'Regras de ordenação automática podem ser criadas na área de configurações "Lista e Classificação" por um usuário com as permissões relevantes.',
'books_sort_named' => 'Ordenar Livro :bookName',
'books_sort_name' => 'Ordernar por Nome',
'books_sort_created' => 'Ordenar por Data de Criação',
@@ -330,6 +331,9 @@ return [
// Editor Sidebar
'toggle_sidebar' => '',
+ 'page_contents' => 'Page Contents',
+ 'page_contents_none' => 'No headings were found in the page content.',
+ 'page_contents_info' => 'The contents menu is generated from any heading formats used in the page.',
'page_tags' => 'Marcadores de Página',
'chapter_tags' => 'Marcadores de Capítulo',
'book_tags' => 'Marcadores de Livro',
diff --git a/lang/pt_BR/settings.php b/lang/pt_BR/settings.php
index 97b434727..8129637c8 100644
--- a/lang/pt_BR/settings.php
+++ b/lang/pt_BR/settings.php
@@ -207,6 +207,7 @@ return [
'role_all' => 'Todos',
'role_own' => 'Próprio',
'role_controlled_by_asset' => 'Controlado pelos ativos nos quais o upload foi realizado',
+ 'role_controlled_by_page_delete' => 'Controlado pelas permissões de exclusão de página',
'role_save' => 'Salvar Perfil',
'role_users' => 'Usuários com este perfil',
'role_users_none' => 'Nenhum usuário está atualmente vinculado a este perfil',
@@ -263,6 +264,9 @@ return [
'users_mfa_desc' => 'A autenticação multi-fator adiciona outra camada de segurança à sua conta.',
'users_mfa_x_methods' => ':count método configurado|:count métodos configurados',
'users_mfa_configure' => 'Configurar Métodos',
+ 'users_mfa_reset' => 'Reset Multi-Factor Authentication Methods',
+ 'users_mfa_reset_desc' => 'This will reset and clear all configured multi-factor authentication methods for this user. If multi-factor authentication is required by any of their roles, they\'ll be prompted to configure new methods on their next login.',
+ 'users_mfa_reset_confirm' => 'Are you sure you want to reset multi-factor authentication for this user?',
// API Tokens
'user_api_token_create' => 'Criar Token de API',
@@ -363,6 +367,7 @@ return [
'sk' => 'Slovensky',
'sl' => 'Slovenščina',
'sv' => 'Svenska',
+ 'th' => 'ภาษาไทย',
'tr' => 'Türkçe',
'uk' => 'Українська',
'uz' => 'O‘zbekcha',
diff --git a/lang/ro/activities.php b/lang/ro/activities.php
index eed5cc083..c00976cf7 100644
--- a/lang/ro/activities.php
+++ b/lang/ro/activities.php
@@ -99,6 +99,8 @@ return [
'user_update_notification' => 'Utilizator actualizat cu succes',
'user_delete' => 'utilizator șters',
'user_delete_notification' => 'Utilizator eliminat cu succes',
+ 'user_mfa_reset' => 'reset MFA for user',
+ 'user_mfa_reset_notification' => 'Multi-factor authentication methods reset',
// API Tokens
'api_token_create' => 'created API token',
diff --git a/lang/ro/auth.php b/lang/ro/auth.php
index e02eeb4c1..73e165381 100644
--- a/lang/ro/auth.php
+++ b/lang/ro/auth.php
@@ -8,6 +8,7 @@ return [
'failed' => 'Aceste credenţiale nu se potrivesc cu înregistrările noastre.',
'throttle' => 'Prea multe încercări de conectare. Vă rugăm să încercați din nou în :seconds secunde.',
+ 'mfa_throttle' => 'Too many multi-factor verification attempts. Please try again in :seconds seconds.',
// Login & Register
'sign_up' => 'Inregistrează-te',
diff --git a/lang/ro/entities.php b/lang/ro/entities.php
index ac8c9d326..18ffd30c9 100644
--- a/lang/ro/entities.php
+++ b/lang/ro/entities.php
@@ -173,6 +173,7 @@ return [
'books_sort_desc' => 'Move chapters and pages within a book to reorganise its contents. Other books can be added which allows easy moving of chapters and pages between books. Optionally an auto sort rule can be set to automatically sort this book\'s contents upon changes.',
'books_sort_auto_sort' => 'Auto Sort Option',
'books_sort_auto_sort_active' => 'Auto Sort Active: :sortName',
+ 'books_sort_auto_sort_creation_hint' => 'Auto sort option rules can be created in the "Lists & Sorting" settings area by a user with the relevant permissions.',
'books_sort_named' => 'Sortează cartea :bookName',
'books_sort_name' => 'Sortează după nume',
'books_sort_created' => 'Sortează după data creării',
@@ -330,6 +331,9 @@ return [
// Editor Sidebar
'toggle_sidebar' => 'Comutați bara laterală',
+ 'page_contents' => 'Page Contents',
+ 'page_contents_none' => 'No headings were found in the page content.',
+ 'page_contents_info' => 'The contents menu is generated from any heading formats used in the page.',
'page_tags' => 'Etichete pagină',
'chapter_tags' => 'Etichete capitol',
'book_tags' => 'Etichete carte',
diff --git a/lang/ro/settings.php b/lang/ro/settings.php
index d65a8e071..bbbaa34d9 100644
--- a/lang/ro/settings.php
+++ b/lang/ro/settings.php
@@ -207,6 +207,7 @@ return [
'role_all' => 'Tot',
'role_own' => 'Propriu',
'role_controlled_by_asset' => 'Controlat de activele pe care sunt încărcate',
+ 'role_controlled_by_page_delete' => 'Controlled by page delete permissions',
'role_save' => 'Salvare rol',
'role_users' => 'Utilizatori cu acest rol',
'role_users_none' => 'Nici un utilizator nu este asociat acestui rol',
@@ -263,6 +264,9 @@ return [
'users_mfa_desc' => 'Configurare autentificarea multi-factor ca un nivel suplimentar de securitate pentru contul tău de utilizator.',
'users_mfa_x_methods' => ':count metodă configurată|:count metode configurate',
'users_mfa_configure' => 'Configurare metode',
+ 'users_mfa_reset' => 'Reset Multi-Factor Authentication Methods',
+ 'users_mfa_reset_desc' => 'This will reset and clear all configured multi-factor authentication methods for this user. If multi-factor authentication is required by any of their roles, they\'ll be prompted to configure new methods on their next login.',
+ 'users_mfa_reset_confirm' => 'Are you sure you want to reset multi-factor authentication for this user?',
// API Tokens
'user_api_token_create' => 'Creare token API',
@@ -363,6 +367,7 @@ return [
'sk' => 'Slovensky',
'sl' => 'Slovenščina',
'sv' => 'Svenska',
+ 'th' => 'ภาษาไทย',
'tr' => 'Türkçe',
'uk' => 'Українська',
'uz' => 'O‘zbekcha',
diff --git a/lang/ru/activities.php b/lang/ru/activities.php
index d353b7a76..9d08d1d4a 100644
--- a/lang/ru/activities.php
+++ b/lang/ru/activities.php
@@ -85,12 +85,12 @@ return [
'webhook_delete_notification' => 'Вебхук успешно удален',
// Imports
- 'import_create' => 'created import',
- 'import_create_notification' => 'Import successfully uploaded',
+ 'import_create' => 'создал импорт',
+ 'import_create_notification' => 'Импорт успешно добавлен',
'import_run' => 'обновлен импорт',
- 'import_run_notification' => 'Content successfully imported',
- 'import_delete' => 'deleted import',
- 'import_delete_notification' => 'Import successfully deleted',
+ 'import_run_notification' => 'Контент успешно импортирован',
+ 'import_delete' => 'удалил импорт',
+ 'import_delete_notification' => 'Импорт успешно удален',
// Users
'user_create' => 'создал пользователя',
@@ -99,6 +99,8 @@ return [
'user_update_notification' => 'Пользователь успешно обновлен',
'user_delete' => 'удалил пользователя',
'user_delete_notification' => 'Пользователь успешно удален',
+ 'user_mfa_reset' => 'reset MFA for user',
+ 'user_mfa_reset_notification' => 'Multi-factor authentication methods reset',
// API Tokens
'api_token_create' => 'создан API токен',
diff --git a/lang/ru/auth.php b/lang/ru/auth.php
index d39da119d..433bfbe5f 100644
--- a/lang/ru/auth.php
+++ b/lang/ru/auth.php
@@ -8,6 +8,7 @@ return [
'failed' => 'Введенные вами данные не найдены в нашей базе.',
'throttle' => 'Слишком много попыток входа. Пожалуйста, повторите попытку через :seconds секунд.',
+ 'mfa_throttle' => 'Too many multi-factor verification attempts. Please try again in :seconds seconds.',
// Login & Register
'sign_up' => 'Регистрация',
diff --git a/lang/ru/common.php b/lang/ru/common.php
index fa9969c32..bf77a999d 100644
--- a/lang/ru/common.php
+++ b/lang/ru/common.php
@@ -30,8 +30,8 @@ return [
'create' => 'Создание',
'update' => 'Обновление',
'edit' => 'Редактировать',
- 'archive' => 'Archive',
- 'unarchive' => 'Un-Archive',
+ 'archive' => 'Архивировать',
+ 'unarchive' => 'Вернуть из архива',
'sort' => 'Сортировать',
'move' => 'Переместить',
'copy' => 'Скопировать',
diff --git a/lang/ru/editor.php b/lang/ru/editor.php
index d26f7edfe..da661559b 100644
--- a/lang/ru/editor.php
+++ b/lang/ru/editor.php
@@ -149,7 +149,7 @@ return [
'url' => 'URL-адрес',
'text_to_display' => 'Текст для отображения',
'title' => 'Заголовок',
- 'browse_links' => 'Browse links',
+ 'browse_links' => 'Просмотр ссылки',
'open_link' => 'Открыть ссылку',
'open_link_in' => 'Открыть ссылку в...',
'open_link_current' => 'В текущем окне',
@@ -166,8 +166,8 @@ return [
'about' => 'О редакторе',
'about_title' => 'О редакторе WYSIWYG',
'editor_license' => 'Лицензия редактора и авторские права',
- 'editor_lexical_license' => 'This editor is built as a fork of :lexicalLink which is distributed under the MIT license.',
- 'editor_lexical_license_link' => 'Full license details can be found here.',
+ 'editor_lexical_license' => 'Этот редактор создан с помощью :lexicalLink, распространяемый под лицензией MIT.',
+ 'editor_lexical_license_link' => 'Здесь вы можете найти полную информацию о лицензии.',
'editor_tiny_license' => 'Этот редактор собран с помощью :tinyLink, который предоставляется под MIT лицензией.',
'editor_tiny_license_link' => 'Авторские права и подробности лицензии TinyMCE вы можете найти здесь.',
'save_continue' => 'Сохранить страницу и продолжить',
diff --git a/lang/ru/entities.php b/lang/ru/entities.php
index bf224c10a..d3c4230ac 100644
--- a/lang/ru/entities.php
+++ b/lang/ru/entities.php
@@ -51,18 +51,18 @@ return [
'import_pending' => 'Ожидается импорт',
'import_pending_none' => 'Импорт не был запущен.',
'import_continue' => 'Продолжить импорт',
- 'import_continue_desc' => 'Review the content due to be imported from the uploaded ZIP file. When ready, run the import to add its contents to this system. The uploaded ZIP import file will be automatically removed on successful import.',
- 'import_details' => 'Import Details',
+ 'import_continue_desc' => 'Проверьте содержимое, которое должно быть импортировано из загруженного ZIP-файла. Если все готово, выполните импорт, чтобы добавить его содержимое в эту систему. Загруженный ZIP файл будет автоматически удален при успешном импорте.',
+ 'import_details' => 'Детали загрузки',
'import_run' => 'Запустить импорт',
'import_size' => ':size Import ZIP Size',
- 'import_uploaded_at' => 'Uploaded :relativeTime',
- 'import_uploaded_by' => 'Uploaded by',
+ 'import_uploaded_at' => 'Загружено :relativeTime',
+ 'import_uploaded_by' => 'Загружено пользователем',
'import_location' => 'Import Location',
- 'import_location_desc' => 'Select a target location for your imported content. You\'ll need the relevant permissions to create within the location you choose.',
+ 'import_location_desc' => 'Выберите целевое местоположение для импортированного содержимого. Для создания в выбранном месте необходимы соответствующие разрешения.',
'import_delete_confirm' => 'Are you sure you want to delete this import?',
- 'import_delete_desc' => 'This will delete the uploaded import ZIP file, and cannot be undone.',
+ 'import_delete_desc' => 'Это приведет к удалению загруженного ZIP файла и не может быть отменено.',
'import_errors' => 'Ошибки импорта',
- 'import_errors_desc' => 'The follow errors occurred during the import attempt:',
+ 'import_errors_desc' => 'Во время попытки импорта произошла следующая ошибка:',
'breadcrumb_siblings_for_page' => 'Navigate siblings for page',
'breadcrumb_siblings_for_chapter' => 'Navigate siblings for chapter',
'breadcrumb_siblings_for_book' => 'Navigate siblings for book',
@@ -170,9 +170,10 @@ return [
'books_search_this' => 'Поиск в этой книге',
'books_navigation' => 'Навигация по книге',
'books_sort' => 'Сортировка содержимого книги',
- 'books_sort_desc' => 'Move chapters and pages within a book to reorganise its contents. Other books can be added which allows easy moving of chapters and pages between books. Optionally an auto sort rule can be set to automatically sort this book\'s contents upon changes.',
- 'books_sort_auto_sort' => 'Auto Sort Option',
- 'books_sort_auto_sort_active' => 'Auto Sort Active: :sortName',
+ 'books_sort_desc' => 'Переместите разделы и страницы в книге, чтобы изменить содержание книги. Могут быть добавлены другие книги, что позволяет легко перемещать разделы и страницы между книгами. При желании правило автоматической сортировки может быть установлено для автоматической сортировки содержимого этой книги после изменений.',
+ 'books_sort_auto_sort' => 'Автосортировка',
+ 'books_sort_auto_sort_active' => 'Автосортировка активна: :sortName',
+ 'books_sort_auto_sort_creation_hint' => 'Правила автоматической сортировки могут быть созданы в области настроек «Список и Сортировка» пользователем с соответствующими разрешениями.',
'books_sort_named' => 'Сортировка книги :bookName',
'books_sort_name' => 'По имени',
'books_sort_created' => 'По дате создания',
@@ -251,7 +252,7 @@ return [
'pages_edit_switch_to_markdown_clean' => 'Только Markdown (с возможными потерями форматирования)',
'pages_edit_switch_to_markdown_stable' => 'Полное сохранение форматирования (HTML)',
'pages_edit_switch_to_wysiwyg' => 'Переключиться в WYSIWYG',
- 'pages_edit_switch_to_new_wysiwyg' => 'Switch to new WYSIWYG',
+ 'pages_edit_switch_to_new_wysiwyg' => 'Переключиться на новый WYSIWYG',
'pages_edit_switch_to_new_wysiwyg_desc' => '(В бета-тестировании)',
'pages_edit_set_changelog' => 'Задать список изменений',
'pages_edit_enter_changelog_desc' => 'Введите краткое описание внесенных изменений',
@@ -330,6 +331,9 @@ return [
// Editor Sidebar
'toggle_sidebar' => 'Переключить боковую панель',
+ 'page_contents' => 'Page Contents',
+ 'page_contents_none' => 'No headings were found in the page content.',
+ 'page_contents_info' => 'The contents menu is generated from any heading formats used in the page.',
'page_tags' => 'Теги страницы',
'chapter_tags' => 'Теги главы',
'book_tags' => 'Теги книги',
diff --git a/lang/ru/notifications.php b/lang/ru/notifications.php
index 96e853723..ea885d910 100644
--- a/lang/ru/notifications.php
+++ b/lang/ru/notifications.php
@@ -12,7 +12,7 @@ return [
'updated_page_intro' => 'Страница была обновлена в :appName:',
'updated_page_debounce' => 'Чтобы предотвратить массовые уведомления, в течение некоторого времени вы не будете получать уведомления о дальнейших правках этой страницы этим же редактором.',
'comment_mention_subject' => 'Вы были упомянуты в комментарии на странице: :pageName',
- 'comment_mention_intro' => 'You were mentioned in a comment on :appName:',
+ 'comment_mention_intro' => 'Вы были упомянуты в комментариях к :appName:',
'detail_page_name' => 'Имя страницы:',
'detail_page_path' => 'Путь страницы:',
diff --git a/lang/ru/preferences.php b/lang/ru/preferences.php
index b61b252c8..2dcd20b11 100644
--- a/lang/ru/preferences.php
+++ b/lang/ru/preferences.php
@@ -23,7 +23,7 @@ return [
'notifications_desc' => 'Управляйте полученными по электронной почте уведомлениями при выполнении определенных действий в системе.',
'notifications_opt_own_page_changes' => 'Уведомлять об изменениях в собственных страницах',
'notifications_opt_own_page_comments' => 'Уведомлять о комментариях на собственных страницах',
- 'notifications_opt_comment_mentions' => 'Notify when I\'m mentioned in a comment',
+ 'notifications_opt_comment_mentions' => 'Уведомлять, когда меня упоминали в комментарии',
'notifications_opt_comment_replies' => 'Уведомлять об ответах на мои комментарии',
'notifications_save' => 'Сохранить настройки',
'notifications_update_success' => 'Настройки уведомлений были обновлены!',
diff --git a/lang/ru/settings.php b/lang/ru/settings.php
index 76a2eebbf..4fdd5784a 100644
--- a/lang/ru/settings.php
+++ b/lang/ru/settings.php
@@ -82,28 +82,28 @@ return [
'sorting_rules_desc' => 'Выберите правило сортировки по умолчанию для новых книг. Это не повлияет на существующие книги и может быть изменено для каждой книги отдельно.',
'sort_rule_assigned_to_x_books' => 'Используется в :count книгах',
'sort_rule_create' => 'Создать правило сортировки',
- 'sort_rule_edit' => 'Edit Sort Rule',
+ 'sort_rule_edit' => 'Изменить правило сортировки',
'sort_rule_delete' => 'Удалить правило сортировки',
'sort_rule_delete_desc' => 'Удалить это правило сортировки из системы. Книги, использующие эту сортировку, вернутся к ручной сортировке.',
- 'sort_rule_delete_warn_books' => 'This sort rule is currently used on :count book(s). Are you sure you want to delete this?',
+ 'sort_rule_delete_warn_books' => 'Это правило сортировки в настоящее время используется в :count book(s). Вы уверены, что хотите удалить его?',
'sort_rule_delete_warn_default' => 'Это правило сортировки используется по умолчанию для книг. Вы уверены, что хотите удалить его?',
'sort_rule_details' => 'Детали правила сортировки',
- 'sort_rule_details_desc' => 'Set a name for this sort rule, which will appear in lists when users are selecting a sort.',
+ 'sort_rule_details_desc' => 'Задайте имя для этого правила сортировки, оно будет отображаться в списках, когда пользователи выбирают сортировку.',
'sort_rule_operations' => 'Sort Operations',
- 'sort_rule_operations_desc' => 'Configure the sort actions to be performed by moving them from the list of available operations. Upon use, the operations will be applied in order, from top to bottom. Any changes made here will be applied to all assigned books upon save.',
+ 'sort_rule_operations_desc' => 'Настройка сортировки выполняемых действий путем перемещения их из списка доступных операций. После использования операции будут выполняться по порядку сверху вниз. Любые изменения, внесенные здесь, будут применены ко всем назначенным книгам после сохранения.',
'sort_rule_available_operations' => 'Доступные операции',
- 'sort_rule_available_operations_empty' => 'No operations remaining',
+ 'sort_rule_available_operations_empty' => 'Операций не осталось',
'sort_rule_configured_operations' => 'Configured Operations',
'sort_rule_configured_operations_empty' => 'Перетащите/добавьте операции из списка "Доступные операции"',
'sort_rule_op_asc' => '(Возрастание)',
'sort_rule_op_desc' => '(Убывание)',
- 'sort_rule_op_name' => 'Name - Alphabetical',
+ 'sort_rule_op_name' => 'Имя - по алфавиту',
'sort_rule_op_name_numeric' => 'По нумерации',
- 'sort_rule_op_created_date' => 'Created Date',
- 'sort_rule_op_updated_date' => 'Updated Date',
+ 'sort_rule_op_created_date' => 'По дате создания',
+ 'sort_rule_op_updated_date' => 'По дате обновления',
'sort_rule_op_chapters_first' => 'Главы в начале',
'sort_rule_op_chapters_last' => 'Главы в конце',
- 'sorting_page_limits' => 'Per-Page Display Limits',
+ 'sorting_page_limits' => 'Ограничения показа на странице',
'sorting_page_limits_desc' => 'Set how many items to show per-page in various lists within the system. Typically a lower amount will be more performant, while a higher amount avoids the need to click through multiple pages. Using a multiple of 6 is recommended.',
// Maintenance settings
@@ -194,19 +194,20 @@ return [
'role_access_api' => 'Доступ к системному API',
'role_manage_settings' => 'Управление настройками приложения',
'role_export_content' => 'Экспорт контента',
- 'role_import_content' => 'Import content',
+ 'role_import_content' => 'Импортировать содержимое',
'role_editor_change' => 'Изменение редактора страниц',
'role_notifications' => 'Получение и управление уведомлениями',
- 'role_permission_note_users_and_roles' => 'These permissions will technically also provide visibility & searching of users & roles in the system.',
+ 'role_permission_note_users_and_roles' => 'Эти разрешения также обеспечивают видимость и поиск пользователей и ролей в системе.',
'role_asset' => 'Права доступа к материалам',
'roles_system_warning' => 'Имейте в виду, что доступ к любому из указанных выше трех разрешений может позволить пользователю изменить свои собственные привилегии или привилегии других пользователей системы. Назначать роли с этими правами можно только доверенным пользователям.',
'role_asset_desc' => 'Эти разрешения контролируют доступ по умолчанию к параметрам внутри системы. Разрешения на книги, главы и страницы перезапишут эти разрешения.',
'role_asset_admins' => 'Администраторы автоматически получают доступ ко всему контенту, но эти опции могут отображать или скрывать параметры пользовательского интерфейса.',
'role_asset_image_view_note' => 'Это относится к видимости в менеджере изображений. Фактический доступ к загруженным файлам изображений будет зависеть от опции хранения системных изображений.',
- 'role_asset_users_note' => 'These permissions will technically also provide visibility & searching of users in the system.',
+ 'role_asset_users_note' => 'Эти разрешения также обеспечивают видимость и поиск пользователей в системе.',
'role_all' => 'Все',
'role_own' => 'Владелец',
'role_controlled_by_asset' => 'Контролируется активом, в который они загружены',
+ 'role_controlled_by_page_delete' => 'Controlled by page delete permissions',
'role_save' => 'Сохранить роль',
'role_users' => 'Пользователи с данной ролью',
'role_users_none' => 'Нет пользователей с данной ролью',
@@ -263,6 +264,9 @@ return [
'users_mfa_desc' => 'Многофакторная аутентификация повышает степень безопасности вашей учетной записи.',
'users_mfa_x_methods' => 'методов настроено :count|методов сконфигурировано :count',
'users_mfa_configure' => 'Настройка методов',
+ 'users_mfa_reset' => 'Reset Multi-Factor Authentication Methods',
+ 'users_mfa_reset_desc' => 'This will reset and clear all configured multi-factor authentication methods for this user. If multi-factor authentication is required by any of their roles, they\'ll be prompted to configure new methods on their next login.',
+ 'users_mfa_reset_confirm' => 'Are you sure you want to reset multi-factor authentication for this user?',
// API Tokens
'user_api_token_create' => 'Создать токен',
@@ -363,6 +367,7 @@ return [
'sk' => 'Slovensky',
'sl' => 'Slovenščina',
'sv' => 'Svenska',
+ 'th' => 'ภาษาไทย',
'tr' => 'Türkçe',
'uk' => 'Українська',
'uz' => 'O‘zbekcha',
diff --git a/lang/ru/validation.php b/lang/ru/validation.php
index ce94faa3b..6d011cff1 100644
--- a/lang/ru/validation.php
+++ b/lang/ru/validation.php
@@ -105,11 +105,11 @@ return [
'url' => 'Формат :attribute некорректен.',
'uploaded' => 'Не удалось загрузить файл. Сервер не может принимать файлы такого размера.',
- 'zip_file' => 'The :attribute needs to reference a file within the ZIP.',
- 'zip_file_size' => 'The file :attribute must not exceed :size MB.',
- 'zip_file_mime' => 'The :attribute needs to reference a file of type :validTypes, found :foundType.',
- 'zip_model_expected' => 'Data object expected but ":type" found.',
- 'zip_unique' => 'The :attribute must be unique for the object type within the ZIP.',
+ 'zip_file' => ':attribute должен ссылаться на файл внутри ZIP.',
+ 'zip_file_size' => 'Файл :attribute не должен превышать :size МБ.',
+ 'zip_file_mime' => ':attribute должен ссылаться на файл типа :validTypes, найден :foundType.',
+ 'zip_model_expected' => 'Ожидался объект данных, но найдено ":type".',
+ 'zip_unique' => 'Значение :attribute должно быть уникальным для типа объекта внутри ZIP.',
// Custom validation lines
'custom' => [
diff --git a/lang/sk/activities.php b/lang/sk/activities.php
index 65542fbe2..b9a532e2e 100644
--- a/lang/sk/activities.php
+++ b/lang/sk/activities.php
@@ -99,6 +99,8 @@ return [
'user_update_notification' => 'Používateľ úspešne upravený',
'user_delete' => 'odstránený používateľ',
'user_delete_notification' => 'Používateľ úspešne zmazaný',
+ 'user_mfa_reset' => 'reset MFA for user',
+ 'user_mfa_reset_notification' => 'Multi-factor authentication methods reset',
// API Tokens
'api_token_create' => 'created API token',
diff --git a/lang/sk/auth.php b/lang/sk/auth.php
index 11ccdc889..52f34f68f 100644
--- a/lang/sk/auth.php
+++ b/lang/sk/auth.php
@@ -8,6 +8,7 @@ return [
'failed' => 'Tieto údaje sa nezhodujú s našimi záznamami.',
'throttle' => 'Priveľa pokusov o prihlásenie. Skúste znova o :seconds sekúnd.',
+ 'mfa_throttle' => 'Too many multi-factor verification attempts. Please try again in :seconds seconds.',
// Login & Register
'sign_up' => 'Registrácia',
diff --git a/lang/sk/entities.php b/lang/sk/entities.php
index eb5254535..697aef0b8 100644
--- a/lang/sk/entities.php
+++ b/lang/sk/entities.php
@@ -173,6 +173,7 @@ return [
'books_sort_desc' => 'Move chapters and pages within a book to reorganise its contents. Other books can be added which allows easy moving of chapters and pages between books. Optionally an auto sort rule can be set to automatically sort this book\'s contents upon changes.',
'books_sort_auto_sort' => 'Auto Sort Option',
'books_sort_auto_sort_active' => 'Auto Sort Active: :sortName',
+ 'books_sort_auto_sort_creation_hint' => 'Auto sort option rules can be created in the "Lists & Sorting" settings area by a user with the relevant permissions.',
'books_sort_named' => 'Zoradiť knihu :bookName',
'books_sort_name' => 'Zoradiť podľa mena',
'books_sort_created' => 'Zoradiť podľa dátumu vytvorenia',
@@ -330,6 +331,9 @@ return [
// Editor Sidebar
'toggle_sidebar' => 'Toggle Sidebar',
+ 'page_contents' => 'Page Contents',
+ 'page_contents_none' => 'No headings were found in the page content.',
+ 'page_contents_info' => 'The contents menu is generated from any heading formats used in the page.',
'page_tags' => 'Štítky stránok',
'chapter_tags' => 'Štítky kapitol',
'book_tags' => 'Štítky kníh',
diff --git a/lang/sk/settings.php b/lang/sk/settings.php
index 67671f6f8..e76fefb98 100644
--- a/lang/sk/settings.php
+++ b/lang/sk/settings.php
@@ -207,6 +207,7 @@ return [
'role_all' => 'Všetko',
'role_own' => 'Vlastné',
'role_controlled_by_asset' => 'Regulované zdrojom, do ktorého sú nahrané',
+ 'role_controlled_by_page_delete' => 'Controlled by page delete permissions',
'role_save' => 'Uložiť rolu',
'role_users' => 'Používatelia s touto rolou',
'role_users_none' => 'Žiadni používatelia nemajú priradenú túto rolu',
@@ -263,6 +264,9 @@ return [
'users_mfa_desc' => 'Pre vyššiu úroveň bezpečnosti si nastavte viacúrovňové prihlasovanie.',
'users_mfa_x_methods' => ':count nakonfigurované metódy|:count nakonfigurovaných metód',
'users_mfa_configure' => 'Konfigurovať metódy',
+ 'users_mfa_reset' => 'Reset Multi-Factor Authentication Methods',
+ 'users_mfa_reset_desc' => 'This will reset and clear all configured multi-factor authentication methods for this user. If multi-factor authentication is required by any of their roles, they\'ll be prompted to configure new methods on their next login.',
+ 'users_mfa_reset_confirm' => 'Are you sure you want to reset multi-factor authentication for this user?',
// API Tokens
'user_api_token_create' => 'Vytvoriť API token',
@@ -363,6 +367,7 @@ return [
'sk' => 'Slovensky',
'sl' => 'Slovenščina',
'sv' => 'Svenska',
+ 'th' => 'ภาษาไทย',
'tr' => 'Türkçe',
'uk' => 'Українська',
'uz' => 'O‘zbekcha',
diff --git a/lang/sl/activities.php b/lang/sl/activities.php
index 117c73ca1..3b8977c2f 100644
--- a/lang/sl/activities.php
+++ b/lang/sl/activities.php
@@ -99,6 +99,8 @@ return [
'user_update_notification' => 'Uporabnik uspešno posodobljen',
'user_delete' => 'uporabnik izbrisan',
'user_delete_notification' => 'Uporabnik uspešno izbrisan',
+ 'user_mfa_reset' => 'reset MFA for user',
+ 'user_mfa_reset_notification' => 'Multi-factor authentication methods reset',
// API Tokens
'api_token_create' => 'ustvarjen žeton API',
diff --git a/lang/sl/auth.php b/lang/sl/auth.php
index e06d823e7..46c6a565d 100644
--- a/lang/sl/auth.php
+++ b/lang/sl/auth.php
@@ -8,6 +8,7 @@ return [
'failed' => 'Poverilnice se ne ujemajo s podatki v naši bazi.',
'throttle' => 'Prekoračili ste število možnih prijav. Poskusite znova čez :seconds sekund.',
+ 'mfa_throttle' => 'Too many multi-factor verification attempts. Please try again in :seconds seconds.',
// Login & Register
'sign_up' => 'Registracija',
diff --git a/lang/sl/entities.php b/lang/sl/entities.php
index 00ac99181..0efbc6d17 100644
--- a/lang/sl/entities.php
+++ b/lang/sl/entities.php
@@ -173,6 +173,7 @@ return [
'books_sort_desc' => 'Move chapters and pages within a book to reorganise its contents. Other books can be added which allows easy moving of chapters and pages between books. Optionally an auto sort rule can be set to automatically sort this book\'s contents upon changes.',
'books_sort_auto_sort' => 'Auto Sort Option',
'books_sort_auto_sort_active' => 'Auto Sort Active: :sortName',
+ 'books_sort_auto_sort_creation_hint' => 'Auto sort option rules can be created in the "Lists & Sorting" settings area by a user with the relevant permissions.',
'books_sort_named' => 'Razvrsti knjigo :bookName',
'books_sort_name' => 'Razvrsti po imenu',
'books_sort_created' => 'Razvrsti po datumu nastanka',
@@ -330,6 +331,9 @@ return [
// Editor Sidebar
'toggle_sidebar' => 'Toggle Sidebar',
+ 'page_contents' => 'Page Contents',
+ 'page_contents_none' => 'No headings were found in the page content.',
+ 'page_contents_info' => 'The contents menu is generated from any heading formats used in the page.',
'page_tags' => 'Oznake strani',
'chapter_tags' => 'Oznake poglavja',
'book_tags' => 'Oznake knjige',
diff --git a/lang/sl/settings.php b/lang/sl/settings.php
index 947621389..9bd63a0e8 100644
--- a/lang/sl/settings.php
+++ b/lang/sl/settings.php
@@ -207,6 +207,7 @@ return [
'role_all' => 'Vse',
'role_own' => 'Lasten',
'role_controlled_by_asset' => 'Nadzira ga sredstvo, v katerega so naloženi',
+ 'role_controlled_by_page_delete' => 'Controlled by page delete permissions',
'role_save' => 'Shrani vlogo',
'role_users' => 'Uporabniki v tej vlogi',
'role_users_none' => 'Tej vlogi trenutno ni dodeljen noben uporabnik',
@@ -263,6 +264,9 @@ return [
'users_mfa_desc' => 'Setup multi-factor authentication as an extra layer of security for your user account.',
'users_mfa_x_methods' => ':count method configured|:count methods configured',
'users_mfa_configure' => 'Configure Methods',
+ 'users_mfa_reset' => 'Reset Multi-Factor Authentication Methods',
+ 'users_mfa_reset_desc' => 'This will reset and clear all configured multi-factor authentication methods for this user. If multi-factor authentication is required by any of their roles, they\'ll be prompted to configure new methods on their next login.',
+ 'users_mfa_reset_confirm' => 'Are you sure you want to reset multi-factor authentication for this user?',
// API Tokens
'user_api_token_create' => 'Ustvari žeton',
@@ -364,6 +368,7 @@ return [
'sk' => 'Slovensky',
'sl' => 'slovenščina',
'sv' => 'Svenska',
+ 'th' => 'ภาษาไทย',
'tr' => 'Türkçe',
'uk' => 'Українська',
'uz' => 'O‘zbekcha',
diff --git a/lang/sq/activities.php b/lang/sq/activities.php
index 9296d1759..2d41a1121 100644
--- a/lang/sq/activities.php
+++ b/lang/sq/activities.php
@@ -99,6 +99,8 @@ return [
'user_update_notification' => 'Përdoruesi u përditësua me sukses',
'user_delete' => 'fshi përdorues',
'user_delete_notification' => 'Përdoruesi u fshi me sukses',
+ 'user_mfa_reset' => 'reset MFA for user',
+ 'user_mfa_reset_notification' => 'Multi-factor authentication methods reset',
// API Tokens
'api_token_create' => 'Krijoi token API',
diff --git a/lang/sq/auth.php b/lang/sq/auth.php
index 6fdc4ee4a..d5bf7acfb 100644
--- a/lang/sq/auth.php
+++ b/lang/sq/auth.php
@@ -8,6 +8,7 @@ return [
'failed' => 'Këto kredenciale nuk përputhen me të dhënat tona.',
'throttle' => 'Shumë përpjekje për hyrje. Ju lutemi provoni përsëri në :seconds sekonda.',
+ 'mfa_throttle' => 'Too many multi-factor verification attempts. Please try again in :seconds seconds.',
// Login & Register
'sign_up' => 'Regjistrohu',
diff --git a/lang/sq/entities.php b/lang/sq/entities.php
index 74c50be3b..58c00ec4b 100644
--- a/lang/sq/entities.php
+++ b/lang/sq/entities.php
@@ -173,6 +173,7 @@ return [
'books_sort_desc' => 'Move chapters and pages within a book to reorganise its contents. Other books can be added which allows easy moving of chapters and pages between books. Optionally an auto sort rule can be set to automatically sort this book\'s contents upon changes.',
'books_sort_auto_sort' => 'Auto Sort Option',
'books_sort_auto_sort_active' => 'Auto Sort Active: :sortName',
+ 'books_sort_auto_sort_creation_hint' => 'Auto sort option rules can be created in the "Lists & Sorting" settings area by a user with the relevant permissions.',
'books_sort_named' => 'Sort Book :bookName',
'books_sort_name' => 'Sort by Name',
'books_sort_created' => 'Sort by Created Date',
@@ -330,6 +331,9 @@ return [
// Editor Sidebar
'toggle_sidebar' => 'Toggle Sidebar',
+ 'page_contents' => 'Page Contents',
+ 'page_contents_none' => 'No headings were found in the page content.',
+ 'page_contents_info' => 'The contents menu is generated from any heading formats used in the page.',
'page_tags' => 'Page Tags',
'chapter_tags' => 'Chapter Tags',
'book_tags' => 'Book Tags',
diff --git a/lang/sq/settings.php b/lang/sq/settings.php
index c4d1eb136..d03024a89 100644
--- a/lang/sq/settings.php
+++ b/lang/sq/settings.php
@@ -207,6 +207,7 @@ return [
'role_all' => 'All',
'role_own' => 'Own',
'role_controlled_by_asset' => 'Controlled by the asset they are uploaded to',
+ 'role_controlled_by_page_delete' => 'Controlled by page delete permissions',
'role_save' => 'Save Role',
'role_users' => 'Users in this role',
'role_users_none' => 'No users are currently assigned to this role',
@@ -263,6 +264,9 @@ return [
'users_mfa_desc' => 'Setup multi-factor authentication as an extra layer of security for your user account.',
'users_mfa_x_methods' => ':count method configured|:count methods configured',
'users_mfa_configure' => 'Configure Methods',
+ 'users_mfa_reset' => 'Reset Multi-Factor Authentication Methods',
+ 'users_mfa_reset_desc' => 'This will reset and clear all configured multi-factor authentication methods for this user. If multi-factor authentication is required by any of their roles, they\'ll be prompted to configure new methods on their next login.',
+ 'users_mfa_reset_confirm' => 'Are you sure you want to reset multi-factor authentication for this user?',
// API Tokens
'user_api_token_create' => 'Create API Token',
@@ -363,6 +367,7 @@ return [
'sk' => 'Slovensky',
'sl' => 'Slovenščina',
'sv' => 'Svenska',
+ 'th' => 'ภาษาไทย',
'tr' => 'Türkçe',
'uk' => 'Українська',
'uz' => 'O‘zbekcha',
diff --git a/lang/sr/activities.php b/lang/sr/activities.php
index b4aa5e2a7..555d01adc 100644
--- a/lang/sr/activities.php
+++ b/lang/sr/activities.php
@@ -99,6 +99,8 @@ return [
'user_update_notification' => 'Корисник је успешно ажуриран',
'user_delete' => 'избрисан корисника',
'user_delete_notification' => 'Корисник је успешно уклоњен',
+ 'user_mfa_reset' => 'reset MFA for user',
+ 'user_mfa_reset_notification' => 'Multi-factor authentication methods reset',
// API Tokens
'api_token_create' => 'креирао апи токен',
diff --git a/lang/sr/auth.php b/lang/sr/auth.php
index 0100e666f..96169fe2b 100644
--- a/lang/sr/auth.php
+++ b/lang/sr/auth.php
@@ -8,6 +8,7 @@ return [
'failed' => 'Ови акредитиви се не поклапају са нашом евиденцијом.',
'throttle' => 'Превише покушаја пријаве. Покушајте поново за :seconds секунди.',
+ 'mfa_throttle' => 'Too many multi-factor verification attempts. Please try again in :seconds seconds.',
// Login & Register
'sign_up' => 'Региструј се',
diff --git a/lang/sr/entities.php b/lang/sr/entities.php
index 151edee40..cd4e732f4 100644
--- a/lang/sr/entities.php
+++ b/lang/sr/entities.php
@@ -173,6 +173,7 @@ return [
'books_sort_desc' => 'Move chapters and pages within a book to reorganise its contents. Other books can be added which allows easy moving of chapters and pages between books. Optionally an auto sort rule can be set to automatically sort this book\'s contents upon changes.',
'books_sort_auto_sort' => 'Auto Sort Option',
'books_sort_auto_sort_active' => 'Auto Sort Active: :sortName',
+ 'books_sort_auto_sort_creation_hint' => 'Auto sort option rules can be created in the "Lists & Sorting" settings area by a user with the relevant permissions.',
'books_sort_named' => 'Sort Book :bookName',
'books_sort_name' => 'Sort by Name',
'books_sort_created' => 'Sort by Created Date',
@@ -330,6 +331,9 @@ return [
// Editor Sidebar
'toggle_sidebar' => 'Toggle Sidebar',
+ 'page_contents' => 'Page Contents',
+ 'page_contents_none' => 'No headings were found in the page content.',
+ 'page_contents_info' => 'The contents menu is generated from any heading formats used in the page.',
'page_tags' => 'Page Tags',
'chapter_tags' => 'Chapter Tags',
'book_tags' => 'Book Tags',
diff --git a/lang/sr/settings.php b/lang/sr/settings.php
index f6c86827e..143fdaef1 100644
--- a/lang/sr/settings.php
+++ b/lang/sr/settings.php
@@ -207,6 +207,7 @@ return [
'role_all' => 'All',
'role_own' => 'Own',
'role_controlled_by_asset' => 'Controlled by the asset they are uploaded to',
+ 'role_controlled_by_page_delete' => 'Controlled by page delete permissions',
'role_save' => 'Save Role',
'role_users' => 'Users in this role',
'role_users_none' => 'No users are currently assigned to this role',
@@ -263,6 +264,9 @@ return [
'users_mfa_desc' => 'Setup multi-factor authentication as an extra layer of security for your user account.',
'users_mfa_x_methods' => ':count method configured|:count methods configured',
'users_mfa_configure' => 'Configure Methods',
+ 'users_mfa_reset' => 'Reset Multi-Factor Authentication Methods',
+ 'users_mfa_reset_desc' => 'This will reset and clear all configured multi-factor authentication methods for this user. If multi-factor authentication is required by any of their roles, they\'ll be prompted to configure new methods on their next login.',
+ 'users_mfa_reset_confirm' => 'Are you sure you want to reset multi-factor authentication for this user?',
// API Tokens
'user_api_token_create' => 'Create API Token',
@@ -363,6 +367,7 @@ return [
'sk' => 'Slovensky',
'sl' => 'Slovenščina',
'sv' => 'Svenska',
+ 'th' => 'ภาษาไทย',
'tr' => 'Türkçe',
'uk' => 'Українська',
'uz' => 'O‘zbekcha',
diff --git a/lang/sv/activities.php b/lang/sv/activities.php
index 3acf6d4ff..c501c6752 100644
--- a/lang/sv/activities.php
+++ b/lang/sv/activities.php
@@ -99,6 +99,8 @@ return [
'user_update_notification' => 'Användaren har uppdaterats',
'user_delete' => 'raderad användare',
'user_delete_notification' => 'Användaren har tagits bort',
+ 'user_mfa_reset' => 'reset MFA for user',
+ 'user_mfa_reset_notification' => 'Multi-factor authentication methods reset',
// API Tokens
'api_token_create' => 'skapade API-token',
diff --git a/lang/sv/auth.php b/lang/sv/auth.php
index c9feb8312..6c94f21f9 100644
--- a/lang/sv/auth.php
+++ b/lang/sv/auth.php
@@ -8,6 +8,7 @@ return [
'failed' => 'Uppgifterna stämmer inte överens med våra register.',
'throttle' => 'För många inloggningsförsök. Prova igen om :seconds sekunder.',
+ 'mfa_throttle' => 'Too many multi-factor verification attempts. Please try again in :seconds seconds.',
// Login & Register
'sign_up' => 'Skapa konto',
diff --git a/lang/sv/entities.php b/lang/sv/entities.php
index 680e0908a..1df816849 100644
--- a/lang/sv/entities.php
+++ b/lang/sv/entities.php
@@ -173,6 +173,7 @@ return [
'books_sort_desc' => 'Flytta kapitel och sidor inom en bok för att omorganisera dess innehåll. Andra böcker kan läggas till, vilket gör det enkelt att flytta kapitel och sidor mellan böcker. Du kan även ställa in en regel som automatiskt sorterar bokens innehåll vid ändringar.',
'books_sort_auto_sort' => 'Automatiskt sorteringsalternativ',
'books_sort_auto_sort_active' => 'Aktiv automatisk sorteringsregel: :sortName',
+ 'books_sort_auto_sort_creation_hint' => 'Auto sort option rules can be created in the "Lists & Sorting" settings area by a user with the relevant permissions.',
'books_sort_named' => 'Sortera boken :bookName',
'books_sort_name' => 'Sortera utifrån namn',
'books_sort_created' => 'Sortera utifrån skapelse',
@@ -330,6 +331,9 @@ return [
// Editor Sidebar
'toggle_sidebar' => 'Visa/Dölj sidopanel',
+ 'page_contents' => 'Page Contents',
+ 'page_contents_none' => 'No headings were found in the page content.',
+ 'page_contents_info' => 'The contents menu is generated from any heading formats used in the page.',
'page_tags' => 'Sidtaggar',
'chapter_tags' => 'Kapiteltaggar',
'book_tags' => 'Boktaggar',
diff --git a/lang/sv/settings.php b/lang/sv/settings.php
index 773c4bff3..e900a86a3 100644
--- a/lang/sv/settings.php
+++ b/lang/sv/settings.php
@@ -207,6 +207,7 @@ return [
'role_all' => 'Alla',
'role_own' => 'Egna',
'role_controlled_by_asset' => 'Kontrolleras av den sida de laddas upp till',
+ 'role_controlled_by_page_delete' => 'Controlled by page delete permissions',
'role_save' => 'Spara roll',
'role_users' => 'Användare med denna roll',
'role_users_none' => 'Inga användare tillhör den här rollen',
@@ -263,6 +264,9 @@ return [
'users_mfa_desc' => 'Konfigurera multifaktorsautentisering som ett extra skydd för ditt konto.',
'users_mfa_x_methods' => ':count metod konfigurerad|:count metoder konfigurerade',
'users_mfa_configure' => 'Konfigurera metoder',
+ 'users_mfa_reset' => 'Reset Multi-Factor Authentication Methods',
+ 'users_mfa_reset_desc' => 'This will reset and clear all configured multi-factor authentication methods for this user. If multi-factor authentication is required by any of their roles, they\'ll be prompted to configure new methods on their next login.',
+ 'users_mfa_reset_confirm' => 'Are you sure you want to reset multi-factor authentication for this user?',
// API Tokens
'user_api_token_create' => 'Skapa API-nyckel',
@@ -363,6 +367,7 @@ return [
'sk' => 'Slovensky',
'sl' => 'Slovenska',
'sv' => 'Svenska',
+ 'th' => 'ภาษาไทย',
'tr' => 'Türkçe',
'uk' => 'Українська',
'uz' => 'O‘zbekcha',
diff --git a/lang/th/activities.php b/lang/th/activities.php
new file mode 100644
index 000000000..0ea18ca0a
--- /dev/null
+++ b/lang/th/activities.php
@@ -0,0 +1,142 @@
+ 'สร้างหน้า',
+ 'page_create_notification' => 'สร้างหน้าสำเร็จแล้ว',
+ 'page_update' => 'แก้ไขหน้า',
+ 'page_update_notification' => 'แก้ไขหน้าสำเร็จแล้ว',
+ 'page_delete' => 'ลบหน้า',
+ 'page_delete_notification' => 'ลบหน้าสำเร็จแล้ว',
+ 'page_restore' => 'กู้คืนหน้า',
+ 'page_restore_notification' => 'กู้คืนหน้าสำเร็จแล้ว',
+ 'page_move' => 'ย้ายหน้า',
+ 'page_move_notification' => 'ย้ายหน้าสำเร็จแล้ว',
+
+ // Chapters
+ 'chapter_create' => 'สร้างบท',
+ 'chapter_create_notification' => 'สร้างบทสำเร็จแล้ว',
+ 'chapter_update' => 'แก้ไขบท',
+ 'chapter_update_notification' => 'แก้ไขบทสำเร็จแล้ว',
+ 'chapter_delete' => 'ลบบท',
+ 'chapter_delete_notification' => 'ลบบทสำเร็จแล้ว',
+ 'chapter_move' => 'ย้ายบท',
+ 'chapter_move_notification' => 'ย้ายบทสำเร็จแล้ว',
+
+ // Books
+ 'book_create' => 'สร้างหนังสือ',
+ 'book_create_notification' => 'สร้างหนังสือสำเร็จแล้ว',
+ 'book_create_from_chapter' => 'แปลงบทเป็นหนังสือ',
+ 'book_create_from_chapter_notification' => 'แปลงบทเป็นหนังสือสำเร็จแล้ว',
+ 'book_update' => 'แก้ไขหนังสือ',
+ 'book_update_notification' => 'แก้ไขหนังสือสำเร็จแล้ว',
+ 'book_delete' => 'ลบหนังสือ',
+ 'book_delete_notification' => 'ลบหนังสือสำเร็จแล้ว',
+ 'book_sort' => 'จัดเรียงหนังสือ',
+ 'book_sort_notification' => 'จัดเรียงหนังสือสำเร็จแล้ว',
+
+ // Bookshelves
+ 'bookshelf_create' => 'สร้างชั้นวาง',
+ 'bookshelf_create_notification' => 'สร้างชั้นวางสำเร็จแล้ว',
+ 'bookshelf_create_from_book' => 'แปลงหนังสือเป็นชั้นวาง',
+ 'bookshelf_create_from_book_notification' => 'แปลงหนังสือเป็นชั้นวางสำเร็จแล้ว',
+ 'bookshelf_update' => 'แก้ไขชั้นวาง',
+ 'bookshelf_update_notification' => 'แก้ไขชั้นวางสำเร็จแล้ว',
+ 'bookshelf_delete' => 'ลบชั้นวาง',
+ 'bookshelf_delete_notification' => 'ลบชั้นวางสำเร็จแล้ว',
+
+ // Revisions
+ 'revision_restore' => 'กู้คืนการแก้ไข',
+ 'revision_delete' => 'ลบการแก้ไข',
+ 'revision_delete_notification' => 'ลบการแก้ไขสำเร็จแล้ว',
+
+ // Favourites
+ 'favourite_add_notification' => 'เพิ่ม ":name" ในรายการโปรดแล้ว',
+ 'favourite_remove_notification' => 'นำ ":name" ออกจากรายการโปรดแล้ว',
+
+ // Watching
+ 'watch_update_level_notification' => 'อัปเดตการตั้งค่าการติดตามสำเร็จแล้ว',
+
+ // Auth
+ 'auth_login' => 'เข้าสู่ระบบ',
+ 'auth_register' => 'ลงทะเบียนเป็นผู้ใช้ใหม่',
+ 'auth_password_reset_request' => 'ขอรีเซ็ตรหัสผ่าน',
+ 'auth_password_reset_update' => 'รีเซ็ตรหัสผ่านแล้ว',
+ 'mfa_setup_method' => 'ตั้งค่าวิธียืนยันตัวตน MFA',
+ 'mfa_setup_method_notification' => 'ตั้งค่าการยืนยันตัวตนแบบหลายขั้นตอนสำเร็จแล้ว',
+ 'mfa_remove_method' => 'ลบวิธียืนยันตัวตน MFA',
+ 'mfa_remove_method_notification' => 'ลบการยืนยันตัวตนแบบหลายขั้นตอนสำเร็จแล้ว',
+
+ // Settings
+ 'settings_update' => 'แก้ไขการตั้งค่า',
+ 'settings_update_notification' => 'แก้ไขการตั้งค่าสำเร็จแล้ว',
+ 'maintenance_action_run' => 'ดำเนินการบำรุงรักษาระบบ',
+
+ // Webhooks
+ 'webhook_create' => 'สร้าง Webhook',
+ 'webhook_create_notification' => 'สร้าง Webhook สำเร็จแล้ว',
+ 'webhook_update' => 'แก้ไข Webhook',
+ 'webhook_update_notification' => 'แก้ไข Webhook สำเร็จแล้ว',
+ 'webhook_delete' => 'ลบ Webhook',
+ 'webhook_delete_notification' => 'ลบ Webhook สำเร็จแล้ว',
+
+ // Imports
+ 'import_create' => 'สร้างการนำเข้า',
+ 'import_create_notification' => 'อัปโหลดไฟล์นำเข้าสำเร็จแล้ว',
+ 'import_run' => 'ดำเนินการนำเข้า',
+ 'import_run_notification' => 'นำเข้าเนื้อหาสำเร็จแล้ว',
+ 'import_delete' => 'ลบการนำเข้า',
+ 'import_delete_notification' => 'ลบการนำเข้าสำเร็จแล้ว',
+
+ // Users
+ 'user_create' => 'สร้างผู้ใช้',
+ 'user_create_notification' => 'สร้างผู้ใช้สำเร็จแล้ว',
+ 'user_update' => 'แก้ไขผู้ใช้',
+ 'user_update_notification' => 'แก้ไขผู้ใช้สำเร็จแล้ว',
+ 'user_delete' => 'ลบผู้ใช้',
+ 'user_delete_notification' => 'ลบผู้ใช้สำเร็จแล้ว',
+ 'user_mfa_reset' => 'reset MFA for user',
+ 'user_mfa_reset_notification' => 'Multi-factor authentication methods reset',
+
+ // API Tokens
+ 'api_token_create' => 'สร้าง API Token',
+ 'api_token_create_notification' => 'สร้าง API Token สำเร็จแล้ว',
+ 'api_token_update' => 'แก้ไข API Token',
+ 'api_token_update_notification' => 'แก้ไข API Token สำเร็จแล้ว',
+ 'api_token_delete' => 'ลบ API Token',
+ 'api_token_delete_notification' => 'ลบ API Token สำเร็จแล้ว',
+
+ // Roles
+ 'role_create' => 'สร้างบทบาท',
+ 'role_create_notification' => 'สร้างบทบาทสำเร็จแล้ว',
+ 'role_update' => 'แก้ไขบทบาท',
+ 'role_update_notification' => 'แก้ไขบทบาทสำเร็จแล้ว',
+ 'role_delete' => 'ลบบทบาท',
+ 'role_delete_notification' => 'ลบบทบาทสำเร็จแล้ว',
+
+ // Recycle Bin
+ 'recycle_bin_empty' => 'ล้างถังรีไซเคิล',
+ 'recycle_bin_restore' => 'กู้คืนจากถังรีไซเคิล',
+ 'recycle_bin_destroy' => 'ลบถาวรจากถังรีไซเคิล',
+
+ // Comments
+ 'commented_on' => 'แสดงความคิดเห็นใน',
+ 'comment_create' => 'เพิ่มความคิดเห็น',
+ 'comment_update' => 'แก้ไขความคิดเห็น',
+ 'comment_delete' => 'ลบความคิดเห็น',
+
+ // Sort Rules
+ 'sort_rule_create' => 'สร้างกฎการจัดเรียง',
+ 'sort_rule_create_notification' => 'สร้างกฎการจัดเรียงสำเร็จแล้ว',
+ 'sort_rule_update' => 'แก้ไขกฎการจัดเรียง',
+ 'sort_rule_update_notification' => 'แก้ไขกฎการจัดเรียงสำเร็จแล้ว',
+ 'sort_rule_delete' => 'ลบกฎการจัดเรียง',
+ 'sort_rule_delete_notification' => 'ลบกฎการจัดเรียงสำเร็จแล้ว',
+
+ // Other
+ 'permissions_update' => 'แก้ไขสิทธิ์',
+];
diff --git a/lang/th/auth.php b/lang/th/auth.php
new file mode 100644
index 000000000..ca24b593c
--- /dev/null
+++ b/lang/th/auth.php
@@ -0,0 +1,118 @@
+ 'ข้อมูลประจำตัวไม่ตรงกับที่มีในระบบ',
+ 'throttle' => 'เข้าสู่ระบบล้มเหลวหลายครั้งเกินไป กรุณาลองใหม่ในอีก :seconds วินาที',
+ 'mfa_throttle' => 'Too many multi-factor verification attempts. Please try again in :seconds seconds.',
+
+ // Login & Register
+ 'sign_up' => 'สมัครสมาชิก',
+ 'log_in' => 'เข้าสู่ระบบ',
+ 'log_in_with' => 'เข้าสู่ระบบด้วย :socialDriver',
+ 'sign_up_with' => 'สมัครสมาชิกด้วย :socialDriver',
+ 'logout' => 'ออกจากระบบ',
+
+ 'name' => 'ชื่อ',
+ 'username' => 'ชื่อผู้ใช้',
+ 'email' => 'อีเมล',
+ 'password' => 'รหัสผ่าน',
+ 'password_confirm' => 'ยืนยันรหัสผ่าน',
+ 'password_hint' => 'ต้องมีอย่างน้อย 8 ตัวอักษร',
+ 'forgot_password' => 'ลืมรหัสผ่าน?',
+ 'remember_me' => 'จดจำฉัน',
+ 'ldap_email_hint' => 'กรุณากรอกอีเมลที่จะใช้กับบัญชีนี้',
+ 'create_account' => 'สร้างบัญชี',
+ 'already_have_account' => 'มีบัญชีอยู่แล้ว?',
+ 'dont_have_account' => 'ยังไม่มีบัญชี?',
+ 'social_login' => 'เข้าสู่ระบบด้วย Social',
+ 'social_registration' => 'ลงทะเบียนด้วย Social',
+ 'social_registration_text' => 'ลงทะเบียนและเข้าสู่ระบบด้วยบริการอื่น',
+
+ 'register_thanks' => 'ขอบคุณที่ลงทะเบียน กรุณายืนยันอีเมลเพื่อเข้าสู่ระบบ',
+ 'register_confirm' => 'ยืนยันและลงทะเบียน',
+ 'registrations_disabled' => 'ขณะนี้ปิดรับการลงทะเบียน',
+ 'registration_email_domain_invalid' => 'โดเมนอีเมลนี้ไม่มีสิทธิ์เข้าถึงระบบ',
+ 'register_success' => 'ขอบคุณที่สมัครสมาชิก คุณได้ลงทะเบียนและเข้าสู่ระบบแล้ว',
+
+ // Login auto-initiation
+ 'auto_init_starting' => 'กำลังเข้าสู่ระบบ',
+ 'auto_init_starting_desc' => 'กำลังติดต่อระบบยืนยันตัวตนเพื่อเริ่มกระบวนการเข้าสู่ระบบ หากไม่มีความคืบหน้าภายใน 5 วินาที กรุณาคลิกลิงก์ด้านล่าง',
+ 'auto_init_start_link' => 'ดำเนินการยืนยันตัวตน',
+
+ // Password Reset
+ 'reset_password' => 'รีเซ็ตรหัสผ่าน',
+ 'reset_password_send_instructions' => 'กรอกอีเมลด้านล่าง ระบบจะส่งลิงก์รีเซ็ตรหัสผ่านให้คุณ',
+ 'reset_password_send_button' => 'ส่งลิงก์รีเซ็ตรหัสผ่าน',
+ 'reset_password_sent' => 'หากพบอีเมล :email ในระบบ จะมีลิงก์รีเซ็ตรหัสผ่านส่งไปให้',
+ 'reset_password_success' => 'รีเซ็ตรหัสผ่านสำเร็จแล้ว',
+ 'email_reset_subject' => 'รีเซ็ตรหัสผ่าน :appName ของคุณ',
+ 'email_reset_text' => 'คุณได้รับอีเมลนี้เพราะมีการขอรีเซ็ตรหัสผ่านสำหรับบัญชีของคุณ',
+ 'email_reset_not_requested' => 'หากคุณไม่ได้ขอรีเซ็ตรหัสผ่าน ไม่ต้องดำเนินการใดๆ เพิ่มเติม',
+
+ // Email Confirmation
+ 'email_confirm_subject' => 'ยืนยันอีเมลของคุณบน :appName',
+ 'email_confirm_greeting' => 'ขอบคุณที่เข้าร่วม :appName!',
+ 'email_confirm_text' => 'กรุณายืนยันอีเมลของคุณโดยคลิกปุ่มด้านล่าง:',
+ 'email_confirm_action' => 'ยืนยันอีเมล',
+ 'email_confirm_send_error' => 'จำเป็นต้องยืนยันอีเมล แต่ระบบไม่สามารถส่งอีเมลได้ กรุณาติดต่อผู้ดูแลระบบเพื่อตรวจสอบการตั้งค่าอีเมล',
+ 'email_confirm_success' => 'ยืนยันอีเมลสำเร็จแล้ว สามารถเข้าสู่ระบบได้',
+ 'email_confirm_resent' => 'ส่งอีเมลยืนยันใหม่แล้ว กรุณาตรวจสอบกล่องจดหมาย',
+ 'email_confirm_thanks' => 'ขอบคุณที่ยืนยัน!',
+ 'email_confirm_thanks_desc' => 'กรุณารอสักครู่ขณะที่ระบบดำเนินการยืนยัน หากไม่ถูกเปลี่ยนหน้าภายใน 3 วินาที กรุณาคลิกลิงก์ "ดำเนินการต่อ" ด้านล่าง',
+
+ 'email_not_confirmed' => 'ยังไม่ได้ยืนยันอีเมล',
+ 'email_not_confirmed_text' => 'อีเมลของคุณยังไม่ได้รับการยืนยัน',
+ 'email_not_confirmed_click_link' => 'กรุณาคลิกลิงก์ในอีเมลที่ส่งให้คุณหลังจากลงทะเบียน',
+ 'email_not_confirmed_resend' => 'หากไม่พบอีเมล คุณสามารถส่งอีเมลยืนยันอีกครั้งโดยกรอกแบบฟอร์มด้านล่าง',
+ 'email_not_confirmed_resend_button' => 'ส่งอีเมลยืนยันอีกครั้ง',
+
+ // User Invite
+ 'user_invite_email_subject' => 'คุณได้รับเชิญให้เข้าร่วม :appName!',
+ 'user_invite_email_greeting' => 'มีการสร้างบัญชีให้คุณบน :appName',
+ 'user_invite_email_text' => 'คลิกปุ่มด้านล่างเพื่อตั้งรหัสผ่านและเข้าใช้งาน:',
+ 'user_invite_email_action' => 'ตั้งรหัสผ่านบัญชี',
+ 'user_invite_page_welcome' => 'ยินดีต้อนรับสู่ :appName!',
+ 'user_invite_page_text' => 'เพื่อเสร็จสิ้นการสร้างบัญชีและเข้าใช้งาน คุณต้องตั้งรหัสผ่านสำหรับเข้าสู่ :appName ในครั้งถัดไป',
+ 'user_invite_page_confirm_button' => 'ยืนยันรหัสผ่าน',
+ 'user_invite_success_login' => 'ตั้งรหัสผ่านแล้ว คุณสามารถเข้าสู่ระบบ :appName ด้วยรหัสผ่านที่ตั้งไว้ได้แล้ว!',
+
+ // Multi-factor Authentication
+ 'mfa_setup' => 'ตั้งค่าการยืนยันตัวตนแบบหลายขั้นตอน',
+ 'mfa_setup_desc' => 'ตั้งค่า MFA เพื่อเพิ่มความปลอดภัยให้บัญชีของคุณ',
+ 'mfa_setup_configured' => 'ตั้งค่าแล้ว',
+ 'mfa_setup_reconfigure' => 'ตั้งค่าใหม่',
+ 'mfa_setup_remove_confirmation' => 'คุณแน่ใจหรือไม่ว่าต้องการลบวิธียืนยันตัวตนแบบหลายขั้นตอนนี้?',
+ 'mfa_setup_action' => 'ตั้งค่า',
+ 'mfa_backup_codes_usage_limit_warning' => 'คุณมีรหัสสำรองเหลือน้อยกว่า 5 รหัส กรุณาสร้างและบันทึกชุดใหม่ก่อนหมด เพื่อป้องกันการถูกล็อกออกจากบัญชี',
+ 'mfa_option_totp_title' => 'แอป Authenticator',
+ 'mfa_option_totp_desc' => 'ในการใช้การยืนยันตัวตนแบบหลายขั้นตอน คุณต้องมีแอปพลิเคชันมือถือที่รองรับ TOTP เช่น Google Authenticator, Authy หรือ Microsoft Authenticator',
+ 'mfa_option_backup_codes_title' => 'รหัสสำรอง',
+ 'mfa_option_backup_codes_desc' => 'สร้างชุดรหัสสำรองแบบใช้ครั้งเดียว ซึ่งจะใช้กรอกเมื่อเข้าสู่ระบบเพื่อยืนยันตัวตน กรุณาเก็บรักษาไว้ในที่ปลอดภัย',
+ 'mfa_gen_confirm_and_enable' => 'ยืนยันและเปิดใช้งาน',
+ 'mfa_gen_backup_codes_title' => 'ตั้งค่ารหัสสำรอง',
+ 'mfa_gen_backup_codes_desc' => 'บันทึกรายการรหัสด้านล่างไว้ในที่ปลอดภัย เมื่อเข้าระบบคุณสามารถใช้รหัสเหล่านี้เป็นการยืนยันตัวตนขั้นที่สองได้',
+ 'mfa_gen_backup_codes_download' => 'ดาวน์โหลดรหัส',
+ 'mfa_gen_backup_codes_usage_warning' => 'รหัสแต่ละรหัสใช้ได้เพียงครั้งเดียว',
+ 'mfa_gen_totp_title' => 'ตั้งค่าแอปมือถือ',
+ 'mfa_gen_totp_desc' => 'ในการใช้การยืนยันตัวตนแบบหลายขั้นตอน คุณต้องมีแอปพลิเคชันมือถือที่รองรับ TOTP เช่น Google Authenticator, Authy หรือ Microsoft Authenticator',
+ 'mfa_gen_totp_scan' => 'สแกน QR code ด้านล่างด้วยแอป Authenticator ที่คุณต้องการใช้',
+ 'mfa_gen_totp_verify_setup' => 'ยืนยันการตั้งค่า',
+ 'mfa_gen_totp_verify_setup_desc' => 'ยืนยันว่าทุกอย่างทำงานได้โดยกรอกรหัสที่สร้างจากแอป Authenticator ในช่องด้านล่าง:',
+ 'mfa_gen_totp_provide_code_here' => 'กรอกรหัสที่สร้างจากแอปของคุณที่นี่',
+ 'mfa_verify_access' => 'ยืนยันการเข้าถึง',
+ 'mfa_verify_access_desc' => 'บัญชีของคุณต้องยืนยันตัวตนผ่านการตรวจสอบเพิ่มเติมก่อนเข้าใช้งาน กรุณายืนยันด้วยวิธีที่ตั้งค่าไว้เพื่อดำเนินการต่อ',
+ 'mfa_verify_no_methods' => 'ยังไม่ได้ตั้งค่าวิธียืนยันตัวตน',
+ 'mfa_verify_no_methods_desc' => 'ไม่พบวิธียืนยันตัวตนแบบหลายขั้นตอนสำหรับบัญชีของคุณ กรุณาตั้งค่าอย่างน้อยหนึ่งวิธีก่อนเข้าใช้งาน',
+ 'mfa_verify_use_totp' => 'ยืนยันด้วยแอปมือถือ',
+ 'mfa_verify_use_backup_codes' => 'ยืนยันด้วยรหัสสำรอง',
+ 'mfa_verify_backup_code' => 'รหัสสำรอง',
+ 'mfa_verify_backup_code_desc' => 'กรอกรหัสสำรองที่เหลืออยู่ของคุณด้านล่าง:',
+ 'mfa_verify_backup_code_enter_here' => 'กรอกรหัสสำรองที่นี่',
+ 'mfa_verify_totp_desc' => 'กรอกรหัสที่สร้างจากแอปมือถือของคุณด้านล่าง:',
+ 'mfa_setup_login_notification' => 'ตั้งค่าวิธียืนยันตัวตนแล้ว กรุณาเข้าสู่ระบบอีกครั้งด้วยวิธีที่ตั้งค่าไว้',
+];
diff --git a/lang/th/common.php b/lang/th/common.php
new file mode 100644
index 000000000..9a8b4fcc5
--- /dev/null
+++ b/lang/th/common.php
@@ -0,0 +1,115 @@
+ 'ยกเลิก',
+ 'close' => 'ปิด',
+ 'confirm' => 'ยืนยัน',
+ 'back' => 'ย้อนกลับ',
+ 'save' => 'บันทึก',
+ 'continue' => 'ดำเนินการต่อ',
+ 'select' => 'เลือก',
+ 'toggle_all' => 'สลับทั้งหมด',
+ 'more' => 'เพิ่มเติม',
+
+ // Form Labels
+ 'name' => 'ชื่อ',
+ 'description' => 'คำอธิบาย',
+ 'role' => 'บทบาท',
+ 'cover_image' => 'ภาพปก',
+ 'cover_image_description' => 'รูปภาพนี้ควรมีขนาดประมาณ 440x250px แต่จะถูกปรับขนาดและตัดให้เหมาะกับการแสดงผลในสถานการณ์ต่างๆ ดังนั้นขนาดที่แสดงจริงอาจแตกต่างกัน',
+
+ // Actions
+ 'actions' => 'การดำเนินการ',
+ 'view' => 'ดู',
+ 'view_all' => 'ดูทั้งหมด',
+ 'new' => 'ใหม่',
+ 'create' => 'สร้าง',
+ 'update' => 'อัปเดต',
+ 'edit' => 'แก้ไข',
+ 'archive' => 'เก็บถาวร',
+ 'unarchive' => 'ยกเลิกการเก็บถาวร',
+ 'sort' => 'จัดเรียง',
+ 'move' => 'ย้าย',
+ 'copy' => 'คัดลอก',
+ 'reply' => 'ตอบกลับ',
+ 'delete' => 'ลบ',
+ 'delete_confirm' => 'ยืนยันการลบ',
+ 'search' => 'ค้นหา',
+ 'search_clear' => 'ล้างการค้นหา',
+ 'reset' => 'รีเซ็ต',
+ 'remove' => 'ลบออก',
+ 'add' => 'เพิ่ม',
+ 'configure' => 'กำหนดค่า',
+ 'manage' => 'จัดการ',
+ 'fullscreen' => 'เต็มหน้าจอ',
+ 'favourite' => 'เพิ่มในรายการโปรด',
+ 'unfavourite' => 'นำออกจากรายการโปรด',
+ 'next' => 'ถัดไป',
+ 'previous' => 'ก่อนหน้า',
+ 'filter_active' => 'ตัวกรองที่ใช้งานอยู่:',
+ 'filter_clear' => 'ล้างตัวกรอง',
+ 'download' => 'ดาวน์โหลด',
+ 'open_in_tab' => 'เปิดในแท็บใหม่',
+ 'open' => 'เปิด',
+
+ // Sort Options
+ 'sort_options' => 'ตัวเลือกการจัดเรียง',
+ 'sort_direction_toggle' => 'สลับทิศทางการจัดเรียง',
+ 'sort_ascending' => 'จัดเรียงจากน้อยไปมาก',
+ 'sort_descending' => 'จัดเรียงจากมากไปน้อย',
+ 'sort_name' => 'ชื่อ',
+ 'sort_default' => 'ค่าเริ่มต้น',
+ 'sort_created_at' => 'วันที่สร้าง',
+ 'sort_updated_at' => 'วันที่แก้ไขล่าสุด',
+
+ // Misc
+ 'deleted_user' => 'ผู้ใช้ที่ถูกลบ',
+ 'no_activity' => 'ไม่มีกิจกรรมที่จะแสดง',
+ 'no_items' => 'ไม่มีรายการ',
+ 'back_to_top' => 'กลับไปด้านบน',
+ 'skip_to_main_content' => 'ข้ามไปยังเนื้อหาหลัก',
+ 'toggle_details' => 'แสดง/ซ่อนรายละเอียด',
+ 'toggle_thumbnails' => 'แสดง/ซ่อนภาพย่อ',
+ 'details' => 'รายละเอียด',
+ 'grid_view' => 'มุมมองตาราง',
+ 'list_view' => 'มุมมองรายการ',
+ 'default' => 'ค่าเริ่มต้น',
+ 'breadcrumb' => 'เส้นทางนำทาง',
+ 'status' => 'สถานะ',
+ 'status_active' => 'ใช้งาน',
+ 'status_inactive' => 'ไม่ใช้งาน',
+ 'never' => 'ไม่เคย',
+ 'none' => 'ไม่มี',
+
+ // Header
+ 'homepage' => 'หน้าแรก',
+ 'header_menu_expand' => 'ขยายเมนูส่วนหัว',
+ 'profile_menu' => 'เมนูโปรไฟล์',
+ 'view_profile' => 'ดูโปรไฟล์',
+ 'edit_profile' => 'แก้ไขโปรไฟล์',
+ 'dark_mode' => 'โหมดมืด',
+ 'light_mode' => 'โหมดสว่าง',
+ 'global_search' => 'ค้นหาทั้งระบบ',
+
+ // Layout tabs
+ 'tab_info' => 'ข้อมูล',
+ 'tab_info_label' => 'แท็บ: แสดงข้อมูลเพิ่มเติม',
+ 'tab_content' => 'เนื้อหา',
+ 'tab_content_label' => 'แท็บ: แสดงเนื้อหาหลัก',
+
+ // Email Content
+ 'email_action_help' => 'หากไม่สามารถคลิกปุ่ม ":actionText" ได้ กรุณาคัดลอก URL ด้านล่างและวางในเบราว์เซอร์:',
+ 'email_rights' => 'สงวนลิขสิทธิ์',
+
+ // Footer Link Options
+ // Not directly used but available for convenience to users.
+ 'privacy_policy' => 'นโยบายความเป็นส่วนตัว',
+ 'terms_of_service' => 'ข้อกำหนดการใช้งาน',
+
+ // OpenSearch
+ 'opensearch_description' => 'ค้นหา :appName',
+];
diff --git a/lang/th/components.php b/lang/th/components.php
new file mode 100644
index 000000000..2931d2bc7
--- /dev/null
+++ b/lang/th/components.php
@@ -0,0 +1,46 @@
+ 'เลือกรูปภาพ',
+ 'image_list' => 'รายการรูปภาพ',
+ 'image_details' => 'รายละเอียดรูปภาพ',
+ 'image_upload' => 'อัปโหลดรูปภาพ',
+ 'image_intro' => 'คุณสามารถเลือกและจัดการรูปภาพที่เคยอัปโหลดไว้ในระบบได้ที่นี่',
+ 'image_intro_upload' => 'อัปโหลดรูปภาพใหม่โดยลากไฟล์รูปภาพมาวางในหน้าต่างนี้ หรือใช้ปุ่ม "อัปโหลดรูปภาพ" ด้านบน',
+ 'image_all' => 'ทั้งหมด',
+ 'image_all_title' => 'ดูรูปภาพทั้งหมด',
+ 'image_book_title' => 'ดูรูปภาพที่อัปโหลดในหนังสือนี้',
+ 'image_page_title' => 'ดูรูปภาพที่อัปโหลดในหน้านี้',
+ 'image_search_hint' => 'ค้นหาตามชื่อรูปภาพ',
+ 'image_uploaded' => 'อัปโหลดเมื่อ :uploadedDate',
+ 'image_uploaded_by' => 'อัปโหลดโดย :userName',
+ 'image_uploaded_to' => 'อัปโหลดไปยัง :pageLink',
+ 'image_updated' => 'อัปเดตเมื่อ :updateDate',
+ 'image_load_more' => 'โหลดเพิ่มเติม',
+ 'image_image_name' => 'ชื่อรูปภาพ',
+ 'image_delete_used' => 'รูปภาพนี้ถูกใช้งานในหน้าด้านล่าง',
+ 'image_delete_confirm_text' => 'คุณแน่ใจหรือไม่ว่าต้องการลบรูปภาพนี้?',
+ 'image_select_image' => 'เลือกรูปภาพ',
+ 'image_dropzone' => 'วางรูปภาพหรือคลิกที่นี่เพื่ออัปโหลด',
+ 'image_dropzone_drop' => 'วางรูปภาพที่นี่เพื่ออัปโหลด',
+ 'images_deleted' => 'ลบรูปภาพแล้ว',
+ 'image_preview' => 'ดูตัวอย่างรูปภาพ',
+ 'image_upload_success' => 'อัปโหลดรูปภาพสำเร็จแล้ว',
+ 'image_update_success' => 'อัปเดตรายละเอียดรูปภาพสำเร็จแล้ว',
+ 'image_delete_success' => 'ลบรูปภาพสำเร็จแล้ว',
+ 'image_replace' => 'แทนที่รูปภาพ',
+ 'image_replace_success' => 'อัปเดตไฟล์รูปภาพสำเร็จแล้ว',
+ 'image_rebuild_thumbs' => 'สร้างภาพย่อขนาดต่างๆ ใหม่',
+ 'image_rebuild_thumbs_success' => 'สร้างภาพย่อขนาดต่างๆ ใหม่สำเร็จแล้ว!',
+
+ // Code Editor
+ 'code_editor' => 'แก้ไขโค้ด',
+ 'code_language' => 'ภาษาโค้ด',
+ 'code_content' => 'เนื้อหาโค้ด',
+ 'code_session_history' => 'ประวัติเซสชัน',
+ 'code_save' => 'บันทึกโค้ด',
+];
diff --git a/lang/th/editor.php b/lang/th/editor.php
new file mode 100644
index 000000000..4af059bf1
--- /dev/null
+++ b/lang/th/editor.php
@@ -0,0 +1,182 @@
+ 'ทั่วไป',
+ 'advanced' => 'ขั้นสูง',
+ 'none' => 'ไม่มี',
+ 'cancel' => 'ยกเลิก',
+ 'save' => 'บันทึก',
+ 'close' => 'ปิด',
+ 'apply' => 'ใช้งาน',
+ 'undo' => 'เลิกทำ',
+ 'redo' => 'ทำซ้ำ',
+ 'left' => 'ซ้าย',
+ 'center' => 'กลาง',
+ 'right' => 'ขวา',
+ 'top' => 'บน',
+ 'middle' => 'กลาง',
+ 'bottom' => 'ล่าง',
+ 'width' => 'ความกว้าง',
+ 'height' => 'ความสูง',
+ 'More' => 'เพิ่มเติม',
+ 'select' => 'เลือก...',
+
+ // Toolbar
+ 'formats' => 'รูปแบบ',
+ 'header_large' => 'หัวข้อใหญ่',
+ 'header_medium' => 'หัวข้อกลาง',
+ 'header_small' => 'หัวข้อเล็ก',
+ 'header_tiny' => 'หัวข้อเล็กมาก',
+ 'paragraph' => 'ย่อหน้า',
+ 'blockquote' => 'คำพูดอ้างอิง',
+ 'inline_code' => 'โค้ดแบบอินไลน์',
+ 'callouts' => 'กล่องข้อความเน้น',
+ 'callout_information' => 'ข้อมูล',
+ 'callout_success' => 'สำเร็จ',
+ 'callout_warning' => 'คำเตือน',
+ 'callout_danger' => 'อันตราย',
+ 'bold' => 'ตัวหนา',
+ 'italic' => 'ตัวเอียง',
+ 'underline' => 'ขีดเส้นใต้',
+ 'strikethrough' => 'ขีดทับ',
+ 'superscript' => 'ตัวยก',
+ 'subscript' => 'ตัวห้อย',
+ 'text_color' => 'สีตัวอักษร',
+ 'highlight_color' => 'สีไฮไลต์',
+ 'custom_color' => 'สีกำหนดเอง',
+ 'remove_color' => 'ลบสี',
+ 'background_color' => 'สีพื้นหลัง',
+ 'align_left' => 'จัดชิดซ้าย',
+ 'align_center' => 'จัดกึ่งกลาง',
+ 'align_right' => 'จัดชิดขวา',
+ 'align_justify' => 'จัดเต็มบรรทัด',
+ 'list_bullet' => 'รายการแบบจุด',
+ 'list_numbered' => 'รายการแบบตัวเลข',
+ 'list_task' => 'รายการงาน',
+ 'indent_increase' => 'เพิ่มการย่อหน้า',
+ 'indent_decrease' => 'ลดการย่อหน้า',
+ 'table' => 'ตาราง',
+ 'insert_image' => 'แทรกรูปภาพ',
+ 'insert_image_title' => 'แทรก/แก้ไขรูปภาพ',
+ 'insert_link' => 'แทรก/แก้ไขลิงก์',
+ 'insert_link_title' => 'แทรก/แก้ไขลิงก์',
+ 'insert_horizontal_line' => 'แทรกเส้นแนวนอน',
+ 'insert_code_block' => 'แทรกบล็อกโค้ด',
+ 'edit_code_block' => 'แก้ไขบล็อกโค้ด',
+ 'insert_drawing' => 'แทรก/แก้ไขภาพวาด',
+ 'drawing_manager' => 'ตัวจัดการภาพวาด',
+ 'insert_media' => 'แทรก/แก้ไขสื่อ',
+ 'insert_media_title' => 'แทรก/แก้ไขสื่อ',
+ 'clear_formatting' => 'ล้างการจัดรูปแบบ',
+ 'source_code' => 'ซอร์สโค้ด',
+ 'source_code_title' => 'ซอร์สโค้ด',
+ 'fullscreen' => 'เต็มหน้าจอ',
+ 'image_options' => 'ตัวเลือกรูปภาพ',
+
+ // Tables
+ 'table_properties' => 'คุณสมบัติตาราง',
+ 'table_properties_title' => 'คุณสมบัติตาราง',
+ 'delete_table' => 'ลบตาราง',
+ 'table_clear_formatting' => 'ล้างการจัดรูปแบบตาราง',
+ 'resize_to_contents' => 'ปรับขนาดตามเนื้อหา',
+ 'row_header' => 'แถวหัวตาราง',
+ 'insert_row_before' => 'แทรกแถวก่อนหน้า',
+ 'insert_row_after' => 'แทรกแถวถัดไป',
+ 'delete_row' => 'ลบแถว',
+ 'insert_column_before' => 'แทรกคอลัมน์ก่อนหน้า',
+ 'insert_column_after' => 'แทรกคอลัมน์ถัดไป',
+ 'delete_column' => 'ลบคอลัมน์',
+ 'table_cell' => 'เซลล์',
+ 'table_row' => 'แถว',
+ 'table_column' => 'คอลัมน์',
+ 'cell_properties' => 'คุณสมบัติเซลล์',
+ 'cell_properties_title' => 'คุณสมบัติเซลล์',
+ 'cell_type' => 'ประเภทเซลล์',
+ 'cell_type_cell' => 'เซลล์',
+ 'cell_scope' => 'ขอบเขต',
+ 'cell_type_header' => 'เซลล์หัวตาราง',
+ 'merge_cells' => 'รวมเซลล์',
+ 'split_cell' => 'แยกเซลล์',
+ 'table_row_group' => 'กลุ่มแถว',
+ 'table_column_group' => 'กลุ่มคอลัมน์',
+ 'horizontal_align' => 'การจัดแนวนอน',
+ 'vertical_align' => 'การจัดแนวตั้ง',
+ 'border_width' => 'ความกว้างเส้นขอบ',
+ 'border_style' => 'รูปแบบเส้นขอบ',
+ 'border_color' => 'สีเส้นขอบ',
+ 'row_properties' => 'คุณสมบัติแถว',
+ 'row_properties_title' => 'คุณสมบัติแถว',
+ 'cut_row' => 'ตัดแถว',
+ 'copy_row' => 'คัดลอกแถว',
+ 'paste_row_before' => 'วางแถวก่อนหน้า',
+ 'paste_row_after' => 'วางแถวถัดไป',
+ 'row_type' => 'ประเภทแถว',
+ 'row_type_header' => 'ส่วนหัว',
+ 'row_type_body' => 'ส่วนเนื้อหา',
+ 'row_type_footer' => 'ส่วนท้าย',
+ 'alignment' => 'การจัดตำแหน่ง',
+ 'cut_column' => 'ตัดคอลัมน์',
+ 'copy_column' => 'คัดลอกคอลัมน์',
+ 'paste_column_before' => 'วางคอลัมน์ก่อนหน้า',
+ 'paste_column_after' => 'วางคอลัมน์ถัดไป',
+ 'cell_padding' => 'ระยะห่างภายในเซลล์',
+ 'cell_spacing' => 'ระยะห่างระหว่างเซลล์',
+ 'caption' => 'คำบรรยาย',
+ 'show_caption' => 'แสดงคำบรรยาย',
+ 'constrain' => 'รักษาสัดส่วน',
+ 'cell_border_solid' => 'เส้นทึบ',
+ 'cell_border_dotted' => 'เส้นจุด',
+ 'cell_border_dashed' => 'เส้นประ',
+ 'cell_border_double' => 'เส้นคู่',
+ 'cell_border_groove' => 'เส้นร่อง',
+ 'cell_border_ridge' => 'เส้นนูน',
+ 'cell_border_inset' => 'เส้นฝัง',
+ 'cell_border_outset' => 'เส้นนูนออก',
+ 'cell_border_none' => 'ไม่มี',
+ 'cell_border_hidden' => 'ซ่อน',
+
+ // Images, links, details/summary & embed
+ 'source' => 'แหล่งที่มา',
+ 'alt_desc' => 'คำอธิบายทดแทน',
+ 'embed' => 'ฝังเนื้อหา',
+ 'paste_embed' => 'วางโค้ดฝังเนื้อหาด้านล่าง:',
+ 'url' => 'URL',
+ 'text_to_display' => 'ข้อความที่แสดง',
+ 'title' => 'ชื่อเรื่อง',
+ 'browse_links' => 'เรียกดูลิงก์',
+ 'open_link' => 'เปิดลิงก์',
+ 'open_link_in' => 'เปิดลิงก์ใน...',
+ 'open_link_current' => 'หน้าต่างปัจจุบัน',
+ 'open_link_new' => 'หน้าต่างใหม่',
+ 'remove_link' => 'ลบลิงก์',
+ 'insert_collapsible' => 'แทรกบล็อกที่ย่อได้',
+ 'collapsible_unwrap' => 'ยกเลิกการห่อ',
+ 'edit_label' => 'แก้ไขป้ายกำกับ',
+ 'toggle_open_closed' => 'สลับเปิด/ปิด',
+ 'collapsible_edit' => 'แก้ไขบล็อกที่ย่อได้',
+ 'toggle_label' => 'ป้ายกำกับสลับ',
+
+ // About view
+ 'about' => 'เกี่ยวกับตัวแก้ไข',
+ 'about_title' => 'เกี่ยวกับตัวแก้ไข WYSIWYG',
+ 'editor_license' => 'สัญญาอนุญาตและลิขสิทธิ์ตัวแก้ไข',
+ 'editor_lexical_license' => 'ตัวแก้ไขนี้สร้างจาก :lexicalLink ซึ่งเผยแพร่ภายใต้สัญญาอนุญาต MIT',
+ 'editor_lexical_license_link' => 'ดูรายละเอียดสัญญาอนุญาตฉบับเต็มได้ที่นี่',
+ 'editor_tiny_license' => 'ตัวแก้ไขนี้สร้างด้วย :tinyLink ซึ่งเผยแพร่ภายใต้สัญญาอนุญาต MIT',
+ 'editor_tiny_license_link' => 'ดูรายละเอียดลิขสิทธิ์และสัญญาอนุญาตของ TinyMCE ได้ที่นี่',
+ 'save_continue' => 'บันทึกหน้าและดำเนินการต่อ',
+ 'callouts_cycle' => '(กดต่อเนื่องเพื่อสลับประเภท)',
+ 'link_selector' => 'ลิงก์ไปยังเนื้อหา',
+ 'shortcuts' => 'แป้นพิมพ์ลัด',
+ 'shortcut' => 'แป้นพิมพ์ลัด',
+ 'shortcuts_intro' => 'แป้นพิมพ์ลัดต่อไปนี้ใช้งานได้ในตัวแก้ไข:',
+ 'windows_linux' => '(Windows/Linux)',
+ 'mac' => '(Mac)',
+ 'description' => 'คำอธิบาย',
+];
diff --git a/lang/th/entities.php b/lang/th/entities.php
new file mode 100644
index 000000000..bda46b62c
--- /dev/null
+++ b/lang/th/entities.php
@@ -0,0 +1,480 @@
+ 'สร้างล่าสุด',
+ 'recently_created_pages' => 'หน้าที่สร้างล่าสุด',
+ 'recently_updated_pages' => 'หน้าที่แก้ไขล่าสุด',
+ 'recently_created_chapters' => 'บทที่สร้างล่าสุด',
+ 'recently_created_books' => 'หนังสือที่สร้างล่าสุด',
+ 'recently_created_shelves' => 'ชั้นวางที่สร้างล่าสุด',
+ 'recently_update' => 'แก้ไขล่าสุด',
+ 'recently_viewed' => 'ดูล่าสุด',
+ 'recent_activity' => 'กิจกรรมล่าสุด',
+ 'create_now' => 'สร้างตอนนี้',
+ 'revisions' => 'การแก้ไข',
+ 'meta_revision' => 'การแก้ไข #:revisionCount',
+ 'meta_created' => 'สร้างเมื่อ :timeLength',
+ 'meta_created_name' => 'สร้างเมื่อ :timeLength โดย :user',
+ 'meta_updated' => 'แก้ไขเมื่อ :timeLength',
+ 'meta_updated_name' => 'แก้ไขเมื่อ :timeLength โดย :user',
+ 'meta_owned_name' => 'เป็นของ :user',
+ 'meta_reference_count' => 'อ้างอิงโดย :count รายการ',
+ 'entity_select' => 'เลือกรายการ',
+ 'entity_select_lack_permission' => 'คุณไม่มีสิทธิ์เลือกรายการนี้',
+ 'images' => 'รูปภาพ',
+ 'my_recent_drafts' => 'ร่างล่าสุดของฉัน',
+ 'my_recently_viewed' => 'ที่ฉันดูล่าสุด',
+ 'my_most_viewed_favourites' => 'รายการโปรดที่ดูบ่อยที่สุด',
+ 'my_favourites' => 'รายการโปรดของฉัน',
+ 'no_pages_viewed' => 'คุณยังไม่ได้ดูหน้าใด',
+ 'no_pages_recently_created' => 'ยังไม่มีหน้าที่สร้างล่าสุด',
+ 'no_pages_recently_updated' => 'ยังไม่มีหน้าที่แก้ไขล่าสุด',
+ 'export' => 'ส่งออก',
+ 'export_html' => 'ไฟล์เว็บ (HTML)',
+ 'export_pdf' => 'ไฟล์ PDF',
+ 'export_text' => 'ไฟล์ข้อความธรรมดา',
+ 'export_md' => 'ไฟล์ Markdown',
+ 'export_zip' => 'ZIP แบบพกพา',
+ 'default_template' => 'แม่แบบหน้าเริ่มต้น',
+ 'default_template_explain' => 'กำหนดแม่แบบหน้าที่จะใช้เป็นเนื้อหาเริ่มต้นสำหรับหน้าที่สร้างในรายการนี้ โปรดทราบว่าจะใช้งานได้เฉพาะเมื่อผู้สร้างหน้ามีสิทธิ์ดูแม่แบบที่เลือก',
+ 'default_template_select' => 'เลือกแม่แบบหน้า',
+ 'import' => 'นำเข้า',
+ 'import_validate' => 'ตรวจสอบการนำเข้า',
+ 'import_desc' => 'นำเข้าหนังสือ บท และหน้าจากไฟล์ ZIP แบบพกพาจากระบบเดียวกันหรือต่างระบบ เลือกไฟล์ ZIP เพื่อดำเนินการต่อ หลังจากอัปโหลดและตรวจสอบแล้ว คุณจะสามารถกำหนดค่าและยืนยันการนำเข้าในขั้นตอนถัดไป',
+ 'import_zip_select' => 'เลือกไฟล์ ZIP ที่จะอัปโหลด',
+ 'import_zip_validation_errors' => 'พบข้อผิดพลาดขณะตรวจสอบไฟล์ ZIP:',
+ 'import_pending' => 'การนำเข้าที่รอดำเนินการ',
+ 'import_pending_none' => 'ยังไม่มีการนำเข้าที่เริ่มไว้',
+ 'import_continue' => 'ดำเนินการนำเข้าต่อ',
+ 'import_continue_desc' => 'ตรวจสอบเนื้อหาที่จะนำเข้าจากไฟล์ ZIP เมื่อพร้อมแล้ว ให้รันการนำเข้าเพื่อเพิ่มเนื้อหาเข้าสู่ระบบ ไฟล์ ZIP จะถูกลบโดยอัตโนมัติเมื่อนำเข้าสำเร็จ',
+ 'import_details' => 'รายละเอียดการนำเข้า',
+ 'import_run' => 'รันการนำเข้า',
+ 'import_size' => 'ขนาดไฟล์ ZIP :size',
+ 'import_uploaded_at' => 'อัปโหลดเมื่อ :relativeTime',
+ 'import_uploaded_by' => 'อัปโหลดโดย',
+ 'import_location' => 'ตำแหน่งนำเข้า',
+ 'import_location_desc' => 'เลือกตำแหน่งปลายทางสำหรับเนื้อหาที่นำเข้า คุณต้องมีสิทธิ์สร้างเนื้อหาในตำแหน่งที่เลือก',
+ 'import_delete_confirm' => 'คุณแน่ใจหรือไม่ว่าต้องการลบการนำเข้านี้?',
+ 'import_delete_desc' => 'การดำเนินการนี้จะลบไฟล์ ZIP ที่อัปโหลดไว้และไม่สามารถยกเลิกได้',
+ 'import_errors' => 'ข้อผิดพลาดในการนำเข้า',
+ 'import_errors_desc' => 'เกิดข้อผิดพลาดต่อไปนี้ระหว่างการนำเข้า:',
+ 'breadcrumb_siblings_for_page' => 'นำทางไปยังหน้าที่อยู่ระดับเดียวกัน',
+ 'breadcrumb_siblings_for_chapter' => 'นำทางไปยังบทที่อยู่ระดับเดียวกัน',
+ 'breadcrumb_siblings_for_book' => 'นำทางไปยังหนังสือที่อยู่ระดับเดียวกัน',
+ 'breadcrumb_siblings_for_bookshelf' => 'นำทางไปยังชั้นวางที่อยู่ระดับเดียวกัน',
+
+ // Permissions and restrictions
+ 'permissions' => 'สิทธิ์',
+ 'permissions_desc' => 'ตั้งค่าสิทธิ์ที่นี่เพื่อแทนที่สิทธิ์เริ่มต้นที่กำหนดโดยบทบาทผู้ใช้',
+ 'permissions_book_cascade' => 'สิทธิ์ที่กำหนดบนหนังสือจะส่งต่อไปยังบทและหน้าลูกโดยอัตโนมัติ เว้นแต่มีการกำหนดสิทธิ์ของตัวเองไว้',
+ 'permissions_chapter_cascade' => 'สิทธิ์ที่กำหนดบนบทจะส่งต่อไปยังหน้าลูกโดยอัตโนมัติ เว้นแต่มีการกำหนดสิทธิ์ของตัวเองไว้',
+ 'permissions_save' => 'บันทึกสิทธิ์',
+ 'permissions_owner' => 'เจ้าของ',
+ 'permissions_role_everyone_else' => 'ทุกคนที่เหลือ',
+ 'permissions_role_everyone_else_desc' => 'ตั้งค่าสิทธิ์สำหรับบทบาทที่ไม่ได้กำหนดไว้โดยเฉพาะ',
+ 'permissions_role_override' => 'แทนที่สิทธิ์สำหรับบทบาท',
+ 'permissions_inherit_defaults' => 'รับสิทธิ์เริ่มต้น',
+
+ // Search
+ 'search_results' => 'ผลการค้นหา',
+ 'search_total_results_found' => 'พบ :count ผลลัพธ์',
+ 'search_clear' => 'ล้างการค้นหา',
+ 'search_no_pages' => 'ไม่มีหน้าที่ตรงกับการค้นหานี้',
+ 'search_for_term' => 'ค้นหา :term',
+ 'search_more' => 'ผลลัพธ์เพิ่มเติม',
+ 'search_advanced' => 'ค้นหาขั้นสูง',
+ 'search_terms' => 'คำค้นหา',
+ 'search_content_type' => 'ประเภทเนื้อหา',
+ 'search_exact_matches' => 'ตรงทั้งหมด',
+ 'search_tags' => 'ค้นหาด้วยแท็ก',
+ 'search_options' => 'ตัวเลือก',
+ 'search_viewed_by_me' => 'ที่ฉันดูแล้ว',
+ 'search_not_viewed_by_me' => 'ที่ฉันยังไม่ได้ดู',
+ 'search_permissions_set' => 'มีการกำหนดสิทธิ์',
+ 'search_created_by_me' => 'ที่ฉันสร้าง',
+ 'search_updated_by_me' => 'ที่ฉันแก้ไข',
+ 'search_owned_by_me' => 'ที่ฉันเป็นเจ้าของ',
+ 'search_date_options' => 'ตัวเลือกวันที่',
+ 'search_updated_before' => 'แก้ไขก่อน',
+ 'search_updated_after' => 'แก้ไขหลัง',
+ 'search_created_before' => 'สร้างก่อน',
+ 'search_created_after' => 'สร้างหลัง',
+ 'search_set_date' => 'กำหนดวันที่',
+ 'search_update' => 'อัปเดตการค้นหา',
+
+ // Shelves
+ 'shelf' => 'ชั้นวาง',
+ 'shelves' => 'ชั้นวาง',
+ 'x_shelves' => ':count ชั้นวาง',
+ 'shelves_empty' => 'ยังไม่มีชั้นวาง',
+ 'shelves_create' => 'สร้างชั้นวางใหม่',
+ 'shelves_popular' => 'ชั้นวางยอดนิยม',
+ 'shelves_new' => 'ชั้นวางใหม่',
+ 'shelves_new_action' => 'ชั้นวางใหม่',
+ 'shelves_popular_empty' => 'ชั้นวางที่ได้รับความนิยมมากที่สุดจะแสดงที่นี่',
+ 'shelves_new_empty' => 'ชั้นวางที่สร้างล่าสุดจะแสดงที่นี่',
+ 'shelves_save' => 'บันทึกชั้นวาง',
+ 'shelves_books' => 'หนังสือในชั้นวางนี้',
+ 'shelves_add_books' => 'เพิ่มหนังสือในชั้นวางนี้',
+ 'shelves_drag_books' => 'ลากหนังสือด้านล่างเพื่อเพิ่มในชั้นวางนี้',
+ 'shelves_empty_contents' => 'ชั้นวางนี้ยังไม่มีหนังสือ',
+ 'shelves_edit_and_assign' => 'แก้ไขชั้นวางเพื่อกำหนดหนังสือ',
+ 'shelves_edit_named' => 'แก้ไขชั้นวาง :name',
+ 'shelves_edit' => 'แก้ไขชั้นวาง',
+ 'shelves_delete' => 'ลบชั้นวาง',
+ 'shelves_delete_named' => 'ลบชั้นวาง :name',
+ 'shelves_delete_explain' => "การดำเนินการนี้จะลบชั้นวางชื่อ ':name' หนังสือภายในจะไม่ถูกลบ",
+ 'shelves_delete_confirmation' => 'คุณแน่ใจหรือไม่ว่าต้องการลบชั้นวางนี้?',
+ 'shelves_permissions' => 'สิทธิ์ชั้นวาง',
+ 'shelves_permissions_updated' => 'อัปเดตสิทธิ์ชั้นวางแล้ว',
+ 'shelves_permissions_active' => 'สิทธิ์ชั้นวางเปิดใช้งานอยู่',
+ 'shelves_permissions_cascade_warning' => 'สิทธิ์บนชั้นวางไม่ส่งต่อไปยังหนังสือภายในโดยอัตโนมัติ เนื่องจากหนังสือสามารถอยู่ในหลายชั้นวางได้ อย่างไรก็ตาม สามารถคัดลอกสิทธิ์ไปยังหนังสือลูกได้โดยใช้ตัวเลือกด้านล่าง',
+ 'shelves_permissions_create' => 'สิทธิ์สร้างชั้นวางจะใช้สำหรับการคัดลอกสิทธิ์ไปยังหนังสือลูกเท่านั้น ไม่ได้ควบคุมความสามารถในการสร้างหนังสือ',
+ 'shelves_copy_permissions_to_books' => 'คัดลอกสิทธิ์ไปยังหนังสือ',
+ 'shelves_copy_permissions' => 'คัดลอกสิทธิ์',
+ 'shelves_copy_permissions_explain' => 'การดำเนินการนี้จะนำการตั้งค่าสิทธิ์ปัจจุบันของชั้นวางนี้ไปใช้กับหนังสือทั้งหมดภายใน ก่อนเริ่มต้น ให้ตรวจสอบว่าบันทึกการเปลี่ยนแปลงสิทธิ์แล้ว',
+ 'shelves_copy_permission_success' => 'คัดลอกสิทธิ์ชั้นวางไปยัง :count หนังสือแล้ว',
+
+ // Books
+ 'book' => 'หนังสือ',
+ 'books' => 'หนังสือ',
+ 'x_books' => ':count หนังสือ',
+ 'books_empty' => 'ยังไม่มีหนังสือ',
+ 'books_popular' => 'หนังสือยอดนิยม',
+ 'books_recent' => 'หนังสือล่าสุด',
+ 'books_new' => 'หนังสือใหม่',
+ 'books_new_action' => 'หนังสือใหม่',
+ 'books_popular_empty' => 'หนังสือที่ได้รับความนิยมมากที่สุดจะแสดงที่นี่',
+ 'books_new_empty' => 'หนังสือที่สร้างล่าสุดจะแสดงที่นี่',
+ 'books_create' => 'สร้างหนังสือใหม่',
+ 'books_delete' => 'ลบหนังสือ',
+ 'books_delete_named' => 'ลบหนังสือ :bookName',
+ 'books_delete_explain' => 'การดำเนินการนี้จะลบหนังสือชื่อ \':bookName\' หน้าและบทภายในทั้งหมดจะถูกลบด้วย',
+ 'books_delete_confirmation' => 'คุณแน่ใจหรือไม่ว่าต้องการลบหนังสือนี้?',
+ 'books_edit' => 'แก้ไขหนังสือ',
+ 'books_edit_named' => 'แก้ไขหนังสือ :bookName',
+ 'books_form_book_name' => 'ชื่อหนังสือ',
+ 'books_save' => 'บันทึกหนังสือ',
+ 'books_permissions' => 'สิทธิ์หนังสือ',
+ 'books_permissions_updated' => 'อัปเดตสิทธิ์หนังสือแล้ว',
+ 'books_empty_contents' => 'ยังไม่มีหน้าหรือบทในหนังสือนี้',
+ 'books_empty_create_page' => 'สร้างหน้าใหม่',
+ 'books_empty_sort_current_book' => 'จัดเรียงหนังสือนี้',
+ 'books_empty_add_chapter' => 'เพิ่มบท',
+ 'books_permissions_active' => 'สิทธิ์หนังสือเปิดใช้งานอยู่',
+ 'books_search_this' => 'ค้นหาในหนังสือนี้',
+ 'books_navigation' => 'การนำทางหนังสือ',
+ 'books_sort' => 'จัดเรียงเนื้อหาหนังสือ',
+ 'books_sort_desc' => 'ย้ายบทและหน้าภายในหนังสือเพื่อจัดเรียงใหม่ สามารถเพิ่มหนังสือเล่มอื่นเพื่อย้ายบทและหน้าระหว่างหนังสือได้ อาจตั้งกฎการจัดเรียงอัตโนมัติเพื่อจัดเรียงเนื้อหาโดยอัตโนมัติเมื่อมีการเปลี่ยนแปลง',
+ 'books_sort_auto_sort' => 'ตัวเลือกการจัดเรียงอัตโนมัติ',
+ 'books_sort_auto_sort_active' => 'การจัดเรียงอัตโนมัติเปิดใช้งาน: :sortName',
+ 'books_sort_auto_sort_creation_hint' => 'กฎการจัดเรียงอัตโนมัติสามารถสร้างได้ในหน้าตั้งค่า "รายการและการจัดเรียง" โดยผู้ใช้ที่มีสิทธิ์ที่เกี่ยวข้อง',
+ 'books_sort_named' => 'จัดเรียงหนังสือ :bookName',
+ 'books_sort_name' => 'จัดเรียงตามชื่อ',
+ 'books_sort_created' => 'จัดเรียงตามวันที่สร้าง',
+ 'books_sort_updated' => 'จัดเรียงตามวันที่แก้ไข',
+ 'books_sort_chapters_first' => 'บทอยู่ก่อน',
+ 'books_sort_chapters_last' => 'บทอยู่หลัง',
+ 'books_sort_show_other' => 'แสดงหนังสือเล่มอื่น',
+ 'books_sort_save' => 'บันทึกลำดับใหม่',
+ 'books_sort_show_other_desc' => 'เพิ่มหนังสือเล่มอื่นที่นี่เพื่อรวมในการจัดเรียง และอนุญาตให้จัดระเบียบข้ามหนังสือได้ง่าย',
+ 'books_sort_move_up' => 'เลื่อนขึ้น',
+ 'books_sort_move_down' => 'เลื่อนลง',
+ 'books_sort_move_prev_book' => 'ย้ายไปหนังสือก่อนหน้า',
+ 'books_sort_move_next_book' => 'ย้ายไปหนังสือถัดไป',
+ 'books_sort_move_prev_chapter' => 'ย้ายเข้าบทก่อนหน้า',
+ 'books_sort_move_next_chapter' => 'ย้ายเข้าบทถัดไป',
+ 'books_sort_move_book_start' => 'ย้ายไปต้นหนังสือ',
+ 'books_sort_move_book_end' => 'ย้ายไปท้ายหนังสือ',
+ 'books_sort_move_before_chapter' => 'ย้ายไปก่อนบท',
+ 'books_sort_move_after_chapter' => 'ย้ายไปหลังบท',
+ 'books_copy' => 'คัดลอกหนังสือ',
+ 'books_copy_success' => 'คัดลอกหนังสือสำเร็จแล้ว',
+
+ // Chapters
+ 'chapter' => 'บท',
+ 'chapters' => 'บท',
+ 'x_chapters' => ':count บท',
+ 'chapters_popular' => 'บทยอดนิยม',
+ 'chapters_new' => 'บทใหม่',
+ 'chapters_create' => 'สร้างบทใหม่',
+ 'chapters_delete' => 'ลบบท',
+ 'chapters_delete_named' => 'ลบบท :chapterName',
+ 'chapters_delete_explain' => 'การดำเนินการนี้จะลบบทชื่อ \':chapterName\' หน้าทั้งหมดในบทนี้จะถูกลบด้วย',
+ 'chapters_delete_confirm' => 'คุณแน่ใจหรือไม่ว่าต้องการลบบทนี้?',
+ 'chapters_edit' => 'แก้ไขบท',
+ 'chapters_edit_named' => 'แก้ไขบท :chapterName',
+ 'chapters_save' => 'บันทึกบท',
+ 'chapters_move' => 'ย้ายบท',
+ 'chapters_move_named' => 'ย้ายบท :chapterName',
+ 'chapters_copy' => 'คัดลอกบท',
+ 'chapters_copy_success' => 'คัดลอกบทสำเร็จแล้ว',
+ 'chapters_permissions' => 'สิทธิ์บท',
+ 'chapters_empty' => 'ยังไม่มีหน้าในบทนี้',
+ 'chapters_permissions_active' => 'สิทธิ์บทเปิดใช้งานอยู่',
+ 'chapters_permissions_success' => 'อัปเดตสิทธิ์บทแล้ว',
+ 'chapters_search_this' => 'ค้นหาในบทนี้',
+ 'chapter_sort_book' => 'จัดเรียงหนังสือ',
+
+ // Pages
+ 'page' => 'หน้า',
+ 'pages' => 'หน้า',
+ 'x_pages' => ':count หน้า',
+ 'pages_popular' => 'หน้ายอดนิยม',
+ 'pages_new' => 'หน้าใหม่',
+ 'pages_attachments' => 'ไฟล์แนบ',
+ 'pages_navigation' => 'การนำทางหน้า',
+ 'pages_delete' => 'ลบหน้า',
+ 'pages_delete_named' => 'ลบหน้า :pageName',
+ 'pages_delete_draft_named' => 'ลบร่างหน้า :pageName',
+ 'pages_delete_draft' => 'ลบร่างหน้า',
+ 'pages_delete_success' => 'ลบหน้าแล้ว',
+ 'pages_delete_draft_success' => 'ลบร่างหน้าแล้ว',
+ 'pages_delete_warning_template' => 'หน้านี้ถูกใช้งานเป็นแม่แบบหน้าเริ่มต้นของหนังสือหรือบท หลังจากลบหน้านี้ หนังสือหรือบทดังกล่าวจะไม่มีแม่แบบหน้าเริ่มต้น',
+ 'pages_delete_confirm' => 'คุณแน่ใจหรือไม่ว่าต้องการลบหน้านี้?',
+ 'pages_delete_draft_confirm' => 'คุณแน่ใจหรือไม่ว่าต้องการลบร่างหน้านี้?',
+ 'pages_editing_named' => 'กำลังแก้ไขหน้า :pageName',
+ 'pages_edit_draft_options' => 'ตัวเลือกร่าง',
+ 'pages_edit_save_draft' => 'บันทึกร่าง',
+ 'pages_edit_draft' => 'แก้ไขร่างหน้า',
+ 'pages_editing_draft' => 'กำลังแก้ไขร่าง',
+ 'pages_editing_page' => 'กำลังแก้ไขหน้า',
+ 'pages_edit_draft_save_at' => 'บันทึกร่างเมื่อ ',
+ 'pages_edit_delete_draft' => 'ลบร่าง',
+ 'pages_edit_delete_draft_confirm' => 'คุณแน่ใจหรือไม่ว่าต้องการลบร่างหน้านี้? การเปลี่ยนแปลงทั้งหมดตั้งแต่บันทึกครั้งล่าสุดจะสูญหาย และตัวแก้ไขจะโหลดเนื้อหาที่บันทึกล่าสุด',
+ 'pages_edit_discard_draft' => 'ยกเลิกร่าง',
+ 'pages_edit_switch_to_markdown' => 'เปลี่ยนไปใช้ตัวแก้ไข Markdown',
+ 'pages_edit_switch_to_markdown_clean' => '(เนื้อหาสะอาด)',
+ 'pages_edit_switch_to_markdown_stable' => '(เนื้อหาเสถียร)',
+ 'pages_edit_switch_to_wysiwyg' => 'เปลี่ยนไปใช้ตัวแก้ไข WYSIWYG',
+ 'pages_edit_switch_to_new_wysiwyg' => 'เปลี่ยนไปใช้ WYSIWYG ใหม่',
+ 'pages_edit_switch_to_new_wysiwyg_desc' => '(กำลังทดสอบ Beta)',
+ 'pages_edit_set_changelog' => 'ตั้งค่า Changelog',
+ 'pages_edit_enter_changelog_desc' => 'กรอกคำอธิบายสั้นๆ เกี่ยวกับการเปลี่ยนแปลงที่ทำ',
+ 'pages_edit_enter_changelog' => 'กรอก Changelog',
+ 'pages_editor_switch_title' => 'เปลี่ยนตัวแก้ไข',
+ 'pages_editor_switch_are_you_sure' => 'คุณแน่ใจหรือไม่ว่าต้องการเปลี่ยนตัวแก้ไขสำหรับหน้านี้?',
+ 'pages_editor_switch_consider_following' => 'โปรดพิจารณาสิ่งต่อไปนี้เมื่อเปลี่ยนตัวแก้ไข:',
+ 'pages_editor_switch_consideration_a' => 'เมื่อบันทึกแล้ว ตัวแก้ไขใหม่จะถูกใช้โดยผู้แก้ไขในอนาคต รวมถึงผู้ที่อาจไม่สามารถเปลี่ยนประเภทตัวแก้ไขได้เอง',
+ 'pages_editor_switch_consideration_b' => 'อาจทำให้รายละเอียดและไวยากรณ์บางอย่างสูญหายในบางสถานการณ์',
+ 'pages_editor_switch_consideration_c' => 'การเปลี่ยนแปลงแท็กหรือ changelog ที่ทำตั้งแต่บันทึกครั้งล่าสุดจะไม่ถูกบันทึกหลังจากเปลี่ยนนี้',
+ 'pages_save' => 'บันทึกหน้า',
+ 'pages_title' => 'ชื่อหน้า',
+ 'pages_name' => 'ชื่อหน้า',
+ 'pages_md_editor' => 'ตัวแก้ไข',
+ 'pages_md_preview' => 'ดูตัวอย่าง',
+ 'pages_md_insert_image' => 'แทรกรูปภาพ',
+ 'pages_md_insert_link' => 'แทรกลิงก์รายการ',
+ 'pages_md_insert_drawing' => 'แทรกภาพวาด',
+ 'pages_md_show_preview' => 'แสดงตัวอย่าง',
+ 'pages_md_sync_scroll' => 'ซิงค์การเลื่อนหน้าตัวอย่าง',
+ 'pages_md_plain_editor' => 'ตัวแก้ไขข้อความธรรมดา',
+ 'pages_drawing_unsaved' => 'พบภาพวาดที่ยังไม่บันทึก',
+ 'pages_drawing_unsaved_confirm' => 'พบข้อมูลภาพวาดที่ยังไม่บันทึกจากการบันทึกที่ล้มเหลวก่อนหน้า ต้องการกู้คืนและแก้ไขภาพวาดที่ยังไม่บันทึกนี้ต่อหรือไม่?',
+ 'pages_not_in_chapter' => 'หน้านี้ไม่ได้อยู่ในบท',
+ 'pages_move' => 'ย้ายหน้า',
+ 'pages_copy' => 'คัดลอกหน้า',
+ 'pages_copy_desination' => 'ปลายทางการคัดลอก',
+ 'pages_copy_success' => 'คัดลอกหน้าสำเร็จแล้ว',
+ 'pages_permissions' => 'สิทธิ์หน้า',
+ 'pages_permissions_success' => 'อัปเดตสิทธิ์หน้าแล้ว',
+ 'pages_revision' => 'การแก้ไข',
+ 'pages_revisions' => 'การแก้ไขหน้า',
+ 'pages_revisions_desc' => 'แสดงรายการการแก้ไขทั้งหมดของหน้านี้ คุณสามารถดูย้อนหลัง เปรียบเทียบ และกู้คืนเวอร์ชันเก่าได้หากมีสิทธิ์ ประวัติทั้งหมดอาจไม่แสดงครบเนื่องจากการตั้งค่าระบบอาจลบการแก้ไขเก่าโดยอัตโนมัติ',
+ 'pages_revisions_named' => 'การแก้ไขหน้าสำหรับ :pageName',
+ 'pages_revision_named' => 'การแก้ไขหน้าสำหรับ :pageName',
+ 'pages_revision_restored_from' => 'กู้คืนจาก #:id; :summary',
+ 'pages_revisions_created_by' => 'สร้างโดย',
+ 'pages_revisions_date' => 'วันที่แก้ไข',
+ 'pages_revisions_number' => '#',
+ 'pages_revisions_sort_number' => 'หมายเลขการแก้ไข',
+ 'pages_revisions_numbered' => 'การแก้ไข #:id',
+ 'pages_revisions_numbered_changes' => 'การเปลี่ยนแปลงในการแก้ไข #:id',
+ 'pages_revisions_editor' => 'ประเภทตัวแก้ไข',
+ 'pages_revisions_changelog' => 'Changelog',
+ 'pages_revisions_changes' => 'การเปลี่ยนแปลง',
+ 'pages_revisions_current' => 'เวอร์ชันปัจจุบัน',
+ 'pages_revisions_preview' => 'ดูตัวอย่าง',
+ 'pages_revisions_restore' => 'กู้คืน',
+ 'pages_revisions_none' => 'หน้านี้ยังไม่มีการแก้ไข',
+ 'pages_copy_link' => 'คัดลอกลิงก์',
+ 'pages_edit_content_link' => 'ข้ามไปยังส่วนในตัวแก้ไข',
+ 'pages_pointer_enter_mode' => 'เข้าสู่โหมดเลือกส่วน',
+ 'pages_pointer_label' => 'ตัวเลือกส่วนหน้า',
+ 'pages_pointer_permalink' => 'ลิงก์ถาวรส่วนหน้า',
+ 'pages_pointer_include_tag' => 'แท็กรวมส่วนหน้า',
+ 'pages_pointer_toggle_link' => 'โหมดลิงก์ถาวร กดเพื่อแสดงแท็กรวม',
+ 'pages_pointer_toggle_include' => 'โหมดแท็กรวม กดเพื่อแสดงลิงก์ถาวร',
+ 'pages_permissions_active' => 'สิทธิ์หน้าเปิดใช้งานอยู่',
+ 'pages_initial_revision' => 'เผยแพร่ครั้งแรก',
+ 'pages_references_update_revision' => 'ระบบอัปเดตลิงก์ภายในอัตโนมัติ',
+ 'pages_initial_name' => 'หน้าใหม่',
+ 'pages_editing_draft_notification' => 'คุณกำลังแก้ไขร่างที่บันทึกล่าสุดเมื่อ :timeDiff',
+ 'pages_draft_edited_notification' => 'หน้านี้ได้รับการอัปเดตตั้งแต่นั้นมา แนะนำให้ยกเลิกร่างนี้',
+ 'pages_draft_page_changed_since_creation' => 'หน้านี้ได้รับการอัปเดตตั้งแต่สร้างร่างนี้ แนะนำให้ยกเลิกร่างหรือระมัดระวังไม่ให้เขียนทับการเปลี่ยนแปลงของหน้า',
+ 'pages_draft_edit_active' => [
+ 'start_a' => 'มีผู้ใช้ :count คนกำลังแก้ไขหน้านี้',
+ 'start_b' => ':userName กำลังแก้ไขหน้านี้',
+ 'time_a' => 'ตั้งแต่อัปเดตหน้าล่าสุด',
+ 'time_b' => 'ใน :minCount นาทีที่ผ่านมา',
+ 'message' => ':start :time โปรดระวังอย่าเขียนทับการแก้ไขของกันและกัน!',
+ ],
+ 'pages_draft_discarded' => 'ยกเลิกร่างแล้ว! ตัวแก้ไขได้รับการอัปเดตด้วยเนื้อหาปัจจุบันของหน้า',
+ 'pages_draft_deleted' => 'ลบร่างแล้ว! ตัวแก้ไขได้รับการอัปเดตด้วยเนื้อหาปัจจุบันของหน้า',
+ 'pages_specific' => 'หน้าเฉพาะ',
+ 'pages_is_template' => 'แม่แบบหน้า',
+
+ // Editor Sidebar
+ 'toggle_sidebar' => 'แสดง/ซ่อนแถบด้านข้าง',
+ 'page_contents' => 'Page Contents',
+ 'page_contents_none' => 'No headings were found in the page content.',
+ 'page_contents_info' => 'The contents menu is generated from any heading formats used in the page.',
+ 'page_tags' => 'แท็กหน้า',
+ 'chapter_tags' => 'แท็กบท',
+ 'book_tags' => 'แท็กหนังสือ',
+ 'shelf_tags' => 'แท็กชั้นวาง',
+ 'tag' => 'แท็ก',
+ 'tags' => 'แท็ก',
+ 'tags_index_desc' => 'แท็กสามารถนำไปใช้กับเนื้อหาในระบบเพื่อจัดหมวดหมู่แบบยืดหยุ่น แท็กสามารถมีทั้งคีย์และค่า โดยค่าไม่บังคับ เมื่อกำหนดแล้ว สามารถค้นหาเนื้อหาด้วยชื่อและค่าของแท็กได้',
+ 'tag_name' => 'ชื่อแท็ก',
+ 'tag_value' => 'ค่าแท็ก (ไม่บังคับ)',
+ 'tags_explain' => "เพิ่มแท็กเพื่อจัดหมวดหมู่เนื้อหาให้ดีขึ้น \n คุณสามารถกำหนดค่าให้แท็กเพื่อการจัดระเบียบที่ละเอียดขึ้น",
+ 'tags_add' => 'เพิ่มแท็ก',
+ 'tags_remove' => 'ลบแท็กนี้',
+ 'tags_usages' => 'การใช้งานแท็กทั้งหมด',
+ 'tags_assigned_pages' => 'กำหนดให้หน้า',
+ 'tags_assigned_chapters' => 'กำหนดให้บท',
+ 'tags_assigned_books' => 'กำหนดให้หนังสือ',
+ 'tags_assigned_shelves' => 'กำหนดให้ชั้นวาง',
+ 'tags_x_unique_values' => ':count ค่าที่ไม่ซ้ำ',
+ 'tags_all_values' => 'ค่าทั้งหมด',
+ 'tags_view_tags' => 'ดูแท็ก',
+ 'tags_view_existing_tags' => 'ดูแท็กที่มีอยู่',
+ 'tags_list_empty_hint' => 'แท็กสามารถกำหนดได้ผ่านแถบด้านข้างของตัวแก้ไขหน้า หรือขณะแก้ไขรายละเอียดของหนังสือ บท หรือชั้นวาง',
+ 'attachments' => 'ไฟล์แนบ',
+ 'attachments_explain' => 'อัปโหลดไฟล์หรือแนบลิงก์เพื่อแสดงในหน้านี้ จะมองเห็นได้ในแถบด้านข้างของหน้า',
+ 'attachments_explain_instant_save' => 'การเปลี่ยนแปลงที่นี่จะบันทึกทันที',
+ 'attachments_upload' => 'อัปโหลดไฟล์',
+ 'attachments_link' => 'แนบลิงก์',
+ 'attachments_upload_drop' => 'หรือคุณสามารถลากและวางไฟล์ที่นี่เพื่ออัปโหลดเป็นไฟล์แนบ',
+ 'attachments_set_link' => 'ตั้งค่าลิงก์',
+ 'attachments_delete' => 'คุณแน่ใจหรือไม่ว่าต้องการลบไฟล์แนบนี้?',
+ 'attachments_dropzone' => 'วางไฟล์ที่นี่เพื่ออัปโหลด',
+ 'attachments_no_files' => 'ยังไม่มีไฟล์ที่อัปโหลด',
+ 'attachments_explain_link' => 'คุณสามารถแนบลิงก์แทนการอัปโหลดไฟล์ได้ ลิงก์อาจเป็นลิงก์ไปยังหน้าอื่นหรือไฟล์ในคลาวด์',
+ 'attachments_link_name' => 'ชื่อลิงก์',
+ 'attachment_link' => 'ลิงก์ไฟล์แนบ',
+ 'attachments_link_url' => 'ลิงก์ไปยังไฟล์',
+ 'attachments_link_url_hint' => 'URL ของเว็บไซต์หรือไฟล์',
+ 'attach' => 'แนบ',
+ 'attachments_insert_link' => 'เพิ่มลิงก์ไฟล์แนบในหน้า',
+ 'attachments_edit_file' => 'แก้ไขไฟล์',
+ 'attachments_edit_file_name' => 'ชื่อไฟล์',
+ 'attachments_edit_drop_upload' => 'วางไฟล์หรือคลิกที่นี่เพื่ออัปโหลดและแทนที่',
+ 'attachments_order_updated' => 'อัปเดตลำดับไฟล์แนบแล้ว',
+ 'attachments_updated_success' => 'อัปเดตรายละเอียดไฟล์แนบแล้ว',
+ 'attachments_deleted' => 'ลบไฟล์แนบแล้ว',
+ 'attachments_file_uploaded' => 'อัปโหลดไฟล์สำเร็จแล้ว',
+ 'attachments_file_updated' => 'อัปเดตไฟล์สำเร็จแล้ว',
+ 'attachments_link_attached' => 'แนบลิงก์ไปยังหน้าสำเร็จแล้ว',
+ 'templates' => 'แม่แบบ',
+ 'templates_set_as_template' => 'หน้านี้เป็นแม่แบบ',
+ 'templates_explain_set_as_template' => 'คุณสามารถตั้งหน้านี้เป็นแม่แบบเพื่อให้นำเนื้อหาไปใช้เมื่อสร้างหน้าอื่น ผู้ใช้อื่นจะสามารถใช้แม่แบบนี้ได้หากมีสิทธิ์ดูหน้านี้',
+ 'templates_replace_content' => 'แทนที่เนื้อหาหน้า',
+ 'templates_append_content' => 'ต่อท้ายเนื้อหาหน้า',
+ 'templates_prepend_content' => 'เพิ่มก่อนเนื้อหาหน้า',
+
+ // Profile View
+ 'profile_user_for_x' => 'ผู้ใช้มาแล้ว :time',
+ 'profile_created_content' => 'เนื้อหาที่สร้าง',
+ 'profile_not_created_pages' => ':userName ยังไม่ได้สร้างหน้าใด',
+ 'profile_not_created_chapters' => ':userName ยังไม่ได้สร้างบทใด',
+ 'profile_not_created_books' => ':userName ยังไม่ได้สร้างหนังสือใด',
+ 'profile_not_created_shelves' => ':userName ยังไม่ได้สร้างชั้นวางใด',
+
+ // Comments
+ 'comment' => 'ความคิดเห็น',
+ 'comments' => 'ความคิดเห็น',
+ 'comment_add' => 'เพิ่มความคิดเห็น',
+ 'comment_none' => 'ไม่มีความคิดเห็น',
+ 'comment_placeholder' => 'เขียนความคิดเห็นที่นี่',
+ 'comment_thread_count' => ':count เธรดความคิดเห็น',
+ 'comment_archived_count' => ':count ที่เก็บถาวร',
+ 'comment_archived_threads' => 'เธรดที่เก็บถาวร',
+ 'comment_save' => 'บันทึกความคิดเห็น',
+ 'comment_new' => 'ความคิดเห็นใหม่',
+ 'comment_created' => 'แสดงความคิดเห็นเมื่อ :createDiff',
+ 'comment_updated' => 'แก้ไขเมื่อ :updateDiff โดย :username',
+ 'comment_updated_indicator' => 'แก้ไขแล้ว',
+ 'comment_deleted_success' => 'ลบความคิดเห็นแล้ว',
+ 'comment_created_success' => 'เพิ่มความคิดเห็นแล้ว',
+ 'comment_updated_success' => 'แก้ไขความคิดเห็นแล้ว',
+ 'comment_archive_success' => 'เก็บถาวรความคิดเห็นแล้ว',
+ 'comment_unarchive_success' => 'ยกเลิกการเก็บถาวรความคิดเห็นแล้ว',
+ 'comment_view' => 'ดูความคิดเห็น',
+ 'comment_jump_to_thread' => 'ไปยังเธรด',
+ 'comment_delete_confirm' => 'คุณแน่ใจหรือไม่ว่าต้องการลบความคิดเห็นนี้?',
+ 'comment_in_reply_to' => 'ตอบกลับ :commentId',
+ 'comment_reference' => 'อ้างอิง',
+ 'comment_reference_outdated' => '(ล้าสมัย)',
+ 'comment_editor_explain' => 'แสดงความคิดเห็นที่มีในหน้านี้ สามารถเพิ่มและจัดการความคิดเห็นได้เมื่อดูหน้าที่บันทึกแล้ว',
+
+ // Revision
+ 'revision_delete_confirm' => 'คุณแน่ใจหรือไม่ว่าต้องการลบการแก้ไขนี้?',
+ 'revision_restore_confirm' => 'คุณแน่ใจหรือไม่ว่าต้องการกู้คืนการแก้ไขนี้? เนื้อหาปัจจุบันของหน้าจะถูกแทนที่',
+ 'revision_cannot_delete_latest' => 'ไม่สามารถลบการแก้ไขล่าสุดได้',
+
+ // Copy view
+ 'copy_consider' => 'โปรดพิจารณาสิ่งต่อไปนี้เมื่อคัดลอกเนื้อหา',
+ 'copy_consider_permissions' => 'การตั้งค่าสิทธิ์แบบกำหนดเองจะไม่ถูกคัดลอก',
+ 'copy_consider_owner' => 'คุณจะเป็นเจ้าของเนื้อหาที่คัดลอกทั้งหมด',
+ 'copy_consider_images' => 'ไฟล์รูปภาพในหน้าจะไม่ถูกทำสำเนา และรูปภาพต้นฉบับจะยังคงเชื่อมกับหน้าที่อัปโหลดไว้เดิม',
+ 'copy_consider_attachments' => 'ไฟล์แนบในหน้าจะไม่ถูกคัดลอก',
+ 'copy_consider_access' => 'การเปลี่ยนตำแหน่ง เจ้าของ หรือสิทธิ์อาจทำให้เนื้อหานี้เข้าถึงได้โดยผู้ที่ไม่เคยมีสิทธิ์มาก่อน',
+
+ // Conversions
+ 'convert_to_shelf' => 'แปลงเป็นชั้นวาง',
+ 'convert_to_shelf_contents_desc' => 'คุณสามารถแปลงหนังสือนี้เป็นชั้นวางใหม่ที่มีเนื้อหาเดิม บทในหนังสือนี้จะถูกแปลงเป็นหนังสือใหม่ หากหนังสือนี้มีหน้าที่ไม่อยู่ในบท หนังสือนี้จะถูกเปลี่ยนชื่อและเก็บหน้าเหล่านั้น และจะกลายเป็นส่วนหนึ่งของชั้นวางใหม่',
+ 'convert_to_shelf_permissions_desc' => 'สิทธิ์ที่กำหนดบนหนังสือนี้จะถูกคัดลอกไปยังชั้นวางใหม่และหนังสือลูกทั้งหมดที่ไม่มีสิทธิ์ของตัวเอง โปรดทราบว่าสิทธิ์บนชั้นวางไม่ส่งต่อไปยังเนื้อหาภายในโดยอัตโนมัติเหมือนกับหนังสือ',
+ 'convert_book' => 'แปลงหนังสือ',
+ 'convert_book_confirm' => 'คุณแน่ใจหรือไม่ว่าต้องการแปลงหนังสือนี้?',
+ 'convert_undo_warning' => 'การดำเนินการนี้ยากที่จะยกเลิก',
+ 'convert_to_book' => 'แปลงเป็นหนังสือ',
+ 'convert_to_book_desc' => 'คุณสามารถแปลงบทนี้เป็นหนังสือใหม่ที่มีเนื้อหาเดิม สิทธิ์ที่กำหนดบนบทนี้จะถูกคัดลอกไปยังหนังสือใหม่ แต่สิทธิ์ที่รับมาจากหนังสือแม่จะไม่ถูกคัดลอก ซึ่งอาจทำให้การควบคุมการเข้าถึงเปลี่ยนแปลงได้',
+ 'convert_chapter' => 'แปลงบท',
+ 'convert_chapter_confirm' => 'คุณแน่ใจหรือไม่ว่าต้องการแปลงบทนี้?',
+
+ // References
+ 'references' => 'การอ้างอิง',
+ 'references_none' => 'ยังไม่มีการอ้างอิงที่ติดตามไปยังรายการนี้',
+ 'references_to_desc' => 'แสดงรายการเนื้อหาทั้งหมดในระบบที่ลิงก์ไปยังรายการนี้',
+
+ // Watch Options
+ 'watch' => 'ติดตาม',
+ 'watch_title_default' => 'การตั้งค่าเริ่มต้น',
+ 'watch_desc_default' => 'กลับไปใช้การตั้งค่าการแจ้งเตือนเริ่มต้นของคุณ',
+ 'watch_title_ignore' => 'ไม่สนใจ',
+ 'watch_desc_ignore' => 'ไม่รับการแจ้งเตือนใดๆ รวมถึงจากการตั้งค่าระดับผู้ใช้',
+ 'watch_title_new' => 'หน้าใหม่',
+ 'watch_desc_new' => 'แจ้งเตือนเมื่อมีการสร้างหน้าใหม่ในรายการนี้',
+ 'watch_title_updates' => 'การอัปเดตหน้าทั้งหมด',
+ 'watch_desc_updates' => 'แจ้งเตือนเมื่อมีหน้าใหม่และการแก้ไขหน้า',
+ 'watch_desc_updates_page' => 'แจ้งเตือนเมื่อมีการแก้ไขหน้า',
+ 'watch_title_comments' => 'การอัปเดตและความคิดเห็นทั้งหมด',
+ 'watch_desc_comments' => 'แจ้งเตือนเมื่อมีหน้าใหม่ การแก้ไขหน้า และความคิดเห็นใหม่',
+ 'watch_desc_comments_page' => 'แจ้งเตือนเมื่อมีการแก้ไขหน้าและความคิดเห็นใหม่',
+ 'watch_change_default' => 'เปลี่ยนการตั้งค่าการแจ้งเตือนเริ่มต้น',
+ 'watch_detail_ignore' => 'ไม่รับการแจ้งเตือน',
+ 'watch_detail_new' => 'ติดตามหน้าใหม่',
+ 'watch_detail_updates' => 'ติดตามหน้าใหม่และการอัปเดต',
+ 'watch_detail_comments' => 'ติดตามหน้าใหม่ การอัปเดต และความคิดเห็น',
+ 'watch_detail_parent_book' => 'ติดตามผ่านหนังสือแม่',
+ 'watch_detail_parent_book_ignore' => 'ไม่รับการแจ้งเตือนผ่านหนังสือแม่',
+ 'watch_detail_parent_chapter' => 'ติดตามผ่านบทแม่',
+ 'watch_detail_parent_chapter_ignore' => 'ไม่รับการแจ้งเตือนผ่านบทแม่',
+];
diff --git a/lang/th/errors.php b/lang/th/errors.php
new file mode 100644
index 000000000..61f1ed82c
--- /dev/null
+++ b/lang/th/errors.php
@@ -0,0 +1,135 @@
+ 'คุณไม่มีสิทธิ์เข้าถึงหน้าที่ร้องขอ',
+ 'permissionJson' => 'คุณไม่มีสิทธิ์ดำเนินการที่ร้องขอ',
+
+ // Auth
+ 'error_user_exists_different_creds' => 'มีผู้ใช้ที่ใช้อีเมล :email อยู่แล้วแต่ใช้ข้อมูลประจำตัวต่างกัน',
+ 'auth_pre_register_theme_prevention' => 'ไม่สามารถลงทะเบียนบัญชีผู้ใช้สำหรับข้อมูลที่ให้มาได้',
+ 'email_already_confirmed' => 'ยืนยันอีเมลแล้ว กรุณาลองเข้าสู่ระบบ',
+ 'email_confirmation_invalid' => 'โทเค็นยืนยันนี้ไม่ถูกต้องหรือถูกใช้ไปแล้ว กรุณาลองลงทะเบียนใหม่',
+ 'email_confirmation_expired' => 'โทเค็นยืนยันหมดอายุแล้ว ส่งอีเมลยืนยันใหม่ให้แล้ว',
+ 'email_confirmation_awaiting' => 'ที่อยู่อีเมลของบัญชีที่ใช้งานอยู่ต้องได้รับการยืนยัน',
+ 'ldap_fail_anonymous' => 'การเข้าถึง LDAP ล้มเหลวโดยใช้การเชื่อมต่อแบบไม่ระบุตัวตน',
+ 'ldap_fail_authed' => 'การเข้าถึง LDAP ล้มเหลวโดยใช้ข้อมูล dn และรหัสผ่านที่กำหนด',
+ 'ldap_extension_not_installed' => 'ไม่ได้ติดตั้ง PHP extension สำหรับ LDAP',
+ 'ldap_cannot_connect' => 'ไม่สามารถเชื่อมต่อกับเซิร์ฟเวอร์ LDAP ได้ การเชื่อมต่อเริ่มต้นล้มเหลว',
+ 'saml_already_logged_in' => 'เข้าสู่ระบบแล้ว',
+ 'saml_no_email_address' => 'ไม่พบที่อยู่อีเมลสำหรับผู้ใช้นี้ในข้อมูลที่ระบบยืนยันตัวตนภายนอกส่งมา',
+ 'saml_invalid_response_id' => 'คำขอจากระบบยืนยันตัวตนภายนอกไม่ได้รับการยอมรับจากกระบวนการที่เริ่มต้นโดยแอปพลิเคชันนี้ การนำทางย้อนกลับหลังเข้าสู่ระบบอาจทำให้เกิดปัญหานี้',
+ 'saml_fail_authed' => 'การเข้าสู่ระบบด้วย :system ล้มเหลว ระบบไม่ได้ให้การอนุญาตที่สำเร็จ',
+ 'oidc_already_logged_in' => 'เข้าสู่ระบบแล้ว',
+ 'oidc_no_email_address' => 'ไม่พบที่อยู่อีเมลสำหรับผู้ใช้นี้ในข้อมูลที่ระบบยืนยันตัวตนภายนอกส่งมา',
+ 'oidc_fail_authed' => 'การเข้าสู่ระบบด้วย :system ล้มเหลว ระบบไม่ได้ให้การอนุญาตที่สำเร็จ',
+ 'social_no_action_defined' => 'ไม่ได้กำหนดการดำเนินการ',
+ 'social_login_bad_response' => "เกิดข้อผิดพลาดระหว่างเข้าสู่ระบบด้วย :socialAccount: \n:error",
+ 'social_account_in_use' => 'บัญชี :socialAccount นี้ถูกใช้งานแล้ว ลองเข้าสู่ระบบผ่านตัวเลือก :socialAccount',
+ 'social_account_email_in_use' => 'อีเมล :email ถูกใช้งานแล้ว หากมีบัญชีอยู่แล้ว คุณสามารถเชื่อมต่อบัญชี :socialAccount จากการตั้งค่าโปรไฟล์ได้',
+ 'social_account_existing' => ':socialAccount นี้เชื่อมต่อกับโปรไฟล์ของคุณแล้ว',
+ 'social_account_already_used_existing' => 'บัญชี :socialAccount นี้ถูกใช้งานโดยผู้ใช้อื่นแล้ว',
+ 'social_account_not_used' => 'บัญชี :socialAccount นี้ไม่ได้เชื่อมต่อกับผู้ใช้ใด กรุณาแนบในการตั้งค่าโปรไฟล์',
+ 'social_account_register_instructions' => 'หากยังไม่มีบัญชี คุณสามารถลงทะเบียนโดยใช้ตัวเลือก :socialAccount',
+ 'social_driver_not_found' => 'ไม่พบ Social driver',
+ 'social_driver_not_configured' => 'การตั้งค่า Social ของ :socialAccount ไม่ถูกต้อง',
+ 'invite_token_expired' => 'ลิงก์เชิญนี้หมดอายุแล้ว คุณสามารถลองรีเซ็ตรหัสผ่านบัญชีแทนได้',
+ 'login_user_not_found' => 'ไม่พบผู้ใช้สำหรับการดำเนินการนี้',
+
+ // System
+ 'path_not_writable' => 'ไม่สามารถอัปโหลดไปยังพาธ :filePath ได้ โปรดตรวจสอบว่าเซิร์ฟเวอร์มีสิทธิ์เขียนได้',
+ 'cannot_get_image_from_url' => 'ไม่สามารถดึงรูปภาพจาก :url ได้',
+ 'cannot_create_thumbs' => 'เซิร์ฟเวอร์ไม่สามารถสร้างภาพย่อได้ โปรดตรวจสอบว่าติดตั้ง PHP extension GD แล้ว',
+ 'server_upload_limit' => 'เซิร์ฟเวอร์ไม่อนุญาตให้อัปโหลดไฟล์ขนาดนี้ กรุณาลองใช้ไฟล์ขนาดเล็กกว่า',
+ 'server_post_limit' => 'เซิร์ฟเวอร์ไม่สามารถรับข้อมูลในปริมาณที่กำหนดได้ ลองใหม่ด้วยข้อมูลน้อยลงหรือไฟล์ขนาดเล็กกว่า',
+ 'uploaded' => 'เซิร์ฟเวอร์ไม่อนุญาตให้อัปโหลดไฟล์ขนาดนี้ กรุณาลองใช้ไฟล์ขนาดเล็กกว่า',
+
+ // Drawing & Images
+ 'image_upload_error' => 'เกิดข้อผิดพลาดขณะอัปโหลดรูปภาพ',
+ 'image_upload_type_error' => 'ประเภทรูปภาพที่อัปโหลดไม่ถูกต้อง',
+ 'image_upload_replace_type' => 'การแทนที่ไฟล์รูปภาพต้องใช้ประเภทเดียวกัน',
+ 'image_upload_memory_limit' => 'ไม่สามารถจัดการการอัปโหลดรูปภาพและ/หรือสร้างภาพย่อได้เนื่องจากทรัพยากรระบบไม่เพียงพอ',
+ 'image_thumbnail_memory_limit' => 'ไม่สามารถสร้างขนาดรูปภาพต่างๆ ได้เนื่องจากทรัพยากรระบบไม่เพียงพอ',
+ 'image_gallery_thumbnail_memory_limit' => 'ไม่สามารถสร้างภาพย่อแกลเลอรีได้เนื่องจากทรัพยากรระบบไม่เพียงพอ',
+ 'drawing_data_not_found' => 'ไม่สามารถโหลดข้อมูลภาพวาดได้ ไฟล์ภาพวาดอาจไม่มีอยู่แล้วหรือคุณไม่มีสิทธิ์เข้าถึง',
+
+ // Attachments
+ 'attachment_not_found' => 'ไม่พบไฟล์แนบ',
+ 'attachment_upload_error' => 'เกิดข้อผิดพลาดขณะอัปโหลดไฟล์แนบ',
+
+ // Pages
+ 'page_draft_autosave_fail' => 'บันทึกร่างล้มเหลว โปรดตรวจสอบการเชื่อมต่ออินเทอร์เน็ตก่อนบันทึกหน้านี้',
+ 'page_draft_delete_fail' => 'ลบร่างหน้าและดึงเนื้อหาที่บันทึกปัจจุบันล้มเหลว',
+ 'page_custom_home_deletion' => 'ไม่สามารถลบหน้าได้ในขณะที่ตั้งเป็นหน้าแรก',
+
+ // Entities
+ 'entity_not_found' => 'ไม่พบรายการ',
+ 'bookshelf_not_found' => 'ไม่พบชั้นวาง',
+ 'book_not_found' => 'ไม่พบหนังสือ',
+ 'page_not_found' => 'ไม่พบหน้า',
+ 'chapter_not_found' => 'ไม่พบบท',
+ 'selected_book_not_found' => 'ไม่พบหนังสือที่เลือก',
+ 'selected_book_chapter_not_found' => 'ไม่พบหนังสือหรือบทที่เลือก',
+ 'guests_cannot_save_drafts' => 'ผู้เยี่ยมชมไม่สามารถบันทึกร่างได้',
+
+ // Users
+ 'users_cannot_delete_only_admin' => 'ไม่สามารถลบผู้ดูแลระบบคนเดียวได้',
+ 'users_cannot_delete_guest' => 'ไม่สามารถลบผู้ใช้แบบผู้เยี่ยมชมได้',
+ 'users_could_not_send_invite' => 'ไม่สามารถสร้างผู้ใช้ได้เนื่องจากส่งอีเมลเชิญล้มเหลว',
+
+ // Roles
+ 'role_cannot_be_edited' => 'บทบาทนี้ไม่สามารถแก้ไขได้',
+ 'role_system_cannot_be_deleted' => 'บทบาทนี้เป็นบทบาทระบบและไม่สามารถลบได้',
+ 'role_registration_default_cannot_delete' => 'บทบาทนี้ไม่สามารถลบได้ในขณะที่ตั้งเป็นบทบาทลงทะเบียนเริ่มต้น',
+ 'role_cannot_remove_only_admin' => 'ผู้ใช้นี้เป็นผู้ใช้คนเดียวที่ได้รับบทบาทผู้ดูแลระบบ กรุณากำหนดบทบาทผู้ดูแลระบบให้ผู้ใช้อื่นก่อนที่จะลบออกที่นี่',
+
+ // Comments
+ 'comment_list' => 'เกิดข้อผิดพลาดขณะดึงความคิดเห็น',
+ 'cannot_add_comment_to_draft' => 'ไม่สามารถเพิ่มความคิดเห็นในร่างได้',
+ 'comment_add' => 'เกิดข้อผิดพลาดขณะเพิ่ม/อัปเดตความคิดเห็น',
+ 'comment_delete' => 'เกิดข้อผิดพลาดขณะลบความคิดเห็น',
+ 'empty_comment' => 'ไม่สามารถเพิ่มความคิดเห็นที่ว่างเปล่าได้',
+
+ // Error pages
+ '404_page_not_found' => 'ไม่พบหน้า',
+ 'sorry_page_not_found' => 'ขออภัย ไม่พบหน้าที่คุณกำลังมองหา',
+ 'sorry_page_not_found_permission_warning' => 'หากคุณคาดว่าหน้านี้มีอยู่ คุณอาจไม่มีสิทธิ์ดูหน้านี้',
+ 'image_not_found' => 'ไม่พบรูปภาพ',
+ 'image_not_found_subtitle' => 'ขออภัย ไม่พบไฟล์รูปภาพที่คุณกำลังมองหา',
+ 'image_not_found_details' => 'หากคุณคาดว่ารูปภาพนี้มีอยู่ อาจถูกลบไปแล้ว',
+ 'return_home' => 'กลับไปหน้าแรก',
+ 'error_occurred' => 'เกิดข้อผิดพลาด',
+ 'app_down' => ':appName ไม่พร้อมใช้งานในขณะนี้',
+ 'back_soon' => 'จะกลับมาให้บริการเร็วๆ นี้',
+
+ // Import
+ 'import_zip_cant_read' => 'ไม่สามารถอ่านไฟล์ ZIP ได้',
+ 'import_zip_cant_decode_data' => 'ไม่สามารถค้นหาและถอดรหัสเนื้อหา data.json ใน ZIP ได้',
+ 'import_zip_no_data' => 'ข้อมูลในไฟล์ ZIP ไม่มีเนื้อหาหนังสือ บท หรือหน้าที่คาดไว้',
+ 'import_zip_data_too_large' => 'เนื้อหา data.json ใน ZIP เกินขนาดอัปโหลดสูงสุดที่กำหนดในแอปพลิเคชัน',
+ 'import_validation_failed' => 'ตรวจสอบ ZIP นำเข้าล้มเหลวพร้อมข้อผิดพลาด:',
+ 'import_zip_failed_notification' => 'นำเข้าไฟล์ ZIP ล้มเหลว',
+ 'import_perms_books' => 'คุณขาดสิทธิ์ที่จำเป็นในการสร้างหนังสือ',
+ 'import_perms_chapters' => 'คุณขาดสิทธิ์ที่จำเป็นในการสร้างบท',
+ 'import_perms_pages' => 'คุณขาดสิทธิ์ที่จำเป็นในการสร้างหน้า',
+ 'import_perms_images' => 'คุณขาดสิทธิ์ที่จำเป็นในการสร้างรูปภาพ',
+ 'import_perms_attachments' => 'คุณขาดสิทธิ์ที่จำเป็นในการสร้างไฟล์แนบ',
+
+ // API errors
+ 'api_no_authorization_found' => 'ไม่พบโทเค็นการอนุญาตในคำขอ',
+ 'api_bad_authorization_format' => 'พบโทเค็นการอนุญาตในคำขอแต่รูปแบบดูเหมือนไม่ถูกต้อง',
+ 'api_user_token_not_found' => 'ไม่พบ API token ที่ตรงกับโทเค็นการอนุญาตที่ให้มา',
+ 'api_incorrect_token_secret' => 'รหัสลับที่ให้มาสำหรับ API token ที่ใช้ไม่ถูกต้อง',
+ 'api_user_no_api_permission' => 'เจ้าของ API token ที่ใช้ไม่มีสิทธิ์เรียกใช้ API',
+ 'api_user_token_expired' => 'โทเค็นการอนุญาตที่ใช้หมดอายุแล้ว',
+ 'api_cookie_auth_only_get' => 'อนุญาตเฉพาะคำขอ GET เมื่อใช้ API ด้วยการยืนยันตัวตนแบบ cookie',
+
+ // Settings & Maintenance
+ 'maintenance_test_email_failure' => 'เกิดข้อผิดพลาดขณะส่งอีเมลทดสอบ:',
+
+ // HTTP errors
+ 'http_ssr_url_no_match' => 'URL ไม่ตรงกับโฮสต์ SSR ที่อนุญาตที่กำหนดค่าไว้',
+];
diff --git a/lang/th/notifications.php b/lang/th/notifications.php
new file mode 100644
index 000000000..661c83fdb
--- /dev/null
+++ b/lang/th/notifications.php
@@ -0,0 +1,29 @@
+ 'ความคิดเห็นใหม่ในหน้า: :pageName',
+ 'new_comment_intro' => 'มีผู้ใช้แสดงความคิดเห็นในหน้าใน :appName:',
+ 'new_page_subject' => 'หน้าใหม่: :pageName',
+ 'new_page_intro' => 'มีการสร้างหน้าใหม่ใน :appName:',
+ 'updated_page_subject' => 'แก้ไขหน้า: :pageName',
+ 'updated_page_intro' => 'มีการแก้ไขหน้าใน :appName:',
+ 'updated_page_debounce' => 'เพื่อป้องกันการแจ้งเตือนจำนวนมาก คุณจะไม่ได้รับการแจ้งเตือนสำหรับการแก้ไขเพิ่มเติมในหน้านี้โดยผู้แก้ไขคนเดิมในช่วงเวลาหนึ่ง',
+ 'comment_mention_subject' => 'คุณถูกกล่าวถึงในความคิดเห็นในหน้า: :pageName',
+ 'comment_mention_intro' => 'คุณถูกกล่าวถึงในความคิดเห็นใน :appName:',
+
+ 'detail_page_name' => 'ชื่อหน้า:',
+ 'detail_page_path' => 'พาธหน้า:',
+ 'detail_commenter' => 'ผู้แสดงความคิดเห็น:',
+ 'detail_comment' => 'ความคิดเห็น:',
+ 'detail_created_by' => 'สร้างโดย:',
+ 'detail_updated_by' => 'แก้ไขโดย:',
+
+ 'action_view_comment' => 'ดูความคิดเห็น',
+ 'action_view_page' => 'ดูหน้า',
+
+ 'footer_reason' => 'คุณได้รับการแจ้งเตือนนี้เพราะ :link ครอบคลุมกิจกรรมประเภทนี้สำหรับรายการนี้',
+ 'footer_reason_link' => 'การตั้งค่าการแจ้งเตือนของคุณ',
+];
diff --git a/lang/th/pagination.php b/lang/th/pagination.php
new file mode 100644
index 000000000..c29e7d0d9
--- /dev/null
+++ b/lang/th/pagination.php
@@ -0,0 +1,12 @@
+ '« ก่อนหน้า',
+ 'next' => 'ถัดไป »',
+
+];
diff --git a/lang/th/passwords.php b/lang/th/passwords.php
new file mode 100644
index 000000000..3429c7763
--- /dev/null
+++ b/lang/th/passwords.php
@@ -0,0 +1,15 @@
+ 'รหัสผ่านต้องมีอย่างน้อยแปดตัวอักษรและต้องตรงกับการยืนยัน',
+ 'user' => "ไม่พบผู้ใช้ที่ใช้ที่อยู่อีเมลนี้",
+ 'token' => 'โทเค็นรีเซ็ตรหัสผ่านไม่ถูกต้องสำหรับที่อยู่อีเมลนี้',
+ 'sent' => 'ส่งลิงก์รีเซ็ตรหัสผ่านไปยังอีเมลของคุณแล้ว!',
+ 'reset' => 'รีเซ็ตรหัสผ่านของคุณแล้ว!',
+
+];
diff --git a/lang/th/preferences.php b/lang/th/preferences.php
new file mode 100644
index 000000000..56d57fc26
--- /dev/null
+++ b/lang/th/preferences.php
@@ -0,0 +1,52 @@
+ 'บัญชีของฉัน',
+
+ 'shortcuts' => 'แป้นพิมพ์ลัด',
+ 'shortcuts_interface' => 'การตั้งค่าแป้นพิมพ์ลัด UI',
+ 'shortcuts_toggle_desc' => 'คุณสามารถเปิดหรือปิดแป้นพิมพ์ลัดของระบบที่ใช้สำหรับการนำทางและการดำเนินการได้ที่นี่',
+ 'shortcuts_customize_desc' => 'คุณสามารถปรับแต่งแป้นพิมพ์ลัดแต่ละรายการด้านล่างได้ เพียงกดคีย์ผสมที่ต้องการหลังจากเลือกช่องป้อนข้อมูลสำหรับแป้นลัดนั้น',
+ 'shortcuts_toggle_label' => 'เปิดใช้งานแป้นพิมพ์ลัด',
+ 'shortcuts_section_navigation' => 'การนำทาง',
+ 'shortcuts_section_actions' => 'การดำเนินการทั่วไป',
+ 'shortcuts_save' => 'บันทึกแป้นพิมพ์ลัด',
+ 'shortcuts_overlay_desc' => 'หมายเหตุ: เมื่อเปิดใช้งานแป้นพิมพ์ลัด จะมีแผงช่วยเหลือที่เข้าถึงได้โดยกด "?" ซึ่งจะแสดงแป้นพิมพ์ลัดที่ใช้ได้สำหรับการดำเนินการที่แสดงอยู่บนหน้าจอ',
+ 'shortcuts_update_success' => 'อัปเดตการตั้งค่าแป้นพิมพ์ลัดแล้ว!',
+ 'shortcuts_overview_desc' => 'จัดการแป้นพิมพ์ลัดที่ใช้นำทางในส่วนติดต่อผู้ใช้ของระบบ',
+
+ 'notifications' => 'การตั้งค่าการแจ้งเตือน',
+ 'notifications_desc' => 'ควบคุมการแจ้งเตือนทางอีเมลที่คุณได้รับเมื่อมีกิจกรรมบางอย่างในระบบ',
+ 'notifications_opt_own_page_changes' => 'แจ้งเตือนเมื่อมีการเปลี่ยนแปลงหน้าที่ฉันเป็นเจ้าของ',
+ 'notifications_opt_own_page_comments' => 'แจ้งเตือนเมื่อมีความคิดเห็นในหน้าที่ฉันเป็นเจ้าของ',
+ 'notifications_opt_comment_mentions' => 'แจ้งเตือนเมื่อฉันถูกกล่าวถึงในความคิดเห็น',
+ 'notifications_opt_comment_replies' => 'แจ้งเตือนเมื่อมีการตอบกลับความคิดเห็นของฉัน',
+ 'notifications_save' => 'บันทึกการตั้งค่า',
+ 'notifications_update_success' => 'อัปเดตการตั้งค่าการแจ้งเตือนแล้ว!',
+ 'notifications_watched' => 'รายการที่ติดตามและไม่สนใจ',
+ 'notifications_watched_desc' => 'รายการด้านล่างมีการตั้งค่าการติดตามแบบกำหนดเอง หากต้องการอัปเดตการตั้งค่า ให้ดูรายการนั้นแล้วค้นหาตัวเลือกการติดตามในแถบด้านข้าง',
+
+ 'auth' => 'การเข้าถึงและความปลอดภัย',
+ 'auth_change_password' => 'เปลี่ยนรหัสผ่าน',
+ 'auth_change_password_desc' => 'เปลี่ยนรหัสผ่านที่ใช้เข้าสู่ระบบ ต้องมีความยาวอย่างน้อย 8 ตัวอักษร',
+ 'auth_change_password_success' => 'อัปเดตรหัสผ่านแล้ว!',
+
+ 'profile' => 'รายละเอียดโปรไฟล์',
+ 'profile_desc' => 'จัดการรายละเอียดบัญชีที่แสดงตัวตนต่อผู้ใช้อื่น รวมถึงรายละเอียดที่ใช้สำหรับการสื่อสารและการปรับแต่งระบบ',
+ 'profile_view_public' => 'ดูโปรไฟล์สาธารณะ',
+ 'profile_name_desc' => 'กำหนดชื่อที่แสดงซึ่งจะมองเห็นได้โดยผู้ใช้อื่นในระบบผ่านกิจกรรมที่คุณดำเนินการและเนื้อหาที่คุณเป็นเจ้าของ',
+ 'profile_email_desc' => 'อีเมลนี้จะใช้สำหรับการแจ้งเตือนและการเข้าถึงระบบขึ้นอยู่กับการยืนยันตัวตนที่ใช้งานอยู่',
+ 'profile_email_no_permission' => 'ขออภัย คุณไม่มีสิทธิ์เปลี่ยนที่อยู่อีเมล หากต้องการเปลี่ยน กรุณาติดต่อผู้ดูแลระบบ',
+ 'profile_avatar_desc' => 'เลือกรูปภาพที่จะใช้แสดงตัวตนต่อผู้อื่นในระบบ รูปภาพควรเป็นรูปสี่เหลี่ยมจัตุรัสขนาดประมาณ 256px',
+ 'profile_admin_options' => 'ตัวเลือกสำหรับผู้ดูแลระบบ',
+ 'profile_admin_options_desc' => 'ตัวเลือกระดับผู้ดูแลระบบเพิ่มเติม เช่น การจัดการการกำหนดบทบาท สามารถพบได้ในพื้นที่ "การตั้งค่า > ผู้ใช้" ของแอปพลิเคชัน',
+
+ 'delete_account' => 'ลบบัญชี',
+ 'delete_my_account' => 'ลบบัญชีของฉัน',
+ 'delete_my_account_desc' => 'การดำเนินการนี้จะลบบัญชีผู้ใช้ของคุณออกจากระบบทั้งหมด คุณจะไม่สามารถกู้คืนบัญชีหรือยกเลิกการดำเนินการนี้ได้ เนื้อหาที่คุณสร้าง เช่น หน้าที่สร้างและรูปภาพที่อัปโหลด จะยังคงอยู่',
+ 'delete_my_account_warning' => 'คุณแน่ใจหรือไม่ว่าต้องการลบบัญชีของคุณ?',
+];
diff --git a/lang/th/settings.php b/lang/th/settings.php
new file mode 100644
index 000000000..558d2da0f
--- /dev/null
+++ b/lang/th/settings.php
@@ -0,0 +1,379 @@
+ 'การตั้งค่า',
+ 'settings_save' => 'บันทึกการตั้งค่า',
+ 'system_version' => 'เวอร์ชันระบบ',
+ 'categories' => 'หมวดหมู่',
+
+ // App Settings
+ 'app_customization' => 'การปรับแต่ง',
+ 'app_features_security' => 'คุณสมบัติและความปลอดภัย',
+ 'app_name' => 'ชื่อแอปพลิเคชัน',
+ 'app_name_desc' => 'ชื่อนี้จะแสดงในส่วนหัวและอีเมลที่ส่งโดยระบบ',
+ 'app_name_header' => 'แสดงชื่อในส่วนหัว',
+ 'app_public_access' => 'การเข้าถึงสาธารณะ',
+ 'app_public_access_desc' => 'การเปิดใช้งานตัวเลือกนี้จะอนุญาตให้ผู้เยี่ยมชมที่ไม่ได้เข้าสู่ระบบสามารถเข้าถึงเนื้อหาใน BookStack ของคุณได้',
+ 'app_public_access_desc_guest' => 'การเข้าถึงของผู้เยี่ยมชมสาธารณะสามารถควบคุมได้ผ่านผู้ใช้ "Guest"',
+ 'app_public_access_toggle' => 'อนุญาตการเข้าถึงสาธารณะ',
+ 'app_public_viewing' => 'อนุญาตให้ดูแบบสาธารณะ?',
+ 'app_secure_images' => 'การอัปโหลดรูปภาพแบบความปลอดภัยสูง',
+ 'app_secure_images_toggle' => 'เปิดใช้งานการอัปโหลดรูปภาพแบบความปลอดภัยสูง',
+ 'app_secure_images_desc' => 'เพื่อประสิทธิภาพ รูปภาพทั้งหมดเป็นสาธารณะ ตัวเลือกนี้จะเพิ่มสตริงสุ่มที่คาดเดาได้ยากหน้า URL รูปภาพ ตรวจสอบให้แน่ใจว่าไม่ได้เปิดใช้งานการแสดงรายการไดเรกทอรีเพื่อป้องกันการเข้าถึงที่ง่าย',
+ 'app_default_editor' => 'ตัวแก้ไขหน้าเริ่มต้น',
+ 'app_default_editor_desc' => 'เลือกตัวแก้ไขที่จะใช้โดยค่าเริ่มต้นเมื่อแก้ไขหน้าใหม่ ซึ่งสามารถแทนที่ได้ในระดับหน้าเมื่อมีสิทธิ์อนุญาต',
+ 'app_custom_html' => 'เนื้อหา HTML Head แบบกำหนดเอง',
+ 'app_custom_html_desc' => 'เนื้อหาที่เพิ่มที่นี่จะถูกแทรกที่ด้านล่างของส่วน ของทุกหน้า มีประโยชน์สำหรับการแทนที่สไตล์หรือเพิ่มโค้ด Analytics',
+ 'app_custom_html_disabled_notice' => 'เนื้อหา HTML head แบบกำหนดเองถูกปิดใช้งานในหน้าการตั้งค่านี้เพื่อให้สามารถเปลี่ยนแปลงที่ทำให้ใช้งานไม่ได้กลับคืนได้',
+ 'app_logo' => 'โลโก้แอปพลิเคชัน',
+ 'app_logo_desc' => 'ใช้ในแถบส่วนหัวของแอปพลิเคชัน รูปภาพควรมีความสูง 86px รูปภาพขนาดใหญ่จะถูกย่อขนาด',
+ 'app_icon' => 'ไอคอนแอปพลิเคชัน',
+ 'app_icon_desc' => 'ไอคอนนี้ใช้สำหรับแท็บเบราว์เซอร์และไอคอนทางลัด ควรเป็นรูปภาพ PNG สี่เหลี่ยมขนาด 256px',
+ 'app_homepage' => 'หน้าแรกของแอปพลิเคชัน',
+ 'app_homepage_desc' => 'เลือกมุมมองที่จะแสดงบนหน้าแรกแทนมุมมองเริ่มต้น สิทธิ์หน้าจะถูกละเว้นสำหรับหน้าที่เลือก',
+ 'app_homepage_select' => 'เลือกหน้า',
+ 'app_footer_links' => 'ลิงก์ส่วนท้าย',
+ 'app_footer_links_desc' => 'เพิ่มลิงก์เพื่อแสดงในส่วนท้ายของเว็บไซต์ จะแสดงที่ด้านล่างของส่วนใหญ่ของหน้า รวมถึงหน้าที่ไม่ต้องเข้าสู่ระบบ คุณสามารถใช้ป้ายชื่อ "trans::
ความคิดเห็นที่มีอยู่จะไม่ถูกแสดง',
+
+ // Color settings
+ 'color_scheme' => 'โครงสีของแอปพลิเคชัน',
+ 'color_scheme_desc' => 'ตั้งค่าสีที่จะใช้ในส่วนติดต่อผู้ใช้ของแอปพลิเคชัน สามารถกำหนดค่าสีแยกกันสำหรับโหมดมืดและโหมดสว่างเพื่อให้เหมาะกับธีมและรับประกันการอ่านง่าย',
+ 'ui_colors_desc' => 'ตั้งค่าสีหลักและสีลิงก์เริ่มต้นของแอปพลิเคชัน สีหลักใช้สำหรับแบนเนอร์ส่วนหัว ปุ่ม และการตกแต่งส่วนติดต่อ สีลิงก์เริ่มต้นใช้สำหรับลิงก์และการดำเนินการที่เป็นข้อความ',
+ 'app_color' => 'สีหลัก',
+ 'link_color' => 'สีลิงก์เริ่มต้น',
+ 'content_colors_desc' => 'ตั้งค่าสีสำหรับองค์ประกอบทั้งหมดในลำดับชั้นการจัดระเบียบหน้า แนะนำให้เลือกสีที่มีความสว่างใกล้เคียงกับสีเริ่มต้นเพื่อการอ่านง่าย',
+ 'bookshelf_color' => 'สีชั้นวาง',
+ 'book_color' => 'สีหนังสือ',
+ 'chapter_color' => 'สีบท',
+ 'page_color' => 'สีหน้า',
+ 'page_draft_color' => 'สีร่างหน้า',
+
+ // Registration Settings
+ 'reg_settings' => 'การลงทะเบียน',
+ 'reg_enable' => 'เปิดใช้งานการลงทะเบียน',
+ 'reg_enable_toggle' => 'เปิดใช้งานการลงทะเบียน',
+ 'reg_enable_desc' => 'เมื่อเปิดใช้งานการลงทะเบียน ผู้ใช้จะสามารถสมัครเป็นผู้ใช้แอปพลิเคชันได้ด้วยตนเอง เมื่อลงทะเบียนแล้วจะได้รับบทบาทผู้ใช้เริ่มต้นหนึ่งบทบาท',
+ 'reg_default_role' => 'บทบาทผู้ใช้เริ่มต้นหลังการลงทะเบียน',
+ 'reg_enable_external_warning' => 'ตัวเลือกด้านบนจะถูกละเว้นเมื่อการยืนยันตัวตน LDAP หรือ SAML ภายนอกเปิดใช้งานอยู่ บัญชีผู้ใช้สำหรับสมาชิกที่ไม่มีอยู่จะถูกสร้างอัตโนมัติหากการยืนยันตัวตนกับระบบภายนอกที่ใช้งานอยู่สำเร็จ',
+ 'reg_email_confirmation' => 'การยืนยันอีเมล',
+ 'reg_email_confirmation_toggle' => 'ต้องยืนยันอีเมล',
+ 'reg_confirm_email_desc' => 'หากใช้การจำกัดโดเมน จะต้องยืนยันอีเมลและตัวเลือกนี้จะถูกละเว้น',
+ 'reg_confirm_restrict_domain' => 'การจำกัดโดเมน',
+ 'reg_confirm_restrict_domain_desc' => 'กรอกรายการโดเมนอีเมลที่คั่นด้วยเครื่องหมายจุลภาคที่ต้องการจำกัดการลงทะเบียน ผู้ใช้จะได้รับอีเมลเพื่อยืนยันที่อยู่ก่อนที่จะสามารถโต้ตอบกับแอปพลิเคชัน
ผู้ใช้จะสามารถเปลี่ยนที่อยู่อีเมลได้หลังจากลงทะเบียนสำเร็จ',
+ 'reg_confirm_restrict_domain_placeholder' => 'ไม่มีการจำกัด',
+
+ // Sorting Settings
+ 'sorting' => 'รายการและการจัดเรียง',
+ 'sorting_book_default' => 'กฎการจัดเรียงหนังสือเริ่มต้น',
+ 'sorting_book_default_desc' => 'เลือกกฎการจัดเรียงเริ่มต้นที่จะใช้กับหนังสือใหม่ ไม่มีผลกับหนังสือที่มีอยู่แล้ว และสามารถแทนที่ได้ต่อหนังสือ',
+ 'sorting_rules' => 'กฎการจัดเรียง',
+ 'sorting_rules_desc' => 'นี่คือการดำเนินการจัดเรียงที่กำหนดไว้ล่วงหน้าซึ่งสามารถนำไปใช้กับเนื้อหาในระบบ',
+ 'sort_rule_assigned_to_x_books' => 'กำหนดให้ :count หนังสือ',
+ 'sort_rule_create' => 'สร้างกฎการจัดเรียง',
+ 'sort_rule_edit' => 'แก้ไขกฎการจัดเรียง',
+ 'sort_rule_delete' => 'ลบกฎการจัดเรียง',
+ 'sort_rule_delete_desc' => 'ลบกฎการจัดเรียงนี้ออกจากระบบ หนังสือที่ใช้กฎนี้จะกลับไปใช้การจัดเรียงแบบกำหนดเอง',
+ 'sort_rule_delete_warn_books' => 'กฎการจัดเรียงนี้ใช้งานอยู่กับ :count เล่ม คุณแน่ใจหรือไม่ว่าต้องการลบ?',
+ 'sort_rule_delete_warn_default' => 'กฎการจัดเรียงนี้ใช้งานอยู่เป็นค่าเริ่มต้นสำหรับหนังสือ คุณแน่ใจหรือไม่ว่าต้องการลบ?',
+ 'sort_rule_details' => 'รายละเอียดกฎการจัดเรียง',
+ 'sort_rule_details_desc' => 'ตั้งชื่อสำหรับกฎการจัดเรียงนี้ ซึ่งจะปรากฏในรายการเมื่อผู้ใช้เลือกการจัดเรียง',
+ 'sort_rule_operations' => 'การดำเนินการจัดเรียง',
+ 'sort_rule_operations_desc' => 'กำหนดการดำเนินการจัดเรียงโดยย้ายจากรายการที่มีให้ เมื่อใช้งาน การดำเนินการจะถูกนำไปใช้ตามลำดับจากบนลงล่าง การเปลี่ยนแปลงจะถูกนำไปใช้กับหนังสือที่กำหนดทั้งหมดเมื่อบันทึก',
+ 'sort_rule_available_operations' => 'การดำเนินการที่มีให้',
+ 'sort_rule_available_operations_empty' => 'ไม่มีการดำเนินการเหลือ',
+ 'sort_rule_configured_operations' => 'การดำเนินการที่กำหนดค่า',
+ 'sort_rule_configured_operations_empty' => 'ลาก/เพิ่มการดำเนินการจากรายการ "การดำเนินการที่มีให้"',
+ 'sort_rule_op_asc' => '(น้อยไปมาก)',
+ 'sort_rule_op_desc' => '(มากไปน้อย)',
+ 'sort_rule_op_name' => 'ชื่อ - ตามตัวอักษร',
+ 'sort_rule_op_name_numeric' => 'ชื่อ - ตามตัวเลข',
+ 'sort_rule_op_created_date' => 'วันที่สร้าง',
+ 'sort_rule_op_updated_date' => 'วันที่แก้ไข',
+ 'sort_rule_op_chapters_first' => 'บทอยู่ก่อน',
+ 'sort_rule_op_chapters_last' => 'บทอยู่หลัง',
+ 'sorting_page_limits' => 'ขีดจำกัดการแสดงผลต่อหน้า',
+ 'sorting_page_limits_desc' => 'ตั้งค่าจำนวนรายการที่จะแสดงต่อหน้าในรายการต่างๆ ในระบบ โดยทั่วไปจำนวนน้อยจะมีประสิทธิภาพดีกว่า ขณะที่จำนวนมากจะลดความจำเป็นในการคลิกผ่านหลายหน้า แนะนำให้ใช้ทวีคูณของ 6',
+
+ // Maintenance settings
+ 'maint' => 'การบำรุงรักษา',
+ 'maint_image_cleanup' => 'ล้างรูปภาพ',
+ 'maint_image_cleanup_desc' => 'สแกนเนื้อหาหน้าและการแก้ไขเพื่อตรวจสอบว่ารูปภาพและภาพวาดใดกำลังใช้งานอยู่และรูปภาพใดซ้ำซ้อน ตรวจสอบให้แน่ใจว่าสร้างข้อมูลสำรองฐานข้อมูลและรูปภาพฉบับสมบูรณ์ก่อนรัน',
+ 'maint_delete_images_only_in_revisions' => 'ลบรูปภาพที่มีเฉพาะในการแก้ไขหน้าเก่าด้วย',
+ 'maint_image_cleanup_run' => 'รันการล้างข้อมูล',
+ 'maint_image_cleanup_warning' => 'พบรูปภาพที่อาจไม่ได้ใช้งาน :count รายการ คุณแน่ใจหรือไม่ว่าต้องการลบรูปภาพเหล่านี้?',
+ 'maint_image_cleanup_success' => 'พบและลบรูปภาพที่อาจไม่ได้ใช้งาน :count รายการ!',
+ 'maint_image_cleanup_nothing_found' => 'ไม่พบรูปภาพที่ไม่ได้ใช้งาน ไม่มีการลบ!',
+ 'maint_send_test_email' => 'ส่งอีเมลทดสอบ',
+ 'maint_send_test_email_desc' => 'ส่งอีเมลทดสอบไปยังที่อยู่อีเมลที่ระบุในโปรไฟล์ของคุณ',
+ 'maint_send_test_email_run' => 'ส่งอีเมลทดสอบ',
+ 'maint_send_test_email_success' => 'ส่งอีเมลไปยัง :address แล้ว',
+ 'maint_send_test_email_mail_subject' => 'อีเมลทดสอบ',
+ 'maint_send_test_email_mail_greeting' => 'การส่งอีเมลดูเหมือนจะทำงานได้!',
+ 'maint_send_test_email_mail_text' => 'ยินดีด้วย! เนื่องจากคุณได้รับการแจ้งเตือนทางอีเมลนี้ การตั้งค่าอีเมลของคุณดูเหมือนจะได้รับการกำหนดค่าอย่างถูกต้อง',
+ 'maint_recycle_bin_desc' => 'ชั้นวาง หนังสือ บท และหน้าที่ถูกลบจะถูกส่งไปยังถังรีไซเคิลเพื่อให้สามารถกู้คืนหรือลบถาวรได้ รายการเก่าในถังรีไซเคิลอาจถูกลบโดยอัตโนมัติหลังจากสักพักขึ้นอยู่กับการกำหนดค่าระบบ',
+ 'maint_recycle_bin_open' => 'เปิดถังรีไซเคิล',
+ 'maint_regen_references' => 'สร้างการอ้างอิงใหม่',
+ 'maint_regen_references_desc' => 'การดำเนินการนี้จะสร้างดัชนีการอ้างอิงข้ามรายการในฐานข้อมูลใหม่ โดยปกติจะจัดการโดยอัตโนมัติ แต่การดำเนินการนี้มีประโยชน์สำหรับการสร้างดัชนีเนื้อหาเก่าหรือเนื้อหาที่เพิ่มผ่านวิธีที่ไม่เป็นทางการ',
+ 'maint_regen_references_success' => 'สร้างดัชนีการอ้างอิงใหม่แล้ว!',
+ 'maint_timeout_command_note' => 'หมายเหตุ: การดำเนินการนี้อาจใช้เวลานาน ซึ่งอาจทำให้เกิดปัญหา timeout ในบางสภาพแวดล้อมเว็บ ทางเลือกหนึ่งคือดำเนินการผ่านคำสั่ง terminal',
+
+ // Recycle Bin
+ 'recycle_bin' => 'ถังรีไซเคิล',
+ 'recycle_bin_desc' => 'คุณสามารถกู้คืนรายการที่ถูกลบหรือเลือกลบออกจากระบบถาวรได้ที่นี่ รายการนี้ไม่ได้กรองต่างจากรายการกิจกรรมที่คล้ายกันในระบบซึ่งมีการกรองสิทธิ์',
+ 'recycle_bin_deleted_item' => 'รายการที่ถูกลบ',
+ 'recycle_bin_deleted_parent' => 'รายการแม่',
+ 'recycle_bin_deleted_by' => 'ลบโดย',
+ 'recycle_bin_deleted_at' => 'เวลาที่ลบ',
+ 'recycle_bin_permanently_delete' => 'ลบถาวร',
+ 'recycle_bin_restore' => 'กู้คืน',
+ 'recycle_bin_contents_empty' => 'ถังรีไซเคิลว่างเปล่า',
+ 'recycle_bin_empty' => 'ล้างถังรีไซเคิล',
+ 'recycle_bin_empty_confirm' => 'การดำเนินการนี้จะทำลายรายการทั้งหมดในถังรีไซเคิลอย่างถาวร รวมถึงเนื้อหาที่อยู่ในแต่ละรายการ คุณแน่ใจหรือไม่ว่าต้องการล้างถังรีไซเคิล?',
+ 'recycle_bin_destroy_confirm' => 'การดำเนินการนี้จะลบรายการนี้ออกจากระบบอย่างถาวร พร้อมกับองค์ประกอบลูกที่แสดงด้านล่าง และคุณจะไม่สามารถกู้คืนเนื้อหานี้ได้ คุณแน่ใจหรือไม่?',
+ 'recycle_bin_destroy_list' => 'รายการที่จะถูกทำลาย',
+ 'recycle_bin_restore_list' => 'รายการที่จะถูกกู้คืน',
+ 'recycle_bin_restore_confirm' => 'การดำเนินการนี้จะกู้คืนรายการที่ถูกลบ รวมถึงองค์ประกอบลูก ไปยังตำแหน่งเดิม หากตำแหน่งเดิมถูกลบไปแล้วและอยู่ในถังรีไซเคิล จะต้องกู้คืนรายการแม่ด้วย',
+ 'recycle_bin_restore_deleted_parent' => 'รายการแม่ของรายการนี้ถูกลบเช่นกัน จะยังคงถูกลบจนกว่าจะกู้คืนรายการแม่',
+ 'recycle_bin_restore_parent' => 'กู้คืนรายการแม่',
+ 'recycle_bin_destroy_notification' => 'ลบรายการทั้งหมด :count รายการจากถังรีไซเคิล',
+ 'recycle_bin_restore_notification' => 'กู้คืนรายการทั้งหมด :count รายการจากถังรีไซเคิล',
+
+ // Audit Log
+ 'audit' => 'บันทึกการตรวจสอบ',
+ 'audit_desc' => 'บันทึกการตรวจสอบนี้แสดงรายการกิจกรรมที่ติดตามในระบบ รายการนี้ไม่ได้กรองต่างจากรายการกิจกรรมที่คล้ายกันในระบบซึ่งมีการกรองสิทธิ์',
+ 'audit_event_filter' => 'ตัวกรองกิจกรรม',
+ 'audit_event_filter_no_filter' => 'ไม่มีตัวกรอง',
+ 'audit_deleted_item' => 'รายการที่ถูกลบ',
+ 'audit_deleted_item_name' => 'ชื่อ: :name',
+ 'audit_table_user' => 'ผู้ใช้',
+ 'audit_table_event' => 'กิจกรรม',
+ 'audit_table_related' => 'รายการหรือรายละเอียดที่เกี่ยวข้อง',
+ 'audit_table_ip' => 'IP Address',
+ 'audit_table_date' => 'วันที่กิจกรรม',
+ 'audit_date_from' => 'ช่วงวันที่ตั้งแต่',
+ 'audit_date_to' => 'ช่วงวันที่ถึง',
+
+ // Role Settings
+ 'roles' => 'บทบาท',
+ 'role_user_roles' => 'บทบาทผู้ใช้',
+ 'roles_index_desc' => 'บทบาทใช้สำหรับจัดกลุ่มผู้ใช้และให้สิทธิ์ระบบแก่สมาชิก เมื่อผู้ใช้เป็นสมาชิกของหลายบทบาท สิทธิ์ที่ได้รับจะสะสมกัน และผู้ใช้จะได้รับความสามารถทั้งหมด',
+ 'roles_x_users_assigned' => 'กำหนด :count ผู้ใช้',
+ 'roles_x_permissions_provided' => ':count สิทธิ์',
+ 'roles_assigned_users' => 'ผู้ใช้ที่กำหนด',
+ 'roles_permissions_provided' => 'สิทธิ์ที่ให้',
+ 'role_create' => 'สร้างบทบาทใหม่',
+ 'role_delete' => 'ลบบทบาท',
+ 'role_delete_confirm' => 'การดำเนินการนี้จะลบบทบาทชื่อ \':roleName\'',
+ 'role_delete_users_assigned' => 'บทบาทนี้มีผู้ใช้ :userCount คนที่กำหนดไว้ หากต้องการย้ายผู้ใช้จากบทบาทนี้ให้เลือกบทบาทใหม่ด้านล่าง',
+ 'role_delete_no_migration' => "ไม่ต้องย้ายผู้ใช้",
+ 'role_delete_sure' => 'คุณแน่ใจหรือไม่ว่าต้องการลบบทบาทนี้?',
+ 'role_edit' => 'แก้ไขบทบาท',
+ 'role_details' => 'รายละเอียดบทบาท',
+ 'role_name' => 'ชื่อบทบาท',
+ 'role_desc' => 'คำอธิบายสั้นของบทบาท',
+ 'role_mfa_enforced' => 'ต้องใช้การยืนยันตัวตนแบบหลายขั้นตอน',
+ 'role_external_auth_id' => 'ID การยืนยันตัวตนภายนอก',
+ 'role_system' => 'สิทธิ์ระบบ',
+ 'role_manage_users' => 'จัดการผู้ใช้',
+ 'role_manage_roles' => 'จัดการบทบาทและสิทธิ์บทบาท',
+ 'role_manage_entity_permissions' => 'จัดการสิทธิ์หนังสือ บท และหน้าทั้งหมด',
+ 'role_manage_own_entity_permissions' => 'จัดการสิทธิ์บนหนังสือ บท และหน้าของตัวเอง',
+ 'role_manage_page_templates' => 'จัดการแม่แบบหน้า',
+ 'role_access_api' => 'เข้าถึง API ระบบ',
+ 'role_manage_settings' => 'จัดการการตั้งค่าแอปพลิเคชัน',
+ 'role_export_content' => 'ส่งออกเนื้อหา',
+ 'role_import_content' => 'นำเข้าเนื้อหา',
+ 'role_editor_change' => 'เปลี่ยนตัวแก้ไขหน้า',
+ 'role_notifications' => 'รับและจัดการการแจ้งเตือน',
+ 'role_permission_note_users_and_roles' => 'สิทธิ์เหล่านี้จะให้การมองเห็นและการค้นหาผู้ใช้และบทบาทในระบบด้วยในทางเทคนิค',
+ 'role_asset' => 'สิทธิ์ Asset',
+ 'roles_system_warning' => 'โปรดทราบว่าการเข้าถึงสิทธิ์ใดๆ ในสามสิทธิ์ข้างต้นอาจอนุญาตให้ผู้ใช้เปลี่ยนแปลงสิทธิ์ของตัวเองหรือของผู้อื่นในระบบ กรุณากำหนดบทบาทที่มีสิทธิ์เหล่านี้เฉพาะกับผู้ใช้ที่เชื่อถือได้เท่านั้น',
+ 'role_asset_desc' => 'สิทธิ์เหล่านี้ควบคุมการเข้าถึงเริ่มต้นสำหรับ asset ในระบบ สิทธิ์บนหนังสือ บท และหน้าจะแทนที่สิทธิ์เหล่านี้',
+ 'role_asset_admins' => 'ผู้ดูแลระบบได้รับสิทธิ์เข้าถึงเนื้อหาทั้งหมดโดยอัตโนมัติ แต่ตัวเลือกเหล่านี้อาจแสดงหรือซ่อนตัวเลือก UI',
+ 'role_asset_image_view_note' => 'เกี่ยวข้องกับการมองเห็นภายในตัวจัดการรูปภาพ การเข้าถึงไฟล์รูปภาพที่อัปโหลดจริงจะขึ้นอยู่กับตัวเลือกการจัดเก็บรูปภาพของระบบ',
+ 'role_asset_users_note' => 'สิทธิ์เหล่านี้จะให้การมองเห็นและการค้นหาผู้ใช้ในระบบด้วยในทางเทคนิค',
+ 'role_all' => 'ทั้งหมด',
+ 'role_own' => 'ของตัวเอง',
+ 'role_controlled_by_asset' => 'ควบคุมโดย asset ที่อัปโหลดไปยัง',
+ 'role_controlled_by_page_delete' => 'ควบคุมโดยสิทธิ์ลบหน้า',
+ 'role_save' => 'บันทึกบทบาท',
+ 'role_users' => 'ผู้ใช้ในบทบาทนี้',
+ 'role_users_none' => 'ยังไม่มีผู้ใช้ที่กำหนดให้บทบาทนี้',
+
+ // Users
+ 'users' => 'ผู้ใช้',
+ 'users_index_desc' => 'สร้างและจัดการบัญชีผู้ใช้แต่ละรายในระบบ บัญชีผู้ใช้ใช้สำหรับเข้าสู่ระบบและระบุที่มาของเนื้อหาและกิจกรรม สิทธิ์การเข้าถึงหลักอิงตามบทบาท แต่ความเป็นเจ้าของเนื้อหาและปัจจัยอื่นๆ อาจส่งผลต่อสิทธิ์และการเข้าถึงด้วย',
+ 'user_profile' => 'โปรไฟล์ผู้ใช้',
+ 'users_add_new' => 'เพิ่มผู้ใช้ใหม่',
+ 'users_search' => 'ค้นหาผู้ใช้',
+ 'users_latest_activity' => 'กิจกรรมล่าสุด',
+ 'users_details' => 'รายละเอียดผู้ใช้',
+ 'users_details_desc' => 'ตั้งชื่อที่แสดงและที่อยู่อีเมลสำหรับผู้ใช้นี้ ที่อยู่อีเมลจะใช้สำหรับเข้าสู่ระบบแอปพลิเคชัน',
+ 'users_details_desc_no_email' => 'ตั้งชื่อที่แสดงสำหรับผู้ใช้นี้เพื่อให้ผู้อื่นรู้จัก',
+ 'users_role' => 'บทบาทผู้ใช้',
+ 'users_role_desc' => 'เลือกบทบาทที่จะกำหนดให้ผู้ใช้นี้ หากผู้ใช้ถูกกำหนดให้หลายบทบาท สิทธิ์จากบทบาทเหล่านั้นจะสะสมกัน',
+ 'users_password' => 'รหัสผ่านผู้ใช้',
+ 'users_password_desc' => 'ตั้งรหัสผ่านสำหรับเข้าสู่ระบบ ต้องมีความยาวอย่างน้อย 8 ตัวอักษร',
+ 'users_send_invite_text' => 'คุณสามารถเลือกส่งอีเมลเชิญให้ผู้ใช้นี้เพื่อให้ตั้งรหัสผ่านของตัวเอง หรือตั้งรหัสผ่านให้เองก็ได้',
+ 'users_send_invite_option' => 'ส่งอีเมลเชิญผู้ใช้',
+ 'users_external_auth_id' => 'ID การยืนยันตัวตนภายนอก',
+ 'users_external_auth_id_desc' => 'เมื่อใช้ระบบยืนยันตัวตนภายนอก (เช่น SAML2, OIDC หรือ LDAP) นี่คือ ID ที่เชื่อมผู้ใช้ BookStack นี้กับบัญชีระบบยืนยันตัวตน สามารถละเว้นช่องนี้หากใช้การยืนยันตัวตนแบบอีเมลเริ่มต้น',
+ 'users_password_warning' => 'กรอกด้านล่างเฉพาะเมื่อต้องการเปลี่ยนรหัสผ่านสำหรับผู้ใช้นี้',
+ 'users_system_public' => 'ผู้ใช้นี้แทนผู้เยี่ยมชมที่เข้าถึง instance ของคุณ ไม่สามารถใช้เข้าสู่ระบบได้ แต่จะถูกกำหนดโดยอัตโนมัติ',
+ 'users_delete' => 'ลบผู้ใช้',
+ 'users_delete_named' => 'ลบผู้ใช้ :userName',
+ 'users_delete_warning' => 'การดำเนินการนี้จะลบผู้ใช้ชื่อ \':userName\' ออกจากระบบทั้งหมด',
+ 'users_delete_confirm' => 'คุณแน่ใจหรือไม่ว่าต้องการลบผู้ใช้นี้?',
+ 'users_migrate_ownership' => 'ย้ายความเป็นเจ้าของ',
+ 'users_migrate_ownership_desc' => 'เลือกผู้ใช้ที่นี่หากต้องการให้ผู้ใช้อื่นเป็นเจ้าของรายการทั้งหมดที่เป็นของผู้ใช้นี้ในปัจจุบัน',
+ 'users_none_selected' => 'ไม่มีผู้ใช้ที่เลือก',
+ 'users_edit' => 'แก้ไขผู้ใช้',
+ 'users_edit_profile' => 'แก้ไขโปรไฟล์',
+ 'users_avatar' => 'รูปโปรไฟล์ผู้ใช้',
+ 'users_avatar_desc' => 'เลือกรูปภาพเพื่อแสดงตัวผู้ใช้นี้ ควรเป็นรูปสี่เหลี่ยมขนาดประมาณ 256px',
+ 'users_preferred_language' => 'ภาษาที่ต้องการ',
+ 'users_preferred_language_desc' => 'ตัวเลือกนี้จะเปลี่ยนภาษาที่ใช้สำหรับส่วนติดต่อผู้ใช้ของแอปพลิเคชัน ไม่มีผลต่อเนื้อหาที่ผู้ใช้สร้าง',
+ 'users_social_accounts' => 'บัญชี Social',
+ 'users_social_accounts_desc' => 'ดูสถานะของบัญชี Social ที่เชื่อมต่อสำหรับผู้ใช้นี้ บัญชี Social สามารถใช้นอกเหนือจากระบบยืนยันตัวตนหลักสำหรับการเข้าถึงระบบ',
+ 'users_social_accounts_info' => 'คุณสามารถเชื่อมต่อบัญชีอื่นที่นี่เพื่อเข้าสู่ระบบที่เร็วและง่ายขึ้น การตัดการเชื่อมต่อบัญชีที่นี่ไม่ได้เพิกถอนสิทธิ์ที่ให้ไว้ก่อนหน้า กรุณาเพิกถอนสิทธิ์จากการตั้งค่าโปรไฟล์บนบัญชี Social ที่เชื่อมต่อ',
+ 'users_social_connect' => 'เชื่อมต่อบัญชี',
+ 'users_social_disconnect' => 'ตัดการเชื่อมต่อบัญชี',
+ 'users_social_status_connected' => 'เชื่อมต่อแล้ว',
+ 'users_social_status_disconnected' => 'ตัดการเชื่อมต่อแล้ว',
+ 'users_social_connected' => 'เชื่อมต่อบัญชี :socialAccount กับโปรไฟล์ของคุณสำเร็จแล้ว',
+ 'users_social_disconnected' => 'ตัดการเชื่อมต่อบัญชี :socialAccount จากโปรไฟล์ของคุณสำเร็จแล้ว',
+ 'users_api_tokens' => 'API Tokens',
+ 'users_api_tokens_desc' => 'สร้างและจัดการโทเค็นการเข้าถึงที่ใช้ยืนยันตัวตนกับ BookStack REST API สิทธิ์สำหรับ API จัดการผ่านผู้ใช้ที่โทเค็นนั้นสังกัด',
+ 'users_api_tokens_none' => 'ยังไม่มี API token ที่สร้างสำหรับผู้ใช้นี้',
+ 'users_api_tokens_create' => 'สร้าง Token',
+ 'users_api_tokens_expires' => 'หมดอายุ',
+ 'users_api_tokens_docs' => 'เอกสาร API',
+ 'users_mfa' => 'การยืนยันตัวตนแบบหลายขั้นตอน',
+ 'users_mfa_desc' => 'ตั้งค่าการยืนยันตัวตนแบบหลายขั้นตอนเป็นชั้นความปลอดภัยเพิ่มเติมสำหรับบัญชีผู้ใช้ของคุณ',
+ 'users_mfa_x_methods' => 'กำหนดค่า :count วิธี',
+ 'users_mfa_configure' => 'กำหนดค่าวิธี',
+ 'users_mfa_reset' => 'Reset Multi-Factor Authentication Methods',
+ 'users_mfa_reset_desc' => 'This will reset and clear all configured multi-factor authentication methods for this user. If multi-factor authentication is required by any of their roles, they\'ll be prompted to configure new methods on their next login.',
+ 'users_mfa_reset_confirm' => 'Are you sure you want to reset multi-factor authentication for this user?',
+
+ // API Tokens
+ 'user_api_token_create' => 'สร้าง API Token',
+ 'user_api_token_name' => 'ชื่อ',
+ 'user_api_token_name_desc' => 'ตั้งชื่อที่อ่านง่ายสำหรับ token นี้เพื่อเตือนความจำเกี่ยวกับวัตถุประสงค์ในอนาคต',
+ 'user_api_token_expiry' => 'วันหมดอายุ',
+ 'user_api_token_expiry_desc' => 'ตั้งวันที่ token นี้หมดอายุ หลังจากวันนี้ คำขอที่ใช้ token นี้จะไม่ทำงานอีกต่อไป การเว้นช่องนี้ว่างจะตั้งวันหมดอายุเป็น 100 ปีในอนาคต',
+ 'user_api_token_create_secret_message' => 'ทันทีหลังจากสร้าง token นี้ "Token ID" และ "Token Secret" จะถูกสร้างและแสดง Secret จะแสดงเพียงครั้งเดียว ดังนั้นให้คัดลอกค่าไปยังที่ปลอดภัยก่อนดำเนินการต่อ',
+ 'user_api_token' => 'API Token',
+ 'user_api_token_id' => 'Token ID',
+ 'user_api_token_id_desc' => 'นี่คือตัวระบุที่สร้างโดยระบบซึ่งไม่สามารถแก้ไขได้สำหรับ token นี้ ซึ่งจะต้องระบุในคำขอ API',
+ 'user_api_token_secret' => 'Token Secret',
+ 'user_api_token_secret_desc' => 'นี่คือ secret ที่สร้างโดยระบบสำหรับ token นี้ซึ่งจะต้องระบุในคำขอ API จะแสดงเพียงครั้งเดียวนี้เท่านั้น ดังนั้นให้คัดลอกค่าไปยังที่ปลอดภัย',
+ 'user_api_token_created' => 'สร้าง Token เมื่อ :timeAgo',
+ 'user_api_token_updated' => 'อัปเดต Token เมื่อ :timeAgo',
+ 'user_api_token_delete' => 'ลบ Token',
+ 'user_api_token_delete_warning' => 'การดำเนินการนี้จะลบ API token ชื่อ \':tokenName\' ออกจากระบบทั้งหมด',
+ 'user_api_token_delete_confirm' => 'คุณแน่ใจหรือไม่ว่าต้องการลบ API token นี้?',
+
+ // Webhooks
+ 'webhooks' => 'Webhooks',
+ 'webhooks_index_desc' => 'Webhooks เป็นวิธีส่งข้อมูลไปยัง URL ภายนอกเมื่อมีการดำเนินการและกิจกรรมบางอย่างในระบบ ซึ่งช่วยให้สามารถรวมกับแพลตฟอร์มภายนอก เช่น ระบบส่งข้อความหรือการแจ้งเตือน',
+ 'webhooks_x_trigger_events' => ':count กิจกรรมทริกเกอร์',
+ 'webhooks_create' => 'สร้าง Webhook ใหม่',
+ 'webhooks_none_created' => 'ยังไม่มี Webhook ที่สร้าง',
+ 'webhooks_edit' => 'แก้ไข Webhook',
+ 'webhooks_save' => 'บันทึก Webhook',
+ 'webhooks_details' => 'รายละเอียด Webhook',
+ 'webhooks_details_desc' => 'ระบุชื่อที่เป็นมิตรกับผู้ใช้และ POST endpoint เป็นตำแหน่งสำหรับส่งข้อมูล Webhook',
+ 'webhooks_events' => 'กิจกรรม Webhook',
+ 'webhooks_events_desc' => 'เลือกกิจกรรมทั้งหมดที่ควรทริกเกอร์ให้เรียก Webhook นี้',
+ 'webhooks_events_warning' => 'โปรดทราบว่ากิจกรรมเหล่านี้จะถูกทริกเกอร์สำหรับกิจกรรมที่เลือกทั้งหมด แม้จะมีสิทธิ์แบบกำหนดเองก็ตาม ตรวจสอบให้แน่ใจว่าการใช้ Webhook นี้จะไม่เปิดเผยเนื้อหาที่เป็นความลับ',
+ 'webhooks_events_all' => 'กิจกรรมทั้งหมดในระบบ',
+ 'webhooks_name' => 'ชื่อ Webhook',
+ 'webhooks_timeout' => 'หมดเวลาคำขอ Webhook (วินาที)',
+ 'webhooks_endpoint' => 'Endpoint ของ Webhook',
+ 'webhooks_active' => 'Webhook เปิดใช้งาน',
+ 'webhook_events_table_header' => 'กิจกรรม',
+ 'webhooks_delete' => 'ลบ Webhook',
+ 'webhooks_delete_warning' => 'การดำเนินการนี้จะลบ Webhook ชื่อ \':webhookName\' ออกจากระบบทั้งหมด',
+ 'webhooks_delete_confirm' => 'คุณแน่ใจหรือไม่ว่าต้องการลบ Webhook นี้?',
+ 'webhooks_format_example' => 'ตัวอย่างรูปแบบ Webhook',
+ 'webhooks_format_example_desc' => 'ข้อมูล Webhook ถูกส่งเป็นคำขอ POST ไปยัง endpoint ที่กำหนดค่าเป็น JSON ตามรูปแบบด้านล่าง คุณสมบัติ "related_item" และ "url" เป็นทางเลือกและขึ้นอยู่กับประเภทกิจกรรมที่ทริกเกอร์',
+ 'webhooks_status' => 'สถานะ Webhook',
+ 'webhooks_last_called' => 'เรียกล่าสุด:',
+ 'webhooks_last_errored' => 'เกิดข้อผิดพลาดล่าสุด:',
+ 'webhooks_last_error_message' => 'ข้อความข้อผิดพลาดล่าสุด:',
+
+ // Licensing
+ 'licenses' => 'สัญญาอนุญาต',
+ 'licenses_desc' => 'หน้านี้แสดงข้อมูลสัญญาอนุญาตสำหรับ BookStack รวมถึงโปรเจกต์และไลบรารีที่ใช้ใน BookStack โปรเจกต์หลายรายการอาจใช้เฉพาะในบริบทการพัฒนา',
+ 'licenses_bookstack' => 'สัญญาอนุญาต BookStack',
+ 'licenses_php' => 'สัญญาอนุญาตไลบรารี PHP',
+ 'licenses_js' => 'สัญญาอนุญาตไลบรารี JavaScript',
+ 'licenses_other' => 'สัญญาอนุญาตอื่นๆ',
+ 'license_details' => 'รายละเอียดสัญญาอนุญาต',
+
+ //! If editing translations files directly please ignore this in all
+ //! languages apart from en. Content will be auto-copied from en.
+ //!////////////////////////////////
+ 'language_select' => [
+ 'en' => 'English',
+ 'ar' => 'العربية',
+ 'bg' => 'Bǎlgarski',
+ 'bs' => 'Bosanski',
+ 'ca' => 'Català',
+ 'cs' => 'Česky',
+ 'cy' => 'Cymraeg',
+ 'da' => 'Dansk',
+ 'de' => 'Deutsch (Sie)',
+ 'de_informal' => 'Deutsch (Du)',
+ 'el' => 'ελληνικά',
+ 'es' => 'Español',
+ 'es_AR' => 'Español Argentina',
+ 'et' => 'Eesti keel',
+ 'eu' => 'Euskara',
+ 'fa' => 'فارسی',
+ 'fi' => 'Suomi',
+ 'fr' => 'Français',
+ 'he' => 'עברית',
+ 'hr' => 'Hrvatski',
+ 'hu' => 'Magyar',
+ 'id' => 'Bahasa Indonesia',
+ 'it' => 'Italian',
+ 'ja' => '日本語',
+ 'ko' => '한국어',
+ 'lt' => 'Lietuvių Kalba',
+ 'lv' => 'Latviešu Valoda',
+ 'nb' => 'Norsk (Bokmål)',
+ 'ne' => 'नेपाली',
+ 'nn' => 'Nynorsk',
+ 'nl' => 'Nederlands',
+ 'pl' => 'Polski',
+ 'pt' => 'Português',
+ 'pt_BR' => 'Português do Brasil',
+ 'ro' => 'Română',
+ 'ru' => 'Русский',
+ 'sk' => 'Slovensky',
+ 'sl' => 'Slovenščina',
+ 'sv' => 'Svenska',
+ 'th' => 'ภาษาไทย',
+ 'tr' => 'Türkçe',
+ 'uk' => 'Українська',
+ 'uz' => 'O‘zbekcha',
+ 'vi' => 'Tiếng Việt',
+ 'zh_CN' => '简体中文',
+ 'zh_TW' => '繁體中文',
+ ],
+ //!////////////////////////////////
+];
diff --git a/lang/th/validation.php b/lang/th/validation.php
new file mode 100644
index 000000000..347eeb36c
--- /dev/null
+++ b/lang/th/validation.php
@@ -0,0 +1,123 @@
+ 'ต้องยอมรับ :attribute',
+ 'active_url' => ':attribute ไม่ใช่ URL ที่ถูกต้อง',
+ 'after' => ':attribute ต้องเป็นวันที่หลังจาก :date',
+ 'alpha' => ':attribute ต้องมีเฉพาะตัวอักษรเท่านั้น',
+ 'alpha_dash' => ':attribute ต้องมีเฉพาะตัวอักษร ตัวเลข ขีดกลาง และขีดล่างเท่านั้น',
+ 'alpha_num' => ':attribute ต้องมีเฉพาะตัวอักษรและตัวเลขเท่านั้น',
+ 'array' => ':attribute ต้องเป็น array',
+ 'backup_codes' => 'รหัสที่ให้มาไม่ถูกต้องหรือถูกใช้ไปแล้ว',
+ 'before' => ':attribute ต้องเป็นวันที่ก่อน :date',
+ 'between' => [
+ 'numeric' => ':attribute ต้องอยู่ระหว่าง :min ถึง :max',
+ 'file' => ':attribute ต้องมีขนาดระหว่าง :min ถึง :max กิโลไบต์',
+ 'string' => ':attribute ต้องมีความยาวระหว่าง :min ถึง :max ตัวอักษร',
+ 'array' => ':attribute ต้องมีระหว่าง :min ถึง :max รายการ',
+ ],
+ 'boolean' => 'ฟิลด์ :attribute ต้องเป็น true หรือ false',
+ 'confirmed' => 'การยืนยัน :attribute ไม่ตรงกัน',
+ 'date' => ':attribute ไม่ใช่วันที่ที่ถูกต้อง',
+ 'date_format' => ':attribute ไม่ตรงกับรูปแบบ :format',
+ 'different' => ':attribute และ :other ต้องแตกต่างกัน',
+ 'digits' => ':attribute ต้องมี :digits หลัก',
+ 'digits_between' => ':attribute ต้องมีระหว่าง :min ถึง :max หลัก',
+ 'email' => ':attribute ต้องเป็นที่อยู่อีเมลที่ถูกต้อง',
+ 'ends_with' => ':attribute ต้องลงท้ายด้วยหนึ่งในนี้: :values',
+ 'file' => ':attribute ต้องเป็นไฟล์ที่ถูกต้อง',
+ 'filled' => 'ฟิลด์ :attribute จำเป็นต้องกรอก',
+ 'gt' => [
+ 'numeric' => ':attribute ต้องมากกว่า :value',
+ 'file' => ':attribute ต้องมากกว่า :value กิโลไบต์',
+ 'string' => ':attribute ต้องมีความยาวมากกว่า :value ตัวอักษร',
+ 'array' => ':attribute ต้องมีมากกว่า :value รายการ',
+ ],
+ 'gte' => [
+ 'numeric' => ':attribute ต้องมากกว่าหรือเท่ากับ :value',
+ 'file' => ':attribute ต้องมากกว่าหรือเท่ากับ :value กิโลไบต์',
+ 'string' => ':attribute ต้องมีความยาวมากกว่าหรือเท่ากับ :value ตัวอักษร',
+ 'array' => ':attribute ต้องมี :value รายการขึ้นไป',
+ ],
+ 'exists' => ':attribute ที่เลือกไม่ถูกต้อง',
+ 'image' => ':attribute ต้องเป็นรูปภาพ',
+ 'image_extension' => ':attribute ต้องมีนามสกุลรูปภาพที่ถูกต้องและรองรับ',
+ 'in' => ':attribute ที่เลือกไม่ถูกต้อง',
+ 'integer' => ':attribute ต้องเป็นจำนวนเต็ม',
+ 'ip' => ':attribute ต้องเป็นที่อยู่ IP ที่ถูกต้อง',
+ 'ipv4' => ':attribute ต้องเป็นที่อยู่ IPv4 ที่ถูกต้อง',
+ 'ipv6' => ':attribute ต้องเป็นที่อยู่ IPv6 ที่ถูกต้อง',
+ 'json' => ':attribute ต้องเป็น JSON string ที่ถูกต้อง',
+ 'lt' => [
+ 'numeric' => ':attribute ต้องน้อยกว่า :value',
+ 'file' => ':attribute ต้องน้อยกว่า :value กิโลไบต์',
+ 'string' => ':attribute ต้องมีความยาวน้อยกว่า :value ตัวอักษร',
+ 'array' => ':attribute ต้องมีน้อยกว่า :value รายการ',
+ ],
+ 'lte' => [
+ 'numeric' => ':attribute ต้องน้อยกว่าหรือเท่ากับ :value',
+ 'file' => ':attribute ต้องน้อยกว่าหรือเท่ากับ :value กิโลไบต์',
+ 'string' => ':attribute ต้องมีความยาวน้อยกว่าหรือเท่ากับ :value ตัวอักษร',
+ 'array' => ':attribute ต้องไม่มีมากกว่า :value รายการ',
+ ],
+ 'max' => [
+ 'numeric' => ':attribute ต้องไม่มากกว่า :max',
+ 'file' => ':attribute ต้องไม่มากกว่า :max กิโลไบต์',
+ 'string' => ':attribute ต้องไม่มากกว่า :max ตัวอักษร',
+ 'array' => ':attribute ต้องไม่มีมากกว่า :max รายการ',
+ ],
+ 'mimes' => ':attribute ต้องเป็นไฟล์ประเภท: :values',
+ 'min' => [
+ 'numeric' => ':attribute ต้องอย่างน้อย :min',
+ 'file' => ':attribute ต้องอย่างน้อย :min กิโลไบต์',
+ 'string' => ':attribute ต้องมีความยาวอย่างน้อย :min ตัวอักษร',
+ 'array' => ':attribute ต้องมีอย่างน้อย :min รายการ',
+ ],
+ 'not_in' => ':attribute ที่เลือกไม่ถูกต้อง',
+ 'not_regex' => 'รูปแบบ :attribute ไม่ถูกต้อง',
+ 'numeric' => ':attribute ต้องเป็นตัวเลข',
+ 'regex' => 'รูปแบบ :attribute ไม่ถูกต้อง',
+ 'required' => 'ฟิลด์ :attribute จำเป็นต้องกรอก',
+ 'required_if' => 'ฟิลด์ :attribute จำเป็นต้องกรอกเมื่อ :other เป็น :value',
+ 'required_with' => 'ฟิลด์ :attribute จำเป็นต้องกรอกเมื่อมี :values',
+ 'required_with_all' => 'ฟิลด์ :attribute จำเป็นต้องกรอกเมื่อมี :values',
+ 'required_without' => 'ฟิลด์ :attribute จำเป็นต้องกรอกเมื่อไม่มี :values',
+ 'required_without_all' => 'ฟิลด์ :attribute จำเป็นต้องกรอกเมื่อไม่มีสิ่งใดใน :values',
+ 'same' => ':attribute และ :other ต้องตรงกัน',
+ 'safe_url' => 'ลิงก์ที่ให้มาอาจไม่ปลอดภัย',
+ 'size' => [
+ 'numeric' => ':attribute ต้องเป็น :size',
+ 'file' => ':attribute ต้องมีขนาด :size กิโลไบต์',
+ 'string' => ':attribute ต้องมีความยาว :size ตัวอักษร',
+ 'array' => ':attribute ต้องมี :size รายการ',
+ ],
+ 'string' => ':attribute ต้องเป็น string',
+ 'timezone' => ':attribute ต้องเป็นเขตเวลาที่ถูกต้อง',
+ 'totp' => 'รหัสที่ให้มาไม่ถูกต้องหรือหมดอายุแล้ว',
+ 'unique' => ':attribute ถูกใช้งานแล้ว',
+ 'url' => 'รูปแบบ :attribute ไม่ถูกต้อง',
+ 'uploaded' => 'ไม่สามารถอัปโหลดไฟล์ได้ เซิร์ฟเวอร์อาจไม่รับไฟล์ขนาดนี้',
+
+ 'zip_file' => ':attribute ต้องอ้างอิงถึงไฟล์ภายใน ZIP',
+ 'zip_file_size' => 'ไฟล์ :attribute ต้องไม่เกิน :size MB',
+ 'zip_file_mime' => ':attribute ต้องอ้างอิงถึงไฟล์ประเภท :validTypes แต่พบ :foundType',
+ 'zip_model_expected' => 'คาดหวัง data object แต่พบ ":type"',
+ 'zip_unique' => ':attribute ต้องไม่ซ้ำกันสำหรับประเภท object ภายใน ZIP',
+
+ // Custom validation lines
+ 'custom' => [
+ 'password-confirm' => [
+ 'required_with' => 'จำเป็นต้องยืนยันรหัสผ่าน',
+ ],
+ ],
+
+ // Custom validation attributes
+ 'attributes' => [],
+];
diff --git a/lang/tk/activities.php b/lang/tk/activities.php
index 4362fc029..e9344a3d4 100644
--- a/lang/tk/activities.php
+++ b/lang/tk/activities.php
@@ -99,6 +99,8 @@ return [
'user_update_notification' => 'User successfully updated',
'user_delete' => 'deleted user',
'user_delete_notification' => 'User successfully removed',
+ 'user_mfa_reset' => 'reset MFA for user',
+ 'user_mfa_reset_notification' => 'Multi-factor authentication methods reset',
// API Tokens
'api_token_create' => 'created API token',
diff --git a/lang/tk/auth.php b/lang/tk/auth.php
index 57f0cb5c6..47be4ea72 100644
--- a/lang/tk/auth.php
+++ b/lang/tk/auth.php
@@ -8,6 +8,7 @@ return [
'failed' => 'These credentials do not match our records.',
'throttle' => 'Too many login attempts. Please try again in :seconds seconds.',
+ 'mfa_throttle' => 'Too many multi-factor verification attempts. Please try again in :seconds seconds.',
// Login & Register
'sign_up' => 'Sign up',
diff --git a/lang/tk/entities.php b/lang/tk/entities.php
index 74c50be3b..58c00ec4b 100644
--- a/lang/tk/entities.php
+++ b/lang/tk/entities.php
@@ -173,6 +173,7 @@ return [
'books_sort_desc' => 'Move chapters and pages within a book to reorganise its contents. Other books can be added which allows easy moving of chapters and pages between books. Optionally an auto sort rule can be set to automatically sort this book\'s contents upon changes.',
'books_sort_auto_sort' => 'Auto Sort Option',
'books_sort_auto_sort_active' => 'Auto Sort Active: :sortName',
+ 'books_sort_auto_sort_creation_hint' => 'Auto sort option rules can be created in the "Lists & Sorting" settings area by a user with the relevant permissions.',
'books_sort_named' => 'Sort Book :bookName',
'books_sort_name' => 'Sort by Name',
'books_sort_created' => 'Sort by Created Date',
@@ -330,6 +331,9 @@ return [
// Editor Sidebar
'toggle_sidebar' => 'Toggle Sidebar',
+ 'page_contents' => 'Page Contents',
+ 'page_contents_none' => 'No headings were found in the page content.',
+ 'page_contents_info' => 'The contents menu is generated from any heading formats used in the page.',
'page_tags' => 'Page Tags',
'chapter_tags' => 'Chapter Tags',
'book_tags' => 'Book Tags',
diff --git a/lang/tk/settings.php b/lang/tk/settings.php
index c4d1eb136..d03024a89 100644
--- a/lang/tk/settings.php
+++ b/lang/tk/settings.php
@@ -207,6 +207,7 @@ return [
'role_all' => 'All',
'role_own' => 'Own',
'role_controlled_by_asset' => 'Controlled by the asset they are uploaded to',
+ 'role_controlled_by_page_delete' => 'Controlled by page delete permissions',
'role_save' => 'Save Role',
'role_users' => 'Users in this role',
'role_users_none' => 'No users are currently assigned to this role',
@@ -263,6 +264,9 @@ return [
'users_mfa_desc' => 'Setup multi-factor authentication as an extra layer of security for your user account.',
'users_mfa_x_methods' => ':count method configured|:count methods configured',
'users_mfa_configure' => 'Configure Methods',
+ 'users_mfa_reset' => 'Reset Multi-Factor Authentication Methods',
+ 'users_mfa_reset_desc' => 'This will reset and clear all configured multi-factor authentication methods for this user. If multi-factor authentication is required by any of their roles, they\'ll be prompted to configure new methods on their next login.',
+ 'users_mfa_reset_confirm' => 'Are you sure you want to reset multi-factor authentication for this user?',
// API Tokens
'user_api_token_create' => 'Create API Token',
@@ -363,6 +367,7 @@ return [
'sk' => 'Slovensky',
'sl' => 'Slovenščina',
'sv' => 'Svenska',
+ 'th' => 'ภาษาไทย',
'tr' => 'Türkçe',
'uk' => 'Українська',
'uz' => 'O‘zbekcha',
diff --git a/lang/tr/activities.php b/lang/tr/activities.php
index 5bed9ea30..71282e448 100644
--- a/lang/tr/activities.php
+++ b/lang/tr/activities.php
@@ -99,6 +99,8 @@ return [
'user_update_notification' => 'Kullanıcı başarıyla güncellendi',
'user_delete' => 'kullanıcı silindi',
'user_delete_notification' => 'Kullanıcı başarıyla silindi',
+ 'user_mfa_reset' => 'reset MFA for user',
+ 'user_mfa_reset_notification' => 'Multi-factor authentication methods reset',
// API Tokens
'api_token_create' => 'created API token',
diff --git a/lang/tr/auth.php b/lang/tr/auth.php
index c9663f21e..f8942a4df 100644
--- a/lang/tr/auth.php
+++ b/lang/tr/auth.php
@@ -8,6 +8,7 @@ return [
'failed' => 'Girdiğiniz bilgiler kayıtlarımızla uyuşmuyor.',
'throttle' => 'Çok fazla giriş yapmaya çalıştınız. Lütfen :seconds saniye içinde tekrar deneyin.',
+ 'mfa_throttle' => 'Too many multi-factor verification attempts. Please try again in :seconds seconds.',
// Login & Register
'sign_up' => 'Kaydol',
diff --git a/lang/tr/entities.php b/lang/tr/entities.php
index 39feb7e39..e5bdacae7 100644
--- a/lang/tr/entities.php
+++ b/lang/tr/entities.php
@@ -173,6 +173,7 @@ return [
'books_sort_desc' => 'Move chapters and pages within a book to reorganise its contents. Other books can be added which allows easy moving of chapters and pages between books. Optionally an auto sort rule can be set to automatically sort this book\'s contents upon changes.',
'books_sort_auto_sort' => 'Auto Sort Option',
'books_sort_auto_sort_active' => 'Auto Sort Active: :sortName',
+ 'books_sort_auto_sort_creation_hint' => 'Auto sort option rules can be created in the "Lists & Sorting" settings area by a user with the relevant permissions.',
'books_sort_named' => ':bookName Kitabını Sırala',
'books_sort_name' => 'İsme Göre Sırala',
'books_sort_created' => 'Oluşturulma Tarihine Göre Sırala',
@@ -330,6 +331,9 @@ return [
// Editor Sidebar
'toggle_sidebar' => 'Toggle Sidebar',
+ 'page_contents' => 'Page Contents',
+ 'page_contents_none' => 'No headings were found in the page content.',
+ 'page_contents_info' => 'The contents menu is generated from any heading formats used in the page.',
'page_tags' => 'Sayfa Etiketleri',
'chapter_tags' => 'Bölüm Etiketleri',
'book_tags' => 'Kitap Etiketleri',
diff --git a/lang/tr/settings.php b/lang/tr/settings.php
index a33d3e0ac..39ae23f28 100644
--- a/lang/tr/settings.php
+++ b/lang/tr/settings.php
@@ -207,6 +207,7 @@ return [
'role_all' => 'Hepsi',
'role_own' => 'Kendine Ait',
'role_controlled_by_asset' => 'Yüklendikleri varlık tarafından kontrol ediliyor',
+ 'role_controlled_by_page_delete' => 'Controlled by page delete permissions',
'role_save' => 'Rolü Kaydet',
'role_users' => 'Bu roldeki kullanıcılar',
'role_users_none' => 'Bu role henüz bir kullanıcı atanmadı',
@@ -263,6 +264,9 @@ return [
'users_mfa_desc' => 'Setup multi-factor authentication as an extra layer of security for your user account.',
'users_mfa_x_methods' => ':count method configured|:count methods configured',
'users_mfa_configure' => 'Yöntemleri Yapılandır',
+ 'users_mfa_reset' => 'Reset Multi-Factor Authentication Methods',
+ 'users_mfa_reset_desc' => 'This will reset and clear all configured multi-factor authentication methods for this user. If multi-factor authentication is required by any of their roles, they\'ll be prompted to configure new methods on their next login.',
+ 'users_mfa_reset_confirm' => 'Are you sure you want to reset multi-factor authentication for this user?',
// API Tokens
'user_api_token_create' => 'API Anahtarı Oluştur',
@@ -363,6 +367,7 @@ return [
'sk' => 'Slovensky',
'sl' => 'Slovence',
'sv' => 'Svenska',
+ 'th' => 'ภาษาไทย',
'tr' => 'Türkçe',
'uk' => 'Українська',
'uz' => 'O‘zbekcha',
diff --git a/lang/uk/activities.php b/lang/uk/activities.php
index e8b77e0d4..140fec47c 100644
--- a/lang/uk/activities.php
+++ b/lang/uk/activities.php
@@ -99,6 +99,8 @@ return [
'user_update_notification' => 'Користувача було успішно оновлено',
'user_delete' => 'вилучений користувач',
'user_delete_notification' => 'Користувача успішно видалено',
+ 'user_mfa_reset' => 'reset MFA for user',
+ 'user_mfa_reset_notification' => 'Multi-factor authentication methods reset',
// API Tokens
'api_token_create' => 'створений APi токен',
diff --git a/lang/uk/auth.php b/lang/uk/auth.php
index 27aae3936..cb927cfd4 100644
--- a/lang/uk/auth.php
+++ b/lang/uk/auth.php
@@ -8,6 +8,7 @@ return [
'failed' => 'Цей обліковий запис не знайдено.',
'throttle' => 'Забагато спроб входу в систему. Будь ласка, спробуйте ще раз через :seconds секунд.',
+ 'mfa_throttle' => 'Too many multi-factor verification attempts. Please try again in :seconds seconds.',
// Login & Register
'sign_up' => 'Реєстрація',
diff --git a/lang/uk/entities.php b/lang/uk/entities.php
index cf79b530c..a77b8e77d 100644
--- a/lang/uk/entities.php
+++ b/lang/uk/entities.php
@@ -173,6 +173,7 @@ return [
'books_sort_desc' => 'Перекладіть розділи та сторінки в межах книги, щоб реорганізувати вміст. Інші книги можна додати, що дозволяє легко переміщати глави та сторінки між книгами. При необхідності правило автоматичного сортування може бути встановлено для автоматичного сортування вмісту цієї книги при змінах.',
'books_sort_auto_sort' => 'Опція автоматичного сортування',
'books_sort_auto_sort_active' => 'Автосортування : :sortName',
+ 'books_sort_auto_sort_creation_hint' => 'Auto sort option rules can be created in the "Lists & Sorting" settings area by a user with the relevant permissions.',
'books_sort_named' => 'Сортувати книгу :bookName',
'books_sort_name' => 'Сортувати за назвою',
'books_sort_created' => 'Сортувати за датою створення',
@@ -330,6 +331,9 @@ return [
// Editor Sidebar
'toggle_sidebar' => 'Перемикач бічної панелі',
+ 'page_contents' => 'Page Contents',
+ 'page_contents_none' => 'No headings were found in the page content.',
+ 'page_contents_info' => 'The contents menu is generated from any heading formats used in the page.',
'page_tags' => 'Теги сторінки',
'chapter_tags' => 'Теги розділів',
'book_tags' => 'Теги книг',
diff --git a/lang/uk/settings.php b/lang/uk/settings.php
index afeb2c489..02fd6a4f6 100644
--- a/lang/uk/settings.php
+++ b/lang/uk/settings.php
@@ -207,6 +207,7 @@ return [
'role_all' => 'Все',
'role_own' => 'Власне',
'role_controlled_by_asset' => 'Контролюється за об\'єктом, до якого вони завантажуються',
+ 'role_controlled_by_page_delete' => 'Controlled by page delete permissions',
'role_save' => 'Зберегти роль',
'role_users' => 'Користувачі в цій ролі',
'role_users_none' => 'Наразі жоден користувач не призначений для цієї ролі',
@@ -263,6 +264,9 @@ return [
'users_mfa_desc' => 'Двофакторна аутентифікація додає ще один рівень безпеки для вашого облікового запису.',
'users_mfa_x_methods' => ':count метод налаштовано|:count методів налаштовано',
'users_mfa_configure' => 'Налаштувати Методи',
+ 'users_mfa_reset' => 'Reset Multi-Factor Authentication Methods',
+ 'users_mfa_reset_desc' => 'This will reset and clear all configured multi-factor authentication methods for this user. If multi-factor authentication is required by any of their roles, they\'ll be prompted to configure new methods on their next login.',
+ 'users_mfa_reset_confirm' => 'Are you sure you want to reset multi-factor authentication for this user?',
// API Tokens
'user_api_token_create' => 'Створити токен API',
@@ -363,6 +367,7 @@ return [
'sk' => 'Slovensky',
'sl' => 'Slovenščina',
'sv' => 'Svenska',
+ 'th' => 'ภาษาไทย',
'tr' => 'Türkçe',
'uk' => 'Українська',
'uz' => 'O‘zbekcha',
diff --git a/lang/uz/activities.php b/lang/uz/activities.php
index 84764192d..f87a52870 100644
--- a/lang/uz/activities.php
+++ b/lang/uz/activities.php
@@ -99,6 +99,8 @@ return [
'user_update_notification' => 'Foydalanuvchi muvaffaqiyatli yangilandi',
'user_delete' => 'deleted user',
'user_delete_notification' => 'Foydalanuvchi muvaffaqiyatli olib tashlandi',
+ 'user_mfa_reset' => 'reset MFA for user',
+ 'user_mfa_reset_notification' => 'Multi-factor authentication methods reset',
// API Tokens
'api_token_create' => 'created API token',
diff --git a/lang/uz/auth.php b/lang/uz/auth.php
index 59a620dae..1c31d8f87 100644
--- a/lang/uz/auth.php
+++ b/lang/uz/auth.php
@@ -8,6 +8,7 @@ return [
'failed' => 'Uchbu ma‘lumotlar, bizdagi ma‘lumotlarga mos kelmadi.',
'throttle' => 'Kirishga urinishlar juda ko‘p. Iltimos :seconds soniyadan so‘ng urinib ko‘ring.',
+ 'mfa_throttle' => 'Too many multi-factor verification attempts. Please try again in :seconds seconds.',
// Login & Register
'sign_up' => 'Ro‘yxatdan o‘tish',
diff --git a/lang/uz/entities.php b/lang/uz/entities.php
index e35a485b6..f87028926 100644
--- a/lang/uz/entities.php
+++ b/lang/uz/entities.php
@@ -173,6 +173,7 @@ return [
'books_sort_desc' => 'Move chapters and pages within a book to reorganise its contents. Other books can be added which allows easy moving of chapters and pages between books. Optionally an auto sort rule can be set to automatically sort this book\'s contents upon changes.',
'books_sort_auto_sort' => 'Auto Sort Option',
'books_sort_auto_sort_active' => 'Auto Sort Active: :sortName',
+ 'books_sort_auto_sort_creation_hint' => 'Auto sort option rules can be created in the "Lists & Sorting" settings area by a user with the relevant permissions.',
'books_sort_named' => 'Kitobni tartiblash: kitob nomi',
'books_sort_name' => 'Nomi bo\'yicha saralash',
'books_sort_created' => 'Yaratilgan sana bo\'yicha saralash',
@@ -330,6 +331,9 @@ return [
// Editor Sidebar
'toggle_sidebar' => 'Toggle Sidebar',
+ 'page_contents' => 'Page Contents',
+ 'page_contents_none' => 'No headings were found in the page content.',
+ 'page_contents_info' => 'The contents menu is generated from any heading formats used in the page.',
'page_tags' => 'Sahifa teglari',
'chapter_tags' => 'Bo\'lim teglari',
'book_tags' => 'Kitob teglari',
diff --git a/lang/uz/settings.php b/lang/uz/settings.php
index 259aee71a..c1d3b3d46 100644
--- a/lang/uz/settings.php
+++ b/lang/uz/settings.php
@@ -207,6 +207,7 @@ return [
'role_all' => 'Hammasi',
'role_own' => 'Shaxsiy',
'role_controlled_by_asset' => 'Ular yuklangan obyekt tomonidan nazorat qilinadi',
+ 'role_controlled_by_page_delete' => 'Controlled by page delete permissions',
'role_save' => 'Rolni saqlash',
'role_users' => 'Ushbu roldagi foydalanuvchilar',
'role_users_none' => 'Hozirda bu rolga hech qanday foydalanuvchi tayinlanmagan',
@@ -263,6 +264,9 @@ return [
'users_mfa_desc' => 'Ko\'p faktorli autentifikatsiyani foydalanuvchi hisobingiz uchun qo\'shimcha xavfsizlik qatlami sifatida o\'rnating.',
'users_mfa_x_methods' => ':count usuli tuzilgan|:count usullari sozlangan',
'users_mfa_configure' => 'Usullarni sozlash',
+ 'users_mfa_reset' => 'Reset Multi-Factor Authentication Methods',
+ 'users_mfa_reset_desc' => 'This will reset and clear all configured multi-factor authentication methods for this user. If multi-factor authentication is required by any of their roles, they\'ll be prompted to configure new methods on their next login.',
+ 'users_mfa_reset_confirm' => 'Are you sure you want to reset multi-factor authentication for this user?',
// API Tokens
'user_api_token_create' => 'API tokenini yarating',
@@ -363,6 +367,7 @@ return [
'sk' => 'Slovensky',
'sl' => 'Slovenščina',
'sv' => 'Svenska',
+ 'th' => 'ภาษาไทย',
'tr' => 'Türkçe',
'uk' => 'Українська',
'uz' => 'O‘zbekcha',
diff --git a/lang/vi/activities.php b/lang/vi/activities.php
index 00ec6ce04..0625bb529 100644
--- a/lang/vi/activities.php
+++ b/lang/vi/activities.php
@@ -99,6 +99,8 @@ return [
'user_update_notification' => 'Người dùng được cập nhật thành công',
'user_delete' => 'người dùng đã bị xóa',
'user_delete_notification' => 'Người dùng đã được xóa thành công',
+ 'user_mfa_reset' => 'reset MFA for user',
+ 'user_mfa_reset_notification' => 'Multi-factor authentication methods reset',
// API Tokens
'api_token_create' => 'Đã tạo Token API ',
diff --git a/lang/vi/auth.php b/lang/vi/auth.php
index d53d2cf4c..9e0ce731b 100644
--- a/lang/vi/auth.php
+++ b/lang/vi/auth.php
@@ -8,6 +8,7 @@ return [
'failed' => 'Thông tin đăng nhập này không khớp với dữ liệu của chúng tôi.',
'throttle' => 'Quá nhiều lần đăng nhập sai. Vui lòng thử lại sau :seconds giây.',
+ 'mfa_throttle' => 'Too many multi-factor verification attempts. Please try again in :seconds seconds.',
// Login & Register
'sign_up' => 'Đăng ký',
diff --git a/lang/vi/entities.php b/lang/vi/entities.php
index f538f993c..a3f92e030 100644
--- a/lang/vi/entities.php
+++ b/lang/vi/entities.php
@@ -173,6 +173,7 @@ return [
'books_sort_desc' => 'Di chuyển các chương và trang trong một cuốn sách để sắp xếp lại nội dung của nó. Các sách khác có thể được thêm vào để dễ dàng di chuyển các chương và trang giữa các sách. Tùy chọn, một quy tắc sắp xếp tự động có thể được đặt để tự động sắp xếp nội dung cuốn sách này khi có thay đổi.',
'books_sort_auto_sort' => 'Tùy chọn sắp xếp tự động',
'books_sort_auto_sort_active' => 'Sắp xếp tự động đang hoạt động: :sortName',
+ 'books_sort_auto_sort_creation_hint' => 'Auto sort option rules can be created in the "Lists & Sorting" settings area by a user with the relevant permissions.',
'books_sort_named' => 'Sắp xếp sách :bookName',
'books_sort_name' => 'Sắp xếp theo tên',
'books_sort_created' => 'Sắp xếp theo ngày tạo',
@@ -330,6 +331,9 @@ return [
// Editor Sidebar
'toggle_sidebar' => 'Chuyển đổi thanh bên',
+ 'page_contents' => 'Page Contents',
+ 'page_contents_none' => 'No headings were found in the page content.',
+ 'page_contents_info' => 'The contents menu is generated from any heading formats used in the page.',
'page_tags' => 'Các Thẻ Trang',
'chapter_tags' => 'Các Thẻ Chương',
'book_tags' => 'Các Thẻ Sách',
diff --git a/lang/vi/settings.php b/lang/vi/settings.php
index f5f2377c8..d029fe7f3 100644
--- a/lang/vi/settings.php
+++ b/lang/vi/settings.php
@@ -207,6 +207,7 @@ return [
'role_all' => 'Tất cả',
'role_own' => 'Sở hữu',
'role_controlled_by_asset' => 'Kiểm soát các tài sản (asset) người dùng tải lên',
+ 'role_controlled_by_page_delete' => 'Controlled by page delete permissions',
'role_save' => 'Lưu Quyền',
'role_users' => 'Người dùng được gán quyền này',
'role_users_none' => 'Không có người dùng nào hiện được gán quyền này',
@@ -263,6 +264,9 @@ return [
'users_mfa_desc' => 'Thiết lập xác thực đa yếu tố như một lớp bảo mật bổ sung cho tài khoản người dùng của bạn.',
'users_mfa_x_methods' => ':count phương thức đã cấu hình|:count phương thức đã cấu hình',
'users_mfa_configure' => 'Cấu hình phương thức',
+ 'users_mfa_reset' => 'Reset Multi-Factor Authentication Methods',
+ 'users_mfa_reset_desc' => 'This will reset and clear all configured multi-factor authentication methods for this user. If multi-factor authentication is required by any of their roles, they\'ll be prompted to configure new methods on their next login.',
+ 'users_mfa_reset_confirm' => 'Are you sure you want to reset multi-factor authentication for this user?',
// API Tokens
'user_api_token_create' => 'Tạo Token API',
@@ -363,6 +367,7 @@ return [
'sk' => 'Slovensky',
'sl' => 'Slovenščina',
'sv' => 'Svenska',
+ 'th' => 'ภาษาไทย',
'tr' => 'Türkçe',
'uk' => 'Українська',
'uz' => 'O‘zbekcha',
diff --git a/lang/zh_CN/activities.php b/lang/zh_CN/activities.php
index a2a2acd24..d30e61f0f 100644
--- a/lang/zh_CN/activities.php
+++ b/lang/zh_CN/activities.php
@@ -99,6 +99,8 @@ return [
'user_update_notification' => '用户更新成功',
'user_delete' => '用户已删除',
'user_delete_notification' => '成功移除用户',
+ 'user_mfa_reset' => '为用户重置MFA',
+ 'user_mfa_reset_notification' => '多因素认证方法已重置',
// API Tokens
'api_token_create' => '已创建 API 令牌',
diff --git a/lang/zh_CN/auth.php b/lang/zh_CN/auth.php
index 8c4ba63f9..4c97b46ce 100644
--- a/lang/zh_CN/auth.php
+++ b/lang/zh_CN/auth.php
@@ -8,6 +8,7 @@ return [
'failed' => '用户名或密码错误。',
'throttle' => '您的登录次数过多,请在:seconds秒后重试。',
+ 'mfa_throttle' => 'Too many multi-factor verification attempts. Please try again in :seconds seconds.',
// Login & Register
'sign_up' => '注册',
diff --git a/lang/zh_CN/entities.php b/lang/zh_CN/entities.php
index c4ec0414d..9daf816da 100644
--- a/lang/zh_CN/entities.php
+++ b/lang/zh_CN/entities.php
@@ -173,6 +173,7 @@ return [
'books_sort_desc' => '在书籍内部移动章节与页面以重组内容;支持添加其他书籍,实现跨书籍便捷移动章节与页面;还可设置自动排序规则,在内容发生变更时自动对本书内容进行排序。',
'books_sort_auto_sort' => '自动排序选项',
'books_sort_auto_sort_active' => '自动排序已激活:::sortName',
+ 'books_sort_auto_sort_creation_hint' => 'Auto sort option rules can be created in the "Lists & Sorting" settings area by a user with the relevant permissions.',
'books_sort_named' => '排序书籍「:bookName」',
'books_sort_name' => '按名称排序',
'books_sort_created' => '创建时间排序',
@@ -330,6 +331,9 @@ return [
// Editor Sidebar
'toggle_sidebar' => '切换侧边栏',
+ 'page_contents' => 'Page Contents',
+ 'page_contents_none' => 'No headings were found in the page content.',
+ 'page_contents_info' => 'The contents menu is generated from any heading formats used in the page.',
'page_tags' => '页面标签',
'chapter_tags' => '章节标签',
'book_tags' => '书籍标签',
diff --git a/lang/zh_CN/settings.php b/lang/zh_CN/settings.php
index e53e67aba..eef14b168 100644
--- a/lang/zh_CN/settings.php
+++ b/lang/zh_CN/settings.php
@@ -207,6 +207,7 @@ return [
'role_all' => '全部的',
'role_own' => '拥有的',
'role_controlled_by_asset' => '由其所在的资源来控制',
+ 'role_controlled_by_page_delete' => 'Controlled by page delete permissions',
'role_save' => '保存角色',
'role_users' => '此角色的用户',
'role_users_none' => '目前没有用户被分配到这个角色',
@@ -263,6 +264,9 @@ return [
'users_mfa_desc' => '设置多重身份认证能增加您账户的安全性。',
'users_mfa_x_methods' => ':count 个措施已配置|:count 个措施已配置',
'users_mfa_configure' => '配置安全措施',
+ 'users_mfa_reset' => '重置多重身份验证方法',
+ 'users_mfa_reset_desc' => '此操作将重置并清除该用户所有已配置的多重身份验证方法。如果多重身份验证是任何角色所要求的,用户在下次登录时将被提示配置新的方法。',
+ 'users_mfa_reset_confirm' => '您确定要重置此用户的多重身份验证吗?',
// API Tokens
'user_api_token_create' => '创建 API 令牌',
@@ -363,6 +367,7 @@ return [
'sk' => 'Slovensky',
'sl' => 'Slovenščina',
'sv' => 'Svenska',
+ 'th' => 'ภาษาไทย',
'tr' => 'Türkçe',
'uk' => 'Українська',
'uz' => 'O‘zbekcha',
diff --git a/lang/zh_TW/activities.php b/lang/zh_TW/activities.php
index 65ba0a565..791fa26b7 100644
--- a/lang/zh_TW/activities.php
+++ b/lang/zh_TW/activities.php
@@ -99,6 +99,8 @@ return [
'user_update_notification' => '使用者已成功更新。',
'user_delete' => '已刪除使用者',
'user_delete_notification' => '使用者移除成功',
+ 'user_mfa_reset' => 'reset MFA for user',
+ 'user_mfa_reset_notification' => 'Multi-factor authentication methods reset',
// API Tokens
'api_token_create' => '建立 API 權杖',
diff --git a/lang/zh_TW/auth.php b/lang/zh_TW/auth.php
index 1168b48b2..47e8ed950 100644
--- a/lang/zh_TW/auth.php
+++ b/lang/zh_TW/auth.php
@@ -8,6 +8,7 @@ return [
'failed' => '使用者名稱或密碼錯誤。',
'throttle' => '您的登入次數過多,請在 :seconds 秒後重試。',
+ 'mfa_throttle' => 'Too many multi-factor verification attempts. Please try again in :seconds seconds.',
// Login & Register
'sign_up' => '註冊',
diff --git a/lang/zh_TW/entities.php b/lang/zh_TW/entities.php
index 46bbe62f9..ba53d885d 100644
--- a/lang/zh_TW/entities.php
+++ b/lang/zh_TW/entities.php
@@ -173,6 +173,7 @@ return [
'books_sort_desc' => '在書籍中移動章節和頁面,重新安排其內容。可加入其他書籍,方便在書籍之間移動章節與頁面。可選擇設定自動排序規則,以便在變更時自動排序此書籍的內容。',
'books_sort_auto_sort' => '自動排序選項',
'books_sort_auto_sort_active' => '自動排序啟動::sortName',
+ 'books_sort_auto_sort_creation_hint' => 'Auto sort option rules can be created in the "Lists & Sorting" settings area by a user with the relevant permissions.',
'books_sort_named' => '排序書本 :bookName',
'books_sort_name' => '按名稱排序',
'books_sort_created' => '按建立時間排序',
@@ -330,6 +331,9 @@ return [
// Editor Sidebar
'toggle_sidebar' => '切換側邊欄',
+ 'page_contents' => 'Page Contents',
+ 'page_contents_none' => 'No headings were found in the page content.',
+ 'page_contents_info' => 'The contents menu is generated from any heading formats used in the page.',
'page_tags' => '頁面標籤',
'chapter_tags' => '章節標籤',
'book_tags' => '書本標籤',
diff --git a/lang/zh_TW/settings.php b/lang/zh_TW/settings.php
index 65778f77c..951085450 100644
--- a/lang/zh_TW/settings.php
+++ b/lang/zh_TW/settings.php
@@ -208,6 +208,7 @@ return [
'role_all' => '全部',
'role_own' => '擁有',
'role_controlled_by_asset' => '依據隸屬的資源來決定',
+ 'role_controlled_by_page_delete' => 'Controlled by page delete permissions',
'role_save' => '儲存角色',
'role_users' => '屬於此角色的使用者',
'role_users_none' => '目前沒有使用者被分配到此角色',
@@ -264,6 +265,9 @@ return [
'users_mfa_desc' => '設定多重身份驗證為您的帳戶多增加了一道防線',
'users_mfa_x_methods' => ':count 個措施已配置|:count 個措施已配置',
'users_mfa_configure' => '方式設置',
+ 'users_mfa_reset' => 'Reset Multi-Factor Authentication Methods',
+ 'users_mfa_reset_desc' => 'This will reset and clear all configured multi-factor authentication methods for this user. If multi-factor authentication is required by any of their roles, they\'ll be prompted to configure new methods on their next login.',
+ 'users_mfa_reset_confirm' => 'Are you sure you want to reset multi-factor authentication for this user?',
// API Tokens
'user_api_token_create' => '建立 API 權杖',
@@ -364,6 +368,7 @@ return [
'sk' => 'Slovensky',
'sl' => 'Slovenščina',
'sv' => 'Svenska',
+ 'th' => 'ภาษาไทย',
'tr' => 'Türkçe',
'uk' => 'Українська',
'uz' => 'O‘zbekcha',
diff --git a/package-lock.json b/package-lock.json
index b6508f1e9..d239426ec 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -5,7 +5,7 @@
"packages": {
"": {
"dependencies": {
- "@codemirror/commands": "^6.10.2",
+ "@codemirror/commands": "^6.10.3",
"@codemirror/lang-css": "^6.3.1",
"@codemirror/lang-html": "^6.4.11",
"@codemirror/lang-javascript": "^6.2.5",
@@ -13,15 +13,14 @@
"@codemirror/lang-markdown": "^6.5.0",
"@codemirror/lang-php": "^6.0.2",
"@codemirror/lang-xml": "^6.1.0",
- "@codemirror/language": "^6.12.2",
+ "@codemirror/language": "^6.12.3",
"@codemirror/legacy-modes": "^6.5.2",
- "@codemirror/state": "^6.5.4",
+ "@codemirror/state": "^6.6.0",
"@codemirror/theme-one-dark": "^6.1.3",
- "@codemirror/view": "^6.39.16",
+ "@codemirror/view": "^6.41.0",
"@lezer/highlight": "^1.2.3",
"@ssddanbrown/codemirror-lang-smarty": "^1.0.0",
"@ssddanbrown/codemirror-lang-twig": "^1.0.0",
- "@types/jest": "^30.0.0",
"codemirror": "^6.0.2",
"idb-keyval": "^6.2.2",
"markdown-it": "^14.1.1",
@@ -32,19 +31,20 @@
"devDependencies": {
"@eslint/js": "^10.0.1",
"@lezer/generator": "^1.8.0",
+ "@types/jest": "^30.0.0",
"@types/markdown-it": "^14.1.2",
"@types/sortablejs": "^1.15.9",
"chokidar-cli": "^3.0",
- "esbuild": "^0.27.3",
- "eslint": "^10.0.2",
+ "esbuild": "^0.28.0",
+ "eslint": "^10.2.0",
"globals": "^17.4.0",
- "jest": "^30.2.0",
- "jest-environment-jsdom": "^30.2.0",
+ "jest": "^30.3.0",
+ "jest-environment-jsdom": "^30.3.0",
"npm-run-all": "^4.1.5",
- "sass": "^1.97.3",
- "ts-jest": "^29.4.6",
+ "sass": "^1.99.0",
+ "ts-jest": "^29.4.9",
"ts-node": "^10.9.2",
- "typescript": "5.9.*"
+ "typescript": "6.0.*"
}
},
"node_modules/@asamuzakjp/css-color": {
@@ -72,6 +72,7 @@
"version": "7.29.0",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz",
"integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-validator-identifier": "^7.28.5",
@@ -223,6 +224,7 @@
"version": "7.28.5",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz",
"integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -239,23 +241,23 @@
}
},
"node_modules/@babel/helpers": {
- "version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.6.tgz",
- "integrity": "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==",
+ "version": "7.29.2",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.2.tgz",
+ "integrity": "sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/template": "^7.28.6",
- "@babel/types": "^7.28.6"
+ "@babel/types": "^7.29.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/parser": {
- "version": "7.29.0",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz",
- "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==",
+ "version": "7.29.2",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.2.tgz",
+ "integrity": "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -575,13 +577,13 @@
}
},
"node_modules/@codemirror/commands": {
- "version": "6.10.2",
- "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.10.2.tgz",
- "integrity": "sha512-vvX1fsih9HledO1c9zdotZYUZnE4xV0m6i3m25s5DIfXofuprk6cRcLUZvSk3CASUbwjQX21tOGbkY2BH8TpnQ==",
+ "version": "6.10.3",
+ "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.10.3.tgz",
+ "integrity": "sha512-JFRiqhKu+bvSkDLI+rUhJwSxQxYb759W5GBezE8Uc8mHLqC9aV/9aTC7yJSqCtB3F00pylrLCwnyS91Ap5ej4Q==",
"license": "MIT",
"dependencies": {
"@codemirror/language": "^6.0.0",
- "@codemirror/state": "^6.4.0",
+ "@codemirror/state": "^6.6.0",
"@codemirror/view": "^6.27.0",
"@lezer/common": "^1.1.0"
}
@@ -684,9 +686,9 @@
}
},
"node_modules/@codemirror/language": {
- "version": "6.12.2",
- "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.12.2.tgz",
- "integrity": "sha512-jEPmz2nGGDxhRTg3lTpzmIyGKxz3Gp3SJES4b0nAuE5SWQoKdT5GoQ69cwMmFd+wvFUhYirtDTr0/DRHpQAyWg==",
+ "version": "6.12.3",
+ "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.12.3.tgz",
+ "integrity": "sha512-QwCZW6Tt1siP37Jet9Tb02Zs81TQt6qQrZR2H+eGMcFsL1zMrk2/b9CLC7/9ieP1fjIUMgviLWMmgiHoJrj+ZA==",
"license": "MIT",
"dependencies": {
"@codemirror/state": "^6.0.0",
@@ -729,9 +731,9 @@
}
},
"node_modules/@codemirror/state": {
- "version": "6.5.4",
- "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.5.4.tgz",
- "integrity": "sha512-8y7xqG/hpB53l25CIoit9/ngxdfoG+fx+V3SHBrinnhOtLvKHRyAJJuHzkWrR4YXXLX8eXBsejgAAxHUOdW1yw==",
+ "version": "6.6.0",
+ "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.6.0.tgz",
+ "integrity": "sha512-4nbvra5R5EtiCzr9BTHiTLc+MLXK2QGiAVYMyi8PkQd3SR+6ixar/Q/01Fa21TBIDOZXgeWV4WppsQolSreAPQ==",
"license": "MIT",
"dependencies": {
"@marijn/find-cluster-break": "^1.0.0"
@@ -750,12 +752,12 @@
}
},
"node_modules/@codemirror/view": {
- "version": "6.39.16",
- "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.39.16.tgz",
- "integrity": "sha512-m6S22fFpKtOWhq8HuhzsI1WzUP/hB9THbDj0Tl5KX4gbO6Y91hwBl7Yky33NdvB6IffuRFiBxf1R8kJMyXmA4Q==",
+ "version": "6.41.0",
+ "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.41.0.tgz",
+ "integrity": "sha512-6H/qadXsVuDY219Yljhohglve8xf4B8xJkVOEWfA5uiYKiTFppjqsvsfR5iPA0RbvRBoOyTZpbLIxe9+0UR8xA==",
"license": "MIT",
"dependencies": {
- "@codemirror/state": "^6.5.0",
+ "@codemirror/state": "^6.6.0",
"crelt": "^1.0.6",
"style-mod": "^4.1.0",
"w3c-keyname": "^2.2.4"
@@ -901,21 +903,21 @@
}
},
"node_modules/@emnapi/core": {
- "version": "1.8.1",
- "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.8.1.tgz",
- "integrity": "sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==",
+ "version": "1.9.2",
+ "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.2.tgz",
+ "integrity": "sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA==",
"dev": true,
"license": "MIT",
"optional": true,
"dependencies": {
- "@emnapi/wasi-threads": "1.1.0",
+ "@emnapi/wasi-threads": "1.2.1",
"tslib": "^2.4.0"
}
},
"node_modules/@emnapi/runtime": {
- "version": "1.8.1",
- "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.8.1.tgz",
- "integrity": "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==",
+ "version": "1.9.2",
+ "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.2.tgz",
+ "integrity": "sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw==",
"dev": true,
"license": "MIT",
"optional": true,
@@ -924,9 +926,9 @@
}
},
"node_modules/@emnapi/wasi-threads": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz",
- "integrity": "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz",
+ "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==",
"dev": true,
"license": "MIT",
"optional": true,
@@ -935,9 +937,9 @@
}
},
"node_modules/@esbuild/aix-ppc64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz",
- "integrity": "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.0.tgz",
+ "integrity": "sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA==",
"cpu": [
"ppc64"
],
@@ -952,9 +954,9 @@
}
},
"node_modules/@esbuild/android-arm": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.3.tgz",
- "integrity": "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.0.tgz",
+ "integrity": "sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ==",
"cpu": [
"arm"
],
@@ -969,9 +971,9 @@
}
},
"node_modules/@esbuild/android-arm64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz",
- "integrity": "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.0.tgz",
+ "integrity": "sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw==",
"cpu": [
"arm64"
],
@@ -986,9 +988,9 @@
}
},
"node_modules/@esbuild/android-x64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.3.tgz",
- "integrity": "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.0.tgz",
+ "integrity": "sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA==",
"cpu": [
"x64"
],
@@ -1003,9 +1005,9 @@
}
},
"node_modules/@esbuild/darwin-arm64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz",
- "integrity": "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.0.tgz",
+ "integrity": "sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q==",
"cpu": [
"arm64"
],
@@ -1020,9 +1022,9 @@
}
},
"node_modules/@esbuild/darwin-x64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz",
- "integrity": "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.0.tgz",
+ "integrity": "sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ==",
"cpu": [
"x64"
],
@@ -1037,9 +1039,9 @@
}
},
"node_modules/@esbuild/freebsd-arm64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz",
- "integrity": "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.0.tgz",
+ "integrity": "sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q==",
"cpu": [
"arm64"
],
@@ -1054,9 +1056,9 @@
}
},
"node_modules/@esbuild/freebsd-x64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz",
- "integrity": "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.0.tgz",
+ "integrity": "sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw==",
"cpu": [
"x64"
],
@@ -1071,9 +1073,9 @@
}
},
"node_modules/@esbuild/linux-arm": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz",
- "integrity": "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.0.tgz",
+ "integrity": "sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw==",
"cpu": [
"arm"
],
@@ -1088,9 +1090,9 @@
}
},
"node_modules/@esbuild/linux-arm64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz",
- "integrity": "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.0.tgz",
+ "integrity": "sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A==",
"cpu": [
"arm64"
],
@@ -1105,9 +1107,9 @@
}
},
"node_modules/@esbuild/linux-ia32": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz",
- "integrity": "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.0.tgz",
+ "integrity": "sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ==",
"cpu": [
"ia32"
],
@@ -1122,9 +1124,9 @@
}
},
"node_modules/@esbuild/linux-loong64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz",
- "integrity": "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.0.tgz",
+ "integrity": "sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg==",
"cpu": [
"loong64"
],
@@ -1139,9 +1141,9 @@
}
},
"node_modules/@esbuild/linux-mips64el": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz",
- "integrity": "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.0.tgz",
+ "integrity": "sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w==",
"cpu": [
"mips64el"
],
@@ -1156,9 +1158,9 @@
}
},
"node_modules/@esbuild/linux-ppc64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz",
- "integrity": "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.0.tgz",
+ "integrity": "sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg==",
"cpu": [
"ppc64"
],
@@ -1173,9 +1175,9 @@
}
},
"node_modules/@esbuild/linux-riscv64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz",
- "integrity": "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.0.tgz",
+ "integrity": "sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ==",
"cpu": [
"riscv64"
],
@@ -1190,9 +1192,9 @@
}
},
"node_modules/@esbuild/linux-s390x": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz",
- "integrity": "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.0.tgz",
+ "integrity": "sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q==",
"cpu": [
"s390x"
],
@@ -1207,9 +1209,9 @@
}
},
"node_modules/@esbuild/linux-x64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz",
- "integrity": "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.0.tgz",
+ "integrity": "sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ==",
"cpu": [
"x64"
],
@@ -1224,9 +1226,9 @@
}
},
"node_modules/@esbuild/netbsd-arm64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz",
- "integrity": "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.0.tgz",
+ "integrity": "sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw==",
"cpu": [
"arm64"
],
@@ -1241,9 +1243,9 @@
}
},
"node_modules/@esbuild/netbsd-x64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz",
- "integrity": "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.0.tgz",
+ "integrity": "sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw==",
"cpu": [
"x64"
],
@@ -1258,9 +1260,9 @@
}
},
"node_modules/@esbuild/openbsd-arm64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz",
- "integrity": "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.0.tgz",
+ "integrity": "sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g==",
"cpu": [
"arm64"
],
@@ -1275,9 +1277,9 @@
}
},
"node_modules/@esbuild/openbsd-x64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz",
- "integrity": "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.0.tgz",
+ "integrity": "sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA==",
"cpu": [
"x64"
],
@@ -1292,9 +1294,9 @@
}
},
"node_modules/@esbuild/openharmony-arm64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz",
- "integrity": "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.0.tgz",
+ "integrity": "sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w==",
"cpu": [
"arm64"
],
@@ -1309,9 +1311,9 @@
}
},
"node_modules/@esbuild/sunos-x64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz",
- "integrity": "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.0.tgz",
+ "integrity": "sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw==",
"cpu": [
"x64"
],
@@ -1326,9 +1328,9 @@
}
},
"node_modules/@esbuild/win32-arm64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz",
- "integrity": "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.0.tgz",
+ "integrity": "sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA==",
"cpu": [
"arm64"
],
@@ -1343,9 +1345,9 @@
}
},
"node_modules/@esbuild/win32-ia32": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz",
- "integrity": "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.0.tgz",
+ "integrity": "sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA==",
"cpu": [
"ia32"
],
@@ -1360,9 +1362,9 @@
}
},
"node_modules/@esbuild/win32-x64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz",
- "integrity": "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.0.tgz",
+ "integrity": "sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw==",
"cpu": [
"x64"
],
@@ -1419,37 +1421,37 @@
}
},
"node_modules/@eslint/config-array": {
- "version": "0.23.2",
- "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.23.2.tgz",
- "integrity": "sha512-YF+fE6LV4v5MGWRGj7G404/OZzGNepVF8fxk7jqmqo3lrza7a0uUcDnROGRBG1WFC1omYUS/Wp1f42i0M+3Q3A==",
+ "version": "0.23.5",
+ "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.23.5.tgz",
+ "integrity": "sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@eslint/object-schema": "^3.0.2",
+ "@eslint/object-schema": "^3.0.5",
"debug": "^4.3.1",
- "minimatch": "^10.2.1"
+ "minimatch": "^10.2.4"
},
"engines": {
"node": "^20.19.0 || ^22.13.0 || >=24"
}
},
"node_modules/@eslint/config-helpers": {
- "version": "0.5.2",
- "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.5.2.tgz",
- "integrity": "sha512-a5MxrdDXEvqnIq+LisyCX6tQMPF/dSJpCfBgBauY+pNZ28yCtSsTvyTYrMhaI+LK26bVyCJfJkT0u8KIj2i1dQ==",
+ "version": "0.5.5",
+ "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.5.5.tgz",
+ "integrity": "sha512-eIJYKTCECbP/nsKaaruF6LW967mtbQbsw4JTtSVkUQc9MneSkbrgPJAbKl9nWr0ZeowV8BfsarBmPpBzGelA2w==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@eslint/core": "^1.1.0"
+ "@eslint/core": "^1.2.1"
},
"engines": {
"node": "^20.19.0 || ^22.13.0 || >=24"
}
},
"node_modules/@eslint/core": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.1.0.tgz",
- "integrity": "sha512-/nr9K9wkr3P1EzFTdFdMoLuo1PmIxjmwvPozwoSodjNBdefGujXQUF93u1DDZpEaTuDvMsIQddsd35BwtrW9Xw==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.2.1.tgz",
+ "integrity": "sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -1481,9 +1483,9 @@
}
},
"node_modules/@eslint/object-schema": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.2.tgz",
- "integrity": "sha512-HOy56KJt48Bx8KmJ+XGQNSUMT/6dZee/M54XyUyuvTvPXJmsERRvBchsUVx1UMe1WwIH49XLAczNC7V2INsuUw==",
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.5.tgz",
+ "integrity": "sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==",
"dev": true,
"license": "Apache-2.0",
"engines": {
@@ -1491,13 +1493,13 @@
}
},
"node_modules/@eslint/plugin-kit": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.6.0.tgz",
- "integrity": "sha512-bIZEUzOI1jkhviX2cp5vNyXQc6olzb2ohewQubuYlMXZ2Q/XjBO0x0XhGPvc9fjSIiUN0vw+0hq53BJ4eQSJKQ==",
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.7.1.tgz",
+ "integrity": "sha512-rZAP3aVgB9ds9KOeUSL+zZ21hPmo8dh6fnIFwRQj5EAZl9gzR7wxYbYXYysAM8CTqGmUGyp2S4kUdV17MnGuWQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@eslint/core": "^1.1.0",
+ "@eslint/core": "^1.2.1",
"levn": "^0.4.1"
},
"engines": {
@@ -1658,17 +1660,17 @@
}
},
"node_modules/@jest/console": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/@jest/console/-/console-30.2.0.tgz",
- "integrity": "sha512-+O1ifRjkvYIkBqASKWgLxrpEhQAAE7hY77ALLUufSk5717KfOShg6IbqLmdsLMPdUiFvA2kTs0R7YZy+l0IzZQ==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/console/-/console-30.3.0.tgz",
+ "integrity": "sha512-PAwCvFJ4696XP2qZj+LAn1BWjZaJ6RjG6c7/lkMaUJnkyMS34ucuIsfqYvfskVNvUI27R/u4P1HMYFnlVXG/Ww==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@jest/types": "30.2.0",
+ "@jest/types": "30.3.0",
"@types/node": "*",
"chalk": "^4.1.2",
- "jest-message-util": "30.2.0",
- "jest-util": "30.2.0",
+ "jest-message-util": "30.3.0",
+ "jest-util": "30.3.0",
"slash": "^3.0.0"
},
"engines": {
@@ -1676,39 +1678,38 @@
}
},
"node_modules/@jest/core": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/@jest/core/-/core-30.2.0.tgz",
- "integrity": "sha512-03W6IhuhjqTlpzh/ojut/pDB2LPRygyWX8ExpgHtQA8H/3K7+1vKmcINx5UzeOX1se6YEsBsOHQ1CRzf3fOwTQ==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/core/-/core-30.3.0.tgz",
+ "integrity": "sha512-U5mVPsBxLSO6xYbf+tgkymLx+iAhvZX43/xI1+ej2ZOPnPdkdO1CzDmFKh2mZBn2s4XZixszHeQnzp1gm/DIxw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@jest/console": "30.2.0",
+ "@jest/console": "30.3.0",
"@jest/pattern": "30.0.1",
- "@jest/reporters": "30.2.0",
- "@jest/test-result": "30.2.0",
- "@jest/transform": "30.2.0",
- "@jest/types": "30.2.0",
+ "@jest/reporters": "30.3.0",
+ "@jest/test-result": "30.3.0",
+ "@jest/transform": "30.3.0",
+ "@jest/types": "30.3.0",
"@types/node": "*",
"ansi-escapes": "^4.3.2",
"chalk": "^4.1.2",
"ci-info": "^4.2.0",
"exit-x": "^0.2.2",
"graceful-fs": "^4.2.11",
- "jest-changed-files": "30.2.0",
- "jest-config": "30.2.0",
- "jest-haste-map": "30.2.0",
- "jest-message-util": "30.2.0",
+ "jest-changed-files": "30.3.0",
+ "jest-config": "30.3.0",
+ "jest-haste-map": "30.3.0",
+ "jest-message-util": "30.3.0",
"jest-regex-util": "30.0.1",
- "jest-resolve": "30.2.0",
- "jest-resolve-dependencies": "30.2.0",
- "jest-runner": "30.2.0",
- "jest-runtime": "30.2.0",
- "jest-snapshot": "30.2.0",
- "jest-util": "30.2.0",
- "jest-validate": "30.2.0",
- "jest-watcher": "30.2.0",
- "micromatch": "^4.0.8",
- "pretty-format": "30.2.0",
+ "jest-resolve": "30.3.0",
+ "jest-resolve-dependencies": "30.3.0",
+ "jest-runner": "30.3.0",
+ "jest-runtime": "30.3.0",
+ "jest-snapshot": "30.3.0",
+ "jest-util": "30.3.0",
+ "jest-validate": "30.3.0",
+ "jest-watcher": "30.3.0",
+ "pretty-format": "30.3.0",
"slash": "^3.0.0"
},
"engines": {
@@ -1724,44 +1725,45 @@
}
},
"node_modules/@jest/diff-sequences": {
- "version": "30.0.1",
- "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.0.1.tgz",
- "integrity": "sha512-n5H8QLDJ47QqbCNn5SuFjCRDrOLEZ0h8vAHCK5RL9Ls7Xa8AQLa/YxAc9UjFqoEDM48muwtBGjtMY5cr0PLDCw==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.3.0.tgz",
+ "integrity": "sha512-cG51MVnLq1ecVUaQ3fr6YuuAOitHK1S4WUJHnsPFE/quQr33ADUx1FfrTCpMCRxvy0Yr9BThKpDjSlcTi91tMA==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
"node_modules/@jest/environment": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.2.0.tgz",
- "integrity": "sha512-/QPTL7OBJQ5ac09UDRa3EQes4gt1FTEG/8jZ/4v5IVzx+Cv7dLxlVIvfvSVRiiX2drWyXeBjkMSR8hvOWSog5g==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.3.0.tgz",
+ "integrity": "sha512-SlLSF4Be735yQXyh2+mctBOzNDx5s5uLv88/j8Qn1wH679PDcwy67+YdADn8NJnGjzlXtN62asGH/T4vWOkfaw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@jest/fake-timers": "30.2.0",
- "@jest/types": "30.2.0",
+ "@jest/fake-timers": "30.3.0",
+ "@jest/types": "30.3.0",
"@types/node": "*",
- "jest-mock": "30.2.0"
+ "jest-mock": "30.3.0"
},
"engines": {
"node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
"node_modules/@jest/environment-jsdom-abstract": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/@jest/environment-jsdom-abstract/-/environment-jsdom-abstract-30.2.0.tgz",
- "integrity": "sha512-kazxw2L9IPuZpQ0mEt9lu9Z98SqR74xcagANmMBU16X0lS23yPc0+S6hGLUz8kVRlomZEs/5S/Zlpqwf5yu6OQ==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/environment-jsdom-abstract/-/environment-jsdom-abstract-30.3.0.tgz",
+ "integrity": "sha512-0hNFs5N6We3DMCwobzI0ydhkY10sT1tZSC0AAiy+0g2Dt/qEWgrcV5BrMxPczhe41cxW4qm6X+jqZaUdpZIajA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@jest/environment": "30.2.0",
- "@jest/fake-timers": "30.2.0",
- "@jest/types": "30.2.0",
+ "@jest/environment": "30.3.0",
+ "@jest/fake-timers": "30.3.0",
+ "@jest/types": "30.3.0",
"@types/jsdom": "^21.1.7",
"@types/node": "*",
- "jest-mock": "30.2.0",
- "jest-util": "30.2.0"
+ "jest-mock": "30.3.0",
+ "jest-util": "30.3.0"
},
"engines": {
"node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
@@ -1777,23 +1779,24 @@
}
},
"node_modules/@jest/expect": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-30.2.0.tgz",
- "integrity": "sha512-V9yxQK5erfzx99Sf+7LbhBwNWEZ9eZay8qQ9+JSC0TrMR1pMDHLMY+BnVPacWU6Jamrh252/IKo4F1Xn/zfiqA==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-30.3.0.tgz",
+ "integrity": "sha512-76Nlh4xJxk2D/9URCn3wFi98d2hb19uWE1idLsTt2ywhvdOldbw3S570hBgn25P4ICUZ/cBjybrBex2g17IDbg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "expect": "30.2.0",
- "jest-snapshot": "30.2.0"
+ "expect": "30.3.0",
+ "jest-snapshot": "30.3.0"
},
"engines": {
"node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
"node_modules/@jest/expect-utils": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.2.0.tgz",
- "integrity": "sha512-1JnRfhqpD8HGpOmQp180Fo9Zt69zNtC+9lR+kT7NVL05tNXIi+QC8Csz7lfidMoVLPD3FnOtcmp0CEFnxExGEA==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.3.0.tgz",
+ "integrity": "sha512-j0+W5iQQ8hBh7tHZkTQv3q2Fh/M7Je72cIsYqC4OaktgtO7v1So9UTjp6uPBHIaB6beoF/RRsCgMJKvti0wADA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@jest/get-type": "30.1.0"
@@ -1803,18 +1806,18 @@
}
},
"node_modules/@jest/fake-timers": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.2.0.tgz",
- "integrity": "sha512-HI3tRLjRxAbBy0VO8dqqm7Hb2mIa8d5bg/NJkyQcOk7V118ObQML8RC5luTF/Zsg4474a+gDvhce7eTnP4GhYw==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.3.0.tgz",
+ "integrity": "sha512-WUQDs8SOP9URStX1DzhD425CqbN/HxUYCTwVrT8sTVBfMvFqYt/s61EK5T05qnHu0po6RitXIvP9otZxYDzTGQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@jest/types": "30.2.0",
- "@sinonjs/fake-timers": "^13.0.0",
+ "@jest/types": "30.3.0",
+ "@sinonjs/fake-timers": "^15.0.0",
"@types/node": "*",
- "jest-message-util": "30.2.0",
- "jest-mock": "30.2.0",
- "jest-util": "30.2.0"
+ "jest-message-util": "30.3.0",
+ "jest-mock": "30.3.0",
+ "jest-util": "30.3.0"
},
"engines": {
"node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
@@ -1824,22 +1827,23 @@
"version": "30.1.0",
"resolved": "https://registry.npmjs.org/@jest/get-type/-/get-type-30.1.0.tgz",
"integrity": "sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
"node_modules/@jest/globals": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-30.2.0.tgz",
- "integrity": "sha512-b63wmnKPaK+6ZZfpYhz9K61oybvbI1aMcIs80++JI1O1rR1vaxHUCNqo3ITu6NU0d4V34yZFoHMn/uoKr/Rwfw==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-30.3.0.tgz",
+ "integrity": "sha512-+owLCBBdfpgL3HU+BD5etr1SvbXpSitJK0is1kiYjJxAAJggYMRQz5hSdd5pq1sSggfxPbw2ld71pt4x5wwViA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@jest/environment": "30.2.0",
- "@jest/expect": "30.2.0",
- "@jest/types": "30.2.0",
- "jest-mock": "30.2.0"
+ "@jest/environment": "30.3.0",
+ "@jest/expect": "30.3.0",
+ "@jest/types": "30.3.0",
+ "jest-mock": "30.3.0"
},
"engines": {
"node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
@@ -1849,6 +1853,7 @@
"version": "30.0.1",
"resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.0.1.tgz",
"integrity": "sha512-gWp7NfQW27LaBQz3TITS8L7ZCQ0TLvtmI//4OwlQRx4rnWxcPNIYjxZpDcN4+UlGxgm3jS5QPz8IPTCkb59wZA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@types/node": "*",
@@ -1859,32 +1864,32 @@
}
},
"node_modules/@jest/reporters": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-30.2.0.tgz",
- "integrity": "sha512-DRyW6baWPqKMa9CzeiBjHwjd8XeAyco2Vt8XbcLFjiwCOEKOvy82GJ8QQnJE9ofsxCMPjH4MfH8fCWIHHDKpAQ==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-30.3.0.tgz",
+ "integrity": "sha512-a09z89S+PkQnL055bVj8+pe2Caed2PBOaczHcXCykW5ngxX9EWx/1uAwncxc/HiU0oZqfwseMjyhxgRjS49qPw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@bcoe/v8-coverage": "^0.2.3",
- "@jest/console": "30.2.0",
- "@jest/test-result": "30.2.0",
- "@jest/transform": "30.2.0",
- "@jest/types": "30.2.0",
+ "@jest/console": "30.3.0",
+ "@jest/test-result": "30.3.0",
+ "@jest/transform": "30.3.0",
+ "@jest/types": "30.3.0",
"@jridgewell/trace-mapping": "^0.3.25",
"@types/node": "*",
"chalk": "^4.1.2",
"collect-v8-coverage": "^1.0.2",
"exit-x": "^0.2.2",
- "glob": "^10.3.10",
+ "glob": "^10.5.0",
"graceful-fs": "^4.2.11",
"istanbul-lib-coverage": "^3.0.0",
"istanbul-lib-instrument": "^6.0.0",
"istanbul-lib-report": "^3.0.0",
"istanbul-lib-source-maps": "^5.0.0",
"istanbul-reports": "^3.1.3",
- "jest-message-util": "30.2.0",
- "jest-util": "30.2.0",
- "jest-worker": "30.2.0",
+ "jest-message-util": "30.3.0",
+ "jest-util": "30.3.0",
+ "jest-worker": "30.3.0",
"slash": "^3.0.0",
"string-length": "^4.0.2",
"v8-to-istanbul": "^9.0.1"
@@ -1905,6 +1910,7 @@
"version": "30.0.5",
"resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz",
"integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@sinclair/typebox": "^0.34.0"
@@ -1914,13 +1920,13 @@
}
},
"node_modules/@jest/snapshot-utils": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/@jest/snapshot-utils/-/snapshot-utils-30.2.0.tgz",
- "integrity": "sha512-0aVxM3RH6DaiLcjj/b0KrIBZhSX1373Xci4l3cW5xiUWPctZ59zQ7jj4rqcJQ/Z8JuN/4wX3FpJSa3RssVvCug==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/snapshot-utils/-/snapshot-utils-30.3.0.tgz",
+ "integrity": "sha512-ORbRN9sf5PP82v3FXNSwmO1OTDR2vzR2YTaR+E3VkSBZ8zadQE6IqYdYEeFH1NIkeB2HIGdF02dapb6K0Mj05g==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@jest/types": "30.2.0",
+ "@jest/types": "30.3.0",
"chalk": "^4.1.2",
"graceful-fs": "^4.2.11",
"natural-compare": "^1.4.0"
@@ -1945,14 +1951,14 @@
}
},
"node_modules/@jest/test-result": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-30.2.0.tgz",
- "integrity": "sha512-RF+Z+0CCHkARz5HT9mcQCBulb1wgCP3FBvl9VFokMX27acKphwyQsNuWH3c+ojd1LeWBLoTYoxF0zm6S/66mjg==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-30.3.0.tgz",
+ "integrity": "sha512-e/52nJGuD74AKTSe0P4y5wFRlaXP0qmrS17rqOMHeSwm278VyNyXE3gFO/4DTGF9w+65ra3lo3VKj0LBrzmgdQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@jest/console": "30.2.0",
- "@jest/types": "30.2.0",
+ "@jest/console": "30.3.0",
+ "@jest/types": "30.3.0",
"@types/istanbul-lib-coverage": "^2.0.6",
"collect-v8-coverage": "^1.0.2"
},
@@ -1961,15 +1967,15 @@
}
},
"node_modules/@jest/test-sequencer": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-30.2.0.tgz",
- "integrity": "sha512-wXKgU/lk8fKXMu/l5Hog1R61bL4q5GCdT6OJvdAFz1P+QrpoFuLU68eoKuVc4RbrTtNnTL5FByhWdLgOPSph+Q==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-30.3.0.tgz",
+ "integrity": "sha512-dgbWy9b8QDlQeRZcv7LNF+/jFiiYHTKho1xirauZ7kVwY7avjFF6uTT0RqlgudB5OuIPagFdVtfFMosjVbk1eA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@jest/test-result": "30.2.0",
+ "@jest/test-result": "30.3.0",
"graceful-fs": "^4.2.11",
- "jest-haste-map": "30.2.0",
+ "jest-haste-map": "30.3.0",
"slash": "^3.0.0"
},
"engines": {
@@ -1977,24 +1983,23 @@
}
},
"node_modules/@jest/transform": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.2.0.tgz",
- "integrity": "sha512-XsauDV82o5qXbhalKxD7p4TZYYdwcaEXC77PPD2HixEFF+6YGppjrAAQurTl2ECWcEomHBMMNS9AH3kcCFx8jA==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.3.0.tgz",
+ "integrity": "sha512-TLKY33fSLVd/lKB2YI1pH69ijyUblO/BQvCj566YvnwuzoTNr648iE0j22vRvVNk2HsPwByPxATg3MleS3gf5A==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/core": "^7.27.4",
- "@jest/types": "30.2.0",
+ "@jest/types": "30.3.0",
"@jridgewell/trace-mapping": "^0.3.25",
"babel-plugin-istanbul": "^7.0.1",
"chalk": "^4.1.2",
"convert-source-map": "^2.0.0",
"fast-json-stable-stringify": "^2.1.0",
"graceful-fs": "^4.2.11",
- "jest-haste-map": "30.2.0",
+ "jest-haste-map": "30.3.0",
"jest-regex-util": "30.0.1",
- "jest-util": "30.2.0",
- "micromatch": "^4.0.8",
+ "jest-util": "30.3.0",
"pirates": "^4.0.7",
"slash": "^3.0.0",
"write-file-atomic": "^5.0.1"
@@ -2004,9 +2009,10 @@
}
},
"node_modules/@jest/types": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz",
- "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.3.0.tgz",
+ "integrity": "sha512-JHm87k7bA33hpBngtU8h6UBub/fqqA9uXfw+21j5Hmk7ooPHlboRNxHq0JcMtC+n8VJGP1mcfnD3Mk+XKe1oSw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@jest/pattern": "30.0.1",
@@ -2072,15 +2078,15 @@
}
},
"node_modules/@lezer/common": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.5.1.tgz",
- "integrity": "sha512-6YRVG9vBkaY7p1IVxL4s44n5nUnaNnGM2/AckNgYOnxTG2kWh1vR8BMxPseWPjRNpb5VtXnMpeYAEAADoRV1Iw==",
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.5.2.tgz",
+ "integrity": "sha512-sxQE460fPZyU3sdc8lafxiPwJHBzZRy/udNFynGQky1SePYBdhkBl1kOagA9uT3pxR8K09bOrmTUqA9wb/PjSQ==",
"license": "MIT"
},
"node_modules/@lezer/css": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/@lezer/css/-/css-1.3.1.tgz",
- "integrity": "sha512-PYAKeUVBo3HFThruRyp/iK91SwiZJnzXh8QzkQlwijB5y+N5iB28+iLk78o2zmKqqV0uolNhCwFqB8LA7b0Svg==",
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/@lezer/css/-/css-1.3.3.tgz",
+ "integrity": "sha512-RzBo8r+/6QJeow7aPHIpGVIH59xTcJXp399820gZoMo9noQDRVpJLheIBUicYwKcsbOYoBRoLZlf2720dG/4Tg==",
"license": "MIT",
"dependencies": {
"@lezer/common": "^1.2.0",
@@ -2333,6 +2339,9 @@
"arm"
],
"dev": true,
+ "libc": [
+ "glibc"
+ ],
"license": "MIT",
"optional": true,
"os": [
@@ -2354,6 +2363,9 @@
"arm"
],
"dev": true,
+ "libc": [
+ "musl"
+ ],
"license": "MIT",
"optional": true,
"os": [
@@ -2375,6 +2387,9 @@
"arm64"
],
"dev": true,
+ "libc": [
+ "glibc"
+ ],
"license": "MIT",
"optional": true,
"os": [
@@ -2396,6 +2411,9 @@
"arm64"
],
"dev": true,
+ "libc": [
+ "musl"
+ ],
"license": "MIT",
"optional": true,
"os": [
@@ -2417,6 +2435,9 @@
"x64"
],
"dev": true,
+ "libc": [
+ "glibc"
+ ],
"license": "MIT",
"optional": true,
"os": [
@@ -2438,6 +2459,9 @@
"x64"
],
"dev": true,
+ "libc": [
+ "musl"
+ ],
"license": "MIT",
"optional": true,
"os": [
@@ -2515,9 +2539,9 @@
}
},
"node_modules/@parcel/watcher/node_modules/picomatch": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
- "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
+ "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
"dev": true,
"license": "MIT",
"optional": true,
@@ -2553,9 +2577,10 @@
}
},
"node_modules/@sinclair/typebox": {
- "version": "0.34.48",
- "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz",
- "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==",
+ "version": "0.34.49",
+ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz",
+ "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==",
+ "dev": true,
"license": "MIT"
},
"node_modules/@sinonjs/commons": {
@@ -2569,9 +2594,9 @@
}
},
"node_modules/@sinonjs/fake-timers": {
- "version": "13.0.5",
- "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-13.0.5.tgz",
- "integrity": "sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==",
+ "version": "15.3.0",
+ "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.3.0.tgz",
+ "integrity": "sha512-m2xozxSfCIxjDdvbhIWazlP2i2aha/iUmbl94alpsIbd3iLTfeXgfBVbwyWogB6l++istyGZqamgA/EcqYf+Bg==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
@@ -2697,12 +2722,14 @@
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz",
"integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==",
+ "dev": true,
"license": "MIT"
},
"node_modules/@types/istanbul-lib-report": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz",
"integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@types/istanbul-lib-coverage": "*"
@@ -2712,6 +2739,7 @@
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz",
"integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@types/istanbul-lib-report": "*"
@@ -2721,6 +2749,7 @@
"version": "30.0.0",
"resolved": "https://registry.npmjs.org/@types/jest/-/jest-30.0.0.tgz",
"integrity": "sha512-XTYugzhuwqWjws0CVz8QpM36+T+Dz5mTEBKhNs/esGLnCIlGdRy+Dq78NRjd7ls7r8BC8ZRMOrKlkO1hU0JOwA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"expect": "^30.0.0",
@@ -2772,9 +2801,10 @@
"license": "MIT"
},
"node_modules/@types/node": {
- "version": "25.3.5",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-25.3.5.tgz",
- "integrity": "sha512-oX8xrhvpiyRCQkG1MFchB09f+cXftgIXb3a7UUa4Y3wpmZPw5tyZGTLWhlESOLq1Rq6oDlc8npVU2/9xiCuXMA==",
+ "version": "25.5.2",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-25.5.2.tgz",
+ "integrity": "sha512-tO4ZIRKNC+MDWV4qKVZe3Ql/woTnmHDr5JD8UI5hn2pwBrHEwOEMZK7WlNb5RKB6EoJ02gwmQS9OrjuFnZYdpg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"undici-types": "~7.18.0"
@@ -2791,6 +2821,7 @@
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz",
"integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==",
+ "dev": true,
"license": "MIT"
},
"node_modules/@types/tough-cookie": {
@@ -2804,6 +2835,7 @@
"version": "17.0.35",
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz",
"integrity": "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@types/yargs-parser": "*"
@@ -2813,6 +2845,7 @@
"version": "21.0.3",
"resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz",
"integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==",
+ "dev": true,
"license": "MIT"
},
"node_modules/@ungap/structured-clone": {
@@ -2928,6 +2961,9 @@
"arm64"
],
"dev": true,
+ "libc": [
+ "glibc"
+ ],
"license": "MIT",
"optional": true,
"os": [
@@ -2942,6 +2978,9 @@
"arm64"
],
"dev": true,
+ "libc": [
+ "musl"
+ ],
"license": "MIT",
"optional": true,
"os": [
@@ -2956,6 +2995,9 @@
"ppc64"
],
"dev": true,
+ "libc": [
+ "glibc"
+ ],
"license": "MIT",
"optional": true,
"os": [
@@ -2970,6 +3012,9 @@
"riscv64"
],
"dev": true,
+ "libc": [
+ "glibc"
+ ],
"license": "MIT",
"optional": true,
"os": [
@@ -2984,6 +3029,9 @@
"riscv64"
],
"dev": true,
+ "libc": [
+ "musl"
+ ],
"license": "MIT",
"optional": true,
"os": [
@@ -2998,6 +3046,9 @@
"s390x"
],
"dev": true,
+ "libc": [
+ "glibc"
+ ],
"license": "MIT",
"optional": true,
"os": [
@@ -3012,6 +3063,9 @@
"x64"
],
"dev": true,
+ "libc": [
+ "glibc"
+ ],
"license": "MIT",
"optional": true,
"os": [
@@ -3026,6 +3080,9 @@
"x64"
],
"dev": true,
+ "libc": [
+ "musl"
+ ],
"license": "MIT",
"optional": true,
"os": [
@@ -3187,6 +3244,7 @@
"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"
@@ -3295,16 +3353,16 @@
}
},
"node_modules/babel-jest": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.2.0.tgz",
- "integrity": "sha512-0YiBEOxWqKkSQWL9nNGGEgndoeL0ZpWrbLMNL5u/Kaxrli3Eaxlt3ZtIDktEvXt4L/R9r3ODr2zKwGM/2BjxVw==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.3.0.tgz",
+ "integrity": "sha512-gRpauEU2KRrCox5Z296aeVHR4jQ98BCnu0IO332D/xpHNOsIH/bgSRk9k6GbKIbBw8vFeN6ctuu6tV8WOyVfYQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@jest/transform": "30.2.0",
+ "@jest/transform": "30.3.0",
"@types/babel__core": "^7.20.5",
"babel-plugin-istanbul": "^7.0.1",
- "babel-preset-jest": "30.2.0",
+ "babel-preset-jest": "30.3.0",
"chalk": "^4.1.2",
"graceful-fs": "^4.2.11",
"slash": "^3.0.0"
@@ -3337,9 +3395,9 @@
}
},
"node_modules/babel-plugin-jest-hoist": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-30.2.0.tgz",
- "integrity": "sha512-ftzhzSGMUnOzcCXd6WHdBGMyuwy15Wnn0iyyWGKgBDLxf9/s5ABuraCSpBX2uG0jUg4rqJnxsLc5+oYBqoxVaA==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-30.3.0.tgz",
+ "integrity": "sha512-+TRkByhsws6sfPjVaitzadk1I0F5sPvOVUH5tyTSzhePpsGIVrdeunHSw/C36QeocS95OOk8lunc4rlu5Anwsg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3377,13 +3435,13 @@
}
},
"node_modules/babel-preset-jest": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-30.2.0.tgz",
- "integrity": "sha512-US4Z3NOieAQumwFnYdUWKvUKh8+YSnS/gB3t6YBiz0bskpu7Pine8pPCheNxlPEW4wnUkma2a94YuW2q3guvCQ==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-30.3.0.tgz",
+ "integrity": "sha512-6ZcUbWHC+dMz2vfzdNwi87Z1gQsLNK2uLuK1Q89R11xdvejcivlYYwDlEv0FHX3VwEXpbBQ9uufB/MUNpZGfhQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "babel-plugin-jest-hoist": "30.2.0",
+ "babel-plugin-jest-hoist": "30.3.0",
"babel-preset-current-node-syntax": "^1.2.0"
},
"engines": {
@@ -3404,9 +3462,9 @@
}
},
"node_modules/baseline-browser-mapping": {
- "version": "2.10.0",
- "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.0.tgz",
- "integrity": "sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA==",
+ "version": "2.10.16",
+ "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.16.tgz",
+ "integrity": "sha512-Lyf3aK28zpsD1yQMiiHD4RvVb6UdMoo8xzG2XzFIfR9luPzOpcBlAsT/qfB1XWS1bxWT+UtE4WmQgsp297FYOA==",
"dev": true,
"license": "Apache-2.0",
"bin": {
@@ -3430,9 +3488,9 @@
}
},
"node_modules/brace-expansion": {
- "version": "5.0.4",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz",
- "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==",
+ "version": "5.0.5",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz",
+ "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3446,6 +3504,7 @@
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"fill-range": "^7.1.1"
@@ -3455,9 +3514,9 @@
}
},
"node_modules/browserslist": {
- "version": "4.28.1",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz",
- "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==",
+ "version": "4.28.2",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz",
+ "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==",
"dev": true,
"funding": [
{
@@ -3475,11 +3534,11 @@
],
"license": "MIT",
"dependencies": {
- "baseline-browser-mapping": "^2.9.0",
- "caniuse-lite": "^1.0.30001759",
- "electron-to-chromium": "^1.5.263",
- "node-releases": "^2.0.27",
- "update-browserslist-db": "^1.2.0"
+ "baseline-browser-mapping": "^2.10.12",
+ "caniuse-lite": "^1.0.30001782",
+ "electron-to-chromium": "^1.5.328",
+ "node-releases": "^2.0.36",
+ "update-browserslist-db": "^1.2.3"
},
"bin": {
"browserslist": "cli.js"
@@ -3589,9 +3648,9 @@
}
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001777",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001777.tgz",
- "integrity": "sha512-tmN+fJxroPndC74efCdp12j+0rk0RHwV5Jwa1zWaFVyw2ZxAuPeG8ZgWC3Wz7uSjT3qMRQ5XHZ4COgQmsCMJAQ==",
+ "version": "1.0.30001787",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001787.tgz",
+ "integrity": "sha512-mNcrMN9KeI68u7muanUpEejSLghOKlVhRqS/Za2IeyGllJ9I9otGpR9g3nsw7n4W378TE/LyIteA0+/FOZm4Kg==",
"dev": true,
"funding": [
{
@@ -3613,6 +3672,7 @@
"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",
@@ -3683,6 +3743,7 @@
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz",
"integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==",
+ "dev": true,
"funding": [
{
"type": "github",
@@ -3850,6 +3911,7 @@
"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"
@@ -3862,6 +3924,7 @@
"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/concat-map": {
@@ -4145,9 +4208,9 @@
"license": "MIT"
},
"node_modules/electron-to-chromium": {
- "version": "1.5.307",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.307.tgz",
- "integrity": "sha512-5z3uFKBWjiNR44nFcYdkcXjKMbg5KXNdciu7mhTPo9tB7NbqSNP2sSnGR+fqknZSCwKkBN+oxiiajWs4dT6ORg==",
+ "version": "1.5.334",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.334.tgz",
+ "integrity": "sha512-mgjZAz7Jyx1SRCwEpy9wefDS7GvNPazLthHg8eQMJ76wBdGQQDW33TCrUTvQ4wzpmOrv2zrFoD3oNufMdyMpog==",
"dev": true,
"license": "ISC"
},
@@ -4194,9 +4257,9 @@
}
},
"node_modules/es-abstract": {
- "version": "1.24.1",
- "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.1.tgz",
- "integrity": "sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw==",
+ "version": "1.24.2",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.2.tgz",
+ "integrity": "sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4330,9 +4393,9 @@
}
},
"node_modules/esbuild": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz",
- "integrity": "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.0.tgz",
+ "integrity": "sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
@@ -4343,32 +4406,32 @@
"node": ">=18"
},
"optionalDependencies": {
- "@esbuild/aix-ppc64": "0.27.3",
- "@esbuild/android-arm": "0.27.3",
- "@esbuild/android-arm64": "0.27.3",
- "@esbuild/android-x64": "0.27.3",
- "@esbuild/darwin-arm64": "0.27.3",
- "@esbuild/darwin-x64": "0.27.3",
- "@esbuild/freebsd-arm64": "0.27.3",
- "@esbuild/freebsd-x64": "0.27.3",
- "@esbuild/linux-arm": "0.27.3",
- "@esbuild/linux-arm64": "0.27.3",
- "@esbuild/linux-ia32": "0.27.3",
- "@esbuild/linux-loong64": "0.27.3",
- "@esbuild/linux-mips64el": "0.27.3",
- "@esbuild/linux-ppc64": "0.27.3",
- "@esbuild/linux-riscv64": "0.27.3",
- "@esbuild/linux-s390x": "0.27.3",
- "@esbuild/linux-x64": "0.27.3",
- "@esbuild/netbsd-arm64": "0.27.3",
- "@esbuild/netbsd-x64": "0.27.3",
- "@esbuild/openbsd-arm64": "0.27.3",
- "@esbuild/openbsd-x64": "0.27.3",
- "@esbuild/openharmony-arm64": "0.27.3",
- "@esbuild/sunos-x64": "0.27.3",
- "@esbuild/win32-arm64": "0.27.3",
- "@esbuild/win32-ia32": "0.27.3",
- "@esbuild/win32-x64": "0.27.3"
+ "@esbuild/aix-ppc64": "0.28.0",
+ "@esbuild/android-arm": "0.28.0",
+ "@esbuild/android-arm64": "0.28.0",
+ "@esbuild/android-x64": "0.28.0",
+ "@esbuild/darwin-arm64": "0.28.0",
+ "@esbuild/darwin-x64": "0.28.0",
+ "@esbuild/freebsd-arm64": "0.28.0",
+ "@esbuild/freebsd-x64": "0.28.0",
+ "@esbuild/linux-arm": "0.28.0",
+ "@esbuild/linux-arm64": "0.28.0",
+ "@esbuild/linux-ia32": "0.28.0",
+ "@esbuild/linux-loong64": "0.28.0",
+ "@esbuild/linux-mips64el": "0.28.0",
+ "@esbuild/linux-ppc64": "0.28.0",
+ "@esbuild/linux-riscv64": "0.28.0",
+ "@esbuild/linux-s390x": "0.28.0",
+ "@esbuild/linux-x64": "0.28.0",
+ "@esbuild/netbsd-arm64": "0.28.0",
+ "@esbuild/netbsd-x64": "0.28.0",
+ "@esbuild/openbsd-arm64": "0.28.0",
+ "@esbuild/openbsd-x64": "0.28.0",
+ "@esbuild/openharmony-arm64": "0.28.0",
+ "@esbuild/sunos-x64": "0.28.0",
+ "@esbuild/win32-arm64": "0.28.0",
+ "@esbuild/win32-ia32": "0.28.0",
+ "@esbuild/win32-x64": "0.28.0"
}
},
"node_modules/escalade": {
@@ -4395,18 +4458,18 @@
}
},
"node_modules/eslint": {
- "version": "10.0.2",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.0.2.tgz",
- "integrity": "sha512-uYixubwmqJZH+KLVYIVKY1JQt7tysXhtj21WSvjcSmU5SVNzMus1bgLe+pAt816yQ8opKfheVVoPLqvVMGejYw==",
+ "version": "10.2.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.2.0.tgz",
+ "integrity": "sha512-+L0vBFYGIpSNIt/KWTpFonPrqYvgKw1eUI5Vn7mEogrQcWtWYtNQ7dNqC+px/J0idT3BAkiWrhfS7k+Tum8TUA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.8.0",
"@eslint-community/regexpp": "^4.12.2",
- "@eslint/config-array": "^0.23.2",
- "@eslint/config-helpers": "^0.5.2",
- "@eslint/core": "^1.1.0",
- "@eslint/plugin-kit": "^0.6.0",
+ "@eslint/config-array": "^0.23.4",
+ "@eslint/config-helpers": "^0.5.4",
+ "@eslint/core": "^1.2.0",
+ "@eslint/plugin-kit": "^0.7.0",
"@humanfs/node": "^0.16.6",
"@humanwhocodes/module-importer": "^1.0.1",
"@humanwhocodes/retry": "^0.4.2",
@@ -4415,9 +4478,9 @@
"cross-spawn": "^7.0.6",
"debug": "^4.3.2",
"escape-string-regexp": "^4.0.0",
- "eslint-scope": "^9.1.1",
+ "eslint-scope": "^9.1.2",
"eslint-visitor-keys": "^5.0.1",
- "espree": "^11.1.1",
+ "espree": "^11.2.0",
"esquery": "^1.7.0",
"esutils": "^2.0.2",
"fast-deep-equal": "^3.1.3",
@@ -4428,7 +4491,7 @@
"imurmurhash": "^0.1.4",
"is-glob": "^4.0.0",
"json-stable-stringify-without-jsonify": "^1.0.1",
- "minimatch": "^10.2.1",
+ "minimatch": "^10.2.4",
"natural-compare": "^1.4.0",
"optionator": "^0.9.3"
},
@@ -4451,9 +4514,9 @@
}
},
"node_modules/eslint-scope": {
- "version": "9.1.1",
- "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.1.tgz",
- "integrity": "sha512-GaUN0sWim5qc8KVErfPBWmc31LEsOkrUJbvJZV+xuL3u2phMUK4HIvXlWAakfC8W4nzlK+chPEAkYOYb5ZScIw==",
+ "version": "9.1.2",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.2.tgz",
+ "integrity": "sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
@@ -4496,9 +4559,9 @@
}
},
"node_modules/espree": {
- "version": "11.1.1",
- "resolved": "https://registry.npmjs.org/espree/-/espree-11.1.1.tgz",
- "integrity": "sha512-AVHPqQoZYc+RUM4/3Ly5udlZY/U4LS8pIG05jEjWM2lQMU/oaZ7qshzAl2YP1tfNmXfftH3ohurfwNAug+MnsQ==",
+ "version": "11.2.0",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-11.2.0.tgz",
+ "integrity": "sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
@@ -4615,17 +4678,18 @@
}
},
"node_modules/expect": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/expect/-/expect-30.2.0.tgz",
- "integrity": "sha512-u/feCi0GPsI+988gU2FLcsHyAHTU0MX1Wg68NhAnN7z/+C5wqG+CY8J53N9ioe8RXgaoz0nBR/TYMf3AycUuPw==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/expect/-/expect-30.3.0.tgz",
+ "integrity": "sha512-1zQrciTiQfRdo7qJM1uG4navm8DayFa2TgCSRlzUyNkhcJ6XUZF3hjnpkyr3VhAqPH7i/9GkG7Tv5abz6fqz0Q==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@jest/expect-utils": "30.2.0",
+ "@jest/expect-utils": "30.3.0",
"@jest/get-type": "30.1.0",
- "jest-matcher-utils": "30.2.0",
- "jest-message-util": "30.2.0",
- "jest-mock": "30.2.0",
- "jest-util": "30.2.0"
+ "jest-matcher-utils": "30.3.0",
+ "jest-message-util": "30.3.0",
+ "jest-mock": "30.3.0",
+ "jest-util": "30.3.0"
},
"engines": {
"node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
@@ -4679,6 +4743,7 @@
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"to-regex-range": "^5.0.1"
@@ -4719,9 +4784,9 @@
}
},
"node_modules/flatted": {
- "version": "3.3.4",
- "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.4.tgz",
- "integrity": "sha512-3+mMldrTAPdta5kjX2G2J7iX4zxtnwpdA8Tr2ZSjkyPSanvbZAcy6flmtnXbEybHrDcU9641lxrMfFuUxVz9vA==",
+ "version": "3.4.2",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz",
+ "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==",
"dev": true,
"license": "ISC"
},
@@ -4974,9 +5039,9 @@
"license": "MIT"
},
"node_modules/glob/node_modules/brace-expansion": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
- "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz",
+ "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5046,12 +5111,13 @@
"version": "4.2.11",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+ "dev": true,
"license": "ISC"
},
"node_modules/handlebars": {
- "version": "4.7.8",
- "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz",
- "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==",
+ "version": "4.7.9",
+ "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.9.tgz",
+ "integrity": "sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5087,6 +5153,7 @@
"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"
@@ -5592,6 +5659,7 @@
"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"
@@ -5894,16 +5962,16 @@
}
},
"node_modules/jest": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/jest/-/jest-30.2.0.tgz",
- "integrity": "sha512-F26gjC0yWN8uAA5m5Ss8ZQf5nDHWGlN/xWZIh8S5SRbsEKBovwZhxGd6LJlbZYxBgCYOtreSUyb8hpXyGC5O4A==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/jest/-/jest-30.3.0.tgz",
+ "integrity": "sha512-AkXIIFcaazymvey2i/+F94XRnM6TsVLZDhBMLsd1Sf/W0wzsvvpjeyUrCZD6HGG4SDYPgDJDBKeiJTBb10WzMg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@jest/core": "30.2.0",
- "@jest/types": "30.2.0",
+ "@jest/core": "30.3.0",
+ "@jest/types": "30.3.0",
"import-local": "^3.2.0",
- "jest-cli": "30.2.0"
+ "jest-cli": "30.3.0"
},
"bin": {
"jest": "bin/jest.js"
@@ -5921,14 +5989,14 @@
}
},
"node_modules/jest-changed-files": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-30.2.0.tgz",
- "integrity": "sha512-L8lR1ChrRnSdfeOvTrwZMlnWV8G/LLjQ0nG9MBclwWZidA2N5FviRki0Bvh20WRMOX31/JYvzdqTJrk5oBdydQ==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-30.3.0.tgz",
+ "integrity": "sha512-B/7Cny6cV5At6M25EWDgf9S617lHivamL8vl6KEpJqkStauzcG4e+WPfDgMMF+H4FVH4A2PLRyvgDJan4441QA==",
"dev": true,
"license": "MIT",
"dependencies": {
"execa": "^5.1.1",
- "jest-util": "30.2.0",
+ "jest-util": "30.3.0",
"p-limit": "^3.1.0"
},
"engines": {
@@ -5936,29 +6004,29 @@
}
},
"node_modules/jest-circus": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-30.2.0.tgz",
- "integrity": "sha512-Fh0096NC3ZkFx05EP2OXCxJAREVxj1BcW/i6EWqqymcgYKWjyyDpral3fMxVcHXg6oZM7iULer9wGRFvfpl+Tg==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-30.3.0.tgz",
+ "integrity": "sha512-PyXq5szeSfR/4f1lYqCmmQjh0vqDkURUYi9N6whnHjlRz4IUQfMcXkGLeEoiJtxtyPqgUaUUfyQlApXWBSN1RA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@jest/environment": "30.2.0",
- "@jest/expect": "30.2.0",
- "@jest/test-result": "30.2.0",
- "@jest/types": "30.2.0",
+ "@jest/environment": "30.3.0",
+ "@jest/expect": "30.3.0",
+ "@jest/test-result": "30.3.0",
+ "@jest/types": "30.3.0",
"@types/node": "*",
"chalk": "^4.1.2",
"co": "^4.6.0",
"dedent": "^1.6.0",
"is-generator-fn": "^2.1.0",
- "jest-each": "30.2.0",
- "jest-matcher-utils": "30.2.0",
- "jest-message-util": "30.2.0",
- "jest-runtime": "30.2.0",
- "jest-snapshot": "30.2.0",
- "jest-util": "30.2.0",
+ "jest-each": "30.3.0",
+ "jest-matcher-utils": "30.3.0",
+ "jest-message-util": "30.3.0",
+ "jest-runtime": "30.3.0",
+ "jest-snapshot": "30.3.0",
+ "jest-util": "30.3.0",
"p-limit": "^3.1.0",
- "pretty-format": "30.2.0",
+ "pretty-format": "30.3.0",
"pure-rand": "^7.0.0",
"slash": "^3.0.0",
"stack-utils": "^2.0.6"
@@ -5968,21 +6036,21 @@
}
},
"node_modules/jest-cli": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-30.2.0.tgz",
- "integrity": "sha512-Os9ukIvADX/A9sLt6Zse3+nmHtHaE6hqOsjQtNiugFTbKRHYIYtZXNGNK9NChseXy7djFPjndX1tL0sCTlfpAA==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-30.3.0.tgz",
+ "integrity": "sha512-l6Tqx+j1fDXJEW5bqYykDQQ7mQg+9mhWXtnj+tQZrTWYHyHoi6Be8HPumDSA+UiX2/2buEgjA58iJzdj146uCw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@jest/core": "30.2.0",
- "@jest/test-result": "30.2.0",
- "@jest/types": "30.2.0",
+ "@jest/core": "30.3.0",
+ "@jest/test-result": "30.3.0",
+ "@jest/types": "30.3.0",
"chalk": "^4.1.2",
"exit-x": "^0.2.2",
"import-local": "^3.2.0",
- "jest-config": "30.2.0",
- "jest-util": "30.2.0",
- "jest-validate": "30.2.0",
+ "jest-config": "30.3.0",
+ "jest-util": "30.3.0",
+ "jest-validate": "30.3.0",
"yargs": "^17.7.2"
},
"bin": {
@@ -6108,34 +6176,33 @@
}
},
"node_modules/jest-config": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-30.2.0.tgz",
- "integrity": "sha512-g4WkyzFQVWHtu6uqGmQR4CQxz/CH3yDSlhzXMWzNjDx843gYjReZnMRanjRCq5XZFuQrGDxgUaiYWE8BRfVckA==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-30.3.0.tgz",
+ "integrity": "sha512-WPMAkMAtNDY9P/oKObtsRG/6KTrhtgPJoBTmk20uDn4Uy6/3EJnnaZJre/FMT1KVRx8cve1r7/FlMIOfRVWL4w==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/core": "^7.27.4",
"@jest/get-type": "30.1.0",
"@jest/pattern": "30.0.1",
- "@jest/test-sequencer": "30.2.0",
- "@jest/types": "30.2.0",
- "babel-jest": "30.2.0",
+ "@jest/test-sequencer": "30.3.0",
+ "@jest/types": "30.3.0",
+ "babel-jest": "30.3.0",
"chalk": "^4.1.2",
"ci-info": "^4.2.0",
"deepmerge": "^4.3.1",
- "glob": "^10.3.10",
+ "glob": "^10.5.0",
"graceful-fs": "^4.2.11",
- "jest-circus": "30.2.0",
+ "jest-circus": "30.3.0",
"jest-docblock": "30.2.0",
- "jest-environment-node": "30.2.0",
+ "jest-environment-node": "30.3.0",
"jest-regex-util": "30.0.1",
- "jest-resolve": "30.2.0",
- "jest-runner": "30.2.0",
- "jest-util": "30.2.0",
- "jest-validate": "30.2.0",
- "micromatch": "^4.0.8",
+ "jest-resolve": "30.3.0",
+ "jest-runner": "30.3.0",
+ "jest-util": "30.3.0",
+ "jest-validate": "30.3.0",
"parse-json": "^5.2.0",
- "pretty-format": "30.2.0",
+ "pretty-format": "30.3.0",
"slash": "^3.0.0",
"strip-json-comments": "^3.1.1"
},
@@ -6160,15 +6227,16 @@
}
},
"node_modules/jest-diff": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.2.0.tgz",
- "integrity": "sha512-dQHFo3Pt4/NLlG5z4PxZ/3yZTZ1C7s9hveiOj+GCN+uT109NC2QgsoVZsVOAvbJ3RgKkvyLGXZV9+piDpWbm6A==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.3.0.tgz",
+ "integrity": "sha512-n3q4PDQjS4LrKxfWB3Z5KNk1XjXtZTBwQp71OP0Jo03Z6V60x++K5L8k6ZrW8MY8pOFylZvHM0zsjS1RqlHJZQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@jest/diff-sequences": "30.0.1",
+ "@jest/diff-sequences": "30.3.0",
"@jest/get-type": "30.1.0",
"chalk": "^4.1.2",
- "pretty-format": "30.2.0"
+ "pretty-format": "30.3.0"
},
"engines": {
"node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
@@ -6188,33 +6256,31 @@
}
},
"node_modules/jest-each": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-30.2.0.tgz",
- "integrity": "sha512-lpWlJlM7bCUf1mfmuqTA8+j2lNURW9eNafOy99knBM01i5CQeY5UH1vZjgT9071nDJac1M4XsbyI44oNOdhlDQ==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-30.3.0.tgz",
+ "integrity": "sha512-V8eMndg/aZ+3LnCJgSm13IxS5XSBM22QSZc9BtPK8Dek6pm+hfUNfwBdvsB3d342bo1q7wnSkC38zjX259qZNA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@jest/get-type": "30.1.0",
- "@jest/types": "30.2.0",
+ "@jest/types": "30.3.0",
"chalk": "^4.1.2",
- "jest-util": "30.2.0",
- "pretty-format": "30.2.0"
+ "jest-util": "30.3.0",
+ "pretty-format": "30.3.0"
},
"engines": {
"node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
"node_modules/jest-environment-jsdom": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-30.2.0.tgz",
- "integrity": "sha512-zbBTiqr2Vl78pKp/laGBREYzbZx9ZtqPjOK4++lL4BNDhxRnahg51HtoDrk9/VjIy9IthNEWdKVd7H5bqBhiWQ==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-30.3.0.tgz",
+ "integrity": "sha512-RLEOJy6ip1lpw0yqJ8tB3i88FC7VBz7i00Zvl2qF71IdxjS98gC9/0SPWYIBVXHm5hgCYK0PAlSlnHGGy9RoMg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@jest/environment": "30.2.0",
- "@jest/environment-jsdom-abstract": "30.2.0",
- "@types/jsdom": "^21.1.7",
- "@types/node": "*",
+ "@jest/environment": "30.3.0",
+ "@jest/environment-jsdom-abstract": "30.3.0",
"jsdom": "^26.1.0"
},
"engines": {
@@ -6230,40 +6296,40 @@
}
},
"node_modules/jest-environment-node": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-30.2.0.tgz",
- "integrity": "sha512-ElU8v92QJ9UrYsKrxDIKCxu6PfNj4Hdcktcn0JX12zqNdqWHB0N+hwOnnBBXvjLd2vApZtuLUGs1QSY+MsXoNA==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-30.3.0.tgz",
+ "integrity": "sha512-4i6HItw/JSiJVsC5q0hnKIe/hbYfZLVG9YJ/0pU9Hz2n/9qZe3Rhn5s5CUZA5ORZlcdT/vmAXRMyONXJwPrmYQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@jest/environment": "30.2.0",
- "@jest/fake-timers": "30.2.0",
- "@jest/types": "30.2.0",
+ "@jest/environment": "30.3.0",
+ "@jest/fake-timers": "30.3.0",
+ "@jest/types": "30.3.0",
"@types/node": "*",
- "jest-mock": "30.2.0",
- "jest-util": "30.2.0",
- "jest-validate": "30.2.0"
+ "jest-mock": "30.3.0",
+ "jest-util": "30.3.0",
+ "jest-validate": "30.3.0"
},
"engines": {
"node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
"node_modules/jest-haste-map": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.2.0.tgz",
- "integrity": "sha512-sQA/jCb9kNt+neM0anSj6eZhLZUIhQgwDt7cPGjumgLM4rXsfb9kpnlacmvZz3Q5tb80nS+oG/if+NBKrHC+Xw==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.3.0.tgz",
+ "integrity": "sha512-mMi2oqG4KRU0R9QEtscl87JzMXfUhbKaFqOxmjb2CKcbHcUGFrJCBWHmnTiUqi6JcnzoBlO4rWfpdl2k/RfLCA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@jest/types": "30.2.0",
+ "@jest/types": "30.3.0",
"@types/node": "*",
"anymatch": "^3.1.3",
"fb-watchman": "^2.0.2",
"graceful-fs": "^4.2.11",
"jest-regex-util": "30.0.1",
- "jest-util": "30.2.0",
- "jest-worker": "30.2.0",
- "micromatch": "^4.0.8",
+ "jest-util": "30.3.0",
+ "jest-worker": "30.3.0",
+ "picomatch": "^4.0.3",
"walker": "^1.0.8"
},
"engines": {
@@ -6273,48 +6339,63 @@
"fsevents": "^2.3.3"
}
},
+ "node_modules/jest-haste-map/node_modules/picomatch": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
+ "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
"node_modules/jest-leak-detector": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-30.2.0.tgz",
- "integrity": "sha512-M6jKAjyzjHG0SrQgwhgZGy9hFazcudwCNovY/9HPIicmNSBuockPSedAP9vlPK6ONFJ1zfyH/M2/YYJxOz5cdQ==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-30.3.0.tgz",
+ "integrity": "sha512-cuKmUUGIjfXZAiGJ7TbEMx0bcqNdPPI6P1V+7aF+m/FUJqFDxkFR4JqkTu8ZOiU5AaX/x0hZ20KaaIPXQzbMGQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@jest/get-type": "30.1.0",
- "pretty-format": "30.2.0"
+ "pretty-format": "30.3.0"
},
"engines": {
"node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
"node_modules/jest-matcher-utils": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.2.0.tgz",
- "integrity": "sha512-dQ94Nq4dbzmUWkQ0ANAWS9tBRfqCrn0bV9AMYdOi/MHW726xn7eQmMeRTpX2ViC00bpNaWXq+7o4lIQ3AX13Hg==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.3.0.tgz",
+ "integrity": "sha512-HEtc9uFQgaUHkC7nLSlQL3Tph4Pjxt/yiPvkIrrDCt9jhoLIgxaubo1G+CFOnmHYMxHwwdaSN7mkIFs6ZK8OhA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@jest/get-type": "30.1.0",
"chalk": "^4.1.2",
- "jest-diff": "30.2.0",
- "pretty-format": "30.2.0"
+ "jest-diff": "30.3.0",
+ "pretty-format": "30.3.0"
},
"engines": {
"node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
"node_modules/jest-message-util": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.2.0.tgz",
- "integrity": "sha512-y4DKFLZ2y6DxTWD4cDe07RglV88ZiNEdlRfGtqahfbIjfsw1nMCPx49Uev4IA/hWn3sDKyAnSPwoYSsAEdcimw==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.3.0.tgz",
+ "integrity": "sha512-Z/j4Bo+4ySJ+JPJN3b2Qbl9hDq3VrXmnjjGEWD/x0BCXeOXPTV1iZYYzl2X8c1MaCOL+ewMyNBcm88sboE6YWw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.27.1",
- "@jest/types": "30.2.0",
+ "@jest/types": "30.3.0",
"@types/stack-utils": "^2.0.3",
"chalk": "^4.1.2",
"graceful-fs": "^4.2.11",
- "micromatch": "^4.0.8",
- "pretty-format": "30.2.0",
+ "picomatch": "^4.0.3",
+ "pretty-format": "30.3.0",
"slash": "^3.0.0",
"stack-utils": "^2.0.6"
},
@@ -6322,15 +6403,29 @@
"node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
+ "node_modules/jest-message-util/node_modules/picomatch": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
+ "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
"node_modules/jest-mock": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.2.0.tgz",
- "integrity": "sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.3.0.tgz",
+ "integrity": "sha512-OTzICK8CpE+t4ndhKrwlIdbM6Pn8j00lvmSmq5ejiO+KxukbLjgOflKWMn3KE34EZdQm5RqTuKj+5RIEniYhog==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@jest/types": "30.2.0",
+ "@jest/types": "30.3.0",
"@types/node": "*",
- "jest-util": "30.2.0"
+ "jest-util": "30.3.0"
},
"engines": {
"node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
@@ -6358,24 +6453,25 @@
"version": "30.0.1",
"resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.0.1.tgz",
"integrity": "sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
"node_modules/jest-resolve": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-30.2.0.tgz",
- "integrity": "sha512-TCrHSxPlx3tBY3hWNtRQKbtgLhsXa1WmbJEqBlTBrGafd5fiQFByy2GNCEoGR+Tns8d15GaL9cxEzKOO3GEb2A==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-30.3.0.tgz",
+ "integrity": "sha512-NRtTAHQlpd15F9rUR36jqwelbrDV/dY4vzNte3S2kxCKUJRYNd5/6nTSbYiak1VX5g8IoFF23Uj5TURkUW8O5g==",
"dev": true,
"license": "MIT",
"dependencies": {
"chalk": "^4.1.2",
"graceful-fs": "^4.2.11",
- "jest-haste-map": "30.2.0",
+ "jest-haste-map": "30.3.0",
"jest-pnp-resolver": "^1.2.3",
- "jest-util": "30.2.0",
- "jest-validate": "30.2.0",
+ "jest-util": "30.3.0",
+ "jest-validate": "30.3.0",
"slash": "^3.0.0",
"unrs-resolver": "^1.7.11"
},
@@ -6384,46 +6480,46 @@
}
},
"node_modules/jest-resolve-dependencies": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-30.2.0.tgz",
- "integrity": "sha512-xTOIGug/0RmIe3mmCqCT95yO0vj6JURrn1TKWlNbhiAefJRWINNPgwVkrVgt/YaerPzY3iItufd80v3lOrFJ2w==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-30.3.0.tgz",
+ "integrity": "sha512-9ev8s3YN6Hsyz9LV75XUwkCVFlwPbaFn6Wp75qnI0wzAINYWY8Fb3+6y59Rwd3QaS3kKXffHXsZMziMavfz/nw==",
"dev": true,
"license": "MIT",
"dependencies": {
"jest-regex-util": "30.0.1",
- "jest-snapshot": "30.2.0"
+ "jest-snapshot": "30.3.0"
},
"engines": {
"node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
"node_modules/jest-runner": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-30.2.0.tgz",
- "integrity": "sha512-PqvZ2B2XEyPEbclp+gV6KO/F1FIFSbIwewRgmROCMBo/aZ6J1w8Qypoj2pEOcg3G2HzLlaP6VUtvwCI8dM3oqQ==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-30.3.0.tgz",
+ "integrity": "sha512-gDv6C9LGKWDPLia9TSzZwf4h3kMQCqyTpq+95PODnTRDO0g9os48XIYYkS6D236vjpBir2fF63YmJFtqkS5Duw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@jest/console": "30.2.0",
- "@jest/environment": "30.2.0",
- "@jest/test-result": "30.2.0",
- "@jest/transform": "30.2.0",
- "@jest/types": "30.2.0",
+ "@jest/console": "30.3.0",
+ "@jest/environment": "30.3.0",
+ "@jest/test-result": "30.3.0",
+ "@jest/transform": "30.3.0",
+ "@jest/types": "30.3.0",
"@types/node": "*",
"chalk": "^4.1.2",
"emittery": "^0.13.1",
"exit-x": "^0.2.2",
"graceful-fs": "^4.2.11",
"jest-docblock": "30.2.0",
- "jest-environment-node": "30.2.0",
- "jest-haste-map": "30.2.0",
- "jest-leak-detector": "30.2.0",
- "jest-message-util": "30.2.0",
- "jest-resolve": "30.2.0",
- "jest-runtime": "30.2.0",
- "jest-util": "30.2.0",
- "jest-watcher": "30.2.0",
- "jest-worker": "30.2.0",
+ "jest-environment-node": "30.3.0",
+ "jest-haste-map": "30.3.0",
+ "jest-leak-detector": "30.3.0",
+ "jest-message-util": "30.3.0",
+ "jest-resolve": "30.3.0",
+ "jest-runtime": "30.3.0",
+ "jest-util": "30.3.0",
+ "jest-watcher": "30.3.0",
+ "jest-worker": "30.3.0",
"p-limit": "^3.1.0",
"source-map-support": "0.5.13"
},
@@ -6432,32 +6528,32 @@
}
},
"node_modules/jest-runtime": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-30.2.0.tgz",
- "integrity": "sha512-p1+GVX/PJqTucvsmERPMgCPvQJpFt4hFbM+VN3n8TMo47decMUcJbt+rgzwrEme0MQUA/R+1de2axftTHkKckg==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-30.3.0.tgz",
+ "integrity": "sha512-CgC+hIBJbuh78HEffkhNKcbXAytQViplcl8xupqeIWyKQF50kCQA8J7GeJCkjisC6hpnC9Muf8jV5RdtdFbGng==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@jest/environment": "30.2.0",
- "@jest/fake-timers": "30.2.0",
- "@jest/globals": "30.2.0",
+ "@jest/environment": "30.3.0",
+ "@jest/fake-timers": "30.3.0",
+ "@jest/globals": "30.3.0",
"@jest/source-map": "30.0.1",
- "@jest/test-result": "30.2.0",
- "@jest/transform": "30.2.0",
- "@jest/types": "30.2.0",
+ "@jest/test-result": "30.3.0",
+ "@jest/transform": "30.3.0",
+ "@jest/types": "30.3.0",
"@types/node": "*",
"chalk": "^4.1.2",
"cjs-module-lexer": "^2.1.0",
"collect-v8-coverage": "^1.0.2",
- "glob": "^10.3.10",
+ "glob": "^10.5.0",
"graceful-fs": "^4.2.11",
- "jest-haste-map": "30.2.0",
- "jest-message-util": "30.2.0",
- "jest-mock": "30.2.0",
+ "jest-haste-map": "30.3.0",
+ "jest-message-util": "30.3.0",
+ "jest-mock": "30.3.0",
"jest-regex-util": "30.0.1",
- "jest-resolve": "30.2.0",
- "jest-snapshot": "30.2.0",
- "jest-util": "30.2.0",
+ "jest-resolve": "30.3.0",
+ "jest-snapshot": "30.3.0",
+ "jest-util": "30.3.0",
"slash": "^3.0.0",
"strip-bom": "^4.0.0"
},
@@ -6466,9 +6562,9 @@
}
},
"node_modules/jest-snapshot": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-30.2.0.tgz",
- "integrity": "sha512-5WEtTy2jXPFypadKNpbNkZ72puZCa6UjSr/7djeecHWOu7iYhSXSnHScT8wBz3Rn8Ena5d5RYRcsyKIeqG1IyA==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-30.3.0.tgz",
+ "integrity": "sha512-f14c7atpb4O2DeNhwcvS810Y63wEn8O1HqK/luJ4F6M4NjvxmAKQwBUWjbExUtMxWJQ0wVgmCKymeJK6NZMnfQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6477,20 +6573,20 @@
"@babel/plugin-syntax-jsx": "^7.27.1",
"@babel/plugin-syntax-typescript": "^7.27.1",
"@babel/types": "^7.27.3",
- "@jest/expect-utils": "30.2.0",
+ "@jest/expect-utils": "30.3.0",
"@jest/get-type": "30.1.0",
- "@jest/snapshot-utils": "30.2.0",
- "@jest/transform": "30.2.0",
- "@jest/types": "30.2.0",
+ "@jest/snapshot-utils": "30.3.0",
+ "@jest/transform": "30.3.0",
+ "@jest/types": "30.3.0",
"babel-preset-current-node-syntax": "^1.2.0",
"chalk": "^4.1.2",
- "expect": "30.2.0",
+ "expect": "30.3.0",
"graceful-fs": "^4.2.11",
- "jest-diff": "30.2.0",
- "jest-matcher-utils": "30.2.0",
- "jest-message-util": "30.2.0",
- "jest-util": "30.2.0",
- "pretty-format": "30.2.0",
+ "jest-diff": "30.3.0",
+ "jest-matcher-utils": "30.3.0",
+ "jest-message-util": "30.3.0",
+ "jest-util": "30.3.0",
+ "pretty-format": "30.3.0",
"semver": "^7.7.2",
"synckit": "^0.11.8"
},
@@ -6512,26 +6608,28 @@
}
},
"node_modules/jest-util": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz",
- "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.3.0.tgz",
+ "integrity": "sha512-/jZDa00a3Sz7rdyu55NLrQCIrbyIkbBxareejQI315f/i8HjYN+ZWsDLLpoQSiUIEIyZF/R8fDg3BmB8AtHttg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@jest/types": "30.2.0",
+ "@jest/types": "30.3.0",
"@types/node": "*",
"chalk": "^4.1.2",
"ci-info": "^4.2.0",
"graceful-fs": "^4.2.11",
- "picomatch": "^4.0.2"
+ "picomatch": "^4.0.3"
},
"engines": {
"node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
"node_modules/jest-util/node_modules/picomatch": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
- "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
+ "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=12"
@@ -6541,18 +6639,18 @@
}
},
"node_modules/jest-validate": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-30.2.0.tgz",
- "integrity": "sha512-FBGWi7dP2hpdi8nBoWxSsLvBFewKAg0+uSQwBaof4Y4DPgBabXgpSYC5/lR7VmnIlSpASmCi/ntRWPbv7089Pw==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-30.3.0.tgz",
+ "integrity": "sha512-I/xzC8h5G+SHCb2P2gWkJYrNiTbeL47KvKeW5EzplkyxzBRBw1ssSHlI/jXec0ukH2q7x2zAWQm7015iusg62Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"@jest/get-type": "30.1.0",
- "@jest/types": "30.2.0",
+ "@jest/types": "30.3.0",
"camelcase": "^6.3.0",
"chalk": "^4.1.2",
"leven": "^3.1.0",
- "pretty-format": "30.2.0"
+ "pretty-format": "30.3.0"
},
"engines": {
"node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
@@ -6572,19 +6670,19 @@
}
},
"node_modules/jest-watcher": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-30.2.0.tgz",
- "integrity": "sha512-PYxa28dxJ9g777pGm/7PrbnMeA0Jr7osHP9bS7eJy9DuAjMgdGtxgf0uKMyoIsTWAkIbUW5hSDdJ3urmgXBqxg==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-30.3.0.tgz",
+ "integrity": "sha512-PJ1d9ThtTR8aMiBWUdcownq9mDdLXsQzJayTk4kmaBRHKvwNQn+ANveuhEBUyNI2hR1TVhvQ8D5kHubbzBHR/w==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@jest/test-result": "30.2.0",
- "@jest/types": "30.2.0",
+ "@jest/test-result": "30.3.0",
+ "@jest/types": "30.3.0",
"@types/node": "*",
"ansi-escapes": "^4.3.2",
"chalk": "^4.1.2",
"emittery": "^0.13.1",
- "jest-util": "30.2.0",
+ "jest-util": "30.3.0",
"string-length": "^4.0.2"
},
"engines": {
@@ -6592,15 +6690,15 @@
}
},
"node_modules/jest-worker": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.2.0.tgz",
- "integrity": "sha512-0Q4Uk8WF7BUwqXHuAjc23vmopWJw5WH7w2tqBoUOZpOjW/ZnR44GXXd1r82RvnmI2GZge3ivrYXk/BE2+VtW2g==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.3.0.tgz",
+ "integrity": "sha512-DrCKkaQwHexjRUFTmPzs7sHQe0TSj9nvDALKGdwmK5mW9v7j90BudWirKAJHt3QQ9Dhrg1F7DogPzhChppkJpQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/node": "*",
"@ungap/structured-clone": "^1.3.0",
- "jest-util": "30.2.0",
+ "jest-util": "30.3.0",
"merge-stream": "^2.0.0",
"supports-color": "^8.1.1"
},
@@ -6628,6 +6726,7 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "dev": true,
"license": "MIT"
},
"node_modules/js-yaml": {
@@ -6989,19 +7088,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/micromatch": {
- "version": "4.0.8",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
- "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
- "license": "MIT",
- "dependencies": {
- "braces": "^3.0.3",
- "picomatch": "^2.3.1"
- },
- "engines": {
- "node": ">=8.6"
- }
- },
"node_modules/mimic-fn": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
@@ -7013,13 +7099,13 @@
}
},
"node_modules/minimatch": {
- "version": "10.2.4",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz",
- "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==",
+ "version": "10.2.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz",
+ "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
- "brace-expansion": "^5.0.2"
+ "brace-expansion": "^5.0.5"
},
"engines": {
"node": "18 || 20 || >=22"
@@ -7108,9 +7194,9 @@
"license": "MIT"
},
"node_modules/node-releases": {
- "version": "2.0.36",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.36.tgz",
- "integrity": "sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==",
+ "version": "2.0.37",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.37.tgz",
+ "integrity": "sha512-1h5gKZCF+pO/o3Iqt5Jp7wc9rH3eJJ0+nh/CIoiRwjRxde/hAHyLPXYN4V3CqKAbiZPSeJFSWHmJsbkicta0Eg==",
"dev": true,
"license": "MIT"
},
@@ -7194,9 +7280,9 @@
"license": "MIT"
},
"node_modules/npm-run-all/node_modules/brace-expansion": {
- "version": "1.1.12",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
- "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+ "version": "1.1.13",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz",
+ "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -7653,12 +7739,14 @@
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "dev": true,
"license": "ISC"
},
"node_modules/picomatch": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
- "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz",
+ "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=8.6"
@@ -7790,9 +7878,10 @@
}
},
"node_modules/pretty-format": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz",
- "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz",
+ "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@jest/schemas": "30.0.5",
@@ -7807,6 +7896,7 @@
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=10"
@@ -7855,6 +7945,7 @@
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
"integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
+ "dev": true,
"license": "MIT"
},
"node_modules/read-pkg": {
@@ -8060,14 +8151,14 @@
"license": "MIT"
},
"node_modules/sass": {
- "version": "1.97.3",
- "resolved": "https://registry.npmjs.org/sass/-/sass-1.97.3.tgz",
- "integrity": "sha512-fDz1zJpd5GycprAbu4Q2PV/RprsRtKC/0z82z0JLgdytmcq0+ujJbJ/09bPGDxCLkKY3Np5cRAOcWiVkLXJURg==",
+ "version": "1.99.0",
+ "resolved": "https://registry.npmjs.org/sass/-/sass-1.99.0.tgz",
+ "integrity": "sha512-kgW13M54DUB7IsIRM5LvJkNlpH+WhMpooUcaWGFARkF1Tc82v9mIWkCbCYf+MBvpIUBSeSOTilpZjEPr2VYE6Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"chokidar": "^4.0.0",
- "immutable": "^5.0.2",
+ "immutable": "^5.1.5",
"source-map-js": ">=0.6.2 <2.0.0"
},
"bin": {
@@ -8246,14 +8337,14 @@
}
},
"node_modules/side-channel-list": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
- "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz",
+ "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==",
"dev": true,
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
- "object-inspect": "^1.13.3"
+ "object-inspect": "^1.13.4"
},
"engines": {
"node": ">= 0.4"
@@ -8318,6 +8409,7 @@
"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"
@@ -8416,6 +8508,7 @@
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz",
"integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"escape-string-regexp": "^2.0.0"
@@ -8428,6 +8521,7 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
"integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -8709,6 +8803,7 @@
"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"
@@ -8776,9 +8871,9 @@
"license": "MIT"
},
"node_modules/test-exclude/node_modules/brace-expansion": {
- "version": "1.1.12",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
- "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+ "version": "1.1.13",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz",
+ "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -8852,6 +8947,7 @@
"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"
@@ -8887,19 +8983,19 @@
}
},
"node_modules/ts-jest": {
- "version": "29.4.6",
- "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.6.tgz",
- "integrity": "sha512-fSpWtOO/1AjSNQguk43hb/JCo16oJDnMJf3CdEGNkqsEX3t0KX96xvyX1D7PfLCpVoKu4MfVrqUkFyblYoY4lA==",
+ "version": "29.4.9",
+ "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.9.tgz",
+ "integrity": "sha512-LTb9496gYPMCqjeDLdPrKuXtncudeV1yRZnF4Wo5l3SFi0RYEnYRNgMrFIdg+FHvfzjCyQk1cLncWVqiSX+EvQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"bs-logger": "^0.2.6",
"fast-json-stable-stringify": "^2.1.0",
- "handlebars": "^4.7.8",
+ "handlebars": "^4.7.9",
"json5": "^2.2.3",
"lodash.memoize": "^4.1.2",
"make-error": "^1.3.6",
- "semver": "^7.7.3",
+ "semver": "^7.7.4",
"type-fest": "^4.41.0",
"yargs-parser": "^21.1.1"
},
@@ -8916,7 +9012,7 @@
"babel-jest": "^29.0.0 || ^30.0.0",
"jest": "^29.0.0 || ^30.0.0",
"jest-util": "^29.0.0 || ^30.0.0",
- "typescript": ">=4.3 <6"
+ "typescript": ">=4.3 <7"
},
"peerDependenciesMeta": {
"@babel/core": {
@@ -9132,9 +9228,9 @@
}
},
"node_modules/typescript": {
- "version": "5.9.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
- "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.2.tgz",
+ "integrity": "sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ==",
"dev": true,
"license": "Apache-2.0",
"bin": {
@@ -9188,6 +9284,7 @@
"version": "7.18.2",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz",
"integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==",
+ "dev": true,
"license": "MIT"
},
"node_modules/unrs-resolver": {
@@ -9622,9 +9719,9 @@
}
},
"node_modules/ws": {
- "version": "8.19.0",
- "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz",
- "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==",
+ "version": "8.20.0",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.0.tgz",
+ "integrity": "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==",
"dev": true,
"license": "MIT",
"engines": {
diff --git a/package.json b/package.json
index 45c275863..2ffebc36a 100644
--- a/package.json
+++ b/package.json
@@ -15,27 +15,29 @@
"lint": "eslint \"resources/**/*.js\" \"resources/**/*.mjs\"",
"fix": "eslint --fix \"resources/**/*.js\" \"resources/**/*.mjs\"",
"ts:lint": "tsc --noEmit",
- "test": "jest"
+ "test": "jest",
+ "test:ci": "jest --maxWorkers=1"
},
"devDependencies": {
"@eslint/js": "^10.0.1",
"@lezer/generator": "^1.8.0",
+ "@types/jest": "^30.0.0",
"@types/markdown-it": "^14.1.2",
"@types/sortablejs": "^1.15.9",
"chokidar-cli": "^3.0",
- "esbuild": "^0.27.3",
- "eslint": "^10.0.2",
+ "esbuild": "^0.28.0",
+ "eslint": "^10.2.0",
"globals": "^17.4.0",
- "jest": "^30.2.0",
- "jest-environment-jsdom": "^30.2.0",
+ "jest": "^30.3.0",
+ "jest-environment-jsdom": "^30.3.0",
"npm-run-all": "^4.1.5",
- "sass": "^1.97.3",
- "ts-jest": "^29.4.6",
+ "sass": "^1.99.0",
+ "ts-jest": "^29.4.9",
"ts-node": "^10.9.2",
- "typescript": "5.9.*"
+ "typescript": "6.0.*"
},
"dependencies": {
- "@codemirror/commands": "^6.10.2",
+ "@codemirror/commands": "^6.10.3",
"@codemirror/lang-css": "^6.3.1",
"@codemirror/lang-html": "^6.4.11",
"@codemirror/lang-javascript": "^6.2.5",
@@ -43,15 +45,14 @@
"@codemirror/lang-markdown": "^6.5.0",
"@codemirror/lang-php": "^6.0.2",
"@codemirror/lang-xml": "^6.1.0",
- "@codemirror/language": "^6.12.2",
+ "@codemirror/language": "^6.12.3",
"@codemirror/legacy-modes": "^6.5.2",
- "@codemirror/state": "^6.5.4",
+ "@codemirror/state": "^6.6.0",
"@codemirror/theme-one-dark": "^6.1.3",
- "@codemirror/view": "^6.39.16",
+ "@codemirror/view": "^6.41.0",
"@lezer/highlight": "^1.2.3",
"@ssddanbrown/codemirror-lang-smarty": "^1.0.0",
"@ssddanbrown/codemirror-lang-twig": "^1.0.0",
- "@types/jest": "^30.0.0",
"codemirror": "^6.0.2",
"idb-keyval": "^6.2.2",
"markdown-it": "^14.1.1",
diff --git a/phpstan.neon.dist b/phpstan.neon.dist
index 72189222f..bab28ea0e 100644
--- a/phpstan.neon.dist
+++ b/phpstan.neon.dist
@@ -7,11 +7,11 @@ parameters:
- app
# The level 8 is the highest level
- level: 3
+ level: 4
phpVersion:
min: 80200
- max: 80400
+ max: 80500
bootstrapFiles:
- bootstrap/phpstan.php
diff --git a/phpunit.xml b/phpunit.xml
index 94fc002b7..55d84d129 100644
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -18,6 +18,8 @@
[](https://source.bookstackapp.com/)
-[](https://gh-stats.bookstackapp.com/)
-[](https://www.bookstackapp.com/links/discord)
+[](https://community.bookstackapp.com/)
[](https://www.bookstackapp.com/links/mastodon)
[](https://foss.video/c/bookstack)
@@ -20,18 +19,17 @@ A platform for storing and organising information and documentation. Details for
* [Installation Instructions](https://www.bookstackapp.com/docs/admin/installation)
* [Documentation](https://www.bookstackapp.com/docs)
* [Demo Instance](https://demo.bookstackapp.com)
- * [Admin Login](https://demo.bookstackapp.com/login?email=admin@example.com&password=password)
* [Screenshots](https://www.bookstackapp.com/#screenshots)
* [BookStack Blog](https://www.bookstackapp.com/blog)
-* [Issue List](https://github.com/BookStackApp/BookStack/issues)
-* [Discord Chat](https://www.bookstackapp.com/links/discord)
+* [Issue List](https://codeberg.org/bookstack/bookstack/issues)
+* [Community Discussions](https://community.bookstackapp.com/)
* [Support Options](https://www.bookstackapp.com/support/)
## 📚 Project Definition
BookStack is an opinionated documentation platform that provides a pleasant and simple out-of-the-box experience. New users to an instance should find the experience intuitive and only basic word-processing skills should be required to get involved in creating content on BookStack. The platform should provide advanced power features to those that desire it, but they should not interfere with the core simple user experience.
-BookStack is not designed as an extensible platform to be used for purposes that differ to the statement above.
+BookStack is not designed as an extensible platform to be used for purposes that differ from the statement above.
In regard to development philosophy, BookStack has a relaxed, open & positive approach. We aim to slowly yet continuously evolve the platform while providing a stable & easy upgrade path.
@@ -72,7 +70,7 @@ Big thanks to these companies for supporting the project.
-
+
@@ -113,19 +111,20 @@ Translations for text within BookStack are managed through the [BookStack projec
Please use [Crowdin](https://crowdin.com/project/bookstack) to contribute translations instead of opening a pull request. The translations within the working codebase can be out-of-date, and merging via code can cause conflicts & sync issues. If for some reason you can't use Crowdin feel free to open an issue to discuss alternative options.
-If you'd like a new language to be added to Crowdin, for you to be able to provide translations for, please [open a new issue here](https://github.com/BookStackApp/BookStack/issues/new?template=language_request.yml).
+If you'd like a new language to be added to Crowdin, for you to be able to provide translations for, please [open a new issue here](https://codeberg.org/bookstack/bookstack/issues/new?template=.forgejo%2fISSUE_TEMPLATE%2flanguage_request.yml).
-Please note, translations in BookStack are provided to the "Crowdin Global Translation Memory" which helps BookStack and other projects with finding translations. If you are not happy with contributing to this then providing translations to BookStack, even manually via GitHub, is not advised.
+Please note, translations in BookStack are provided to the "Crowdin Global Translation Memory" which helps BookStack and other projects with finding translations. If you are not happy with contributing to this then providing translations to BookStack, even manually via code, is not advised.
## 🎁 Contributing, Issues & Pull Requests
-Feel free to [create issues](https://github.com/BookStackApp/BookStack/issues/new/choose) to request new features or to report bugs & problems. Just please follow the template given when creating the issue.
+Feel free to [create issues](https://codeberg.org/bookstack/bookstack/issues/new/choose) to request new features or to report bugs & problems. Just please follow the template given when creating the issue.
Pull requests are welcome but, unless it's a small tweak, it may be best to open the pull request early or create an issue for your intended change to discuss how it will fit into the project and plan out the merge. Just because a feature request exists, or is tagged, does not mean that feature would be accepted into the core project.
Pull requests should be created from the `development` branch since they will be merged back into `development` once done. Please do not build from or request a merge into the `release` branch as this is only for publishing releases. If you are looking to alter CSS or JavaScript content please edit the source files found in `resources/`. Any CSS or JS files within `public` are built from these source files and therefore should not be edited directly.
+See the [Development & Testing](#-development--testing) section above for further development guidance.
-The project's code of conduct [can be found here](https://github.com/BookStackApp/BookStack/blob/development/.github/CODE_OF_CONDUCT.md).
+The project's community rules, including those for raising issues and making code contributions, [can be found here](https://www.bookstackapp.com/about/community-rules/).
## 🔒 Security
@@ -133,7 +132,7 @@ Security information for administering a BookStack instance can be found on the
If you'd like to be notified of new potential security concerns you can [sign-up to the BookStack security mailing list](https://updates.bookstackapp.com/signup/bookstack-security-updates).
-If you would like to report a security concern, details of doing so [can be found here](https://github.com/BookStackApp/BookStack/blob/development/.github/SECURITY.md).
+If you would like to report a security concern, details of doing so [can be found here](.forgejo/SECURITY.md).
## ♿ Accessibility
@@ -141,18 +140,18 @@ We want BookStack to remain accessible to as many people as possible. We aim for
## 🖥️ Website, Docs & Blog
-The website which contains the project docs & blog can be found in the [BookStackApp/website](https://codeberg.org/bookstack/website) repo.
+The website which contains the project docs & blog can be found in the [bookstack/website](https://codeberg.org/bookstack/website) repo.
## ⚖️ License
-The BookStack source is provided under the [MIT License](https://github.com/BookStackApp/BookStack/blob/development/LICENSE).
+The BookStack source is provided under the [MIT License](https://codeberg.org/bookstack/bookstack/src/branch/development/LICENSE).
The libraries used by, and included with, BookStack are provided under their own licenses and copyright.
The licenses for many of our core dependencies can be found in the attribution list below, but this is not an exhaustive list of all projects used within BookStack.
## 👪 Attribution
-The great people that have worked to build and improve BookStack can [be seen here](https://github.com/BookStackApp/BookStack/graphs/contributors). The wonderful people that have provided translations, either through GitHub or via Crowdin [can be seen here](https://github.com/BookStackApp/BookStack/blob/development/.github/translators.txt).
+The great people that have worked to build and improve BookStack can [be seen here](https://codeberg.org/bookstack/bookstack/activity/contributors). The wonderful people that have provided translations, either through GitHub, Codeberg or via Crowdin [can be seen here](https://codeberg.org/bookstack/bookstack/src/branch/development/.github/translators.txt).
Below are the great open-source projects used to help build BookStack.
Note: This is not an exhaustive list of all libraries and projects that would be used in an active BookStack instance.
diff --git a/resources/icons/contents.svg b/resources/icons/contents.svg
new file mode 100644
index 000000000..3a315b431
--- /dev/null
+++ b/resources/icons/contents.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/icons/editor/table-header.svg b/resources/icons/editor/table-header.svg
new file mode 100644
index 000000000..e3cfcbb63
--- /dev/null
+++ b/resources/icons/editor/table-header.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/js/components/index.ts b/resources/js/components/index.ts
index 736d93f05..688877227 100644
--- a/resources/js/components/index.ts
+++ b/resources/js/components/index.ts
@@ -58,6 +58,7 @@ export {Tabs} from './tabs';
export {TagManager} from './tag-manager';
export {TemplateManager} from './template-manager';
export {ToggleSwitch} from './toggle-switch';
+export {ToolboxContents} from './toolbox-contents';
export {TriLayout} from './tri-layout';
export {UserSelect} from './user-select';
export {WebhookEvents} from './webhook-events';
diff --git a/resources/js/components/toolbox-contents.ts b/resources/js/components/toolbox-contents.ts
new file mode 100644
index 000000000..1cbaeda5d
--- /dev/null
+++ b/resources/js/components/toolbox-contents.ts
@@ -0,0 +1,152 @@
+import {Component} from "./component";
+import {debounce} from "../services/util";
+import {EditorToolboxChangeEventData} from "./editor-toolbox";
+import {PageEditor} from "./page-editor";
+import {MarkdownEditor} from "./markdown-editor";
+import {WysiwygEditorTinymce} from "./wysiwyg-editor-tinymce";
+import {WysiwygEditor} from "./wysiwyg-editor";
+import {elem} from "../services/dom";
+import {patchDomFromDom} from "../services/vdom";
+
+interface ToolboxContentHeader {
+ // The text shown for the header
+ text: string;
+ // The level/depth of the header
+ level: number;
+ // The index of the header relative to all other headers in the content
+ index: number;
+ // The id set for the header (if at all)
+ id: string;
+}
+
+export class ToolboxContents extends Component {
+ protected container!: HTMLElement;
+ protected noneEl!: HTMLElement;
+ protected display!: HTMLElement;
+ protected isActive: boolean = false;
+
+ setup() {
+ this.container = this.$el as HTMLLinkElement;
+ this.noneEl = this.$refs.none;
+ this.display = this.$refs.display;
+
+ // Listen to when visible in the editor toolbox so we only update when visible
+ window.addEventListener('editor-toolbox-change', ((event: CustomEvent
+
`;
+
+ editor.updateAndCommit(() => {
+ const root = $getRoot();
+ root.append(...$htmlToBlockNodes(editor, input));
+ const list = root.getFirstChild() as ListNode;
+ const itemB = list.getChildAtIndex(1) as ListItemNode;
+
+ newItem = itemB.insertNewAfter($createRangeSelection());
+ });
+
+ expect(newItem).toBeInstanceOf(ParagraphNode);
+
+ expectNodeShapeToMatch(editor, [
+ {
+ type: 'list',
+ children: [{type: 'listitem', children: [{text: 'Item A'}]}],
+ },
+ {
+ type: 'paragraph',
+ },
+ {
+ type: 'list',
+ children: [{type: 'listitem', children: [{text: 'Item C'}]}],
+ }
+ ])
+ });
+
+ test('new items after last empty top-level inserts a new paragraph below, and removes the list item', () => {
+ let newItem: LexicalNode|null = null;
+ const input = `
+
`;
+
+ editor.updateAndCommit(() => {
+ const root = $getRoot();
+ root.append(...$htmlToBlockNodes(editor, input));
+ const list = root.getFirstChild() as ListNode;
+ const itemC = list.getChildAtIndex(2) as ListItemNode;
+
+ newItem = itemC.insertNewAfter($createRangeSelection());
+ });
+
+ expect(newItem).toBeInstanceOf(ParagraphNode);
+
+ expectNodeShapeToMatch(editor, [
+ {
+ type: 'list',
+ children: [{type: 'listitem', children: [{text: 'Item A'}]}, {type: 'listitem', children: [{text: 'Item B'}]}],
+ },
+ {
+ type: 'paragraph',
+ },
+ ])
+ });
});
test('$createListItemNode()', async () => {
diff --git a/resources/js/wysiwyg/lexical/list/formatList.ts b/resources/js/wysiwyg/lexical/list/formatList.ts
index aa0d5d611..5c7b81b7a 100644
--- a/resources/js/wysiwyg/lexical/list/formatList.ts
+++ b/resources/js/wysiwyg/lexical/list/formatList.ts
@@ -25,12 +25,14 @@ import invariant from 'lexical/shared/invariant';
import {
$createListItemNode,
- $createListNode,
$isListItemNode,
- $isListNode,
ListItemNode,
+} from './LexicalListItemNode';
+import {
+ $createListNode,
+ $isListNode,
ListNode,
-} from './';
+} from './LexicalListNode';
import {ListType} from './LexicalListNode';
import {
$getAllListItems,
diff --git a/resources/js/wysiwyg/lexical/list/index.ts b/resources/js/wysiwyg/lexical/list/index.ts
index 157fe79de..00e33c115 100644
--- a/resources/js/wysiwyg/lexical/list/index.ts
+++ b/resources/js/wysiwyg/lexical/list/index.ts
@@ -8,7 +8,10 @@
import type {SerializedListItemNode} from './LexicalListItemNode';
import type {ListType, SerializedListNode} from './LexicalListNode';
-import type {LexicalCommand} from 'lexical';
+import {
+ $getSelection,
+ $isRangeSelection, COMMAND_PRIORITY_NORMAL, INSERT_PARAGRAPH_COMMAND, LexicalCommand, LexicalEditor
+} from 'lexical';
import {createCommand} from 'lexical';
@@ -20,6 +23,8 @@ import {
} from './LexicalListItemNode';
import {$createListNode, $isListNode, ListNode} from './LexicalListNode';
import {$getListDepth} from './utils';
+import {mergeRegister} from "@lexical/utils";
+import {$getAncestor, INTERNAL_$isBlock} from "lexical/LexicalUtils";
export {
$createListItemNode,
@@ -48,3 +53,34 @@ export const INSERT_CHECK_LIST_COMMAND: LexicalCommand
');
+ await Promise.resolve().then();
+
+ expectNodeShapeToMatch(editor, [
+ {
+ type: 'list',
+ children: [
+ { type: 'listitem', children: [{ text: 'Item A' }] },
+ { type: 'listitem', children: [{ text: 'Item B' }] },
+ ],
+ },
+ ]);
+ });
+ });
+});
diff --git a/resources/js/wysiwyg/utils/actions.ts b/resources/js/wysiwyg/utils/actions.ts
index e18ac515f..c1d819f22 100644
--- a/resources/js/wysiwyg/utils/actions.ts
+++ b/resources/js/wysiwyg/utils/actions.ts
@@ -1,6 +1,7 @@
-import {$getRoot, $getSelection, $insertNodes, $isBlockElementNode, LexicalEditor} from "lexical";
+import {$createParagraphNode, $getRoot, $getSelection, $insertNodes, $isBlockElementNode, LexicalEditor} from "lexical";
import {$generateHtmlFromNodes} from "@lexical/html";
-import {$getNearestNodeBlockParent, $htmlToBlockNodes, $htmlToNodes} from "./nodes";
+import {$getAllNodesOfType, $getNearestNodeBlockParent, $htmlToBlockNodes, $htmlToNodes} from "./nodes";
+import {$isHeadingNode} from "@lexical/rich-text/LexicalHeadingNode";
export function setEditorContentFromHtml(editor: LexicalEditor, html: string) {
editor.update(() => {
@@ -12,6 +13,12 @@ export function setEditorContentFromHtml(editor: LexicalEditor, html: string) {
const nodes = $htmlToBlockNodes(editor, html);
root.append(...nodes);
+
+ // Always ensure we at least have a paragraph in the root
+ // as a target for the cursor/focus/actions.
+ if (root.isEmpty()) {
+ root.append($createParagraphNode());
+ }
});
}
@@ -85,5 +92,24 @@ export function getEditorContentAsHtml(editor: LexicalEditor): Promise
- @if($endpoint['controller_method_kebab'] === 'list')
+ @if(str_starts_with($endpoint['controller_method_kebab'], 'list') && !str_contains($endpoint['uri'], '{'))
{{ url($endpoint['uri']) }}
@else
{{ url($endpoint['uri']) }}
diff --git a/resources/views/api-docs/parts/getting-started.blade.php b/resources/views/api-docs/parts/getting-started.blade.php
index 663389047..8a14befa5 100644
--- a/resources/views/api-docs/parts/getting-started.blade.php
+++ b/resources/views/api-docs/parts/getting-started.blade.php
@@ -2,7 +2,7 @@
- Examples of API usage, in a variety of programming languages, can be found in the BookStack api-scripts repo on GitHub.
+ Examples of API usage, in a variety of programming languages, can be found in the BookStack api-scripts repo on Codeberg.
Some alternative options for extension and customization can be found below:
@@ -14,11 +14,11 @@
HTTP POST calls upon events occurring in BookStack.
{{ trans('entities.books_sort') }}
{{ trans('entities.page_contents') }}
+
+ {{ trans('settings.system_version') }}
diff --git a/resources/views/settings/roles/parts/form.blade.php b/resources/views/settings/roles/parts/form.blade.php
index 5a9eca7d2..890f79057 100644
--- a/resources/views/settings/roles/parts/form.blade.php
+++ b/resources/views/settings/roles/parts/form.blade.php
@@ -79,6 +79,7 @@
@include('settings.roles.parts.asset-permissions-row', ['title' => trans('entities.books'), 'permissionPrefix' => 'book'])
@include('settings.roles.parts.asset-permissions-row', ['title' => trans('entities.chapters'), 'permissionPrefix' => 'chapter'])
@include('settings.roles.parts.asset-permissions-row', ['title' => trans('entities.pages'), 'permissionPrefix' => 'page'])
+ @include('settings.roles.parts.revisions-permissions-row', ['title' => trans('entities.revisions'), 'permissionPrefix' => 'revision'])
@include('settings.roles.parts.related-asset-permissions-row', ['title' => trans('entities.images'), 'permissionPrefix' => 'image'])
@include('settings.roles.parts.related-asset-permissions-row', ['title' => trans('entities.attachments'), 'permissionPrefix' => 'attachment'])
@include('settings.roles.parts.related-asset-permissions-row', ['title' => trans('entities.comments'), 'permissionPrefix' => 'comment'])
diff --git a/resources/views/settings/roles/parts/revisions-permissions-row.blade.php b/resources/views/settings/roles/parts/revisions-permissions-row.blade.php
new file mode 100644
index 000000000..326925ef9
--- /dev/null
+++ b/resources/views/settings/roles/parts/revisions-permissions-row.blade.php
@@ -0,0 +1,22 @@
+
+ {{ trans('common.toggle_all') }}
+
+ -
+
+ @include('settings.roles.parts.checkbox', ['permission' => $permissionPrefix . '-view-all', 'label' => trans('settings.role_all')])
+
+ -
+
+ {{ trans('settings.role_controlled_by_page_delete') }}
+ Test
Test
codecode
',
+ ]);
+ $initialRevisionCount = $page->revisions()->count();
+ $page->refresh();
+
+ // Get the page content from the edit view to ensure we're using the
+ // exact same content which would be loaded into the editor.
+ $editView = $this->get($page->getUrl('/edit'));
+ $htmlContentEncoded = $this->withHtml($editView)->getInnerHtml('textarea#html-editor');
+ $htmlContent = html_entity_decode($htmlContentEncoded);
+
+ $this->asEditor()->put($page->getUrl(), [
+ 'name' => 'Stability Test',
+ 'html' => $htmlContent,
+ ]);
+
+ $this->assertEquals($initialRevisionCount, $page->revisions()->count());
+ }
}
diff --git a/tests/ErrorTest.php b/tests/ErrorTest.php
index 642945d43..27c83e212 100644
--- a/tests/ErrorTest.php
+++ b/tests/ErrorTest.php
@@ -2,7 +2,6 @@
namespace Tests;
-use Illuminate\Foundation\Http\Middleware\ValidatePostSize;
use Illuminate\Support\Facades\Log;
class ErrorTest extends TestCase
@@ -44,7 +43,7 @@ class ErrorTest extends TestCase
$this->actingAs($editor)->get($page->getUrl())->assertOk();
$this->permissions->disableEntityInheritedPermissions($book);
- $this->permissions->addEntityPermission($page, ['view'], $editor->roles()->first());
+ $this->permissions->setEntityPermissionsForRole($page, ['view'], $editor->roles()->first());
$resp = $this->actingAs($editor)->get($book->getUrl());
$resp->assertNotFound();
diff --git a/tests/Exports/HtmlExportTest.php b/tests/Exports/HtmlExportTest.php
index f23352e0e..223a8c922 100644
--- a/tests/Exports/HtmlExportTest.php
+++ b/tests/Exports/HtmlExportTest.php
@@ -5,6 +5,7 @@ namespace Tests\Exports;
use BookStack\Entities\Models\Book;
use BookStack\Entities\Models\Chapter;
use BookStack\Entities\Models\Page;
+use BookStack\Permissions\Permission;
use Illuminate\Support\Facades\Storage;
use Tests\TestCase;
@@ -229,6 +230,20 @@ class HtmlExportTest extends TestCase
$resp->assertDontSee('ExportWizardTheFifth');
}
+ public function test_page_export_only_includes_revision_count_if_user_has_revision_view_permissions()
+ {
+ $editor = $this->users->editor();
+ $page = $this->entities->page();
+
+ $resp = $this->actingAs($editor)->get($page->getUrl('/export/html'));
+ $resp->assertSee('Revision #');
+
+ $this->permissions->removeUserRolePermissions($editor, [Permission::RevisionViewAll]);
+
+ $resp = $this->actingAs($editor)->get($page->getUrl('/export/html'));
+ $resp->assertDontSee('Revision #');
+ }
+
public function test_html_exports_contain_csp_meta_tag()
{
$entities = [
diff --git a/tests/Exports/PdfExportTest.php b/tests/Exports/PdfExportTest.php
index f311f8457..78da3b0c2 100644
--- a/tests/Exports/PdfExportTest.php
+++ b/tests/Exports/PdfExportTest.php
@@ -79,6 +79,39 @@ class PdfExportTest extends TestCase
$this->assertStringContainsString('a
more <©> text with bold
+HTML; + $expected = <<
{{ trans('entities.page_contents_info') }}
+{{ trans('entities.page_contents_none') }}
+ +