diff --git a/.drone.yml b/.drone.yml index 95d4032413..1e21c43f39 100644 --- a/.drone.yml +++ b/.drone.yml @@ -100,7 +100,7 @@ steps: - name: checks-backend image: golang:1.19 commands: - - make checks-backend + - make --always-make checks-backend # ensure the 'go-licenses' make target runs depends_on: [deps-backend] volumes: - name: deps @@ -112,16 +112,11 @@ steps: - make test-frontend depends_on: [lint-frontend] - - name: generate-frontend - image: golang:1.19 - commands: - - make generate-frontend - - name: build-frontend image: node:18 commands: - make frontend - depends_on: [deps-frontend, generate-frontend] + depends_on: [deps-frontend] - name: build-backend-no-gcc image: golang:1.18 # this step is kept as the lowest version of golang that we support @@ -549,16 +544,11 @@ steps: commands: - make deps-frontend - - name: generate-frontend - image: golang:1.18 - commands: - - make generate-frontend - - name: build-frontend image: node:18 commands: - make frontend - depends_on: [deps-frontend, generate-frontend] + depends_on: [deps-frontend] - name: deps-backend image: golang:1.18 @@ -571,9 +561,9 @@ steps: # TODO: We should probably build all dependencies into a test image - name: test-e2e - image: mcr.microsoft.com/playwright:v1.24.0-focal + image: mcr.microsoft.com/playwright:v1.27.0-focal commands: - - curl -sLO https://go.dev/dl/go1.18.linux-amd64.tar.gz && tar -C /usr/local -xzf go1.18.linux-amd64.tar.gz + - curl -sLO https://go.dev/dl/go1.19.linux-amd64.tar.gz && tar -C /usr/local -xzf go1.19.linux-amd64.tar.gz - groupadd --gid 1001 gitea && useradd -m --gid 1001 --uid 1001 gitea - apt-get -qq update && apt-get -qqy install build-essential - export TEST_PGSQL_SCHEMA='' diff --git a/.eslintrc.yaml b/.eslintrc.yaml index a0d5655bbf..66d4452ec5 100644 --- a/.eslintrc.yaml +++ b/.eslintrc.yaml @@ -185,6 +185,7 @@ rules: linebreak-style: [2, unix] lines-around-comment: [0] lines-between-class-members: [0] + logical-assignment-operators: [0] max-classes-per-file: [0] max-depth: [0] max-len: [0] @@ -245,7 +246,7 @@ rules: no-floating-decimal: [0] no-func-assign: [2] no-global-assign: [2] - no-implicit-coercion: [0] + no-implicit-coercion: [2] no-implicit-globals: [0] no-implied-eval: [2] no-import-assign: [2] @@ -322,7 +323,7 @@ rules: no-unused-private-class-members: [2] no-unused-vars: [2, {args: all, argsIgnorePattern: ^_, varsIgnorePattern: ^_, caughtErrorsIgnorePattern: ^_, destructuredArrayIgnorePattern: ^_, ignoreRestSiblings: false}] no-use-before-define: [2, {functions: false, classes: true, variables: true, allowNamedExports: true}] - no-useless-backreference: [0] + no-useless-backreference: [2] no-useless-call: [2] no-useless-catch: [2] no-useless-computed-key: [2] @@ -353,7 +354,7 @@ rules: prefer-named-capture-group: [0] prefer-numeric-literals: [2] prefer-object-has-own: [0] - prefer-object-spread: [0] + prefer-object-spread: [2] prefer-promise-reject-errors: [2, {allowEmptyReject: false}] prefer-regex-literals: [2] prefer-rest-params: [2] @@ -455,6 +456,7 @@ rules: unicorn/no-static-only-class: [2] unicorn/no-thenable: [2] unicorn/no-this-assignment: [2] + unicorn/no-unnecessary-await: [2] unicorn/no-unreadable-array-destructuring: [0] unicorn/no-unreadable-iife: [2] unicorn/no-unsafe-regex: [0] @@ -519,6 +521,7 @@ rules: unicorn/require-number-to-fixed-digits-argument: [2] unicorn/require-post-message-target-origin: [0] unicorn/string-content: [0] + unicorn/switch-case-braces: [0] unicorn/template-indent: [2] unicorn/text-encoding-identifier-case: [0] unicorn/throw-new-error: [2] diff --git a/.gitattributes b/.gitattributes index bb2783b0ad..34482b9e8c 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,5 +1,6 @@ * text=auto eol=lf *.tmpl linguist-language=Handlebars +/assets/*.json linguist-generated /public/vendor/** -text -eol linguist-vendored /vendor/** -text -eol linguist-vendored /web_src/fomantic/build/** linguist-generated diff --git a/.gitpod.yml b/.gitpod.yml new file mode 100644 index 0000000000..55a12cc9e4 --- /dev/null +++ b/.gitpod.yml @@ -0,0 +1,39 @@ +tasks: + - name: Setup + init: | + make deps + make build + command: | + gp sync-done setup + exit 0 + - name: Run frontend + command: | + gp sync-await setup + make watch-frontend + - name: Run backend + command: | + gp sync-await setup + mkdir -p custom/conf/ + echo -e "[server]\nROOT_URL=$(gp url 3000)/" > custom/conf/app.ini + echo -e "\n[database]\nDB_TYPE = sqlite3\nPATH = $GITPOD_REPO_ROOT/data/gitea.db" >> custom/conf/app.ini + export TAGS="sqlite sqlite_unlock_notify" + make watch-backend + - name: Run docs + before: sudo bash -c "$(grep 'https://github.com/gohugoio/hugo/releases/download' Makefile | tr -d '\')" # install hugo + command: cd docs && make clean update && hugo server -D -F --baseUrl $(gp url 1313) --liveReloadPort=443 --appendPort=false --bind=0.0.0.0 + +vscode: + extensions: + - editorconfig.editorconfig + - dbaeumer.vscode-eslint + - golang.go + - stylelint.vscode-stylelint + - DavidAnson.vscode-markdownlint + - johnsoncodehk.volar + - ms-azuretools.vscode-docker + +ports: + - name: Gitea + port: 3000 + - name: Docs + port: 1313 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b13af805bc..4aff27fc65 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -170,17 +170,22 @@ import ( To maintain understandable code and avoid circular dependencies it is important to have a good structure of the code. The Gitea code is divided into the following parts: -- **integration:** Integration tests - **models:** Contains the data structures used by xorm to construct database tables. It also contains supporting functions to query and update the database. Dependencies to other code in Gitea should be avoided although some modules might be needed (for example for logging). - **models/fixtures:** Sample model data used in integration tests. - **models/migrations:** Handling of database migrations between versions. PRs that changes a database structure shall also have a migration step. -- **modules:** Different modules to handle specific functionality in Gitea. +- **modules:** Different modules to handle specific functionality in Gitea. Shall only depend on other modules but not other packages (models, services). - **public:** Frontend files (javascript, images, css, etc.) -- **routers:** Handling of server requests. As it uses other Gitea packages to serve the request, other packages (models, modules or services) shall not depend on routers +- **routers:** Handling of server requests. As it uses other Gitea packages to serve the request, other packages (models, modules or services) shall not depend on routers. - **services:** Support functions for common routing operations. Uses models and modules to handle the request. - **templates:** Golang templates for generating the html output. +- **tests/e2e:** End to end tests +- **tests/integration:** Integration tests - **vendor:** External code that Gitea depends on. +## Documentation + +If you add a new feature or change an existing aspect of Gitea, the documentation for that feature must be created or updated. + ## API v1 The API is documented by [swagger](http://try.gitea.io/api/swagger) and is based on [GitHub API v3](https://developer.github.com/v3/). @@ -229,27 +234,6 @@ An endpoint which changes/edits an object expects all fields to be optional (exc - support pagination (`page` & `limit` options in query) - set `X-Total-Count` header via **SetTotalCountHeader** ([example](https://github.com/go-gitea/gitea/blob/7aae98cc5d4113f1e9918b7ee7dd09f67c189e3e/routers/api/v1/repo/issue.go#L444)) -## Large Character Comments - -Throughout the codebase there are large-text comments for sections of code, e.g.: - -```go -// __________ .__ -// \______ \ _______ _|__| ______ _ __ -// | _// __ \ \/ / |/ __ \ \/ \/ / -// | | \ ___/\ /| \ ___/\ / -// |____|_ /\___ >\_/ |__|\___ >\/\_/ -// \/ \/ \/ -``` - -These were created using the `figlet` tool with the `graffiti` font. - -A simple way of creating these is to use the following: - -```bash -figlet -f graffiti Review | sed -e's+^+// +' - | xclip -sel clip -in -``` - ## Backports and Frontports Occasionally backports of PRs are required. diff --git a/Makefile b/Makefile index e258ac748f..9828275758 100644 --- a/Makefile +++ b/Makefile @@ -341,7 +341,7 @@ lint: lint-frontend lint-backend .PHONY: lint-frontend lint-frontend: node_modules - npx eslint --color --max-warnings=0 --ext js,vue web_src/js build *.config.js docs/assets/js tests/e2e/*.test.e2e.js tests/e2e/utils_e2e.js + npx eslint --color --max-warnings=0 --ext js,vue web_src/js build *.config.js docs/assets/js tests/e2e npx stylelint --color --max-warnings=0 web_src/less npx spectral lint -q -F hint $(SWAGGER_SPEC) npx markdownlint docs *.md @@ -406,6 +406,7 @@ unit-test-coverage: tidy: $(eval MIN_GO_VERSION := $(shell grep -Eo '^go\s+[0-9]+\.[0-9.]+' go.mod | cut -d' ' -f2)) $(GO) mod tidy -compat=$(MIN_GO_VERSION) + @$(MAKE) --no-print-directory $(GO_LICENSE_FILE) vendor: go.mod go.sum $(GO) mod vendor @@ -413,7 +414,7 @@ vendor: go.mod go.sum .PHONY: tidy-check tidy-check: tidy - @diff=$$(git diff go.mod go.sum); \ + @diff=$$(git diff go.mod go.sum $(GO_LICENSE_FILE)); \ if [ -n "$$diff" ]; then \ echo "Please run 'make tidy' and commit the result:"; \ echo "$${diff}"; \ @@ -709,17 +710,14 @@ install: $(wildcard *.go) build: frontend backend .PHONY: frontend -frontend: generate-frontend $(WEBPACK_DEST) +frontend: $(WEBPACK_DEST) .PHONY: backend backend: go-check generate-backend $(EXECUTABLE) # We generate the backend before the frontend in case we in future we want to generate things in the frontend from generated files in backend .PHONY: generate -generate: generate-backend generate-frontend - -.PHONY: generate-frontend -generate-frontend: $(GO_LICENSE_FILE) +generate: generate-backend .PHONY: generate-backend generate-backend: $(TAGS_PREREQ) generate-go diff --git a/README.md b/README.md index 80f1159aea..115cafb58d 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,12 @@ + + Contribute with Gitpod + diff --git a/README_ZH.md b/README_ZH.md index 2be3574267..0e58ad6d4a 100644 --- a/README_ZH.md +++ b/README_ZH.md @@ -33,6 +33,12 @@ + + Contribute with Gitpod + diff --git a/assets/go-licenses.json b/assets/go-licenses.json index 8d129557de..db0b00865e 100644 --- a/assets/go-licenses.json +++ b/assets/go-licenses.json @@ -75,8 +75,8 @@ "licenseText": "\n Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n\n TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n 1. Definitions.\n\n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n\n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n\n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" means (i) the power, direct or indirect, to cause the\n direction or management of such entity, whether by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\n outstanding shares, or (iii) beneficial ownership of such entity.\n\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n exercising permissions granted by this License.\n\n \"Source\" form shall mean the preferred form for making modifications,\n including but not limited to software source code, documentation\n source, and configuration files.\n\n \"Object\" form shall mean any form resulting from mechanical\n transformation or translation of a Source form, including but\n not limited to compiled object code, generated documentation,\n and conversions to other media types.\n\n \"Work\" shall mean the work of authorship, whether in Source or\n Object form, made available under the License, as indicated by a\n copyright notice that is included in or attached to the work\n (an example is provided in the Appendix below).\n\n \"Derivative Works\" shall mean any work, whether in Source or Object\n form, that is based on (or derived from) the Work and for which the\n editorial revisions, annotations, elaborations, or other modifications\n represent, as a whole, an original work of authorship. For the purposes\n of this License, Derivative Works shall not include works that remain\n separable from, or merely link (or bind by name) to the interfaces of,\n the Work and Derivative Works thereof.\n\n \"Contribution\" shall mean any work of authorship, including\n the original version of the Work and any modifications or additions\n to that Work or Derivative Works thereof, that is intentionally\n submitted to Licensor for inclusion in the Work by the copyright owner\n or by an individual or Legal Entity authorized to submit on behalf of\n the copyright owner. For the purposes of this definition, \"submitted\"\n means any form of electronic, verbal, or written communication sent\n to the Licensor or its representatives, including but not limited to\n communication on electronic mailing lists, source code control systems,\n and issue tracking systems that are managed by, or on behalf of, the\n Licensor for the purpose of discussing and improving the Work, but\n excluding communication that is conspicuously marked or otherwise\n designated in writing by the copyright owner as \"Not a Contribution.\"\n\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\n on behalf of whom a Contribution has been received by Licensor and\n subsequently incorporated within the Work.\n\n 2. Grant of Copyright License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright license to reproduce, prepare Derivative Works of,\n publicly display, publicly perform, sublicense, and distribute the\n Work and such Derivative Works in Source or Object form.\n\n 3. Grant of Patent License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n (except as stated in this section) patent license to make, have made,\n use, offer to sell, sell, import, and otherwise transfer the Work,\n where such license applies only to those patent claims licensable\n by such Contributor that are necessarily infringed by their\n Contribution(s) alone or by combination of their Contribution(s)\n with the Work to which such Contribution(s) was submitted. If You\n institute patent litigation against any entity (including a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n or a Contribution incorporated within the Work constitutes direct\n or contributory patent infringement, then any patent licenses\n granted to You under this License for that Work shall terminate\n as of the date such litigation is filed.\n\n 4. Redistribution. You may reproduce and distribute copies of the\n Work or Derivative Works thereof in any medium, with or without\n modifications, and in Source or Object form, provided that You\n meet the following conditions:\n\n (a) You must give any other recipients of the Work or\n Derivative Works a copy of this License; and\n\n (b) You must cause any modified files to carry prominent notices\n stating that You changed the files; and\n\n (c) You must retain, in the Source form of any Derivative Works\n that You distribute, all copyright, patent, trademark, and\n attribution notices from the Source form of the Work,\n excluding those notices that do not pertain to any part of\n the Derivative Works; and\n\n (d) If the Work includes a \"NOTICE\" text file as part of its\n distribution, then any Derivative Works that You distribute must\n include a readable copy of the attribution notices contained\n within such NOTICE file, excluding those notices that do not\n pertain to any part of the Derivative Works, in at least one\n of the following places: within a NOTICE text file distributed\n as part of the Derivative Works; within the Source form or\n documentation, if provided along with the Derivative Works; or,\n within a display generated by the Derivative Works, if and\n wherever such third-party notices normally appear. The contents\n of the NOTICE file are for informational purposes only and\n do not modify the License. You may add Your own attribution\n notices within Derivative Works that You distribute, alongside\n or as an addendum to the NOTICE text from the Work, provided\n that such additional attribution notices cannot be construed\n as modifying the License.\n\n You may add Your own copyright statement to Your modifications and\n may provide additional or different license terms and conditions\n for use, reproduction, or distribution of Your modifications, or\n for any such Derivative Works as a whole, provided Your use,\n reproduction, and distribution of the Work otherwise complies with\n the conditions stated in this License.\n\n 5. Submission of Contributions. Unless You explicitly state otherwise,\n any Contribution intentionally submitted for inclusion in the Work\n by You to the Licensor shall be under the terms and conditions of\n this License, without any additional terms or conditions.\n Notwithstanding the above, nothing herein shall supersede or modify\n the terms of any separate license agreement you may have executed\n with Licensor regarding such Contributions.\n\n 6. Trademarks. This License does not grant permission to use the trade\n names, trademarks, service marks, or product names of the Licensor,\n except as required for reasonable and customary use in describing the\n origin of the Work and reproducing the content of the NOTICE file.\n\n 7. Disclaimer of Warranty. Unless required by applicable law or\n agreed to in writing, Licensor provides the Work (and each\n Contributor provides its Contributions) on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n implied, including, without limitation, any warranties or conditions\n of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n PARTICULAR PURPOSE. You are solely responsible for determining the\n appropriateness of using or redistributing the Work and assume any\n risks associated with Your exercise of permissions under this License.\n\n 8. Limitation of Liability. In no event and under no legal theory,\n whether in tort (including negligence), contract, or otherwise,\n unless required by applicable law (such as deliberate and grossly\n negligent acts) or agreed to in writing, shall any Contributor be\n liable to You for damages, including any direct, indirect, special,\n incidental, or consequential damages of any character arising as a\n result of this License or out of the use or inability to use the\n Work (including but not limited to damages for loss of goodwill,\n work stoppage, computer failure or malfunction, or any and all\n other commercial damages or losses), even if such Contributor\n has been advised of the possibility of such damages.\n\n 9. Accepting Warranty or Additional Liability. While redistributing\n the Work or Derivative Works thereof, You may choose to offer,\n and charge a fee for, acceptance of support, warranty, indemnity,\n or other liability obligations and/or rights consistent with this\n License. However, in accepting such obligations, You may act only\n on Your own behalf and on Your sole responsibility, not on behalf\n of any other Contributor, and only if You agree to indemnify,\n defend, and hold each Contributor harmless for any liability\n incurred by, or claims asserted against, such Contributor by reason\n of your accepting any such warranty or additional liability.\n\n END OF TERMS AND CONDITIONS\n\n APPENDIX: How to apply the Apache License to your work.\n\n To apply the Apache License to your work, attach the following\n boilerplate notice, with the fields enclosed by brackets \"[]\"\n replaced with your own identifying information. (Don't include\n the brackets!) The text should be enclosed in the appropriate\n comment syntax for the file format. We also recommend that a\n file or class name and description of purpose be included on the\n same \"printed page\" as the copyright notice for easier\n identification within third-party archives.\n\n Copyright 2016 by the authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n\n================================================================================\n\nPortions of runcontainer.go are from the Go standard library, which is licensed\nunder:\n\nCopyright (c) 2009 The Go Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n * Redistributions of source code must retain the above copyright\n notice, this list of conditions and the following disclaimer.\n * Redistributions in binary form must reproduce the above\n copyright notice, this list of conditions and the following disclaimer\n in the documentation and/or other materials provided with the\n distribution.\n * Neither the name of Google Inc. nor the names of its\n contributors may be used to endorse or promote products derived from\n this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" }, { - "name": "github.com/alecthomas/chroma", - "path": "github.com/alecthomas/chroma/COPYING", + "name": "github.com/alecthomas/chroma/v2", + "path": "github.com/alecthomas/chroma/v2/COPYING", "licenseText": "Copyright (C) 2017 Alec Thomas\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\nof the Software, and to permit persons to whom the Software is furnished to do\nso, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n" }, { @@ -114,6 +114,11 @@ "path": "github.com/blevesearch/bleve_index_api/LICENSE", "licenseText": "\n Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n\n TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n 1. Definitions.\n\n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n\n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n\n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" means (i) the power, direct or indirect, to cause the\n direction or management of such entity, whether by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\n outstanding shares, or (iii) beneficial ownership of such entity.\n\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n exercising permissions granted by this License.\n\n \"Source\" form shall mean the preferred form for making modifications,\n including but not limited to software source code, documentation\n source, and configuration files.\n\n \"Object\" form shall mean any form resulting from mechanical\n transformation or translation of a Source form, including but\n not limited to compiled object code, generated documentation,\n and conversions to other media types.\n\n \"Work\" shall mean the work of authorship, whether in Source or\n Object form, made available under the License, as indicated by a\n copyright notice that is included in or attached to the work\n (an example is provided in the Appendix below).\n\n \"Derivative Works\" shall mean any work, whether in Source or Object\n form, that is based on (or derived from) the Work and for which the\n editorial revisions, annotations, elaborations, or other modifications\n represent, as a whole, an original work of authorship. For the purposes\n of this License, Derivative Works shall not include works that remain\n separable from, or merely link (or bind by name) to the interfaces of,\n the Work and Derivative Works thereof.\n\n \"Contribution\" shall mean any work of authorship, including\n the original version of the Work and any modifications or additions\n to that Work or Derivative Works thereof, that is intentionally\n submitted to Licensor for inclusion in the Work by the copyright owner\n or by an individual or Legal Entity authorized to submit on behalf of\n the copyright owner. For the purposes of this definition, \"submitted\"\n means any form of electronic, verbal, or written communication sent\n to the Licensor or its representatives, including but not limited to\n communication on electronic mailing lists, source code control systems,\n and issue tracking systems that are managed by, or on behalf of, the\n Licensor for the purpose of discussing and improving the Work, but\n excluding communication that is conspicuously marked or otherwise\n designated in writing by the copyright owner as \"Not a Contribution.\"\n\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\n on behalf of whom a Contribution has been received by Licensor and\n subsequently incorporated within the Work.\n\n 2. Grant of Copyright License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright license to reproduce, prepare Derivative Works of,\n publicly display, publicly perform, sublicense, and distribute the\n Work and such Derivative Works in Source or Object form.\n\n 3. Grant of Patent License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n (except as stated in this section) patent license to make, have made,\n use, offer to sell, sell, import, and otherwise transfer the Work,\n where such license applies only to those patent claims licensable\n by such Contributor that are necessarily infringed by their\n Contribution(s) alone or by combination of their Contribution(s)\n with the Work to which such Contribution(s) was submitted. If You\n institute patent litigation against any entity (including a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n or a Contribution incorporated within the Work constitutes direct\n or contributory patent infringement, then any patent licenses\n granted to You under this License for that Work shall terminate\n as of the date such litigation is filed.\n\n 4. Redistribution. You may reproduce and distribute copies of the\n Work or Derivative Works thereof in any medium, with or without\n modifications, and in Source or Object form, provided that You\n meet the following conditions:\n\n (a) You must give any other recipients of the Work or\n Derivative Works a copy of this License; and\n\n (b) You must cause any modified files to carry prominent notices\n stating that You changed the files; and\n\n (c) You must retain, in the Source form of any Derivative Works\n that You distribute, all copyright, patent, trademark, and\n attribution notices from the Source form of the Work,\n excluding those notices that do not pertain to any part of\n the Derivative Works; and\n\n (d) If the Work includes a \"NOTICE\" text file as part of its\n distribution, then any Derivative Works that You distribute must\n include a readable copy of the attribution notices contained\n within such NOTICE file, excluding those notices that do not\n pertain to any part of the Derivative Works, in at least one\n of the following places: within a NOTICE text file distributed\n as part of the Derivative Works; within the Source form or\n documentation, if provided along with the Derivative Works; or,\n within a display generated by the Derivative Works, if and\n wherever such third-party notices normally appear. The contents\n of the NOTICE file are for informational purposes only and\n do not modify the License. You may add Your own attribution\n notices within Derivative Works that You distribute, alongside\n or as an addendum to the NOTICE text from the Work, provided\n that such additional attribution notices cannot be construed\n as modifying the License.\n\n You may add Your own copyright statement to Your modifications and\n may provide additional or different license terms and conditions\n for use, reproduction, or distribution of Your modifications, or\n for any such Derivative Works as a whole, provided Your use,\n reproduction, and distribution of the Work otherwise complies with\n the conditions stated in this License.\n\n 5. Submission of Contributions. Unless You explicitly state otherwise,\n any Contribution intentionally submitted for inclusion in the Work\n by You to the Licensor shall be under the terms and conditions of\n this License, without any additional terms or conditions.\n Notwithstanding the above, nothing herein shall supersede or modify\n the terms of any separate license agreement you may have executed\n with Licensor regarding such Contributions.\n\n 6. Trademarks. This License does not grant permission to use the trade\n names, trademarks, service marks, or product names of the Licensor,\n except as required for reasonable and customary use in describing the\n origin of the Work and reproducing the content of the NOTICE file.\n\n 7. Disclaimer of Warranty. Unless required by applicable law or\n agreed to in writing, Licensor provides the Work (and each\n Contributor provides its Contributions) on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n implied, including, without limitation, any warranties or conditions\n of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n PARTICULAR PURPOSE. You are solely responsible for determining the\n appropriateness of using or redistributing the Work and assume any\n risks associated with Your exercise of permissions under this License.\n\n 8. Limitation of Liability. In no event and under no legal theory,\n whether in tort (including negligence), contract, or otherwise,\n unless required by applicable law (such as deliberate and grossly\n negligent acts) or agreed to in writing, shall any Contributor be\n liable to You for damages, including any direct, indirect, special,\n incidental, or consequential damages of any character arising as a\n result of this License or out of the use or inability to use the\n Work (including but not limited to damages for loss of goodwill,\n work stoppage, computer failure or malfunction, or any and all\n other commercial damages or losses), even if such Contributor\n has been advised of the possibility of such damages.\n\n 9. Accepting Warranty or Additional Liability. While redistributing\n the Work or Derivative Works thereof, You may choose to offer,\n and charge a fee for, acceptance of support, warranty, indemnity,\n or other liability obligations and/or rights consistent with this\n License. However, in accepting such obligations, You may act only\n on Your own behalf and on Your sole responsibility, not on behalf\n of any other Contributor, and only if You agree to indemnify,\n defend, and hold each Contributor harmless for any liability\n incurred by, or claims asserted against, such Contributor by reason\n of your accepting any such warranty or additional liability.\n\n END OF TERMS AND CONDITIONS\n\n APPENDIX: How to apply the Apache License to your work.\n\n To apply the Apache License to your work, attach the following\n boilerplate notice, with the fields enclosed by brackets \"[]\"\n replaced with your own identifying information. (Don't include\n the brackets!) The text should be enclosed in the appropriate\n comment syntax for the file format. We also recommend that a\n file or class name and description of purpose be included on the\n same \"printed page\" as the copyright notice for easier\n identification within third-party archives.\n\n Copyright [yyyy] [name of copyright owner]\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License." }, + { + "name": "github.com/blevesearch/geo", + "path": "github.com/blevesearch/geo/LICENSE", + "licenseText": "\n Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n\n TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n 1. Definitions.\n\n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n\n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n\n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" means (i) the power, direct or indirect, to cause the\n direction or management of such entity, whether by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\n outstanding shares, or (iii) beneficial ownership of such entity.\n\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n exercising permissions granted by this License.\n\n \"Source\" form shall mean the preferred form for making modifications,\n including but not limited to software source code, documentation\n source, and configuration files.\n\n \"Object\" form shall mean any form resulting from mechanical\n transformation or translation of a Source form, including but\n not limited to compiled object code, generated documentation,\n and conversions to other media types.\n\n \"Work\" shall mean the work of authorship, whether in Source or\n Object form, made available under the License, as indicated by a\n copyright notice that is included in or attached to the work\n (an example is provided in the Appendix below).\n\n \"Derivative Works\" shall mean any work, whether in Source or Object\n form, that is based on (or derived from) the Work and for which the\n editorial revisions, annotations, elaborations, or other modifications\n represent, as a whole, an original work of authorship. For the purposes\n of this License, Derivative Works shall not include works that remain\n separable from, or merely link (or bind by name) to the interfaces of,\n the Work and Derivative Works thereof.\n\n \"Contribution\" shall mean any work of authorship, including\n the original version of the Work and any modifications or additions\n to that Work or Derivative Works thereof, that is intentionally\n submitted to Licensor for inclusion in the Work by the copyright owner\n or by an individual or Legal Entity authorized to submit on behalf of\n the copyright owner. For the purposes of this definition, \"submitted\"\n means any form of electronic, verbal, or written communication sent\n to the Licensor or its representatives, including but not limited to\n communication on electronic mailing lists, source code control systems,\n and issue tracking systems that are managed by, or on behalf of, the\n Licensor for the purpose of discussing and improving the Work, but\n excluding communication that is conspicuously marked or otherwise\n designated in writing by the copyright owner as \"Not a Contribution.\"\n\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\n on behalf of whom a Contribution has been received by Licensor and\n subsequently incorporated within the Work.\n\n 2. Grant of Copyright License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright license to reproduce, prepare Derivative Works of,\n publicly display, publicly perform, sublicense, and distribute the\n Work and such Derivative Works in Source or Object form.\n\n 3. Grant of Patent License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n (except as stated in this section) patent license to make, have made,\n use, offer to sell, sell, import, and otherwise transfer the Work,\n where such license applies only to those patent claims licensable\n by such Contributor that are necessarily infringed by their\n Contribution(s) alone or by combination of their Contribution(s)\n with the Work to which such Contribution(s) was submitted. If You\n institute patent litigation against any entity (including a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n or a Contribution incorporated within the Work constitutes direct\n or contributory patent infringement, then any patent licenses\n granted to You under this License for that Work shall terminate\n as of the date such litigation is filed.\n\n 4. Redistribution. You may reproduce and distribute copies of the\n Work or Derivative Works thereof in any medium, with or without\n modifications, and in Source or Object form, provided that You\n meet the following conditions:\n\n (a) You must give any other recipients of the Work or\n Derivative Works a copy of this License; and\n\n (b) You must cause any modified files to carry prominent notices\n stating that You changed the files; and\n\n (c) You must retain, in the Source form of any Derivative Works\n that You distribute, all copyright, patent, trademark, and\n attribution notices from the Source form of the Work,\n excluding those notices that do not pertain to any part of\n the Derivative Works; and\n\n (d) If the Work includes a \"NOTICE\" text file as part of its\n distribution, then any Derivative Works that You distribute must\n include a readable copy of the attribution notices contained\n within such NOTICE file, excluding those notices that do not\n pertain to any part of the Derivative Works, in at least one\n of the following places: within a NOTICE text file distributed\n as part of the Derivative Works; within the Source form or\n documentation, if provided along with the Derivative Works; or,\n within a display generated by the Derivative Works, if and\n wherever such third-party notices normally appear. The contents\n of the NOTICE file are for informational purposes only and\n do not modify the License. You may add Your own attribution\n notices within Derivative Works that You distribute, alongside\n or as an addendum to the NOTICE text from the Work, provided\n that such additional attribution notices cannot be construed\n as modifying the License.\n\n You may add Your own copyright statement to Your modifications and\n may provide additional or different license terms and conditions\n for use, reproduction, or distribution of Your modifications, or\n for any such Derivative Works as a whole, provided Your use,\n reproduction, and distribution of the Work otherwise complies with\n the conditions stated in this License.\n\n 5. Submission of Contributions. Unless You explicitly state otherwise,\n any Contribution intentionally submitted for inclusion in the Work\n by You to the Licensor shall be under the terms and conditions of\n this License, without any additional terms or conditions.\n Notwithstanding the above, nothing herein shall supersede or modify\n the terms of any separate license agreement you may have executed\n with Licensor regarding such Contributions.\n\n 6. Trademarks. This License does not grant permission to use the trade\n names, trademarks, service marks, or product names of the Licensor,\n except as required for reasonable and customary use in describing the\n origin of the Work and reproducing the content of the NOTICE file.\n\n 7. Disclaimer of Warranty. Unless required by applicable law or\n agreed to in writing, Licensor provides the Work (and each\n Contributor provides its Contributions) on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n implied, including, without limitation, any warranties or conditions\n of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n PARTICULAR PURPOSE. You are solely responsible for determining the\n appropriateness of using or redistributing the Work and assume any\n risks associated with Your exercise of permissions under this License.\n\n 8. Limitation of Liability. In no event and under no legal theory,\n whether in tort (including negligence), contract, or otherwise,\n unless required by applicable law (such as deliberate and grossly\n negligent acts) or agreed to in writing, shall any Contributor be\n liable to You for damages, including any direct, indirect, special,\n incidental, or consequential damages of any character arising as a\n result of this License or out of the use or inability to use the\n Work (including but not limited to damages for loss of goodwill,\n work stoppage, computer failure or malfunction, or any and all\n other commercial damages or losses), even if such Contributor\n has been advised of the possibility of such damages.\n\n 9. Accepting Warranty or Additional Liability. While redistributing\n the Work or Derivative Works thereof, You may choose to offer,\n and charge a fee for, acceptance of support, warranty, indemnity,\n or other liability obligations and/or rights consistent with this\n License. However, in accepting such obligations, You may act only\n on Your own behalf and on Your sole responsibility, not on behalf\n of any other Contributor, and only if You agree to indemnify,\n defend, and hold each Contributor harmless for any liability\n incurred by, or claims asserted against, such Contributor by reason\n of your accepting any such warranty or additional liability.\n\n END OF TERMS AND CONDITIONS\n\n APPENDIX: How to apply the Apache License to your work.\n\n To apply the Apache License to your work, attach the following\n boilerplate notice, with the fields enclosed by brackets \"[]\"\n replaced with your own identifying information. (Don't include\n the brackets!) The text should be enclosed in the appropriate\n comment syntax for the file format. We also recommend that a\n file or class name and description of purpose be included on the\n same \"printed page\" as the copyright notice for easier\n identification within third-party archives.\n\n Copyright [yyyy] [name of copyright owner]\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n" + }, { "name": "github.com/blevesearch/go-porterstemmer", "path": "github.com/blevesearch/go-porterstemmer/LICENSE", @@ -404,6 +409,11 @@ "path": "github.com/golang-sql/sqlexp/LICENSE", "licenseText": "Copyright (c) 2017 The Go Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n * Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" }, + { + "name": "github.com/golang/geo", + "path": "github.com/golang/geo/LICENSE", + "licenseText": "\n Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n\n TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n 1. Definitions.\n\n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n\n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n\n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" means (i) the power, direct or indirect, to cause the\n direction or management of such entity, whether by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\n outstanding shares, or (iii) beneficial ownership of such entity.\n\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n exercising permissions granted by this License.\n\n \"Source\" form shall mean the preferred form for making modifications,\n including but not limited to software source code, documentation\n source, and configuration files.\n\n \"Object\" form shall mean any form resulting from mechanical\n transformation or translation of a Source form, including but\n not limited to compiled object code, generated documentation,\n and conversions to other media types.\n\n \"Work\" shall mean the work of authorship, whether in Source or\n Object form, made available under the License, as indicated by a\n copyright notice that is included in or attached to the work\n (an example is provided in the Appendix below).\n\n \"Derivative Works\" shall mean any work, whether in Source or Object\n form, that is based on (or derived from) the Work and for which the\n editorial revisions, annotations, elaborations, or other modifications\n represent, as a whole, an original work of authorship. For the purposes\n of this License, Derivative Works shall not include works that remain\n separable from, or merely link (or bind by name) to the interfaces of,\n the Work and Derivative Works thereof.\n\n \"Contribution\" shall mean any work of authorship, including\n the original version of the Work and any modifications or additions\n to that Work or Derivative Works thereof, that is intentionally\n submitted to Licensor for inclusion in the Work by the copyright owner\n or by an individual or Legal Entity authorized to submit on behalf of\n the copyright owner. For the purposes of this definition, \"submitted\"\n means any form of electronic, verbal, or written communication sent\n to the Licensor or its representatives, including but not limited to\n communication on electronic mailing lists, source code control systems,\n and issue tracking systems that are managed by, or on behalf of, the\n Licensor for the purpose of discussing and improving the Work, but\n excluding communication that is conspicuously marked or otherwise\n designated in writing by the copyright owner as \"Not a Contribution.\"\n\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\n on behalf of whom a Contribution has been received by Licensor and\n subsequently incorporated within the Work.\n\n 2. Grant of Copyright License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright license to reproduce, prepare Derivative Works of,\n publicly display, publicly perform, sublicense, and distribute the\n Work and such Derivative Works in Source or Object form.\n\n 3. Grant of Patent License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n (except as stated in this section) patent license to make, have made,\n use, offer to sell, sell, import, and otherwise transfer the Work,\n where such license applies only to those patent claims licensable\n by such Contributor that are necessarily infringed by their\n Contribution(s) alone or by combination of their Contribution(s)\n with the Work to which such Contribution(s) was submitted. If You\n institute patent litigation against any entity (including a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n or a Contribution incorporated within the Work constitutes direct\n or contributory patent infringement, then any patent licenses\n granted to You under this License for that Work shall terminate\n as of the date such litigation is filed.\n\n 4. Redistribution. You may reproduce and distribute copies of the\n Work or Derivative Works thereof in any medium, with or without\n modifications, and in Source or Object form, provided that You\n meet the following conditions:\n\n (a) You must give any other recipients of the Work or\n Derivative Works a copy of this License; and\n\n (b) You must cause any modified files to carry prominent notices\n stating that You changed the files; and\n\n (c) You must retain, in the Source form of any Derivative Works\n that You distribute, all copyright, patent, trademark, and\n attribution notices from the Source form of the Work,\n excluding those notices that do not pertain to any part of\n the Derivative Works; and\n\n (d) If the Work includes a \"NOTICE\" text file as part of its\n distribution, then any Derivative Works that You distribute must\n include a readable copy of the attribution notices contained\n within such NOTICE file, excluding those notices that do not\n pertain to any part of the Derivative Works, in at least one\n of the following places: within a NOTICE text file distributed\n as part of the Derivative Works; within the Source form or\n documentation, if provided along with the Derivative Works; or,\n within a display generated by the Derivative Works, if and\n wherever such third-party notices normally appear. The contents\n of the NOTICE file are for informational purposes only and\n do not modify the License. You may add Your own attribution\n notices within Derivative Works that You distribute, alongside\n or as an addendum to the NOTICE text from the Work, provided\n that such additional attribution notices cannot be construed\n as modifying the License.\n\n You may add Your own copyright statement to Your modifications and\n may provide additional or different license terms and conditions\n for use, reproduction, or distribution of Your modifications, or\n for any such Derivative Works as a whole, provided Your use,\n reproduction, and distribution of the Work otherwise complies with\n the conditions stated in this License.\n\n 5. Submission of Contributions. Unless You explicitly state otherwise,\n any Contribution intentionally submitted for inclusion in the Work\n by You to the Licensor shall be under the terms and conditions of\n this License, without any additional terms or conditions.\n Notwithstanding the above, nothing herein shall supersede or modify\n the terms of any separate license agreement you may have executed\n with Licensor regarding such Contributions.\n\n 6. Trademarks. This License does not grant permission to use the trade\n names, trademarks, service marks, or product names of the Licensor,\n except as required for reasonable and customary use in describing the\n origin of the Work and reproducing the content of the NOTICE file.\n\n 7. Disclaimer of Warranty. Unless required by applicable law or\n agreed to in writing, Licensor provides the Work (and each\n Contributor provides its Contributions) on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n implied, including, without limitation, any warranties or conditions\n of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n PARTICULAR PURPOSE. You are solely responsible for determining the\n appropriateness of using or redistributing the Work and assume any\n risks associated with Your exercise of permissions under this License.\n\n 8. Limitation of Liability. In no event and under no legal theory,\n whether in tort (including negligence), contract, or otherwise,\n unless required by applicable law (such as deliberate and grossly\n negligent acts) or agreed to in writing, shall any Contributor be\n liable to You for damages, including any direct, indirect, special,\n incidental, or consequential damages of any character arising as a\n result of this License or out of the use or inability to use the\n Work (including but not limited to damages for loss of goodwill,\n work stoppage, computer failure or malfunction, or any and all\n other commercial damages or losses), even if such Contributor\n has been advised of the possibility of such damages.\n\n 9. Accepting Warranty or Additional Liability. While redistributing\n the Work or Derivative Works thereof, You may choose to offer,\n and charge a fee for, acceptance of support, warranty, indemnity,\n or other liability obligations and/or rights consistent with this\n License. However, in accepting such obligations, You may act only\n on Your own behalf and on Your sole responsibility, not on behalf\n of any other Contributor, and only if You agree to indemnify,\n defend, and hold each Contributor harmless for any liability\n incurred by, or claims asserted against, such Contributor by reason\n of your accepting any such warranty or additional liability.\n\n END OF TERMS AND CONDITIONS\n\n APPENDIX: How to apply the Apache License to your work.\n\n To apply the Apache License to your work, attach the following\n boilerplate notice, with the fields enclosed by brackets \"[]\"\n replaced with your own identifying information. (Don't include\n the brackets!) The text should be enclosed in the appropriate\n comment syntax for the file format. We also recommend that a\n file or class name and description of purpose be included on the\n same \"printed page\" as the copyright notice for easier\n identification within third-party archives.\n\n Copyright [yyyy] [name of copyright owner]\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n" + }, { "name": "github.com/golang/protobuf", "path": "github.com/golang/protobuf/LICENSE", @@ -785,8 +795,8 @@ "licenseText": "Copyright 2015 Yohann Coppel\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n" }, { - "name": "github.com/yuin/goldmark-highlighting", - "path": "github.com/yuin/goldmark-highlighting/LICENSE", + "name": "github.com/yuin/goldmark-highlighting/v2", + "path": "github.com/yuin/goldmark-highlighting/v2/LICENSE", "licenseText": "MIT License\n\nCopyright (c) 2019 Yusuke Inuzuka\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n" }, { diff --git a/contrib/systemd/gitea.service b/contrib/systemd/gitea.service index 79c34564bc..d205c6ee8b 100644 --- a/contrib/systemd/gitea.service +++ b/contrib/systemd/gitea.service @@ -49,12 +49,8 @@ After=network.target ### [Service] -# Modify these two values and uncomment them if you have -# repos with lots of files and get an HTTP error 500 because -# of that -### -#LimitMEMLOCK=infinity -#LimitNOFILE=65535 +# Uncomment the next line if you have repos with lots of files and get a HTTP 500 error because of that +# LimitNOFILE=524288:524288 RestartSec=2s Type=simple User=git diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index 3759428ed5..ec0b7c5235 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -887,7 +887,7 @@ ROUTER = console ;USE_COMPAT_SSH_URI = false ;; ;; Close issues as long as a commit on any branch marks it as fixed -;; Comma separated list of globally disabled repo units. Allowed values: repo.issues, repo.ext_issues, repo.pulls, repo.wiki, repo.ext_wiki +;; Comma separated list of globally disabled repo units. Allowed values: repo.issues, repo.ext_issues, repo.pulls, repo.wiki, repo.ext_wiki, repo.projects ;DISABLED_REPO_UNITS = ;; ;; Comma separated list of default repo units. Allowed values: repo.code, repo.releases, repo.issues, repo.pulls, repo.wiki, repo.projects. diff --git a/docs/content/doc/advanced/config-cheat-sheet.en-us.md b/docs/content/doc/advanced/config-cheat-sheet.en-us.md index 50571bd443..3fd853fb14 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md +++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md @@ -537,9 +537,9 @@ Certain queues have defaults that override the defaults set in `[queue]` (this o ## Camo (`camo`) - `ENABLED`: **false**: Enable media proxy, we support images only at the moment. -- `SERVER_URL`: ****: url of camo server, it **is required** if camo is enabled. -- `HMAC_KEY`: ****: Provide the HMAC key for encoding urls, it **is required** if camo is enabled. -- `ALLWAYS`: **false**: Set to true to use camo for https too lese only non https urls are proxyed +- `SERVER_URL`: ****: URL of camo server, it **is required** if camo is enabled. +- `HMAC_KEY`: ****: Provide the HMAC key for encoding URLs, it **is required** if camo is enabled. +- `ALLWAYS`: **false**: Set to true to use camo for both HTTP and HTTPS content, otherwise only non-HTTPS URLs are proxied ## OpenID (`openid`) diff --git a/docs/content/doc/developers/guidelines-backend.md b/docs/content/doc/developers/guidelines-backend.md index b680d73c82..913898be83 100644 --- a/docs/content/doc/developers/guidelines-backend.md +++ b/docs/content/doc/developers/guidelines-backend.md @@ -67,22 +67,18 @@ Some actions should allow for rollback when database record insertion/update/del So services must be allowed to create a database transaction. Here is some example, ```go -// servcies/repository/repo.go -func CreateXXXX() error {\ - ctx, committer, err := db.TxContext() - if err != nil { - return err - } - defer committer.Close() - - // do something, if return err, it will rollback automatically when `committer.Close()` is invoked. - if err := issues.UpdateIssue(ctx, repoID); err != nil { - // ... - } - - // ...... - - return committer.Commit() +// services/repository/repository.go +func CreateXXXX() error { + return db.WithTx(func(ctx context.Context) error { + e := db.GetEngine(ctx) + // do something, if err is returned, it will rollback automatically + if err := issues.UpdateIssue(ctx, repoID); err != nil { + // ... + return err + } + // ... + return nil + }) } ``` @@ -94,14 +90,14 @@ If the function will be used in the transaction, just let `context.Context` as t func UpdateIssue(ctx context.Context, repoID int64) error { e := db.GetEngine(ctx) - // ...... + // ... } ``` ### Package Name For the top level package, use a plural as package name, i.e. `services`, `models`, for sub packages, use singular, -i.e. `servcies/user`, `models/repository`. +i.e. `services/user`, `models/repository`. ### Import Alias diff --git a/docs/content/doc/developers/guidelines-frontend.md b/docs/content/doc/developers/guidelines-frontend.en-us.md similarity index 100% rename from docs/content/doc/developers/guidelines-frontend.md rename to docs/content/doc/developers/guidelines-frontend.en-us.md diff --git a/docs/content/doc/developers/hacking-on-gitea.en-us.md b/docs/content/doc/developers/hacking-on-gitea.en-us.md index 361ab530fa..d8427b58f3 100644 --- a/docs/content/doc/developers/hacking-on-gitea.en-us.md +++ b/docs/content/doc/developers/hacking-on-gitea.en-us.md @@ -19,6 +19,12 @@ menu: {{< toc >}} +## Quickstart + +To get a quick working development environment you could use Gitpod. + +[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/go-gitea/gitea) + ## Installing go You should [install go](https://golang.org/doc/install) and set up your go @@ -171,7 +177,7 @@ server as mentioned above. ### Working on JS and CSS -Frontend development should follow [Guidelines for Frontend Development](./guidelines-frontend.md) +Frontend development should follow [Guidelines for Frontend Development]({{< relref "doc/developers/guidelines-frontend.en-us.md" >}}) To build with frontend resources, either use the `watch-frontend` target mentioned above or just build once: diff --git a/docs/content/doc/upgrade/from-gitea.en-us.md b/docs/content/doc/upgrade/from-gitea.en-us.md index 0d22a32439..4dc47b05a4 100644 --- a/docs/content/doc/upgrade/from-gitea.en-us.md +++ b/docs/content/doc/upgrade/from-gitea.en-us.md @@ -1,6 +1,8 @@ --- date: "2021-09-02T16:00:00+08:00" title: "Upgrade from an old Gitea" +aliases: + - /en-us/upgrade/ slug: "upgrade-from-gitea" weight: 10 toc: false diff --git a/docs/static/_redirects b/docs/static/_redirects index 2114ae933f..676181b61f 100644 --- a/docs/static/_redirects +++ b/docs/static/_redirects @@ -10,3 +10,7 @@ https://gitea-docs.netlify.com/* https://docs.gitea.io/:splat 302! /en-us/ci-cd/ /en-us/integrations/ 302! /en-us/third-party-tools/ /en-us/integrations/ 302! /en-us/make/ /en-us/hacking-on-gitea/ 302! +/en-us/upgrade/ /en-us/upgrade-from-gitea/ 302! +/fr-fr/upgrade/ /fr-fr/upgrade-from-gitea/ 302! +/zh-cn/upgrade/ /zh-cn/upgrade-from-gitea/ 302! +/zh-tw/upgrade/ /zh-tw/upgrade-from-gitea/ 302! diff --git a/go.mod b/go.mod index 4501944a22..5bafaf4142 100644 --- a/go.mod +++ b/go.mod @@ -35,7 +35,7 @@ require ( github.com/go-ap/jsonld v0.0.0-20220917142617-76bf51585778 github.com/go-chi/chi/v5 v5.0.7 github.com/go-chi/cors v1.2.1 - github.com/go-enry/go-enry/v2 v2.8.2 + github.com/go-enry/go-enry/v2 v2.8.3 github.com/go-fed/httpsig v1.1.1-0.20201223112313-55836744818e github.com/go-git/go-billy/v5 v5.3.1 github.com/go-git/go-git/v5 v5.4.3-0.20220529141257-bc1f419cebcf @@ -98,7 +98,7 @@ require ( golang.org/x/net v0.0.0-20220927171203-f486391704dc golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1 golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec - golang.org/x/text v0.3.7 + golang.org/x/text v0.3.8 golang.org/x/tools v0.1.12 gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df gopkg.in/ini.v1 v1.67.0 diff --git a/go.sum b/go.sum index b6d76dfe6f..b53732f6a5 100644 --- a/go.sum +++ b/go.sum @@ -485,8 +485,8 @@ github.com/go-chi/chi/v5 v5.0.7 h1:rDTPXLDHGATaeHvVlLcR4Qe0zftYethFucbjVQ1PxU8= github.com/go-chi/chi/v5 v5.0.7/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4= github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58= -github.com/go-enry/go-enry/v2 v2.8.2 h1:uiGmC+3K8sVd/6DOe2AOJEOihJdqda83nPyJNtMR8RI= -github.com/go-enry/go-enry/v2 v2.8.2/go.mod h1:GVzIiAytiS5uT/QiuakK7TF1u4xDab87Y8V5EJRpsIQ= +github.com/go-enry/go-enry/v2 v2.8.3 h1:BwvNrN58JqBJhyyVdZSl5QD3xoxEEGYUrRyPh31FGhw= +github.com/go-enry/go-enry/v2 v2.8.3/go.mod h1:GVzIiAytiS5uT/QiuakK7TF1u4xDab87Y8V5EJRpsIQ= github.com/go-enry/go-oniguruma v1.2.1 h1:k8aAMuJfMrqm/56SG2lV9Cfti6tC4x8673aHCcBk+eo= github.com/go-enry/go-oniguruma v1.2.1/go.mod h1:bWDhYP+S6xZQgiRL7wlTScFYBe023B6ilRZbCAD5Hf4= github.com/go-fed/httpsig v1.1.1-0.20201223112313-55836744818e h1:oRq/fiirun5HqlEWMLIcDmLpIELlG4iGbd0s8iqgPi8= @@ -1891,8 +1891,9 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/jest.config.js b/jest.config.js index 34d47acc43..2767c1b7ae 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,3 +1,4 @@ +// to run tests with ES6 module, node must run with "--experimental-vm-modules", or see Makefile's "test-frontend" for reference export default { rootDir: 'web_src', setupFilesAfterEnv: ['jest-extended/all'], @@ -7,6 +8,8 @@ export default { transform: { '\\.svg$': '/js/testUtils/jestRawLoader.js', }, + setupFiles: [ + './js/testUtils/jestSetup.js', // prepare global variables used by our code (eg: window.config) + ], verbose: false, }; - diff --git a/models/activities/action_list.go b/models/activities/action_list.go index 16fb4bac8c..f349b94ac8 100644 --- a/models/activities/action_list.go +++ b/models/activities/action_list.go @@ -18,13 +18,11 @@ import ( type ActionList []*Action func (actions ActionList) getUserIDs() []int64 { - userIDs := make(map[int64]struct{}, len(actions)) + userIDs := make(container.Set[int64], len(actions)) for _, action := range actions { - if _, ok := userIDs[action.ActUserID]; !ok { - userIDs[action.ActUserID] = struct{}{} - } + userIDs.Add(action.ActUserID) } - return container.KeysInt64(userIDs) + return userIDs.Values() } func (actions ActionList) loadUsers(ctx context.Context) (map[int64]*user_model.User, error) { @@ -48,13 +46,11 @@ func (actions ActionList) loadUsers(ctx context.Context) (map[int64]*user_model. } func (actions ActionList) getRepoIDs() []int64 { - repoIDs := make(map[int64]struct{}, len(actions)) + repoIDs := make(container.Set[int64], len(actions)) for _, action := range actions { - if _, ok := repoIDs[action.RepoID]; !ok { - repoIDs[action.RepoID] = struct{}{} - } + repoIDs.Add(action.RepoID) } - return container.KeysInt64(repoIDs) + return repoIDs.Values() } func (actions ActionList) loadRepositories(ctx context.Context) error { diff --git a/models/activities/notification.go b/models/activities/notification.go index 88776db42b..2f21dc74d1 100644 --- a/models/activities/notification.go +++ b/models/activities/notification.go @@ -200,7 +200,7 @@ func CreateOrUpdateIssueNotifications(issueID, commentID, notificationAuthorID, func createOrUpdateIssueNotifications(ctx context.Context, issueID, commentID, notificationAuthorID, receiverID int64) error { // init - var toNotify map[int64]struct{} + var toNotify container.Set[int64] notifications, err := getNotificationsByIssueID(ctx, issueID) if err != nil { return err @@ -212,33 +212,27 @@ func createOrUpdateIssueNotifications(ctx context.Context, issueID, commentID, n } if receiverID > 0 { - toNotify = make(map[int64]struct{}, 1) - toNotify[receiverID] = struct{}{} + toNotify = make(container.Set[int64], 1) + toNotify.Add(receiverID) } else { - toNotify = make(map[int64]struct{}, 32) + toNotify = make(container.Set[int64], 32) issueWatches, err := issues_model.GetIssueWatchersIDs(ctx, issueID, true) if err != nil { return err } - for _, id := range issueWatches { - toNotify[id] = struct{}{} - } + toNotify.AddMultiple(issueWatches...) if !(issue.IsPull && issues_model.HasWorkInProgressPrefix(issue.Title)) { repoWatches, err := repo_model.GetRepoWatchersIDs(ctx, issue.RepoID) if err != nil { return err } - for _, id := range repoWatches { - toNotify[id] = struct{}{} - } + toNotify.AddMultiple(repoWatches...) } issueParticipants, err := issue.GetParticipantIDsByIssue(ctx) if err != nil { return err } - for _, id := range issueParticipants { - toNotify[id] = struct{}{} - } + toNotify.AddMultiple(issueParticipants...) // dont notify user who cause notification delete(toNotify, notificationAuthorID) @@ -248,7 +242,7 @@ func createOrUpdateIssueNotifications(ctx context.Context, issueID, commentID, n return err } for _, id := range issueUnWatches { - delete(toNotify, id) + toNotify.Remove(id) } } @@ -499,16 +493,14 @@ func (nl NotificationList) LoadAttributes() error { } func (nl NotificationList) getPendingRepoIDs() []int64 { - ids := make(map[int64]struct{}, len(nl)) + ids := make(container.Set[int64], len(nl)) for _, notification := range nl { if notification.Repository != nil { continue } - if _, ok := ids[notification.RepoID]; !ok { - ids[notification.RepoID] = struct{}{} - } + ids.Add(notification.RepoID) } - return container.KeysInt64(ids) + return ids.Values() } // LoadRepos loads repositories from database @@ -575,16 +567,14 @@ func (nl NotificationList) LoadRepos() (repo_model.RepositoryList, []int, error) } func (nl NotificationList) getPendingIssueIDs() []int64 { - ids := make(map[int64]struct{}, len(nl)) + ids := make(container.Set[int64], len(nl)) for _, notification := range nl { if notification.Issue != nil { continue } - if _, ok := ids[notification.IssueID]; !ok { - ids[notification.IssueID] = struct{}{} - } + ids.Add(notification.IssueID) } - return container.KeysInt64(ids) + return ids.Values() } // LoadIssues loads issues from database @@ -661,16 +651,14 @@ func (nl NotificationList) Without(failures []int) NotificationList { } func (nl NotificationList) getPendingCommentIDs() []int64 { - ids := make(map[int64]struct{}, len(nl)) + ids := make(container.Set[int64], len(nl)) for _, notification := range nl { if notification.CommentID == 0 || notification.Comment != nil { continue } - if _, ok := ids[notification.CommentID]; !ok { - ids[notification.CommentID] = struct{}{} - } + ids.Add(notification.CommentID) } - return container.KeysInt64(ids) + return ids.Values() } // LoadComments loads comments from database diff --git a/models/auth/oauth2.go b/models/auth/oauth2.go index 73c250d4af..abcd9e1ca6 100644 --- a/models/auth/oauth2.go +++ b/models/auth/oauth2.go @@ -225,7 +225,8 @@ func updateOAuth2Application(ctx context.Context, app *OAuth2Application) error func deleteOAuth2Application(ctx context.Context, id, userid int64) error { sess := db.GetEngine(ctx) - if deleted, err := sess.Delete(&OAuth2Application{ID: id, UID: userid}); err != nil { + // the userid could be 0 if the app is instance-wide + if deleted, err := sess.Where(builder.Eq{"id": id, "uid": userid}).Delete(&OAuth2Application{}); err != nil { return err } else if deleted == 0 { return ErrOAuthApplicationNotFound{ID: id} @@ -476,7 +477,7 @@ func GetOAuth2GrantsByUserID(ctx context.Context, uid int64) ([]*OAuth2Grant, er // RevokeOAuth2Grant deletes the grant with grantID and userID func RevokeOAuth2Grant(ctx context.Context, grantID, userID int64) error { - _, err := db.DeleteByBean(ctx, &OAuth2Grant{ID: grantID, UserID: userID}) + _, err := db.GetEngine(ctx).Where(builder.Eq{"id": grantID, "user_id": userID}).Delete(&OAuth2Grant{}) return err } diff --git a/models/fixtures/oauth2_application.yml b/models/fixtures/oauth2_application.yml index a13e20b10e..34d5a88777 100644 --- a/models/fixtures/oauth2_application.yml +++ b/models/fixtures/oauth2_application.yml @@ -4,6 +4,6 @@ name: "Test" client_id: "da7da3ba-9a13-4167-856f-3899de0b0138" client_secret: "$2a$10$UYRgUSgekzBp6hYe8pAdc.cgB4Gn06QRKsORUnIYTYQADs.YR/uvi" # bcrypt of "4MK8Na6R55smdCY0WuCCumZ6hjRPnGY5saWVRHHjJiA= - redirect_uris: '["a"]' + redirect_uris: '["a", "https://example.com/xyzzy"]' created_unix: 1546869730 updated_unix: 1546869730 diff --git a/models/issues/comment_list.go b/models/issues/comment_list.go index e3406a5cbe..70105d7ff0 100644 --- a/models/issues/comment_list.go +++ b/models/issues/comment_list.go @@ -17,13 +17,11 @@ import ( type CommentList []*Comment func (comments CommentList) getPosterIDs() []int64 { - posterIDs := make(map[int64]struct{}, len(comments)) + posterIDs := make(container.Set[int64], len(comments)) for _, comment := range comments { - if _, ok := posterIDs[comment.PosterID]; !ok { - posterIDs[comment.PosterID] = struct{}{} - } + posterIDs.Add(comment.PosterID) } - return container.KeysInt64(posterIDs) + return posterIDs.Values() } func (comments CommentList) loadPosters(ctx context.Context) error { @@ -70,13 +68,11 @@ func (comments CommentList) getCommentIDs() []int64 { } func (comments CommentList) getLabelIDs() []int64 { - ids := make(map[int64]struct{}, len(comments)) + ids := make(container.Set[int64], len(comments)) for _, comment := range comments { - if _, ok := ids[comment.LabelID]; !ok { - ids[comment.LabelID] = struct{}{} - } + ids.Add(comment.LabelID) } - return container.KeysInt64(ids) + return ids.Values() } func (comments CommentList) loadLabels(ctx context.Context) error { //nolint @@ -120,13 +116,11 @@ func (comments CommentList) loadLabels(ctx context.Context) error { //nolint } func (comments CommentList) getMilestoneIDs() []int64 { - ids := make(map[int64]struct{}, len(comments)) + ids := make(container.Set[int64], len(comments)) for _, comment := range comments { - if _, ok := ids[comment.MilestoneID]; !ok { - ids[comment.MilestoneID] = struct{}{} - } + ids.Add(comment.MilestoneID) } - return container.KeysInt64(ids) + return ids.Values() } func (comments CommentList) loadMilestones(ctx context.Context) error { @@ -163,13 +157,11 @@ func (comments CommentList) loadMilestones(ctx context.Context) error { } func (comments CommentList) getOldMilestoneIDs() []int64 { - ids := make(map[int64]struct{}, len(comments)) + ids := make(container.Set[int64], len(comments)) for _, comment := range comments { - if _, ok := ids[comment.OldMilestoneID]; !ok { - ids[comment.OldMilestoneID] = struct{}{} - } + ids.Add(comment.OldMilestoneID) } - return container.KeysInt64(ids) + return ids.Values() } func (comments CommentList) loadOldMilestones(ctx context.Context) error { @@ -206,13 +198,11 @@ func (comments CommentList) loadOldMilestones(ctx context.Context) error { } func (comments CommentList) getAssigneeIDs() []int64 { - ids := make(map[int64]struct{}, len(comments)) + ids := make(container.Set[int64], len(comments)) for _, comment := range comments { - if _, ok := ids[comment.AssigneeID]; !ok { - ids[comment.AssigneeID] = struct{}{} - } + ids.Add(comment.AssigneeID) } - return container.KeysInt64(ids) + return ids.Values() } func (comments CommentList) loadAssignees(ctx context.Context) error { @@ -259,16 +249,14 @@ func (comments CommentList) loadAssignees(ctx context.Context) error { // getIssueIDs returns all the issue ids on this comment list which issue hasn't been loaded func (comments CommentList) getIssueIDs() []int64 { - ids := make(map[int64]struct{}, len(comments)) + ids := make(container.Set[int64], len(comments)) for _, comment := range comments { if comment.Issue != nil { continue } - if _, ok := ids[comment.IssueID]; !ok { - ids[comment.IssueID] = struct{}{} - } + ids.Add(comment.IssueID) } - return container.KeysInt64(ids) + return ids.Values() } // Issues returns all the issues of comments @@ -334,16 +322,14 @@ func (comments CommentList) loadIssues(ctx context.Context) error { } func (comments CommentList) getDependentIssueIDs() []int64 { - ids := make(map[int64]struct{}, len(comments)) + ids := make(container.Set[int64], len(comments)) for _, comment := range comments { if comment.DependentIssue != nil { continue } - if _, ok := ids[comment.DependentIssueID]; !ok { - ids[comment.DependentIssueID] = struct{}{} - } + ids.Add(comment.DependentIssueID) } - return container.KeysInt64(ids) + return ids.Values() } func (comments CommentList) loadDependentIssues(ctx context.Context) error { @@ -439,13 +425,11 @@ func (comments CommentList) loadAttachments(ctx context.Context) (err error) { } func (comments CommentList) getReviewIDs() []int64 { - ids := make(map[int64]struct{}, len(comments)) + ids := make(container.Set[int64], len(comments)) for _, comment := range comments { - if _, ok := ids[comment.ReviewID]; !ok { - ids[comment.ReviewID] = struct{}{} - } + ids.Add(comment.ReviewID) } - return container.KeysInt64(ids) + return ids.Values() } func (comments CommentList) loadReviews(ctx context.Context) error { //nolint diff --git a/models/issues/issue_list.go b/models/issues/issue_list.go index 874f2a6368..deadb6a564 100644 --- a/models/issues/issue_list.go +++ b/models/issues/issue_list.go @@ -22,16 +22,16 @@ type IssueList []*Issue // get the repo IDs to be loaded later, these IDs are for issue.Repo and issue.PullRequest.HeadRepo func (issues IssueList) getRepoIDs() []int64 { - repoIDs := make(map[int64]struct{}, len(issues)) + repoIDs := make(container.Set[int64], len(issues)) for _, issue := range issues { if issue.Repo == nil { - repoIDs[issue.RepoID] = struct{}{} + repoIDs.Add(issue.RepoID) } if issue.PullRequest != nil && issue.PullRequest.HeadRepo == nil { - repoIDs[issue.PullRequest.HeadRepoID] = struct{}{} + repoIDs.Add(issue.PullRequest.HeadRepoID) } } - return container.KeysInt64(repoIDs) + return repoIDs.Values() } func (issues IssueList) loadRepositories(ctx context.Context) ([]*repo_model.Repository, error) { @@ -79,13 +79,11 @@ func (issues IssueList) LoadRepositories() ([]*repo_model.Repository, error) { } func (issues IssueList) getPosterIDs() []int64 { - posterIDs := make(map[int64]struct{}, len(issues)) + posterIDs := make(container.Set[int64], len(issues)) for _, issue := range issues { - if _, ok := posterIDs[issue.PosterID]; !ok { - posterIDs[issue.PosterID] = struct{}{} - } + posterIDs.Add(issue.PosterID) } - return container.KeysInt64(posterIDs) + return posterIDs.Values() } func (issues IssueList) loadPosters(ctx context.Context) error { @@ -185,13 +183,11 @@ func (issues IssueList) loadLabels(ctx context.Context) error { } func (issues IssueList) getMilestoneIDs() []int64 { - ids := make(map[int64]struct{}, len(issues)) + ids := make(container.Set[int64], len(issues)) for _, issue := range issues { - if _, ok := ids[issue.MilestoneID]; !ok { - ids[issue.MilestoneID] = struct{}{} - } + ids.Add(issue.MilestoneID) } - return container.KeysInt64(ids) + return ids.Values() } func (issues IssueList) loadMilestones(ctx context.Context) error { @@ -224,14 +220,11 @@ func (issues IssueList) loadMilestones(ctx context.Context) error { } func (issues IssueList) getProjectIDs() []int64 { - ids := make(map[int64]struct{}, len(issues)) + ids := make(container.Set[int64], len(issues)) for _, issue := range issues { - projectID := issue.ProjectID() - if _, ok := ids[projectID]; !ok { - ids[projectID] = struct{}{} - } + ids.Add(issue.ProjectID()) } - return container.KeysInt64(ids) + return ids.Values() } func (issues IssueList) loadProjects(ctx context.Context) error { diff --git a/models/issues/reaction.go b/models/issues/reaction.go index e7295c8af8..ccda10be2c 100644 --- a/models/issues/reaction.go +++ b/models/issues/reaction.go @@ -211,7 +211,7 @@ type ReactionOptions struct { // CreateReaction creates reaction for issue or comment. func CreateReaction(opts *ReactionOptions) (*Reaction, error) { - if !setting.UI.ReactionsMap[opts.Type] { + if !setting.UI.ReactionsLookup.Contains(opts.Type) { return nil, ErrForbiddenIssueReaction{opts.Type} } @@ -316,16 +316,14 @@ func (list ReactionList) GroupByType() map[string]ReactionList { } func (list ReactionList) getUserIDs() []int64 { - userIDs := make(map[int64]struct{}, len(list)) + userIDs := make(container.Set[int64], len(list)) for _, reaction := range list { if reaction.OriginalAuthor != "" { continue } - if _, ok := userIDs[reaction.UserID]; !ok { - userIDs[reaction.UserID] = struct{}{} - } + userIDs.Add(reaction.UserID) } - return container.KeysInt64(userIDs) + return userIDs.Values() } func valuesUser(m map[int64]*user_model.User) []*user_model.User { diff --git a/models/migrate.go b/models/migrate.go index f6bceaa019..d842fb967b 100644 --- a/models/migrate.go +++ b/models/migrate.go @@ -10,6 +10,7 @@ import ( "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" + "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/structs" ) @@ -99,9 +100,9 @@ func InsertIssueComments(comments []*issues_model.Comment) error { return nil } - issueIDs := make(map[int64]bool) + issueIDs := make(container.Set[int64]) for _, comment := range comments { - issueIDs[comment.IssueID] = true + issueIDs.Add(comment.IssueID) } ctx, committer, err := db.TxContext() diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go index 28ffc99886..2a38772180 100644 --- a/models/migrations/migrations.go +++ b/models/migrations/migrations.go @@ -413,6 +413,8 @@ var migrations = []Migration{ NewMigration("Add badges to users", createUserBadgesTable), // v225 -> v226 NewMigration("Alter gpg_key/public_key content TEXT fields to MEDIUMTEXT", alterPublicGPGKeyContentFieldsToMediumText), + // v226 -> v227 + NewMigration("Conan and generic packages do not need to be semantically versioned", fixPackageSemverField), } // GetCurrentDBVersion returns the current db version diff --git a/models/migrations/v115.go b/models/migrations/v115.go index 7708ed5e28..b242ccf238 100644 --- a/models/migrations/v115.go +++ b/models/migrations/v115.go @@ -13,6 +13,7 @@ import ( "path/filepath" "time" + "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" @@ -39,7 +40,7 @@ func renameExistingUserAvatarName(x *xorm.Engine) error { } log.Info("%d User Avatar(s) to migrate ...", count) - deleteList := make(map[string]struct{}) + deleteList := make(container.Set[string]) start := 0 migrated := 0 for { @@ -86,7 +87,7 @@ func renameExistingUserAvatarName(x *xorm.Engine) error { return fmt.Errorf("[user: %s] user table update: %v", user.LowerName, err) } - deleteList[filepath.Join(setting.Avatar.Path, oldAvatar)] = struct{}{} + deleteList.Add(filepath.Join(setting.Avatar.Path, oldAvatar)) migrated++ select { case <-ticker.C: diff --git a/models/migrations/v226.go b/models/migrations/v226.go new file mode 100644 index 0000000000..2f85bca21f --- /dev/null +++ b/models/migrations/v226.go @@ -0,0 +1,15 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package migrations + +import ( + "xorm.io/builder" + "xorm.io/xorm" +) + +func fixPackageSemverField(x *xorm.Engine) error { + _, err := x.Exec(builder.Update(builder.Eq{"semver_compatible": false}).From("`package`").Where(builder.In("`type`", "conan", "generic"))) + return err +} diff --git a/models/packages/conan/search.go b/models/packages/conan/search.go index 6a2cfa38f5..39a9000459 100644 --- a/models/packages/conan/search.go +++ b/models/packages/conan/search.go @@ -12,6 +12,7 @@ import ( "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/packages" + "code.gitea.io/gitea/modules/container" conan_module "code.gitea.io/gitea/modules/packages/conan" "xorm.io/builder" @@ -88,7 +89,7 @@ func SearchRecipes(ctx context.Context, opts *RecipeSearchOptions) ([]string, er return nil, err } - unique := make(map[string]bool) + unique := make(container.Set[string]) for _, info := range results { recipe := fmt.Sprintf("%s/%s", info.Name, info.Version) @@ -111,7 +112,7 @@ func SearchRecipes(ctx context.Context, opts *RecipeSearchOptions) ([]string, er } } - unique[recipe] = true + unique.Add(recipe) } recipes := make([]string, 0, len(unique)) diff --git a/models/repo.go b/models/repo.go index f2676a5696..558678bfe5 100644 --- a/models/repo.go +++ b/models/repo.go @@ -438,15 +438,27 @@ func CheckRepoStats(ctx context.Context) error { repoStatsCorrectNumStars, "repository count 'num_stars'", }, + // Repository.NumIssues + { + statsQuery("SELECT repo.id FROM `repository` repo WHERE repo.num_issues!=(SELECT COUNT(*) FROM `issue` WHERE repo_id=repo.id AND is_closed=? AND is_pull=?)", false, false), + repoStatsCorrectNumIssues, + "repository count 'num_issues'", + }, // Repository.NumClosedIssues { statsQuery("SELECT repo.id FROM `repository` repo WHERE repo.num_closed_issues!=(SELECT COUNT(*) FROM `issue` WHERE repo_id=repo.id AND is_closed=? AND is_pull=?)", true, false), repoStatsCorrectNumClosedIssues, "repository count 'num_closed_issues'", }, + // Repository.NumPulls + { + statsQuery("SELECT repo.id FROM `repository` repo WHERE repo.num_pulls!=(SELECT COUNT(*) FROM `issue` WHERE repo_id=repo.id AND is_closed=? AND is_pull=?)", false, true), + repoStatsCorrectNumPulls, + "repository count 'num_pulls'", + }, // Repository.NumClosedPulls { - statsQuery("SELECT repo.id FROM `repository` repo WHERE repo.num_closed_issues!=(SELECT COUNT(*) FROM `issue` WHERE repo_id=repo.id AND is_closed=? AND is_pull=?)", true, true), + statsQuery("SELECT repo.id FROM `repository` repo WHERE repo.num_closed_pulls!=(SELECT COUNT(*) FROM `issue` WHERE repo_id=repo.id AND is_closed=? AND is_pull=?)", true, true), repoStatsCorrectNumClosedPulls, "repository count 'num_closed_pulls'", }, diff --git a/models/repo/repo_list.go b/models/repo/repo_list.go index ee72dc6ee7..0cd0a3c8e3 100644 --- a/models/repo/repo_list.go +++ b/models/repo/repo_list.go @@ -68,10 +68,10 @@ func (repos RepositoryList) loadAttributes(ctx context.Context) error { return nil } - set := make(map[int64]struct{}) + set := make(container.Set[int64]) repoIDs := make([]int64, len(repos)) for i := range repos { - set[repos[i].OwnerID] = struct{}{} + set.Add(repos[i].OwnerID) repoIDs[i] = repos[i].ID } @@ -79,7 +79,7 @@ func (repos RepositoryList) loadAttributes(ctx context.Context) error { users := make(map[int64]*user_model.User, len(set)) if err := db.GetEngine(ctx). Where("id > 0"). - In("id", container.KeysInt64(set)). + In("id", set.Values()). Find(&users); err != nil { return fmt.Errorf("find users: %v", err) } @@ -593,6 +593,16 @@ func searchRepositoryByCondition(ctx context.Context, opts *SearchRepoOptions, c return sess, count, nil } +// SearchRepositoryIDsByCondition search repository IDs by given condition. +func SearchRepositoryIDsByCondition(ctx context.Context, cond builder.Cond) ([]int64, error) { + repoIDs := make([]int64, 0, 10) + return repoIDs, db.GetEngine(ctx). + Table("repository"). + Cols("id"). + Where(cond). + Find(&repoIDs) +} + // AccessibleRepositoryCondition takes a user a returns a condition for checking if a repository is accessible func AccessibleRepositoryCondition(user *user_model.User, unitType unit.Type) builder.Cond { cond := builder.NewCond() @@ -680,16 +690,16 @@ func AccessibleRepoIDsQuery(user *user_model.User) *builder.Builder { } // FindUserCodeAccessibleRepoIDs finds all at Code level accessible repositories' ID by the user's id -func FindUserCodeAccessibleRepoIDs(user *user_model.User) ([]int64, error) { - repoIDs := make([]int64, 0, 10) - if err := db.GetEngine(db.DefaultContext). - Table("repository"). - Cols("id"). - Where(AccessibleRepositoryCondition(user, unit.TypeCode)). - Find(&repoIDs); err != nil { - return nil, fmt.Errorf("FindUserCodeAccesibleRepoIDs: %v", err) - } - return repoIDs, nil +func FindUserCodeAccessibleRepoIDs(ctx context.Context, user *user_model.User) ([]int64, error) { + return SearchRepositoryIDsByCondition(ctx, AccessibleRepositoryCondition(user, unit.TypeCode)) +} + +// FindUserCodeAccessibleOwnerRepoIDs finds all repository IDs for the given owner whose code the user can see. +func FindUserCodeAccessibleOwnerRepoIDs(ctx context.Context, ownerID int64, user *user_model.User) ([]int64, error) { + return SearchRepositoryIDsByCondition(ctx, builder.NewCond().And( + builder.Eq{"owner_id": ownerID}, + AccessibleRepositoryCondition(user, unit.TypeCode), + )) } // GetUserRepositories returns a list of repositories of given user. diff --git a/models/repo/topic.go b/models/repo/topic.go index 2a16467215..7ba9a49e89 100644 --- a/models/repo/topic.go +++ b/models/repo/topic.go @@ -11,6 +11,7 @@ import ( "strings" "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/timeutil" "xorm.io/builder" @@ -62,7 +63,7 @@ func ValidateTopic(topic string) bool { // SanitizeAndValidateTopics sanitizes and checks an array or topics func SanitizeAndValidateTopics(topics []string) (validTopics, invalidTopics []string) { validTopics = make([]string, 0) - mValidTopics := make(map[string]struct{}) + mValidTopics := make(container.Set[string]) invalidTopics = make([]string, 0) for _, topic := range topics { @@ -72,12 +73,12 @@ func SanitizeAndValidateTopics(topics []string) (validTopics, invalidTopics []st continue } // ignore same topic twice - if _, ok := mValidTopics[topic]; ok { + if mValidTopics.Contains(topic) { continue } if ValidateTopic(topic) { validTopics = append(validTopics, topic) - mValidTopics[topic] = struct{}{} + mValidTopics.Add(topic) } else { invalidTopics = append(invalidTopics, topic) } diff --git a/models/repo/user_repo.go b/models/repo/user_repo.go index 6c0a241dc5..e7125f70f8 100644 --- a/models/repo/user_repo.go +++ b/models/repo/user_repo.go @@ -10,6 +10,7 @@ import ( "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/perm" user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/container" api "code.gitea.io/gitea/modules/structs" "xorm.io/builder" @@ -83,37 +84,19 @@ func GetRepoAssignees(ctx context.Context, repo *Repository) (_ []*user_model.Us return nil, err } - uidMap := map[int64]bool{} - i := 0 - for _, uid := range userIDs { - if uidMap[uid] { - continue - } - uidMap[uid] = true - userIDs[i] = uid - i++ - } - userIDs = userIDs[:i] - userIDs = append(userIDs, additionalUserIDs...) - - for _, uid := range additionalUserIDs { - if uidMap[uid] { - continue - } - userIDs[i] = uid - i++ - } - userIDs = userIDs[:i] + uniqueUserIDs := make(container.Set[int64]) + uniqueUserIDs.AddMultiple(userIDs...) + uniqueUserIDs.AddMultiple(additionalUserIDs...) // Leave a seat for owner itself to append later, but if owner is an organization // and just waste 1 unit is cheaper than re-allocate memory once. - users := make([]*user_model.User, 0, len(userIDs)+1) + users := make([]*user_model.User, 0, len(uniqueUserIDs)+1) if len(userIDs) > 0 { - if err = e.In("id", userIDs).OrderBy(user_model.GetOrderByName()).Find(&users); err != nil { + if err = e.In("id", uniqueUserIDs.Values()).OrderBy(user_model.GetOrderByName()).Find(&users); err != nil { return nil, err } } - if !repo.Owner.IsOrganization() && !uidMap[repo.OwnerID] { + if !repo.Owner.IsOrganization() && !uniqueUserIDs.Contains(repo.OwnerID) { users = append(users, repo.Owner) } diff --git a/models/user/email_address.go b/models/user/email_address.go index c931db9c16..d87b945706 100644 --- a/models/user/email_address.go +++ b/models/user/email_address.go @@ -41,6 +41,7 @@ func (err ErrEmailCharIsNotSupported) Error() string { } // ErrEmailInvalid represents an error where the email address does not comply with RFC 5322 +// or has a leading '-' character type ErrEmailInvalid struct { Email string } @@ -134,9 +135,7 @@ func ValidateEmail(email string) error { return ErrEmailCharIsNotSupported{email} } - if !(email[0] >= 'a' && email[0] <= 'z') && - !(email[0] >= 'A' && email[0] <= 'Z') && - !(email[0] >= '0' && email[0] <= '9') { + if email[0] == '-' { return ErrEmailInvalid{email} } diff --git a/models/user/email_address_test.go b/models/user/email_address_test.go index 471598c897..b9acaa1113 100644 --- a/models/user/email_address_test.go +++ b/models/user/email_address_test.go @@ -281,23 +281,25 @@ func TestEmailAddressValidate(t *testing.T) { `first~last@iana.org`: nil, `first;last@iana.org`: user_model.ErrEmailCharIsNotSupported{`first;last@iana.org`}, ".233@qq.com": user_model.ErrEmailInvalid{".233@qq.com"}, - "!233@qq.com": user_model.ErrEmailInvalid{"!233@qq.com"}, - "#233@qq.com": user_model.ErrEmailInvalid{"#233@qq.com"}, - "$233@qq.com": user_model.ErrEmailInvalid{"$233@qq.com"}, - "%233@qq.com": user_model.ErrEmailInvalid{"%233@qq.com"}, - "&233@qq.com": user_model.ErrEmailInvalid{"&233@qq.com"}, - "'233@qq.com": user_model.ErrEmailInvalid{"'233@qq.com"}, - "*233@qq.com": user_model.ErrEmailInvalid{"*233@qq.com"}, - "+233@qq.com": user_model.ErrEmailInvalid{"+233@qq.com"}, - "/233@qq.com": user_model.ErrEmailInvalid{"/233@qq.com"}, - "=233@qq.com": user_model.ErrEmailInvalid{"=233@qq.com"}, - "?233@qq.com": user_model.ErrEmailInvalid{"?233@qq.com"}, - "^233@qq.com": user_model.ErrEmailInvalid{"^233@qq.com"}, - "`233@qq.com": user_model.ErrEmailInvalid{"`233@qq.com"}, - "{233@qq.com": user_model.ErrEmailInvalid{"{233@qq.com"}, - "|233@qq.com": user_model.ErrEmailInvalid{"|233@qq.com"}, - "}233@qq.com": user_model.ErrEmailInvalid{"}233@qq.com"}, - "~233@qq.com": user_model.ErrEmailInvalid{"~233@qq.com"}, + "!233@qq.com": nil, + "#233@qq.com": nil, + "$233@qq.com": nil, + "%233@qq.com": nil, + "&233@qq.com": nil, + "'233@qq.com": nil, + "*233@qq.com": nil, + "+233@qq.com": nil, + "-233@qq.com": user_model.ErrEmailInvalid{"-233@qq.com"}, + "/233@qq.com": nil, + "=233@qq.com": nil, + "?233@qq.com": nil, + "^233@qq.com": nil, + "_233@qq.com": nil, + "`233@qq.com": nil, + "{233@qq.com": nil, + "|233@qq.com": nil, + "}233@qq.com": nil, + "~233@qq.com": nil, ";233@qq.com": user_model.ErrEmailCharIsNotSupported{";233@qq.com"}, "Foo ": user_model.ErrEmailCharIsNotSupported{"Foo "}, string([]byte{0xE2, 0x84, 0xAA}): user_model.ErrEmailCharIsNotSupported{string([]byte{0xE2, 0x84, 0xAA})}, diff --git a/modules/base/tool.go b/modules/base/tool.go index a981fd6c57..f1e4a3bf97 100644 --- a/modules/base/tool.go +++ b/modules/base/tool.go @@ -241,15 +241,6 @@ func Int64sToStrings(ints []int64) []string { return strs } -// Int64sToMap converts a slice of int64 to a int64 map. -func Int64sToMap(ints []int64) map[int64]bool { - m := make(map[int64]bool) - for _, i := range ints { - m[i] = true - } - return m -} - // Int64sContains returns if a int64 in a slice of int64 func Int64sContains(intsSlice []int64, a int64) bool { for _, c := range intsSlice { diff --git a/modules/base/tool_test.go b/modules/base/tool_test.go index 6685168bac..87de898e0b 100644 --- a/modules/base/tool_test.go +++ b/modules/base/tool_test.go @@ -214,16 +214,7 @@ func TestInt64sToStrings(t *testing.T) { ) } -func TestInt64sToMap(t *testing.T) { - assert.Equal(t, map[int64]bool{}, Int64sToMap([]int64{})) - assert.Equal(t, - map[int64]bool{1: true, 4: true, 16: true}, - Int64sToMap([]int64{1, 4, 16}), - ) -} - func TestInt64sContains(t *testing.T) { - assert.Equal(t, map[int64]bool{}, Int64sToMap([]int64{})) assert.True(t, Int64sContains([]int64{6, 44324, 4324, 32, 1, 2323}, 1)) assert.True(t, Int64sContains([]int64{2323}, 2323)) assert.False(t, Int64sContains([]int64{6, 44324, 4324, 32, 1, 2323}, 232)) diff --git a/modules/container/map.go b/modules/container/map.go deleted file mode 100644 index 3519de0951..0000000000 --- a/modules/container/map.go +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2022 The Gitea Authors. All rights reserved. -// Use of this source code is governed by a MIT-style -// license that can be found in the LICENSE file. - -package container - -// KeysInt64 returns keys slice for a map with int64 key -func KeysInt64(m map[int64]struct{}) []int64 { - keys := make([]int64, 0, len(m)) - for k := range m { - keys = append(keys, k) - } - return keys -} diff --git a/modules/container/set.go b/modules/container/set.go new file mode 100644 index 0000000000..4b4c74525d --- /dev/null +++ b/modules/container/set.go @@ -0,0 +1,57 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package container + +type Set[T comparable] map[T]struct{} + +// SetOf creates a set and adds the specified elements to it. +func SetOf[T comparable](values ...T) Set[T] { + s := make(Set[T], len(values)) + s.AddMultiple(values...) + return s +} + +// Add adds the specified element to a set. +// Returns true if the element is added; false if the element is already present. +func (s Set[T]) Add(value T) bool { + if _, has := s[value]; !has { + s[value] = struct{}{} + return true + } + return false +} + +// AddMultiple adds the specified elements to a set. +func (s Set[T]) AddMultiple(values ...T) { + for _, value := range values { + s.Add(value) + } +} + +// Contains determines whether a set contains the specified element. +// Returns true if the set contains the specified element; otherwise, false. +func (s Set[T]) Contains(value T) bool { + _, has := s[value] + return has +} + +// Remove removes the specified element. +// Returns true if the element is successfully found and removed; otherwise, false. +func (s Set[T]) Remove(value T) bool { + if _, has := s[value]; has { + delete(s, value) + return true + } + return false +} + +// Values gets a list of all elements in the set. +func (s Set[T]) Values() []T { + keys := make([]T, 0, len(s)) + for k := range s { + keys = append(keys, k) + } + return keys +} diff --git a/modules/container/set_test.go b/modules/container/set_test.go new file mode 100644 index 0000000000..6654763e56 --- /dev/null +++ b/modules/container/set_test.go @@ -0,0 +1,37 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package container + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestSet(t *testing.T) { + s := make(Set[string]) + + assert.True(t, s.Add("key1")) + assert.False(t, s.Add("key1")) + assert.True(t, s.Add("key2")) + + assert.True(t, s.Contains("key1")) + assert.True(t, s.Contains("key2")) + assert.False(t, s.Contains("key3")) + + assert.True(t, s.Remove("key2")) + assert.False(t, s.Contains("key2")) + + assert.False(t, s.Remove("key3")) + + s.AddMultiple("key4", "key5") + assert.True(t, s.Contains("key4")) + assert.True(t, s.Contains("key5")) + + s = SetOf("key6", "key7") + assert.False(t, s.Contains("key1")) + assert.True(t, s.Contains("key6")) + assert.True(t, s.Contains("key7")) +} diff --git a/modules/context/org.go b/modules/context/org.go index d020befa40..89260b8654 100644 --- a/modules/context/org.go +++ b/modules/context/org.go @@ -130,6 +130,7 @@ func HandleOrgAssignment(ctx *Context, args ...bool) { ctx.Data["IsOrganizationOwner"] = ctx.Org.IsOwner ctx.Data["IsOrganizationMember"] = ctx.Org.IsMember ctx.Data["IsPackageEnabled"] = setting.Packages.Enabled + ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled ctx.Data["IsPublicMember"] = func(uid int64) bool { is, _ := organization.IsPublicMembership(ctx.Org.Organization.ID, uid) return is diff --git a/modules/context/repo.go b/modules/context/repo.go index 1742683d3c..1a0263a330 100644 --- a/modules/context/repo.go +++ b/modules/context/repo.go @@ -451,11 +451,20 @@ func RepoAssignment(ctx *Context) (cancel context.CancelFunc) { owner, err = user_model.GetUserByName(ctx, userName) if err != nil { if user_model.IsErrUserNotExist(err) { + // go-get does not support redirects + // https://github.com/golang/go/issues/19760 if ctx.FormString("go-get") == "1" { EarlyResponseForGoGetMeta(ctx) return } - ctx.NotFound("GetUserByName", nil) + + if redirectUserID, err := user_model.LookupUserRedirect(userName); err == nil { + RedirectToUser(ctx, userName, redirectUserID) + } else if user_model.IsErrUserRedirectNotExist(err) { + ctx.NotFound("GetUserByName", nil) + } else { + ctx.ServerError("LookupUserRedirect", err) + } } else { ctx.ServerError("GetUserByName", err) } diff --git a/modules/convert/convert.go b/modules/convert/convert.go index af759cb938..187c67fa76 100644 --- a/modules/convert/convert.go +++ b/modules/convert/convert.go @@ -412,7 +412,7 @@ func ToLFSLock(l *git_model.LFSLock) *api.LFSLock { Path: l.Path, LockedAt: l.Created.Round(time.Second), Owner: &api.LFSLockOwner{ - Name: u.DisplayName(), + Name: u.Name, }, } } diff --git a/modules/convert/git_commit.go b/modules/convert/git_commit.go index dfd6cb080c..6015a73712 100644 --- a/modules/convert/git_commit.go +++ b/modules/convert/git_commit.go @@ -73,7 +73,7 @@ func ToPayloadCommit(repo *repo_model.Repository, c *git.Commit) *api.PayloadCom } // ToCommit convert a git.Commit to api.Commit -func ToCommit(repo *repo_model.Repository, gitRepo *git.Repository, commit *git.Commit, userCache map[string]*user_model.User) (*api.Commit, error) { +func ToCommit(repo *repo_model.Repository, gitRepo *git.Repository, commit *git.Commit, userCache map[string]*user_model.User, stat bool) (*api.Commit, error) { var apiAuthor, apiCommitter *api.User // Retrieve author and committer information @@ -133,28 +133,7 @@ func ToCommit(repo *repo_model.Repository, gitRepo *git.Repository, commit *git. } } - // Retrieve files affected by the commit - fileStatus, err := git.GetCommitFileStatus(gitRepo.Ctx, repo.RepoPath(), commit.ID.String()) - if err != nil { - return nil, err - } - affectedFileList := make([]*api.CommitAffectedFiles, 0, len(fileStatus.Added)+len(fileStatus.Removed)+len(fileStatus.Modified)) - for _, files := range [][]string{fileStatus.Added, fileStatus.Removed, fileStatus.Modified} { - for _, filename := range files { - affectedFileList = append(affectedFileList, &api.CommitAffectedFiles{ - Filename: filename, - }) - } - } - - diff, err := gitdiff.GetDiff(gitRepo, &gitdiff.DiffOptions{ - AfterCommitID: commit.ID.String(), - }) - if err != nil { - return nil, err - } - - return &api.Commit{ + res := &api.Commit{ CommitMeta: &api.CommitMeta{ URL: repo.APIURL() + "/git/commits/" + url.PathEscape(commit.ID.String()), SHA: commit.ID.String(), @@ -188,11 +167,37 @@ func ToCommit(repo *repo_model.Repository, gitRepo *git.Repository, commit *git. Author: apiAuthor, Committer: apiCommitter, Parents: apiParents, - Files: affectedFileList, - Stats: &api.CommitStats{ + } + + // Retrieve files affected by the commit + if stat { + fileStatus, err := git.GetCommitFileStatus(gitRepo.Ctx, repo.RepoPath(), commit.ID.String()) + if err != nil { + return nil, err + } + affectedFileList := make([]*api.CommitAffectedFiles, 0, len(fileStatus.Added)+len(fileStatus.Removed)+len(fileStatus.Modified)) + for _, files := range [][]string{fileStatus.Added, fileStatus.Removed, fileStatus.Modified} { + for _, filename := range files { + affectedFileList = append(affectedFileList, &api.CommitAffectedFiles{ + Filename: filename, + }) + } + } + + diff, err := gitdiff.GetDiff(gitRepo, &gitdiff.DiffOptions{ + AfterCommitID: commit.ID.String(), + }) + if err != nil { + return nil, err + } + + res.Files = affectedFileList + res.Stats = &api.CommitStats{ Total: diff.TotalAddition + diff.TotalDeletion, Additions: diff.TotalAddition, Deletions: diff.TotalDeletion, - }, - }, nil + } + } + + return res, nil } diff --git a/modules/convert/repository.go b/modules/convert/repository.go index f853163848..09b84afa6c 100644 --- a/modules/convert/repository.go +++ b/modules/convert/repository.go @@ -56,9 +56,10 @@ func innerToRepo(repo *repo_model.Repository, mode perm.AccessMode, isParent boo config := unit.ExternalTrackerConfig() hasIssues = true externalTracker = &api.ExternalTracker{ - ExternalTrackerURL: config.ExternalTrackerURL, - ExternalTrackerFormat: config.ExternalTrackerFormat, - ExternalTrackerStyle: config.ExternalTrackerStyle, + ExternalTrackerURL: config.ExternalTrackerURL, + ExternalTrackerFormat: config.ExternalTrackerFormat, + ExternalTrackerStyle: config.ExternalTrackerStyle, + ExternalTrackerRegexpPattern: config.ExternalTrackerRegexpPattern, } } hasWiki := false diff --git a/modules/doctor/authorizedkeys.go b/modules/doctor/authorizedkeys.go index 34dfe939d3..d4ceef87c0 100644 --- a/modules/doctor/authorizedkeys.go +++ b/modules/doctor/authorizedkeys.go @@ -14,6 +14,7 @@ import ( "strings" asymkey_model "code.gitea.io/gitea/models/asymkey" + "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" ) @@ -40,7 +41,7 @@ func checkAuthorizedKeys(ctx context.Context, logger log.Logger, autofix bool) e } defer f.Close() - linesInAuthorizedKeys := map[string]bool{} + linesInAuthorizedKeys := make(container.Set[string]) scanner := bufio.NewScanner(f) for scanner.Scan() { @@ -48,7 +49,7 @@ func checkAuthorizedKeys(ctx context.Context, logger log.Logger, autofix bool) e if strings.HasPrefix(line, tplCommentPrefix) { continue } - linesInAuthorizedKeys[line] = true + linesInAuthorizedKeys.Add(line) } f.Close() @@ -64,7 +65,7 @@ func checkAuthorizedKeys(ctx context.Context, logger log.Logger, autofix bool) e if strings.HasPrefix(line, tplCommentPrefix) { continue } - if ok := linesInAuthorizedKeys[line]; ok { + if linesInAuthorizedKeys.Contains(line) { continue } if !autofix { diff --git a/modules/doctor/heads.go b/modules/doctor/heads.go new file mode 100644 index 0000000000..ec14aa4ead --- /dev/null +++ b/modules/doctor/heads.go @@ -0,0 +1,91 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package doctor + +import ( + "context" + + repo_model "code.gitea.io/gitea/models/repo" + "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/log" +) + +func synchronizeRepoHeads(ctx context.Context, logger log.Logger, autofix bool) error { + numRepos := 0 + numHeadsBroken := 0 + numDefaultBranchesBroken := 0 + numReposUpdated := 0 + err := iterateRepositories(ctx, func(repo *repo_model.Repository) error { + numRepos++ + runOpts := &git.RunOpts{Dir: repo.RepoPath()} + + _, _, defaultBranchErr := git.NewCommand(ctx, "rev-parse", "--", repo.DefaultBranch).RunStdString(runOpts) + + head, _, headErr := git.NewCommand(ctx, "symbolic-ref", "--short", "HEAD").RunStdString(runOpts) + + // what we expect: default branch is valid, and HEAD points to it + if headErr == nil && defaultBranchErr == nil && head == repo.DefaultBranch { + return nil + } + + if headErr != nil { + numHeadsBroken++ + } + if defaultBranchErr != nil { + numDefaultBranchesBroken++ + } + + // if default branch is broken, let the user fix that in the UI + if defaultBranchErr != nil { + logger.Warn("Default branch for %s/%s doesn't point to a valid commit", repo.OwnerName, repo.Name) + return nil + } + + // if we're not autofixing, that's all we can do + if !autofix { + return nil + } + + // otherwise, let's try fixing HEAD + err := git.NewCommand(ctx, "symbolic-ref", "--", "HEAD", repo.DefaultBranch).Run(runOpts) + if err != nil { + logger.Warn("Failed to fix HEAD for %s/%s: %v", repo.OwnerName, repo.Name, err) + return nil + } + numReposUpdated++ + return nil + }) + if err != nil { + logger.Critical("Error when fixing repo HEADs: %v", err) + } + + if autofix { + logger.Info("Out of %d repos, HEADs for %d are now fixed and HEADS for %d are still broken", numRepos, numReposUpdated, numDefaultBranchesBroken+numHeadsBroken-numReposUpdated) + } else { + if numHeadsBroken == 0 && numDefaultBranchesBroken == 0 { + logger.Info("All %d repos have their HEADs in the correct state") + } else { + if numHeadsBroken == 0 && numDefaultBranchesBroken != 0 { + logger.Critical("Default branches are broken for %d/%d repos", numDefaultBranchesBroken, numRepos) + } else if numHeadsBroken != 0 && numDefaultBranchesBroken == 0 { + logger.Warn("HEADs are broken for %d/%d repos", numHeadsBroken, numRepos) + } else { + logger.Critical("Out of %d repos, HEADS are broken for %d and default branches are broken for %d", numRepos, numHeadsBroken, numDefaultBranchesBroken) + } + } + } + + return err +} + +func init() { + Register(&Check{ + Title: "Synchronize repo HEADs", + Name: "synchronize-repo-heads", + IsDefault: true, + Run: synchronizeRepoHeads, + Priority: 7, + }) +} diff --git a/modules/git/log_name_status.go b/modules/git/log_name_status.go index 80f1602708..469932525f 100644 --- a/modules/git/log_name_status.go +++ b/modules/git/log_name_status.go @@ -14,6 +14,8 @@ import ( "sort" "strings" + "code.gitea.io/gitea/modules/container" + "github.com/djherbis/buffer" "github.com/djherbis/nio/v3" ) @@ -339,7 +341,7 @@ func WalkGitLog(ctx context.Context, repo *Repository, head *Commit, treepath st lastEmptyParent := head.ID.String() commitSinceLastEmptyParent := uint64(0) commitSinceNextRestart := uint64(0) - parentRemaining := map[string]bool{} + parentRemaining := make(container.Set[string]) changed := make([]bool, len(paths)) @@ -365,7 +367,7 @@ heaploop: if current == nil { break heaploop } - delete(parentRemaining, current.CommitID) + parentRemaining.Remove(current.CommitID) if current.Paths != nil { for i, found := range current.Paths { if !found { @@ -410,14 +412,12 @@ heaploop: } } g = NewLogNameStatusRepoParser(ctx, repo.Path, lastEmptyParent, treepath, remainingPaths...) - parentRemaining = map[string]bool{} + parentRemaining = make(container.Set[string]) nextRestart = (remaining * 3) / 4 continue heaploop } } - for _, parent := range current.ParentIDs { - parentRemaining[parent] = true - } + parentRemaining.AddMultiple(current.ParentIDs...) } g.Close() diff --git a/modules/git/parse_nogogit.go b/modules/git/parse_nogogit.go index c8f0f994fc..fb5b63def9 100644 --- a/modules/git/parse_nogogit.go +++ b/modules/git/parse_nogogit.go @@ -22,70 +22,72 @@ func ParseTreeEntries(data []byte) ([]*TreeEntry, error) { return parseTreeEntries(data, nil) } +var sepSpace = []byte{' '} + func parseTreeEntries(data []byte, ptree *Tree) ([]*TreeEntry, error) { - entries := make([]*TreeEntry, 0, 10) + var err error + entries := make([]*TreeEntry, 0, bytes.Count(data, []byte{'\n'})+1) for pos := 0; pos < len(data); { - // expect line to be of the form " \t" + // expect line to be of the form: + // \t + // \t + posEnd := bytes.IndexByte(data[pos:], '\n') + if posEnd == -1 { + posEnd = len(data) + } else { + posEnd += pos + } + line := data[pos:posEnd] + posTab := bytes.IndexByte(line, '\t') + if posTab == -1 { + return nil, fmt.Errorf("invalid ls-tree output (no tab): %q", line) + } + entry := new(TreeEntry) entry.ptree = ptree - if pos+6 > len(data) { - return nil, fmt.Errorf("Invalid ls-tree output: %s", string(data)) + + entryAttrs := line[:posTab] + entryName := line[posTab+1:] + + entryMode, entryAttrs, _ := bytes.Cut(entryAttrs, sepSpace) + _ /* entryType */, entryAttrs, _ = bytes.Cut(entryAttrs, sepSpace) // the type is not used, the mode is enough to determine the type + entryObjectID, entryAttrs, _ := bytes.Cut(entryAttrs, sepSpace) + if len(entryAttrs) > 0 { + entrySize := entryAttrs // the last field is the space-padded-size + entry.size, _ = strconv.ParseInt(strings.TrimSpace(string(entrySize)), 10, 64) + entry.sized = true } - switch string(data[pos : pos+6]) { + + switch string(entryMode) { case "100644": entry.entryMode = EntryModeBlob - pos += 12 // skip over "100644 blob " case "100755": entry.entryMode = EntryModeExec - pos += 12 // skip over "100755 blob " case "120000": entry.entryMode = EntryModeSymlink - pos += 12 // skip over "120000 blob " case "160000": entry.entryMode = EntryModeCommit - pos += 14 // skip over "160000 object " case "040000", "040755": // git uses 040000 for tree object, but some users may get 040755 for unknown reasons entry.entryMode = EntryModeTree - pos += 12 // skip over "040000 tree " default: - return nil, fmt.Errorf("unknown type: %v", string(data[pos:pos+6])) + return nil, fmt.Errorf("unknown type: %v", string(entryMode)) } - if pos+40 > len(data) { - return nil, fmt.Errorf("Invalid ls-tree output: %s", string(data)) - } - id, err := NewIDFromString(string(data[pos : pos+40])) + entry.ID, err = NewIDFromString(string(entryObjectID)) if err != nil { - return nil, fmt.Errorf("Invalid ls-tree output: %v", err) - } - entry.ID = id - pos += 41 // skip over sha and trailing space - - end := pos + bytes.IndexByte(data[pos:], '\t') - if end < pos { - return nil, fmt.Errorf("Invalid ls-tree -l output: %s", string(data)) - } - entry.size, _ = strconv.ParseInt(strings.TrimSpace(string(data[pos:end])), 10, 64) - entry.sized = true - - pos = end + 1 - - end = pos + bytes.IndexByte(data[pos:], '\n') - if end < pos { - return nil, fmt.Errorf("Invalid ls-tree output: %s", string(data)) + return nil, fmt.Errorf("invalid ls-tree output (invalid object id): %q, err: %w", line, err) } - // In case entry name is surrounded by double quotes(it happens only in git-shell). - if data[pos] == '"' { - entry.name, err = strconv.Unquote(string(data[pos:end])) + if len(entryName) > 0 && entryName[0] == '"' { + entry.name, err = strconv.Unquote(string(entryName)) if err != nil { - return nil, fmt.Errorf("Invalid ls-tree output: %v", err) + return nil, fmt.Errorf("invalid ls-tree output (invalid name): %q, err: %w", line, err) } } else { - entry.name = string(data[pos:end]) + entry.name = string(entryName) } - pos = end + 1 + pos = posEnd + 1 entries = append(entries, entry) } return entries, nil diff --git a/modules/git/parse_nogogit_test.go b/modules/git/parse_nogogit_test.go index 483f96e9a7..cecd3960da 100644 --- a/modules/git/parse_nogogit_test.go +++ b/modules/git/parse_nogogit_test.go @@ -12,7 +12,7 @@ import ( "github.com/stretchr/testify/assert" ) -func TestParseTreeEntries(t *testing.T) { +func TestParseTreeEntriesLong(t *testing.T) { testCases := []struct { Input string Expected []*TreeEntry @@ -59,11 +59,47 @@ func TestParseTreeEntries(t *testing.T) { assert.NoError(t, err) assert.Len(t, entries, len(testCase.Expected)) for i, entry := range entries { - assert.EqualValues(t, testCase.Expected[i].ID, entry.ID) - assert.EqualValues(t, testCase.Expected[i].name, entry.name) - assert.EqualValues(t, testCase.Expected[i].entryMode, entry.entryMode) - assert.EqualValues(t, testCase.Expected[i].sized, entry.sized) - assert.EqualValues(t, testCase.Expected[i].size, entry.size) + assert.EqualValues(t, testCase.Expected[i], entry) } } } + +func TestParseTreeEntriesShort(t *testing.T) { + testCases := []struct { + Input string + Expected []*TreeEntry + }{ + { + Input: `100644 blob ea0d83c9081af9500ac9f804101b3fd0a5c293af README.md +040000 tree 84b90550547016f73c5dd3f50dea662389e67b6d assets +`, + Expected: []*TreeEntry{ + { + ID: MustIDFromString("ea0d83c9081af9500ac9f804101b3fd0a5c293af"), + name: "README.md", + entryMode: EntryModeBlob, + }, + { + ID: MustIDFromString("84b90550547016f73c5dd3f50dea662389e67b6d"), + name: "assets", + entryMode: EntryModeTree, + }, + }, + }, + } + for _, testCase := range testCases { + entries, err := ParseTreeEntries([]byte(testCase.Input)) + assert.NoError(t, err) + assert.Len(t, entries, len(testCase.Expected)) + for i, entry := range entries { + assert.EqualValues(t, testCase.Expected[i], entry) + } + } +} + +func TestParseTreeEntriesInvalid(t *testing.T) { + // there was a panic: "runtime error: slice bounds out of range" when the input was invalid: #20315 + entries, err := ParseTreeEntries([]byte("100644 blob ea0d83c9081af9500ac9f804101b3fd0a5c293af")) + assert.Error(t, err) + assert.Len(t, entries, 0) +} diff --git a/modules/git/repo_attribute.go b/modules/git/repo_attribute.go index 1305e6f224..21ff93e498 100644 --- a/modules/git/repo_attribute.go +++ b/modules/git/repo_attribute.go @@ -191,8 +191,8 @@ func (c *CheckAttributeReader) Run() error { // CheckPath check attr for given path func (c *CheckAttributeReader) CheckPath(path string) (rs map[string]string, err error) { defer func() { - if err != nil { - log.Error("CheckPath returns error: %v", err) + if err != nil && err != c.ctx.Err() { + log.Error("Unexpected error when checking path %s in %s. Error: %v", path, c.Repo.Path, err) } }() diff --git a/modules/git/repo_language_stats_nogogit.go b/modules/git/repo_language_stats_nogogit.go index d237924f92..7388ef403b 100644 --- a/modules/git/repo_language_stats_nogogit.go +++ b/modules/git/repo_language_stats_nogogit.go @@ -57,7 +57,7 @@ func (repo *Repository) GetLanguageStats(commitID string) (map[string]int64, err tree := commit.Tree - entries, err := tree.ListEntriesRecursive() + entries, err := tree.ListEntriesRecursiveWithSize() if err != nil { return nil, err } diff --git a/modules/git/repo_stats.go b/modules/git/repo_stats.go index c0c91c6fc6..cb44c58cec 100644 --- a/modules/git/repo_stats.go +++ b/modules/git/repo_stats.go @@ -13,6 +13,8 @@ import ( "strconv" "strings" "time" + + "code.gitea.io/gitea/modules/container" ) // CodeActivityStats represents git statistics data @@ -80,7 +82,7 @@ func (repo *Repository) GetCodeActivityStats(fromTime time.Time, branch string) stats.Additions = 0 stats.Deletions = 0 authors := make(map[string]*CodeActivityAuthor) - files := make(map[string]bool) + files := make(container.Set[string]) var author string p := 0 for scanner.Scan() { @@ -119,9 +121,7 @@ func (repo *Repository) GetCodeActivityStats(fromTime time.Time, branch string) stats.Deletions += c } } - if _, ok := files[parts[2]]; !ok { - files[parts[2]] = true - } + files.Add(parts[2]) } } } diff --git a/modules/git/tree_gogit.go b/modules/git/tree_gogit.go index 54f8e140fb..480c5e44da 100644 --- a/modules/git/tree_gogit.go +++ b/modules/git/tree_gogit.go @@ -57,8 +57,8 @@ func (t *Tree) ListEntries() (Entries, error) { return entries, nil } -// ListEntriesRecursive returns all entries of current tree recursively including all subtrees -func (t *Tree) ListEntriesRecursive() (Entries, error) { +// ListEntriesRecursiveWithSize returns all entries of current tree recursively including all subtrees +func (t *Tree) ListEntriesRecursiveWithSize() (Entries, error) { if t.gogitTree == nil { err := t.loadTreeObject() if err != nil { @@ -92,3 +92,8 @@ func (t *Tree) ListEntriesRecursive() (Entries, error) { return entries, nil } + +// ListEntriesRecursiveFast is the alias of ListEntriesRecursiveWithSize for the gogit version +func (t *Tree) ListEntriesRecursiveFast() (Entries, error) { + return t.ListEntriesRecursiveWithSize() +} diff --git a/modules/git/tree_nogogit.go b/modules/git/tree_nogogit.go index 7defb064a4..d61d19e4c2 100644 --- a/modules/git/tree_nogogit.go +++ b/modules/git/tree_nogogit.go @@ -99,13 +99,16 @@ func (t *Tree) ListEntries() (Entries, error) { return t.entries, err } -// ListEntriesRecursive returns all entries of current tree recursively including all subtrees -func (t *Tree) ListEntriesRecursive() (Entries, error) { +// listEntriesRecursive returns all entries of current tree recursively including all subtrees +// extraArgs could be "-l" to get the size, which is slower +func (t *Tree) listEntriesRecursive(extraArgs ...string) (Entries, error) { if t.entriesRecursiveParsed { return t.entriesRecursive, nil } - stdout, _, runErr := NewCommand(t.repo.Ctx, "ls-tree", "-t", "-l", "-r", t.ID.String()).RunStdBytes(&RunOpts{Dir: t.repo.Path}) + args := append([]string{"ls-tree", "-t", "-r"}, extraArgs...) + args = append(args, t.ID.String()) + stdout, _, runErr := NewCommand(t.repo.Ctx, args...).RunStdBytes(&RunOpts{Dir: t.repo.Path}) if runErr != nil { return nil, runErr } @@ -118,3 +121,13 @@ func (t *Tree) ListEntriesRecursive() (Entries, error) { return t.entriesRecursive, err } + +// ListEntriesRecursiveFast returns all entries of current tree recursively including all subtrees, no size +func (t *Tree) ListEntriesRecursiveFast() (Entries, error) { + return t.listEntriesRecursive() +} + +// ListEntriesRecursiveWithSize returns all entries of current tree recursively including all subtrees, with size +func (t *Tree) ListEntriesRecursiveWithSize() (Entries, error) { + return t.listEntriesRecursive("--long") +} diff --git a/modules/issue/template/template.go b/modules/issue/template/template.go index a4c0fb5aa6..3b33852cb5 100644 --- a/modules/issue/template/template.go +++ b/modules/issue/template/template.go @@ -11,6 +11,7 @@ import ( "strconv" "strings" + "code.gitea.io/gitea/modules/container" api "code.gitea.io/gitea/modules/structs" "gitea.com/go-chi/binding" @@ -43,7 +44,7 @@ func validateYaml(template *api.IssueTemplate) error { if len(template.Fields) == 0 { return fmt.Errorf("'body' is required") } - ids := map[string]struct{}{} + ids := make(container.Set[string]) for idx, field := range template.Fields { if err := validateID(field, idx, ids); err != nil { return err @@ -125,7 +126,7 @@ func validateRequired(field *api.IssueFormField, idx int) error { return validateBoolItem(newErrorPosition(idx, field.Type), field.Validations, "required") } -func validateID(field *api.IssueFormField, idx int, ids map[string]struct{}) error { +func validateID(field *api.IssueFormField, idx int, ids container.Set[string]) error { if field.Type == api.IssueFormFieldTypeMarkdown { // The ID is not required for a markdown field return nil @@ -139,10 +140,9 @@ func validateID(field *api.IssueFormField, idx int, ids map[string]struct{}) err if binding.AlphaDashPattern.MatchString(field.ID) { return position.Errorf("'id' should contain only alphanumeric, '-' and '_'") } - if _, ok := ids[field.ID]; ok { + if !ids.Add(field.ID) { return position.Errorf("'id' should be unique") } - ids[field.ID] = struct{}{} return nil } diff --git a/modules/markup/html_test.go b/modules/markup/html_test.go index 370bc21822..e57187a677 100644 --- a/modules/markup/html_test.go +++ b/modules/markup/html_test.go @@ -7,6 +7,7 @@ package markup_test import ( "context" "io" + "os" "strings" "testing" @@ -32,6 +33,7 @@ func TestMain(m *testing.M) { if err := git.InitSimple(context.Background()); err != nil { log.Fatal("git init failed, err: %v", err) } + os.Exit(m.Run()) } func TestRender_Commits(t *testing.T) { @@ -336,7 +338,7 @@ func TestRender_emoji(t *testing.T) { `

Some text with 😄😄 2 emoji next to each other

`) test( "😎🤪🔐🤑❓", - `

😎🤪🔐🤑

`) + `

😎🤪🔐🤑

`) // should match nothing test( diff --git a/modules/markup/markdown/goldmark.go b/modules/markup/markdown/goldmark.go index 24f1ab7a01..8417019ddb 100644 --- a/modules/markup/markdown/goldmark.go +++ b/modules/markup/markdown/goldmark.go @@ -10,6 +10,7 @@ import ( "regexp" "strings" + "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/markup" "code.gitea.io/gitea/modules/markup/common" "code.gitea.io/gitea/modules/setting" @@ -198,7 +199,7 @@ func (g *ASTTransformer) Transform(node *ast.Document, reader text.Reader, pc pa } type prefixedIDs struct { - values map[string]bool + values container.Set[string] } // Generate generates a new element id. @@ -219,14 +220,12 @@ func (p *prefixedIDs) GenerateWithDefault(value, dft []byte) []byte { if !bytes.HasPrefix(result, []byte("user-content-")) { result = append([]byte("user-content-"), result...) } - if _, ok := p.values[util.BytesToReadOnlyString(result)]; !ok { - p.values[util.BytesToReadOnlyString(result)] = true + if p.values.Add(util.BytesToReadOnlyString(result)) { return result } for i := 1; ; i++ { newResult := fmt.Sprintf("%s-%d", result, i) - if _, ok := p.values[newResult]; !ok { - p.values[newResult] = true + if p.values.Add(newResult) { return []byte(newResult) } } @@ -234,12 +233,12 @@ func (p *prefixedIDs) GenerateWithDefault(value, dft []byte) []byte { // Put puts a given element id to the used ids table. func (p *prefixedIDs) Put(value []byte) { - p.values[util.BytesToReadOnlyString(value)] = true + p.values.Add(util.BytesToReadOnlyString(value)) } func newPrefixedIDs() *prefixedIDs { return &prefixedIDs{ - values: map[string]bool{}, + values: make(container.Set[string]), } } diff --git a/modules/markup/markdown/markdown_test.go b/modules/markup/markdown/markdown_test.go index fdbc291c94..49ed3d75d6 100644 --- a/modules/markup/markdown/markdown_test.go +++ b/modules/markup/markdown/markdown_test.go @@ -6,6 +6,7 @@ package markdown_test import ( "context" + "os" "strings" "testing" @@ -37,6 +38,7 @@ func TestMain(m *testing.M) { if err := git.InitSimple(context.Background()); err != nil { log.Fatal("git init failed, err: %v", err) } + os.Exit(m.Run()) } func TestRender_StandardLinks(t *testing.T) { @@ -426,3 +428,51 @@ func TestRenderEmojiInLinks_Issue12331(t *testing.T) { assert.NoError(t, err) assert.Equal(t, expected, res) } + +func TestMathBlock(t *testing.T) { + const nl = "\n" + testcases := []struct { + testcase string + expected string + }{ + { + "$a$", + `

a

` + nl, + }, + { + "$ a $", + `

a

` + nl, + }, + { + "$a$ $b$", + `

a b

` + nl, + }, + { + `\(a\) \(b\)`, + `

a b

` + nl, + }, + { + `$a a$b b$`, + `

a a$b b

` + nl, + }, + { + `a a$b b`, + `

a a$b b

` + nl, + }, + { + `a$b $a a$b b$`, + `

a$b a a$b b

` + nl, + }, + { + "$$a$$", + `
a
` + nl, + }, + } + + for _, test := range testcases { + res, err := RenderString(&markup.RenderContext{}, test.testcase) + assert.NoError(t, err, "Unexpected error in testcase: %q", test.testcase) + assert.Equal(t, test.expected, res, "Unexpected result in testcase %q", test.testcase) + + } +} diff --git a/modules/markup/markdown/math/inline_parser.go b/modules/markup/markdown/math/inline_parser.go index 0339674b6c..8dc88eb858 100644 --- a/modules/markup/markdown/math/inline_parser.go +++ b/modules/markup/markdown/math/inline_parser.go @@ -37,7 +37,7 @@ func NewInlineBracketParser() parser.InlineParser { return defaultInlineBracketParser } -// Trigger triggers this parser on $ +// Trigger triggers this parser on $ or \ func (parser *inlineParser) Trigger() []byte { return parser.start[0:1] } @@ -50,29 +50,50 @@ func isAlphanumeric(b byte) bool { // Parse parses the current line and returns a result of parsing. func (parser *inlineParser) Parse(parent ast.Node, block text.Reader, pc parser.Context) ast.Node { line, _ := block.PeekLine() - opener := bytes.Index(line, parser.start) - if opener < 0 { - return nil - } - if opener != 0 && isAlphanumeric(line[opener-1]) { + + if !bytes.HasPrefix(line, parser.start) { + // We'll catch this one on the next time round return nil } - opener += len(parser.start) - ender := bytes.Index(line[opener:], parser.end) - if ender < 0 { + precedingCharacter := block.PrecendingCharacter() + if precedingCharacter < 256 && isAlphanumeric(byte(precedingCharacter)) { + // need to exclude things like `a$` from being considered a start return nil } - if len(line) > opener+ender+len(parser.end) && isAlphanumeric(line[opener+ender+len(parser.end)]) { - return nil + + // move the opener marker point at the start of the text + opener := len(parser.start) + + // Now look for an ending line + ender := opener + for { + pos := bytes.Index(line[ender:], parser.end) + if pos < 0 { + return nil + } + + ender += pos + + // Now we want to check the character at the end of our parser section + // that is ender + len(parser.end) + pos = ender + len(parser.end) + if len(line) <= pos { + break + } + if !isAlphanumeric(line[pos]) { + break + } + // move the pointer onwards + ender += len(parser.end) } block.Advance(opener) _, pos := block.Position() node := NewInline() - segment := pos.WithStop(pos.Start + ender) + segment := pos.WithStop(pos.Start + ender - opener) node.AppendChild(node, ast.NewRawTextSegment(segment)) - block.Advance(ender + len(parser.end)) + block.Advance(ender - opener + len(parser.end)) trimBlock(node, block) return node diff --git a/modules/markup/markdown/meta.go b/modules/markup/markdown/meta.go index b08121e868..45d79d537a 100644 --- a/modules/markup/markdown/meta.go +++ b/modules/markup/markdown/meta.go @@ -88,7 +88,9 @@ func ExtractMetadataBytes(contents []byte, out interface{}) ([]byte, error) { line := contents[start:end] if isYAMLSeparator(line) { front = contents[frontMatterStart:start] - body = contents[end+1:] + if end+1 < len(contents) { + body = contents[end+1:] + } break } } diff --git a/modules/markup/markdown/meta_test.go b/modules/markup/markdown/meta_test.go index 9332b35b42..720d0066f4 100644 --- a/modules/markup/markdown/meta_test.go +++ b/modules/markup/markdown/meta_test.go @@ -61,7 +61,7 @@ func TestExtractMetadataBytes(t *testing.T) { var meta structs.IssueTemplate body, err := ExtractMetadataBytes([]byte(fmt.Sprintf("%s\n%s\n%s\n%s", sepTest, frontTest, sepTest, bodyTest)), &meta) assert.NoError(t, err) - assert.Equal(t, bodyTest, body) + assert.Equal(t, bodyTest, string(body)) assert.Equal(t, metaTest, meta) assert.True(t, validateMetadata(meta)) }) @@ -82,7 +82,7 @@ func TestExtractMetadataBytes(t *testing.T) { var meta structs.IssueTemplate body, err := ExtractMetadataBytes([]byte(fmt.Sprintf("%s\n%s\n%s", sepTest, frontTest, sepTest)), &meta) assert.NoError(t, err) - assert.Equal(t, "", body) + assert.Equal(t, "", string(body)) assert.Equal(t, metaTest, meta) assert.True(t, validateMetadata(meta)) }) diff --git a/modules/markup/markdown/renderconfig.go b/modules/markup/markdown/renderconfig.go index 003579115f..1ba75dbb68 100644 --- a/modules/markup/markdown/renderconfig.go +++ b/modules/markup/markdown/renderconfig.go @@ -5,10 +5,9 @@ package markdown import ( + "fmt" "strings" - "code.gitea.io/gitea/modules/log" - "github.com/yuin/goldmark/ast" "gopkg.in/yaml.v3" ) @@ -33,17 +32,13 @@ func (rc *RenderConfig) UnmarshalYAML(value *yaml.Node) error { } rc.yamlNode = value - type basicRenderConfig struct { - Gitea *yaml.Node `yaml:"gitea"` - TOC bool `yaml:"include_toc"` - Lang string `yaml:"lang"` + type commonRenderConfig struct { + TOC bool `yaml:"include_toc"` + Lang string `yaml:"lang"` } - - var basic basicRenderConfig - - err := value.Decode(&basic) - if err != nil { - return err + var basic commonRenderConfig + if err := value.Decode(&basic); err != nil { + return fmt.Errorf("unable to decode into commonRenderConfig %w", err) } if basic.Lang != "" { @@ -51,14 +46,48 @@ func (rc *RenderConfig) UnmarshalYAML(value *yaml.Node) error { } rc.TOC = basic.TOC - if basic.Gitea == nil { + + type controlStringRenderConfig struct { + Gitea string `yaml:"gitea"` + } + + var stringBasic controlStringRenderConfig + + if err := value.Decode(&stringBasic); err == nil { + if stringBasic.Gitea != "" { + switch strings.TrimSpace(strings.ToLower(stringBasic.Gitea)) { + case "none": + rc.Meta = "none" + case "table": + rc.Meta = "table" + default: // "details" + rc.Meta = "details" + } + } return nil } - var control *string - if err := basic.Gitea.Decode(&control); err == nil && control != nil { - log.Info("control %v", control) - switch strings.TrimSpace(strings.ToLower(*control)) { + type giteaControl struct { + Meta *string `yaml:"meta"` + Icon *string `yaml:"details_icon"` + TOC *bool `yaml:"include_toc"` + Lang *string `yaml:"lang"` + } + + type complexGiteaConfig struct { + Gitea *giteaControl `yaml:"gitea"` + } + var complex complexGiteaConfig + if err := value.Decode(&complex); err != nil { + return fmt.Errorf("unable to decode into complexRenderConfig %w", err) + } + + if complex.Gitea == nil { + return nil + } + + if complex.Gitea.Meta != nil { + switch strings.TrimSpace(strings.ToLower(*complex.Gitea.Meta)) { case "none": rc.Meta = "none" case "table": @@ -66,39 +95,18 @@ func (rc *RenderConfig) UnmarshalYAML(value *yaml.Node) error { default: // "details" rc.Meta = "details" } - return nil } - type giteaControl struct { - Meta string `yaml:"meta"` - Icon string `yaml:"details_icon"` - TOC *yaml.Node `yaml:"include_toc"` - Lang string `yaml:"lang"` + if complex.Gitea.Icon != nil { + rc.Icon = strings.TrimSpace(strings.ToLower(*complex.Gitea.Icon)) } - var controlStruct *giteaControl - if err := basic.Gitea.Decode(controlStruct); err != nil || controlStruct == nil { - return err + if complex.Gitea.Lang != nil && *complex.Gitea.Lang != "" { + rc.Lang = *complex.Gitea.Lang } - switch strings.TrimSpace(strings.ToLower(controlStruct.Meta)) { - case "none": - rc.Meta = "none" - case "table": - rc.Meta = "table" - default: // "details" - rc.Meta = "details" - } - - rc.Icon = strings.TrimSpace(strings.ToLower(controlStruct.Icon)) - - if controlStruct.Lang != "" { - rc.Lang = controlStruct.Lang - } - - var toc bool - if err := controlStruct.TOC.Decode(&toc); err == nil { - rc.TOC = toc + if complex.Gitea.TOC != nil { + rc.TOC = *complex.Gitea.TOC } return nil diff --git a/modules/markup/markdown/renderconfig_test.go b/modules/markup/markdown/renderconfig_test.go index 1027035cda..672edbf46d 100644 --- a/modules/markup/markdown/renderconfig_test.go +++ b/modules/markup/markdown/renderconfig_test.go @@ -5,6 +5,7 @@ package markdown import ( + "strings" "testing" "gopkg.in/yaml.v3" @@ -81,9 +82,9 @@ func TestRenderConfig_UnmarshalYAML(t *testing.T) { TOC: true, Lang: "testlang", }, ` - include_toc: true - lang: testlang -`, + include_toc: true + lang: testlang + `, }, { "complexlang", &RenderConfig{ @@ -91,9 +92,9 @@ func TestRenderConfig_UnmarshalYAML(t *testing.T) { Icon: "table", Lang: "testlang", }, ` - gitea: - lang: testlang -`, + gitea: + lang: testlang + `, }, { "complexlang2", &RenderConfig{ @@ -140,8 +141,8 @@ func TestRenderConfig_UnmarshalYAML(t *testing.T) { Icon: "table", Lang: "", } - if err := yaml.Unmarshal([]byte(tt.args), got); err != nil { - t.Errorf("RenderConfig.UnmarshalYAML() error = %v", err) + if err := yaml.Unmarshal([]byte(strings.ReplaceAll(tt.args, "\t", " ")), got); err != nil { + t.Errorf("RenderConfig.UnmarshalYAML() error = %v\n%q", err, tt.args) return } diff --git a/modules/notification/ui/ui.go b/modules/notification/ui/ui.go index 5e5196a70a..4d96a6b0ed 100644 --- a/modules/notification/ui/ui.go +++ b/modules/notification/ui/ui.go @@ -10,6 +10,7 @@ import ( issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/notification/base" @@ -123,14 +124,14 @@ func (ns *notificationService) NotifyNewPullRequest(pr *issues_model.PullRequest log.Error("Unable to load issue: %d for pr: %d: Error: %v", pr.IssueID, pr.ID, err) return } - toNotify := make(map[int64]struct{}, 32) + toNotify := make(container.Set[int64], 32) repoWatchers, err := repo_model.GetRepoWatchersIDs(db.DefaultContext, pr.Issue.RepoID) if err != nil { log.Error("GetRepoWatchersIDs: %v", err) return } for _, id := range repoWatchers { - toNotify[id] = struct{}{} + toNotify.Add(id) } issueParticipants, err := issues_model.GetParticipantsIDsByIssueID(pr.IssueID) if err != nil { @@ -138,11 +139,11 @@ func (ns *notificationService) NotifyNewPullRequest(pr *issues_model.PullRequest return } for _, id := range issueParticipants { - toNotify[id] = struct{}{} + toNotify.Add(id) } delete(toNotify, pr.Issue.PosterID) for _, mention := range mentions { - toNotify[mention.ID] = struct{}{} + toNotify.Add(mention.ID) } for receiverID := range toNotify { _ = ns.issueQueue.Push(issueNotificationOpts{ diff --git a/modules/options/static.go b/modules/options/static.go index d9a6c83664..4d60879be3 100644 --- a/modules/options/static.go +++ b/modules/options/static.go @@ -1,4 +1,4 @@ -// Copyright 2016 The Gitea Authors. All rights reserved. +// Copyright 2022 The Gitea Authors. All rights reserved. // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. @@ -32,12 +32,12 @@ func Dir(name string) ([]string, error) { customDir := path.Join(setting.CustomPath, "options", name) isDir, err := util.IsDir(customDir) if err != nil { - return []string{}, fmt.Errorf("Failed to check if custom directory %s is a directory. %v", err) + return []string{}, fmt.Errorf("unable to check if custom directory %q is a directory. %w", customDir, err) } if isDir { files, err := util.StatDir(customDir, true) if err != nil { - return []string{}, fmt.Errorf("Failed to read custom directory. %v", err) + return []string{}, fmt.Errorf("unable to read custom directory %q. %w", customDir, err) } result = append(result, files...) @@ -45,11 +45,10 @@ func Dir(name string) ([]string, error) { files, err := AssetDir(name) if err != nil { - return []string{}, fmt.Errorf("Failed to read embedded directory. %v", err) + return []string{}, fmt.Errorf("unable to read embedded directory %q. %w", name, err) } result = append(result, files...) - return directories.AddAndGet(name, result), nil } diff --git a/modules/packages/npm/creator.go b/modules/packages/npm/creator.go index 2ed4d26248..16cadefb89 100644 --- a/modules/packages/npm/creator.go +++ b/modules/packages/npm/creator.go @@ -66,7 +66,8 @@ type PackageMetadata struct { License string `json:"license,omitempty"` } -// PackageMetadataVersion https://github.com/npm/registry/blob/master/docs/REGISTRY-API.md#version +// PackageMetadataVersion documentation: https://github.com/npm/registry/blob/master/docs/REGISTRY-API.md#version +// PackageMetadataVersion response: https://github.com/npm/registry/blob/master/docs/responses/package-metadata.md#abbreviated-version-object type PackageMetadataVersion struct { ID string `json:"_id"` Name string `json:"name"` @@ -80,6 +81,7 @@ type PackageMetadataVersion struct { Dependencies map[string]string `json:"dependencies,omitempty"` DevDependencies map[string]string `json:"devDependencies,omitempty"` PeerDependencies map[string]string `json:"peerDependencies,omitempty"` + Bin map[string]string `json:"bin,omitempty"` OptionalDependencies map[string]string `json:"optionalDependencies,omitempty"` Readme string `json:"readme,omitempty"` Dist PackageDistribution `json:"dist"` @@ -220,6 +222,7 @@ func ParsePackage(r io.Reader) (*Package, error) { DevelopmentDependencies: meta.DevDependencies, PeerDependencies: meta.PeerDependencies, OptionalDependencies: meta.OptionalDependencies, + Bin: meta.Bin, Readme: meta.Readme, }, } diff --git a/modules/packages/npm/creator_test.go b/modules/packages/npm/creator_test.go index 64ae6238f3..2b844f4b0e 100644 --- a/modules/packages/npm/creator_test.go +++ b/modules/packages/npm/creator_test.go @@ -23,6 +23,7 @@ func TestParsePackage(t *testing.T) { packageVersion := "1.0.1-pre" packageTag := "latest" packageAuthor := "KN4CK3R" + packageBin := "gitea" packageDescription := "Test Description" data := "H4sIAAAAAAAA/ytITM5OTE/VL4DQelnF+XkMVAYGBgZmJiYK2MRBwNDcSIHB2NTMwNDQzMwAqA7IMDUxA9LUdgg2UFpcklgEdAql5kD8ogCnhwio5lJQUMpLzE1VslJQcihOzi9I1S9JLS7RhSYIJR2QgrLUouLM/DyQGkM9Az1D3YIiqExKanFyUWZBCVQ2BKhVwQVJDKwosbQkI78IJO/tZ+LsbRykxFXLNdA+HwWjYBSMgpENACgAbtAACAAA" integrity := "sha512-yA4FJsVhetynGfOC1jFf79BuS+jrHbm0fhh+aHzCQkOaOBXKf9oBnC4a6DnLLnEsHQDRLYd00cwj8sCXpC+wIg==" @@ -236,6 +237,9 @@ func TestParsePackage(t *testing.T) { Dependencies: map[string]string{ "package": "1.2.0", }, + Bin: map[string]string{ + "bin": packageBin, + }, Dist: PackageDistribution{ Integrity: integrity, }, @@ -264,6 +268,7 @@ func TestParsePackage(t *testing.T) { assert.Equal(t, packageDescription, p.Metadata.Description) assert.Equal(t, packageDescription, p.Metadata.Readme) assert.Equal(t, packageAuthor, p.Metadata.Author) + assert.Equal(t, packageBin, p.Metadata.Bin["bin"]) assert.Equal(t, "MIT", p.Metadata.License) assert.Equal(t, "https://gitea.io/", p.Metadata.ProjectURL) assert.Contains(t, p.Metadata.Dependencies, "package") diff --git a/modules/packages/npm/metadata.go b/modules/packages/npm/metadata.go index 643a4d344b..44714cd6ea 100644 --- a/modules/packages/npm/metadata.go +++ b/modules/packages/npm/metadata.go @@ -20,5 +20,6 @@ type Metadata struct { DevelopmentDependencies map[string]string `json:"development_dependencies,omitempty"` PeerDependencies map[string]string `json:"peer_dependencies,omitempty"` OptionalDependencies map[string]string `json:"optional_dependencies,omitempty"` + Bin map[string]string `json:"bin,omitempty"` Readme string `json:"readme,omitempty"` } diff --git a/modules/private/internal.go b/modules/private/internal.go index 2ea516ba80..21e5c9a279 100644 --- a/modules/private/internal.go +++ b/modules/private/internal.go @@ -10,6 +10,8 @@ import ( "fmt" "net" "net/http" + "os" + "strings" "code.gitea.io/gitea/modules/httplib" "code.gitea.io/gitea/modules/json" @@ -18,13 +20,14 @@ import ( "code.gitea.io/gitea/modules/setting" ) -func newRequest(ctx context.Context, url, method string) *httplib.Request { +func newRequest(ctx context.Context, url, method, sourceIP string) *httplib.Request { if setting.InternalToken == "" { log.Fatal(`The INTERNAL_TOKEN setting is missing from the configuration file: %q. Ensure you are running in the correct environment or set the correct configuration file with -c.`, setting.CustomConf) } return httplib.NewRequest(url, method). SetContext(ctx). + Header("X-Real-IP", sourceIP). Header("Authorization", fmt.Sprintf("Bearer %s", setting.InternalToken)) } @@ -42,8 +45,16 @@ func decodeJSONError(resp *http.Response) *Response { return &res } +func getClientIP() string { + sshConnEnv := strings.TrimSpace(os.Getenv("SSH_CONNECTION")) + if len(sshConnEnv) == 0 { + return "127.0.0.1" + } + return strings.Fields(sshConnEnv)[0] +} + func newInternalRequest(ctx context.Context, url, method string) *httplib.Request { - req := newRequest(ctx, url, method).SetTLSClientConfig(&tls.Config{ + req := newRequest(ctx, url, method, getClientIP()).SetTLSClientConfig(&tls.Config{ InsecureSkipVerify: true, ServerName: setting.Domain, }) diff --git a/modules/public/public.go b/modules/public/public.go index 7804e945e7..ac1d80c860 100644 --- a/modules/public/public.go +++ b/modules/public/public.go @@ -11,6 +11,7 @@ import ( "path/filepath" "strings" + "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/httpcache" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" @@ -83,11 +84,11 @@ func AssetsHandlerFunc(opts *Options) http.HandlerFunc { } // parseAcceptEncoding parse Accept-Encoding: deflate, gzip;q=1.0, *;q=0.5 as compress methods -func parseAcceptEncoding(val string) map[string]bool { +func parseAcceptEncoding(val string) container.Set[string] { parts := strings.Split(val, ";") - types := make(map[string]bool) + types := make(container.Set[string]) for _, v := range strings.Split(parts[0], ",") { - types[strings.TrimSpace(v)] = true + types.Add(strings.TrimSpace(v)) } return types } diff --git a/modules/public/public_test.go b/modules/public/public_test.go index 430e734564..8b58d6af33 100644 --- a/modules/public/public_test.go +++ b/modules/public/public_test.go @@ -7,28 +7,23 @@ package public import ( "testing" + "code.gitea.io/gitea/modules/container" + "github.com/stretchr/testify/assert" ) func TestParseAcceptEncoding(t *testing.T) { kases := []struct { Header string - Expected map[string]bool + Expected container.Set[string] }{ { - Header: "deflate, gzip;q=1.0, *;q=0.5", - Expected: map[string]bool{ - "deflate": true, - "gzip": true, - }, + Header: "deflate, gzip;q=1.0, *;q=0.5", + Expected: container.SetOf("deflate", "gzip"), }, { - Header: " gzip, deflate, br", - Expected: map[string]bool{ - "deflate": true, - "gzip": true, - "br": true, - }, + Header: " gzip, deflate, br", + Expected: container.SetOf("deflate", "gzip", "br"), }, } diff --git a/modules/public/serve_static.go b/modules/public/serve_static.go index 9666880adf..10120bf85d 100644 --- a/modules/public/serve_static.go +++ b/modules/public/serve_static.go @@ -60,7 +60,7 @@ func AssetIsDir(name string) (bool, error) { // serveContent serve http content func serveContent(w http.ResponseWriter, req *http.Request, fi os.FileInfo, modtime time.Time, content io.ReadSeeker) { encodings := parseAcceptEncoding(req.Header.Get("Accept-Encoding")) - if encodings["gzip"] { + if encodings.Contains("gzip") { if cf, ok := fi.(*vfsgen۰CompressedFileInfo); ok { rdGzip := bytes.NewReader(cf.GzipBytes()) // all static files are managed by Gitea, so we can make sure every file has the correct ext name diff --git a/modules/queue/unique_queue_channel.go b/modules/queue/unique_queue_channel.go index 6e8d37a20c..d1bf7239eb 100644 --- a/modules/queue/unique_queue_channel.go +++ b/modules/queue/unique_queue_channel.go @@ -12,6 +12,7 @@ import ( "sync/atomic" "time" + "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/log" ) @@ -33,7 +34,7 @@ type ChannelUniqueQueueConfiguration ChannelQueueConfiguration type ChannelUniqueQueue struct { *WorkerPool lock sync.Mutex - table map[string]bool + table container.Set[string] shutdownCtx context.Context shutdownCtxCancel context.CancelFunc terminateCtx context.Context @@ -58,7 +59,7 @@ func NewChannelUniqueQueue(handle HandlerFunc, cfg, exemplar interface{}) (Queue shutdownCtx, shutdownCtxCancel := context.WithCancel(terminateCtx) queue := &ChannelUniqueQueue{ - table: map[string]bool{}, + table: make(container.Set[string]), shutdownCtx: shutdownCtx, shutdownCtxCancel: shutdownCtxCancel, terminateCtx: terminateCtx, @@ -73,7 +74,7 @@ func NewChannelUniqueQueue(handle HandlerFunc, cfg, exemplar interface{}) (Queue bs, _ := json.Marshal(datum) queue.lock.Lock() - delete(queue.table, string(bs)) + queue.table.Remove(string(bs)) queue.lock.Unlock() if u := handle(datum); u != nil { @@ -127,16 +128,15 @@ func (q *ChannelUniqueQueue) PushFunc(data Data, fn func() error) error { q.lock.Unlock() } }() - if _, ok := q.table[string(bs)]; ok { + if !q.table.Add(string(bs)) { return ErrAlreadyInQueue } // FIXME: We probably need to implement some sort of limit here // If the downstream queue blocks this table will grow without limit - q.table[string(bs)] = true if fn != nil { err := fn() if err != nil { - delete(q.table, string(bs)) + q.table.Remove(string(bs)) return err } } @@ -155,8 +155,7 @@ func (q *ChannelUniqueQueue) Has(data Data) (bool, error) { q.lock.Lock() defer q.lock.Unlock() - _, has := q.table[string(bs)] - return has, nil + return q.table.Contains(string(bs)), nil } // Flush flushes the channel with a timeout - the Flush worker will be registered as a flush worker with the manager diff --git a/modules/repository/repo.go b/modules/repository/repo.go index 48c3edf60f..b01be322d2 100644 --- a/modules/repository/repo.go +++ b/modules/repository/repo.go @@ -18,6 +18,7 @@ import ( "code.gitea.io/gitea/models/organization" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/lfs" "code.gitea.io/gitea/modules/log" @@ -275,7 +276,7 @@ func SyncReleasesWithTags(repo *repo_model.Repository, gitRepo *git.Repository) return pullMirrorReleaseSync(repo, gitRepo) } - existingRelTags := make(map[string]struct{}) + existingRelTags := make(container.Set[string]) opts := repo_model.FindReleasesOptions{ IncludeDrafts: true, IncludeTags: true, @@ -303,14 +304,14 @@ func SyncReleasesWithTags(repo *repo_model.Repository, gitRepo *git.Repository) return fmt.Errorf("unable to PushUpdateDeleteTag: %q in Repo[%d:%s/%s]: %w", rel.TagName, repo.ID, repo.OwnerName, repo.Name, err) } } else { - existingRelTags[strings.ToLower(rel.TagName)] = struct{}{} + existingRelTags.Add(strings.ToLower(rel.TagName)) } } } _, err := gitRepo.WalkReferences(git.ObjectTag, 0, 0, func(sha1, refname string) error { tagName := strings.TrimPrefix(refname, git.TagPrefix) - if _, ok := existingRelTags[strings.ToLower(tagName)]; ok { + if existingRelTags.Contains(strings.ToLower(tagName)) { return nil } diff --git a/modules/setting/queue.go b/modules/setting/queue.go index cb86cbdfe0..d3bb33b248 100644 --- a/modules/setting/queue.go +++ b/modules/setting/queue.go @@ -9,6 +9,7 @@ import ( "strconv" "time" + "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/log" ini "gopkg.in/ini.v1" @@ -109,8 +110,8 @@ func NewQueueService() { // Now handle the old issue_indexer configuration // FIXME: DEPRECATED to be removed in v1.18.0 section := Cfg.Section("queue.issue_indexer") - directlySet := toDirectlySetKeysMap(section) - if !directlySet["TYPE"] && defaultType == "" { + directlySet := toDirectlySetKeysSet(section) + if !directlySet.Contains("TYPE") && defaultType == "" { switch typ := Cfg.Section("indexer").Key("ISSUE_INDEXER_QUEUE_TYPE").MustString(""); typ { case "levelqueue": _, _ = section.NewKey("TYPE", "level") @@ -124,25 +125,25 @@ func NewQueueService() { log.Fatal("Unsupported indexer queue type: %v", typ) } } - if !directlySet["LENGTH"] { + if !directlySet.Contains("LENGTH") { length := Cfg.Section("indexer").Key("UPDATE_BUFFER_LEN").MustInt(0) if length != 0 { _, _ = section.NewKey("LENGTH", strconv.Itoa(length)) } } - if !directlySet["BATCH_LENGTH"] { + if !directlySet.Contains("BATCH_LENGTH") { fallback := Cfg.Section("indexer").Key("ISSUE_INDEXER_QUEUE_BATCH_NUMBER").MustInt(0) if fallback != 0 { _, _ = section.NewKey("BATCH_LENGTH", strconv.Itoa(fallback)) } } - if !directlySet["DATADIR"] { + if !directlySet.Contains("DATADIR") { queueDir := filepath.ToSlash(Cfg.Section("indexer").Key("ISSUE_INDEXER_QUEUE_DIR").MustString("")) if queueDir != "" { _, _ = section.NewKey("DATADIR", queueDir) } } - if !directlySet["CONN_STR"] { + if !directlySet.Contains("CONN_STR") { connStr := Cfg.Section("indexer").Key("ISSUE_INDEXER_QUEUE_CONN_STR").MustString("") if connStr != "" { _, _ = section.NewKey("CONN_STR", connStr) @@ -178,19 +179,19 @@ func handleOldLengthConfiguration(queueName, oldSection, oldKey string, defaultV } section := Cfg.Section("queue." + queueName) - directlySet := toDirectlySetKeysMap(section) - if !directlySet["LENGTH"] { + directlySet := toDirectlySetKeysSet(section) + if !directlySet.Contains("LENGTH") { _, _ = section.NewKey("LENGTH", strconv.Itoa(value)) } } -// toDirectlySetKeysMap returns a bool map of keys directly set by this section +// toDirectlySetKeysSet returns a set of keys directly set by this section // Note: we cannot use section.HasKey(...) as that will immediately set the Key if a parent section has the Key // but this section does not. -func toDirectlySetKeysMap(section *ini.Section) map[string]bool { - sectionMap := map[string]bool{} +func toDirectlySetKeysSet(section *ini.Section) container.Set[string] { + sections := make(container.Set[string]) for _, key := range section.Keys() { - sectionMap[key.Name()] = true + sections.Add(key.Name()) } - return sectionMap + return sections } diff --git a/modules/setting/setting.go b/modules/setting/setting.go index 6233437bf5..007e3ef61f 100644 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -21,6 +21,7 @@ import ( "text/template" "time" + "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/user" @@ -234,7 +235,7 @@ var ( DefaultTheme string Themes []string Reactions []string - ReactionsMap map[string]bool `ini:"-"` + ReactionsLookup container.Set[string] `ini:"-"` CustomEmojis []string CustomEmojisMap map[string]string `ini:"-"` SearchRepoDescription bool @@ -1100,9 +1101,9 @@ func loadFromConf(allowEmpty bool, extraConfig string) { newMarkup() - UI.ReactionsMap = make(map[string]bool) + UI.ReactionsLookup = make(container.Set[string]) for _, reaction := range UI.Reactions { - UI.ReactionsMap[reaction] = true + UI.ReactionsLookup.Add(reaction) } UI.CustomEmojisMap = make(map[string]string) for _, emoji := range UI.CustomEmojis { diff --git a/modules/structs/org_team.go b/modules/structs/org_team.go index 53e3fcf62d..10bd9e62ce 100644 --- a/modules/structs/org_team.go +++ b/modules/structs/org_team.go @@ -17,7 +17,7 @@ type Team struct { // example: ["repo.code","repo.issues","repo.ext_issues","repo.wiki","repo.pulls","repo.releases","repo.projects","repo.ext_wiki"] // Deprecated: This variable should be replaced by UnitsMap and will be dropped in later versions. Units []string `json:"units"` - // example: {"repo.code":"read","repo.issues":"write","repo.ext_issues":"none","repo.wiki":"admin","repo.pulls":"owner","repo.releases":"none","repo.projects":"none","repo.ext_wiki":"none"] + // example: {"repo.code":"read","repo.issues":"write","repo.ext_issues":"none","repo.wiki":"admin","repo.pulls":"owner","repo.releases":"none","repo.projects":"none","repo.ext_wiki":"none"} UnitsMap map[string]string `json:"units_map"` CanCreateOrgRepo bool `json:"can_create_org_repo"` } @@ -33,7 +33,7 @@ type CreateTeamOption struct { // example: ["repo.code","repo.issues","repo.ext_issues","repo.wiki","repo.pulls","repo.releases","repo.projects","repo.ext_wiki"] // Deprecated: This variable should be replaced by UnitsMap and will be dropped in later versions. Units []string `json:"units"` - // example: {"repo.code":"read","repo.issues":"write","repo.ext_issues":"none","repo.wiki":"admin","repo.pulls":"owner","repo.releases":"none","repo.projects":"none","repo.ext_wiki":"none"] + // example: {"repo.code":"read","repo.issues":"write","repo.ext_issues":"none","repo.wiki":"admin","repo.pulls":"owner","repo.releases":"none","repo.projects":"none","repo.ext_wiki":"none"} UnitsMap map[string]string `json:"units_map"` CanCreateOrgRepo bool `json:"can_create_org_repo"` } @@ -49,7 +49,7 @@ type EditTeamOption struct { // example: ["repo.code","repo.issues","repo.ext_issues","repo.wiki","repo.pulls","repo.releases","repo.projects","repo.ext_wiki"] // Deprecated: This variable should be replaced by UnitsMap and will be dropped in later versions. Units []string `json:"units"` - // example: {"repo.code":"read","repo.issues":"write","repo.ext_issues":"none","repo.wiki":"admin","repo.pulls":"owner","repo.releases":"none","repo.projects":"none","repo.ext_wiki":"none"] + // example: {"repo.code":"read","repo.issues":"write","repo.ext_issues":"none","repo.wiki":"admin","repo.pulls":"owner","repo.releases":"none","repo.projects":"none","repo.ext_wiki":"none"} UnitsMap map[string]string `json:"units_map"` CanCreateOrgRepo *bool `json:"can_create_org_repo"` } diff --git a/modules/structs/repo.go b/modules/structs/repo.go index 403e8e6f4c..6832c76e1a 100644 --- a/modules/structs/repo.go +++ b/modules/structs/repo.go @@ -34,8 +34,10 @@ type ExternalTracker struct { ExternalTrackerURL string `json:"external_tracker_url"` // External Issue Tracker URL Format. Use the placeholders {user}, {repo} and {index} for the username, repository name and issue index. ExternalTrackerFormat string `json:"external_tracker_format"` - // External Issue Tracker Number Format, either `numeric` or `alphanumeric` + // External Issue Tracker Number Format, either `numeric`, `alphanumeric`, or `regexp` ExternalTrackerStyle string `json:"external_tracker_style"` + // External Issue Tracker issue regular expression + ExternalTrackerRegexpPattern string `json:"external_tracker_regexp_pattern"` } // ExternalWiki represents setting for external wiki diff --git a/modules/sync/status_pool.go b/modules/sync/status_pool.go index acbd93ab17..99e5ce9cb3 100644 --- a/modules/sync/status_pool.go +++ b/modules/sync/status_pool.go @@ -6,6 +6,8 @@ package sync import ( "sync" + + "code.gitea.io/gitea/modules/container" ) // StatusTable is a table maintains true/false values. @@ -14,13 +16,13 @@ import ( // in different goroutines. type StatusTable struct { lock sync.RWMutex - pool map[string]struct{} + pool container.Set[string] } // NewStatusTable initializes and returns a new StatusTable object. func NewStatusTable() *StatusTable { return &StatusTable{ - pool: make(map[string]struct{}), + pool: make(container.Set[string]), } } @@ -28,32 +30,29 @@ func NewStatusTable() *StatusTable { // Returns whether set value was set to true func (p *StatusTable) StartIfNotRunning(name string) bool { p.lock.Lock() - _, ok := p.pool[name] - if !ok { - p.pool[name] = struct{}{} - } + added := p.pool.Add(name) p.lock.Unlock() - return !ok + return added } // Start sets value of given name to true in the pool. func (p *StatusTable) Start(name string) { p.lock.Lock() - p.pool[name] = struct{}{} + p.pool.Add(name) p.lock.Unlock() } // Stop sets value of given name to false in the pool. func (p *StatusTable) Stop(name string) { p.lock.Lock() - delete(p.pool, name) + p.pool.Remove(name) p.lock.Unlock() } // IsRunning checks if value of given name is set to true in the pool. func (p *StatusTable) IsRunning(name string) bool { p.lock.RLock() - _, ok := p.pool[name] + exists := p.pool.Contains(name) p.lock.RUnlock() - return ok + return exists } diff --git a/modules/templates/dynamic.go b/modules/templates/dynamic.go index 4896580f62..a86e71a8c8 100644 --- a/modules/templates/dynamic.go +++ b/modules/templates/dynamic.go @@ -33,6 +33,21 @@ func GetAsset(name string) ([]byte, error) { return os.ReadFile(filepath.Join(setting.StaticRootPath, name)) } +// GetAssetFilename returns the filename of the provided asset +func GetAssetFilename(name string) (string, error) { + filename := filepath.Join(setting.CustomPath, name) + _, err := os.Stat(filename) + if err != nil && !os.IsNotExist(err) { + return filename, err + } else if err == nil { + return filename, nil + } + + filename = filepath.Join(setting.StaticRootPath, name) + _, err = os.Stat(filename) + return filename, err +} + // walkTemplateFiles calls a callback for each template asset func walkTemplateFiles(callback func(path, name string, d fs.DirEntry, err error) error) error { if err := walkAssetDir(filepath.Join(setting.CustomPath, "templates"), true, callback); err != nil && !os.IsNotExist(err) { diff --git a/modules/templates/htmlrenderer.go b/modules/templates/htmlrenderer.go index 210bb5e73c..81ea660161 100644 --- a/modules/templates/htmlrenderer.go +++ b/modules/templates/htmlrenderer.go @@ -5,7 +5,12 @@ package templates import ( + "bytes" "context" + "fmt" + "regexp" + "strconv" + "strings" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" @@ -14,7 +19,14 @@ import ( "github.com/unrolled/render" ) -var rendererKey interface{} = "templatesHtmlRendereer" +var ( + rendererKey interface{} = "templatesHtmlRenderer" + + templateError = regexp.MustCompile(`^template: (.*):([0-9]+): (.*)`) + notDefinedError = regexp.MustCompile(`^template: (.*):([0-9]+): function "(.*)" not defined`) + unexpectedError = regexp.MustCompile(`^template: (.*):([0-9]+): unexpected "(.*)" in operand`) + expectedEndError = regexp.MustCompile(`^template: (.*):([0-9]+): expected end; found (.*)`) +) // HTMLRenderer returns the current html renderer for the context or creates and stores one within the context for future use func HTMLRenderer(ctx context.Context) (context.Context, *render.Render) { @@ -32,6 +44,25 @@ func HTMLRenderer(ctx context.Context) (context.Context, *render.Render) { } log.Log(1, log.DEBUG, "Creating "+rendererType+" HTML Renderer") + compilingTemplates := true + defer func() { + if !compilingTemplates { + return + } + + panicked := recover() + if panicked == nil { + return + } + + // OK try to handle the panic... + err, ok := panicked.(error) + if ok { + handlePanicError(err) + } + log.Fatal("PANIC: Unable to compile templates!\n%v\n\nStacktrace:\n%s", panicked, log.Stack(2)) + }() + renderer := render.New(render.Options{ Extensions: []string{".tmpl"}, Directory: "templates", @@ -42,6 +73,7 @@ func HTMLRenderer(ctx context.Context) (context.Context, *render.Render) { IsDevelopment: false, DisableHTTPErrorRendering: true, }) + compilingTemplates = false if !setting.IsProd { watcher.CreateWatcher(ctx, "HTML Templates", &watcher.CreateWatcherOpts{ PathsCallback: walkTemplateFiles, @@ -50,3 +82,168 @@ func HTMLRenderer(ctx context.Context) (context.Context, *render.Render) { } return context.WithValue(ctx, rendererKey, renderer), renderer } + +func handlePanicError(err error) { + wrapFatal(handleNotDefinedPanicError(err)) + wrapFatal(handleUnexpected(err)) + wrapFatal(handleExpectedEnd(err)) + wrapFatal(handleGenericTemplateError(err)) +} + +func wrapFatal(format string, args []interface{}) { + if format == "" { + return + } + log.FatalWithSkip(1, format, args...) +} + +func handleGenericTemplateError(err error) (string, []interface{}) { + groups := templateError.FindStringSubmatch(err.Error()) + if len(groups) != 4 { + return "", nil + } + + templateName, lineNumberStr, message := groups[1], groups[2], groups[3] + + filename, assetErr := GetAssetFilename("templates/" + templateName + ".tmpl") + if assetErr != nil { + return "", nil + } + + lineNumber, _ := strconv.Atoi(lineNumberStr) + + line := getLineFromAsset(templateName, lineNumber, "") + + return "PANIC: Unable to compile templates!\n%s in template file %s at line %d:\n\n%s\nStacktrace:\n\n%s", []interface{}{message, filename, lineNumber, log.NewColoredValue(line, log.Reset), log.Stack(2)} +} + +func handleNotDefinedPanicError(err error) (string, []interface{}) { + groups := notDefinedError.FindStringSubmatch(err.Error()) + if len(groups) != 4 { + return "", nil + } + + templateName, lineNumberStr, functionName := groups[1], groups[2], groups[3] + + functionName, _ = strconv.Unquote(`"` + functionName + `"`) + + filename, assetErr := GetAssetFilename("templates/" + templateName + ".tmpl") + if assetErr != nil { + return "", nil + } + + lineNumber, _ := strconv.Atoi(lineNumberStr) + + line := getLineFromAsset(templateName, lineNumber, functionName) + + return "PANIC: Unable to compile templates!\nUndefined function %q in template file %s at line %d:\n\n%s", []interface{}{functionName, filename, lineNumber, log.NewColoredValue(line, log.Reset)} +} + +func handleUnexpected(err error) (string, []interface{}) { + groups := unexpectedError.FindStringSubmatch(err.Error()) + if len(groups) != 4 { + return "", nil + } + + templateName, lineNumberStr, unexpected := groups[1], groups[2], groups[3] + unexpected, _ = strconv.Unquote(`"` + unexpected + `"`) + + filename, assetErr := GetAssetFilename("templates/" + templateName + ".tmpl") + if assetErr != nil { + return "", nil + } + + lineNumber, _ := strconv.Atoi(lineNumberStr) + + line := getLineFromAsset(templateName, lineNumber, unexpected) + + return "PANIC: Unable to compile templates!\nUnexpected %q in template file %s at line %d:\n\n%s", []interface{}{unexpected, filename, lineNumber, log.NewColoredValue(line, log.Reset)} +} + +func handleExpectedEnd(err error) (string, []interface{}) { + groups := expectedEndError.FindStringSubmatch(err.Error()) + if len(groups) != 4 { + return "", nil + } + + templateName, lineNumberStr, unexpected := groups[1], groups[2], groups[3] + + filename, assetErr := GetAssetFilename("templates/" + templateName + ".tmpl") + if assetErr != nil { + return "", nil + } + + lineNumber, _ := strconv.Atoi(lineNumberStr) + + line := getLineFromAsset(templateName, lineNumber, unexpected) + + return "PANIC: Unable to compile templates!\nMissing end with unexpected %q in template file %s at line %d:\n\n%s", []interface{}{unexpected, filename, lineNumber, log.NewColoredValue(line, log.Reset)} +} + +const dashSeparator = "----------------------------------------------------------------------\n" + +func getLineFromAsset(templateName string, targetLineNum int, target string) string { + bs, err := GetAsset("templates/" + templateName + ".tmpl") + if err != nil { + return fmt.Sprintf("(unable to read template file: %v)", err) + } + + sb := &strings.Builder{} + + // Write the header + sb.WriteString(dashSeparator) + + var lineBs []byte + + // Iterate through the lines from the asset file to find the target line + for start, currentLineNum := 0, 1; currentLineNum <= targetLineNum && start < len(bs); currentLineNum++ { + // Find the next new line + end := bytes.IndexByte(bs[start:], '\n') + + // adjust the end to be a direct pointer in to []byte + if end < 0 { + end = len(bs) + } else { + end += start + } + + // set lineBs to the current line []byte + lineBs = bs[start:end] + + // move start to after the current new line position + start = end + 1 + + // Write 2 preceding lines + the target line + if targetLineNum-currentLineNum < 3 { + _, _ = sb.Write(lineBs) + _ = sb.WriteByte('\n') + } + } + + // If there is a provided target to look for in the line add a pointer to it + // e.g. ^^^^^^^ + if target != "" { + idx := bytes.Index(lineBs, []byte(target)) + + if idx >= 0 { + // take the current line and replace preceding text with whitespace (except for tab) + for i := range lineBs[:idx] { + if lineBs[i] != '\t' { + lineBs[i] = ' ' + } + } + + // write the preceding "space" + _, _ = sb.Write(lineBs[:idx]) + + // Now write the ^^ pointer + _, _ = sb.WriteString(strings.Repeat("^", len(target))) + _ = sb.WriteByte('\n') + } + } + + // Finally write the footer + sb.WriteString(dashSeparator) + + return sb.String() +} diff --git a/modules/templates/static.go b/modules/templates/static.go index 3265bd9cfc..7f7cbe702f 100644 --- a/modules/templates/static.go +++ b/modules/templates/static.go @@ -31,6 +31,18 @@ func GlobalModTime(filename string) time.Time { return timeutil.GetExecutableModTime() } +// GetAssetFilename returns the filename of the provided asset +func GetAssetFilename(name string) (string, error) { + filename := filepath.Join(setting.CustomPath, name) + _, err := os.Stat(filename) + if err != nil && !os.IsNotExist(err) { + return name, err + } else if err == nil { + return filename, nil + } + return "(builtin) " + name, nil +} + // GetAsset get a special asset, only for chi func GetAsset(name string) ([]byte, error) { bs, err := os.ReadFile(filepath.Join(setting.CustomPath, name)) diff --git a/options/locale/TRANSLATORS b/options/locale/TRANSLATORS index 3884207f0a..e67255f2fb 100644 --- a/options/locale/TRANSLATORS +++ b/options/locale/TRANSLATORS @@ -72,7 +72,7 @@ Thomas Fanninger Tilmann Bach Toni Villena Jiménez Viktor Sperl -Vladimir Jigulin mogaika AT yandex DOT ru +Vladimir Jigulin Vladimir Vissoultchev Yaşar Çiv YJSoft diff --git a/options/locale/locale_de-DE.ini b/options/locale/locale_de-DE.ini index ec2e6ba50a..35cc9a1c53 100644 --- a/options/locale/locale_de-DE.ini +++ b/options/locale/locale_de-DE.ini @@ -227,7 +227,7 @@ default_keep_email_private_popup=E-Mail-Adressen von neuen Benutzern standardmä default_allow_create_organization=Erstellen von Organisationen standardmäßig erlauben default_allow_create_organization_popup=Neuen Nutzern das Erstellen von Organisationen standardmäßig erlauben. default_enable_timetracking=Zeiterfassung standardmäßig aktivieren -default_enable_timetracking_popup=Zeiterfassung standardmäßig für neue Repositories aktivieren. +default_enable_timetracking_popup=Zeiterfassung standardmäßig für neue Repositorys aktivieren. no_reply_address=Versteckte E-Mail-Domain no_reply_address_helper=Domain-Name für Benutzer mit einer versteckten Emailadresse. Zum Beispiel wird der Benutzername „Joe“ in Git als „joe@noreply.example.org“ protokolliert, wenn die versteckte E-Mail-Domain „noreply.example.org“ festgelegt ist. password_algorithm=Passwort Hashing Algorithmus @@ -237,15 +237,15 @@ password_algorithm_helper=Lege den Passwort Hashing Algorithmus fest. Unterschie uname_holder=E-Mail-Adresse oder Benutzername password_holder=Passwort switch_dashboard_context=Kontext der Übersichtsseite wechseln -my_repos=Repositories -show_more_repos=Zeige mehr Repositories… -collaborative_repos=Gemeinschaftliche Repositories +my_repos=Repositorys +show_more_repos=Zeige mehr Repositorys… +collaborative_repos=Gemeinschaftliche Repositorys my_orgs=Meine Organisationen my_mirrors=Meine Mirrors view_home=%s ansehen search_repos=Finde ein Repository… filter=Andere Filter -filter_by_team_repositories=Nach Team Repositories filtern +filter_by_team_repositories=Nach Team-Repositorys filtern feed_of=Feed von "%s" show_archived=Archiviert @@ -258,10 +258,10 @@ show_both_private_public=Öffentliche und private anzeigen show_only_private=Nur private anzeigen show_only_public=Nur öffentliche anzeigen -issues.in_your_repos=Eigene Repositories +issues.in_your_repos=Eigene Repositorys [explore] -repos=Repositories +repos=Repositorys users=Benutzer organizations=Organisationen search=Suche @@ -269,12 +269,14 @@ code=Code search.fuzzy=Ähnlich search.match=Genau code_search_unavailable=Derzeit ist die Code-Suche nicht verfügbar. Bitte wende dich an den Website-Administrator. -repo_no_results=Keine passenden Repositories gefunden. +repo_no_results=Keine passenden Repositorys gefunden. user_no_results=Keine passenden Benutzer gefunden. org_no_results=Keine passenden Organisationen gefunden. code_no_results=Es konnte kein passender Code für deinen Suchbegriff gefunden werden. code_search_results=Suchergebnisse für „%s“ code_last_indexed_at=Zuletzt indexiert %s +relevant_repositories_tooltip=Repositorys, die Forks sind oder die kein Thema, kein Symbol und keine Beschreibung haben, werden ausgeblendet. +relevant_repositories=Es werden nur relevante Repositorys angezeigt, zeigt ungefilterte Ergebnisse an. [auth] @@ -337,7 +339,7 @@ email_domain_blacklisted=Du kannst dich nicht mit deiner E-Mail-Adresse registri authorize_application=Anwendung autorisieren authorize_redirect_notice=Du wirst zu %s weitergeleitet, wenn du diese Anwendung autorisierst. authorize_application_created_by=Diese Anwendung wurde von %s erstellt. -authorize_application_description=Wenn du diese Anwendung autorisierst, wird sie die Berechtigung erhalten, alle Informationen zu deinem Account zu bearbeiten oder zu lesen. Dies beinhaltet auch private Repositories und Organisationen. +authorize_application_description=Wenn du diese Anwendung autorisierst, wird sie die Berechtigung erhalten, alle Informationen zu deinem Account zu bearbeiten oder zu lesen. Dies beinhaltet auch private Repositorys und Organisationen. authorize_title="%s" den Zugriff auf deinen Account gestatten? authorization_failed=Autorisierung fehlgeschlagen authorization_failed_desc=Die Autorisierung ist fehlgeschlagen, da wir eine ungültige Anfrage festgestellt haben. Bitte kontaktiere den Betreiber der Anwendung, die du gerade autorisieren wolltest. @@ -453,7 +455,7 @@ lang_select_error=Wähle eine Sprache aus der Liste aus. username_been_taken=Der Benutzername ist bereits vergeben. username_change_not_local_user=Nicht-lokale Benutzer dürfen ihren Nutzernamen nicht ändern. repo_name_been_taken=Der Repository-Name wird schon verwendet. -repository_force_private=Privat erzwingen ist aktiviert: Private Repositories können nicht veröffentlicht werden. +repository_force_private=Privat erzwingen ist aktiviert: Private Repositorys können nicht veröffentlicht werden. repository_files_already_exist=Dateien für dieses Repository sind bereits vorhanden. Kontaktiere den Systemadministrator. repository_files_already_exist.adopt=Dateien für dieses Repository existieren bereits und können nur übernommen werden. repository_files_already_exist.delete=Dateien für dieses Repository sind bereits vorhanden. Du must sie löschen. @@ -487,7 +489,7 @@ invalid_ssh_principal=Ungültige Identität: %s unable_verify_ssh_key=Dein SSH-Key kann nicht überprüft werden, probiere es erneut. auth_failed=Authentifizierung fehlgeschlagen: %v -still_own_repo=Dein Konto besitzt ein oder mehrere Repositories. Diese müssen zuerst gelöscht oder übertragen werden. +still_own_repo=Dein Konto besitzt ein oder mehrere Repositorys. Diese müssen zuerst gelöscht oder übertragen werden. still_has_org=Dein Account ist Mitglied in mindestens einer Organisation. Bitte verlasse diese zuerst. still_own_packages=Ihr Konto besitzt ein oder mehrere Pakete; löschen Sie diese zuerst. org_still_own_repo=Diese Organisation besitzt noch mindestens ein Repository. Bitte lösche oder übertrage diese zuerst. @@ -498,7 +500,7 @@ target_branch_not_exist=Der Ziel-Branch existiert nicht. [user] change_avatar=Profilbild ändern… join_on=Beigetreten am -repositories=Repositories +repositories=Repositorys activity=Öffentliche Aktivität followers=Follower starred=Favoriten @@ -970,7 +972,7 @@ migrate.gogs.description=Daten von notabug.org oder anderen Gogs Instanzen migri migrate.onedev.description=Daten von code.onedev.io oder anderen OneDev Instanzen migrieren. migrate.codebase.description=Daten von codebasehq.com migrieren. migrate.gitbucket.description=Daten von GitBucket Instanzen migrieren. -migrate.migrating_git=Git Daten werden migriert +migrate.migrating_git=Git-Daten werden migriert migrate.migrating_topics=Themen werden migriert migrate.migrating_milestones=Meilensteine werden migriert migrate.migrating_labels=Labels werden migriert @@ -2335,7 +2337,7 @@ settings.delete_prompt=Die Organisation wird dauerhaft gelöscht. Dies K settings.confirm_delete_account=Löschen bestätigen settings.delete_org_title=Organisation löschen settings.delete_org_desc=Diese Organisation wird dauerhaft gelöscht. Fortfahren? -settings.hooks_desc=Webhooks hinzufügen, die für alle Repositories dieser Organisation ausgelöst werden. +settings.hooks_desc=Webhooks hinzufügen, die für alle Repositorys dieser Organisation ausgelöst werden. settings.labels_desc=Labels hinzufügen, die für alle Repositories dieser Organisation genutzt werden können. @@ -2439,7 +2441,7 @@ dashboard.cron.error=Fehler in Cron: %s: %[3]s dashboard.cron.finished=Cron: %[1]s ist beendet dashboard.delete_inactive_accounts=Alle nicht aktivierten Konten löschen dashboard.delete_inactive_accounts.started=Löschen aller nicht aktivierten Account-Aufgabe gestartet. -dashboard.delete_repo_archives=Lösche alle Repository Archive (ZIP, TAR.GZ, …) +dashboard.delete_repo_archives=Lösche alle Repository-Archive (ZIP, TAR.GZ, …) dashboard.delete_repo_archives.started=Löschen aller Repository-Archive gestartet. dashboard.delete_missing_repos=Alle Repository-Datensätze mit verloren gegangenen Git-Dateien löschen dashboard.delete_missing_repos.started=Alle Repositories löschen, die die Git-Dateien-Aufgabe nicht gestartet haben. @@ -2528,8 +2530,9 @@ users.allow_create_organization=Darf Organisationen erstellen users.update_profile=Benutzerkonto aktualisieren users.delete_account=Benutzerkonto löschen users.cannot_delete_self=Du kannst dich nicht selbst löschen -users.still_own_repo=Dieser Benutzer besitzt noch mindestens ein Repository. Bitte lösche oder übertrage diese zuerst. +users.still_own_repo=Dieser Benutzer besitzt noch mindestens ein Repository. Bitte lösche oder übertrage diese(s) zuerst. users.still_has_org=Dieser Nutzer ist Mitglied einer Organisation. Du musst ihn zuerst aus allen Organisationen entfernen. +users.purge_help=Erzwinge das Löschen des Benutzers inklusive aller seiner Repositorys, Organisationen, Pakete und Kommentare. users.still_own_packages=Dieser Benutzer besitzt noch ein oder mehrere Pakete. Lösche diese Pakete zuerst. users.deletion_success=Der Account wurde gelöscht. users.reset_2fa=2FA zurücksetzen diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 1dba1d71d8..fbf9b70643 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -268,8 +268,11 @@ users = Users organizations = Organizations search = Search code = Code +search.type.tooltip = Search type search.fuzzy = Fuzzy +search.fuzzy.tooltip = Include results that also matches the search term closely search.match = Match +search.match.tooltip = Include only results that matches the exact search term code_search_unavailable = Currently code search is not available. Please contact your site administrator. repo_no_results = No matching repositories found. user_no_results = No matching users found. @@ -507,6 +510,7 @@ activity = Public Activity followers = Followers starred = Starred Repositories watched = Watched Repositories +code = Code projects = Projects following = Following follow = Follow @@ -1763,8 +1767,11 @@ activity.git_stats_deletion_n = %d deletions search = Search search.search_repo = Search repository +search.type.tooltip = Search type search.fuzzy = Fuzzy +search.fuzzy.tooltip = Include results that also matches the search term closely search.match = Match +search.match.tooltip = Include only results that matches the exact search term search.results = Search results for "%s" in %s search.code_no_results = No source code matching your search term found. search.code_search_unavailable = Currently code search is not available. Please contact your site administrator. @@ -2310,6 +2317,7 @@ create_org = Create Organization repo_updated = Updated people = People teams = Teams +code = Code lower_members = members lower_repositories = repositories create_new_team = New Team diff --git a/options/locale/locale_pt-PT.ini b/options/locale/locale_pt-PT.ini index 133f7d8962..1a301ddde6 100644 --- a/options/locale/locale_pt-PT.ini +++ b/options/locale/locale_pt-PT.ini @@ -268,8 +268,11 @@ users=Utilizadores organizations=Organizações search=Procurar code=Código +search.type.tooltip=Tipo de pesquisa search.fuzzy=Aproximada +search.fuzzy.tooltip=Incluir também os resultados que estejam próximos do termo de pesquisa search.match=Fiel +search.match.tooltip=Incluir somente os resultados que correspondam rigorosamente ao termo de pesquisa code_search_unavailable=A pesquisa por código-fonte não está disponível, neste momento. Entre em contacto com o administrador. repo_no_results=Não foram encontrados quaisquer repositórios correspondentes. user_no_results=Não foram encontrados quaisquer utilizadores correspondentes. @@ -507,6 +510,7 @@ activity=Trabalho público followers=Seguidores starred=Repositórios favoritos watched=Repositórios sob vigilância +code=Código projects=Planeamentos following=Que segue follow=Seguir @@ -1763,8 +1767,11 @@ activity.git_stats_deletion_n=%d eliminações search=Procurar search.search_repo=Procurar repositório +search.type.tooltip=Tipo de pesquisa search.fuzzy=Aproximada +search.fuzzy.tooltip=Incluir também os resultados que estejam próximos do termo de pesquisa search.match=Fiel +search.match.tooltip=Incluir somente os resultados que correspondam rigorosamente ao termo de pesquisa search.results=Resultados da procura de "%s" em %s search.code_no_results=Não foi encontrado qualquer código-fonte correspondente à sua pesquisa. search.code_search_unavailable=A pesquisa por código-fonte não está disponível, neste momento. Entre em contacto com o administrador. @@ -2310,6 +2317,7 @@ create_org=Criar organização repo_updated=Modificado people=Pessoas teams=Equipas +code=Código lower_members=membros lower_repositories=repositórios create_new_team=Nova equipa diff --git a/package-lock.json b/package-lock.json index 05d414c9ae..784adfebe8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,13 +8,13 @@ "license": "MIT", "dependencies": { "@claviska/jquery-minicolors": "2.3.6", - "@mcaptcha/vanilla-glue": "0.1.0-alpha-2", - "@primer/octicons": "17.5.0", - "@vue/compiler-sfc": "3.2.37", + "@mcaptcha/vanilla-glue": "0.1.0-alpha-3", + "@primer/octicons": "17.7.0", + "@vue/compiler-sfc": "3.2.40", "add-asset-webpack-plugin": "2.0.1", "css-loader": "6.7.1", "dropzone": "6.0.0-beta.2", - "easymde": "2.17.0", + "easymde": "2.18.0", "esbuild-loader": "2.20.0", "escape-goat": "4.0.0", "fast-glob": "3.2.12", @@ -23,19 +23,19 @@ "jquery.are-you-sure": "1.9.0", "katex": "0.16.2", "less": "4.1.3", - "less-loader": "11.0.0", + "less-loader": "11.1.0", "license-checker-webpack-plugin": "0.2.1", - "mermaid": "9.1.6", + "mermaid": "9.1.7", "mini-css-extract-plugin": "2.6.1", "monaco-editor": "0.34.0", "monaco-editor-webpack-plugin": "7.0.1", "pretty-ms": "8.0.0", "sortablejs": "1.15.0", - "swagger-ui-dist": "4.14.0", + "swagger-ui-dist": "4.14.2", "tippy.js": "6.3.7", "tributejs": "5.1.3", "uint8-to-base64": "0.2.0", - "vue": "3.2.37", + "vue": "3.2.40", "vue-bar-graph": "2.0.0", "vue-loader": "17.0.0", "vue3-calendar-heatmap": "2.0.0", @@ -47,23 +47,23 @@ "wrap-ansi": "8.0.1" }, "devDependencies": { - "@playwright/test": "1.25.2", + "@playwright/test": "1.27.0", "@stoplight/spectral-cli": "6.5.1", - "eslint": "8.23.0", + "eslint": "8.25.0", "eslint-plugin-import": "2.26.0", "eslint-plugin-jquery": "1.5.1", "eslint-plugin-sonarjs": "0.15.0", - "eslint-plugin-unicorn": "43.0.2", - "eslint-plugin-vue": "9.4.0", - "jest": "29.0.3", - "jest-environment-jsdom": "29.0.3", + "eslint-plugin-unicorn": "44.0.2", + "eslint-plugin-vue": "9.6.0", + "jest": "29.1.2", + "jest-environment-jsdom": "29.1.2", "jest-extended": "3.1.0", "markdownlint-cli": "0.32.2", "postcss-less": "6.0.0", - "stylelint": "14.11.0", + "stylelint": "14.13.0", "stylelint-config-standard": "28.0.0", "svgo": "2.8.0", - "updates": "13.1.5" + "updates": "13.1.8" }, "engines": { "node": ">= 14.0.0" @@ -83,9 +83,9 @@ } }, "node_modules/@asyncapi/specs": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/@asyncapi/specs/-/specs-2.14.0.tgz", - "integrity": "sha512-hHsYF6XsYNIKb1P2rXaooF4H+uKKQ4b/Ljxrk3rZ3riEDiSxMshMEfb1fUlw9Yj4V4OmJhjXwkNvw8W59AXv1A==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@asyncapi/specs/-/specs-3.2.1.tgz", + "integrity": "sha512-FO+EteK+Gk3zwumrBw6frpp9cJ4oQL5++hBBpfM81w16e9KaiA4sKrzvQsvVjifoZZHNvVEX4D2zoz9i8CLccQ==", "dev": true }, "node_modules/@babel/code-frame": { @@ -101,30 +101,30 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.19.0.tgz", - "integrity": "sha512-y5rqgTTPTmaF5e2nVhOxw+Ur9HDJLsWb6U/KpgUzRZEdPfE6VOubXBKLdbcUTijzRptednSBDQbYZBOSqJxpJw==", + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.19.3.tgz", + "integrity": "sha512-prBHMK4JYYK+wDjJF1q99KK4JLL+egWS4nmNqdlMUgCExMZ+iZW0hGhyC3VEbsPjvaN0TBhW//VIFwBrk8sEiw==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.0.tgz", - "integrity": "sha512-reM4+U7B9ss148rh2n1Qs9ASS+w94irYXga7c2jaQv9RVzpS7Mv1a9rnYYwuDa45G+DkORt9g6An2k/V4d9LbQ==", + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.3.tgz", + "integrity": "sha512-WneDJxdsjEvyKtXKsaBGbDeiyOjR5vYq4HcShxnIbG0qixpoHjI3MqeZM9NDvsojNCEBItQE4juOo/bU6e72gQ==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.1.0", "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.19.0", - "@babel/helper-compilation-targets": "^7.19.0", + "@babel/generator": "^7.19.3", + "@babel/helper-compilation-targets": "^7.19.3", "@babel/helper-module-transforms": "^7.19.0", "@babel/helpers": "^7.19.0", - "@babel/parser": "^7.19.0", + "@babel/parser": "^7.19.3", "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.0", - "@babel/types": "^7.19.0", + "@babel/traverse": "^7.19.3", + "@babel/types": "^7.19.3", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -149,12 +149,12 @@ } }, "node_modules/@babel/generator": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.19.0.tgz", - "integrity": "sha512-S1ahxf1gZ2dpoiFgA+ohK9DIpz50bJ0CWs7Zlzb54Z4sG8qmdIrGrVqmy1sAtTVRb+9CU6U8VqT9L0Zj7hxHVg==", + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.19.3.tgz", + "integrity": "sha512-fqVZnmp1ncvZU757UzDheKZpfPgatqY59XtW2/j/18H7u76akb8xqvjw82f+i2UKd/ksYsSick/BCLQUUtJ/qQ==", "dev": true, "dependencies": { - "@babel/types": "^7.19.0", + "@babel/types": "^7.19.3", "@jridgewell/gen-mapping": "^0.3.2", "jsesc": "^2.5.1" }, @@ -177,14 +177,14 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.0.tgz", - "integrity": "sha512-Ai5bNWXIvwDvWM7njqsG3feMlL9hCVQsPYXodsZyLwshYkZVJt59Gftau4VrE8S9IT9asd2uSP1hG6wCNw+sXA==", + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.3.tgz", + "integrity": "sha512-65ESqLGyGmLvgR0mst5AdW1FkNlj9rQsCKduzEoEPhBCDFGXvz2jW6bXFG6i0/MrV2s7hhXjjb2yAzcPuQlLwg==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.19.0", + "@babel/compat-data": "^7.19.3", "@babel/helper-validator-option": "^7.18.6", - "browserslist": "^4.20.2", + "browserslist": "^4.21.3", "semver": "^6.3.0" }, "engines": { @@ -311,9 +311,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz", - "integrity": "sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==", + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", "dev": true, "engines": { "node": ">=6.9.0" @@ -428,9 +428,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.19.0.tgz", - "integrity": "sha512-74bEXKX2h+8rrfQUfsBfuZZHzsEs6Eql4pqy/T4Nn6Y9wNPggQOqD6z6pn5Bl8ZfysKouFZT/UXEH94ummEeQw==", + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.19.3.tgz", + "integrity": "sha512-pJ9xOlNWHiy9+FuFP09DEAFbAn4JskgRsVcc169w2xRBC3FRGuQEwjeIMMND9L2zc0iEhO/tGv4Zq+km+hxNpQ==", "bin": { "parser": "bin/babel-parser.js" }, @@ -630,19 +630,19 @@ } }, "node_modules/@babel/traverse": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.19.0.tgz", - "integrity": "sha512-4pKpFRDh+utd2mbRC8JLnlsMUii3PMHjpL6a0SZ4NMZy7YFP9aXORxEhdMVOc9CpWtDF09IkciQLEhK7Ml7gRA==", + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.19.3.tgz", + "integrity": "sha512-qh5yf6149zhq2sgIXmwjnsvmnNQC2iw70UFjp4olxucKrWd/dvlUsBI88VSLUsnMNF7/vnOiA+nk1+yLoCqROQ==", "dev": true, "dependencies": { "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.19.0", + "@babel/generator": "^7.19.3", "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-function-name": "^7.19.0", "@babel/helper-hoist-variables": "^7.18.6", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.19.0", - "@babel/types": "^7.19.0", + "@babel/parser": "^7.19.3", + "@babel/types": "^7.19.3", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -660,13 +660,13 @@ } }, "node_modules/@babel/types": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.0.tgz", - "integrity": "sha512-YuGopBq3ke25BVSiS6fgF49Ul9gH1x70Bcr6bqRLjWCkcX8Hre1/5+z+IiWOIerRMSSEfGZVB9z9kyq7wVs9YA==", + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.3.tgz", + "integrity": "sha512-hGCaQzIY22DJlDh9CH7NOxgKkFjBk0Cw9xDO1Xmh2151ti7wiGfQ3LauXzL4HP1fmFlTX6XjpRETTpUcv7wQLw==", "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.18.10", - "@babel/helper-validator-identifier": "^7.18.6", + "@babel/helper-validator-identifier": "^7.19.1", "to-fast-properties": "^2.0.0" }, "engines": { @@ -717,10 +717,25 @@ "node": ">=10.0.0" } }, + "node_modules/@esbuild/android-arm": { + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.15.10.tgz", + "integrity": "sha512-FNONeQPy/ox+5NBkcSbYJxoXj9GWu8gVGJTVmUyoOCKQFDTrHVKgNSzChdNt0I8Aj/iKcsDf2r9BFwv+FSNUXg==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@esbuild/linux-loong64": { - "version": "0.15.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.7.tgz", - "integrity": "sha512-IKznSJOsVUuyt7cDzzSZyqBEcZe+7WlBqTVXiF1OXP/4Nm387ToaXZ0fyLwI1iBlI/bzpxVq411QE2/Bt2XWWw==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.10.tgz", + "integrity": "sha512-w0Ou3Z83LOYEkwaui2M8VwIp+nLi/NA60lBLMvaJ+vXVMcsARYdEzLNE7RSm4+lSg4zq4d7fAVuzk7PNQ5JFgg==", "cpu": [ "loong64" ], @@ -733,9 +748,9 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.1.tgz", - "integrity": "sha512-OhSY22oQQdw3zgPOOwdoj01l/Dzl1Z+xyUP33tkSN+aqyEhymJCcPHyXt+ylW8FSe0TfRC2VG+ROQOapD0aZSQ==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", + "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", "dev": true, "dependencies": { "ajv": "^6.12.4", @@ -778,9 +793,9 @@ "dev": true }, "node_modules/@humanwhocodes/config-array": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.4.tgz", - "integrity": "sha512-mXAIHxZT3Vcpg83opl1wGlVZ9xydbfZO3r5YfRSH6Gpp2J/PfdBP0wbDa2sO6/qRbcalpoevVyW6A/fI6LfeMw==", + "version": "0.10.7", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.7.tgz", + "integrity": "sha512-MDl6D6sBsaV452/QSdX+4CXIjZhIcI0PELsxUjk4U828yd58vk3bTIvk/6w5FY+4hIy9sLW0sfrV7K7Kc++j/w==", "dev": true, "dependencies": { "@humanwhocodes/object-schema": "^1.2.1", @@ -791,16 +806,6 @@ "node": ">=10.10.0" } }, - "node_modules/@humanwhocodes/gitignore-to-minimatch": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz", - "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==", - "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", @@ -929,16 +934,16 @@ } }, "node_modules/@jest/console": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.0.3.tgz", - "integrity": "sha512-cGg0r+klVHSYnfE977S9wmpuQ9L+iYuYgL+5bPXiUlUynLLYunRxswEmhBzvrSKGof5AKiHuTTmUKAqRcDY9dg==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.1.2.tgz", + "integrity": "sha512-ujEBCcYs82BTmRxqfHMQggSlkUZP63AE5YEaTPj7eFyJOzukkTorstOUC7L6nE3w5SYadGVAnTsQ/ZjTGL0qYQ==", "dev": true, "dependencies": { - "@jest/types": "^29.0.3", + "@jest/types": "^29.1.2", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^29.0.3", - "jest-util": "^29.0.3", + "jest-message-util": "^29.1.2", + "jest-util": "^29.1.2", "slash": "^3.0.0" }, "engines": { @@ -946,16 +951,16 @@ } }, "node_modules/@jest/core": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.0.3.tgz", - "integrity": "sha512-1d0hLbOrM1qQE3eP3DtakeMbKTcXiXP3afWxqz103xPyddS2NhnNghS7MaXx1dcDt4/6p4nlhmeILo2ofgi8cQ==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.1.2.tgz", + "integrity": "sha512-sCO2Va1gikvQU2ynDN8V4+6wB7iVrD2CvT0zaRst4rglf56yLly0NQ9nuRRAWFeimRf+tCdFsb1Vk1N9LrrMPA==", "dev": true, "dependencies": { - "@jest/console": "^29.0.3", - "@jest/reporters": "^29.0.3", - "@jest/test-result": "^29.0.3", - "@jest/transform": "^29.0.3", - "@jest/types": "^29.0.3", + "@jest/console": "^29.1.2", + "@jest/reporters": "^29.1.2", + "@jest/test-result": "^29.1.2", + "@jest/transform": "^29.1.2", + "@jest/types": "^29.1.2", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", @@ -963,20 +968,20 @@ "exit": "^0.1.2", "graceful-fs": "^4.2.9", "jest-changed-files": "^29.0.0", - "jest-config": "^29.0.3", - "jest-haste-map": "^29.0.3", - "jest-message-util": "^29.0.3", + "jest-config": "^29.1.2", + "jest-haste-map": "^29.1.2", + "jest-message-util": "^29.1.2", "jest-regex-util": "^29.0.0", - "jest-resolve": "^29.0.3", - "jest-resolve-dependencies": "^29.0.3", - "jest-runner": "^29.0.3", - "jest-runtime": "^29.0.3", - "jest-snapshot": "^29.0.3", - "jest-util": "^29.0.3", - "jest-validate": "^29.0.3", - "jest-watcher": "^29.0.3", + "jest-resolve": "^29.1.2", + "jest-resolve-dependencies": "^29.1.2", + "jest-runner": "^29.1.2", + "jest-runtime": "^29.1.2", + "jest-snapshot": "^29.1.2", + "jest-util": "^29.1.2", + "jest-validate": "^29.1.2", + "jest-watcher": "^29.1.2", "micromatch": "^4.0.4", - "pretty-format": "^29.0.3", + "pretty-format": "^29.1.2", "slash": "^3.0.0", "strip-ansi": "^6.0.0" }, @@ -993,37 +998,37 @@ } }, "node_modules/@jest/environment": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.0.3.tgz", - "integrity": "sha512-iKl272NKxYNQNqXMQandAIwjhQaGw5uJfGXduu8dS9llHi8jV2ChWrtOAVPnMbaaoDhnI3wgUGNDvZgHeEJQCA==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.1.2.tgz", + "integrity": "sha512-rG7xZ2UeOfvOVzoLIJ0ZmvPl4tBEQ2n73CZJSlzUjPw4or1oSWC0s0Rk0ZX+pIBJ04aVr6hLWFn1DFtrnf8MhQ==", "dev": true, "dependencies": { - "@jest/fake-timers": "^29.0.3", - "@jest/types": "^29.0.3", + "@jest/fake-timers": "^29.1.2", + "@jest/types": "^29.1.2", "@types/node": "*", - "jest-mock": "^29.0.3" + "jest-mock": "^29.1.2" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/expect": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.0.3.tgz", - "integrity": "sha512-6W7K+fsI23FQ01H/BWccPyDZFrnU9QlzDcKOjrNVU5L8yUORFAJJIpmyxWPW70+X624KUNqzZwPThPMX28aXEQ==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.1.2.tgz", + "integrity": "sha512-FXw/UmaZsyfRyvZw3M6POgSNqwmuOXJuzdNiMWW9LCYo0GRoRDhg+R5iq5higmRTHQY7hx32+j7WHwinRmoILQ==", "dev": true, "dependencies": { - "expect": "^29.0.3", - "jest-snapshot": "^29.0.3" + "expect": "^29.1.2", + "jest-snapshot": "^29.1.2" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/expect-utils": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.0.3.tgz", - "integrity": "sha512-i1xUkau7K/63MpdwiRqaxgZOjxYs4f0WMTGJnYwUKubsNRZSeQbLorS7+I4uXVF9KQ5r61BUPAUMZ7Lf66l64Q==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.1.2.tgz", + "integrity": "sha512-4a48bhKfGj/KAH39u0ppzNTABXQ8QPccWAFUFobWBaEMSMp+sB31Z2fK/l47c4a/Mu1po2ffmfAIPxXbVTXdtg==", "dev": true, "dependencies": { "jest-get-type": "^29.0.0" @@ -1033,48 +1038,48 @@ } }, "node_modules/@jest/fake-timers": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.0.3.tgz", - "integrity": "sha512-tmbUIo03x0TdtcZCESQ0oQSakPCpo7+s6+9mU19dd71MptkP4zCwoeZqna23//pgbhtT1Wq02VmA9Z9cNtvtCQ==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.1.2.tgz", + "integrity": "sha512-GppaEqS+QQYegedxVMpCe2xCXxxeYwQ7RsNx55zc8f+1q1qevkZGKequfTASI7ejmg9WwI+SJCrHe9X11bLL9Q==", "dev": true, "dependencies": { - "@jest/types": "^29.0.3", + "@jest/types": "^29.1.2", "@sinonjs/fake-timers": "^9.1.2", "@types/node": "*", - "jest-message-util": "^29.0.3", - "jest-mock": "^29.0.3", - "jest-util": "^29.0.3" + "jest-message-util": "^29.1.2", + "jest-mock": "^29.1.2", + "jest-util": "^29.1.2" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/globals": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.0.3.tgz", - "integrity": "sha512-YqGHT65rFY2siPIHHFjuCGUsbzRjdqkwbat+Of6DmYRg5shIXXrLdZoVE/+TJ9O1dsKsFmYhU58JvIbZRU1Z9w==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.1.2.tgz", + "integrity": "sha512-uMgfERpJYoQmykAd0ffyMq8wignN4SvLUG6orJQRe9WAlTRc9cdpCaE/29qurXixYJVZWUqIBXhSk8v5xN1V9g==", "dev": true, "dependencies": { - "@jest/environment": "^29.0.3", - "@jest/expect": "^29.0.3", - "@jest/types": "^29.0.3", - "jest-mock": "^29.0.3" + "@jest/environment": "^29.1.2", + "@jest/expect": "^29.1.2", + "@jest/types": "^29.1.2", + "jest-mock": "^29.1.2" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/reporters": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.0.3.tgz", - "integrity": "sha512-3+QU3d4aiyOWfmk1obDerie4XNCaD5Xo1IlKNde2yGEi02WQD+ZQD0i5Hgqm1e73sMV7kw6pMlCnprtEwEVwxw==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.1.2.tgz", + "integrity": "sha512-X4fiwwyxy9mnfpxL0g9DD0KcTmEIqP0jUdnc2cfa9riHy+I6Gwwp5vOZiwyg0vZxfSDxrOlK9S4+340W4d+DAA==", "dev": true, "dependencies": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^29.0.3", - "@jest/test-result": "^29.0.3", - "@jest/transform": "^29.0.3", - "@jest/types": "^29.0.3", + "@jest/console": "^29.1.2", + "@jest/test-result": "^29.1.2", + "@jest/transform": "^29.1.2", + "@jest/types": "^29.1.2", "@jridgewell/trace-mapping": "^0.3.15", "@types/node": "*", "chalk": "^4.0.0", @@ -1087,9 +1092,9 @@ "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", "istanbul-reports": "^3.1.3", - "jest-message-util": "^29.0.3", - "jest-util": "^29.0.3", - "jest-worker": "^29.0.3", + "jest-message-util": "^29.1.2", + "jest-util": "^29.1.2", + "jest-worker": "^29.1.2", "slash": "^3.0.0", "string-length": "^4.0.1", "strip-ansi": "^6.0.0", @@ -1135,13 +1140,13 @@ } }, "node_modules/@jest/test-result": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.0.3.tgz", - "integrity": "sha512-vViVnQjCgTmbhDKEonKJPtcFe9G/CJO4/Np4XwYJah+lF2oI7KKeRp8t1dFvv44wN2NdbDb/qC6pi++Vpp0Dlg==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.1.2.tgz", + "integrity": "sha512-jjYYjjumCJjH9hHCoMhA8PCl1OxNeGgAoZ7yuGYILRJX9NjgzTN0pCT5qAoYR4jfOP8htIByvAlz9vfNSSBoVg==", "dev": true, "dependencies": { - "@jest/console": "^29.0.3", - "@jest/types": "^29.0.3", + "@jest/console": "^29.1.2", + "@jest/types": "^29.1.2", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" }, @@ -1150,14 +1155,14 @@ } }, "node_modules/@jest/test-sequencer": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.0.3.tgz", - "integrity": "sha512-Hf4+xYSWZdxTNnhDykr8JBs0yBN/nxOXyUQWfotBUqqy0LF9vzcFB0jm/EDNZCx587znLWTIgxcokW7WeZMobQ==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.1.2.tgz", + "integrity": "sha512-fU6dsUqqm8sA+cd85BmeF7Gu9DsXVWFdGn9taxM6xN1cKdcP/ivSgXh5QucFRFz1oZxKv3/9DYYbq0ULly3P/Q==", "dev": true, "dependencies": { - "@jest/test-result": "^29.0.3", + "@jest/test-result": "^29.1.2", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.0.3", + "jest-haste-map": "^29.1.2", "slash": "^3.0.0" }, "engines": { @@ -1165,22 +1170,22 @@ } }, "node_modules/@jest/transform": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.0.3.tgz", - "integrity": "sha512-C5ihFTRYaGDbi/xbRQRdbo5ddGtI4VSpmL6AIcZxdhwLbXMa7PcXxxqyI91vGOFHnn5aVM3WYnYKCHEqmLVGzg==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.1.2.tgz", + "integrity": "sha512-2uaUuVHTitmkx1tHF+eBjb4p7UuzBG7SXIaA/hNIkaMP6K+gXYGxP38ZcrofzqN0HeZ7A90oqsOa97WU7WZkSw==", "dev": true, "dependencies": { "@babel/core": "^7.11.6", - "@jest/types": "^29.0.3", + "@jest/types": "^29.1.2", "@jridgewell/trace-mapping": "^0.3.15", "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", "convert-source-map": "^1.4.0", "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.0.3", + "jest-haste-map": "^29.1.2", "jest-regex-util": "^29.0.0", - "jest-util": "^29.0.3", + "jest-util": "^29.1.2", "micromatch": "^4.0.4", "pirates": "^4.0.4", "slash": "^3.0.0", @@ -1191,9 +1196,9 @@ } }, "node_modules/@jest/types": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.0.3.tgz", - "integrity": "sha512-coBJmOQvurXjN1Hh5PzF7cmsod0zLIOXpP8KD161mqNlroMhLcwpODiEzi7ZsRl5Z/AIuxpeNm8DCl43F4kz8A==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.1.2.tgz", + "integrity": "sha512-DcXGtoTykQB5jiwCmVr8H4vdg2OJhQex3qPkG+ISyDO7xQXbt/4R6dowcRyPemRnkH7JoHvZuxPBdlq+9JxFCg==", "dev": true, "dependencies": { "@jest/schemas": "^29.0.0", @@ -1264,18 +1269,18 @@ "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.15", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz", - "integrity": "sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==", + "version": "0.3.16", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.16.tgz", + "integrity": "sha512-LCQ+NeThyJ4k1W2d+vIKdxuSt9R3pQSZ4P92m7EakaYuXcVWbHuT5bjNcqLd4Rdgi6xYWYDvBJZJLZSLanjDcA==", "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" } }, "node_modules/@jsep-plugin/regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@jsep-plugin/regex/-/regex-1.0.2.tgz", - "integrity": "sha512-Nn/Bcaww8zOebMDqNmGlhAWPWhIr/8S8lGIgaB/fSqev5xaO5uKy5i4qvTh63GpR+VzKqimgxDdcxdcRuCJXSw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@jsep-plugin/regex/-/regex-1.0.3.tgz", + "integrity": "sha512-XfZgry4DwEZvSFtS/6Y+R48D7qJYJK6R9/yJFyUFHCIUMEEHuJ4X95TDgJp5QkmzfLYvapMPzskV5HpIDrREug==", "dev": true, "engines": { "node": ">= 10.16.0" @@ -1285,9 +1290,9 @@ } }, "node_modules/@jsep-plugin/ternary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jsep-plugin/ternary/-/ternary-1.1.2.tgz", - "integrity": "sha512-gXguJc09uCrqWt1MD7L1+ChO32g4UH4BYGpHPoQRLhyU7pAPPRA7cvKbyjoqhnUlLutiXvLzB5hVVawPKax8jw==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@jsep-plugin/ternary/-/ternary-1.1.3.tgz", + "integrity": "sha512-qtLGzCNzPVJ3kdH6/zoLWDPjauHIKiLSBAR71Wa0+PWvGA8wODUQvRgxtpUA5YqAYL3CQ8S4qXhd/9WuWTZirg==", "dev": true, "engines": { "node": ">= 10.16.0" @@ -1297,9 +1302,9 @@ } }, "node_modules/@mcaptcha/core-glue": { - "version": "0.1.0-alpha-3", - "resolved": "https://registry.npmjs.org/@mcaptcha/core-glue/-/core-glue-0.1.0-alpha-3.tgz", - "integrity": "sha512-avphBVgf3PPDWuUoDsB2qiXAss2pc00lUILswJaMQofr8FQyflzkhha8H2Z+qGFiX0Iib/yyP2TOtBDbHqE9Tg==", + "version": "0.1.0-alpha-5", + "resolved": "https://registry.npmjs.org/@mcaptcha/core-glue/-/core-glue-0.1.0-alpha-5.tgz", + "integrity": "sha512-16qWm5O5X0Y9LXULULaAks8Vf9FNlUUBcR5KDt49aWhFhG5++JzxNmCwQM9EJSHNU7y0U+FdyAWcGmjfKlkRLA==", "funding": [ { "type": "individual", @@ -1320,9 +1325,9 @@ ] }, "node_modules/@mcaptcha/vanilla-glue": { - "version": "0.1.0-alpha-2", - "resolved": "https://registry.npmjs.org/@mcaptcha/vanilla-glue/-/vanilla-glue-0.1.0-alpha-2.tgz", - "integrity": "sha512-cQOg3EIhdjk1xoZtjD9SVPwQAnd49FCvHKchwFZZuhdNTeFs7SUHynOCekuGow2Ip0RJZuMZGcRxvWMgd0ogng==", + "version": "0.1.0-alpha-3", + "resolved": "https://registry.npmjs.org/@mcaptcha/vanilla-glue/-/vanilla-glue-0.1.0-alpha-3.tgz", + "integrity": "sha512-GT6TJBgmViGXcXiT5VOr+h/6iOnThSlZuCoOWncubyTZU9R3cgU5vWPkF7G6Ob6ee2CBe3yqBxxk24CFVGTVXw==", "funding": [ { "type": "individual", @@ -1342,7 +1347,7 @@ } ], "dependencies": { - "@mcaptcha/core-glue": "^0.1.0-alpha-3" + "@mcaptcha/core-glue": "^0.1.0-alpha-5" } }, "node_modules/@nodelib/fs.scandir": { @@ -1378,13 +1383,13 @@ } }, "node_modules/@playwright/test": { - "version": "1.25.2", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.25.2.tgz", - "integrity": "sha512-6qPznIR4Fw02OMbqXUPMG6bFFg1hDVNEdihKy0t9K0dmRbus1DyP5Q5XFQhGwEHQkLG5hrSfBuu9CW/foqhQHQ==", + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.27.0.tgz", + "integrity": "sha512-L4BswoJvGkFsEHhEgzVNHBnkFB1FbnBQn3QmvTl7+AouoJQ4a8tLwZKvytdovCsNi7B5cXuRo58yGvfM5PnExw==", "dev": true, "dependencies": { "@types/node": "*", - "playwright-core": "1.25.2" + "playwright-core": "1.27.0" }, "bin": { "playwright": "cli.js" @@ -1403,9 +1408,9 @@ } }, "node_modules/@primer/octicons": { - "version": "17.5.0", - "resolved": "https://registry.npmjs.org/@primer/octicons/-/octicons-17.5.0.tgz", - "integrity": "sha512-Bx/IfCMXZSq0YBPspoRoALVou5LiAdSg4yNtwEoYDZ137aq238Glnb6SBE5BtRSyzegTv7wFp/uYUPXMXT2MRg==", + "version": "17.7.0", + "resolved": "https://registry.npmjs.org/@primer/octicons/-/octicons-17.7.0.tgz", + "integrity": "sha512-J5cVJDhExmqLGLWu8zHTOqcC8g1rQL7QzQZdbvHxW85u8ya82GtF5F68uHMDI5En3fsMlbkkF8Rz6dCaV3r+KA==", "dependencies": { "object-assign": "^4.1.1" } @@ -1455,9 +1460,9 @@ "dev": true }, "node_modules/@sinclair/typebox": { - "version": "0.24.40", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.40.tgz", - "integrity": "sha512-Xint60L8rF0+nRy+6fCjW9jQMmu7fTpbwTBrXZiK6eq/RHDJS7LvWX/0oXC8O7fCePmrY/XdfaTv2HiUDeCq4g==", + "version": "0.24.44", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.44.tgz", + "integrity": "sha512-ka0W0KN5i6LfrSocduwliMMpqVgohtPFidKdMEOUjoOFCHcOOYkKsPRxfs5f15oPNHTm6ERAm0GV/+/LTKeiWg==", "dev": true }, "node_modules/@sinonjs/commons": { @@ -1551,18 +1556,6 @@ "node": ">=8.3.0" } }, - "node_modules/@stoplight/lifecycle": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/@stoplight/lifecycle/-/lifecycle-2.3.2.tgz", - "integrity": "sha512-v0u8p27FA/eg04b4z6QXw4s0NeeFcRzyvseBW0+k/q4jtpg7EhVCqy42EbbbU43NTNDpIeQ81OcvkFz+6CYshw==", - "dev": true, - "dependencies": { - "wolfy87-eventemitter": "~5.2.8" - }, - "engines": { - "node": ">=8.3.0" - } - }, "node_modules/@stoplight/ordered-object-literal": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@stoplight/ordered-object-literal/-/ordered-object-literal-1.0.4.tgz", @@ -1647,14 +1640,13 @@ } }, "node_modules/@stoplight/spectral-core": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-core/-/spectral-core-1.14.1.tgz", - "integrity": "sha512-UMPfkrDqIMiAoZuVx4QiVV3D5fssfhDQ6R36qTP3x0hZFOeVDIFIcVdKV8lgmvsbpKaOgU/AD/2s4jScyTIqoA==", + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-core/-/spectral-core-1.14.2.tgz", + "integrity": "sha512-W2Z31lasEICpZS50STFskOdkn4g0Va81XA1A88LIj9mvlctDFf4BfpjLgIjKkI4f2DEK5C4j3COcbbzV8y5Xig==", "dev": true, "dependencies": { "@stoplight/better-ajv-errors": "1.0.3", "@stoplight/json": "~3.20.1", - "@stoplight/lifecycle": "2.3.2", "@stoplight/path": "1.3.2", "@stoplight/spectral-parsers": "^1.0.0", "@stoplight/spectral-ref-resolver": "^1.0.0", @@ -1711,9 +1703,9 @@ } }, "node_modules/@stoplight/spectral-formats": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-formats/-/spectral-formats-1.2.0.tgz", - "integrity": "sha512-idvn7r8fvQjY/KeJpKgXQ5eJhce6N6/KoKWMPSh5yyvYDpn+bkU4pxAD79jOJaDnIyKJd1jjTPEJWnxbS0jj6A==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-formats/-/spectral-formats-1.4.0.tgz", + "integrity": "sha512-j9VQukDzgqDSi26rK9LqsbXrqtkeIsPSPgEf5/sxRsmeF2bwWUhSjYXgYin4flSZ7owFZjZWQ3o0Qq3iApi2JQ==", "dev": true, "dependencies": { "@stoplight/json": "^3.17.0", @@ -1765,9 +1757,9 @@ } }, "node_modules/@stoplight/spectral-functions/node_modules/@stoplight/types": { - "version": "13.6.0", - "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.6.0.tgz", - "integrity": "sha512-dzyuzvUjv3m1wmhPfq82lCVYGcXG0xUYgqnWfCq3PCVR4BKFhjdkHrnJ+jIDoMKvXb05AZP/ObQF6+NpDo29IQ==", + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.7.0.tgz", + "integrity": "sha512-7ePIccfTxjEhruv8VrkDv5whP5qd9ijRzAWEbjYpUYnDfaqPTfq8/wMMjMCAKIecboxsAVD9LZy/3puXddGsDQ==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.4", @@ -1810,9 +1802,9 @@ } }, "node_modules/@stoplight/spectral-parsers/node_modules/@stoplight/types": { - "version": "13.6.0", - "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.6.0.tgz", - "integrity": "sha512-dzyuzvUjv3m1wmhPfq82lCVYGcXG0xUYgqnWfCq3PCVR4BKFhjdkHrnJ+jIDoMKvXb05AZP/ObQF6+NpDo29IQ==", + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.7.0.tgz", + "integrity": "sha512-7ePIccfTxjEhruv8VrkDv5whP5qd9ijRzAWEbjYpUYnDfaqPTfq8/wMMjMCAKIecboxsAVD9LZy/3puXddGsDQ==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.4", @@ -1887,9 +1879,9 @@ } }, "node_modules/@stoplight/spectral-ruleset-bundler/node_modules/@stoplight/types": { - "version": "13.6.0", - "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.6.0.tgz", - "integrity": "sha512-dzyuzvUjv3m1wmhPfq82lCVYGcXG0xUYgqnWfCq3PCVR4BKFhjdkHrnJ+jIDoMKvXb05AZP/ObQF6+NpDo29IQ==", + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.7.0.tgz", + "integrity": "sha512-7ePIccfTxjEhruv8VrkDv5whP5qd9ijRzAWEbjYpUYnDfaqPTfq8/wMMjMCAKIecboxsAVD9LZy/3puXddGsDQ==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.4", @@ -1942,9 +1934,9 @@ } }, "node_modules/@stoplight/spectral-ruleset-migrator/node_modules/@stoplight/types": { - "version": "13.6.0", - "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.6.0.tgz", - "integrity": "sha512-dzyuzvUjv3m1wmhPfq82lCVYGcXG0xUYgqnWfCq3PCVR4BKFhjdkHrnJ+jIDoMKvXb05AZP/ObQF6+NpDo29IQ==", + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.7.0.tgz", + "integrity": "sha512-7ePIccfTxjEhruv8VrkDv5whP5qd9ijRzAWEbjYpUYnDfaqPTfq8/wMMjMCAKIecboxsAVD9LZy/3puXddGsDQ==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.4", @@ -1955,16 +1947,16 @@ } }, "node_modules/@stoplight/spectral-rulesets": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-rulesets/-/spectral-rulesets-1.12.0.tgz", - "integrity": "sha512-ktSO5YPzYzscnGTQffyKJwrzsR2i5cpPUC4yBp0isc6mOeiVec4r9sjMUN1mJt0RVnXi509vd0+YlMthFIZYnw==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-rulesets/-/spectral-rulesets-1.14.1.tgz", + "integrity": "sha512-tn6a5fYPFDwEY+/YyK/hcq2gcR5nSIBt7l+JGELb/2RdTzD5ikj2mfl2ua3uxbqOZytftFoOX5ewGZ0qQNrudw==", "dev": true, "dependencies": { - "@asyncapi/specs": "^2.14.0", + "@asyncapi/specs": "^3.2.0", "@stoplight/better-ajv-errors": "1.0.3", "@stoplight/json": "^3.17.0", "@stoplight/spectral-core": "^1.8.1", - "@stoplight/spectral-formats": "^1.2.0", + "@stoplight/spectral-formats": "^1.4.0", "@stoplight/spectral-functions": "^1.5.1", "@stoplight/spectral-runtime": "^1.1.1", "@stoplight/types": "^13.6.0", @@ -1980,9 +1972,9 @@ } }, "node_modules/@stoplight/spectral-rulesets/node_modules/@stoplight/types": { - "version": "13.6.0", - "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.6.0.tgz", - "integrity": "sha512-dzyuzvUjv3m1wmhPfq82lCVYGcXG0xUYgqnWfCq3PCVR4BKFhjdkHrnJ+jIDoMKvXb05AZP/ObQF6+NpDo29IQ==", + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.7.0.tgz", + "integrity": "sha512-7ePIccfTxjEhruv8VrkDv5whP5qd9ijRzAWEbjYpUYnDfaqPTfq8/wMMjMCAKIecboxsAVD9LZy/3puXddGsDQ==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.4", @@ -2045,9 +2037,9 @@ "dev": true }, "node_modules/@stoplight/yaml/node_modules/@stoplight/types": { - "version": "13.6.0", - "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.6.0.tgz", - "integrity": "sha512-dzyuzvUjv3m1wmhPfq82lCVYGcXG0xUYgqnWfCq3PCVR4BKFhjdkHrnJ+jIDoMKvXb05AZP/ObQF6+NpDo29IQ==", + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.7.0.tgz", + "integrity": "sha512-7ePIccfTxjEhruv8VrkDv5whP5qd9ijRzAWEbjYpUYnDfaqPTfq8/wMMjMCAKIecboxsAVD9LZy/3puXddGsDQ==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.4", @@ -2113,9 +2105,9 @@ } }, "node_modules/@types/babel__traverse": { - "version": "7.18.1", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.1.tgz", - "integrity": "sha512-FSdLaZh2UxaMuLp9lixWaHq/golWTRWOnRsAXzDTDSDOQLuZb1nsdCt6pJSPWSEQt2eFZ2YVk3oYhn+1kLMeMA==", + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.2.tgz", + "integrity": "sha512-FcFaxOr2V5KZCviw1TnutEMVUVsGt4D2hP1TAfXZAMKuHYW3xQhe3jTxNPWutgCJ3/X1c5yX8ZoGVEItxKbwBg==", "dev": true, "dependencies": { "@babel/types": "^7.3.0" @@ -2228,9 +2220,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "18.7.16", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.16.tgz", - "integrity": "sha512-EQHhixfu+mkqHMZl1R2Ovuvn47PUw18azMJOTwSZr9/fhzHNGXAJ0ma0dayRVchprpCj0Kc1K1xKoWaATWF1qg==" + "version": "18.8.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.8.3.tgz", + "integrity": "sha512-0os9vz6BpGwxGe9LOhgP/ncvYN5Tx1fNcd2TM3rD/aCGBkysb+ZWpXEocG24h6ZzOi13+VB8HndAQFezsSOw1w==" }, "node_modules/@types/normalize-package-data": { "version": "2.4.1", @@ -2245,9 +2237,9 @@ "dev": true }, "node_modules/@types/prettier": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.0.tgz", - "integrity": "sha512-RI1L7N4JnW5gQw2spvL7Sllfuf1SaHdrZpCHiBlCXjIlufi1SMNnbu2teze3/QE67Fg2tBlH7W+mi4hVNk4p0A==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.1.tgz", + "integrity": "sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow==", "dev": true }, "node_modules/@types/stack-utils": { @@ -2277,9 +2269,9 @@ "dev": true }, "node_modules/@types/yargs": { - "version": "17.0.12", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.12.tgz", - "integrity": "sha512-Nz4MPhecOFArtm81gFQvQqdV7XYCrWKx5uUt6GNHredFHn1i2mtWqXTON7EPXMtNi1qjtjEM/VCHDhcHsAMLXQ==", + "version": "17.0.13", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.13.tgz", + "integrity": "sha512-9sWaruZk2JGxIQU+IhI1fhPYRcQ0UuTNuKuCW9bR5fp7qi2Llf7WDzNa17Cy7TKnh3cdxDOiyTu6gaLS0eDatg==", "dev": true, "dependencies": { "@types/yargs-parser": "*" @@ -2292,36 +2284,36 @@ "dev": true }, "node_modules/@vue/compiler-core": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.37.tgz", - "integrity": "sha512-81KhEjo7YAOh0vQJoSmAD68wLfYqJvoiD4ulyedzF+OEk/bk6/hx3fTNVfuzugIIaTrOx4PGx6pAiBRe5e9Zmg==", + "version": "3.2.40", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.40.tgz", + "integrity": "sha512-2Dc3Stk0J/VyQ4OUr2yEC53kU28614lZS+bnrCbFSAIftBJ40g/2yQzf4mPBiFuqguMB7hyHaujdgZAQ67kZYA==", "dependencies": { "@babel/parser": "^7.16.4", - "@vue/shared": "3.2.37", + "@vue/shared": "3.2.40", "estree-walker": "^2.0.2", "source-map": "^0.6.1" } }, "node_modules/@vue/compiler-dom": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.37.tgz", - "integrity": "sha512-yxJLH167fucHKxaqXpYk7x8z7mMEnXOw3G2q62FTkmsvNxu4FQSu5+3UMb+L7fjKa26DEzhrmCxAgFLLIzVfqQ==", + "version": "3.2.40", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.40.tgz", + "integrity": "sha512-OZCNyYVC2LQJy4H7h0o28rtk+4v+HMQygRTpmibGoG9wZyomQiS5otU7qo3Wlq5UfHDw2RFwxb9BJgKjVpjrQw==", "dependencies": { - "@vue/compiler-core": "3.2.37", - "@vue/shared": "3.2.37" + "@vue/compiler-core": "3.2.40", + "@vue/shared": "3.2.40" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.37.tgz", - "integrity": "sha512-+7i/2+9LYlpqDv+KTtWhOZH+pa8/HnX/905MdVmAcI/mPQOBwkHHIzrsEsucyOIZQYMkXUiTkmZq5am/NyXKkg==", + "version": "3.2.40", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.40.tgz", + "integrity": "sha512-tzqwniIN1fu1PDHC3CpqY/dPCfN/RN1thpBC+g69kJcrl7mbGiHKNwbA6kJ3XKKy8R6JLKqcpVugqN4HkeBFFg==", "dependencies": { "@babel/parser": "^7.16.4", - "@vue/compiler-core": "3.2.37", - "@vue/compiler-dom": "3.2.37", - "@vue/compiler-ssr": "3.2.37", - "@vue/reactivity-transform": "3.2.37", - "@vue/shared": "3.2.37", + "@vue/compiler-core": "3.2.40", + "@vue/compiler-dom": "3.2.40", + "@vue/compiler-ssr": "3.2.40", + "@vue/reactivity-transform": "3.2.40", + "@vue/shared": "3.2.40", "estree-walker": "^2.0.2", "magic-string": "^0.25.7", "postcss": "^8.1.10", @@ -2329,69 +2321,69 @@ } }, "node_modules/@vue/compiler-ssr": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.37.tgz", - "integrity": "sha512-7mQJD7HdXxQjktmsWp/J67lThEIcxLemz1Vb5I6rYJHR5vI+lON3nPGOH3ubmbvYGt8xEUaAr1j7/tIFWiEOqw==", + "version": "3.2.40", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.40.tgz", + "integrity": "sha512-80cQcgasKjrPPuKcxwuCx7feq+wC6oFl5YaKSee9pV3DNq+6fmCVwEEC3vvkf/E2aI76rIJSOYHsWSEIxK74oQ==", "dependencies": { - "@vue/compiler-dom": "3.2.37", - "@vue/shared": "3.2.37" + "@vue/compiler-dom": "3.2.40", + "@vue/shared": "3.2.40" } }, "node_modules/@vue/reactivity": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.37.tgz", - "integrity": "sha512-/7WRafBOshOc6m3F7plwzPeCu/RCVv9uMpOwa/5PiY1Zz+WLVRWiy0MYKwmg19KBdGtFWsmZ4cD+LOdVPcs52A==", + "version": "3.2.40", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.40.tgz", + "integrity": "sha512-N9qgGLlZmtUBMHF9xDT4EkD9RdXde1Xbveb+niWMXuHVWQP5BzgRmE3SFyUBBcyayG4y1lhoz+lphGRRxxK4RA==", "dependencies": { - "@vue/shared": "3.2.37" + "@vue/shared": "3.2.40" } }, "node_modules/@vue/reactivity-transform": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.37.tgz", - "integrity": "sha512-IWopkKEb+8qpu/1eMKVeXrK0NLw9HicGviJzhJDEyfxTR9e1WtpnnbYkJWurX6WwoFP0sz10xQg8yL8lgskAZg==", + "version": "3.2.40", + "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.40.tgz", + "integrity": "sha512-HQUCVwEaacq6fGEsg2NUuGKIhUveMCjOk8jGHqLXPI2w6zFoPrlQhwWEaINTv5kkZDXKEnCijAp+4gNEHG03yw==", "dependencies": { "@babel/parser": "^7.16.4", - "@vue/compiler-core": "3.2.37", - "@vue/shared": "3.2.37", + "@vue/compiler-core": "3.2.40", + "@vue/shared": "3.2.40", "estree-walker": "^2.0.2", "magic-string": "^0.25.7" } }, "node_modules/@vue/runtime-core": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.37.tgz", - "integrity": "sha512-JPcd9kFyEdXLl/i0ClS7lwgcs0QpUAWj+SKX2ZC3ANKi1U4DOtiEr6cRqFXsPwY5u1L9fAjkinIdB8Rz3FoYNQ==", + "version": "3.2.40", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.40.tgz", + "integrity": "sha512-U1+rWf0H8xK8aBUZhnrN97yoZfHbjgw/bGUzfgKPJl69/mXDuSg8CbdBYBn6VVQdR947vWneQBFzdhasyzMUKg==", "dependencies": { - "@vue/reactivity": "3.2.37", - "@vue/shared": "3.2.37" + "@vue/reactivity": "3.2.40", + "@vue/shared": "3.2.40" } }, "node_modules/@vue/runtime-dom": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.37.tgz", - "integrity": "sha512-HimKdh9BepShW6YozwRKAYjYQWg9mQn63RGEiSswMbW+ssIht1MILYlVGkAGGQbkhSh31PCdoUcfiu4apXJoPw==", + "version": "3.2.40", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.40.tgz", + "integrity": "sha512-AO2HMQ+0s2+MCec8hXAhxMgWhFhOPJ/CyRXnmTJ6XIOnJFLrH5Iq3TNwvVcODGR295jy77I6dWPj+wvFoSYaww==", "dependencies": { - "@vue/runtime-core": "3.2.37", - "@vue/shared": "3.2.37", + "@vue/runtime-core": "3.2.40", + "@vue/shared": "3.2.40", "csstype": "^2.6.8" } }, "node_modules/@vue/server-renderer": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.37.tgz", - "integrity": "sha512-kLITEJvaYgZQ2h47hIzPh2K3jG8c1zCVbp/o/bzQOyvzaKiCquKS7AaioPI28GNxIsE/zSx+EwWYsNxDCX95MA==", + "version": "3.2.40", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.40.tgz", + "integrity": "sha512-gtUcpRwrXOJPJ4qyBpU3EyxQa4EkV8I4f8VrDePcGCPe4O/hd0BPS7v9OgjIQob6Ap8VDz9G+mGTKazE45/95w==", "dependencies": { - "@vue/compiler-ssr": "3.2.37", - "@vue/shared": "3.2.37" + "@vue/compiler-ssr": "3.2.40", + "@vue/shared": "3.2.40" }, "peerDependencies": { - "vue": "3.2.37" + "vue": "3.2.40" } }, "node_modules/@vue/shared": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.37.tgz", - "integrity": "sha512-4rSJemR2NQIo9Klm1vabqWjD8rs/ZaJSzMxkMNeJS6lHiUjjUeYFbooN19NgFjztubEKh3WlZUeOLVdbbUWHsw==" + "version": "3.2.40", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.40.tgz", + "integrity": "sha512-0PLQ6RUtZM0vO3teRfzGi4ltLUO5aO+kLgwh4Um3THSR03rpQWLTuRCkuO5A41ITzwdWeKdPHtSARuPkoo5pCQ==" }, "node_modules/@webassemblyjs/ast": { "version": "1.11.1", @@ -2597,25 +2589,13 @@ } }, "node_modules/acorn-globals": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", - "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-7.0.1.tgz", + "integrity": "sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==", "dev": true, "dependencies": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" - } - }, - "node_modules/acorn-globals/node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" + "acorn": "^8.1.0", + "acorn-walk": "^8.0.2" } }, "node_modules/acorn-import-assertions": { @@ -2636,9 +2616,9 @@ } }, "node_modules/acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", "dev": true, "engines": { "node": ">=0.4.0" @@ -2912,12 +2892,12 @@ "dev": true }, "node_modules/babel-jest": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.0.3.tgz", - "integrity": "sha512-ApPyHSOhS/sVzwUOQIWJmdvDhBsMG01HX9z7ogtkp1TToHGGUWFlnXJUIzCgKPSfiYLn3ibipCYzsKSURHEwLg==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.1.2.tgz", + "integrity": "sha512-IuG+F3HTHryJb7gacC7SQ59A9kO56BctUsT67uJHp1mMCHUOMXpDwOHWGifWqdWVknN2WNkCVQELPjXx0aLJ9Q==", "dev": true, "dependencies": { - "@jest/transform": "^29.0.3", + "@jest/transform": "^29.1.2", "@types/babel__core": "^7.1.14", "babel-plugin-istanbul": "^6.1.1", "babel-preset-jest": "^29.0.2", @@ -3047,16 +3027,10 @@ "node": ">=8" } }, - "node_modules/browser-process-hrtime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", - "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", - "dev": true - }, "node_modules/browserslist": { - "version": "4.21.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.3.tgz", - "integrity": "sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ==", + "version": "4.21.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", + "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", "funding": [ { "type": "opencollective", @@ -3068,10 +3042,10 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001370", - "electron-to-chromium": "^1.4.202", + "caniuse-lite": "^1.0.30001400", + "electron-to-chromium": "^1.4.251", "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.5" + "update-browserslist-db": "^1.0.9" }, "bin": { "browserslist": "cli.js" @@ -3170,9 +3144,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001393", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001393.tgz", - "integrity": "sha512-N/od11RX+Gsk+1qY/jbPa0R6zJupEa0lxeBG598EbrtblxVCTJsQwbRBm6+V+rxpc5lHKdsXb9RY83cZIPLseA==", + "version": "1.0.30001418", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001418.tgz", + "integrity": "sha512-oIs7+JL3K9JRQ3jPZjlH6qyYDp+nBTCais7hjh0s+fuBwufc7uZ7hPYMXrDOJhV360KGMTcczMRObk0/iMqZRg==", "funding": [ { "type": "opencollective", @@ -3217,9 +3191,9 @@ } }, "node_modules/ci-info": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.4.0.tgz", - "integrity": "sha512-t5QdPT5jq3o262DOQ8zA6E1tlH2upmUc4Hlvrbx1pGYJuiiHl7O7rvVNI+l8HTVhd/q3Qc9vqimkNk5yiXsAug==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.5.0.tgz", + "integrity": "sha512-yH4RezKOGlOhxkmhbeNuC4eYZKAUsEaGtBuBzDDP1eFUKiccDWzBABxBfOx31IDwDIXMTxWuwAxUGModvkbuVw==", "dev": true }, "node_modules/cjs-module-lexer": { @@ -3312,9 +3286,9 @@ } }, "node_modules/codemirror": { - "version": "5.65.8", - "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.8.tgz", - "integrity": "sha512-TNGkSkkoAsmZSf6W6g35LMVQJBHKasc2CKwhr/fTxSYun7cn6J+CbtyNjV/MYlFVkNTsqZoviegyCZimWhoMMA==" + "version": "5.65.9", + "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.9.tgz", + "integrity": "sha512-19Jox5sAKpusTDgqgKB5dawPpQcY+ipQK7xoEI+MVucEF9qqFaXpeqY1KaoyGBso/wHQoDa4HMMxMjdsS3Zzzw==" }, "node_modules/codemirror-spell-checker": { "version": "1.1.2", @@ -3370,12 +3344,11 @@ } }, "node_modules/commander": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-9.4.0.tgz", - "integrity": "sha512-sRPT+umqkz90UA8M1yqYfnHlZA7fF6nSphDtxeywPZ49ysjxDQybzk13CL+mXekDRG92skbcqCLVovuCusNmFw==", - "dev": true, + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", "engines": { - "node": "^12.20.0 || >=14" + "node": ">= 12" } }, "node_modules/commondir": { @@ -4332,9 +4305,9 @@ } }, "node_modules/decimal.js": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.0.tgz", - "integrity": "sha512-Nv6ENEzyPQ6AItkGwLE2PGKinZZ9g59vSh2BeH6NqPu0OTKZ5ruJsVqh/orbAnqXc9pBbgXAIrc2EyaCj8NpGg==", + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.1.tgz", + "integrity": "sha512-F29o+vci4DodHYT9UrR5IEbfBw9pE5eSapIJdTqXK5+6hq+t8VRxwQyKlW2i+KDKFkkJQRvFyI/QXD83h8LyQw==", "dev": true }, "node_modules/dedent": { @@ -4632,9 +4605,9 @@ } }, "node_modules/dompurify": { - "version": "2.3.10", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.3.10.tgz", - "integrity": "sha512-o7Fg/AgC7p/XpKjf/+RC3Ok6k4St5F7Q6q6+Nnm3p2zGWioAY6dh0CbbuwOhH2UcSzKsdniE/YnE2/92JcsA+g==" + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.4.0.tgz", + "integrity": "sha512-Be9tbQMZds4a3C6xTmz68NlMfeONA//4dOavl/1rNw50E+/QO0KVpbcU0PcaW0nsQxurXls9ZocqFxk8R2mWEA==" }, "node_modules/domutils": { "version": "2.8.0", @@ -4665,21 +4638,21 @@ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" }, "node_modules/easymde": { - "version": "2.17.0", - "resolved": "https://registry.npmjs.org/easymde/-/easymde-2.17.0.tgz", - "integrity": "sha512-xerjhBh6G+FDfU2EBfKNEVqawYGqnK2zACKtyQlZKnxPoaesncRbHiSX5Yrf3Ur8KjEX1BvG7Ysccrd8hKTkig==", + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/easymde/-/easymde-2.18.0.tgz", + "integrity": "sha512-IxVVUxNWIoXLeqtBU4BLc+eS/ScYhT1Dcb6yF5Wchoj1iXAV+TIIDWx+NCaZhY7RcSHqDPKllbYq7nwGKILnoA==", "dependencies": { "@types/codemirror": "^5.60.4", - "@types/marked": "^4.0.1", + "@types/marked": "^4.0.7", "codemirror": "^5.63.1", "codemirror-spell-checker": "1.1.2", - "marked": "^4.0.18" + "marked": "^4.1.0" } }, "node_modules/electron-to-chromium": { - "version": "1.4.247", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.247.tgz", - "integrity": "sha512-FLs6R4FQE+1JHM0hh3sfdxnYjKvJpHZyhQDjc2qFq/xFvmmRt/TATNToZhrcGUFzpF2XjeiuozrA8lI0PZmYYw==" + "version": "1.4.276", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.276.tgz", + "integrity": "sha512-EpuHPqu8YhonqLBXHoU6hDJCD98FCe6KDoet3/gY1qsQ6usjJoHqBH2YIVs8FXaAtHwVL8Uqa/fsYao/vq9VWQ==" }, "node_modules/emittery": { "version": "0.10.2", @@ -4769,22 +4742,22 @@ } }, "node_modules/es-abstract": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.2.tgz", - "integrity": "sha512-XxXQuVNrySBNlEkTYJoDNFe5+s2yIOpzq80sUHEdPdQr0S5nTLz4ZPPPswNIpKseDDUS5yghX1gfLIHQZ1iNuQ==", + "version": "1.20.4", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.4.tgz", + "integrity": "sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA==", "dev": true, "dependencies": { "call-bind": "^1.0.2", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.1.2", + "get-intrinsic": "^1.1.3", "get-symbol-description": "^1.0.0", "has": "^1.0.3", "has-property-descriptors": "^1.0.0", "has-symbols": "^1.0.3", "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", + "is-callable": "^1.2.7", "is-negative-zero": "^2.0.2", "is-regex": "^1.1.4", "is-shared-array-buffer": "^1.0.2", @@ -4794,6 +4767,7 @@ "object-keys": "^1.1.1", "object.assign": "^4.1.4", "regexp.prototype.flags": "^1.4.3", + "safe-regex-test": "^1.0.0", "string.prototype.trimend": "^1.0.5", "string.prototype.trimstart": "^1.0.5", "unbox-primitive": "^1.0.2" @@ -4858,9 +4832,9 @@ } }, "node_modules/esbuild": { - "version": "0.15.7", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.7.tgz", - "integrity": "sha512-7V8tzllIbAQV1M4QoE52ImKu8hT/NLGlGXkiDsbEU5PS6K8Mn09ZnYoS+dcmHxOS9CRsV4IRAMdT3I67IyUNXw==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.10.tgz", + "integrity": "sha512-N7wBhfJ/E5fzn/SpNgX+oW2RLRjwaL8Y0ezqNqhjD6w0H2p0rDuEz2FKZqpqLnO8DCaWumKe8dsC/ljvVSSxng==", "hasInstallScript": true, "bin": { "esbuild": "bin/esbuild" @@ -4869,33 +4843,34 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/linux-loong64": "0.15.7", - "esbuild-android-64": "0.15.7", - "esbuild-android-arm64": "0.15.7", - "esbuild-darwin-64": "0.15.7", - "esbuild-darwin-arm64": "0.15.7", - "esbuild-freebsd-64": "0.15.7", - "esbuild-freebsd-arm64": "0.15.7", - "esbuild-linux-32": "0.15.7", - "esbuild-linux-64": "0.15.7", - "esbuild-linux-arm": "0.15.7", - "esbuild-linux-arm64": "0.15.7", - "esbuild-linux-mips64le": "0.15.7", - "esbuild-linux-ppc64le": "0.15.7", - "esbuild-linux-riscv64": "0.15.7", - "esbuild-linux-s390x": "0.15.7", - "esbuild-netbsd-64": "0.15.7", - "esbuild-openbsd-64": "0.15.7", - "esbuild-sunos-64": "0.15.7", - "esbuild-windows-32": "0.15.7", - "esbuild-windows-64": "0.15.7", - "esbuild-windows-arm64": "0.15.7" + "@esbuild/android-arm": "0.15.10", + "@esbuild/linux-loong64": "0.15.10", + "esbuild-android-64": "0.15.10", + "esbuild-android-arm64": "0.15.10", + "esbuild-darwin-64": "0.15.10", + "esbuild-darwin-arm64": "0.15.10", + "esbuild-freebsd-64": "0.15.10", + "esbuild-freebsd-arm64": "0.15.10", + "esbuild-linux-32": "0.15.10", + "esbuild-linux-64": "0.15.10", + "esbuild-linux-arm": "0.15.10", + "esbuild-linux-arm64": "0.15.10", + "esbuild-linux-mips64le": "0.15.10", + "esbuild-linux-ppc64le": "0.15.10", + "esbuild-linux-riscv64": "0.15.10", + "esbuild-linux-s390x": "0.15.10", + "esbuild-netbsd-64": "0.15.10", + "esbuild-openbsd-64": "0.15.10", + "esbuild-sunos-64": "0.15.10", + "esbuild-windows-32": "0.15.10", + "esbuild-windows-64": "0.15.10", + "esbuild-windows-arm64": "0.15.10" } }, "node_modules/esbuild-android-64": { - "version": "0.15.7", - "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.7.tgz", - "integrity": "sha512-p7rCvdsldhxQr3YHxptf1Jcd86dlhvc3EQmQJaZzzuAxefO9PvcI0GLOa5nCWem1AJ8iMRu9w0r5TG8pHmbi9w==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.10.tgz", + "integrity": "sha512-UI7krF8OYO1N7JYTgLT9ML5j4+45ra3amLZKx7LO3lmLt1Ibn8t3aZbX5Pu4BjWiqDuJ3m/hsvhPhK/5Y/YpnA==", "cpu": [ "x64" ], @@ -4908,9 +4883,9 @@ } }, "node_modules/esbuild-android-arm64": { - "version": "0.15.7", - "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.7.tgz", - "integrity": "sha512-L775l9ynJT7rVqRM5vo+9w5g2ysbOCfsdLV4CWanTZ1k/9Jb3IYlQ06VCI1edhcosTYJRECQFJa3eAvkx72eyQ==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.10.tgz", + "integrity": "sha512-EOt55D6xBk5O05AK8brXUbZmoFj4chM8u3riGflLa6ziEoVvNjRdD7Cnp82NHQGfSHgYR06XsPI8/sMuA/cUwg==", "cpu": [ "arm64" ], @@ -4923,9 +4898,9 @@ } }, "node_modules/esbuild-darwin-64": { - "version": "0.15.7", - "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.7.tgz", - "integrity": "sha512-KGPt3r1c9ww009t2xLB6Vk0YyNOXh7hbjZ3EecHoVDxgtbUlYstMPDaReimKe6eOEfyY4hBEEeTvKwPsiH5WZg==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.10.tgz", + "integrity": "sha512-hbDJugTicqIm+WKZgp208d7FcXcaK8j2c0l+fqSJ3d2AzQAfjEYDRM3Z2oMeqSJ9uFxyj/muSACLdix7oTstRA==", "cpu": [ "x64" ], @@ -4938,9 +4913,9 @@ } }, "node_modules/esbuild-darwin-arm64": { - "version": "0.15.7", - "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.7.tgz", - "integrity": "sha512-kBIHvtVqbSGajN88lYMnR3aIleH3ABZLLFLxwL2stiuIGAjGlQW741NxVTpUHQXUmPzxi6POqc9npkXa8AcSZQ==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.10.tgz", + "integrity": "sha512-M1t5+Kj4IgSbYmunf2BB6EKLkWUq+XlqaFRiGOk8bmBapu9bCDrxjf4kUnWn59Dka3I27EiuHBKd1rSO4osLFQ==", "cpu": [ "arm64" ], @@ -4953,9 +4928,9 @@ } }, "node_modules/esbuild-freebsd-64": { - "version": "0.15.7", - "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.7.tgz", - "integrity": "sha512-hESZB91qDLV5MEwNxzMxPfbjAhOmtfsr9Wnuci7pY6TtEh4UDuevmGmkUIjX/b+e/k4tcNBMf7SRQ2mdNuK/HQ==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.10.tgz", + "integrity": "sha512-KMBFMa7C8oc97nqDdoZwtDBX7gfpolkk6Bcmj6YFMrtCMVgoU/x2DI1p74DmYl7CSS6Ppa3xgemrLrr5IjIn0w==", "cpu": [ "x64" ], @@ -4968,9 +4943,9 @@ } }, "node_modules/esbuild-freebsd-arm64": { - "version": "0.15.7", - "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.7.tgz", - "integrity": "sha512-dLFR0ChH5t+b3J8w0fVKGvtwSLWCv7GYT2Y2jFGulF1L5HftQLzVGN+6pi1SivuiVSmTh28FwUhi9PwQicXI6Q==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.10.tgz", + "integrity": "sha512-m2KNbuCX13yQqLlbSojFMHpewbn8wW5uDS6DxRpmaZKzyq8Dbsku6hHvh2U+BcLwWY4mpgXzFUoENEf7IcioGg==", "cpu": [ "arm64" ], @@ -4983,9 +4958,9 @@ } }, "node_modules/esbuild-linux-32": { - "version": "0.15.7", - "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.7.tgz", - "integrity": "sha512-v3gT/LsONGUZcjbt2swrMjwxo32NJzk+7sAgtxhGx1+ZmOFaTRXBAi1PPfgpeo/J//Un2jIKm/I+qqeo4caJvg==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.10.tgz", + "integrity": "sha512-guXrwSYFAvNkuQ39FNeV4sNkNms1bLlA5vF1H0cazZBOLdLFIny6BhT+TUbK/hdByMQhtWQ5jI9VAmPKbVPu1w==", "cpu": [ "ia32" ], @@ -4998,9 +4973,9 @@ } }, "node_modules/esbuild-linux-64": { - "version": "0.15.7", - "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.7.tgz", - "integrity": "sha512-LxXEfLAKwOVmm1yecpMmWERBshl+Kv5YJ/1KnyAr6HRHFW8cxOEsEfisD3sVl/RvHyW//lhYUVSuy9jGEfIRAQ==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.10.tgz", + "integrity": "sha512-jd8XfaSJeucMpD63YNMO1JCrdJhckHWcMv6O233bL4l6ogQKQOxBYSRP/XLWP+6kVTu0obXovuckJDcA0DKtQA==", "cpu": [ "x64" ], @@ -5013,9 +4988,9 @@ } }, "node_modules/esbuild-linux-arm": { - "version": "0.15.7", - "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.7.tgz", - "integrity": "sha512-JKgAHtMR5f75wJTeuNQbyznZZa+pjiUHV7sRZp42UNdyXC6TiUYMW/8z8yIBAr2Fpad8hM1royZKQisqPABPvQ==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.10.tgz", + "integrity": "sha512-6N8vThLL/Lysy9y4Ex8XoLQAlbZKUyExCWyayGi2KgTBelKpPgj6RZnUaKri0dHNPGgReJriKVU6+KDGQwn10A==", "cpu": [ "arm" ], @@ -5028,9 +5003,9 @@ } }, "node_modules/esbuild-linux-arm64": { - "version": "0.15.7", - "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.7.tgz", - "integrity": "sha512-P3cfhudpzWDkglutWgXcT2S7Ft7o2e3YDMrP1n0z2dlbUZghUkKCyaWw0zhp4KxEEzt/E7lmrtRu/pGWnwb9vw==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.10.tgz", + "integrity": "sha512-GByBi4fgkvZFTHFDYNftu1DQ1GzR23jws0oWyCfhnI7eMOe+wgwWrc78dbNk709Ivdr/evefm2PJiUBMiusS1A==", "cpu": [ "arm64" ], @@ -5043,9 +5018,9 @@ } }, "node_modules/esbuild-linux-mips64le": { - "version": "0.15.7", - "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.7.tgz", - "integrity": "sha512-T7XKuxl0VpeFLCJXub6U+iybiqh0kM/bWOTb4qcPyDDwNVhLUiPcGdG2/0S7F93czUZOKP57YiLV8YQewgLHKw==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.10.tgz", + "integrity": "sha512-BxP+LbaGVGIdQNJUNF7qpYjEGWb0YyHVSKqYKrn+pTwH/SiHUxFyJYSP3pqkku61olQiSBnSmWZ+YUpj78Tw7Q==", "cpu": [ "mips64el" ], @@ -5058,9 +5033,9 @@ } }, "node_modules/esbuild-linux-ppc64le": { - "version": "0.15.7", - "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.7.tgz", - "integrity": "sha512-6mGuC19WpFN7NYbecMIJjeQgvDb5aMuvyk0PDYBJrqAEMkTwg3Z98kEKuCm6THHRnrgsdr7bp4SruSAxEM4eJw==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.10.tgz", + "integrity": "sha512-LoSQCd6498PmninNgqd/BR7z3Bsk/mabImBWuQ4wQgmQEeanzWd5BQU2aNi9mBURCLgyheuZS6Xhrw5luw3OkQ==", "cpu": [ "ppc64" ], @@ -5073,9 +5048,9 @@ } }, "node_modules/esbuild-linux-riscv64": { - "version": "0.15.7", - "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.7.tgz", - "integrity": "sha512-uUJsezbswAYo/X7OU/P+PuL/EI9WzxsEQXDekfwpQ23uGiooxqoLFAPmXPcRAt941vjlY9jtITEEikWMBr+F/g==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.10.tgz", + "integrity": "sha512-Lrl9Cr2YROvPV4wmZ1/g48httE8z/5SCiXIyebiB5N8VT7pX3t6meI7TQVHw/wQpqP/AF4SksDuFImPTM7Z32Q==", "cpu": [ "riscv64" ], @@ -5088,9 +5063,9 @@ } }, "node_modules/esbuild-linux-s390x": { - "version": "0.15.7", - "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.7.tgz", - "integrity": "sha512-+tO+xOyTNMc34rXlSxK7aCwJgvQyffqEM5MMdNDEeMU3ss0S6wKvbBOQfgd5jRPblfwJ6b+bKiz0g5nABpY0QQ==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.10.tgz", + "integrity": "sha512-ReP+6q3eLVVP2lpRrvl5EodKX7EZ1bS1/z5j6hsluAlZP5aHhk6ghT6Cq3IANvvDdscMMCB4QEbI+AjtvoOFpA==", "cpu": [ "s390x" ], @@ -5122,9 +5097,9 @@ } }, "node_modules/esbuild-netbsd-64": { - "version": "0.15.7", - "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.7.tgz", - "integrity": "sha512-yVc4Wz+Pu3cP5hzm5kIygNPrjar/v5WCSoRmIjCPWfBVJkZNb5brEGKUlf+0Y759D48BCWa0WHrWXaNy0DULTQ==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.10.tgz", + "integrity": "sha512-iGDYtJCMCqldMskQ4eIV+QSS/CuT7xyy9i2/FjpKvxAuCzrESZXiA1L64YNj6/afuzfBe9i8m/uDkFHy257hTw==", "cpu": [ "x64" ], @@ -5137,9 +5112,9 @@ } }, "node_modules/esbuild-openbsd-64": { - "version": "0.15.7", - "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.7.tgz", - "integrity": "sha512-GsimbwC4FSR4lN3wf8XmTQ+r8/0YSQo21rWDL0XFFhLHKlzEA4SsT1Tl8bPYu00IU6UWSJ+b3fG/8SB69rcuEQ==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.10.tgz", + "integrity": "sha512-ftMMIwHWrnrYnvuJQRJs/Smlcb28F9ICGde/P3FUTCgDDM0N7WA0o9uOR38f5Xe2/OhNCgkjNeb7QeaE3cyWkQ==", "cpu": [ "x64" ], @@ -5152,9 +5127,9 @@ } }, "node_modules/esbuild-sunos-64": { - "version": "0.15.7", - "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.7.tgz", - "integrity": "sha512-8CDI1aL/ts0mDGbWzjEOGKXnU7p3rDzggHSBtVryQzkSOsjCHRVe0iFYUuhczlxU1R3LN/E7HgUO4NXzGGP/Ag==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.10.tgz", + "integrity": "sha512-mf7hBL9Uo2gcy2r3rUFMjVpTaGpFJJE5QTDDqUFf1632FxteYANffDZmKbqX0PfeQ2XjUDE604IcE7OJeoHiyg==", "cpu": [ "x64" ], @@ -5167,9 +5142,9 @@ } }, "node_modules/esbuild-windows-32": { - "version": "0.15.7", - "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.7.tgz", - "integrity": "sha512-cOnKXUEPS8EGCzRSFa1x6NQjGhGsFlVgjhqGEbLTPsA7x4RRYiy2RKoArNUU4iR2vHmzqS5Gr84MEumO/wxYKA==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.10.tgz", + "integrity": "sha512-ttFVo+Cg8b5+qHmZHbEc8Vl17kCleHhLzgT8X04y8zudEApo0PxPg9Mz8Z2cKH1bCYlve1XL8LkyXGFjtUYeGg==", "cpu": [ "ia32" ], @@ -5182,9 +5157,9 @@ } }, "node_modules/esbuild-windows-64": { - "version": "0.15.7", - "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.7.tgz", - "integrity": "sha512-7MI08Ec2sTIDv+zH6StNBKO+2hGUYIT42GmFyW6MBBWWtJhTcQLinKS6ldIN1d52MXIbiJ6nXyCJ+LpL4jBm3Q==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.10.tgz", + "integrity": "sha512-2H0gdsyHi5x+8lbng3hLbxDWR7mKHWh5BXZGKVG830KUmXOOWFE2YKJ4tHRkejRduOGDrBvHBriYsGtmTv3ntA==", "cpu": [ "x64" ], @@ -5197,9 +5172,9 @@ } }, "node_modules/esbuild-windows-arm64": { - "version": "0.15.7", - "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.7.tgz", - "integrity": "sha512-R06nmqBlWjKHddhRJYlqDd3Fabx9LFdKcjoOy08YLimwmsswlFBJV4rXzZCxz/b7ZJXvrZgj8DDv1ewE9+StMw==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.10.tgz", + "integrity": "sha512-S+th4F+F8VLsHLR0zrUcG+Et4hx0RKgK1eyHc08kztmLOES8BWwMiaGdoW9hiXuzznXQ0I/Fg904MNbr11Nktw==", "cpu": [ "arm64" ], @@ -5316,14 +5291,13 @@ } }, "node_modules/eslint": { - "version": "8.23.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.23.0.tgz", - "integrity": "sha512-pBG/XOn0MsJcKcTRLr27S5HpzQo4kLr+HjLQIyK4EiCsijDl/TB+h5uEuJU6bQ8Edvwz1XWOjpaP2qgnXGpTcA==", + "version": "8.25.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.25.0.tgz", + "integrity": "sha512-DVlJOZ4Pn50zcKW5bYH7GQK/9MsoQG2d5eDH0ebEkE8PbgzTTmtt/VTH9GGJ4BfeZCpBLqFfvsjX35UacUL83A==", "dev": true, "dependencies": { - "@eslint/eslintrc": "^1.3.1", - "@humanwhocodes/config-array": "^0.10.4", - "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", + "@eslint/eslintrc": "^1.3.3", + "@humanwhocodes/config-array": "^0.10.5", "@humanwhocodes/module-importer": "^1.0.1", "ajv": "^6.10.0", "chalk": "^4.0.0", @@ -5340,7 +5314,6 @@ "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "find-up": "^5.0.0", - "functional-red-black-tree": "^1.0.1", "glob-parent": "^6.0.1", "globals": "^13.15.0", "globby": "^11.1.0", @@ -5349,6 +5322,7 @@ "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", + "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", @@ -5492,18 +5466,18 @@ } }, "node_modules/eslint-plugin-unicorn": { - "version": "43.0.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-43.0.2.tgz", - "integrity": "sha512-DtqZ5mf/GMlfWoz1abIjq5jZfaFuHzGBZYIeuJfEoKKGWRHr2JiJR+ea+BF7Wx2N1PPRoT/2fwgiK1NnmNE3Hg==", + "version": "44.0.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-44.0.2.tgz", + "integrity": "sha512-GLIDX1wmeEqpGaKcnMcqRvMVsoabeF0Ton0EX4Th5u6Kmf7RM9WBl705AXFEsns56ESkEs0uyelLuUTvz9Tr0w==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.18.6", - "ci-info": "^3.3.2", + "@babel/helper-validator-identifier": "^7.19.1", + "ci-info": "^3.4.0", "clean-regexp": "^1.0.0", "eslint-utils": "^3.0.0", "esquery": "^1.4.0", "indent-string": "^4.0.0", - "is-builtin-module": "^3.1.0", + "is-builtin-module": "^3.2.0", "lodash": "^4.17.21", "pluralize": "^8.0.0", "read-pkg-up": "^7.0.1", @@ -5519,13 +5493,13 @@ "url": "https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1" }, "peerDependencies": { - "eslint": ">=8.18.0" + "eslint": ">=8.23.1" } }, "node_modules/eslint-plugin-vue": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.4.0.tgz", - "integrity": "sha512-Nzz2QIJ8FG+rtJaqT/7/ru5ie2XgT9KCudkbN0y3uFYhQ41nuHEaboLAiqwMcK006hZPQv/rVMRhUIwEGhIvfQ==", + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.6.0.tgz", + "integrity": "sha512-zzySkJgVbFCylnG2+9MDF7N+2Rjze2y0bF8GyUNpFOnT8mCMfqqtLDJkHBuYu9N/psW1A6DVbQhPkP92E+qakA==", "dev": true, "dependencies": { "eslint-utils": "^3.0.0", @@ -5739,16 +5713,16 @@ } }, "node_modules/expect": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.0.3.tgz", - "integrity": "sha512-t8l5DTws3212VbmPL+tBFXhjRHLmctHB0oQbL8eUc6S7NzZtYUhycrFO9mkxA0ZUC6FAWdNi7JchJSkODtcu1Q==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.1.2.tgz", + "integrity": "sha512-AuAGn1uxva5YBbBlXb+2JPxJRuemZsmlGcapPXWNSBNsQtAULfjioREGBWuI0EOvYUKjDnrCy8PW5Zlr1md5mw==", "dev": true, "dependencies": { - "@jest/expect-utils": "^29.0.3", + "@jest/expect-utils": "^29.1.2", "jest-get-type": "^29.0.0", - "jest-matcher-utils": "^29.0.3", - "jest-message-util": "^29.0.3", - "jest-util": "^29.0.3" + "jest-matcher-utils": "^29.1.2", + "jest-message-util": "^29.1.2", + "jest-util": "^29.1.2" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -5819,9 +5793,9 @@ } }, "node_modules/fb-watchman": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", - "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", "dev": true, "dependencies": { "bser": "2.1.1" @@ -5985,12 +5959,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", - "dev": true - }, "node_modules/functions-have-names": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", @@ -6019,9 +5987,9 @@ } }, "node_modules/get-intrinsic": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz", - "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", + "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", "dev": true, "dependencies": { "function-bind": "^1.1.1", @@ -6279,9 +6247,9 @@ } }, "node_modules/gsap": { - "version": "3.11.1", - "resolved": "https://registry.npmjs.org/gsap/-/gsap-3.11.1.tgz", - "integrity": "sha512-UKuJ0UPhntFHMwT6URFQ4cTQv88xc7Kd9Dhxt7qX9IPhC+d+/a5wKW5E5Vn33hZ53nBI1JfApcEbzKgXkcuPZw==" + "version": "3.11.3", + "resolved": "https://registry.npmjs.org/gsap/-/gsap-3.11.3.tgz", + "integrity": "sha512-xc/iIJy+LWiMbRa4IdMtdnnKa/7PXEK6NNzV71gdOYUVeTZN7UWnLU0fB7Hi1iwiz4ZZoYkBZPPYGg+2+zzFHA==" }, "node_modules/hard-rejection": { "version": "2.1.0", @@ -6675,9 +6643,9 @@ } }, "node_modules/is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "dev": true, "engines": { "node": ">= 0.4" @@ -6932,9 +6900,9 @@ } }, "node_modules/istanbul-lib-instrument": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.0.tgz", - "integrity": "sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", "dev": true, "dependencies": { "@babel/core": "^7.12.3", @@ -6998,15 +6966,15 @@ } }, "node_modules/jest": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest/-/jest-29.0.3.tgz", - "integrity": "sha512-ElgUtJBLgXM1E8L6K1RW1T96R897YY/3lRYqq9uVcPWtP2AAl/nQ16IYDh/FzQOOQ12VEuLdcPU83mbhG2C3PQ==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.1.2.tgz", + "integrity": "sha512-5wEIPpCezgORnqf+rCaYD1SK+mNN7NsstWzIsuvsnrhR/hSxXWd82oI7DkrbJ+XTD28/eG8SmxdGvukrGGK6Tw==", "dev": true, "dependencies": { - "@jest/core": "^29.0.3", - "@jest/types": "^29.0.3", + "@jest/core": "^29.1.2", + "@jest/types": "^29.1.2", "import-local": "^3.0.2", - "jest-cli": "^29.0.3" + "jest-cli": "^29.1.2" }, "bin": { "jest": "bin/jest.js" @@ -7037,28 +7005,28 @@ } }, "node_modules/jest-circus": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.0.3.tgz", - "integrity": "sha512-QeGzagC6Hw5pP+df1+aoF8+FBSgkPmraC1UdkeunWh0jmrp7wC0Hr6umdUAOELBQmxtKAOMNC3KAdjmCds92Zg==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.1.2.tgz", + "integrity": "sha512-ajQOdxY6mT9GtnfJRZBRYS7toNIJayiiyjDyoZcnvPRUPwJ58JX0ci0PKAKUo2C1RyzlHw0jabjLGKksO42JGA==", "dev": true, "dependencies": { - "@jest/environment": "^29.0.3", - "@jest/expect": "^29.0.3", - "@jest/test-result": "^29.0.3", - "@jest/types": "^29.0.3", + "@jest/environment": "^29.1.2", + "@jest/expect": "^29.1.2", + "@jest/test-result": "^29.1.2", + "@jest/types": "^29.1.2", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", "dedent": "^0.7.0", "is-generator-fn": "^2.0.0", - "jest-each": "^29.0.3", - "jest-matcher-utils": "^29.0.3", - "jest-message-util": "^29.0.3", - "jest-runtime": "^29.0.3", - "jest-snapshot": "^29.0.3", - "jest-util": "^29.0.3", + "jest-each": "^29.1.2", + "jest-matcher-utils": "^29.1.2", + "jest-message-util": "^29.1.2", + "jest-runtime": "^29.1.2", + "jest-snapshot": "^29.1.2", + "jest-util": "^29.1.2", "p-limit": "^3.1.0", - "pretty-format": "^29.0.3", + "pretty-format": "^29.1.2", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -7067,21 +7035,21 @@ } }, "node_modules/jest-cli": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.0.3.tgz", - "integrity": "sha512-aUy9Gd/Kut1z80eBzG10jAn6BgS3BoBbXyv+uXEqBJ8wnnuZ5RpNfARoskSrTIy1GY4a8f32YGuCMwibtkl9CQ==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.1.2.tgz", + "integrity": "sha512-vsvBfQ7oS2o4MJdAH+4u9z76Vw5Q8WBQF5MchDbkylNknZdrPTX1Ix7YRJyTlOWqRaS7ue/cEAn+E4V1MWyMzw==", "dev": true, "dependencies": { - "@jest/core": "^29.0.3", - "@jest/test-result": "^29.0.3", - "@jest/types": "^29.0.3", + "@jest/core": "^29.1.2", + "@jest/test-result": "^29.1.2", + "@jest/types": "^29.1.2", "chalk": "^4.0.0", "exit": "^0.1.2", "graceful-fs": "^4.2.9", "import-local": "^3.0.2", - "jest-config": "^29.0.3", - "jest-util": "^29.0.3", - "jest-validate": "^29.0.3", + "jest-config": "^29.1.2", + "jest-util": "^29.1.2", + "jest-validate": "^29.1.2", "prompts": "^2.0.1", "yargs": "^17.3.1" }, @@ -7101,31 +7069,31 @@ } }, "node_modules/jest-config": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.0.3.tgz", - "integrity": "sha512-U5qkc82HHVYe3fNu2CRXLN4g761Na26rWKf7CjM8LlZB3In1jadEkZdMwsE37rd9RSPV0NfYaCjHdk/gu3v+Ew==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.1.2.tgz", + "integrity": "sha512-EC3Zi86HJUOz+2YWQcJYQXlf0zuBhJoeyxLM6vb6qJsVmpP7KcCP1JnyF0iaqTaXdBP8Rlwsvs7hnKWQWWLwwA==", "dev": true, "dependencies": { "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^29.0.3", - "@jest/types": "^29.0.3", - "babel-jest": "^29.0.3", + "@jest/test-sequencer": "^29.1.2", + "@jest/types": "^29.1.2", + "babel-jest": "^29.1.2", "chalk": "^4.0.0", "ci-info": "^3.2.0", "deepmerge": "^4.2.2", "glob": "^7.1.3", "graceful-fs": "^4.2.9", - "jest-circus": "^29.0.3", - "jest-environment-node": "^29.0.3", + "jest-circus": "^29.1.2", + "jest-environment-node": "^29.1.2", "jest-get-type": "^29.0.0", "jest-regex-util": "^29.0.0", - "jest-resolve": "^29.0.3", - "jest-runner": "^29.0.3", - "jest-util": "^29.0.3", - "jest-validate": "^29.0.3", + "jest-resolve": "^29.1.2", + "jest-runner": "^29.1.2", + "jest-util": "^29.1.2", + "jest-validate": "^29.1.2", "micromatch": "^4.0.4", "parse-json": "^5.2.0", - "pretty-format": "^29.0.3", + "pretty-format": "^29.1.2", "slash": "^3.0.0", "strip-json-comments": "^3.1.1" }, @@ -7146,15 +7114,15 @@ } }, "node_modules/jest-diff": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.0.3.tgz", - "integrity": "sha512-+X/AIF5G/vX9fWK+Db9bi9BQas7M9oBME7egU7psbn4jlszLFCu0dW63UgeE6cs/GANq4fLaT+8sGHQQ0eCUfg==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.1.2.tgz", + "integrity": "sha512-4GQts0aUopVvecIT4IwD/7xsBaMhKTYoM4/njE/aVw9wpw+pIUVp8Vab/KnSzSilr84GnLBkaP3JLDnQYCKqVQ==", "dev": true, "dependencies": { "chalk": "^4.0.0", "diff-sequences": "^29.0.0", "jest-get-type": "^29.0.0", - "pretty-format": "^29.0.3" + "pretty-format": "^29.1.2" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -7173,34 +7141,34 @@ } }, "node_modules/jest-each": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.0.3.tgz", - "integrity": "sha512-wILhZfESURHHBNvPMJ0lZlYZrvOQJxAo3wNHi+ycr90V7M+uGR9Gh4+4a/BmaZF0XTyZsk4OiYEf3GJN7Ltqzg==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.1.2.tgz", + "integrity": "sha512-AmTQp9b2etNeEwMyr4jc0Ql/LIX/dhbgP21gHAizya2X6rUspHn2gysMXaj6iwWuOJ2sYRgP8c1P4cXswgvS1A==", "dev": true, "dependencies": { - "@jest/types": "^29.0.3", + "@jest/types": "^29.1.2", "chalk": "^4.0.0", "jest-get-type": "^29.0.0", - "jest-util": "^29.0.3", - "pretty-format": "^29.0.3" + "jest-util": "^29.1.2", + "pretty-format": "^29.1.2" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-environment-jsdom": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-29.0.3.tgz", - "integrity": "sha512-KIGvpm12c71hoYTjL4wC2c8K6KfhOHJqJtaHc1IApu5rG047YWZoEP13BlbucWfzGISBrmli8KFqdhdQEa8Wnw==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-29.1.2.tgz", + "integrity": "sha512-D+XNIKia5+uDjSMwL/G1l6N9MCb7LymKI8FpcLo7kkISjc/Sa9w+dXXEa7u1Wijo3f8sVLqfxdGqYtRhmca+Xw==", "dev": true, "dependencies": { - "@jest/environment": "^29.0.3", - "@jest/fake-timers": "^29.0.3", - "@jest/types": "^29.0.3", + "@jest/environment": "^29.1.2", + "@jest/fake-timers": "^29.1.2", + "@jest/types": "^29.1.2", "@types/jsdom": "^20.0.0", "@types/node": "*", - "jest-mock": "^29.0.3", - "jest-util": "^29.0.3", + "jest-mock": "^29.1.2", + "jest-util": "^29.1.2", "jsdom": "^20.0.0" }, "engines": { @@ -7208,17 +7176,17 @@ } }, "node_modules/jest-environment-node": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.0.3.tgz", - "integrity": "sha512-cdZqRCnmIlTXC+9vtvmfiY/40Cj6s2T0czXuq1whvQdmpzAnj4sbqVYuZ4zFHk766xTTJ+Ij3uUqkk8KCfXoyg==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.1.2.tgz", + "integrity": "sha512-C59yVbdpY8682u6k/lh8SUMDJPbOyCHOTgLVVi1USWFxtNV+J8fyIwzkg+RJIVI30EKhKiAGNxYaFr3z6eyNhQ==", "dev": true, "dependencies": { - "@jest/environment": "^29.0.3", - "@jest/fake-timers": "^29.0.3", - "@jest/types": "^29.0.3", + "@jest/environment": "^29.1.2", + "@jest/fake-timers": "^29.1.2", + "@jest/types": "^29.1.2", "@types/node": "*", - "jest-mock": "^29.0.3", - "jest-util": "^29.0.3" + "jest-mock": "^29.1.2", + "jest-util": "^29.1.2" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -7250,20 +7218,20 @@ } }, "node_modules/jest-haste-map": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.0.3.tgz", - "integrity": "sha512-uMqR99+GuBHo0RjRhOE4iA6LmsxEwRdgiIAQgMU/wdT2XebsLDz5obIwLZm/Psj+GwSEQhw9AfAVKGYbh2G55A==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.1.2.tgz", + "integrity": "sha512-xSjbY8/BF11Jh3hGSPfYTa/qBFrm3TPM7WU8pU93m2gqzORVLkHFWvuZmFsTEBPRKndfewXhMOuzJNHyJIZGsw==", "dev": true, "dependencies": { - "@jest/types": "^29.0.3", + "@jest/types": "^29.1.2", "@types/graceful-fs": "^4.1.3", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "graceful-fs": "^4.2.9", "jest-regex-util": "^29.0.0", - "jest-util": "^29.0.3", - "jest-worker": "^29.0.3", + "jest-util": "^29.1.2", + "jest-worker": "^29.1.2", "micromatch": "^4.0.4", "walker": "^1.0.8" }, @@ -7275,46 +7243,46 @@ } }, "node_modules/jest-leak-detector": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.0.3.tgz", - "integrity": "sha512-YfW/G63dAuiuQ3QmQlh8hnqLDe25WFY3eQhuc/Ev1AGmkw5zREblTh7TCSKLoheyggu6G9gxO2hY8p9o6xbaRQ==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.1.2.tgz", + "integrity": "sha512-TG5gAZJpgmZtjb6oWxBLf2N6CfQ73iwCe6cofu/Uqv9iiAm6g502CAnGtxQaTfpHECBdVEMRBhomSXeLnoKjiQ==", "dev": true, "dependencies": { "jest-get-type": "^29.0.0", - "pretty-format": "^29.0.3" + "pretty-format": "^29.1.2" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-matcher-utils": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.0.3.tgz", - "integrity": "sha512-RsR1+cZ6p1hDV4GSCQTg+9qjeotQCgkaleIKLK7dm+U4V/H2bWedU3RAtLm8+mANzZ7eDV33dMar4pejd7047w==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.1.2.tgz", + "integrity": "sha512-MV5XrD3qYSW2zZSHRRceFzqJ39B2z11Qv0KPyZYxnzDHFeYZGJlgGi0SW+IXSJfOewgJp/Km/7lpcFT+cgZypw==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "jest-diff": "^29.0.3", + "jest-diff": "^29.1.2", "jest-get-type": "^29.0.0", - "pretty-format": "^29.0.3" + "pretty-format": "^29.1.2" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-message-util": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.0.3.tgz", - "integrity": "sha512-7T8JiUTtDfppojosORAflABfLsLKMLkBHSWkjNQrjIltGoDzNGn7wEPOSfjqYAGTYME65esQzMJxGDjuLBKdOg==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.1.2.tgz", + "integrity": "sha512-9oJ2Os+Qh6IlxLpmvshVbGUiSkZVc2FK+uGOm6tghafnB2RyjKAxMZhtxThRMxfX1J1SOMhTn9oK3/MutRWQJQ==", "dev": true, "dependencies": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.0.3", + "@jest/types": "^29.1.2", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^29.0.3", + "pretty-format": "^29.1.2", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -7323,13 +7291,14 @@ } }, "node_modules/jest-mock": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.0.3.tgz", - "integrity": "sha512-ort9pYowltbcrCVR43wdlqfAiFJXBx8l4uJDsD8U72LgBcetvEp+Qxj1W9ZYgMRoeAo+ov5cnAGF2B6+Oth+ww==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.1.2.tgz", + "integrity": "sha512-PFDAdjjWbjPUtQPkQufvniXIS3N9Tv7tbibePEjIIprzjgo0qQlyUiVMrT4vL8FaSJo1QXifQUOuPH3HQC/aMA==", "dev": true, "dependencies": { - "@jest/types": "^29.0.3", - "@types/node": "*" + "@jest/types": "^29.1.2", + "@types/node": "*", + "jest-util": "^29.1.2" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -7362,17 +7331,17 @@ } }, "node_modules/jest-resolve": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.0.3.tgz", - "integrity": "sha512-toVkia85Y/BPAjJasTC9zIPY6MmVXQPtrCk8SmiheC4MwVFE/CMFlOtMN6jrwPMC6TtNh8+sTMllasFeu1wMPg==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.1.2.tgz", + "integrity": "sha512-7fcOr+k7UYSVRJYhSmJHIid3AnDBcLQX3VmT9OSbPWsWz1MfT7bcoerMhADKGvKCoMpOHUQaDHtQoNp/P9JMGg==", "dev": true, "dependencies": { "chalk": "^4.0.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.0.3", + "jest-haste-map": "^29.1.2", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.0.3", - "jest-validate": "^29.0.3", + "jest-util": "^29.1.2", + "jest-validate": "^29.1.2", "resolve": "^1.20.0", "resolve.exports": "^1.1.0", "slash": "^3.0.0" @@ -7382,43 +7351,43 @@ } }, "node_modules/jest-resolve-dependencies": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.0.3.tgz", - "integrity": "sha512-KzuBnXqNvbuCdoJpv8EanbIGObk7vUBNt/PwQPPx2aMhlv/jaXpUJsqWYRpP/0a50faMBY7WFFP8S3/CCzwfDw==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.1.2.tgz", + "integrity": "sha512-44yYi+yHqNmH3OoWZvPgmeeiwKxhKV/0CfrzaKLSkZG9gT973PX8i+m8j6pDrTYhhHoiKfF3YUFg/6AeuHw4HQ==", "dev": true, "dependencies": { "jest-regex-util": "^29.0.0", - "jest-snapshot": "^29.0.3" + "jest-snapshot": "^29.1.2" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-runner": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.0.3.tgz", - "integrity": "sha512-Usu6VlTOZlCZoNuh3b2Tv/yzDpKqtiNAetG9t3kJuHfUyVMNW7ipCCJOUojzKkjPoaN7Bl1f7Buu6PE0sGpQxw==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.1.2.tgz", + "integrity": "sha512-yy3LEWw8KuBCmg7sCGDIqKwJlULBuNIQa2eFSVgVASWdXbMYZ9H/X0tnXt70XFoGf92W2sOQDOIFAA6f2BG04Q==", "dev": true, "dependencies": { - "@jest/console": "^29.0.3", - "@jest/environment": "^29.0.3", - "@jest/test-result": "^29.0.3", - "@jest/transform": "^29.0.3", - "@jest/types": "^29.0.3", + "@jest/console": "^29.1.2", + "@jest/environment": "^29.1.2", + "@jest/test-result": "^29.1.2", + "@jest/transform": "^29.1.2", + "@jest/types": "^29.1.2", "@types/node": "*", "chalk": "^4.0.0", "emittery": "^0.10.2", "graceful-fs": "^4.2.9", "jest-docblock": "^29.0.0", - "jest-environment-node": "^29.0.3", - "jest-haste-map": "^29.0.3", - "jest-leak-detector": "^29.0.3", - "jest-message-util": "^29.0.3", - "jest-resolve": "^29.0.3", - "jest-runtime": "^29.0.3", - "jest-util": "^29.0.3", - "jest-watcher": "^29.0.3", - "jest-worker": "^29.0.3", + "jest-environment-node": "^29.1.2", + "jest-haste-map": "^29.1.2", + "jest-leak-detector": "^29.1.2", + "jest-message-util": "^29.1.2", + "jest-resolve": "^29.1.2", + "jest-runtime": "^29.1.2", + "jest-util": "^29.1.2", + "jest-watcher": "^29.1.2", + "jest-worker": "^29.1.2", "p-limit": "^3.1.0", "source-map-support": "0.5.13" }, @@ -7427,31 +7396,31 @@ } }, "node_modules/jest-runtime": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.0.3.tgz", - "integrity": "sha512-12gZXRQ7ozEeEHKTY45a+YLqzNDR/x4c//X6AqwKwKJPpWM8FY4vwn4VQJOcLRS3Nd1fWwgP7LU4SoynhuUMHQ==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.1.2.tgz", + "integrity": "sha512-jr8VJLIf+cYc+8hbrpt412n5jX3tiXmpPSYTGnwcvNemY+EOuLNiYnHJ3Kp25rkaAcTWOEI4ZdOIQcwYcXIAZw==", "dev": true, "dependencies": { - "@jest/environment": "^29.0.3", - "@jest/fake-timers": "^29.0.3", - "@jest/globals": "^29.0.3", + "@jest/environment": "^29.1.2", + "@jest/fake-timers": "^29.1.2", + "@jest/globals": "^29.1.2", "@jest/source-map": "^29.0.0", - "@jest/test-result": "^29.0.3", - "@jest/transform": "^29.0.3", - "@jest/types": "^29.0.3", + "@jest/test-result": "^29.1.2", + "@jest/transform": "^29.1.2", + "@jest/types": "^29.1.2", "@types/node": "*", "chalk": "^4.0.0", "cjs-module-lexer": "^1.0.0", "collect-v8-coverage": "^1.0.0", "glob": "^7.1.3", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.0.3", - "jest-message-util": "^29.0.3", - "jest-mock": "^29.0.3", + "jest-haste-map": "^29.1.2", + "jest-message-util": "^29.1.2", + "jest-mock": "^29.1.2", "jest-regex-util": "^29.0.0", - "jest-resolve": "^29.0.3", - "jest-snapshot": "^29.0.3", - "jest-util": "^29.0.3", + "jest-resolve": "^29.1.2", + "jest-snapshot": "^29.1.2", + "jest-util": "^29.1.2", "slash": "^3.0.0", "strip-bom": "^4.0.0" }, @@ -7460,9 +7429,9 @@ } }, "node_modules/jest-snapshot": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.0.3.tgz", - "integrity": "sha512-52q6JChm04U3deq+mkQ7R/7uy7YyfVIrebMi6ZkBoDJ85yEjm/sJwdr1P0LOIEHmpyLlXrxy3QP0Zf5J2kj0ew==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.1.2.tgz", + "integrity": "sha512-rYFomGpVMdBlfwTYxkUp3sjD6usptvZcONFYNqVlaz4EpHPnDvlWjvmOQ9OCSNKqYZqLM2aS3wq01tWujLg7gg==", "dev": true, "dependencies": { "@babel/core": "^7.11.6", @@ -7471,23 +7440,23 @@ "@babel/plugin-syntax-typescript": "^7.7.2", "@babel/traverse": "^7.7.2", "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.0.3", - "@jest/transform": "^29.0.3", - "@jest/types": "^29.0.3", + "@jest/expect-utils": "^29.1.2", + "@jest/transform": "^29.1.2", + "@jest/types": "^29.1.2", "@types/babel__traverse": "^7.0.6", "@types/prettier": "^2.1.5", "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^29.0.3", + "expect": "^29.1.2", "graceful-fs": "^4.2.9", - "jest-diff": "^29.0.3", + "jest-diff": "^29.1.2", "jest-get-type": "^29.0.0", - "jest-haste-map": "^29.0.3", - "jest-matcher-utils": "^29.0.3", - "jest-message-util": "^29.0.3", - "jest-util": "^29.0.3", + "jest-haste-map": "^29.1.2", + "jest-matcher-utils": "^29.1.2", + "jest-message-util": "^29.1.2", + "jest-util": "^29.1.2", "natural-compare": "^1.4.0", - "pretty-format": "^29.0.3", + "pretty-format": "^29.1.2", "semver": "^7.3.5" }, "engines": { @@ -7495,12 +7464,12 @@ } }, "node_modules/jest-util": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.0.3.tgz", - "integrity": "sha512-Q0xaG3YRG8QiTC4R6fHjHQPaPpz9pJBEi0AeOE4mQh/FuWOijFjGXMMOfQEaU9i3z76cNR7FobZZUQnL6IyfdQ==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.1.2.tgz", + "integrity": "sha512-vPCk9F353i0Ymx3WQq3+a4lZ07NXu9Ca8wya6o4Fe4/aO1e1awMMprZ3woPFpKwghEOW+UXgd15vVotuNN9ONQ==", "dev": true, "dependencies": { - "@jest/types": "^29.0.3", + "@jest/types": "^29.1.2", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -7512,17 +7481,17 @@ } }, "node_modules/jest-validate": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.0.3.tgz", - "integrity": "sha512-OebiqqT6lK8cbMPtrSoS3aZP4juID762lZvpf1u+smZnwTEBCBInan0GAIIhv36MxGaJvmq5uJm7dl5gVt+Zrw==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.1.2.tgz", + "integrity": "sha512-k71pOslNlV8fVyI+mEySy2pq9KdXdgZtm7NHrBX8LghJayc3wWZH0Yr0mtYNGaCU4F1OLPXRkwZR0dBm/ClshA==", "dev": true, "dependencies": { - "@jest/types": "^29.0.3", + "@jest/types": "^29.1.2", "camelcase": "^6.2.0", "chalk": "^4.0.0", "jest-get-type": "^29.0.0", "leven": "^3.1.0", - "pretty-format": "^29.0.3" + "pretty-format": "^29.1.2" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -7541,18 +7510,18 @@ } }, "node_modules/jest-watcher": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.0.3.tgz", - "integrity": "sha512-tQX9lU91A+9tyUQKUMp0Ns8xAcdhC9fo73eqA3LFxP2bSgiF49TNcc+vf3qgGYYK9qRjFpXW9+4RgF/mbxyOOw==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.1.2.tgz", + "integrity": "sha512-6JUIUKVdAvcxC6bM8/dMgqY2N4lbT+jZVsxh0hCJRbwkIEnbr/aPjMQ28fNDI5lB51Klh00MWZZeVf27KBUj5w==", "dev": true, "dependencies": { - "@jest/test-result": "^29.0.3", - "@jest/types": "^29.0.3", + "@jest/test-result": "^29.1.2", + "@jest/types": "^29.1.2", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "emittery": "^0.10.2", - "jest-util": "^29.0.3", + "jest-util": "^29.1.2", "string-length": "^4.0.1" }, "engines": { @@ -7560,12 +7529,13 @@ } }, "node_modules/jest-worker": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.0.3.tgz", - "integrity": "sha512-Tl/YWUugQOjoTYwjKdfJWkSOfhufJHO5LhXTSZC3TRoQKO+fuXnZAdoXXBlpLXKGODBL3OvdUasfDD4PcMe6ng==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.1.2.tgz", + "integrity": "sha512-AdTZJxKjTSPHbXT/AIOjQVmoFx0LHFcVabWu0sxI7PAy7rFf8c0upyvgBKgguVXdM4vY74JdwkyD4hSmpTW8jA==", "dev": true, "dependencies": { "@types/node": "*", + "jest-util": "^29.1.2", "merge-stream": "^2.0.0", "supports-color": "^8.0.0" }, @@ -7612,6 +7582,12 @@ "node": ">=0.8.0" } }, + "node_modules/js-sdsl": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.5.tgz", + "integrity": "sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q==", + "dev": true + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -7631,18 +7607,18 @@ } }, "node_modules/jsdom": { - "version": "20.0.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.0.tgz", - "integrity": "sha512-x4a6CKCgx00uCmP+QakBDFXwjAJ69IkkIWHmtmjd3wvXPcdOS44hfX2vqkOQrVrq8l9DhNNADZRXaCEWvgXtVA==", + "version": "20.0.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.1.tgz", + "integrity": "sha512-pksjj7Rqoa+wdpkKcLzQRHhJCEE42qQhl/xLMUKHgoSejaKOdaXEAnqs6uDNwMl/fciHTzKeR8Wm8cw7N+g98A==", "dev": true, "dependencies": { "abab": "^2.0.6", - "acorn": "^8.7.1", - "acorn-globals": "^6.0.0", + "acorn": "^8.8.0", + "acorn-globals": "^7.0.0", "cssom": "^0.5.0", "cssstyle": "^2.3.0", "data-urls": "^3.0.2", - "decimal.js": "^10.3.1", + "decimal.js": "^10.4.1", "domexception": "^4.0.0", "escodegen": "^2.0.0", "form-data": "^4.0.0", @@ -7650,18 +7626,17 @@ "http-proxy-agent": "^5.0.0", "https-proxy-agent": "^5.0.1", "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.0", - "parse5": "^7.0.0", + "nwsapi": "^2.2.2", + "parse5": "^7.1.1", "saxes": "^6.0.0", "symbol-tree": "^3.2.4", - "tough-cookie": "^4.0.0", - "w3c-hr-time": "^1.0.2", + "tough-cookie": "^4.1.2", "w3c-xmlserializer": "^3.0.0", "webidl-conversions": "^7.0.0", "whatwg-encoding": "^2.0.0", "whatwg-mimetype": "^3.0.0", "whatwg-url": "^11.0.0", - "ws": "^8.8.0", + "ws": "^8.9.0", "xml-name-validator": "^4.0.0" }, "engines": { @@ -7677,9 +7652,9 @@ } }, "node_modules/jsep": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/jsep/-/jsep-1.3.6.tgz", - "integrity": "sha512-o7fP1eZVROIChADx7HKiwGRVI0tUqgUUGhaok6DP7cMxpDeparuooREDBDeNk2G5KIB49MBSkRYsCOu4PmZ+1w==", + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/jsep/-/jsep-1.3.7.tgz", + "integrity": "sha512-NFbZTr1t13fPKw53swmZFKwBkEDWDnno7uLJk+a+Rw9tGDTkGgnGdZJ8A/o3gR1+XaAXmSsbpfIBIBgqRBZWDA==", "dev": true, "engines": { "node": ">= 10.16.0" @@ -7777,14 +7752,6 @@ "katex": "cli.js" } }, - "node_modules/katex/node_modules/commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", - "engines": { - "node": ">= 12" - } - }, "node_modules/khroma": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/khroma/-/khroma-2.0.0.tgz", @@ -7847,9 +7814,9 @@ } }, "node_modules/less-loader": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-11.0.0.tgz", - "integrity": "sha512-9+LOWWjuoectIEx3zrfN83NAGxSUB5pWEabbbidVQVgZhN+wN68pOvuyirVlH1IK4VT1f3TmlyvAnCXh8O5KEw==", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-11.1.0.tgz", + "integrity": "sha512-C+uDBV7kS7W5fJlUjq5mPBeBVhYpTIm5gB09APT9o3n/ILeaXVsiSFTbZpTJCJwQ/Crczfn3DmfQFwxYusWFug==", "dependencies": { "klona": "^2.0.4" }, @@ -8189,6 +8156,15 @@ "balanced-match": "^1.0.0" } }, + "node_modules/markdownlint-cli/node_modules/commander": { + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.4.1.tgz", + "integrity": "sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==", + "dev": true, + "engines": { + "node": "^12.20.0 || >=14" + } + }, "node_modules/markdownlint-cli/node_modules/glob": { "version": "8.0.3", "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", @@ -8236,9 +8212,9 @@ } }, "node_modules/marked": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/marked/-/marked-4.1.0.tgz", - "integrity": "sha512-+Z6KDjSPa6/723PQYyc1axYZpYYpDnECDaU6hkaf5gqBieBkMKYReL5hteF2QizhlMbgbo8umXl/clZ67+GlsA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.1.1.tgz", + "integrity": "sha512-0cNMnTcUJPxbA6uWmCmjWz4NJRe/0Xfk2NhXCUHjew9qJzFN20krFnsUe7QynwqOwa5m1fZ4UDg0ycKFVC0ccw==", "bin": { "marked": "bin/marked.js" }, @@ -8365,15 +8341,15 @@ } }, "node_modules/mermaid": { - "version": "9.1.6", - "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-9.1.6.tgz", - "integrity": "sha512-oBuQk7s55wQgEgH/AK0GYY8U0kBqOIGK9QlJL+VYxh+1kZQtU9tNwoy0gWCfBJDaFIRdfpc/fm9PagaIXg6XFQ==", + "version": "9.1.7", + "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-9.1.7.tgz", + "integrity": "sha512-MRVHXy5FLjnUQUG7YS3UN9jEN6FXCJbFCXVGJQjVIbiR6Vhw0j/6pLIjqsiah9xoHmQU6DEaKOvB3S1g/1nBPA==", "dependencies": { "@braintree/sanitize-url": "^6.0.0", "d3": "^7.0.0", "dagre": "^0.8.5", "dagre-d3": "^0.6.4", - "dompurify": "2.3.10", + "dompurify": "2.4.0", "graphlib": "^2.1.8", "khroma": "^2.0.0", "moment-mini": "2.24.0", @@ -9118,9 +9094,9 @@ } }, "node_modules/playwright-core": { - "version": "1.25.2", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.25.2.tgz", - "integrity": "sha512-0yTbUE9lIddkEpLHL3u8PoCL+pWiZtj5A/j3U7YoNjcmKKDGBnCrgHJMzwd2J5vy6l28q4ki3JIuz7McLHhl1A==", + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.27.0.tgz", + "integrity": "sha512-VBKaaFUVKDo3akW+o4DwbK1ZyXh46tcSwQKPK3lruh8IJd5feu55XVZx4vOkbb2uqrNdIF51sgsadYT533SdpA==", "dev": true, "bin": { "playwright": "cli.js" @@ -9148,9 +9124,9 @@ } }, "node_modules/postcss": { - "version": "8.4.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.16.tgz", - "integrity": "sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ==", + "version": "8.4.17", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.17.tgz", + "integrity": "sha512-UNxNOLQydcOFi41yHNMcKRZ39NeXlr8AxGuZJsdub8vIb12fHzcq37DTU/QtbI6WLxNg2gF9Z+8qtRwTj1UI1Q==", "funding": [ { "type": "opencollective", @@ -9292,9 +9268,9 @@ } }, "node_modules/pretty-format": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.0.3.tgz", - "integrity": "sha512-cHudsvQr1K5vNVLbvYF/nv3Qy/F/BcEKxGuIeMiVMRHxPOO1RxXooP8g/ZrwAp7Dx+KdMZoOc7NxLHhMrP2f9Q==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.1.2.tgz", + "integrity": "sha512-CGJ6VVGXVRP2o2Dorl4mAwwvDWT25luIsYhkyVQW32E4nL+TgW939J7LlKT/npq5Cpq6j3s+sy+13yk7xYpBmg==", "dev": true, "dependencies": { "@jest/schemas": "^29.0.0", @@ -9784,9 +9760,9 @@ "integrity": "sha512-ndEIpszUHiG4HtDsQLeIuMvRsDnn8c8rYStabochtUeCvfuvNptb5TUbVD68LRAILPX7p9nqQGh4xJgn3EHS/g==" }, "node_modules/rollup": { - "version": "2.79.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.0.tgz", - "integrity": "sha512-x4KsrCgwQ7ZJPcFA/SUu6QVcYlO7uRLfLAy0DSA4NS2eG8japdbpM50ToH7z4iObodRYOJ0soneF0iaQRJ6zhA==", + "version": "2.79.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", + "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", "dev": true, "bin": { "rollup": "dist/bin/rollup" @@ -9854,6 +9830,20 @@ "regexp-tree": "~0.1.1" } }, + "node_modules/safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/safe-stable-stringify": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-1.1.1.tgz", @@ -9902,9 +9892,9 @@ } }, "node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dependencies": { "lru-cache": "^6.0.0" }, @@ -10050,9 +10040,9 @@ } }, "node_modules/socks": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.0.tgz", - "integrity": "sha512-scnOe9y4VuiNUULJN72GrM26BNOjVsfPXI+j+98PkyEfsIXroa5ofyjT+FzGvn/xHs73U2JtoBYAVx9Hl4quSA==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", + "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", "dev": true, "dependencies": { "ip": "^2.0.0", @@ -10359,9 +10349,9 @@ "dev": true }, "node_modules/stylelint": { - "version": "14.11.0", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-14.11.0.tgz", - "integrity": "sha512-OTLjLPxpvGtojEfpESWM8Ir64Z01E89xsisaBMUP/ngOx1+4VG2DPRcUyCCiin9Rd3kPXPsh/uwHd9eqnvhsYA==", + "version": "14.13.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-14.13.0.tgz", + "integrity": "sha512-NJSAdloiAB/jgVJKxMR90mWlctvmeBFGFVUvyKngi9+j/qPSJ5ZB+u8jOmGbLTnS7OHrII9NFGehPRyar8U5vg==", "dev": true, "dependencies": { "@csstools/selector-specificity": "^2.0.2", @@ -10370,7 +10360,7 @@ "cosmiconfig": "^7.0.1", "css-functions-list": "^3.1.0", "debug": "^4.3.4", - "fast-glob": "^3.2.11", + "fast-glob": "^3.2.12", "fastest-levenshtein": "^1.0.16", "file-entry-cache": "^6.0.1", "global-modules": "^2.0.0", @@ -10397,7 +10387,7 @@ "string-width": "^4.2.3", "strip-ansi": "^6.0.1", "style-search": "^0.1.0", - "supports-hyperlinks": "^2.2.0", + "supports-hyperlinks": "^2.3.0", "svg-tags": "^1.0.0", "table": "^6.8.0", "v8-compile-cache": "^2.3.0", @@ -10532,9 +10522,9 @@ } }, "node_modules/swagger-ui-dist": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-4.14.0.tgz", - "integrity": "sha512-TBzhheU15s+o54Cgk9qxuYcZMiqSm/SkvKnapoGHOF66kz0Y5aGjpzj5BT/vpBbn6rTPJ9tUYXQxuDWfsjiGMw==" + "version": "4.14.2", + "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-4.14.2.tgz", + "integrity": "sha512-kOIU7Ts3TrXDLb3/c9jRe4qGp8O3bRT19FFJA8wJfrRFkcK/4atPn3krhtBVJ57ZkNNofworXHxuYwmaisXBdg==" }, "node_modules/symbol-tree": { "version": "3.2.4", @@ -10583,9 +10573,9 @@ } }, "node_modules/terser": { - "version": "5.15.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.15.0.tgz", - "integrity": "sha512-L1BJiXVmheAQQy+as0oF3Pwtlo4s3Wi1X2zNZ2NxOB4wx9bdS9Vk67XQENLFdLYGCK/Z2di53mTj/hBafR+dTA==", + "version": "5.15.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.15.1.tgz", + "integrity": "sha512-K1faMUvpm/FBxjBXud0LWVAGxmvoPbZbfTCYbSgaaYQaIXI3/TdI7a7ZGA73Zrou6Q8Zmz3oeUTsp/dj+ag2Xw==", "dependencies": { "@jridgewell/source-map": "^0.3.2", "acorn": "^8.5.0", @@ -10952,9 +10942,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.7.tgz", - "integrity": "sha512-iN/XYesmZ2RmmWAiI4Z5rq0YqSiv0brj9Ce9CfhNE4xIW2h+MFxcgkxIzZ+ShkFPUkjU3gQ+3oypadD3RAMtrg==", + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", "funding": [ { "type": "opencollective", @@ -10977,9 +10967,9 @@ } }, "node_modules/updates": { - "version": "13.1.5", - "resolved": "https://registry.npmjs.org/updates/-/updates-13.1.5.tgz", - "integrity": "sha512-7WPn2P8WskugozCdhMI+D1m9OmJnzZqRUuDYM2G8O55TuyvfqOT2vdR2+InkpXUyK6ZNmbLopvw++h9YQElbmg==", + "version": "13.1.8", + "resolved": "https://registry.npmjs.org/updates/-/updates-13.1.8.tgz", + "integrity": "sha512-hcDCkif1i4MWArx1QkJjLHyPCr8taYyzoypQ7ST/vbmNJyH/cpiawQf+5frvH5uekiSSwtuQNWKdFWB3UH4sew==", "dev": true, "bin": { "updates": "bin/updates.js" @@ -11081,25 +11071,16 @@ "node": ">=6.0" } }, - "node_modules/vm2/node_modules/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/vue": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.37.tgz", - "integrity": "sha512-bOKEZxrm8Eh+fveCqS1/NkG/n6aMidsI6hahas7pa0w/l7jkbssJVsRhVDs07IdDq7h9KHswZOgItnwJAgtVtQ==", + "version": "3.2.40", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.40.tgz", + "integrity": "sha512-1mGHulzUbl2Nk3pfvI5aXYYyJUs1nm4kyvuz38u4xlQkLUn1i2R7nDbI4TufECmY8v1qNBHYy62bCaM+3cHP2A==", "dependencies": { - "@vue/compiler-dom": "3.2.37", - "@vue/compiler-sfc": "3.2.37", - "@vue/runtime-dom": "3.2.37", - "@vue/server-renderer": "3.2.37", - "@vue/shared": "3.2.37" + "@vue/compiler-dom": "3.2.40", + "@vue/compiler-sfc": "3.2.40", + "@vue/runtime-dom": "3.2.40", + "@vue/server-renderer": "3.2.40", + "@vue/shared": "3.2.40" } }, "node_modules/vue-bar-graph": { @@ -11162,15 +11143,6 @@ "vue": "^3.2.24" } }, - "node_modules/w3c-hr-time": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", - "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", - "dev": true, - "dependencies": { - "browser-process-hrtime": "^1.0.0" - } - }, "node_modules/w3c-xmlserializer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-3.0.0.tgz", @@ -11484,12 +11456,6 @@ "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==" }, - "node_modules/wolfy87-eventemitter": { - "version": "5.2.9", - "resolved": "https://registry.npmjs.org/wolfy87-eventemitter/-/wolfy87-eventemitter-5.2.9.tgz", - "integrity": "sha512-P+6vtWyuDw+MB01X7UeF8TaHBvbCovf4HPEMF/SV7BdDc1SMTiBy13SRD71lQh4ExFTG1d/WNzDGDCyOKSMblw==", - "dev": true - }, "node_modules/word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -11676,9 +11642,9 @@ } }, "node_modules/ws": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.8.1.tgz", - "integrity": "sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA==", + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.9.0.tgz", + "integrity": "sha512-Ja7nszREasGaYUYCI2k4lCKIRTt+y7XuqVoHR44YpI49TtryyqbqvDMn5eqfW7e6HzTukDRIsXqzVHScqRcafg==", "dev": true, "engines": { "node": ">=10.0.0" @@ -11805,9 +11771,9 @@ } }, "@asyncapi/specs": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/@asyncapi/specs/-/specs-2.14.0.tgz", - "integrity": "sha512-hHsYF6XsYNIKb1P2rXaooF4H+uKKQ4b/Ljxrk3rZ3riEDiSxMshMEfb1fUlw9Yj4V4OmJhjXwkNvw8W59AXv1A==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@asyncapi/specs/-/specs-3.2.1.tgz", + "integrity": "sha512-FO+EteK+Gk3zwumrBw6frpp9cJ4oQL5++hBBpfM81w16e9KaiA4sKrzvQsvVjifoZZHNvVEX4D2zoz9i8CLccQ==", "dev": true }, "@babel/code-frame": { @@ -11820,27 +11786,27 @@ } }, "@babel/compat-data": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.19.0.tgz", - "integrity": "sha512-y5rqgTTPTmaF5e2nVhOxw+Ur9HDJLsWb6U/KpgUzRZEdPfE6VOubXBKLdbcUTijzRptednSBDQbYZBOSqJxpJw==", + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.19.3.tgz", + "integrity": "sha512-prBHMK4JYYK+wDjJF1q99KK4JLL+egWS4nmNqdlMUgCExMZ+iZW0hGhyC3VEbsPjvaN0TBhW//VIFwBrk8sEiw==", "dev": true }, "@babel/core": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.0.tgz", - "integrity": "sha512-reM4+U7B9ss148rh2n1Qs9ASS+w94irYXga7c2jaQv9RVzpS7Mv1a9rnYYwuDa45G+DkORt9g6An2k/V4d9LbQ==", + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.3.tgz", + "integrity": "sha512-WneDJxdsjEvyKtXKsaBGbDeiyOjR5vYq4HcShxnIbG0qixpoHjI3MqeZM9NDvsojNCEBItQE4juOo/bU6e72gQ==", "dev": true, "requires": { "@ampproject/remapping": "^2.1.0", "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.19.0", - "@babel/helper-compilation-targets": "^7.19.0", + "@babel/generator": "^7.19.3", + "@babel/helper-compilation-targets": "^7.19.3", "@babel/helper-module-transforms": "^7.19.0", "@babel/helpers": "^7.19.0", - "@babel/parser": "^7.19.0", + "@babel/parser": "^7.19.3", "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.0", - "@babel/types": "^7.19.0", + "@babel/traverse": "^7.19.3", + "@babel/types": "^7.19.3", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -11857,12 +11823,12 @@ } }, "@babel/generator": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.19.0.tgz", - "integrity": "sha512-S1ahxf1gZ2dpoiFgA+ohK9DIpz50bJ0CWs7Zlzb54Z4sG8qmdIrGrVqmy1sAtTVRb+9CU6U8VqT9L0Zj7hxHVg==", + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.19.3.tgz", + "integrity": "sha512-fqVZnmp1ncvZU757UzDheKZpfPgatqY59XtW2/j/18H7u76akb8xqvjw82f+i2UKd/ksYsSick/BCLQUUtJ/qQ==", "dev": true, "requires": { - "@babel/types": "^7.19.0", + "@babel/types": "^7.19.3", "@jridgewell/gen-mapping": "^0.3.2", "jsesc": "^2.5.1" }, @@ -11881,14 +11847,14 @@ } }, "@babel/helper-compilation-targets": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.0.tgz", - "integrity": "sha512-Ai5bNWXIvwDvWM7njqsG3feMlL9hCVQsPYXodsZyLwshYkZVJt59Gftau4VrE8S9IT9asd2uSP1hG6wCNw+sXA==", + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.3.tgz", + "integrity": "sha512-65ESqLGyGmLvgR0mst5AdW1FkNlj9rQsCKduzEoEPhBCDFGXvz2jW6bXFG6i0/MrV2s7hhXjjb2yAzcPuQlLwg==", "dev": true, "requires": { - "@babel/compat-data": "^7.19.0", + "@babel/compat-data": "^7.19.3", "@babel/helper-validator-option": "^7.18.6", - "browserslist": "^4.20.2", + "browserslist": "^4.21.3", "semver": "^6.3.0" }, "dependencies": { @@ -11981,9 +11947,9 @@ "dev": true }, "@babel/helper-validator-identifier": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz", - "integrity": "sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==", + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", "dev": true }, "@babel/helper-validator-option": { @@ -12073,9 +12039,9 @@ } }, "@babel/parser": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.19.0.tgz", - "integrity": "sha512-74bEXKX2h+8rrfQUfsBfuZZHzsEs6Eql4pqy/T4Nn6Y9wNPggQOqD6z6pn5Bl8ZfysKouFZT/UXEH94ummEeQw==" + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.19.3.tgz", + "integrity": "sha512-pJ9xOlNWHiy9+FuFP09DEAFbAn4JskgRsVcc169w2xRBC3FRGuQEwjeIMMND9L2zc0iEhO/tGv4Zq+km+hxNpQ==" }, "@babel/plugin-syntax-async-generators": { "version": "7.8.4", @@ -12215,19 +12181,19 @@ } }, "@babel/traverse": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.19.0.tgz", - "integrity": "sha512-4pKpFRDh+utd2mbRC8JLnlsMUii3PMHjpL6a0SZ4NMZy7YFP9aXORxEhdMVOc9CpWtDF09IkciQLEhK7Ml7gRA==", + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.19.3.tgz", + "integrity": "sha512-qh5yf6149zhq2sgIXmwjnsvmnNQC2iw70UFjp4olxucKrWd/dvlUsBI88VSLUsnMNF7/vnOiA+nk1+yLoCqROQ==", "dev": true, "requires": { "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.19.0", + "@babel/generator": "^7.19.3", "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-function-name": "^7.19.0", "@babel/helper-hoist-variables": "^7.18.6", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.19.0", - "@babel/types": "^7.19.0", + "@babel/parser": "^7.19.3", + "@babel/types": "^7.19.3", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -12241,13 +12207,13 @@ } }, "@babel/types": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.0.tgz", - "integrity": "sha512-YuGopBq3ke25BVSiS6fgF49Ul9gH1x70Bcr6bqRLjWCkcX8Hre1/5+z+IiWOIerRMSSEfGZVB9z9kyq7wVs9YA==", + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.3.tgz", + "integrity": "sha512-hGCaQzIY22DJlDh9CH7NOxgKkFjBk0Cw9xDO1Xmh2151ti7wiGfQ3LauXzL4HP1fmFlTX6XjpRETTpUcv7wQLw==", "dev": true, "requires": { "@babel/helper-string-parser": "^7.18.10", - "@babel/helper-validator-identifier": "^7.18.6", + "@babel/helper-validator-identifier": "^7.19.1", "to-fast-properties": "^2.0.0" } }, @@ -12280,16 +12246,22 @@ "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==" }, + "@esbuild/android-arm": { + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.15.10.tgz", + "integrity": "sha512-FNONeQPy/ox+5NBkcSbYJxoXj9GWu8gVGJTVmUyoOCKQFDTrHVKgNSzChdNt0I8Aj/iKcsDf2r9BFwv+FSNUXg==", + "optional": true + }, "@esbuild/linux-loong64": { - "version": "0.15.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.7.tgz", - "integrity": "sha512-IKznSJOsVUuyt7cDzzSZyqBEcZe+7WlBqTVXiF1OXP/4Nm387ToaXZ0fyLwI1iBlI/bzpxVq411QE2/Bt2XWWw==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.10.tgz", + "integrity": "sha512-w0Ou3Z83LOYEkwaui2M8VwIp+nLi/NA60lBLMvaJ+vXVMcsARYdEzLNE7RSm4+lSg4zq4d7fAVuzk7PNQ5JFgg==", "optional": true }, "@eslint/eslintrc": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.1.tgz", - "integrity": "sha512-OhSY22oQQdw3zgPOOwdoj01l/Dzl1Z+xyUP33tkSN+aqyEhymJCcPHyXt+ylW8FSe0TfRC2VG+ROQOapD0aZSQ==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", + "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", "dev": true, "requires": { "ajv": "^6.12.4", @@ -12324,9 +12296,9 @@ } }, "@humanwhocodes/config-array": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.4.tgz", - "integrity": "sha512-mXAIHxZT3Vcpg83opl1wGlVZ9xydbfZO3r5YfRSH6Gpp2J/PfdBP0wbDa2sO6/qRbcalpoevVyW6A/fI6LfeMw==", + "version": "0.10.7", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.7.tgz", + "integrity": "sha512-MDl6D6sBsaV452/QSdX+4CXIjZhIcI0PELsxUjk4U828yd58vk3bTIvk/6w5FY+4hIy9sLW0sfrV7K7Kc++j/w==", "dev": true, "requires": { "@humanwhocodes/object-schema": "^1.2.1", @@ -12334,12 +12306,6 @@ "minimatch": "^3.0.4" } }, - "@humanwhocodes/gitignore-to-minimatch": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz", - "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==", - "dev": true - }, "@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", @@ -12436,30 +12402,30 @@ "dev": true }, "@jest/console": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.0.3.tgz", - "integrity": "sha512-cGg0r+klVHSYnfE977S9wmpuQ9L+iYuYgL+5bPXiUlUynLLYunRxswEmhBzvrSKGof5AKiHuTTmUKAqRcDY9dg==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.1.2.tgz", + "integrity": "sha512-ujEBCcYs82BTmRxqfHMQggSlkUZP63AE5YEaTPj7eFyJOzukkTorstOUC7L6nE3w5SYadGVAnTsQ/ZjTGL0qYQ==", "dev": true, "requires": { - "@jest/types": "^29.0.3", + "@jest/types": "^29.1.2", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^29.0.3", - "jest-util": "^29.0.3", + "jest-message-util": "^29.1.2", + "jest-util": "^29.1.2", "slash": "^3.0.0" } }, "@jest/core": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.0.3.tgz", - "integrity": "sha512-1d0hLbOrM1qQE3eP3DtakeMbKTcXiXP3afWxqz103xPyddS2NhnNghS7MaXx1dcDt4/6p4nlhmeILo2ofgi8cQ==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.1.2.tgz", + "integrity": "sha512-sCO2Va1gikvQU2ynDN8V4+6wB7iVrD2CvT0zaRst4rglf56yLly0NQ9nuRRAWFeimRf+tCdFsb1Vk1N9LrrMPA==", "dev": true, "requires": { - "@jest/console": "^29.0.3", - "@jest/reporters": "^29.0.3", - "@jest/test-result": "^29.0.3", - "@jest/transform": "^29.0.3", - "@jest/types": "^29.0.3", + "@jest/console": "^29.1.2", + "@jest/reporters": "^29.1.2", + "@jest/test-result": "^29.1.2", + "@jest/transform": "^29.1.2", + "@jest/types": "^29.1.2", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", @@ -12467,92 +12433,92 @@ "exit": "^0.1.2", "graceful-fs": "^4.2.9", "jest-changed-files": "^29.0.0", - "jest-config": "^29.0.3", - "jest-haste-map": "^29.0.3", - "jest-message-util": "^29.0.3", + "jest-config": "^29.1.2", + "jest-haste-map": "^29.1.2", + "jest-message-util": "^29.1.2", "jest-regex-util": "^29.0.0", - "jest-resolve": "^29.0.3", - "jest-resolve-dependencies": "^29.0.3", - "jest-runner": "^29.0.3", - "jest-runtime": "^29.0.3", - "jest-snapshot": "^29.0.3", - "jest-util": "^29.0.3", - "jest-validate": "^29.0.3", - "jest-watcher": "^29.0.3", + "jest-resolve": "^29.1.2", + "jest-resolve-dependencies": "^29.1.2", + "jest-runner": "^29.1.2", + "jest-runtime": "^29.1.2", + "jest-snapshot": "^29.1.2", + "jest-util": "^29.1.2", + "jest-validate": "^29.1.2", + "jest-watcher": "^29.1.2", "micromatch": "^4.0.4", - "pretty-format": "^29.0.3", + "pretty-format": "^29.1.2", "slash": "^3.0.0", "strip-ansi": "^6.0.0" } }, "@jest/environment": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.0.3.tgz", - "integrity": "sha512-iKl272NKxYNQNqXMQandAIwjhQaGw5uJfGXduu8dS9llHi8jV2ChWrtOAVPnMbaaoDhnI3wgUGNDvZgHeEJQCA==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.1.2.tgz", + "integrity": "sha512-rG7xZ2UeOfvOVzoLIJ0ZmvPl4tBEQ2n73CZJSlzUjPw4or1oSWC0s0Rk0ZX+pIBJ04aVr6hLWFn1DFtrnf8MhQ==", "dev": true, "requires": { - "@jest/fake-timers": "^29.0.3", - "@jest/types": "^29.0.3", + "@jest/fake-timers": "^29.1.2", + "@jest/types": "^29.1.2", "@types/node": "*", - "jest-mock": "^29.0.3" + "jest-mock": "^29.1.2" } }, "@jest/expect": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.0.3.tgz", - "integrity": "sha512-6W7K+fsI23FQ01H/BWccPyDZFrnU9QlzDcKOjrNVU5L8yUORFAJJIpmyxWPW70+X624KUNqzZwPThPMX28aXEQ==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.1.2.tgz", + "integrity": "sha512-FXw/UmaZsyfRyvZw3M6POgSNqwmuOXJuzdNiMWW9LCYo0GRoRDhg+R5iq5higmRTHQY7hx32+j7WHwinRmoILQ==", "dev": true, "requires": { - "expect": "^29.0.3", - "jest-snapshot": "^29.0.3" + "expect": "^29.1.2", + "jest-snapshot": "^29.1.2" } }, "@jest/expect-utils": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.0.3.tgz", - "integrity": "sha512-i1xUkau7K/63MpdwiRqaxgZOjxYs4f0WMTGJnYwUKubsNRZSeQbLorS7+I4uXVF9KQ5r61BUPAUMZ7Lf66l64Q==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.1.2.tgz", + "integrity": "sha512-4a48bhKfGj/KAH39u0ppzNTABXQ8QPccWAFUFobWBaEMSMp+sB31Z2fK/l47c4a/Mu1po2ffmfAIPxXbVTXdtg==", "dev": true, "requires": { "jest-get-type": "^29.0.0" } }, "@jest/fake-timers": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.0.3.tgz", - "integrity": "sha512-tmbUIo03x0TdtcZCESQ0oQSakPCpo7+s6+9mU19dd71MptkP4zCwoeZqna23//pgbhtT1Wq02VmA9Z9cNtvtCQ==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.1.2.tgz", + "integrity": "sha512-GppaEqS+QQYegedxVMpCe2xCXxxeYwQ7RsNx55zc8f+1q1qevkZGKequfTASI7ejmg9WwI+SJCrHe9X11bLL9Q==", "dev": true, "requires": { - "@jest/types": "^29.0.3", + "@jest/types": "^29.1.2", "@sinonjs/fake-timers": "^9.1.2", "@types/node": "*", - "jest-message-util": "^29.0.3", - "jest-mock": "^29.0.3", - "jest-util": "^29.0.3" + "jest-message-util": "^29.1.2", + "jest-mock": "^29.1.2", + "jest-util": "^29.1.2" } }, "@jest/globals": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.0.3.tgz", - "integrity": "sha512-YqGHT65rFY2siPIHHFjuCGUsbzRjdqkwbat+Of6DmYRg5shIXXrLdZoVE/+TJ9O1dsKsFmYhU58JvIbZRU1Z9w==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.1.2.tgz", + "integrity": "sha512-uMgfERpJYoQmykAd0ffyMq8wignN4SvLUG6orJQRe9WAlTRc9cdpCaE/29qurXixYJVZWUqIBXhSk8v5xN1V9g==", "dev": true, "requires": { - "@jest/environment": "^29.0.3", - "@jest/expect": "^29.0.3", - "@jest/types": "^29.0.3", - "jest-mock": "^29.0.3" + "@jest/environment": "^29.1.2", + "@jest/expect": "^29.1.2", + "@jest/types": "^29.1.2", + "jest-mock": "^29.1.2" } }, "@jest/reporters": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.0.3.tgz", - "integrity": "sha512-3+QU3d4aiyOWfmk1obDerie4XNCaD5Xo1IlKNde2yGEi02WQD+ZQD0i5Hgqm1e73sMV7kw6pMlCnprtEwEVwxw==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.1.2.tgz", + "integrity": "sha512-X4fiwwyxy9mnfpxL0g9DD0KcTmEIqP0jUdnc2cfa9riHy+I6Gwwp5vOZiwyg0vZxfSDxrOlK9S4+340W4d+DAA==", "dev": true, "requires": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^29.0.3", - "@jest/test-result": "^29.0.3", - "@jest/transform": "^29.0.3", - "@jest/types": "^29.0.3", + "@jest/console": "^29.1.2", + "@jest/test-result": "^29.1.2", + "@jest/transform": "^29.1.2", + "@jest/types": "^29.1.2", "@jridgewell/trace-mapping": "^0.3.15", "@types/node": "*", "chalk": "^4.0.0", @@ -12565,9 +12531,9 @@ "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", "istanbul-reports": "^3.1.3", - "jest-message-util": "^29.0.3", - "jest-util": "^29.0.3", - "jest-worker": "^29.0.3", + "jest-message-util": "^29.1.2", + "jest-util": "^29.1.2", + "jest-worker": "^29.1.2", "slash": "^3.0.0", "string-length": "^4.0.1", "strip-ansi": "^6.0.0", @@ -12596,46 +12562,46 @@ } }, "@jest/test-result": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.0.3.tgz", - "integrity": "sha512-vViVnQjCgTmbhDKEonKJPtcFe9G/CJO4/Np4XwYJah+lF2oI7KKeRp8t1dFvv44wN2NdbDb/qC6pi++Vpp0Dlg==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.1.2.tgz", + "integrity": "sha512-jjYYjjumCJjH9hHCoMhA8PCl1OxNeGgAoZ7yuGYILRJX9NjgzTN0pCT5qAoYR4jfOP8htIByvAlz9vfNSSBoVg==", "dev": true, "requires": { - "@jest/console": "^29.0.3", - "@jest/types": "^29.0.3", + "@jest/console": "^29.1.2", + "@jest/types": "^29.1.2", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, "@jest/test-sequencer": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.0.3.tgz", - "integrity": "sha512-Hf4+xYSWZdxTNnhDykr8JBs0yBN/nxOXyUQWfotBUqqy0LF9vzcFB0jm/EDNZCx587znLWTIgxcokW7WeZMobQ==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.1.2.tgz", + "integrity": "sha512-fU6dsUqqm8sA+cd85BmeF7Gu9DsXVWFdGn9taxM6xN1cKdcP/ivSgXh5QucFRFz1oZxKv3/9DYYbq0ULly3P/Q==", "dev": true, "requires": { - "@jest/test-result": "^29.0.3", + "@jest/test-result": "^29.1.2", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.0.3", + "jest-haste-map": "^29.1.2", "slash": "^3.0.0" } }, "@jest/transform": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.0.3.tgz", - "integrity": "sha512-C5ihFTRYaGDbi/xbRQRdbo5ddGtI4VSpmL6AIcZxdhwLbXMa7PcXxxqyI91vGOFHnn5aVM3WYnYKCHEqmLVGzg==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.1.2.tgz", + "integrity": "sha512-2uaUuVHTitmkx1tHF+eBjb4p7UuzBG7SXIaA/hNIkaMP6K+gXYGxP38ZcrofzqN0HeZ7A90oqsOa97WU7WZkSw==", "dev": true, "requires": { "@babel/core": "^7.11.6", - "@jest/types": "^29.0.3", + "@jest/types": "^29.1.2", "@jridgewell/trace-mapping": "^0.3.15", "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", "convert-source-map": "^1.4.0", "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.0.3", + "jest-haste-map": "^29.1.2", "jest-regex-util": "^29.0.0", - "jest-util": "^29.0.3", + "jest-util": "^29.1.2", "micromatch": "^4.0.4", "pirates": "^4.0.4", "slash": "^3.0.0", @@ -12643,9 +12609,9 @@ } }, "@jest/types": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.0.3.tgz", - "integrity": "sha512-coBJmOQvurXjN1Hh5PzF7cmsod0zLIOXpP8KD161mqNlroMhLcwpODiEzi7ZsRl5Z/AIuxpeNm8DCl43F4kz8A==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.1.2.tgz", + "integrity": "sha512-DcXGtoTykQB5jiwCmVr8H4vdg2OJhQex3qPkG+ISyDO7xQXbt/4R6dowcRyPemRnkH7JoHvZuxPBdlq+9JxFCg==", "dev": true, "requires": { "@jest/schemas": "^29.0.0", @@ -12703,39 +12669,39 @@ "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" }, "@jridgewell/trace-mapping": { - "version": "0.3.15", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz", - "integrity": "sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==", + "version": "0.3.16", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.16.tgz", + "integrity": "sha512-LCQ+NeThyJ4k1W2d+vIKdxuSt9R3pQSZ4P92m7EakaYuXcVWbHuT5bjNcqLd4Rdgi6xYWYDvBJZJLZSLanjDcA==", "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" } }, "@jsep-plugin/regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@jsep-plugin/regex/-/regex-1.0.2.tgz", - "integrity": "sha512-Nn/Bcaww8zOebMDqNmGlhAWPWhIr/8S8lGIgaB/fSqev5xaO5uKy5i4qvTh63GpR+VzKqimgxDdcxdcRuCJXSw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@jsep-plugin/regex/-/regex-1.0.3.tgz", + "integrity": "sha512-XfZgry4DwEZvSFtS/6Y+R48D7qJYJK6R9/yJFyUFHCIUMEEHuJ4X95TDgJp5QkmzfLYvapMPzskV5HpIDrREug==", "dev": true, "requires": {} }, "@jsep-plugin/ternary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jsep-plugin/ternary/-/ternary-1.1.2.tgz", - "integrity": "sha512-gXguJc09uCrqWt1MD7L1+ChO32g4UH4BYGpHPoQRLhyU7pAPPRA7cvKbyjoqhnUlLutiXvLzB5hVVawPKax8jw==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@jsep-plugin/ternary/-/ternary-1.1.3.tgz", + "integrity": "sha512-qtLGzCNzPVJ3kdH6/zoLWDPjauHIKiLSBAR71Wa0+PWvGA8wODUQvRgxtpUA5YqAYL3CQ8S4qXhd/9WuWTZirg==", "dev": true, "requires": {} }, "@mcaptcha/core-glue": { - "version": "0.1.0-alpha-3", - "resolved": "https://registry.npmjs.org/@mcaptcha/core-glue/-/core-glue-0.1.0-alpha-3.tgz", - "integrity": "sha512-avphBVgf3PPDWuUoDsB2qiXAss2pc00lUILswJaMQofr8FQyflzkhha8H2Z+qGFiX0Iib/yyP2TOtBDbHqE9Tg==" + "version": "0.1.0-alpha-5", + "resolved": "https://registry.npmjs.org/@mcaptcha/core-glue/-/core-glue-0.1.0-alpha-5.tgz", + "integrity": "sha512-16qWm5O5X0Y9LXULULaAks8Vf9FNlUUBcR5KDt49aWhFhG5++JzxNmCwQM9EJSHNU7y0U+FdyAWcGmjfKlkRLA==" }, "@mcaptcha/vanilla-glue": { - "version": "0.1.0-alpha-2", - "resolved": "https://registry.npmjs.org/@mcaptcha/vanilla-glue/-/vanilla-glue-0.1.0-alpha-2.tgz", - "integrity": "sha512-cQOg3EIhdjk1xoZtjD9SVPwQAnd49FCvHKchwFZZuhdNTeFs7SUHynOCekuGow2Ip0RJZuMZGcRxvWMgd0ogng==", + "version": "0.1.0-alpha-3", + "resolved": "https://registry.npmjs.org/@mcaptcha/vanilla-glue/-/vanilla-glue-0.1.0-alpha-3.tgz", + "integrity": "sha512-GT6TJBgmViGXcXiT5VOr+h/6iOnThSlZuCoOWncubyTZU9R3cgU5vWPkF7G6Ob6ee2CBe3yqBxxk24CFVGTVXw==", "requires": { - "@mcaptcha/core-glue": "^0.1.0-alpha-3" + "@mcaptcha/core-glue": "^0.1.0-alpha-5" } }, "@nodelib/fs.scandir": { @@ -12762,13 +12728,13 @@ } }, "@playwright/test": { - "version": "1.25.2", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.25.2.tgz", - "integrity": "sha512-6qPznIR4Fw02OMbqXUPMG6bFFg1hDVNEdihKy0t9K0dmRbus1DyP5Q5XFQhGwEHQkLG5hrSfBuu9CW/foqhQHQ==", + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.27.0.tgz", + "integrity": "sha512-L4BswoJvGkFsEHhEgzVNHBnkFB1FbnBQn3QmvTl7+AouoJQ4a8tLwZKvytdovCsNi7B5cXuRo58yGvfM5PnExw==", "dev": true, "requires": { "@types/node": "*", - "playwright-core": "1.25.2" + "playwright-core": "1.27.0" } }, "@popperjs/core": { @@ -12777,9 +12743,9 @@ "integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==" }, "@primer/octicons": { - "version": "17.5.0", - "resolved": "https://registry.npmjs.org/@primer/octicons/-/octicons-17.5.0.tgz", - "integrity": "sha512-Bx/IfCMXZSq0YBPspoRoALVou5LiAdSg4yNtwEoYDZ137aq238Glnb6SBE5BtRSyzegTv7wFp/uYUPXMXT2MRg==", + "version": "17.7.0", + "resolved": "https://registry.npmjs.org/@primer/octicons/-/octicons-17.7.0.tgz", + "integrity": "sha512-J5cVJDhExmqLGLWu8zHTOqcC8g1rQL7QzQZdbvHxW85u8ya82GtF5F68uHMDI5En3fsMlbkkF8Rz6dCaV3r+KA==", "requires": { "object-assign": "^4.1.1" } @@ -12819,9 +12785,9 @@ } }, "@sinclair/typebox": { - "version": "0.24.40", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.40.tgz", - "integrity": "sha512-Xint60L8rF0+nRy+6fCjW9jQMmu7fTpbwTBrXZiK6eq/RHDJS7LvWX/0oXC8O7fCePmrY/XdfaTv2HiUDeCq4g==", + "version": "0.24.44", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.44.tgz", + "integrity": "sha512-ka0W0KN5i6LfrSocduwliMMpqVgohtPFidKdMEOUjoOFCHcOOYkKsPRxfs5f15oPNHTm6ERAm0GV/+/LTKeiWg==", "dev": true }, "@sinonjs/commons": { @@ -12902,15 +12868,6 @@ "urijs": "^1.19.6" } }, - "@stoplight/lifecycle": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/@stoplight/lifecycle/-/lifecycle-2.3.2.tgz", - "integrity": "sha512-v0u8p27FA/eg04b4z6QXw4s0NeeFcRzyvseBW0+k/q4jtpg7EhVCqy42EbbbU43NTNDpIeQ81OcvkFz+6CYshw==", - "dev": true, - "requires": { - "wolfy87-eventemitter": "~5.2.8" - } - }, "@stoplight/ordered-object-literal": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@stoplight/ordered-object-literal/-/ordered-object-literal-1.0.4.tgz", @@ -12979,14 +12936,13 @@ } }, "@stoplight/spectral-core": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-core/-/spectral-core-1.14.1.tgz", - "integrity": "sha512-UMPfkrDqIMiAoZuVx4QiVV3D5fssfhDQ6R36qTP3x0hZFOeVDIFIcVdKV8lgmvsbpKaOgU/AD/2s4jScyTIqoA==", + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-core/-/spectral-core-1.14.2.tgz", + "integrity": "sha512-W2Z31lasEICpZS50STFskOdkn4g0Va81XA1A88LIj9mvlctDFf4BfpjLgIjKkI4f2DEK5C4j3COcbbzV8y5Xig==", "dev": true, "requires": { "@stoplight/better-ajv-errors": "1.0.3", "@stoplight/json": "~3.20.1", - "@stoplight/lifecycle": "2.3.2", "@stoplight/path": "1.3.2", "@stoplight/spectral-parsers": "^1.0.0", "@stoplight/spectral-ref-resolver": "^1.0.0", @@ -13036,9 +12992,9 @@ } }, "@stoplight/spectral-formats": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-formats/-/spectral-formats-1.2.0.tgz", - "integrity": "sha512-idvn7r8fvQjY/KeJpKgXQ5eJhce6N6/KoKWMPSh5yyvYDpn+bkU4pxAD79jOJaDnIyKJd1jjTPEJWnxbS0jj6A==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-formats/-/spectral-formats-1.4.0.tgz", + "integrity": "sha512-j9VQukDzgqDSi26rK9LqsbXrqtkeIsPSPgEf5/sxRsmeF2bwWUhSjYXgYin4flSZ7owFZjZWQ3o0Qq3iApi2JQ==", "dev": true, "requires": { "@stoplight/json": "^3.17.0", @@ -13081,9 +13037,9 @@ } }, "@stoplight/types": { - "version": "13.6.0", - "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.6.0.tgz", - "integrity": "sha512-dzyuzvUjv3m1wmhPfq82lCVYGcXG0xUYgqnWfCq3PCVR4BKFhjdkHrnJ+jIDoMKvXb05AZP/ObQF6+NpDo29IQ==", + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.7.0.tgz", + "integrity": "sha512-7ePIccfTxjEhruv8VrkDv5whP5qd9ijRzAWEbjYpUYnDfaqPTfq8/wMMjMCAKIecboxsAVD9LZy/3puXddGsDQ==", "dev": true, "requires": { "@types/json-schema": "^7.0.4", @@ -13119,9 +13075,9 @@ } }, "@stoplight/types": { - "version": "13.6.0", - "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.6.0.tgz", - "integrity": "sha512-dzyuzvUjv3m1wmhPfq82lCVYGcXG0xUYgqnWfCq3PCVR4BKFhjdkHrnJ+jIDoMKvXb05AZP/ObQF6+NpDo29IQ==", + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.7.0.tgz", + "integrity": "sha512-7ePIccfTxjEhruv8VrkDv5whP5qd9ijRzAWEbjYpUYnDfaqPTfq8/wMMjMCAKIecboxsAVD9LZy/3puXddGsDQ==", "dev": true, "requires": { "@types/json-schema": "^7.0.4", @@ -13183,9 +13139,9 @@ } }, "@stoplight/types": { - "version": "13.6.0", - "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.6.0.tgz", - "integrity": "sha512-dzyuzvUjv3m1wmhPfq82lCVYGcXG0xUYgqnWfCq3PCVR4BKFhjdkHrnJ+jIDoMKvXb05AZP/ObQF6+NpDo29IQ==", + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.7.0.tgz", + "integrity": "sha512-7ePIccfTxjEhruv8VrkDv5whP5qd9ijRzAWEbjYpUYnDfaqPTfq8/wMMjMCAKIecboxsAVD9LZy/3puXddGsDQ==", "dev": true, "requires": { "@types/json-schema": "^7.0.4", @@ -13231,9 +13187,9 @@ } }, "@stoplight/types": { - "version": "13.6.0", - "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.6.0.tgz", - "integrity": "sha512-dzyuzvUjv3m1wmhPfq82lCVYGcXG0xUYgqnWfCq3PCVR4BKFhjdkHrnJ+jIDoMKvXb05AZP/ObQF6+NpDo29IQ==", + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.7.0.tgz", + "integrity": "sha512-7ePIccfTxjEhruv8VrkDv5whP5qd9ijRzAWEbjYpUYnDfaqPTfq8/wMMjMCAKIecboxsAVD9LZy/3puXddGsDQ==", "dev": true, "requires": { "@types/json-schema": "^7.0.4", @@ -13243,16 +13199,16 @@ } }, "@stoplight/spectral-rulesets": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-rulesets/-/spectral-rulesets-1.12.0.tgz", - "integrity": "sha512-ktSO5YPzYzscnGTQffyKJwrzsR2i5cpPUC4yBp0isc6mOeiVec4r9sjMUN1mJt0RVnXi509vd0+YlMthFIZYnw==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-rulesets/-/spectral-rulesets-1.14.1.tgz", + "integrity": "sha512-tn6a5fYPFDwEY+/YyK/hcq2gcR5nSIBt7l+JGELb/2RdTzD5ikj2mfl2ua3uxbqOZytftFoOX5ewGZ0qQNrudw==", "dev": true, "requires": { - "@asyncapi/specs": "^2.14.0", + "@asyncapi/specs": "^3.2.0", "@stoplight/better-ajv-errors": "1.0.3", "@stoplight/json": "^3.17.0", "@stoplight/spectral-core": "^1.8.1", - "@stoplight/spectral-formats": "^1.2.0", + "@stoplight/spectral-formats": "^1.4.0", "@stoplight/spectral-functions": "^1.5.1", "@stoplight/spectral-runtime": "^1.1.1", "@stoplight/types": "^13.6.0", @@ -13265,9 +13221,9 @@ }, "dependencies": { "@stoplight/types": { - "version": "13.6.0", - "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.6.0.tgz", - "integrity": "sha512-dzyuzvUjv3m1wmhPfq82lCVYGcXG0xUYgqnWfCq3PCVR4BKFhjdkHrnJ+jIDoMKvXb05AZP/ObQF6+NpDo29IQ==", + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.7.0.tgz", + "integrity": "sha512-7ePIccfTxjEhruv8VrkDv5whP5qd9ijRzAWEbjYpUYnDfaqPTfq8/wMMjMCAKIecboxsAVD9LZy/3puXddGsDQ==", "dev": true, "requires": { "@types/json-schema": "^7.0.4", @@ -13314,9 +13270,9 @@ }, "dependencies": { "@stoplight/types": { - "version": "13.6.0", - "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.6.0.tgz", - "integrity": "sha512-dzyuzvUjv3m1wmhPfq82lCVYGcXG0xUYgqnWfCq3PCVR4BKFhjdkHrnJ+jIDoMKvXb05AZP/ObQF6+NpDo29IQ==", + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.7.0.tgz", + "integrity": "sha512-7ePIccfTxjEhruv8VrkDv5whP5qd9ijRzAWEbjYpUYnDfaqPTfq8/wMMjMCAKIecboxsAVD9LZy/3puXddGsDQ==", "dev": true, "requires": { "@types/json-schema": "^7.0.4", @@ -13381,9 +13337,9 @@ } }, "@types/babel__traverse": { - "version": "7.18.1", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.1.tgz", - "integrity": "sha512-FSdLaZh2UxaMuLp9lixWaHq/golWTRWOnRsAXzDTDSDOQLuZb1nsdCt6pJSPWSEQt2eFZ2YVk3oYhn+1kLMeMA==", + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.2.tgz", + "integrity": "sha512-FcFaxOr2V5KZCviw1TnutEMVUVsGt4D2hP1TAfXZAMKuHYW3xQhe3jTxNPWutgCJ3/X1c5yX8ZoGVEItxKbwBg==", "dev": true, "requires": { "@babel/types": "^7.3.0" @@ -13496,9 +13452,9 @@ "dev": true }, "@types/node": { - "version": "18.7.16", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.16.tgz", - "integrity": "sha512-EQHhixfu+mkqHMZl1R2Ovuvn47PUw18azMJOTwSZr9/fhzHNGXAJ0ma0dayRVchprpCj0Kc1K1xKoWaATWF1qg==" + "version": "18.8.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.8.3.tgz", + "integrity": "sha512-0os9vz6BpGwxGe9LOhgP/ncvYN5Tx1fNcd2TM3rD/aCGBkysb+ZWpXEocG24h6ZzOi13+VB8HndAQFezsSOw1w==" }, "@types/normalize-package-data": { "version": "2.4.1", @@ -13513,9 +13469,9 @@ "dev": true }, "@types/prettier": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.0.tgz", - "integrity": "sha512-RI1L7N4JnW5gQw2spvL7Sllfuf1SaHdrZpCHiBlCXjIlufi1SMNnbu2teze3/QE67Fg2tBlH7W+mi4hVNk4p0A==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.1.tgz", + "integrity": "sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow==", "dev": true }, "@types/stack-utils": { @@ -13545,9 +13501,9 @@ "dev": true }, "@types/yargs": { - "version": "17.0.12", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.12.tgz", - "integrity": "sha512-Nz4MPhecOFArtm81gFQvQqdV7XYCrWKx5uUt6GNHredFHn1i2mtWqXTON7EPXMtNi1qjtjEM/VCHDhcHsAMLXQ==", + "version": "17.0.13", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.13.tgz", + "integrity": "sha512-9sWaruZk2JGxIQU+IhI1fhPYRcQ0UuTNuKuCW9bR5fp7qi2Llf7WDzNa17Cy7TKnh3cdxDOiyTu6gaLS0eDatg==", "dev": true, "requires": { "@types/yargs-parser": "*" @@ -13560,36 +13516,36 @@ "dev": true }, "@vue/compiler-core": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.37.tgz", - "integrity": "sha512-81KhEjo7YAOh0vQJoSmAD68wLfYqJvoiD4ulyedzF+OEk/bk6/hx3fTNVfuzugIIaTrOx4PGx6pAiBRe5e9Zmg==", + "version": "3.2.40", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.40.tgz", + "integrity": "sha512-2Dc3Stk0J/VyQ4OUr2yEC53kU28614lZS+bnrCbFSAIftBJ40g/2yQzf4mPBiFuqguMB7hyHaujdgZAQ67kZYA==", "requires": { "@babel/parser": "^7.16.4", - "@vue/shared": "3.2.37", + "@vue/shared": "3.2.40", "estree-walker": "^2.0.2", "source-map": "^0.6.1" } }, "@vue/compiler-dom": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.37.tgz", - "integrity": "sha512-yxJLH167fucHKxaqXpYk7x8z7mMEnXOw3G2q62FTkmsvNxu4FQSu5+3UMb+L7fjKa26DEzhrmCxAgFLLIzVfqQ==", + "version": "3.2.40", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.40.tgz", + "integrity": "sha512-OZCNyYVC2LQJy4H7h0o28rtk+4v+HMQygRTpmibGoG9wZyomQiS5otU7qo3Wlq5UfHDw2RFwxb9BJgKjVpjrQw==", "requires": { - "@vue/compiler-core": "3.2.37", - "@vue/shared": "3.2.37" + "@vue/compiler-core": "3.2.40", + "@vue/shared": "3.2.40" } }, "@vue/compiler-sfc": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.37.tgz", - "integrity": "sha512-+7i/2+9LYlpqDv+KTtWhOZH+pa8/HnX/905MdVmAcI/mPQOBwkHHIzrsEsucyOIZQYMkXUiTkmZq5am/NyXKkg==", + "version": "3.2.40", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.40.tgz", + "integrity": "sha512-tzqwniIN1fu1PDHC3CpqY/dPCfN/RN1thpBC+g69kJcrl7mbGiHKNwbA6kJ3XKKy8R6JLKqcpVugqN4HkeBFFg==", "requires": { "@babel/parser": "^7.16.4", - "@vue/compiler-core": "3.2.37", - "@vue/compiler-dom": "3.2.37", - "@vue/compiler-ssr": "3.2.37", - "@vue/reactivity-transform": "3.2.37", - "@vue/shared": "3.2.37", + "@vue/compiler-core": "3.2.40", + "@vue/compiler-dom": "3.2.40", + "@vue/compiler-ssr": "3.2.40", + "@vue/reactivity-transform": "3.2.40", + "@vue/shared": "3.2.40", "estree-walker": "^2.0.2", "magic-string": "^0.25.7", "postcss": "^8.1.10", @@ -13597,66 +13553,66 @@ } }, "@vue/compiler-ssr": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.37.tgz", - "integrity": "sha512-7mQJD7HdXxQjktmsWp/J67lThEIcxLemz1Vb5I6rYJHR5vI+lON3nPGOH3ubmbvYGt8xEUaAr1j7/tIFWiEOqw==", + "version": "3.2.40", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.40.tgz", + "integrity": "sha512-80cQcgasKjrPPuKcxwuCx7feq+wC6oFl5YaKSee9pV3DNq+6fmCVwEEC3vvkf/E2aI76rIJSOYHsWSEIxK74oQ==", "requires": { - "@vue/compiler-dom": "3.2.37", - "@vue/shared": "3.2.37" + "@vue/compiler-dom": "3.2.40", + "@vue/shared": "3.2.40" } }, "@vue/reactivity": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.37.tgz", - "integrity": "sha512-/7WRafBOshOc6m3F7plwzPeCu/RCVv9uMpOwa/5PiY1Zz+WLVRWiy0MYKwmg19KBdGtFWsmZ4cD+LOdVPcs52A==", + "version": "3.2.40", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.40.tgz", + "integrity": "sha512-N9qgGLlZmtUBMHF9xDT4EkD9RdXde1Xbveb+niWMXuHVWQP5BzgRmE3SFyUBBcyayG4y1lhoz+lphGRRxxK4RA==", "requires": { - "@vue/shared": "3.2.37" + "@vue/shared": "3.2.40" } }, "@vue/reactivity-transform": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.37.tgz", - "integrity": "sha512-IWopkKEb+8qpu/1eMKVeXrK0NLw9HicGviJzhJDEyfxTR9e1WtpnnbYkJWurX6WwoFP0sz10xQg8yL8lgskAZg==", + "version": "3.2.40", + "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.40.tgz", + "integrity": "sha512-HQUCVwEaacq6fGEsg2NUuGKIhUveMCjOk8jGHqLXPI2w6zFoPrlQhwWEaINTv5kkZDXKEnCijAp+4gNEHG03yw==", "requires": { "@babel/parser": "^7.16.4", - "@vue/compiler-core": "3.2.37", - "@vue/shared": "3.2.37", + "@vue/compiler-core": "3.2.40", + "@vue/shared": "3.2.40", "estree-walker": "^2.0.2", "magic-string": "^0.25.7" } }, "@vue/runtime-core": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.37.tgz", - "integrity": "sha512-JPcd9kFyEdXLl/i0ClS7lwgcs0QpUAWj+SKX2ZC3ANKi1U4DOtiEr6cRqFXsPwY5u1L9fAjkinIdB8Rz3FoYNQ==", + "version": "3.2.40", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.40.tgz", + "integrity": "sha512-U1+rWf0H8xK8aBUZhnrN97yoZfHbjgw/bGUzfgKPJl69/mXDuSg8CbdBYBn6VVQdR947vWneQBFzdhasyzMUKg==", "requires": { - "@vue/reactivity": "3.2.37", - "@vue/shared": "3.2.37" + "@vue/reactivity": "3.2.40", + "@vue/shared": "3.2.40" } }, "@vue/runtime-dom": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.37.tgz", - "integrity": "sha512-HimKdh9BepShW6YozwRKAYjYQWg9mQn63RGEiSswMbW+ssIht1MILYlVGkAGGQbkhSh31PCdoUcfiu4apXJoPw==", + "version": "3.2.40", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.40.tgz", + "integrity": "sha512-AO2HMQ+0s2+MCec8hXAhxMgWhFhOPJ/CyRXnmTJ6XIOnJFLrH5Iq3TNwvVcODGR295jy77I6dWPj+wvFoSYaww==", "requires": { - "@vue/runtime-core": "3.2.37", - "@vue/shared": "3.2.37", + "@vue/runtime-core": "3.2.40", + "@vue/shared": "3.2.40", "csstype": "^2.6.8" } }, "@vue/server-renderer": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.37.tgz", - "integrity": "sha512-kLITEJvaYgZQ2h47hIzPh2K3jG8c1zCVbp/o/bzQOyvzaKiCquKS7AaioPI28GNxIsE/zSx+EwWYsNxDCX95MA==", + "version": "3.2.40", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.40.tgz", + "integrity": "sha512-gtUcpRwrXOJPJ4qyBpU3EyxQa4EkV8I4f8VrDePcGCPe4O/hd0BPS7v9OgjIQob6Ap8VDz9G+mGTKazE45/95w==", "requires": { - "@vue/compiler-ssr": "3.2.37", - "@vue/shared": "3.2.37" + "@vue/compiler-ssr": "3.2.40", + "@vue/shared": "3.2.40" } }, "@vue/shared": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.37.tgz", - "integrity": "sha512-4rSJemR2NQIo9Klm1vabqWjD8rs/ZaJSzMxkMNeJS6lHiUjjUeYFbooN19NgFjztubEKh3WlZUeOLVdbbUWHsw==" + "version": "3.2.40", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.40.tgz", + "integrity": "sha512-0PLQ6RUtZM0vO3teRfzGi4ltLUO5aO+kLgwh4Um3THSR03rpQWLTuRCkuO5A41ITzwdWeKdPHtSARuPkoo5pCQ==" }, "@webassemblyjs/ast": { "version": "1.11.1", @@ -13840,21 +13796,13 @@ "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==" }, "acorn-globals": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", - "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-7.0.1.tgz", + "integrity": "sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==", "dev": true, "requires": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" - }, - "dependencies": { - "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true - } + "acorn": "^8.1.0", + "acorn-walk": "^8.0.2" } }, "acorn-import-assertions": { @@ -13871,9 +13819,9 @@ "requires": {} }, "acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", "dev": true }, "add-asset-webpack-plugin": { @@ -14057,12 +14005,12 @@ "dev": true }, "babel-jest": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.0.3.tgz", - "integrity": "sha512-ApPyHSOhS/sVzwUOQIWJmdvDhBsMG01HX9z7ogtkp1TToHGGUWFlnXJUIzCgKPSfiYLn3ibipCYzsKSURHEwLg==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.1.2.tgz", + "integrity": "sha512-IuG+F3HTHryJb7gacC7SQ59A9kO56BctUsT67uJHp1mMCHUOMXpDwOHWGifWqdWVknN2WNkCVQELPjXx0aLJ9Q==", "dev": true, "requires": { - "@jest/transform": "^29.0.3", + "@jest/transform": "^29.1.2", "@types/babel__core": "^7.1.14", "babel-plugin-istanbul": "^6.1.1", "babel-preset-jest": "^29.0.2", @@ -14165,21 +14113,15 @@ "fill-range": "^7.0.1" } }, - "browser-process-hrtime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", - "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", - "dev": true - }, "browserslist": { - "version": "4.21.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.3.tgz", - "integrity": "sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ==", + "version": "4.21.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", + "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", "requires": { - "caniuse-lite": "^1.0.30001370", - "electron-to-chromium": "^1.4.202", + "caniuse-lite": "^1.0.30001400", + "electron-to-chromium": "^1.4.251", "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.5" + "update-browserslist-db": "^1.0.9" } }, "bser": { @@ -14248,9 +14190,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001393", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001393.tgz", - "integrity": "sha512-N/od11RX+Gsk+1qY/jbPa0R6zJupEa0lxeBG598EbrtblxVCTJsQwbRBm6+V+rxpc5lHKdsXb9RY83cZIPLseA==" + "version": "1.0.30001418", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001418.tgz", + "integrity": "sha512-oIs7+JL3K9JRQ3jPZjlH6qyYDp+nBTCais7hjh0s+fuBwufc7uZ7hPYMXrDOJhV360KGMTcczMRObk0/iMqZRg==" }, "chalk": { "version": "4.1.2", @@ -14273,9 +14215,9 @@ "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==" }, "ci-info": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.4.0.tgz", - "integrity": "sha512-t5QdPT5jq3o262DOQ8zA6E1tlH2upmUc4Hlvrbx1pGYJuiiHl7O7rvVNI+l8HTVhd/q3Qc9vqimkNk5yiXsAug==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.5.0.tgz", + "integrity": "sha512-yH4RezKOGlOhxkmhbeNuC4eYZKAUsEaGtBuBzDDP1eFUKiccDWzBABxBfOx31IDwDIXMTxWuwAxUGModvkbuVw==", "dev": true }, "cjs-module-lexer": { @@ -14352,9 +14294,9 @@ "dev": true }, "codemirror": { - "version": "5.65.8", - "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.8.tgz", - "integrity": "sha512-TNGkSkkoAsmZSf6W6g35LMVQJBHKasc2CKwhr/fTxSYun7cn6J+CbtyNjV/MYlFVkNTsqZoviegyCZimWhoMMA==" + "version": "5.65.9", + "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.9.tgz", + "integrity": "sha512-19Jox5sAKpusTDgqgKB5dawPpQcY+ipQK7xoEI+MVucEF9qqFaXpeqY1KaoyGBso/wHQoDa4HMMxMjdsS3Zzzw==" }, "codemirror-spell-checker": { "version": "1.1.2", @@ -14404,10 +14346,9 @@ } }, "commander": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-9.4.0.tgz", - "integrity": "sha512-sRPT+umqkz90UA8M1yqYfnHlZA7fF6nSphDtxeywPZ49ysjxDQybzk13CL+mXekDRG92skbcqCLVovuCusNmFw==", - "dev": true + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==" }, "commondir": { "version": "1.0.1", @@ -15178,9 +15119,9 @@ } }, "decimal.js": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.0.tgz", - "integrity": "sha512-Nv6ENEzyPQ6AItkGwLE2PGKinZZ9g59vSh2BeH6NqPu0OTKZ5ruJsVqh/orbAnqXc9pBbgXAIrc2EyaCj8NpGg==", + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.1.tgz", + "integrity": "sha512-F29o+vci4DodHYT9UrR5IEbfBw9pE5eSapIJdTqXK5+6hq+t8VRxwQyKlW2i+KDKFkkJQRvFyI/QXD83h8LyQw==", "dev": true }, "dedent": { @@ -15398,9 +15339,9 @@ } }, "dompurify": { - "version": "2.3.10", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.3.10.tgz", - "integrity": "sha512-o7Fg/AgC7p/XpKjf/+RC3Ok6k4St5F7Q6q6+Nnm3p2zGWioAY6dh0CbbuwOhH2UcSzKsdniE/YnE2/92JcsA+g==" + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.4.0.tgz", + "integrity": "sha512-Be9tbQMZds4a3C6xTmz68NlMfeONA//4dOavl/1rNw50E+/QO0KVpbcU0PcaW0nsQxurXls9ZocqFxk8R2mWEA==" }, "domutils": { "version": "2.8.0", @@ -15428,21 +15369,21 @@ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" }, "easymde": { - "version": "2.17.0", - "resolved": "https://registry.npmjs.org/easymde/-/easymde-2.17.0.tgz", - "integrity": "sha512-xerjhBh6G+FDfU2EBfKNEVqawYGqnK2zACKtyQlZKnxPoaesncRbHiSX5Yrf3Ur8KjEX1BvG7Ysccrd8hKTkig==", + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/easymde/-/easymde-2.18.0.tgz", + "integrity": "sha512-IxVVUxNWIoXLeqtBU4BLc+eS/ScYhT1Dcb6yF5Wchoj1iXAV+TIIDWx+NCaZhY7RcSHqDPKllbYq7nwGKILnoA==", "requires": { "@types/codemirror": "^5.60.4", - "@types/marked": "^4.0.1", + "@types/marked": "^4.0.7", "codemirror": "^5.63.1", "codemirror-spell-checker": "1.1.2", - "marked": "^4.0.18" + "marked": "^4.1.0" } }, "electron-to-chromium": { - "version": "1.4.247", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.247.tgz", - "integrity": "sha512-FLs6R4FQE+1JHM0hh3sfdxnYjKvJpHZyhQDjc2qFq/xFvmmRt/TATNToZhrcGUFzpF2XjeiuozrA8lI0PZmYYw==" + "version": "1.4.276", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.276.tgz", + "integrity": "sha512-EpuHPqu8YhonqLBXHoU6hDJCD98FCe6KDoet3/gY1qsQ6usjJoHqBH2YIVs8FXaAtHwVL8Uqa/fsYao/vq9VWQ==" }, "emittery": { "version": "0.10.2", @@ -15505,22 +15446,22 @@ } }, "es-abstract": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.2.tgz", - "integrity": "sha512-XxXQuVNrySBNlEkTYJoDNFe5+s2yIOpzq80sUHEdPdQr0S5nTLz4ZPPPswNIpKseDDUS5yghX1gfLIHQZ1iNuQ==", + "version": "1.20.4", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.4.tgz", + "integrity": "sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA==", "dev": true, "requires": { "call-bind": "^1.0.2", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.1.2", + "get-intrinsic": "^1.1.3", "get-symbol-description": "^1.0.0", "has": "^1.0.3", "has-property-descriptors": "^1.0.0", "has-symbols": "^1.0.3", "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", + "is-callable": "^1.2.7", "is-negative-zero": "^2.0.2", "is-regex": "^1.1.4", "is-shared-array-buffer": "^1.0.2", @@ -15530,6 +15471,7 @@ "object-keys": "^1.1.1", "object.assign": "^4.1.4", "regexp.prototype.flags": "^1.4.3", + "safe-regex-test": "^1.0.0", "string.prototype.trimend": "^1.0.5", "string.prototype.trimstart": "^1.0.5", "unbox-primitive": "^1.0.2" @@ -15576,115 +15518,116 @@ } }, "esbuild": { - "version": "0.15.7", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.7.tgz", - "integrity": "sha512-7V8tzllIbAQV1M4QoE52ImKu8hT/NLGlGXkiDsbEU5PS6K8Mn09ZnYoS+dcmHxOS9CRsV4IRAMdT3I67IyUNXw==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.10.tgz", + "integrity": "sha512-N7wBhfJ/E5fzn/SpNgX+oW2RLRjwaL8Y0ezqNqhjD6w0H2p0rDuEz2FKZqpqLnO8DCaWumKe8dsC/ljvVSSxng==", "requires": { - "@esbuild/linux-loong64": "0.15.7", - "esbuild-android-64": "0.15.7", - "esbuild-android-arm64": "0.15.7", - "esbuild-darwin-64": "0.15.7", - "esbuild-darwin-arm64": "0.15.7", - "esbuild-freebsd-64": "0.15.7", - "esbuild-freebsd-arm64": "0.15.7", - "esbuild-linux-32": "0.15.7", - "esbuild-linux-64": "0.15.7", - "esbuild-linux-arm": "0.15.7", - "esbuild-linux-arm64": "0.15.7", - "esbuild-linux-mips64le": "0.15.7", - "esbuild-linux-ppc64le": "0.15.7", - "esbuild-linux-riscv64": "0.15.7", - "esbuild-linux-s390x": "0.15.7", - "esbuild-netbsd-64": "0.15.7", - "esbuild-openbsd-64": "0.15.7", - "esbuild-sunos-64": "0.15.7", - "esbuild-windows-32": "0.15.7", - "esbuild-windows-64": "0.15.7", - "esbuild-windows-arm64": "0.15.7" + "@esbuild/android-arm": "0.15.10", + "@esbuild/linux-loong64": "0.15.10", + "esbuild-android-64": "0.15.10", + "esbuild-android-arm64": "0.15.10", + "esbuild-darwin-64": "0.15.10", + "esbuild-darwin-arm64": "0.15.10", + "esbuild-freebsd-64": "0.15.10", + "esbuild-freebsd-arm64": "0.15.10", + "esbuild-linux-32": "0.15.10", + "esbuild-linux-64": "0.15.10", + "esbuild-linux-arm": "0.15.10", + "esbuild-linux-arm64": "0.15.10", + "esbuild-linux-mips64le": "0.15.10", + "esbuild-linux-ppc64le": "0.15.10", + "esbuild-linux-riscv64": "0.15.10", + "esbuild-linux-s390x": "0.15.10", + "esbuild-netbsd-64": "0.15.10", + "esbuild-openbsd-64": "0.15.10", + "esbuild-sunos-64": "0.15.10", + "esbuild-windows-32": "0.15.10", + "esbuild-windows-64": "0.15.10", + "esbuild-windows-arm64": "0.15.10" } }, "esbuild-android-64": { - "version": "0.15.7", - "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.7.tgz", - "integrity": "sha512-p7rCvdsldhxQr3YHxptf1Jcd86dlhvc3EQmQJaZzzuAxefO9PvcI0GLOa5nCWem1AJ8iMRu9w0r5TG8pHmbi9w==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.10.tgz", + "integrity": "sha512-UI7krF8OYO1N7JYTgLT9ML5j4+45ra3amLZKx7LO3lmLt1Ibn8t3aZbX5Pu4BjWiqDuJ3m/hsvhPhK/5Y/YpnA==", "optional": true }, "esbuild-android-arm64": { - "version": "0.15.7", - "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.7.tgz", - "integrity": "sha512-L775l9ynJT7rVqRM5vo+9w5g2ysbOCfsdLV4CWanTZ1k/9Jb3IYlQ06VCI1edhcosTYJRECQFJa3eAvkx72eyQ==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.10.tgz", + "integrity": "sha512-EOt55D6xBk5O05AK8brXUbZmoFj4chM8u3riGflLa6ziEoVvNjRdD7Cnp82NHQGfSHgYR06XsPI8/sMuA/cUwg==", "optional": true }, "esbuild-darwin-64": { - "version": "0.15.7", - "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.7.tgz", - "integrity": "sha512-KGPt3r1c9ww009t2xLB6Vk0YyNOXh7hbjZ3EecHoVDxgtbUlYstMPDaReimKe6eOEfyY4hBEEeTvKwPsiH5WZg==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.10.tgz", + "integrity": "sha512-hbDJugTicqIm+WKZgp208d7FcXcaK8j2c0l+fqSJ3d2AzQAfjEYDRM3Z2oMeqSJ9uFxyj/muSACLdix7oTstRA==", "optional": true }, "esbuild-darwin-arm64": { - "version": "0.15.7", - "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.7.tgz", - "integrity": "sha512-kBIHvtVqbSGajN88lYMnR3aIleH3ABZLLFLxwL2stiuIGAjGlQW741NxVTpUHQXUmPzxi6POqc9npkXa8AcSZQ==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.10.tgz", + "integrity": "sha512-M1t5+Kj4IgSbYmunf2BB6EKLkWUq+XlqaFRiGOk8bmBapu9bCDrxjf4kUnWn59Dka3I27EiuHBKd1rSO4osLFQ==", "optional": true }, "esbuild-freebsd-64": { - "version": "0.15.7", - "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.7.tgz", - "integrity": "sha512-hESZB91qDLV5MEwNxzMxPfbjAhOmtfsr9Wnuci7pY6TtEh4UDuevmGmkUIjX/b+e/k4tcNBMf7SRQ2mdNuK/HQ==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.10.tgz", + "integrity": "sha512-KMBFMa7C8oc97nqDdoZwtDBX7gfpolkk6Bcmj6YFMrtCMVgoU/x2DI1p74DmYl7CSS6Ppa3xgemrLrr5IjIn0w==", "optional": true }, "esbuild-freebsd-arm64": { - "version": "0.15.7", - "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.7.tgz", - "integrity": "sha512-dLFR0ChH5t+b3J8w0fVKGvtwSLWCv7GYT2Y2jFGulF1L5HftQLzVGN+6pi1SivuiVSmTh28FwUhi9PwQicXI6Q==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.10.tgz", + "integrity": "sha512-m2KNbuCX13yQqLlbSojFMHpewbn8wW5uDS6DxRpmaZKzyq8Dbsku6hHvh2U+BcLwWY4mpgXzFUoENEf7IcioGg==", "optional": true }, "esbuild-linux-32": { - "version": "0.15.7", - "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.7.tgz", - "integrity": "sha512-v3gT/LsONGUZcjbt2swrMjwxo32NJzk+7sAgtxhGx1+ZmOFaTRXBAi1PPfgpeo/J//Un2jIKm/I+qqeo4caJvg==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.10.tgz", + "integrity": "sha512-guXrwSYFAvNkuQ39FNeV4sNkNms1bLlA5vF1H0cazZBOLdLFIny6BhT+TUbK/hdByMQhtWQ5jI9VAmPKbVPu1w==", "optional": true }, "esbuild-linux-64": { - "version": "0.15.7", - "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.7.tgz", - "integrity": "sha512-LxXEfLAKwOVmm1yecpMmWERBshl+Kv5YJ/1KnyAr6HRHFW8cxOEsEfisD3sVl/RvHyW//lhYUVSuy9jGEfIRAQ==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.10.tgz", + "integrity": "sha512-jd8XfaSJeucMpD63YNMO1JCrdJhckHWcMv6O233bL4l6ogQKQOxBYSRP/XLWP+6kVTu0obXovuckJDcA0DKtQA==", "optional": true }, "esbuild-linux-arm": { - "version": "0.15.7", - "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.7.tgz", - "integrity": "sha512-JKgAHtMR5f75wJTeuNQbyznZZa+pjiUHV7sRZp42UNdyXC6TiUYMW/8z8yIBAr2Fpad8hM1royZKQisqPABPvQ==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.10.tgz", + "integrity": "sha512-6N8vThLL/Lysy9y4Ex8XoLQAlbZKUyExCWyayGi2KgTBelKpPgj6RZnUaKri0dHNPGgReJriKVU6+KDGQwn10A==", "optional": true }, "esbuild-linux-arm64": { - "version": "0.15.7", - "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.7.tgz", - "integrity": "sha512-P3cfhudpzWDkglutWgXcT2S7Ft7o2e3YDMrP1n0z2dlbUZghUkKCyaWw0zhp4KxEEzt/E7lmrtRu/pGWnwb9vw==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.10.tgz", + "integrity": "sha512-GByBi4fgkvZFTHFDYNftu1DQ1GzR23jws0oWyCfhnI7eMOe+wgwWrc78dbNk709Ivdr/evefm2PJiUBMiusS1A==", "optional": true }, "esbuild-linux-mips64le": { - "version": "0.15.7", - "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.7.tgz", - "integrity": "sha512-T7XKuxl0VpeFLCJXub6U+iybiqh0kM/bWOTb4qcPyDDwNVhLUiPcGdG2/0S7F93czUZOKP57YiLV8YQewgLHKw==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.10.tgz", + "integrity": "sha512-BxP+LbaGVGIdQNJUNF7qpYjEGWb0YyHVSKqYKrn+pTwH/SiHUxFyJYSP3pqkku61olQiSBnSmWZ+YUpj78Tw7Q==", "optional": true }, "esbuild-linux-ppc64le": { - "version": "0.15.7", - "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.7.tgz", - "integrity": "sha512-6mGuC19WpFN7NYbecMIJjeQgvDb5aMuvyk0PDYBJrqAEMkTwg3Z98kEKuCm6THHRnrgsdr7bp4SruSAxEM4eJw==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.10.tgz", + "integrity": "sha512-LoSQCd6498PmninNgqd/BR7z3Bsk/mabImBWuQ4wQgmQEeanzWd5BQU2aNi9mBURCLgyheuZS6Xhrw5luw3OkQ==", "optional": true }, "esbuild-linux-riscv64": { - "version": "0.15.7", - "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.7.tgz", - "integrity": "sha512-uUJsezbswAYo/X7OU/P+PuL/EI9WzxsEQXDekfwpQ23uGiooxqoLFAPmXPcRAt941vjlY9jtITEEikWMBr+F/g==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.10.tgz", + "integrity": "sha512-Lrl9Cr2YROvPV4wmZ1/g48httE8z/5SCiXIyebiB5N8VT7pX3t6meI7TQVHw/wQpqP/AF4SksDuFImPTM7Z32Q==", "optional": true }, "esbuild-linux-s390x": { - "version": "0.15.7", - "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.7.tgz", - "integrity": "sha512-+tO+xOyTNMc34rXlSxK7aCwJgvQyffqEM5MMdNDEeMU3ss0S6wKvbBOQfgd5jRPblfwJ6b+bKiz0g5nABpY0QQ==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.10.tgz", + "integrity": "sha512-ReP+6q3eLVVP2lpRrvl5EodKX7EZ1bS1/z5j6hsluAlZP5aHhk6ghT6Cq3IANvvDdscMMCB4QEbI+AjtvoOFpA==", "optional": true }, "esbuild-loader": { @@ -15701,39 +15644,39 @@ } }, "esbuild-netbsd-64": { - "version": "0.15.7", - "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.7.tgz", - "integrity": "sha512-yVc4Wz+Pu3cP5hzm5kIygNPrjar/v5WCSoRmIjCPWfBVJkZNb5brEGKUlf+0Y759D48BCWa0WHrWXaNy0DULTQ==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.10.tgz", + "integrity": "sha512-iGDYtJCMCqldMskQ4eIV+QSS/CuT7xyy9i2/FjpKvxAuCzrESZXiA1L64YNj6/afuzfBe9i8m/uDkFHy257hTw==", "optional": true }, "esbuild-openbsd-64": { - "version": "0.15.7", - "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.7.tgz", - "integrity": "sha512-GsimbwC4FSR4lN3wf8XmTQ+r8/0YSQo21rWDL0XFFhLHKlzEA4SsT1Tl8bPYu00IU6UWSJ+b3fG/8SB69rcuEQ==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.10.tgz", + "integrity": "sha512-ftMMIwHWrnrYnvuJQRJs/Smlcb28F9ICGde/P3FUTCgDDM0N7WA0o9uOR38f5Xe2/OhNCgkjNeb7QeaE3cyWkQ==", "optional": true }, "esbuild-sunos-64": { - "version": "0.15.7", - "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.7.tgz", - "integrity": "sha512-8CDI1aL/ts0mDGbWzjEOGKXnU7p3rDzggHSBtVryQzkSOsjCHRVe0iFYUuhczlxU1R3LN/E7HgUO4NXzGGP/Ag==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.10.tgz", + "integrity": "sha512-mf7hBL9Uo2gcy2r3rUFMjVpTaGpFJJE5QTDDqUFf1632FxteYANffDZmKbqX0PfeQ2XjUDE604IcE7OJeoHiyg==", "optional": true }, "esbuild-windows-32": { - "version": "0.15.7", - "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.7.tgz", - "integrity": "sha512-cOnKXUEPS8EGCzRSFa1x6NQjGhGsFlVgjhqGEbLTPsA7x4RRYiy2RKoArNUU4iR2vHmzqS5Gr84MEumO/wxYKA==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.10.tgz", + "integrity": "sha512-ttFVo+Cg8b5+qHmZHbEc8Vl17kCleHhLzgT8X04y8zudEApo0PxPg9Mz8Z2cKH1bCYlve1XL8LkyXGFjtUYeGg==", "optional": true }, "esbuild-windows-64": { - "version": "0.15.7", - "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.7.tgz", - "integrity": "sha512-7MI08Ec2sTIDv+zH6StNBKO+2hGUYIT42GmFyW6MBBWWtJhTcQLinKS6ldIN1d52MXIbiJ6nXyCJ+LpL4jBm3Q==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.10.tgz", + "integrity": "sha512-2H0gdsyHi5x+8lbng3hLbxDWR7mKHWh5BXZGKVG830KUmXOOWFE2YKJ4tHRkejRduOGDrBvHBriYsGtmTv3ntA==", "optional": true }, "esbuild-windows-arm64": { - "version": "0.15.7", - "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.7.tgz", - "integrity": "sha512-R06nmqBlWjKHddhRJYlqDd3Fabx9LFdKcjoOy08YLimwmsswlFBJV4rXzZCxz/b7ZJXvrZgj8DDv1ewE9+StMw==", + "version": "0.15.10", + "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.10.tgz", + "integrity": "sha512-S+th4F+F8VLsHLR0zrUcG+Et4hx0RKgK1eyHc08kztmLOES8BWwMiaGdoW9hiXuzznXQ0I/Fg904MNbr11Nktw==", "optional": true }, "escalade": { @@ -15807,14 +15750,13 @@ } }, "eslint": { - "version": "8.23.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.23.0.tgz", - "integrity": "sha512-pBG/XOn0MsJcKcTRLr27S5HpzQo4kLr+HjLQIyK4EiCsijDl/TB+h5uEuJU6bQ8Edvwz1XWOjpaP2qgnXGpTcA==", + "version": "8.25.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.25.0.tgz", + "integrity": "sha512-DVlJOZ4Pn50zcKW5bYH7GQK/9MsoQG2d5eDH0ebEkE8PbgzTTmtt/VTH9GGJ4BfeZCpBLqFfvsjX35UacUL83A==", "dev": true, "requires": { - "@eslint/eslintrc": "^1.3.1", - "@humanwhocodes/config-array": "^0.10.4", - "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", + "@eslint/eslintrc": "^1.3.3", + "@humanwhocodes/config-array": "^0.10.5", "@humanwhocodes/module-importer": "^1.0.1", "ajv": "^6.10.0", "chalk": "^4.0.0", @@ -15831,7 +15773,6 @@ "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "find-up": "^5.0.0", - "functional-red-black-tree": "^1.0.1", "glob-parent": "^6.0.1", "globals": "^13.15.0", "globby": "^11.1.0", @@ -15840,6 +15781,7 @@ "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", + "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", @@ -15976,18 +15918,18 @@ "requires": {} }, "eslint-plugin-unicorn": { - "version": "43.0.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-43.0.2.tgz", - "integrity": "sha512-DtqZ5mf/GMlfWoz1abIjq5jZfaFuHzGBZYIeuJfEoKKGWRHr2JiJR+ea+BF7Wx2N1PPRoT/2fwgiK1NnmNE3Hg==", + "version": "44.0.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-44.0.2.tgz", + "integrity": "sha512-GLIDX1wmeEqpGaKcnMcqRvMVsoabeF0Ton0EX4Th5u6Kmf7RM9WBl705AXFEsns56ESkEs0uyelLuUTvz9Tr0w==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.18.6", - "ci-info": "^3.3.2", + "@babel/helper-validator-identifier": "^7.19.1", + "ci-info": "^3.4.0", "clean-regexp": "^1.0.0", "eslint-utils": "^3.0.0", "esquery": "^1.4.0", "indent-string": "^4.0.0", - "is-builtin-module": "^3.1.0", + "is-builtin-module": "^3.2.0", "lodash": "^4.17.21", "pluralize": "^8.0.0", "read-pkg-up": "^7.0.1", @@ -15998,9 +15940,9 @@ } }, "eslint-plugin-vue": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.4.0.tgz", - "integrity": "sha512-Nzz2QIJ8FG+rtJaqT/7/ru5ie2XgT9KCudkbN0y3uFYhQ41nuHEaboLAiqwMcK006hZPQv/rVMRhUIwEGhIvfQ==", + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.6.0.tgz", + "integrity": "sha512-zzySkJgVbFCylnG2+9MDF7N+2Rjze2y0bF8GyUNpFOnT8mCMfqqtLDJkHBuYu9N/psW1A6DVbQhPkP92E+qakA==", "dev": true, "requires": { "eslint-utils": "^3.0.0", @@ -16130,16 +16072,16 @@ "dev": true }, "expect": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.0.3.tgz", - "integrity": "sha512-t8l5DTws3212VbmPL+tBFXhjRHLmctHB0oQbL8eUc6S7NzZtYUhycrFO9mkxA0ZUC6FAWdNi7JchJSkODtcu1Q==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.1.2.tgz", + "integrity": "sha512-AuAGn1uxva5YBbBlXb+2JPxJRuemZsmlGcapPXWNSBNsQtAULfjioREGBWuI0EOvYUKjDnrCy8PW5Zlr1md5mw==", "dev": true, "requires": { - "@jest/expect-utils": "^29.0.3", + "@jest/expect-utils": "^29.1.2", "jest-get-type": "^29.0.0", - "jest-matcher-utils": "^29.0.3", - "jest-message-util": "^29.0.3", - "jest-util": "^29.0.3" + "jest-matcher-utils": "^29.1.2", + "jest-message-util": "^29.1.2", + "jest-util": "^29.1.2" } }, "fast-deep-equal": { @@ -16200,9 +16142,9 @@ } }, "fb-watchman": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", - "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", "dev": true, "requires": { "bser": "2.1.1" @@ -16323,12 +16265,6 @@ "functions-have-names": "^1.2.2" } }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", - "dev": true - }, "functions-have-names": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", @@ -16348,9 +16284,9 @@ "dev": true }, "get-intrinsic": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz", - "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", + "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", "dev": true, "requires": { "function-bind": "^1.1.1", @@ -16548,9 +16484,9 @@ } }, "gsap": { - "version": "3.11.1", - "resolved": "https://registry.npmjs.org/gsap/-/gsap-3.11.1.tgz", - "integrity": "sha512-UKuJ0UPhntFHMwT6URFQ4cTQv88xc7Kd9Dhxt7qX9IPhC+d+/a5wKW5E5Vn33hZ53nBI1JfApcEbzKgXkcuPZw==" + "version": "3.11.3", + "resolved": "https://registry.npmjs.org/gsap/-/gsap-3.11.3.tgz", + "integrity": "sha512-xc/iIJy+LWiMbRa4IdMtdnnKa/7PXEK6NNzV71gdOYUVeTZN7UWnLU0fB7Hi1iwiz4ZZoYkBZPPYGg+2+zzFHA==" }, "hard-rejection": { "version": "2.1.0", @@ -16824,9 +16760,9 @@ } }, "is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "dev": true }, "is-core-module": { @@ -16997,9 +16933,9 @@ "dev": true }, "istanbul-lib-instrument": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.0.tgz", - "integrity": "sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", "dev": true, "requires": { "@babel/core": "^7.12.3", @@ -17050,15 +16986,15 @@ } }, "jest": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest/-/jest-29.0.3.tgz", - "integrity": "sha512-ElgUtJBLgXM1E8L6K1RW1T96R897YY/3lRYqq9uVcPWtP2AAl/nQ16IYDh/FzQOOQ12VEuLdcPU83mbhG2C3PQ==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.1.2.tgz", + "integrity": "sha512-5wEIPpCezgORnqf+rCaYD1SK+mNN7NsstWzIsuvsnrhR/hSxXWd82oI7DkrbJ+XTD28/eG8SmxdGvukrGGK6Tw==", "dev": true, "requires": { - "@jest/core": "^29.0.3", - "@jest/types": "^29.0.3", + "@jest/core": "^29.1.2", + "@jest/types": "^29.1.2", "import-local": "^3.0.2", - "jest-cli": "^29.0.3" + "jest-cli": "^29.1.2" } }, "jest-changed-files": { @@ -17072,92 +17008,92 @@ } }, "jest-circus": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.0.3.tgz", - "integrity": "sha512-QeGzagC6Hw5pP+df1+aoF8+FBSgkPmraC1UdkeunWh0jmrp7wC0Hr6umdUAOELBQmxtKAOMNC3KAdjmCds92Zg==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.1.2.tgz", + "integrity": "sha512-ajQOdxY6mT9GtnfJRZBRYS7toNIJayiiyjDyoZcnvPRUPwJ58JX0ci0PKAKUo2C1RyzlHw0jabjLGKksO42JGA==", "dev": true, "requires": { - "@jest/environment": "^29.0.3", - "@jest/expect": "^29.0.3", - "@jest/test-result": "^29.0.3", - "@jest/types": "^29.0.3", + "@jest/environment": "^29.1.2", + "@jest/expect": "^29.1.2", + "@jest/test-result": "^29.1.2", + "@jest/types": "^29.1.2", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", "dedent": "^0.7.0", "is-generator-fn": "^2.0.0", - "jest-each": "^29.0.3", - "jest-matcher-utils": "^29.0.3", - "jest-message-util": "^29.0.3", - "jest-runtime": "^29.0.3", - "jest-snapshot": "^29.0.3", - "jest-util": "^29.0.3", + "jest-each": "^29.1.2", + "jest-matcher-utils": "^29.1.2", + "jest-message-util": "^29.1.2", + "jest-runtime": "^29.1.2", + "jest-snapshot": "^29.1.2", + "jest-util": "^29.1.2", "p-limit": "^3.1.0", - "pretty-format": "^29.0.3", + "pretty-format": "^29.1.2", "slash": "^3.0.0", "stack-utils": "^2.0.3" } }, "jest-cli": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.0.3.tgz", - "integrity": "sha512-aUy9Gd/Kut1z80eBzG10jAn6BgS3BoBbXyv+uXEqBJ8wnnuZ5RpNfARoskSrTIy1GY4a8f32YGuCMwibtkl9CQ==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.1.2.tgz", + "integrity": "sha512-vsvBfQ7oS2o4MJdAH+4u9z76Vw5Q8WBQF5MchDbkylNknZdrPTX1Ix7YRJyTlOWqRaS7ue/cEAn+E4V1MWyMzw==", "dev": true, "requires": { - "@jest/core": "^29.0.3", - "@jest/test-result": "^29.0.3", - "@jest/types": "^29.0.3", + "@jest/core": "^29.1.2", + "@jest/test-result": "^29.1.2", + "@jest/types": "^29.1.2", "chalk": "^4.0.0", "exit": "^0.1.2", "graceful-fs": "^4.2.9", "import-local": "^3.0.2", - "jest-config": "^29.0.3", - "jest-util": "^29.0.3", - "jest-validate": "^29.0.3", + "jest-config": "^29.1.2", + "jest-util": "^29.1.2", + "jest-validate": "^29.1.2", "prompts": "^2.0.1", "yargs": "^17.3.1" } }, "jest-config": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.0.3.tgz", - "integrity": "sha512-U5qkc82HHVYe3fNu2CRXLN4g761Na26rWKf7CjM8LlZB3In1jadEkZdMwsE37rd9RSPV0NfYaCjHdk/gu3v+Ew==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.1.2.tgz", + "integrity": "sha512-EC3Zi86HJUOz+2YWQcJYQXlf0zuBhJoeyxLM6vb6qJsVmpP7KcCP1JnyF0iaqTaXdBP8Rlwsvs7hnKWQWWLwwA==", "dev": true, "requires": { "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^29.0.3", - "@jest/types": "^29.0.3", - "babel-jest": "^29.0.3", + "@jest/test-sequencer": "^29.1.2", + "@jest/types": "^29.1.2", + "babel-jest": "^29.1.2", "chalk": "^4.0.0", "ci-info": "^3.2.0", "deepmerge": "^4.2.2", "glob": "^7.1.3", "graceful-fs": "^4.2.9", - "jest-circus": "^29.0.3", - "jest-environment-node": "^29.0.3", + "jest-circus": "^29.1.2", + "jest-environment-node": "^29.1.2", "jest-get-type": "^29.0.0", "jest-regex-util": "^29.0.0", - "jest-resolve": "^29.0.3", - "jest-runner": "^29.0.3", - "jest-util": "^29.0.3", - "jest-validate": "^29.0.3", + "jest-resolve": "^29.1.2", + "jest-runner": "^29.1.2", + "jest-util": "^29.1.2", + "jest-validate": "^29.1.2", "micromatch": "^4.0.4", "parse-json": "^5.2.0", - "pretty-format": "^29.0.3", + "pretty-format": "^29.1.2", "slash": "^3.0.0", "strip-json-comments": "^3.1.1" } }, "jest-diff": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.0.3.tgz", - "integrity": "sha512-+X/AIF5G/vX9fWK+Db9bi9BQas7M9oBME7egU7psbn4jlszLFCu0dW63UgeE6cs/GANq4fLaT+8sGHQQ0eCUfg==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.1.2.tgz", + "integrity": "sha512-4GQts0aUopVvecIT4IwD/7xsBaMhKTYoM4/njE/aVw9wpw+pIUVp8Vab/KnSzSilr84GnLBkaP3JLDnQYCKqVQ==", "dev": true, "requires": { "chalk": "^4.0.0", "diff-sequences": "^29.0.0", "jest-get-type": "^29.0.0", - "pretty-format": "^29.0.3" + "pretty-format": "^29.1.2" } }, "jest-docblock": { @@ -17170,46 +17106,46 @@ } }, "jest-each": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.0.3.tgz", - "integrity": "sha512-wILhZfESURHHBNvPMJ0lZlYZrvOQJxAo3wNHi+ycr90V7M+uGR9Gh4+4a/BmaZF0XTyZsk4OiYEf3GJN7Ltqzg==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.1.2.tgz", + "integrity": "sha512-AmTQp9b2etNeEwMyr4jc0Ql/LIX/dhbgP21gHAizya2X6rUspHn2gysMXaj6iwWuOJ2sYRgP8c1P4cXswgvS1A==", "dev": true, "requires": { - "@jest/types": "^29.0.3", + "@jest/types": "^29.1.2", "chalk": "^4.0.0", "jest-get-type": "^29.0.0", - "jest-util": "^29.0.3", - "pretty-format": "^29.0.3" + "jest-util": "^29.1.2", + "pretty-format": "^29.1.2" } }, "jest-environment-jsdom": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-29.0.3.tgz", - "integrity": "sha512-KIGvpm12c71hoYTjL4wC2c8K6KfhOHJqJtaHc1IApu5rG047YWZoEP13BlbucWfzGISBrmli8KFqdhdQEa8Wnw==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-29.1.2.tgz", + "integrity": "sha512-D+XNIKia5+uDjSMwL/G1l6N9MCb7LymKI8FpcLo7kkISjc/Sa9w+dXXEa7u1Wijo3f8sVLqfxdGqYtRhmca+Xw==", "dev": true, "requires": { - "@jest/environment": "^29.0.3", - "@jest/fake-timers": "^29.0.3", - "@jest/types": "^29.0.3", + "@jest/environment": "^29.1.2", + "@jest/fake-timers": "^29.1.2", + "@jest/types": "^29.1.2", "@types/jsdom": "^20.0.0", "@types/node": "*", - "jest-mock": "^29.0.3", - "jest-util": "^29.0.3", + "jest-mock": "^29.1.2", + "jest-util": "^29.1.2", "jsdom": "^20.0.0" } }, "jest-environment-node": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.0.3.tgz", - "integrity": "sha512-cdZqRCnmIlTXC+9vtvmfiY/40Cj6s2T0czXuq1whvQdmpzAnj4sbqVYuZ4zFHk766xTTJ+Ij3uUqkk8KCfXoyg==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.1.2.tgz", + "integrity": "sha512-C59yVbdpY8682u6k/lh8SUMDJPbOyCHOTgLVVi1USWFxtNV+J8fyIwzkg+RJIVI30EKhKiAGNxYaFr3z6eyNhQ==", "dev": true, "requires": { - "@jest/environment": "^29.0.3", - "@jest/fake-timers": "^29.0.3", - "@jest/types": "^29.0.3", + "@jest/environment": "^29.1.2", + "@jest/fake-timers": "^29.1.2", + "@jest/types": "^29.1.2", "@types/node": "*", - "jest-mock": "^29.0.3", - "jest-util": "^29.0.3" + "jest-mock": "^29.1.2", + "jest-util": "^29.1.2" } }, "jest-extended": { @@ -17229,12 +17165,12 @@ "dev": true }, "jest-haste-map": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.0.3.tgz", - "integrity": "sha512-uMqR99+GuBHo0RjRhOE4iA6LmsxEwRdgiIAQgMU/wdT2XebsLDz5obIwLZm/Psj+GwSEQhw9AfAVKGYbh2G55A==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.1.2.tgz", + "integrity": "sha512-xSjbY8/BF11Jh3hGSPfYTa/qBFrm3TPM7WU8pU93m2gqzORVLkHFWvuZmFsTEBPRKndfewXhMOuzJNHyJIZGsw==", "dev": true, "requires": { - "@jest/types": "^29.0.3", + "@jest/types": "^29.1.2", "@types/graceful-fs": "^4.1.3", "@types/node": "*", "anymatch": "^3.0.3", @@ -17242,59 +17178,60 @@ "fsevents": "^2.3.2", "graceful-fs": "^4.2.9", "jest-regex-util": "^29.0.0", - "jest-util": "^29.0.3", - "jest-worker": "^29.0.3", + "jest-util": "^29.1.2", + "jest-worker": "^29.1.2", "micromatch": "^4.0.4", "walker": "^1.0.8" } }, "jest-leak-detector": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.0.3.tgz", - "integrity": "sha512-YfW/G63dAuiuQ3QmQlh8hnqLDe25WFY3eQhuc/Ev1AGmkw5zREblTh7TCSKLoheyggu6G9gxO2hY8p9o6xbaRQ==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.1.2.tgz", + "integrity": "sha512-TG5gAZJpgmZtjb6oWxBLf2N6CfQ73iwCe6cofu/Uqv9iiAm6g502CAnGtxQaTfpHECBdVEMRBhomSXeLnoKjiQ==", "dev": true, "requires": { "jest-get-type": "^29.0.0", - "pretty-format": "^29.0.3" + "pretty-format": "^29.1.2" } }, "jest-matcher-utils": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.0.3.tgz", - "integrity": "sha512-RsR1+cZ6p1hDV4GSCQTg+9qjeotQCgkaleIKLK7dm+U4V/H2bWedU3RAtLm8+mANzZ7eDV33dMar4pejd7047w==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.1.2.tgz", + "integrity": "sha512-MV5XrD3qYSW2zZSHRRceFzqJ39B2z11Qv0KPyZYxnzDHFeYZGJlgGi0SW+IXSJfOewgJp/Km/7lpcFT+cgZypw==", "dev": true, "requires": { "chalk": "^4.0.0", - "jest-diff": "^29.0.3", + "jest-diff": "^29.1.2", "jest-get-type": "^29.0.0", - "pretty-format": "^29.0.3" + "pretty-format": "^29.1.2" } }, "jest-message-util": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.0.3.tgz", - "integrity": "sha512-7T8JiUTtDfppojosORAflABfLsLKMLkBHSWkjNQrjIltGoDzNGn7wEPOSfjqYAGTYME65esQzMJxGDjuLBKdOg==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.1.2.tgz", + "integrity": "sha512-9oJ2Os+Qh6IlxLpmvshVbGUiSkZVc2FK+uGOm6tghafnB2RyjKAxMZhtxThRMxfX1J1SOMhTn9oK3/MutRWQJQ==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.0.3", + "@jest/types": "^29.1.2", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^29.0.3", + "pretty-format": "^29.1.2", "slash": "^3.0.0", "stack-utils": "^2.0.3" } }, "jest-mock": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.0.3.tgz", - "integrity": "sha512-ort9pYowltbcrCVR43wdlqfAiFJXBx8l4uJDsD8U72LgBcetvEp+Qxj1W9ZYgMRoeAo+ov5cnAGF2B6+Oth+ww==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.1.2.tgz", + "integrity": "sha512-PFDAdjjWbjPUtQPkQufvniXIS3N9Tv7tbibePEjIIprzjgo0qQlyUiVMrT4vL8FaSJo1QXifQUOuPH3HQC/aMA==", "dev": true, "requires": { - "@jest/types": "^29.0.3", - "@types/node": "*" + "@jest/types": "^29.1.2", + "@types/node": "*", + "jest-util": "^29.1.2" } }, "jest-pnp-resolver": { @@ -17311,95 +17248,95 @@ "dev": true }, "jest-resolve": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.0.3.tgz", - "integrity": "sha512-toVkia85Y/BPAjJasTC9zIPY6MmVXQPtrCk8SmiheC4MwVFE/CMFlOtMN6jrwPMC6TtNh8+sTMllasFeu1wMPg==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.1.2.tgz", + "integrity": "sha512-7fcOr+k7UYSVRJYhSmJHIid3AnDBcLQX3VmT9OSbPWsWz1MfT7bcoerMhADKGvKCoMpOHUQaDHtQoNp/P9JMGg==", "dev": true, "requires": { "chalk": "^4.0.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.0.3", + "jest-haste-map": "^29.1.2", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.0.3", - "jest-validate": "^29.0.3", + "jest-util": "^29.1.2", + "jest-validate": "^29.1.2", "resolve": "^1.20.0", "resolve.exports": "^1.1.0", "slash": "^3.0.0" } }, "jest-resolve-dependencies": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.0.3.tgz", - "integrity": "sha512-KzuBnXqNvbuCdoJpv8EanbIGObk7vUBNt/PwQPPx2aMhlv/jaXpUJsqWYRpP/0a50faMBY7WFFP8S3/CCzwfDw==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.1.2.tgz", + "integrity": "sha512-44yYi+yHqNmH3OoWZvPgmeeiwKxhKV/0CfrzaKLSkZG9gT973PX8i+m8j6pDrTYhhHoiKfF3YUFg/6AeuHw4HQ==", "dev": true, "requires": { "jest-regex-util": "^29.0.0", - "jest-snapshot": "^29.0.3" + "jest-snapshot": "^29.1.2" } }, "jest-runner": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.0.3.tgz", - "integrity": "sha512-Usu6VlTOZlCZoNuh3b2Tv/yzDpKqtiNAetG9t3kJuHfUyVMNW7ipCCJOUojzKkjPoaN7Bl1f7Buu6PE0sGpQxw==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.1.2.tgz", + "integrity": "sha512-yy3LEWw8KuBCmg7sCGDIqKwJlULBuNIQa2eFSVgVASWdXbMYZ9H/X0tnXt70XFoGf92W2sOQDOIFAA6f2BG04Q==", "dev": true, "requires": { - "@jest/console": "^29.0.3", - "@jest/environment": "^29.0.3", - "@jest/test-result": "^29.0.3", - "@jest/transform": "^29.0.3", - "@jest/types": "^29.0.3", + "@jest/console": "^29.1.2", + "@jest/environment": "^29.1.2", + "@jest/test-result": "^29.1.2", + "@jest/transform": "^29.1.2", + "@jest/types": "^29.1.2", "@types/node": "*", "chalk": "^4.0.0", "emittery": "^0.10.2", "graceful-fs": "^4.2.9", "jest-docblock": "^29.0.0", - "jest-environment-node": "^29.0.3", - "jest-haste-map": "^29.0.3", - "jest-leak-detector": "^29.0.3", - "jest-message-util": "^29.0.3", - "jest-resolve": "^29.0.3", - "jest-runtime": "^29.0.3", - "jest-util": "^29.0.3", - "jest-watcher": "^29.0.3", - "jest-worker": "^29.0.3", + "jest-environment-node": "^29.1.2", + "jest-haste-map": "^29.1.2", + "jest-leak-detector": "^29.1.2", + "jest-message-util": "^29.1.2", + "jest-resolve": "^29.1.2", + "jest-runtime": "^29.1.2", + "jest-util": "^29.1.2", + "jest-watcher": "^29.1.2", + "jest-worker": "^29.1.2", "p-limit": "^3.1.0", "source-map-support": "0.5.13" } }, "jest-runtime": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.0.3.tgz", - "integrity": "sha512-12gZXRQ7ozEeEHKTY45a+YLqzNDR/x4c//X6AqwKwKJPpWM8FY4vwn4VQJOcLRS3Nd1fWwgP7LU4SoynhuUMHQ==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.1.2.tgz", + "integrity": "sha512-jr8VJLIf+cYc+8hbrpt412n5jX3tiXmpPSYTGnwcvNemY+EOuLNiYnHJ3Kp25rkaAcTWOEI4ZdOIQcwYcXIAZw==", "dev": true, "requires": { - "@jest/environment": "^29.0.3", - "@jest/fake-timers": "^29.0.3", - "@jest/globals": "^29.0.3", + "@jest/environment": "^29.1.2", + "@jest/fake-timers": "^29.1.2", + "@jest/globals": "^29.1.2", "@jest/source-map": "^29.0.0", - "@jest/test-result": "^29.0.3", - "@jest/transform": "^29.0.3", - "@jest/types": "^29.0.3", + "@jest/test-result": "^29.1.2", + "@jest/transform": "^29.1.2", + "@jest/types": "^29.1.2", "@types/node": "*", "chalk": "^4.0.0", "cjs-module-lexer": "^1.0.0", "collect-v8-coverage": "^1.0.0", "glob": "^7.1.3", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.0.3", - "jest-message-util": "^29.0.3", - "jest-mock": "^29.0.3", + "jest-haste-map": "^29.1.2", + "jest-message-util": "^29.1.2", + "jest-mock": "^29.1.2", "jest-regex-util": "^29.0.0", - "jest-resolve": "^29.0.3", - "jest-snapshot": "^29.0.3", - "jest-util": "^29.0.3", + "jest-resolve": "^29.1.2", + "jest-snapshot": "^29.1.2", + "jest-util": "^29.1.2", "slash": "^3.0.0", "strip-bom": "^4.0.0" } }, "jest-snapshot": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.0.3.tgz", - "integrity": "sha512-52q6JChm04U3deq+mkQ7R/7uy7YyfVIrebMi6ZkBoDJ85yEjm/sJwdr1P0LOIEHmpyLlXrxy3QP0Zf5J2kj0ew==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.1.2.tgz", + "integrity": "sha512-rYFomGpVMdBlfwTYxkUp3sjD6usptvZcONFYNqVlaz4EpHPnDvlWjvmOQ9OCSNKqYZqLM2aS3wq01tWujLg7gg==", "dev": true, "requires": { "@babel/core": "^7.11.6", @@ -17408,33 +17345,33 @@ "@babel/plugin-syntax-typescript": "^7.7.2", "@babel/traverse": "^7.7.2", "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.0.3", - "@jest/transform": "^29.0.3", - "@jest/types": "^29.0.3", + "@jest/expect-utils": "^29.1.2", + "@jest/transform": "^29.1.2", + "@jest/types": "^29.1.2", "@types/babel__traverse": "^7.0.6", "@types/prettier": "^2.1.5", "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^29.0.3", + "expect": "^29.1.2", "graceful-fs": "^4.2.9", - "jest-diff": "^29.0.3", + "jest-diff": "^29.1.2", "jest-get-type": "^29.0.0", - "jest-haste-map": "^29.0.3", - "jest-matcher-utils": "^29.0.3", - "jest-message-util": "^29.0.3", - "jest-util": "^29.0.3", + "jest-haste-map": "^29.1.2", + "jest-matcher-utils": "^29.1.2", + "jest-message-util": "^29.1.2", + "jest-util": "^29.1.2", "natural-compare": "^1.4.0", - "pretty-format": "^29.0.3", + "pretty-format": "^29.1.2", "semver": "^7.3.5" } }, "jest-util": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.0.3.tgz", - "integrity": "sha512-Q0xaG3YRG8QiTC4R6fHjHQPaPpz9pJBEi0AeOE4mQh/FuWOijFjGXMMOfQEaU9i3z76cNR7FobZZUQnL6IyfdQ==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.1.2.tgz", + "integrity": "sha512-vPCk9F353i0Ymx3WQq3+a4lZ07NXu9Ca8wya6o4Fe4/aO1e1awMMprZ3woPFpKwghEOW+UXgd15vVotuNN9ONQ==", "dev": true, "requires": { - "@jest/types": "^29.0.3", + "@jest/types": "^29.1.2", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -17443,17 +17380,17 @@ } }, "jest-validate": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.0.3.tgz", - "integrity": "sha512-OebiqqT6lK8cbMPtrSoS3aZP4juID762lZvpf1u+smZnwTEBCBInan0GAIIhv36MxGaJvmq5uJm7dl5gVt+Zrw==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.1.2.tgz", + "integrity": "sha512-k71pOslNlV8fVyI+mEySy2pq9KdXdgZtm7NHrBX8LghJayc3wWZH0Yr0mtYNGaCU4F1OLPXRkwZR0dBm/ClshA==", "dev": true, "requires": { - "@jest/types": "^29.0.3", + "@jest/types": "^29.1.2", "camelcase": "^6.2.0", "chalk": "^4.0.0", "jest-get-type": "^29.0.0", "leven": "^3.1.0", - "pretty-format": "^29.0.3" + "pretty-format": "^29.1.2" }, "dependencies": { "camelcase": { @@ -17465,28 +17402,29 @@ } }, "jest-watcher": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.0.3.tgz", - "integrity": "sha512-tQX9lU91A+9tyUQKUMp0Ns8xAcdhC9fo73eqA3LFxP2bSgiF49TNcc+vf3qgGYYK9qRjFpXW9+4RgF/mbxyOOw==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.1.2.tgz", + "integrity": "sha512-6JUIUKVdAvcxC6bM8/dMgqY2N4lbT+jZVsxh0hCJRbwkIEnbr/aPjMQ28fNDI5lB51Klh00MWZZeVf27KBUj5w==", "dev": true, "requires": { - "@jest/test-result": "^29.0.3", - "@jest/types": "^29.0.3", + "@jest/test-result": "^29.1.2", + "@jest/types": "^29.1.2", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "emittery": "^0.10.2", - "jest-util": "^29.0.3", + "jest-util": "^29.1.2", "string-length": "^4.0.1" } }, "jest-worker": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.0.3.tgz", - "integrity": "sha512-Tl/YWUugQOjoTYwjKdfJWkSOfhufJHO5LhXTSZC3TRoQKO+fuXnZAdoXXBlpLXKGODBL3OvdUasfDD4PcMe6ng==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.1.2.tgz", + "integrity": "sha512-AdTZJxKjTSPHbXT/AIOjQVmoFx0LHFcVabWu0sxI7PAy7rFf8c0upyvgBKgguVXdM4vY74JdwkyD4hSmpTW8jA==", "dev": true, "requires": { "@types/node": "*", + "jest-util": "^29.1.2", "merge-stream": "^2.0.0", "supports-color": "^8.0.0" }, @@ -17520,6 +17458,12 @@ "jquery": ">=1.4.2" } }, + "js-sdsl": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.5.tgz", + "integrity": "sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q==", + "dev": true + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -17536,18 +17480,18 @@ } }, "jsdom": { - "version": "20.0.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.0.tgz", - "integrity": "sha512-x4a6CKCgx00uCmP+QakBDFXwjAJ69IkkIWHmtmjd3wvXPcdOS44hfX2vqkOQrVrq8l9DhNNADZRXaCEWvgXtVA==", + "version": "20.0.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.1.tgz", + "integrity": "sha512-pksjj7Rqoa+wdpkKcLzQRHhJCEE42qQhl/xLMUKHgoSejaKOdaXEAnqs6uDNwMl/fciHTzKeR8Wm8cw7N+g98A==", "dev": true, "requires": { "abab": "^2.0.6", - "acorn": "^8.7.1", - "acorn-globals": "^6.0.0", + "acorn": "^8.8.0", + "acorn-globals": "^7.0.0", "cssom": "^0.5.0", "cssstyle": "^2.3.0", "data-urls": "^3.0.2", - "decimal.js": "^10.3.1", + "decimal.js": "^10.4.1", "domexception": "^4.0.0", "escodegen": "^2.0.0", "form-data": "^4.0.0", @@ -17555,25 +17499,24 @@ "http-proxy-agent": "^5.0.0", "https-proxy-agent": "^5.0.1", "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.0", - "parse5": "^7.0.0", + "nwsapi": "^2.2.2", + "parse5": "^7.1.1", "saxes": "^6.0.0", "symbol-tree": "^3.2.4", - "tough-cookie": "^4.0.0", - "w3c-hr-time": "^1.0.2", + "tough-cookie": "^4.1.2", "w3c-xmlserializer": "^3.0.0", "webidl-conversions": "^7.0.0", "whatwg-encoding": "^2.0.0", "whatwg-mimetype": "^3.0.0", "whatwg-url": "^11.0.0", - "ws": "^8.8.0", + "ws": "^8.9.0", "xml-name-validator": "^4.0.0" } }, "jsep": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/jsep/-/jsep-1.3.6.tgz", - "integrity": "sha512-o7fP1eZVROIChADx7HKiwGRVI0tUqgUUGhaok6DP7cMxpDeparuooREDBDeNk2G5KIB49MBSkRYsCOu4PmZ+1w==", + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/jsep/-/jsep-1.3.7.tgz", + "integrity": "sha512-NFbZTr1t13fPKw53swmZFKwBkEDWDnno7uLJk+a+Rw9tGDTkGgnGdZJ8A/o3gR1+XaAXmSsbpfIBIBgqRBZWDA==", "dev": true }, "jsesc": { @@ -17641,13 +17584,6 @@ "integrity": "sha512-70DJdQAyh9EMsthw3AaQlDyFf54X7nWEUIa5W+rq8XOpEk//w5Th7/8SqFqpvi/KZ2t6MHUj4f9wLmztBmAYQA==", "requires": { "commander": "^8.0.0" - }, - "dependencies": { - "commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==" - } } }, "khroma": { @@ -17713,9 +17649,9 @@ } }, "less-loader": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-11.0.0.tgz", - "integrity": "sha512-9+LOWWjuoectIEx3zrfN83NAGxSUB5pWEabbbidVQVgZhN+wN68pOvuyirVlH1IK4VT1f3TmlyvAnCXh8O5KEw==", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-11.1.0.tgz", + "integrity": "sha512-C+uDBV7kS7W5fJlUjq5mPBeBVhYpTIm5gB09APT9o3n/ILeaXVsiSFTbZpTJCJwQ/Crczfn3DmfQFwxYusWFug==", "requires": { "klona": "^2.0.4" } @@ -17972,6 +17908,12 @@ "balanced-match": "^1.0.0" } }, + "commander": { + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.4.1.tgz", + "integrity": "sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==", + "dev": true + }, "glob": { "version": "8.0.3", "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", @@ -18009,9 +17951,9 @@ "dev": true }, "marked": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/marked/-/marked-4.1.0.tgz", - "integrity": "sha512-+Z6KDjSPa6/723PQYyc1axYZpYYpDnECDaU6hkaf5gqBieBkMKYReL5hteF2QizhlMbgbo8umXl/clZ67+GlsA==" + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.1.1.tgz", + "integrity": "sha512-0cNMnTcUJPxbA6uWmCmjWz4NJRe/0Xfk2NhXCUHjew9qJzFN20krFnsUe7QynwqOwa5m1fZ4UDg0ycKFVC0ccw==" }, "mathml-tag-names": { "version": "2.1.3", @@ -18106,15 +18048,15 @@ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" }, "mermaid": { - "version": "9.1.6", - "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-9.1.6.tgz", - "integrity": "sha512-oBuQk7s55wQgEgH/AK0GYY8U0kBqOIGK9QlJL+VYxh+1kZQtU9tNwoy0gWCfBJDaFIRdfpc/fm9PagaIXg6XFQ==", + "version": "9.1.7", + "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-9.1.7.tgz", + "integrity": "sha512-MRVHXy5FLjnUQUG7YS3UN9jEN6FXCJbFCXVGJQjVIbiR6Vhw0j/6pLIjqsiah9xoHmQU6DEaKOvB3S1g/1nBPA==", "requires": { "@braintree/sanitize-url": "^6.0.0", "d3": "^7.0.0", "dagre": "^0.8.5", "dagre-d3": "^0.6.4", - "dompurify": "2.3.10", + "dompurify": "2.4.0", "graphlib": "^2.1.8", "khroma": "^2.0.0", "moment-mini": "2.24.0", @@ -18660,9 +18602,9 @@ } }, "playwright-core": { - "version": "1.25.2", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.25.2.tgz", - "integrity": "sha512-0yTbUE9lIddkEpLHL3u8PoCL+pWiZtj5A/j3U7YoNjcmKKDGBnCrgHJMzwd2J5vy6l28q4ki3JIuz7McLHhl1A==", + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.27.0.tgz", + "integrity": "sha512-VBKaaFUVKDo3akW+o4DwbK1ZyXh46tcSwQKPK3lruh8IJd5feu55XVZx4vOkbb2uqrNdIF51sgsadYT533SdpA==", "dev": true }, "pluralize": { @@ -18678,9 +18620,9 @@ "dev": true }, "postcss": { - "version": "8.4.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.16.tgz", - "integrity": "sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ==", + "version": "8.4.17", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.17.tgz", + "integrity": "sha512-UNxNOLQydcOFi41yHNMcKRZ39NeXlr8AxGuZJsdub8vIb12fHzcq37DTU/QtbI6WLxNg2gF9Z+8qtRwTj1UI1Q==", "requires": { "nanoid": "^3.3.4", "picocolors": "^1.0.0", @@ -18766,9 +18708,9 @@ "dev": true }, "pretty-format": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.0.3.tgz", - "integrity": "sha512-cHudsvQr1K5vNVLbvYF/nv3Qy/F/BcEKxGuIeMiVMRHxPOO1RxXooP8g/ZrwAp7Dx+KdMZoOc7NxLHhMrP2f9Q==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.1.2.tgz", + "integrity": "sha512-CGJ6VVGXVRP2o2Dorl4mAwwvDWT25luIsYhkyVQW32E4nL+TgW939J7LlKT/npq5Cpq6j3s+sy+13yk7xYpBmg==", "dev": true, "requires": { "@jest/schemas": "^29.0.0", @@ -19129,9 +19071,9 @@ "integrity": "sha512-ndEIpszUHiG4HtDsQLeIuMvRsDnn8c8rYStabochtUeCvfuvNptb5TUbVD68LRAILPX7p9nqQGh4xJgn3EHS/g==" }, "rollup": { - "version": "2.79.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.0.tgz", - "integrity": "sha512-x4KsrCgwQ7ZJPcFA/SUu6QVcYlO7uRLfLAy0DSA4NS2eG8japdbpM50ToH7z4iObodRYOJ0soneF0iaQRJ6zhA==", + "version": "2.79.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", + "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", "dev": true, "requires": { "fsevents": "~2.3.2" @@ -19176,6 +19118,17 @@ "regexp-tree": "~0.1.1" } }, + "safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + } + }, "safe-stable-stringify": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-1.1.1.tgz", @@ -19214,9 +19167,9 @@ } }, "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "requires": { "lru-cache": "^6.0.0" }, @@ -19327,9 +19280,9 @@ "dev": true }, "socks": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.0.tgz", - "integrity": "sha512-scnOe9y4VuiNUULJN72GrM26BNOjVsfPXI+j+98PkyEfsIXroa5ofyjT+FzGvn/xHs73U2JtoBYAVx9Hl4quSA==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", + "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", "dev": true, "requires": { "ip": "^2.0.0", @@ -19587,9 +19540,9 @@ "dev": true }, "stylelint": { - "version": "14.11.0", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-14.11.0.tgz", - "integrity": "sha512-OTLjLPxpvGtojEfpESWM8Ir64Z01E89xsisaBMUP/ngOx1+4VG2DPRcUyCCiin9Rd3kPXPsh/uwHd9eqnvhsYA==", + "version": "14.13.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-14.13.0.tgz", + "integrity": "sha512-NJSAdloiAB/jgVJKxMR90mWlctvmeBFGFVUvyKngi9+j/qPSJ5ZB+u8jOmGbLTnS7OHrII9NFGehPRyar8U5vg==", "dev": true, "requires": { "@csstools/selector-specificity": "^2.0.2", @@ -19598,7 +19551,7 @@ "cosmiconfig": "^7.0.1", "css-functions-list": "^3.1.0", "debug": "^4.3.4", - "fast-glob": "^3.2.11", + "fast-glob": "^3.2.12", "fastest-levenshtein": "^1.0.16", "file-entry-cache": "^6.0.1", "global-modules": "^2.0.0", @@ -19625,7 +19578,7 @@ "string-width": "^4.2.3", "strip-ansi": "^6.0.1", "style-search": "^0.1.0", - "supports-hyperlinks": "^2.2.0", + "supports-hyperlinks": "^2.3.0", "svg-tags": "^1.0.0", "table": "^6.8.0", "v8-compile-cache": "^2.3.0", @@ -19725,9 +19678,9 @@ } }, "swagger-ui-dist": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-4.14.0.tgz", - "integrity": "sha512-TBzhheU15s+o54Cgk9qxuYcZMiqSm/SkvKnapoGHOF66kz0Y5aGjpzj5BT/vpBbn6rTPJ9tUYXQxuDWfsjiGMw==" + "version": "4.14.2", + "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-4.14.2.tgz", + "integrity": "sha512-kOIU7Ts3TrXDLb3/c9jRe4qGp8O3bRT19FFJA8wJfrRFkcK/4atPn3krhtBVJ57ZkNNofworXHxuYwmaisXBdg==" }, "symbol-tree": { "version": "3.2.4", @@ -19764,9 +19717,9 @@ } }, "terser": { - "version": "5.15.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.15.0.tgz", - "integrity": "sha512-L1BJiXVmheAQQy+as0oF3Pwtlo4s3Wi1X2zNZ2NxOB4wx9bdS9Vk67XQENLFdLYGCK/Z2di53mTj/hBafR+dTA==", + "version": "5.15.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.15.1.tgz", + "integrity": "sha512-K1faMUvpm/FBxjBXud0LWVAGxmvoPbZbfTCYbSgaaYQaIXI3/TdI7a7ZGA73Zrou6Q8Zmz3oeUTsp/dj+ag2Xw==", "requires": { "@jridgewell/source-map": "^0.3.2", "acorn": "^8.5.0", @@ -20041,18 +19994,18 @@ "dev": true }, "update-browserslist-db": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.7.tgz", - "integrity": "sha512-iN/XYesmZ2RmmWAiI4Z5rq0YqSiv0brj9Ce9CfhNE4xIW2h+MFxcgkxIzZ+ShkFPUkjU3gQ+3oypadD3RAMtrg==", + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", "requires": { "escalade": "^3.1.1", "picocolors": "^1.0.0" } }, "updates": { - "version": "13.1.5", - "resolved": "https://registry.npmjs.org/updates/-/updates-13.1.5.tgz", - "integrity": "sha512-7WPn2P8WskugozCdhMI+D1m9OmJnzZqRUuDYM2G8O55TuyvfqOT2vdR2+InkpXUyK6ZNmbLopvw++h9YQElbmg==", + "version": "13.1.8", + "resolved": "https://registry.npmjs.org/updates/-/updates-13.1.8.tgz", + "integrity": "sha512-hcDCkif1i4MWArx1QkJjLHyPCr8taYyzoypQ7ST/vbmNJyH/cpiawQf+5frvH5uekiSSwtuQNWKdFWB3UH4sew==", "dev": true }, "uri-js": { @@ -20134,26 +20087,18 @@ "requires": { "acorn": "^8.7.0", "acorn-walk": "^8.2.0" - }, - "dependencies": { - "acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true - } } }, "vue": { - "version": "3.2.37", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.37.tgz", - "integrity": "sha512-bOKEZxrm8Eh+fveCqS1/NkG/n6aMidsI6hahas7pa0w/l7jkbssJVsRhVDs07IdDq7h9KHswZOgItnwJAgtVtQ==", + "version": "3.2.40", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.40.tgz", + "integrity": "sha512-1mGHulzUbl2Nk3pfvI5aXYYyJUs1nm4kyvuz38u4xlQkLUn1i2R7nDbI4TufECmY8v1qNBHYy62bCaM+3cHP2A==", "requires": { - "@vue/compiler-dom": "3.2.37", - "@vue/compiler-sfc": "3.2.37", - "@vue/runtime-dom": "3.2.37", - "@vue/server-renderer": "3.2.37", - "@vue/shared": "3.2.37" + "@vue/compiler-dom": "3.2.40", + "@vue/compiler-sfc": "3.2.40", + "@vue/runtime-dom": "3.2.40", + "@vue/server-renderer": "3.2.40", + "@vue/shared": "3.2.40" } }, "vue-bar-graph": { @@ -20198,15 +20143,6 @@ "tippy.js": "^6.3.7" } }, - "w3c-hr-time": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", - "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", - "dev": true, - "requires": { - "browser-process-hrtime": "^1.0.0" - } - }, "w3c-xmlserializer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-3.0.0.tgz", @@ -20424,12 +20360,6 @@ "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==" }, - "wolfy87-eventemitter": { - "version": "5.2.9", - "resolved": "https://registry.npmjs.org/wolfy87-eventemitter/-/wolfy87-eventemitter-5.2.9.tgz", - "integrity": "sha512-P+6vtWyuDw+MB01X7UeF8TaHBvbCovf4HPEMF/SV7BdDc1SMTiBy13SRD71lQh4ExFTG1d/WNzDGDCyOKSMblw==", - "dev": true - }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -20561,9 +20491,9 @@ } }, "ws": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.8.1.tgz", - "integrity": "sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA==", + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.9.0.tgz", + "integrity": "sha512-Ja7nszREasGaYUYCI2k4lCKIRTt+y7XuqVoHR44YpI49TtryyqbqvDMn5eqfW7e6HzTukDRIsXqzVHScqRcafg==", "dev": true, "requires": {} }, diff --git a/package.json b/package.json index c7add76aae..599c77287c 100644 --- a/package.json +++ b/package.json @@ -8,13 +8,13 @@ }, "dependencies": { "@claviska/jquery-minicolors": "2.3.6", - "@mcaptcha/vanilla-glue": "0.1.0-alpha-2", - "@primer/octicons": "17.5.0", - "@vue/compiler-sfc": "3.2.37", + "@mcaptcha/vanilla-glue": "0.1.0-alpha-3", + "@primer/octicons": "17.7.0", + "@vue/compiler-sfc": "3.2.40", "add-asset-webpack-plugin": "2.0.1", "css-loader": "6.7.1", "dropzone": "6.0.0-beta.2", - "easymde": "2.17.0", + "easymde": "2.18.0", "esbuild-loader": "2.20.0", "escape-goat": "4.0.0", "fast-glob": "3.2.12", @@ -23,19 +23,19 @@ "jquery.are-you-sure": "1.9.0", "katex": "0.16.2", "less": "4.1.3", - "less-loader": "11.0.0", + "less-loader": "11.1.0", "license-checker-webpack-plugin": "0.2.1", - "mermaid": "9.1.6", + "mermaid": "9.1.7", "mini-css-extract-plugin": "2.6.1", "monaco-editor": "0.34.0", "monaco-editor-webpack-plugin": "7.0.1", "pretty-ms": "8.0.0", "sortablejs": "1.15.0", - "swagger-ui-dist": "4.14.0", + "swagger-ui-dist": "4.14.2", "tippy.js": "6.3.7", "tributejs": "5.1.3", "uint8-to-base64": "0.2.0", - "vue": "3.2.37", + "vue": "3.2.40", "vue-bar-graph": "2.0.0", "vue-loader": "17.0.0", "vue3-calendar-heatmap": "2.0.0", @@ -47,23 +47,23 @@ "wrap-ansi": "8.0.1" }, "devDependencies": { - "@playwright/test": "1.25.2", + "@playwright/test": "1.27.0", "@stoplight/spectral-cli": "6.5.1", - "eslint": "8.23.0", + "eslint": "8.25.0", "eslint-plugin-import": "2.26.0", "eslint-plugin-jquery": "1.5.1", "eslint-plugin-sonarjs": "0.15.0", - "eslint-plugin-unicorn": "43.0.2", - "eslint-plugin-vue": "9.4.0", - "jest": "29.0.3", - "jest-environment-jsdom": "29.0.3", + "eslint-plugin-unicorn": "44.0.2", + "eslint-plugin-vue": "9.6.0", + "jest": "29.1.2", + "jest-environment-jsdom": "29.1.2", "jest-extended": "3.1.0", "markdownlint-cli": "0.32.2", "postcss-less": "6.0.0", - "stylelint": "14.11.0", + "stylelint": "14.13.0", "stylelint-config-standard": "28.0.0", "svgo": "2.8.0", - "updates": "13.1.5" + "updates": "13.1.8" }, "browserslist": [ "defaults", diff --git a/playwright.config.js b/playwright.config.js index af67717a2d..b7badf1cc0 100644 --- a/playwright.config.js +++ b/playwright.config.js @@ -24,7 +24,7 @@ export default { }, /* Fail the build on CI if you accidentally left test.only in the source code. */ - forbidOnly: !!process.env.CI, + forbidOnly: Boolean(process.env.CI), /* Retry on CI only */ retries: process.env.CI ? 2 : 0, @@ -64,12 +64,13 @@ export default { }, }, - { - name: 'firefox', - use: { - ...devices['Desktop Firefox'], - }, - }, + // disabled because of https://github.com/go-gitea/gitea/issues/21355 + // { + // name: 'firefox', + // use: { + // ...devices['Desktop Firefox'], + // }, + // }, { name: 'webkit', diff --git a/public/img/svg/octicon-alert-fill.svg b/public/img/svg/octicon-alert-fill.svg new file mode 100644 index 0000000000..34795cfbe4 --- /dev/null +++ b/public/img/svg/octicon-alert-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/routers/api/packages/api.go b/routers/api/packages/api.go index 3354fe12d4..a54add0621 100644 --- a/routers/api/packages/api.go +++ b/routers/api/packages/api.go @@ -196,7 +196,7 @@ func Routes(ctx gocontext.Context) *web.Route { r.Put("/symbolpackage", nuget.UploadSymbolPackage) r.Delete("/{id}/{version}", nuget.DeletePackage) }, reqPackageAccess(perm.AccessModeWrite)) - r.Get("/symbols/{filename}/{guid:[0-9a-f]{32}}FFFFFFFF/{filename2}", nuget.DownloadSymbolFile) + r.Get("/symbols/{filename}/{guid:[0-9a-fA-F]{32}[fF]{8}}/{filename2}", nuget.DownloadSymbolFile) }, reqPackageAccess(perm.AccessModeRead)) }) r.Group("/npm", func() { @@ -316,8 +316,10 @@ func ContainerRoutes(ctx gocontext.Context) *web.Route { r.Group("/blobs/uploads", func() { r.Post("", container.InitiateUploadBlob) r.Group("/{uuid}", func() { + r.Get("", container.GetUploadBlob) r.Patch("", container.UploadBlob) r.Put("", container.EndUploadBlob) + r.Delete("", container.CancelUploadBlob) }) }, reqPackageAccess(perm.AccessModeWrite)) r.Group("/blobs/{digest}", func() { @@ -377,7 +379,7 @@ func ContainerRoutes(ctx gocontext.Context) *web.Route { } m := blobsUploadsPattern.FindStringSubmatch(path) - if len(m) == 3 && (isPut || isPatch) { + if len(m) == 3 && (isGet || isPut || isPatch || isDelete) { reqPackageAccess(perm.AccessModeWrite)(ctx) if ctx.Written() { return @@ -391,10 +393,14 @@ func ContainerRoutes(ctx gocontext.Context) *web.Route { ctx.SetParams("uuid", m[2]) - if isPatch { + if isGet { + container.GetUploadBlob(ctx) + } else if isPatch { container.UploadBlob(ctx) - } else { + } else if isPut { container.EndUploadBlob(ctx) + } else { + container.CancelUploadBlob(ctx) } return } diff --git a/routers/api/packages/conan/conan.go b/routers/api/packages/conan/conan.go index 90924c7c4b..dd078d6ad3 100644 --- a/routers/api/packages/conan/conan.go +++ b/routers/api/packages/conan/conan.go @@ -14,6 +14,7 @@ import ( "code.gitea.io/gitea/models/db" packages_model "code.gitea.io/gitea/models/packages" conan_model "code.gitea.io/gitea/models/packages/conan" + "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/log" @@ -33,20 +34,18 @@ const ( packageReferenceKey = "PackageReference" ) -type stringSet map[string]struct{} - var ( - recipeFileList = stringSet{ - conanfileFile: struct{}{}, - "conanmanifest.txt": struct{}{}, - "conan_sources.tgz": struct{}{}, - "conan_export.tgz": struct{}{}, - } - packageFileList = stringSet{ - conaninfoFile: struct{}{}, - "conanmanifest.txt": struct{}{}, - "conan_package.tgz": struct{}{}, - } + recipeFileList = container.SetOf( + conanfileFile, + "conanmanifest.txt", + "conan_sources.tgz", + "conan_export.tgz", + ) + packageFileList = container.SetOf( + conaninfoFile, + "conanmanifest.txt", + "conan_package.tgz", + ) ) func jsonResponse(ctx *context.Context, status int, obj interface{}) { @@ -268,7 +267,7 @@ func PackageUploadURLs(ctx *context.Context) { ) } -func serveUploadURLs(ctx *context.Context, fileFilter stringSet, uploadURL string) { +func serveUploadURLs(ctx *context.Context, fileFilter container.Set[string], uploadURL string) { defer ctx.Req.Body.Close() var files map[string]int64 @@ -279,7 +278,7 @@ func serveUploadURLs(ctx *context.Context, fileFilter stringSet, uploadURL strin urls := make(map[string]string) for file := range files { - if _, ok := fileFilter[file]; ok { + if fileFilter.Contains(file) { urls[file] = fmt.Sprintf("%s/%s", uploadURL, file) } } @@ -301,12 +300,12 @@ func UploadPackageFile(ctx *context.Context) { uploadFile(ctx, packageFileList, pref.AsKey()) } -func uploadFile(ctx *context.Context, fileFilter stringSet, fileKey string) { +func uploadFile(ctx *context.Context, fileFilter container.Set[string], fileKey string) { rref := ctx.Data[recipeReferenceKey].(*conan_module.RecipeReference) pref := ctx.Data[packageReferenceKey].(*conan_module.PackageReference) filename := ctx.Params("filename") - if _, ok := fileFilter[filename]; !ok { + if !fileFilter.Contains(filename) { apiError(ctx, http.StatusBadRequest, nil) return } @@ -342,8 +341,7 @@ func uploadFile(ctx *context.Context, fileFilter stringSet, fileKey string) { Name: rref.Name, Version: rref.Version, }, - SemverCompatible: true, - Creator: ctx.Doer, + Creator: ctx.Doer, } pfci := &packages_service.PackageFileCreationInfo{ PackageFileInfo: packages_service.PackageFileInfo{ @@ -443,11 +441,11 @@ func DownloadPackageFile(ctx *context.Context) { downloadFile(ctx, packageFileList, pref.AsKey()) } -func downloadFile(ctx *context.Context, fileFilter stringSet, fileKey string) { +func downloadFile(ctx *context.Context, fileFilter container.Set[string], fileKey string) { rref := ctx.Data[recipeReferenceKey].(*conan_module.RecipeReference) filename := ctx.Params("filename") - if _, ok := fileFilter[filename]; !ok { + if !fileFilter.Contains(filename) { apiError(ctx, http.StatusBadRequest, nil) return } diff --git a/routers/api/packages/container/container.go b/routers/api/packages/container/container.go index b961cd4afb..5bc64e1b29 100644 --- a/routers/api/packages/container/container.go +++ b/routers/api/packages/container/container.go @@ -248,6 +248,27 @@ func InitiateUploadBlob(ctx *context.Context) { }) } +// https://docs.docker.com/registry/spec/api/#get-blob-upload +func GetUploadBlob(ctx *context.Context) { + uuid := ctx.Params("uuid") + + upload, err := packages_model.GetBlobUploadByID(ctx, uuid) + if err != nil { + if err == packages_model.ErrPackageBlobUploadNotExist { + apiErrorDefined(ctx, errBlobUploadUnknown) + } else { + apiError(ctx, http.StatusInternalServerError, err) + } + return + } + + setResponseHeaders(ctx.Resp, &containerHeaders{ + Range: fmt.Sprintf("0-%d", upload.BytesReceived), + UploadUUID: upload.ID, + Status: http.StatusNoContent, + }) +} + // https://github.com/opencontainers/distribution-spec/blob/main/spec.md#pushing-a-blob-in-chunks func UploadBlob(ctx *context.Context) { image := ctx.Params("image") @@ -354,6 +375,30 @@ func EndUploadBlob(ctx *context.Context) { }) } +// https://docs.docker.com/registry/spec/api/#delete-blob-upload +func CancelUploadBlob(ctx *context.Context) { + uuid := ctx.Params("uuid") + + _, err := packages_model.GetBlobUploadByID(ctx, uuid) + if err != nil { + if err == packages_model.ErrPackageBlobUploadNotExist { + apiErrorDefined(ctx, errBlobUploadUnknown) + } else { + apiError(ctx, http.StatusInternalServerError, err) + } + return + } + + if err := container_service.RemoveBlobUploadByID(ctx, uuid); err != nil { + apiError(ctx, http.StatusInternalServerError, err) + return + } + + setResponseHeaders(ctx.Resp, &containerHeaders{ + Status: http.StatusNoContent, + }) +} + func getBlobFromContext(ctx *context.Context) (*packages_model.PackageFileDescriptor, error) { digest := ctx.Params("digest") diff --git a/routers/api/packages/npm/api.go b/routers/api/packages/npm/api.go index d1027763a8..490387a0e4 100644 --- a/routers/api/packages/npm/api.go +++ b/routers/api/packages/npm/api.go @@ -67,6 +67,7 @@ func createPackageMetadataVersion(registryURL string, pd *packages_model.Package PeerDependencies: metadata.PeerDependencies, OptionalDependencies: metadata.OptionalDependencies, Readme: metadata.Readme, + Bin: metadata.Bin, Dist: npm_module.PackageDistribution{ Shasum: pd.Files[0].Blob.HashSHA1, Integrity: "sha512-" + base64.StdEncoding.EncodeToString(hashBytes), diff --git a/routers/api/packages/nuget/nuget.go b/routers/api/packages/nuget/nuget.go index eadf7486a5..3c61ae28bb 100644 --- a/routers/api/packages/nuget/nuget.go +++ b/routers/api/packages/nuget/nuget.go @@ -353,7 +353,7 @@ func processUploadedFile(ctx *context.Context, expectedType nuget_module.Package // DownloadSymbolFile https://github.com/dotnet/symstore/blob/main/docs/specs/Simple_Symbol_Query_Protocol.md#request func DownloadSymbolFile(ctx *context.Context) { filename := ctx.Params("filename") - guid := ctx.Params("guid") + guid := ctx.Params("guid")[:32] filename2 := ctx.Params("filename2") if filename != filename2 { diff --git a/routers/api/v1/repo/commits.go b/routers/api/v1/repo/commits.go index 12c329c203..4e77c3f2f5 100644 --- a/routers/api/v1/repo/commits.go +++ b/routers/api/v1/repo/commits.go @@ -70,7 +70,7 @@ func getCommit(ctx *context.APIContext, identifier string) { return } - json, err := convert.ToCommit(ctx.Repo.Repository, ctx.Repo.GitRepo, commit, nil) + json, err := convert.ToCommit(ctx.Repo.Repository, ctx.Repo.GitRepo, commit, nil, true) if err != nil { ctx.Error(http.StatusInternalServerError, "toCommit", err) return @@ -104,6 +104,10 @@ func GetAllCommits(ctx *context.APIContext) { // in: query // description: filepath of a file/dir // type: string + // - name: stat + // in: query + // description: include diff stats for every commit (disable for speedup, default 'true') + // type: boolean // - name: page // in: query // description: page number of results to return (1-based) @@ -209,9 +213,12 @@ func GetAllCommits(ctx *context.APIContext) { userCache := make(map[string]*user_model.User) apiCommits := make([]*api.Commit, len(commits)) + + stat := ctx.FormString("stat") == "" || ctx.FormBool("stat") + for i, commit := range commits { // Create json struct - apiCommits[i], err = convert.ToCommit(ctx.Repo.Repository, ctx.Repo.GitRepo, commit, userCache) + apiCommits[i], err = convert.ToCommit(ctx.Repo.Repository, ctx.Repo.GitRepo, commit, userCache, stat) if err != nil { ctx.Error(http.StatusInternalServerError, "toCommit", err) return diff --git a/routers/api/v1/repo/notes.go b/routers/api/v1/repo/notes.go index 67f097a424..ee3133adec 100644 --- a/routers/api/v1/repo/notes.go +++ b/routers/api/v1/repo/notes.go @@ -69,7 +69,7 @@ func getNote(ctx *context.APIContext, identifier string) { return } - cmt, err := convert.ToCommit(ctx.Repo.Repository, ctx.Repo.GitRepo, note.Commit, nil) + cmt, err := convert.ToCommit(ctx.Repo.Repository, ctx.Repo.GitRepo, note.Commit, nil, true) if err != nil { ctx.Error(http.StatusInternalServerError, "ToCommit", err) return diff --git a/routers/api/v1/repo/pull.go b/routers/api/v1/repo/pull.go index 2cf30e7c47..f6507dceba 100644 --- a/routers/api/v1/repo/pull.go +++ b/routers/api/v1/repo/pull.go @@ -1306,7 +1306,7 @@ func GetPullRequestCommits(ctx *context.APIContext) { apiCommits := make([]*api.Commit, 0, end-start) for i := start; i < end; i++ { - apiCommit, err := convert.ToCommit(ctx.Repo.Repository, baseGitRepo, commits[i], userCache) + apiCommit, err := convert.ToCommit(ctx.Repo.Repository, baseGitRepo, commits[i], userCache, true) if err != nil { ctx.ServerError("toCommit", err) return diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go index 319c4c781a..de8a4d1864 100644 --- a/routers/api/v1/repo/repo.go +++ b/routers/api/v1/repo/repo.go @@ -755,9 +755,10 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error { RepoID: repo.ID, Type: unit_model.TypeExternalTracker, Config: &repo_model.ExternalTrackerConfig{ - ExternalTrackerURL: opts.ExternalTracker.ExternalTrackerURL, - ExternalTrackerFormat: opts.ExternalTracker.ExternalTrackerFormat, - ExternalTrackerStyle: opts.ExternalTracker.ExternalTrackerStyle, + ExternalTrackerURL: opts.ExternalTracker.ExternalTrackerURL, + ExternalTrackerFormat: opts.ExternalTracker.ExternalTrackerFormat, + ExternalTrackerStyle: opts.ExternalTracker.ExternalTrackerStyle, + ExternalTrackerRegexpPattern: opts.ExternalTracker.ExternalTrackerRegexpPattern, }, }) deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeIssues) diff --git a/routers/private/internal.go b/routers/private/internal.go index e9cc20a77d..f8e451e80f 100644 --- a/routers/private/internal.go +++ b/routers/private/internal.go @@ -17,6 +17,7 @@ import ( "code.gitea.io/gitea/modules/web" "gitea.com/go-chi/binding" + chi_middleware "github.com/go-chi/chi/v5/middleware" ) // CheckInternalToken check internal token is set @@ -57,6 +58,9 @@ func Routes() *web.Route { r := web.NewRoute() r.Use(context.PrivateContexter()) r.Use(CheckInternalToken) + // Log the real ip address of the request from SSH is really helpful for diagnosing sometimes. + // Since internal API will be sent only from Gitea sub commands and it's under control (checked by InternalToken), we can trust the headers. + r.Use(chi_middleware.RealIP) r.Post("/ssh/authorized_keys", AuthorizedPublicKeyByContent) r.Post("/ssh/{id}/update/{repoid}", UpdatePublicKeyInRepo) diff --git a/routers/web/admin/applications.go b/routers/web/admin/applications.go new file mode 100644 index 0000000000..c7a9c3100f --- /dev/null +++ b/routers/web/admin/applications.go @@ -0,0 +1,93 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package admin + +import ( + "fmt" + "net/http" + + "code.gitea.io/gitea/models/auth" + "code.gitea.io/gitea/modules/base" + "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/setting" + user_setting "code.gitea.io/gitea/routers/web/user/setting" +) + +var ( + tplSettingsApplications base.TplName = "admin/applications/list" + tplSettingsOauth2ApplicationEdit base.TplName = "admin/applications/oauth2_edit" +) + +func newOAuth2CommonHandlers() *user_setting.OAuth2CommonHandlers { + return &user_setting.OAuth2CommonHandlers{ + OwnerID: 0, + BasePathList: fmt.Sprintf("%s/admin/applications", setting.AppSubURL), + BasePathEditPrefix: fmt.Sprintf("%s/admin/applications/oauth2", setting.AppSubURL), + TplAppEdit: tplSettingsOauth2ApplicationEdit, + } +} + +// Applications render org applications page (for org, at the moment, there are only OAuth2 applications) +func Applications(ctx *context.Context) { + ctx.Data["Title"] = ctx.Tr("settings.applications") + ctx.Data["PageIsAdmin"] = true + ctx.Data["PageIsAdminApplications"] = true + + apps, err := auth.GetOAuth2ApplicationsByUserID(ctx, 0) + if err != nil { + ctx.ServerError("GetOAuth2ApplicationsByUserID", err) + return + } + ctx.Data["Applications"] = apps + + ctx.HTML(http.StatusOK, tplSettingsApplications) +} + +// ApplicationsPost response for adding an oauth2 application +func ApplicationsPost(ctx *context.Context) { + ctx.Data["Title"] = ctx.Tr("settings.applications") + ctx.Data["PageIsAdmin"] = true + ctx.Data["PageIsAdminApplications"] = true + + oa := newOAuth2CommonHandlers() + oa.AddApp(ctx) +} + +// EditApplication displays the given application +func EditApplication(ctx *context.Context) { + ctx.Data["PageIsAdmin"] = true + ctx.Data["PageIsAdminApplications"] = true + + oa := newOAuth2CommonHandlers() + oa.EditShow(ctx) +} + +// EditApplicationPost response for editing oauth2 application +func EditApplicationPost(ctx *context.Context) { + ctx.Data["Title"] = ctx.Tr("settings.applications") + ctx.Data["PageIsAdmin"] = true + ctx.Data["PageIsAdminApplications"] = true + + oa := newOAuth2CommonHandlers() + oa.EditSave(ctx) +} + +// ApplicationsRegenerateSecret handles the post request for regenerating the secret +func ApplicationsRegenerateSecret(ctx *context.Context) { + ctx.Data["Title"] = ctx.Tr("settings") + ctx.Data["PageIsAdmin"] = true + ctx.Data["PageIsAdminApplications"] = true + + oa := newOAuth2CommonHandlers() + oa.RegenerateSecret(ctx) +} + +// DeleteApplication deletes the given oauth2 application +func DeleteApplication(ctx *context.Context) { + oa := newOAuth2CommonHandlers() + oa.DeleteApp(ctx) +} + +// TODO: revokes the grant with the given id diff --git a/routers/web/auth/oauth.go b/routers/web/auth/oauth.go index d145150535..c172215b90 100644 --- a/routers/web/auth/oauth.go +++ b/routers/web/auth/oauth.go @@ -380,10 +380,13 @@ func AuthorizeOAuth(ctx *context.Context) { return } - user, err := user_model.GetUserByID(app.UID) - if err != nil { - ctx.ServerError("GetUserByID", err) - return + var user *user_model.User + if app.UID != 0 { + user, err = user_model.GetUserByID(app.UID) + if err != nil { + ctx.ServerError("GetUserByID", err) + return + } } if !app.ContainsRedirectURI(form.RedirectURI) { @@ -475,7 +478,11 @@ func AuthorizeOAuth(ctx *context.Context) { ctx.Data["State"] = form.State ctx.Data["Scope"] = form.Scope ctx.Data["Nonce"] = form.Nonce - ctx.Data["ApplicationUserLinkHTML"] = "@" + html.EscapeString(user.Name) + "" + if user != nil { + ctx.Data["ApplicationCreatorLinkHTML"] = fmt.Sprintf(`@%s`, html.EscapeString(user.HomeLink()), html.EscapeString(user.Name)) + } else { + ctx.Data["ApplicationCreatorLinkHTML"] = fmt.Sprintf(`%s`, html.EscapeString(setting.AppSubURL+"/"), html.EscapeString(setting.AppName)) + } ctx.Data["ApplicationRedirectDomainHTML"] = "" + html.EscapeString(form.RedirectURI) + "" // TODO document SESSION <=> FORM err = ctx.Session.Set("client_id", app.ClientID) @@ -588,7 +595,8 @@ func OIDCKeys(ctx *context.Context) { // AccessTokenOAuth manages all access token requests by the client func AccessTokenOAuth(ctx *context.Context) { form := *web.GetForm(ctx).(*forms.AccessTokenForm) - if form.ClientID == "" { + // if there is no ClientID or ClientSecret in the request body, fill these fields by the Authorization header and ensure the provided field matches the Authorization header + if form.ClientID == "" || form.ClientSecret == "" { authHeader := ctx.Req.Header.Get("Authorization") authContent := strings.SplitN(authHeader, " ", 2) if len(authContent) == 2 && authContent[0] == "Basic" { @@ -608,7 +616,21 @@ func AccessTokenOAuth(ctx *context.Context) { }) return } + if form.ClientID != "" && form.ClientID != pair[0] { + handleAccessTokenError(ctx, AccessTokenError{ + ErrorCode: AccessTokenErrorCodeInvalidRequest, + ErrorDescription: "client_id in request body inconsistent with Authorization header", + }) + return + } form.ClientID = pair[0] + if form.ClientSecret != "" && form.ClientSecret != pair[1] { + handleAccessTokenError(ctx, AccessTokenError{ + ErrorCode: AccessTokenErrorCodeInvalidRequest, + ErrorDescription: "client_secret in request body inconsistent with Authorization header", + }) + return + } form.ClientSecret = pair[1] } } @@ -686,9 +708,13 @@ func handleAuthorizationCode(ctx *context.Context, form forms.AccessTokenForm, s return } if !app.ValidateClientSecret([]byte(form.ClientSecret)) { + errorDescription := "invalid client secret" + if form.ClientSecret == "" { + errorDescription = "invalid empty client secret" + } handleAccessTokenError(ctx, AccessTokenError{ ErrorCode: AccessTokenErrorCodeUnauthorizedClient, - ErrorDescription: "invalid client secret", + ErrorDescription: errorDescription, }) return } diff --git a/routers/web/explore/code.go b/routers/web/explore/code.go index 3afb2110d9..2357b34fd0 100644 --- a/routers/web/explore/code.go +++ b/routers/web/explore/code.go @@ -34,86 +34,91 @@ func Code(ctx *context.Context) { language := ctx.FormTrim("l") keyword := ctx.FormTrim("q") + + queryType := ctx.FormTrim("t") + isMatch := queryType == "match" + + ctx.Data["Keyword"] = keyword + ctx.Data["Language"] = language + ctx.Data["queryType"] = queryType + ctx.Data["PageIsViewCode"] = true + + if keyword == "" { + ctx.HTML(http.StatusOK, tplExploreCode) + return + } + page := ctx.FormInt("page") if page <= 0 { page = 1 } - queryType := ctx.FormTrim("t") - isMatch := queryType == "match" - - if keyword != "" { - var ( - repoIDs []int64 - err error - isAdmin bool - ) - if ctx.Doer != nil { - isAdmin = ctx.Doer.IsAdmin - } - - // guest user or non-admin user - if ctx.Doer == nil || !isAdmin { - repoIDs, err = repo_model.FindUserCodeAccessibleRepoIDs(ctx.Doer) - if err != nil { - ctx.ServerError("SearchResults", err) - return - } - } - - var ( - total int - searchResults []*code_indexer.Result - searchResultLanguages []*code_indexer.SearchResultLanguages - ) - - if (len(repoIDs) > 0) || isAdmin { - total, searchResults, searchResultLanguages, err = code_indexer.PerformSearch(ctx, repoIDs, language, keyword, page, setting.UI.RepoSearchPagingNum, isMatch) - if err != nil { - if code_indexer.IsAvailable() { - ctx.ServerError("SearchResults", err) - return - } - ctx.Data["CodeIndexerUnavailable"] = true - } else { - ctx.Data["CodeIndexerUnavailable"] = !code_indexer.IsAvailable() - } - - loadRepoIDs := make([]int64, 0, len(searchResults)) - for _, result := range searchResults { - var find bool - for _, id := range loadRepoIDs { - if id == result.RepoID { - find = true - break - } - } - if !find { - loadRepoIDs = append(loadRepoIDs, result.RepoID) - } - } - - repoMaps, err := repo_model.GetRepositoriesMapByIDs(loadRepoIDs) - if err != nil { - ctx.ServerError("SearchResults", err) - return - } - - ctx.Data["RepoMaps"] = repoMaps - } - - ctx.Data["Keyword"] = keyword - ctx.Data["Language"] = language - ctx.Data["queryType"] = queryType - ctx.Data["SearchResults"] = searchResults - ctx.Data["SearchResultLanguages"] = searchResultLanguages - ctx.Data["PageIsViewCode"] = true - - pager := context.NewPagination(total, setting.UI.RepoSearchPagingNum, page, 5) - pager.SetDefaultParams(ctx) - pager.AddParam(ctx, "l", "Language") - ctx.Data["Page"] = pager + var ( + repoIDs []int64 + err error + isAdmin bool + ) + if ctx.Doer != nil { + isAdmin = ctx.Doer.IsAdmin } + // guest user or non-admin user + if ctx.Doer == nil || !isAdmin { + repoIDs, err = repo_model.FindUserCodeAccessibleRepoIDs(ctx, ctx.Doer) + if err != nil { + ctx.ServerError("FindUserCodeAccessibleRepoIDs", err) + return + } + } + + var ( + total int + searchResults []*code_indexer.Result + searchResultLanguages []*code_indexer.SearchResultLanguages + ) + + if (len(repoIDs) > 0) || isAdmin { + total, searchResults, searchResultLanguages, err = code_indexer.PerformSearch(ctx, repoIDs, language, keyword, page, setting.UI.RepoSearchPagingNum, isMatch) + if err != nil { + if code_indexer.IsAvailable() { + ctx.ServerError("SearchResults", err) + return + } + ctx.Data["CodeIndexerUnavailable"] = true + } else { + ctx.Data["CodeIndexerUnavailable"] = !code_indexer.IsAvailable() + } + + loadRepoIDs := make([]int64, 0, len(searchResults)) + for _, result := range searchResults { + var find bool + for _, id := range loadRepoIDs { + if id == result.RepoID { + find = true + break + } + } + if !find { + loadRepoIDs = append(loadRepoIDs, result.RepoID) + } + } + + repoMaps, err := repo_model.GetRepositoriesMapByIDs(loadRepoIDs) + if err != nil { + ctx.ServerError("GetRepositoriesMapByIDs", err) + return + } + + ctx.Data["RepoMaps"] = repoMaps + } + + ctx.Data["SearchResults"] = searchResults + ctx.Data["SearchResultLanguages"] = searchResultLanguages + + pager := context.NewPagination(total, setting.UI.RepoSearchPagingNum, page, 5) + pager.SetDefaultParams(ctx) + pager.AddParam(ctx, "l", "Language") + ctx.Data["Page"] = pager + ctx.HTML(http.StatusOK, tplExploreCode) } diff --git a/routers/web/feed/profile.go b/routers/web/feed/profile.go index c467f7412a..0e11f210ce 100644 --- a/routers/web/feed/profile.go +++ b/routers/web/feed/profile.go @@ -26,10 +26,12 @@ func ShowUserFeedAtom(ctx *context.Context) { // showUserFeed show user activity as RSS / Atom feed func showUserFeed(ctx *context.Context, formatType string) { + includePrivate := ctx.IsSigned && (ctx.Doer.IsAdmin || ctx.Doer.ID == ctx.ContextUser.ID) + actions, err := activities_model.GetFeeds(ctx, activities_model.GetFeedsOptions{ RequestedUser: ctx.ContextUser, Actor: ctx.Doer, - IncludePrivate: false, + IncludePrivate: includePrivate, OnlyPerformedBy: !ctx.ContextUser.IsOrganization(), IncludeDeleted: false, Date: ctx.FormString("date"), diff --git a/routers/web/org/setting_oauth2.go b/routers/web/org/setting_oauth2.go new file mode 100644 index 0000000000..47d1141f34 --- /dev/null +++ b/routers/web/org/setting_oauth2.go @@ -0,0 +1,93 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package org + +import ( + "fmt" + "net/http" + + "code.gitea.io/gitea/models/auth" + "code.gitea.io/gitea/modules/base" + "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/setting" + user_setting "code.gitea.io/gitea/routers/web/user/setting" +) + +const ( + tplSettingsApplications base.TplName = "org/settings/applications" + tplSettingsOAuthApplicationEdit base.TplName = "org/settings/applications_oauth2_edit" +) + +func newOAuth2CommonHandlers(org *context.Organization) *user_setting.OAuth2CommonHandlers { + return &user_setting.OAuth2CommonHandlers{ + OwnerID: org.Organization.ID, + BasePathList: fmt.Sprintf("%s/org/%s/settings/applications", setting.AppSubURL, org.Organization.Name), + BasePathEditPrefix: fmt.Sprintf("%s/org/%s/settings/applications/oauth2", setting.AppSubURL, org.Organization.Name), + TplAppEdit: tplSettingsOAuthApplicationEdit, + } +} + +// Applications render org applications page (for org, at the moment, there are only OAuth2 applications) +func Applications(ctx *context.Context) { + ctx.Data["Title"] = ctx.Tr("settings.applications") + ctx.Data["PageIsOrgSettings"] = true + ctx.Data["PageIsSettingsApplications"] = true + + apps, err := auth.GetOAuth2ApplicationsByUserID(ctx, ctx.Org.Organization.ID) + if err != nil { + ctx.ServerError("GetOAuth2ApplicationsByUserID", err) + return + } + ctx.Data["Applications"] = apps + + ctx.HTML(http.StatusOK, tplSettingsApplications) +} + +// OAuthApplicationsPost response for adding an oauth2 application +func OAuthApplicationsPost(ctx *context.Context) { + ctx.Data["Title"] = ctx.Tr("settings.applications") + ctx.Data["PageIsOrgSettings"] = true + ctx.Data["PageIsSettingsApplications"] = true + + oa := newOAuth2CommonHandlers(ctx.Org) + oa.AddApp(ctx) +} + +// OAuth2ApplicationShow displays the given application +func OAuth2ApplicationShow(ctx *context.Context) { + ctx.Data["PageIsOrgSettings"] = true + ctx.Data["PageIsSettingsApplications"] = true + + oa := newOAuth2CommonHandlers(ctx.Org) + oa.EditShow(ctx) +} + +// OAuth2ApplicationEdit response for editing oauth2 application +func OAuth2ApplicationEdit(ctx *context.Context) { + ctx.Data["Title"] = ctx.Tr("settings.applications") + ctx.Data["PageIsOrgSettings"] = true + ctx.Data["PageIsSettingsApplications"] = true + + oa := newOAuth2CommonHandlers(ctx.Org) + oa.EditSave(ctx) +} + +// OAuthApplicationsRegenerateSecret handles the post request for regenerating the secret +func OAuthApplicationsRegenerateSecret(ctx *context.Context) { + ctx.Data["Title"] = ctx.Tr("settings") + ctx.Data["PageIsOrgSettings"] = true + ctx.Data["PageIsSettingsApplications"] = true + + oa := newOAuth2CommonHandlers(ctx.Org) + oa.RegenerateSecret(ctx) +} + +// DeleteOAuth2Application deletes the given oauth2 application +func DeleteOAuth2Application(ctx *context.Context) { + oa := newOAuth2CommonHandlers(ctx.Org) + oa.DeleteApp(ctx) +} + +// TODO: revokes the grant with the given id diff --git a/routers/web/repo/activity.go b/routers/web/repo/activity.go index 7f2ed8cb26..316cbcd95f 100644 --- a/routers/web/repo/activity.go +++ b/routers/web/repo/activity.go @@ -47,8 +47,8 @@ func Activity(ctx *context.Context) { ctx.Data["Period"] = "weekly" timeFrom = timeUntil.Add(-time.Hour * 168) } - ctx.Data["DateFrom"] = timeFrom.Format("January 2, 2006") - ctx.Data["DateUntil"] = timeUntil.Format("January 2, 2006") + ctx.Data["DateFrom"] = timeFrom.UTC().Format(time.RFC3339) + ctx.Data["DateUntil"] = timeUntil.UTC().Format(time.RFC3339) ctx.Data["PeriodText"] = ctx.Tr("repo.activity.period." + ctx.Data["Period"].(string)) var err error diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go index 5dab770d55..38ad593c17 100644 --- a/routers/web/repo/issue.go +++ b/routers/web/repo/issue.go @@ -30,6 +30,7 @@ import ( "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" + "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/git" @@ -947,10 +948,11 @@ func ValidateRepoMetas(ctx *context.Context, form forms.CreateIssueForm, isPull if err != nil { return nil, nil, 0, 0 } - labelIDMark := base.Int64sToMap(labelIDs) + labelIDMark := make(container.Set[int64]) + labelIDMark.AddMultiple(labelIDs...) for i := range labels { - if labelIDMark[labels[i].ID] { + if labelIDMark.Contains(labels[i].ID) { labels[i].IsChecked = true hasSelected = true } @@ -1293,9 +1295,9 @@ func ViewIssue(ctx *context.Context) { // Metas. // Check labels. - labelIDMark := make(map[int64]bool) - for i := range issue.Labels { - labelIDMark[issue.Labels[i].ID] = true + labelIDMark := make(container.Set[int64]) + for _, label := range issue.Labels { + labelIDMark.Add(label.ID) } labels, err := issues_model.GetLabelsByRepoID(ctx, repo.ID, "", db.ListOptions{}) if err != nil { @@ -1317,7 +1319,7 @@ func ViewIssue(ctx *context.Context) { hasSelected := false for i := range labels { - if labelIDMark[labels[i].ID] { + if labelIDMark.Contains(labels[i].ID) { labels[i].IsChecked = true hasSelected = true } diff --git a/routers/web/repo/lfs.go b/routers/web/repo/lfs.go index baec48bfea..633b8ab1a5 100644 --- a/routers/web/repo/lfs.go +++ b/routers/web/repo/lfs.go @@ -18,6 +18,7 @@ import ( git_model "code.gitea.io/gitea/models/git" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/charset" + "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git/pipeline" @@ -176,14 +177,12 @@ func LFSLocks(ctx *context.Context) { return } - filemap := make(map[string]bool, len(filelist)) - for _, name := range filelist { - filemap[name] = true - } + fileset := make(container.Set[string], len(filelist)) + fileset.AddMultiple(filelist...) linkable := make([]bool, len(lfsLocks)) for i, lock := range lfsLocks { - linkable[i] = filemap[lock.Path] + linkable[i] = fileset.Contains(lock.Path) } ctx.Data["Linkable"] = linkable diff --git a/routers/web/repo/search.go b/routers/web/repo/search.go index 8f141cb149..3d1835c7c3 100644 --- a/routers/web/repo/search.go +++ b/routers/web/repo/search.go @@ -21,14 +21,27 @@ func Search(ctx *context.Context) { ctx.Redirect(ctx.Repo.RepoLink) return } + language := ctx.FormTrim("l") keyword := ctx.FormTrim("q") + + queryType := ctx.FormTrim("t") + isMatch := queryType == "match" + + ctx.Data["Keyword"] = keyword + ctx.Data["Language"] = language + ctx.Data["queryType"] = queryType + ctx.Data["PageIsViewCode"] = true + + if keyword == "" { + ctx.HTML(http.StatusOK, tplSearch) + return + } + page := ctx.FormInt("page") if page <= 0 { page = 1 } - queryType := ctx.FormTrim("t") - isMatch := queryType == "match" total, searchResults, searchResultLanguages, err := code_indexer.PerformSearch(ctx, []int64{ctx.Repo.Repository.ID}, language, keyword, page, setting.UI.RepoSearchPagingNum, isMatch) @@ -41,13 +54,10 @@ func Search(ctx *context.Context) { } else { ctx.Data["CodeIndexerUnavailable"] = !code_indexer.IsAvailable() } - ctx.Data["Keyword"] = keyword - ctx.Data["Language"] = language - ctx.Data["queryType"] = queryType + ctx.Data["SourcePath"] = ctx.Repo.Repository.HTMLURL() ctx.Data["SearchResults"] = searchResults ctx.Data["SearchResultLanguages"] = searchResultLanguages - ctx.Data["PageIsViewCode"] = true pager := context.NewPagination(total, setting.UI.RepoSearchPagingNum, page, 5) pager.SetDefaultParams(ctx) diff --git a/routers/web/repo/treelist.go b/routers/web/repo/treelist.go index 35ac0d507f..80f43a0c40 100644 --- a/routers/web/repo/treelist.go +++ b/routers/web/repo/treelist.go @@ -22,9 +22,9 @@ func TreeList(ctx *context.Context) { return } - entries, err := tree.ListEntriesRecursive() + entries, err := tree.ListEntriesRecursiveFast() if err != nil { - ctx.ServerError("ListEntriesRecursive", err) + ctx.ServerError("ListEntriesRecursiveFast", err) return } entries.CustomSort(base.NaturalSortLess) diff --git a/routers/web/repo/view.go b/routers/web/repo/view.go index 768a30ec21..a43840467d 100644 --- a/routers/web/repo/view.go +++ b/routers/web/repo/view.go @@ -28,6 +28,7 @@ import ( user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/charset" + "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/highlight" @@ -455,7 +456,7 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st ctx.ServerError("GetTreePathLock", err) return } - ctx.Data["LFSLockOwner"] = u.DisplayName() + ctx.Data["LFSLockOwner"] = u.Name ctx.Data["LFSLockOwnerHomeLink"] = u.HomeLink() ctx.Data["LFSLockHint"] = ctx.Tr("repo.editor.this_file_locked") } @@ -811,16 +812,14 @@ func renderDirectoryFiles(ctx *context.Context, timeout time.Duration) git.Entri defer cancel() } - selected := map[string]bool{} - for _, pth := range ctx.FormStrings("f[]") { - selected[pth] = true - } + selected := make(container.Set[string]) + selected.AddMultiple(ctx.FormStrings("f[]")...) entries := allEntries if len(selected) > 0 { entries = make(git.Entries, 0, len(selected)) for _, entry := range allEntries { - if selected[entry.Name()] { + if selected.Contains(entry.Name()) { entries = append(entries, entry) } } diff --git a/routers/web/user/code.go b/routers/web/user/code.go new file mode 100644 index 0000000000..89bd23588b --- /dev/null +++ b/routers/web/user/code.go @@ -0,0 +1,114 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package user + +import ( + "net/http" + + repo_model "code.gitea.io/gitea/models/repo" + "code.gitea.io/gitea/modules/base" + "code.gitea.io/gitea/modules/context" + code_indexer "code.gitea.io/gitea/modules/indexer/code" + "code.gitea.io/gitea/modules/setting" +) + +const ( + tplUserCode base.TplName = "user/code" +) + +// CodeSearch render user/organization code search page +func CodeSearch(ctx *context.Context) { + if !setting.Indexer.RepoIndexerEnabled { + ctx.Redirect(ctx.ContextUser.HomeLink()) + return + } + + ctx.Data["IsPackageEnabled"] = setting.Packages.Enabled + ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled + ctx.Data["Title"] = ctx.Tr("code.title") + ctx.Data["ContextUser"] = ctx.ContextUser + + language := ctx.FormTrim("l") + keyword := ctx.FormTrim("q") + + queryType := ctx.FormTrim("t") + isMatch := queryType == "match" + + ctx.Data["Keyword"] = keyword + ctx.Data["Language"] = language + ctx.Data["queryType"] = queryType + ctx.Data["IsCodePage"] = true + + if keyword == "" { + ctx.HTML(http.StatusOK, tplUserCode) + return + } + + var ( + repoIDs []int64 + err error + ) + + page := ctx.FormInt("page") + if page <= 0 { + page = 1 + } + + repoIDs, err = repo_model.FindUserCodeAccessibleOwnerRepoIDs(ctx, ctx.ContextUser.ID, ctx.Doer) + if err != nil { + ctx.ServerError("FindUserCodeAccessibleOwnerRepoIDs", err) + return + } + + var ( + total int + searchResults []*code_indexer.Result + searchResultLanguages []*code_indexer.SearchResultLanguages + ) + + if len(repoIDs) > 0 { + total, searchResults, searchResultLanguages, err = code_indexer.PerformSearch(ctx, repoIDs, language, keyword, page, setting.UI.RepoSearchPagingNum, isMatch) + if err != nil { + if code_indexer.IsAvailable() { + ctx.ServerError("SearchResults", err) + return + } + ctx.Data["CodeIndexerUnavailable"] = true + } else { + ctx.Data["CodeIndexerUnavailable"] = !code_indexer.IsAvailable() + } + + loadRepoIDs := make([]int64, 0, len(searchResults)) + for _, result := range searchResults { + var find bool + for _, id := range loadRepoIDs { + if id == result.RepoID { + find = true + break + } + } + if !find { + loadRepoIDs = append(loadRepoIDs, result.RepoID) + } + } + + repoMaps, err := repo_model.GetRepositoriesMapByIDs(loadRepoIDs) + if err != nil { + ctx.ServerError("GetRepositoriesMapByIDs", err) + return + } + + ctx.Data["RepoMaps"] = repoMaps + } + ctx.Data["SearchResults"] = searchResults + ctx.Data["SearchResultLanguages"] = searchResultLanguages + + pager := context.NewPagination(total, setting.UI.RepoSearchPagingNum, page, 5) + pager.SetDefaultParams(ctx) + pager.AddParam(ctx, "l", "Language") + ctx.Data["Page"] = pager + + ctx.HTML(http.StatusOK, tplUserCode) +} diff --git a/routers/web/user/package.go b/routers/web/user/package.go index 20d8e32d29..c72592e728 100644 --- a/routers/web/user/package.go +++ b/routers/web/user/package.go @@ -86,6 +86,7 @@ func ListPackages(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("packages.title") ctx.Data["IsPackagesPage"] = true + ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled ctx.Data["ContextUser"] = ctx.ContextUser ctx.Data["Query"] = query ctx.Data["PackageType"] = packageType @@ -157,6 +158,7 @@ func ViewPackageVersion(ctx *context.Context) { ctx.Data["Title"] = pd.Package.Name ctx.Data["IsPackagesPage"] = true + ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled ctx.Data["ContextUser"] = ctx.ContextUser ctx.Data["PackageDescriptor"] = pd @@ -234,6 +236,7 @@ func ListPackageVersions(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("packages.title") ctx.Data["IsPackagesPage"] = true + ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled ctx.Data["ContextUser"] = ctx.ContextUser ctx.Data["PackageDescriptor"] = &packages_model.PackageDescriptor{ Package: p, @@ -305,6 +308,7 @@ func PackageSettings(ctx *context.Context) { ctx.Data["Title"] = pd.Package.Name ctx.Data["IsPackagesPage"] = true + ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled ctx.Data["ContextUser"] = ctx.ContextUser ctx.Data["PackageDescriptor"] = pd diff --git a/routers/web/user/profile.go b/routers/web/user/profile.go index a3452fd692..6e16b377db 100644 --- a/routers/web/user/profile.go +++ b/routers/web/user/profile.go @@ -290,6 +290,7 @@ func Profile(ctx *context.Context) { } ctx.Data["Page"] = pager ctx.Data["IsPackageEnabled"] = setting.Packages.Enabled + ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled ctx.Data["ShowUserEmail"] = len(ctx.ContextUser.Email) > 0 && ctx.IsSigned && (!ctx.ContextUser.KeepEmailPrivate || ctx.ContextUser.ID == ctx.Doer.ID) diff --git a/routers/web/user/setting/oauth2.go b/routers/web/user/setting/oauth2.go index db76a12f18..0cc05dd040 100644 --- a/routers/web/user/setting/oauth2.go +++ b/routers/web/user/setting/oauth2.go @@ -5,79 +5,40 @@ package setting import ( - "fmt" - "net/http" - - "code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" - "code.gitea.io/gitea/modules/web" - "code.gitea.io/gitea/services/forms" ) const ( - tplSettingsOAuthApplications base.TplName = "user/settings/applications_oauth2_edit" + tplSettingsOAuthApplicationEdit base.TplName = "user/settings/applications_oauth2_edit" ) +func newOAuth2CommonHandlers(userID int64) *OAuth2CommonHandlers { + return &OAuth2CommonHandlers{ + OwnerID: userID, + BasePathList: setting.AppSubURL + "/user/settings/applications", + BasePathEditPrefix: setting.AppSubURL + "/user/settings/applications/oauth2", + TplAppEdit: tplSettingsOAuthApplicationEdit, + } +} + // OAuthApplicationsPost response for adding a oauth2 application func OAuthApplicationsPost(ctx *context.Context) { - form := web.GetForm(ctx).(*forms.EditOAuth2ApplicationForm) ctx.Data["Title"] = ctx.Tr("settings") ctx.Data["PageIsSettingsApplications"] = true - if ctx.HasError() { - loadApplicationsData(ctx) - - ctx.HTML(http.StatusOK, tplSettingsApplications) - return - } - // TODO validate redirect URI - app, err := auth.CreateOAuth2Application(ctx, auth.CreateOAuth2ApplicationOptions{ - Name: form.Name, - RedirectURIs: []string{form.RedirectURI}, - UserID: ctx.Doer.ID, - }) - if err != nil { - ctx.ServerError("CreateOAuth2Application", err) - return - } - ctx.Flash.Success(ctx.Tr("settings.create_oauth2_application_success")) - ctx.Data["App"] = app - ctx.Data["ClientSecret"], err = app.GenerateClientSecret() - if err != nil { - ctx.ServerError("GenerateClientSecret", err) - return - } - ctx.HTML(http.StatusOK, tplSettingsOAuthApplications) + oa := newOAuth2CommonHandlers(ctx.Doer.ID) + oa.AddApp(ctx) } // OAuthApplicationsEdit response for editing oauth2 application func OAuthApplicationsEdit(ctx *context.Context) { - form := web.GetForm(ctx).(*forms.EditOAuth2ApplicationForm) ctx.Data["Title"] = ctx.Tr("settings") ctx.Data["PageIsSettingsApplications"] = true - if ctx.HasError() { - loadApplicationsData(ctx) - - ctx.HTML(http.StatusOK, tplSettingsApplications) - return - } - // TODO validate redirect URI - var err error - if ctx.Data["App"], err = auth.UpdateOAuth2Application(auth.UpdateOAuth2ApplicationOptions{ - ID: ctx.ParamsInt64("id"), - Name: form.Name, - RedirectURIs: []string{form.RedirectURI}, - UserID: ctx.Doer.ID, - }); err != nil { - ctx.ServerError("UpdateOAuth2Application", err) - return - } - ctx.Flash.Success(ctx.Tr("settings.update_oauth2_application_success")) - ctx.HTML(http.StatusOK, tplSettingsOAuthApplications) + oa := newOAuth2CommonHandlers(ctx.Doer.ID) + oa.EditSave(ctx) } // OAuthApplicationsRegenerateSecret handles the post request for regenerating the secret @@ -85,75 +46,24 @@ func OAuthApplicationsRegenerateSecret(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("settings") ctx.Data["PageIsSettingsApplications"] = true - app, err := auth.GetOAuth2ApplicationByID(ctx, ctx.ParamsInt64("id")) - if err != nil { - if auth.IsErrOAuthApplicationNotFound(err) { - ctx.NotFound("Application not found", err) - return - } - ctx.ServerError("GetOAuth2ApplicationByID", err) - return - } - if app.UID != ctx.Doer.ID { - ctx.NotFound("Application not found", nil) - return - } - ctx.Data["App"] = app - ctx.Data["ClientSecret"], err = app.GenerateClientSecret() - if err != nil { - ctx.ServerError("GenerateClientSecret", err) - return - } - ctx.Flash.Success(ctx.Tr("settings.update_oauth2_application_success")) - ctx.HTML(http.StatusOK, tplSettingsOAuthApplications) + oa := newOAuth2CommonHandlers(ctx.Doer.ID) + oa.RegenerateSecret(ctx) } // OAuth2ApplicationShow displays the given application func OAuth2ApplicationShow(ctx *context.Context) { - app, err := auth.GetOAuth2ApplicationByID(ctx, ctx.ParamsInt64("id")) - if err != nil { - if auth.IsErrOAuthApplicationNotFound(err) { - ctx.NotFound("Application not found", err) - return - } - ctx.ServerError("GetOAuth2ApplicationByID", err) - return - } - if app.UID != ctx.Doer.ID { - ctx.NotFound("Application not found", nil) - return - } - ctx.Data["App"] = app - ctx.HTML(http.StatusOK, tplSettingsOAuthApplications) + oa := newOAuth2CommonHandlers(ctx.Doer.ID) + oa.EditShow(ctx) } // DeleteOAuth2Application deletes the given oauth2 application func DeleteOAuth2Application(ctx *context.Context) { - if err := auth.DeleteOAuth2Application(ctx.FormInt64("id"), ctx.Doer.ID); err != nil { - ctx.ServerError("DeleteOAuth2Application", err) - return - } - log.Trace("OAuth2 Application deleted: %s", ctx.Doer.Name) - - ctx.Flash.Success(ctx.Tr("settings.remove_oauth2_application_success")) - ctx.JSON(http.StatusOK, map[string]interface{}{ - "redirect": setting.AppSubURL + "/user/settings/applications", - }) + oa := newOAuth2CommonHandlers(ctx.Doer.ID) + oa.DeleteApp(ctx) } // RevokeOAuth2Grant revokes the grant with the given id func RevokeOAuth2Grant(ctx *context.Context) { - if ctx.Doer.ID == 0 || ctx.FormInt64("id") == 0 { - ctx.ServerError("RevokeOAuth2Grant", fmt.Errorf("user id or grant id is zero")) - return - } - if err := auth.RevokeOAuth2Grant(ctx, ctx.FormInt64("id"), ctx.Doer.ID); err != nil { - ctx.ServerError("RevokeOAuth2Grant", err) - return - } - - ctx.Flash.Success(ctx.Tr("settings.revoke_oauth2_grant_success")) - ctx.JSON(http.StatusOK, map[string]interface{}{ - "redirect": setting.AppSubURL + "/user/settings/applications", - }) + oa := newOAuth2CommonHandlers(ctx.Doer.ID) + oa.RevokeGrant(ctx) } diff --git a/routers/web/user/setting/oauth2_common.go b/routers/web/user/setting/oauth2_common.go new file mode 100644 index 0000000000..f02f6ab041 --- /dev/null +++ b/routers/web/user/setting/oauth2_common.go @@ -0,0 +1,150 @@ +// Copyright 2019 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package setting + +import ( + "fmt" + "net/http" + + "code.gitea.io/gitea/models/auth" + "code.gitea.io/gitea/modules/base" + "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/forms" +) + +type OAuth2CommonHandlers struct { + OwnerID int64 // 0 for instance-wide, otherwise OrgID or UserID + BasePathList string // the base URL for the application list page, eg: "/user/setting/applications" + BasePathEditPrefix string // the base URL for the application edit page, will be appended with app id, eg: "/user/setting/applications/oauth2" + TplAppEdit base.TplName // the template for the application edit page +} + +func (oa *OAuth2CommonHandlers) renderEditPage(ctx *context.Context) { + app := ctx.Data["App"].(*auth.OAuth2Application) + ctx.Data["FormActionPath"] = fmt.Sprintf("%s/%d", oa.BasePathEditPrefix, app.ID) + ctx.HTML(http.StatusOK, oa.TplAppEdit) +} + +// AddApp adds an oauth2 application +func (oa *OAuth2CommonHandlers) AddApp(ctx *context.Context) { + form := web.GetForm(ctx).(*forms.EditOAuth2ApplicationForm) + if ctx.HasError() { + // go to the application list page + ctx.Redirect(oa.BasePathList) + return + } + + // TODO validate redirect URI + app, err := auth.CreateOAuth2Application(ctx, auth.CreateOAuth2ApplicationOptions{ + Name: form.Name, + RedirectURIs: []string{form.RedirectURI}, + UserID: oa.OwnerID, + }) + if err != nil { + ctx.ServerError("CreateOAuth2Application", err) + return + } + + // render the edit page with secret + ctx.Flash.Success(ctx.Tr("settings.create_oauth2_application_success"), true) + ctx.Data["App"] = app + ctx.Data["ClientSecret"], err = app.GenerateClientSecret() + if err != nil { + ctx.ServerError("GenerateClientSecret", err) + return + } + oa.renderEditPage(ctx) +} + +// EditShow displays the given application +func (oa *OAuth2CommonHandlers) EditShow(ctx *context.Context) { + app, err := auth.GetOAuth2ApplicationByID(ctx, ctx.ParamsInt64("id")) + if err != nil { + if auth.IsErrOAuthApplicationNotFound(err) { + ctx.NotFound("Application not found", err) + return + } + ctx.ServerError("GetOAuth2ApplicationByID", err) + return + } + if app.UID != oa.OwnerID { + ctx.NotFound("Application not found", nil) + return + } + ctx.Data["App"] = app + oa.renderEditPage(ctx) +} + +// EditSave saves the oauth2 application +func (oa *OAuth2CommonHandlers) EditSave(ctx *context.Context) { + form := web.GetForm(ctx).(*forms.EditOAuth2ApplicationForm) + + if ctx.HasError() { + oa.renderEditPage(ctx) + return + } + + // TODO validate redirect URI + var err error + if ctx.Data["App"], err = auth.UpdateOAuth2Application(auth.UpdateOAuth2ApplicationOptions{ + ID: ctx.ParamsInt64("id"), + Name: form.Name, + RedirectURIs: []string{form.RedirectURI}, + UserID: oa.OwnerID, + }); err != nil { + ctx.ServerError("UpdateOAuth2Application", err) + return + } + ctx.Flash.Success(ctx.Tr("settings.update_oauth2_application_success")) + ctx.Redirect(oa.BasePathList) +} + +// RegenerateSecret regenerates the secret +func (oa *OAuth2CommonHandlers) RegenerateSecret(ctx *context.Context) { + app, err := auth.GetOAuth2ApplicationByID(ctx, ctx.ParamsInt64("id")) + if err != nil { + if auth.IsErrOAuthApplicationNotFound(err) { + ctx.NotFound("Application not found", err) + return + } + ctx.ServerError("GetOAuth2ApplicationByID", err) + return + } + if app.UID != oa.OwnerID { + ctx.NotFound("Application not found", nil) + return + } + ctx.Data["App"] = app + ctx.Data["ClientSecret"], err = app.GenerateClientSecret() + if err != nil { + ctx.ServerError("GenerateClientSecret", err) + return + } + ctx.Flash.Success(ctx.Tr("settings.update_oauth2_application_success"), true) + oa.renderEditPage(ctx) +} + +// DeleteApp deletes the given oauth2 application +func (oa *OAuth2CommonHandlers) DeleteApp(ctx *context.Context) { + if err := auth.DeleteOAuth2Application(ctx.ParamsInt64("id"), oa.OwnerID); err != nil { + ctx.ServerError("DeleteOAuth2Application", err) + return + } + + ctx.Flash.Success(ctx.Tr("settings.remove_oauth2_application_success")) + ctx.JSON(http.StatusOK, map[string]interface{}{"redirect": oa.BasePathList}) +} + +// RevokeGrant revokes the grant +func (oa *OAuth2CommonHandlers) RevokeGrant(ctx *context.Context) { + if err := auth.RevokeOAuth2Grant(ctx, ctx.ParamsInt64("grantId"), oa.OwnerID); err != nil { + ctx.ServerError("RevokeOAuth2Grant", err) + return + } + + ctx.Flash.Success(ctx.Tr("settings.revoke_oauth2_grant_success")) + ctx.JSON(http.StatusOK, map[string]interface{}{"redirect": oa.BasePathList}) +} diff --git a/routers/web/web.go b/routers/web/web.go index acce071891..c01a2bce40 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -427,8 +427,8 @@ func RegisterRoutes(m *web.Route) { m.Post("/{id}", bindIgnErr(forms.EditOAuth2ApplicationForm{}), user_setting.OAuthApplicationsEdit) m.Post("/{id}/regenerate_secret", user_setting.OAuthApplicationsRegenerateSecret) m.Post("", bindIgnErr(forms.EditOAuth2ApplicationForm{}), user_setting.OAuthApplicationsPost) - m.Post("/delete", user_setting.DeleteOAuth2Application) - m.Post("/revoke", user_setting.RevokeOAuth2Grant) + m.Post("/{id}/delete", user_setting.DeleteOAuth2Application) + m.Post("/{id}/revoke/{grantId}", user_setting.RevokeOAuth2Grant) }) m.Combo("/applications").Get(user_setting.Applications). Post(bindIgnErr(forms.NewAccessTokenForm{}), user_setting.ApplicationsPost) @@ -569,6 +569,23 @@ func RegisterRoutes(m *web.Route) { m.Post("/delete", admin.DeleteNotices) m.Post("/empty", admin.EmptyNotices) }) + + m.Group("/applications", func() { + m.Get("", admin.Applications) + m.Post("/oauth2", bindIgnErr(forms.EditOAuth2ApplicationForm{}), admin.ApplicationsPost) + m.Group("/oauth2/{id}", func() { + m.Combo("").Get(admin.EditApplication).Post(bindIgnErr(forms.EditOAuth2ApplicationForm{}), admin.EditApplicationPost) + m.Post("/regenerate_secret", admin.ApplicationsRegenerateSecret) + m.Post("/delete", admin.DeleteApplication) + }) + }, func(ctx *context.Context) { + if !setting.OAuth2.Enable { + ctx.Error(http.StatusForbidden) + return + } + }) + }, func(ctx *context.Context) { + ctx.Data["EnableOAuth2"] = setting.OAuth2.Enable }, adminReq) // ***** END: Admin ***** @@ -662,6 +679,20 @@ func RegisterRoutes(m *web.Route) { Post(bindIgnErr(forms.UpdateOrgSettingForm{}), org.SettingsPost) m.Post("/avatar", bindIgnErr(forms.AvatarForm{}), org.SettingsAvatar) m.Post("/avatar/delete", org.SettingsDeleteAvatar) + m.Group("/applications", func() { + m.Get("", org.Applications) + m.Post("/oauth2", bindIgnErr(forms.EditOAuth2ApplicationForm{}), org.OAuthApplicationsPost) + m.Group("/oauth2/{id}", func() { + m.Combo("").Get(org.OAuth2ApplicationShow).Post(bindIgnErr(forms.EditOAuth2ApplicationForm{}), org.OAuth2ApplicationEdit) + m.Post("/regenerate_secret", org.OAuthApplicationsRegenerateSecret) + m.Post("/delete", org.DeleteOAuth2Application) + }) + }, func(ctx *context.Context) { + if !setting.OAuth2.Enable { + ctx.Error(http.StatusForbidden) + return + } + }) m.Group("/hooks", func() { m.Get("", org.Webhooks) @@ -702,6 +733,8 @@ func RegisterRoutes(m *web.Route) { }) m.Route("/delete", "GET,POST", org.SettingsDelete) + }, func(ctx *context.Context) { + ctx.Data["EnableOAuth2"] = setting.OAuth2.Enable }) }, context.OrgAssignment(true, true)) }, reqSignIn) @@ -738,6 +771,7 @@ func RegisterRoutes(m *web.Route) { }) }, ignSignIn, context.PackageAssignment(), reqPackageAccess(perm.AccessModeRead)) } + m.Get("/code", user.CodeSearch) }, context_service.UserAssignmentWeb()) // ***** Release Attachment Download without Signin diff --git a/services/auth/session.go b/services/auth/session.go index 6a23a17665..1ec94aa0af 100644 --- a/services/auth/session.go +++ b/services/auth/session.go @@ -39,6 +39,10 @@ func (s *Session) Verify(req *http.Request, w http.ResponseWriter, store DataSto // SessionUser returns the user object corresponding to the "uid" session variable. func SessionUser(sess SessionStore) *user_model.User { + if sess == nil { + return nil + } + // Get user ID uid := sess.Get("uid") if uid == nil { diff --git a/services/gitdiff/gitdiff.go b/services/gitdiff/gitdiff.go index 9844992f5b..e7362cdcdd 100644 --- a/services/gitdiff/gitdiff.go +++ b/services/gitdiff/gitdiff.go @@ -1178,8 +1178,6 @@ func GetDiff(gitRepo *git.Repository, opts *DiffOptions, files ...string) (*Diff } else if language, has := attrs["gitlab-language"]; has && language != "unspecified" && language != "" { diffFile.Language = language } - } else { - log.Error("Unexpected error: %v", err) } } diff --git a/services/issue/commit.go b/services/issue/commit.go index 0d04de81bc..c8cfa6cc8a 100644 --- a/services/issue/commit.go +++ b/services/issue/commit.go @@ -18,6 +18,7 @@ import ( access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/references" "code.gitea.io/gitea/modules/repository" @@ -111,7 +112,7 @@ func UpdateIssuesCommit(doer *user_model.User, repo *repo_model.Repository, comm Action references.XRefAction } - refMarked := make(map[markKey]bool) + refMarked := make(container.Set[markKey]) var refRepo *repo_model.Repository var refIssue *issues_model.Issue var err error @@ -144,10 +145,9 @@ func UpdateIssuesCommit(doer *user_model.User, repo *repo_model.Repository, comm } key := markKey{ID: refIssue.ID, Action: ref.Action} - if refMarked[key] { + if !refMarked.Add(key) { continue } - refMarked[key] = true // FIXME: this kind of condition is all over the code, it should be consolidated in a single place canclose := perm.IsAdmin() || perm.IsOwner() || perm.CanWriteIssuesOrPulls(refIssue.IsPull) || refIssue.PosterID == doer.ID diff --git a/services/mailer/mail_comment.go b/services/mailer/mail_comment.go index 2dab673b4e..af07821c29 100644 --- a/services/mailer/mail_comment.go +++ b/services/mailer/mail_comment.go @@ -10,6 +10,7 @@ import ( activities_model "code.gitea.io/gitea/models/activities" issues_model "code.gitea.io/gitea/models/issues" user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" ) @@ -46,8 +47,8 @@ func MailMentionsComment(ctx context.Context, pr *issues_model.PullRequest, c *i return nil } - visited := make(map[int64]bool, len(mentions)+1) - visited[c.Poster.ID] = true + visited := make(container.Set[int64], len(mentions)+1) + visited.Add(c.Poster.ID) if err = mailIssueCommentBatch( &mailCommentContext{ Context: ctx, diff --git a/services/mailer/mail_issue.go b/services/mailer/mail_issue.go index ec6ddcf14e..15bfa4af41 100644 --- a/services/mailer/mail_issue.go +++ b/services/mailer/mail_issue.go @@ -14,6 +14,7 @@ import ( repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" ) @@ -89,11 +90,11 @@ func mailIssueCommentToParticipants(ctx *mailCommentContext, mentions []*user_mo unfiltered = append(ids, unfiltered...) } - visited := make(map[int64]bool, len(unfiltered)+len(mentions)+1) + visited := make(container.Set[int64], len(unfiltered)+len(mentions)+1) // Avoid mailing the doer if ctx.Doer.EmailNotificationsPreference != user_model.EmailNotificationsAndYourOwn { - visited[ctx.Doer.ID] = true + visited.Add(ctx.Doer.ID) } // =========== Mentions =========== @@ -106,9 +107,7 @@ func mailIssueCommentToParticipants(ctx *mailCommentContext, mentions []*user_mo if err != nil { return fmt.Errorf("GetIssueWatchersIDs(%d): %v", ctx.Issue.ID, err) } - for _, i := range ids { - visited[i] = true - } + visited.AddMultiple(ids...) unfilteredUsers, err := user_model.GetMaileableUsersByIDs(unfiltered, false) if err != nil { @@ -121,7 +120,7 @@ func mailIssueCommentToParticipants(ctx *mailCommentContext, mentions []*user_mo return nil } -func mailIssueCommentBatch(ctx *mailCommentContext, users []*user_model.User, visited map[int64]bool, fromMention bool) error { +func mailIssueCommentBatch(ctx *mailCommentContext, users []*user_model.User, visited container.Set[int64], fromMention bool) error { checkUnit := unit.TypeIssues if ctx.Issue.IsPull { checkUnit = unit.TypePullRequests @@ -142,13 +141,10 @@ func mailIssueCommentBatch(ctx *mailCommentContext, users []*user_model.User, vi } // if we have already visited this user we exclude them - if _, ok := visited[user.ID]; ok { + if !visited.Add(user.ID) { continue } - // now mark them as visited - visited[user.ID] = true - // test if this user is allowed to see the issue/pull if !access_model.CheckRepoUnitUser(ctx, ctx.Issue.Repo, user, checkUnit) { continue diff --git a/services/pull/merge.go b/services/pull/merge.go index 4cd4e3bd7e..6f3df6ab2a 100644 --- a/services/pull/merge.go +++ b/services/pull/merge.go @@ -28,6 +28,7 @@ import ( user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/cache" "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/notification" "code.gitea.io/gitea/modules/references" @@ -165,9 +166,10 @@ func Merge(ctx context.Context, pr *issues_model.PullRequest, doer *user_model.U go AddTestPullRequestTask(doer, pr.BaseRepo.ID, pr.BaseBranch, false, "", "") }() - // TODO: make it able to do this in a database session - mergeCtx := context.Background() - pr.MergedCommitID, err = rawMerge(mergeCtx, pr, doer, mergeStyle, expectedHeadCommitID, message) + // Run the merge in the hammer context to prevent cancellation + hammerCtx := graceful.GetManager().HammerContext() + + pr.MergedCommitID, err = rawMerge(hammerCtx, pr, doer, mergeStyle, expectedHeadCommitID, message) if err != nil { return err } @@ -176,18 +178,18 @@ func Merge(ctx context.Context, pr *issues_model.PullRequest, doer *user_model.U pr.Merger = doer pr.MergerID = doer.ID - if _, err := pr.SetMerged(ctx); err != nil { + if _, err := pr.SetMerged(hammerCtx); err != nil { log.Error("setMerged [%d]: %v", pr.ID, err) } - if err := pr.LoadIssueCtx(ctx); err != nil { + if err := pr.LoadIssueCtx(hammerCtx); err != nil { log.Error("loadIssue [%d]: %v", pr.ID, err) } - if err := pr.Issue.LoadRepo(ctx); err != nil { + if err := pr.Issue.LoadRepo(hammerCtx); err != nil { log.Error("loadRepo for issue [%d]: %v", pr.ID, err) } - if err := pr.Issue.Repo.GetOwner(ctx); err != nil { + if err := pr.Issue.Repo.GetOwner(hammerCtx); err != nil { log.Error("GetOwner for issue repo [%d]: %v", pr.ID, err) } @@ -197,17 +199,17 @@ func Merge(ctx context.Context, pr *issues_model.PullRequest, doer *user_model.U cache.Remove(pr.Issue.Repo.GetCommitsCountCacheKey(pr.BaseBranch, true)) // Resolve cross references - refs, err := pr.ResolveCrossReferences(ctx) + refs, err := pr.ResolveCrossReferences(hammerCtx) if err != nil { log.Error("ResolveCrossReferences: %v", err) return nil } for _, ref := range refs { - if err = ref.LoadIssueCtx(ctx); err != nil { + if err = ref.LoadIssueCtx(hammerCtx); err != nil { return err } - if err = ref.Issue.LoadRepo(ctx); err != nil { + if err = ref.Issue.LoadRepo(hammerCtx); err != nil { return err } close := ref.RefAction == references.XRefActionCloses diff --git a/services/pull/patch.go b/services/pull/patch.go index 32895b2e78..dafd577069 100644 --- a/services/pull/patch.go +++ b/services/pull/patch.go @@ -17,6 +17,7 @@ import ( "code.gitea.io/gitea/models" issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unit" + "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/log" @@ -409,7 +410,7 @@ func checkConflicts(ctx context.Context, pr *issues_model.PullRequest, gitRepo * const appliedPatchPrefix = "Applied patch to '" const withConflicts = "' with conflicts." - conflictMap := map[string]bool{} + conflicts := make(container.Set[string]) // Now scan the output from the command scanner := bufio.NewScanner(stderrReader) @@ -418,7 +419,7 @@ func checkConflicts(ctx context.Context, pr *issues_model.PullRequest, gitRepo * if strings.HasPrefix(line, prefix) { conflict = true filepath := strings.TrimSpace(strings.Split(line[len(prefix):], ":")[0]) - conflictMap[filepath] = true + conflicts.Add(filepath) } else if is3way && line == threewayFailed { conflict = true } else if strings.HasPrefix(line, errorPrefix) { @@ -427,7 +428,7 @@ func checkConflicts(ctx context.Context, pr *issues_model.PullRequest, gitRepo * if strings.HasSuffix(line, suffix) { filepath := strings.TrimSpace(strings.TrimSuffix(line[len(errorPrefix):], suffix)) if filepath != "" { - conflictMap[filepath] = true + conflicts.Add(filepath) } break } @@ -436,18 +437,18 @@ func checkConflicts(ctx context.Context, pr *issues_model.PullRequest, gitRepo * conflict = true filepath := strings.TrimPrefix(strings.TrimSuffix(line, withConflicts), appliedPatchPrefix) if filepath != "" { - conflictMap[filepath] = true + conflicts.Add(filepath) } } // only list 10 conflicted files - if len(conflictMap) >= 10 { + if len(conflicts) >= 10 { break } } - if len(conflictMap) > 0 { - pr.ConflictedFiles = make([]string, 0, len(conflictMap)) - for key := range conflictMap { + if len(conflicts) > 0 { + pr.ConflictedFiles = make([]string, 0, len(conflicts)) + for key := range conflicts { pr.ConflictedFiles = append(pr.ConflictedFiles, key) } } diff --git a/services/pull/pull.go b/services/pull/pull.go index 103fdc340d..9de7cb5d4f 100644 --- a/services/pull/pull.go +++ b/services/pull/pull.go @@ -20,6 +20,7 @@ import ( issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/json" @@ -640,7 +641,7 @@ func GetSquashMergeCommitMessages(ctx context.Context, pr *issues_model.PullRequ posterSig := pr.Issue.Poster.NewGitSig().String() - authorsMap := map[string]bool{} + uniqueAuthors := make(container.Set[string]) authors := make([]string, 0, len(commits)) stringBuilder := strings.Builder{} @@ -687,9 +688,8 @@ func GetSquashMergeCommitMessages(ctx context.Context, pr *issues_model.PullRequ } authorString := commit.Author.String() - if !authorsMap[authorString] && authorString != posterSig { + if uniqueAuthors.Add(authorString) && authorString != posterSig { authors = append(authors, authorString) - authorsMap[authorString] = true } } @@ -709,9 +709,8 @@ func GetSquashMergeCommitMessages(ctx context.Context, pr *issues_model.PullRequ } for _, commit := range commits { authorString := commit.Author.String() - if !authorsMap[authorString] && authorString != posterSig { + if uniqueAuthors.Add(authorString) && authorString != posterSig { authors = append(authors, authorString) - authorsMap[authorString] = true } } skip += limit diff --git a/services/release/release.go b/services/release/release.go index ae610b0e3c..187ebeb486 100644 --- a/services/release/release.go +++ b/services/release/release.go @@ -15,6 +15,7 @@ import ( git_model "code.gitea.io/gitea/models/git" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/notification" @@ -209,7 +210,7 @@ func UpdateRelease(doer *user_model.User, gitRepo *git.Repository, rel *repo_mod return fmt.Errorf("AddReleaseAttachments: %v", err) } - deletedUUIDsMap := make(map[string]bool) + deletedUUIDs := make(container.Set[string]) if len(delAttachmentUUIDs) > 0 { // Check attachments attachments, err := repo_model.GetAttachmentsByUUIDs(ctx, delAttachmentUUIDs) @@ -220,7 +221,7 @@ func UpdateRelease(doer *user_model.User, gitRepo *git.Repository, rel *repo_mod if attach.ReleaseID != rel.ID { return errors.New("delete attachement of release permission denied") } - deletedUUIDsMap[attach.UUID] = true + deletedUUIDs.Add(attach.UUID) } if _, err := repo_model.DeleteAttachments(ctx, attachments, false); err != nil { @@ -245,7 +246,7 @@ func UpdateRelease(doer *user_model.User, gitRepo *git.Repository, rel *repo_mod } for uuid, newName := range editAttachments { - if !deletedUUIDsMap[uuid] { + if !deletedUUIDs.Contains(uuid) { if err = repo_model.UpdateAttachmentByUUID(ctx, &repo_model.Attachment{ UUID: uuid, Name: newName, diff --git a/services/repository/adopt.go b/services/repository/adopt.go index 74876d8e76..9e04c15977 100644 --- a/services/repository/adopt.go +++ b/services/repository/adopt.go @@ -14,6 +14,7 @@ import ( "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/notification" @@ -257,12 +258,12 @@ func checkUnadoptedRepositories(userName string, repoNamesToCheck []string, unad if len(repos) == len(repoNamesToCheck) { return nil } - repoNames := make(map[string]bool, len(repos)) + repoNames := make(container.Set[string], len(repos)) for _, repo := range repos { - repoNames[repo.LowerName] = true + repoNames.Add(repo.LowerName) } for _, repoName := range repoNamesToCheck { - if _, ok := repoNames[repoName]; !ok { + if !repoNames.Contains(repoName) { unadopted.add(filepath.Join(userName, repoName)) } } diff --git a/services/repository/files/tree.go b/services/repository/files/tree.go index caad732887..59e5690977 100644 --- a/services/repository/files/tree.go +++ b/services/repository/files/tree.go @@ -29,7 +29,7 @@ func GetTreeBySHA(ctx context.Context, repo *repo_model.Repository, gitRepo *git tree.URL = repo.APIURL() + "/git/trees/" + url.PathEscape(tree.SHA) var entries git.Entries if recursive { - entries, err = gitTree.ListEntriesRecursive() + entries, err = gitTree.ListEntriesRecursiveWithSize() } else { entries, err = gitTree.ListEntries() } diff --git a/services/webhook/matrix.go b/services/webhook/matrix.go index f4c4cf0e9a..59eae48307 100644 --- a/services/webhook/matrix.go +++ b/services/webhook/matrix.go @@ -195,7 +195,7 @@ func (m *MatrixPayloadUnsafe) PullRequest(p *api.PullRequestPayload) (api.Payloa func (m *MatrixPayloadUnsafe) Review(p *api.PullRequestPayload, event webhook_model.HookEventType) (api.Payloader, error) { senderLink := MatrixLinkFormatter(setting.AppURL+url.PathEscape(p.Sender.UserName), p.Sender.UserName) title := fmt.Sprintf("#%d %s", p.Index, p.PullRequest.Title) - titleLink := fmt.Sprintf("%s/pulls/%d", p.Repository.HTMLURL, p.Index) + titleLink := MatrixLinkFormatter(p.PullRequest.URL, title) repoLink := MatrixLinkFormatter(p.Repository.HTMLURL, p.Repository.FullName) var text string @@ -206,7 +206,7 @@ func (m *MatrixPayloadUnsafe) Review(p *api.PullRequestPayload, event webhook_mo return nil, err } - text = fmt.Sprintf("[%s] Pull request review %s: [%s](%s) by %s", repoLink, action, title, titleLink, senderLink) + text = fmt.Sprintf("[%s] Pull request review %s: %s by %s", repoLink, action, titleLink, senderLink) } return getMatrixPayloadUnsafe(text, nil, m.AccessToken, m.MsgType), nil diff --git a/services/webhook/matrix_test.go b/services/webhook/matrix_test.go index 4cab845330..624986ee9b 100644 --- a/services/webhook/matrix_test.go +++ b/services/webhook/matrix_test.go @@ -140,7 +140,7 @@ func TestMatrixPayload(t *testing.T) { require.IsType(t, &MatrixPayloadUnsafe{}, pl) assert.Equal(t, "[[test/repo](http://localhost:3000/test/repo)] Pull request review approved: [#12 Fix bug](http://localhost:3000/test/repo/pulls/12) by [user1](https://try.gitea.io/user1)", pl.(*MatrixPayloadUnsafe).Body) - assert.Equal(t, `[test/repo] Pull request review approved: [#12 Fix bug](http://localhost:3000/test/repo/pulls/12) by user1`, pl.(*MatrixPayloadUnsafe).FormattedBody) + assert.Equal(t, `[test/repo] Pull request review approved: #12 Fix bug by user1`, pl.(*MatrixPayloadUnsafe).FormattedBody) }) t.Run("Repository", func(t *testing.T) { diff --git a/templates/admin/applications/list.tmpl b/templates/admin/applications/list.tmpl new file mode 100644 index 0000000000..6d627129df --- /dev/null +++ b/templates/admin/applications/list.tmpl @@ -0,0 +1,14 @@ +{{template "base/head" .}} +
+ {{template "admin/navbar" .}} +
+
+ {{template "base/alert" .}} +

+ {{.locale.Tr "settings.applications"}} +

+ {{template "user/settings/applications_oauth2_list" .}} +
+
+
+{{template "base/footer" .}} diff --git a/templates/admin/applications/oauth2_edit.tmpl b/templates/admin/applications/oauth2_edit.tmpl new file mode 100644 index 0000000000..84d821ecca --- /dev/null +++ b/templates/admin/applications/oauth2_edit.tmpl @@ -0,0 +1,7 @@ +{{template "base/head" .}} +
+ {{template "admin/navbar" .}} + + {{template "user/settings/applications_oauth2_edit_form" .}} +
+{{template "base/footer" .}} diff --git a/templates/admin/navbar.tmpl b/templates/admin/navbar.tmpl index 0db1aab079..b138eb79ba 100644 --- a/templates/admin/navbar.tmpl +++ b/templates/admin/navbar.tmpl @@ -26,6 +26,11 @@ {{.locale.Tr "admin.emails"}} + {{if .EnableOAuth2}} + + {{.locale.Tr "settings.applications"}} + + {{end}} {{.locale.Tr "admin.config"}} diff --git a/templates/base/footer_content.tmpl b/templates/base/footer_content.tmpl index 88dec014f6..89be609225 100644 --- a/templates/base/footer_content.tmpl +++ b/templates/base/footer_content.tmpl @@ -12,8 +12,7 @@ {{end}} {{if and .TemplateLoadTimes ShowFooterTemplateLoadTime}} {{.locale.Tr "page"}}: {{LoadTimes .PageStartTime}} - {{.locale.Tr "template"}} - {{if .TemplateName}} {{.TemplateName}}{{end}}: {{call .TemplateLoadTimes}} + {{.locale.Tr "template"}}{{if .TemplateName}} {{.TemplateName}}{{end}}: {{call .TemplateLoadTimes}} {{end}}