diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0c2ab8a434..d62707aac2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -71,7 +71,7 @@ jobs: echo "NEXT_VERSION=$nextStrict" >> $GITHUB_ENV - name: Create Draft Release - uses: ncipollo/release-action@v1.12.0 + uses: ncipollo/release-action@v1.13.0 if: ${{ github.ref_name == 'release' }} with: prerelease: true @@ -352,7 +352,7 @@ jobs: histCoveragePath: historical-coverage.json - name: Create Release - uses: ncipollo/release-action@v1.12.0 + uses: ncipollo/release-action@v1.13.0 if: ${{ env.SHOULD_DEPLOY == 'true' }} with: allowUpdates: true @@ -365,7 +365,7 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} - name: Update Baseline Coverage - uses: ncipollo/release-action@v1.12.0 + uses: ncipollo/release-action@v1.13.0 if: ${{ github.event.inputs.updateCoverage == 'true' }} with: allowUpdates: true diff --git a/.github/workflows/ci-run-tests.yml b/.github/workflows/ci-run-tests.yml index eec60cb641..8ca2736844 100644 --- a/.github/workflows/ci-run-tests.yml +++ b/.github/workflows/ci-run-tests.yml @@ -130,6 +130,7 @@ jobs: run: | echo "Running checks..." ./ietf/manage.py check + ./ietf/manage.py migrate --fake-initial echo "Starting datatracker..." ./ietf/manage.py runserver 0.0.0.0:8000 --settings=settings_local & echo "Waiting for datatracker to be ready..." diff --git a/.pnp.cjs b/.pnp.cjs index efd5316577..66bfbf894f 100644 --- a/.pnp.cjs +++ b/.pnp.cjs @@ -46,9 +46,9 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["@parcel/transformer-inline-string", "npm:2.9.3"],\ ["@parcel/transformer-sass", "npm:2.9.3"],\ ["@popperjs/core", "npm:2.11.8"],\ - ["@rollup/pluginutils", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:5.0.2"],\ + ["@rollup/pluginutils", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:5.0.3"],\ ["@twuni/emojify", "npm:1.0.2"],\ - ["@vitejs/plugin-vue", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:4.2.3"],\ + ["@vitejs/plugin-vue", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:4.3.3"],\ ["bootstrap", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:5.3.0"],\ ["bootstrap-icons", "npm:1.10.5"],\ ["browser-fs-access", "npm:0.34.1"],\ @@ -56,17 +56,17 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["c8", "npm:8.0.1"],\ ["caniuse-lite", "npm:1.0.30001519"],\ ["d3", "npm:7.8.5"],\ - ["eslint", "npm:8.45.0"],\ + ["eslint", "npm:8.47.0"],\ ["eslint-config-standard", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:17.1.0"],\ - ["eslint-plugin-cypress", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.13.3"],\ - ["eslint-plugin-import", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.28.0"],\ + ["eslint-plugin-cypress", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.14.0"],\ + ["eslint-plugin-import", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.28.1"],\ ["eslint-plugin-n", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:16.0.1"],\ ["eslint-plugin-node", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:11.1.0"],\ ["eslint-plugin-promise", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:6.1.1"],\ - ["eslint-plugin-vue", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:9.16.1"],\ + ["eslint-plugin-vue", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:9.17.0"],\ ["file-saver", "npm:2.0.5"],\ ["highcharts", "npm:11.1.0"],\ - ["html-validate", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:8.1.0"],\ + ["html-validate", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:8.2.0"],\ ["ical.js", "npm:1.5.0"],\ ["jquery", "npm:3.7.0"],\ ["jquery-migrate", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:3.4.1"],\ @@ -74,7 +74,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["list.js", "npm:2.3.1"],\ ["lodash", "npm:4.17.21"],\ ["lodash-es", "npm:4.17.21"],\ - ["luxon", "npm:3.3.0"],\ + ["luxon", "npm:3.4.0"],\ ["moment", "npm:2.29.4"],\ ["moment-timezone", "npm:0.5.43"],\ ["ms", "npm:2.1.3"],\ @@ -84,7 +84,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["pinia", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.1.6"],\ ["pinia-plugin-persist", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:1.0.0"],\ ["pug", "npm:3.0.2"],\ - ["sass", "npm:1.64.1"],\ + ["sass", "npm:1.66.1"],\ ["seedrandom", "npm:3.0.5"],\ ["select2", "npm:4.1.0-rc.0"],\ ["select2-bootstrap-5-theme", "npm:1.3.0"],\ @@ -92,7 +92,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["shepherd.js", "npm:11.1.1"],\ ["slugify", "npm:1.6.6"],\ ["sortablejs", "npm:1.15.0"],\ - ["vanillajs-datepicker", "npm:1.3.3"],\ + ["vanillajs-datepicker", "npm:1.3.4"],\ ["vite", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:4.4.9"],\ ["vue", "npm:3.3.4"],\ ["vue-router", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:4.2.4"],\ @@ -438,12 +438,12 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ],\ "linkType": "SOFT"\ }],\ - ["virtual:a03a909c3f5870829b2a1f1c58cd72dd0904272c636f0500be601a3bd781404d19a891ad23156b2b680426d08dbfc464b1e4ab195d463ee4ff16262a9e851f5e#npm:4.4.0", {\ - "packageLocation": "./.yarn/__virtual__/@eslint-community-eslint-utils-virtual-c51d166267/0/cache/@eslint-community-eslint-utils-npm-4.4.0-d1791bd5a3-cdfe3ae42b.zip/node_modules/@eslint-community/eslint-utils/",\ + ["virtual:84c6b60ea80c2e474ae2eb1949a4b42a725b5ad125a348fd9ccd31d528ef15de82d28192a86b98baf21067fd8c90bd02753cac42e9ee96bf5f8084788455b3e4#npm:4.4.0", {\ + "packageLocation": "./.yarn/__virtual__/@eslint-community-eslint-utils-virtual-5ceedd2a81/0/cache/@eslint-community-eslint-utils-npm-4.4.0-d1791bd5a3-cdfe3ae42b.zip/node_modules/@eslint-community/eslint-utils/",\ "packageDependencies": [\ - ["@eslint-community/eslint-utils", "virtual:a03a909c3f5870829b2a1f1c58cd72dd0904272c636f0500be601a3bd781404d19a891ad23156b2b680426d08dbfc464b1e4ab195d463ee4ff16262a9e851f5e#npm:4.4.0"],\ + ["@eslint-community/eslint-utils", "virtual:84c6b60ea80c2e474ae2eb1949a4b42a725b5ad125a348fd9ccd31d528ef15de82d28192a86b98baf21067fd8c90bd02753cac42e9ee96bf5f8084788455b3e4#npm:4.4.0"],\ ["@types/eslint", null],\ - ["eslint", "npm:8.45.0"],\ + ["eslint", "npm:8.47.0"],\ ["eslint-visitor-keys", "npm:3.3.0"]\ ],\ "packagePeers": [\ @@ -454,17 +454,17 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]\ ]],\ ["@eslint-community/regexpp", [\ - ["npm:4.4.1", {\ - "packageLocation": "./.yarn/cache/@eslint-community-regexpp-npm-4.4.1-44c7391499-db97d8d08e.zip/node_modules/@eslint-community/regexpp/",\ + ["npm:4.5.1", {\ + "packageLocation": "./.yarn/cache/@eslint-community-regexpp-npm-4.5.1-bf72922237-6d901166d6.zip/node_modules/@eslint-community/regexpp/",\ "packageDependencies": [\ - ["@eslint-community/regexpp", "npm:4.4.1"]\ + ["@eslint-community/regexpp", "npm:4.5.1"]\ ],\ "linkType": "HARD"\ }],\ - ["npm:4.5.1", {\ - "packageLocation": "./.yarn/cache/@eslint-community-regexpp-npm-4.5.1-bf72922237-6d901166d6.zip/node_modules/@eslint-community/regexpp/",\ + ["npm:4.8.0", {\ + "packageLocation": "./.yarn/cache/@eslint-community-regexpp-npm-4.8.0-92ece47e3d-601e6d033d.zip/node_modules/@eslint-community/regexpp/",\ "packageDependencies": [\ - ["@eslint-community/regexpp", "npm:4.5.1"]\ + ["@eslint-community/regexpp", "npm:4.8.0"]\ ],\ "linkType": "HARD"\ }]\ @@ -488,10 +488,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]\ ]],\ ["@eslint/js", [\ - ["npm:8.44.0", {\ - "packageLocation": "./.yarn/cache/@eslint-js-npm-8.44.0-66b473d41b-fc53958322.zip/node_modules/@eslint/js/",\ + ["npm:8.48.0", {\ + "packageLocation": "./.yarn/cache/@eslint-js-npm-8.48.0-cee42a7097-b2755f9c0e.zip/node_modules/@eslint/js/",\ "packageDependencies": [\ - ["@eslint/js", "npm:8.44.0"]\ + ["@eslint/js", "npm:8.48.0"]\ ],\ "linkType": "HARD"\ }]\ @@ -654,7 +654,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["@fullcalendar/core", "npm:6.1.8"],\ ["@types/fullcalendar__core", null],\ ["@types/luxon", null],\ - ["luxon", "npm:3.3.0"]\ + ["luxon", "npm:3.4.0"]\ ],\ "packagePeers": [\ "@fullcalendar/core",\ @@ -2346,17 +2346,17 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]\ ]],\ ["@rollup/pluginutils", [\ - ["npm:5.0.2", {\ - "packageLocation": "./.yarn/cache/@rollup-pluginutils-npm-5.0.2-6aa9d0ddd4-edea15e543.zip/node_modules/@rollup/pluginutils/",\ + ["npm:5.0.3", {\ + "packageLocation": "./.yarn/cache/@rollup-pluginutils-npm-5.0.3-33f9e7f020-8efbdeac53.zip/node_modules/@rollup/pluginutils/",\ "packageDependencies": [\ - ["@rollup/pluginutils", "npm:5.0.2"]\ + ["@rollup/pluginutils", "npm:5.0.3"]\ ],\ "linkType": "SOFT"\ }],\ - ["virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:5.0.2", {\ - "packageLocation": "./.yarn/__virtual__/@rollup-pluginutils-virtual-ca58d3a074/0/cache/@rollup-pluginutils-npm-5.0.2-6aa9d0ddd4-edea15e543.zip/node_modules/@rollup/pluginutils/",\ + ["virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:5.0.3", {\ + "packageLocation": "./.yarn/__virtual__/@rollup-pluginutils-virtual-e8c80fae3a/0/cache/@rollup-pluginutils-npm-5.0.3-33f9e7f020-8efbdeac53.zip/node_modules/@rollup/pluginutils/",\ "packageDependencies": [\ - ["@rollup/pluginutils", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:5.0.2"],\ + ["@rollup/pluginutils", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:5.0.3"],\ ["@types/estree", "npm:1.0.0"],\ ["@types/rollup", null],\ ["estree-walker", "npm:2.0.2"],\ @@ -2378,10 +2378,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ],\ "linkType": "SOFT"\ }],\ - ["virtual:bbfdcb87fdcbacbba9ebe8ba4b476510d780b50c748b7a71307807b8e2c47cca6be20627a384f24b655b80a0ab5fd5b193ef3274afb79c45d120013674fc6a35#npm:2.0.0", {\ - "packageLocation": "./.yarn/__virtual__/@sidvind-better-ajv-errors-virtual-fb9d43dbe5/0/cache/@sidvind-better-ajv-errors-npm-2.0.0-3531bddef9-12b0d87855.zip/node_modules/@sidvind/better-ajv-errors/",\ + ["virtual:d54cf140bc899b791890b50d03f9737577eb8c2e0b480e2b1bc40b168f05a300b97a0338d73f013a8f7410236526aba6ee56a063db404e7ae64ba5f1e4e85cb8#npm:2.0.0", {\ + "packageLocation": "./.yarn/__virtual__/@sidvind-better-ajv-errors-virtual-23ff750c09/0/cache/@sidvind-better-ajv-errors-npm-2.0.0-3531bddef9-12b0d87855.zip/node_modules/@sidvind/better-ajv-errors/",\ "packageDependencies": [\ - ["@sidvind/better-ajv-errors", "virtual:bbfdcb87fdcbacbba9ebe8ba4b476510d780b50c748b7a71307807b8e2c47cca6be20627a384f24b655b80a0ab5fd5b193ef3274afb79c45d120013674fc6a35#npm:2.0.0"],\ + ["@sidvind/better-ajv-errors", "virtual:d54cf140bc899b791890b50d03f9737577eb8c2e0b480e2b1bc40b168f05a300b97a0338d73f013a8f7410236526aba6ee56a063db404e7ae64ba5f1e4e85cb8#npm:2.0.0"],\ ["@babel/code-frame", "npm:7.16.7"],\ ["@types/ajv", null],\ ["ajv", "npm:8.11.0"],\ @@ -2627,17 +2627,17 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]\ ]],\ ["@vitejs/plugin-vue", [\ - ["npm:4.2.3", {\ - "packageLocation": "./.yarn/cache/@vitejs-plugin-vue-npm-4.2.3-f2af5ce2fe-1c70c1cd18.zip/node_modules/@vitejs/plugin-vue/",\ + ["npm:4.3.3", {\ + "packageLocation": "./.yarn/cache/@vitejs-plugin-vue-npm-4.3.3-ffc8f9f2ac-17f8d73708.zip/node_modules/@vitejs/plugin-vue/",\ "packageDependencies": [\ - ["@vitejs/plugin-vue", "npm:4.2.3"]\ + ["@vitejs/plugin-vue", "npm:4.3.3"]\ ],\ "linkType": "SOFT"\ }],\ - ["virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:4.2.3", {\ - "packageLocation": "./.yarn/__virtual__/@vitejs-plugin-vue-virtual-ad1e69b525/0/cache/@vitejs-plugin-vue-npm-4.2.3-f2af5ce2fe-1c70c1cd18.zip/node_modules/@vitejs/plugin-vue/",\ + ["virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:4.3.3", {\ + "packageLocation": "./.yarn/__virtual__/@vitejs-plugin-vue-virtual-c26a0d639a/0/cache/@vitejs-plugin-vue-npm-4.3.3-ffc8f9f2ac-17f8d73708.zip/node_modules/@vitejs/plugin-vue/",\ "packageDependencies": [\ - ["@vitejs/plugin-vue", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:4.2.3"],\ + ["@vitejs/plugin-vue", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:4.3.3"],\ ["@types/vite", null],\ ["@types/vue", null],\ ["vite", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:4.4.9"],\ @@ -4619,14 +4619,14 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]\ ]],\ ["eslint", [\ - ["npm:8.45.0", {\ - "packageLocation": "./.yarn/cache/eslint-npm-8.45.0-a03a909c3f-3e6dcce5cc.zip/node_modules/eslint/",\ + ["npm:8.47.0", {\ + "packageLocation": "./.yarn/cache/eslint-npm-8.47.0-84c6b60ea8-1988617f70.zip/node_modules/eslint/",\ "packageDependencies": [\ - ["eslint", "npm:8.45.0"],\ - ["@eslint-community/eslint-utils", "virtual:a03a909c3f5870829b2a1f1c58cd72dd0904272c636f0500be601a3bd781404d19a891ad23156b2b680426d08dbfc464b1e4ab195d463ee4ff16262a9e851f5e#npm:4.4.0"],\ - ["@eslint-community/regexpp", "npm:4.4.1"],\ + ["eslint", "npm:8.47.0"],\ + ["@eslint-community/eslint-utils", "virtual:84c6b60ea80c2e474ae2eb1949a4b42a725b5ad125a348fd9ccd31d528ef15de82d28192a86b98baf21067fd8c90bd02753cac42e9ee96bf5f8084788455b3e4#npm:4.4.0"],\ + ["@eslint-community/regexpp", "npm:4.8.0"],\ ["@eslint/eslintrc", "npm:2.1.2"],\ - ["@eslint/js", "npm:8.44.0"],\ + ["@eslint/js", "npm:8.48.0"],\ ["@humanwhocodes/config-array", "npm:0.11.10"],\ ["@humanwhocodes/module-importer", "npm:1.0.1"],\ ["@nodelib/fs.walk", "npm:1.2.8"],\ @@ -4636,8 +4636,8 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["debug", "virtual:b86a9fb34323a98c6519528ed55faa0d9b44ca8879307c0b29aa384bde47ff59a7d0c9051b31246f14521dfb71ba3c5d6d0b35c29fffc17bf875aa6ad977d9e8#npm:4.3.4"],\ ["doctrine", "npm:3.0.0"],\ ["escape-string-regexp", "npm:4.0.0"],\ - ["eslint-scope", "npm:7.2.0"],\ - ["eslint-visitor-keys", "npm:3.4.1"],\ + ["eslint-scope", "npm:7.2.2"],\ + ["eslint-visitor-keys", "npm:3.4.3"],\ ["espree", "npm:9.6.1"],\ ["esquery", "npm:1.5.0"],\ ["esutils", "npm:2.0.3"],\ @@ -4680,8 +4680,8 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["@types/eslint-plugin-import", null],\ ["@types/eslint-plugin-n", null],\ ["@types/eslint-plugin-promise", null],\ - ["eslint", "npm:8.45.0"],\ - ["eslint-plugin-import", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.28.0"],\ + ["eslint", "npm:8.47.0"],\ + ["eslint-plugin-import", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.28.1"],\ ["eslint-plugin-n", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:16.0.1"],\ ["eslint-plugin-promise", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:6.1.1"]\ ],\ @@ -4718,10 +4718,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ],\ "linkType": "SOFT"\ }],\ - ["virtual:ec3843619a313054d408df3901c13ec8bb0acce27ef6bd14eee15f259bc019cfdb93e958a7f4ce4e64688e7e47232df540c3c57af900bead08c4578c9e8e4b3a#npm:2.8.0", {\ - "packageLocation": "./.yarn/__virtual__/eslint-module-utils-virtual-6de382c6db/0/cache/eslint-module-utils-npm-2.8.0-05e42bcab0-74c6dfea76.zip/node_modules/eslint-module-utils/",\ + ["virtual:ef2ff17f0affe5aeeb05f2e27f2212e975bb78d898c026b74cc62e05a17de36abb35a54f0831f2ff5fced26e6128bfc2c0cf332f7c60149823619b008d0ea480#npm:2.8.0", {\ + "packageLocation": "./.yarn/__virtual__/eslint-module-utils-virtual-0e305f99a7/0/cache/eslint-module-utils-npm-2.8.0-05e42bcab0-74c6dfea76.zip/node_modules/eslint-module-utils/",\ "packageDependencies": [\ - ["eslint-module-utils", "virtual:ec3843619a313054d408df3901c13ec8bb0acce27ef6bd14eee15f259bc019cfdb93e958a7f4ce4e64688e7e47232df540c3c57af900bead08c4578c9e8e4b3a#npm:2.8.0"],\ + ["eslint-module-utils", "virtual:ef2ff17f0affe5aeeb05f2e27f2212e975bb78d898c026b74cc62e05a17de36abb35a54f0831f2ff5fced26e6128bfc2c0cf332f7c60149823619b008d0ea480#npm:2.8.0"],\ ["@types/eslint", null],\ ["@types/eslint-import-resolver-node", null],\ ["@types/eslint-import-resolver-typescript", null],\ @@ -4729,7 +4729,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["@types/typescript-eslint__parser", null],\ ["@typescript-eslint/parser", null],\ ["debug", "virtual:65bed195431eadffc59e2238eb20cc12d9a1665bc7458ce780a9320ff795091b03cb5c4c2094938315ddd967b5b02c0f1df67b3ed435c69b7457092b7cc06ed8#npm:3.2.7"],\ - ["eslint", "npm:8.45.0"],\ + ["eslint", "npm:8.47.0"],\ ["eslint-import-resolver-node", "npm:0.3.7"],\ ["eslint-import-resolver-typescript", null],\ ["eslint-import-resolver-webpack", null]\ @@ -4750,20 +4750,20 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]\ ]],\ ["eslint-plugin-cypress", [\ - ["npm:2.13.3", {\ - "packageLocation": "./.yarn/cache/eslint-plugin-cypress-npm-2.13.3-0ad3bff9c9-9affbcee29.zip/node_modules/eslint-plugin-cypress/",\ + ["npm:2.14.0", {\ + "packageLocation": "./.yarn/cache/eslint-plugin-cypress-npm-2.14.0-4d90862e1d-3fa118a757.zip/node_modules/eslint-plugin-cypress/",\ "packageDependencies": [\ - ["eslint-plugin-cypress", "npm:2.13.3"]\ + ["eslint-plugin-cypress", "npm:2.14.0"]\ ],\ "linkType": "SOFT"\ }],\ - ["virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.13.3", {\ - "packageLocation": "./.yarn/__virtual__/eslint-plugin-cypress-virtual-2dc00cb202/0/cache/eslint-plugin-cypress-npm-2.13.3-0ad3bff9c9-9affbcee29.zip/node_modules/eslint-plugin-cypress/",\ + ["virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.14.0", {\ + "packageLocation": "./.yarn/__virtual__/eslint-plugin-cypress-virtual-57ccfb2b3e/0/cache/eslint-plugin-cypress-npm-2.14.0-4d90862e1d-3fa118a757.zip/node_modules/eslint-plugin-cypress/",\ "packageDependencies": [\ - ["eslint-plugin-cypress", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.13.3"],\ + ["eslint-plugin-cypress", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.14.0"],\ ["@types/eslint", null],\ - ["eslint", "npm:8.45.0"],\ - ["globals", "npm:11.12.0"]\ + ["eslint", "npm:8.47.0"],\ + ["globals", "npm:13.21.0"]\ ],\ "packagePeers": [\ "@types/eslint",\ @@ -4785,7 +4785,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "packageDependencies": [\ ["eslint-plugin-es", "virtual:5cccaf00e87dfff96dbbb5eaf7a3055373358b8114d6a1adfb32f54ed6b40ba06068d3aa1fdd8062899a0cad040f68c17cc6b72bac2cdbe9700f3d6330d112f3#npm:3.0.1"],\ ["@types/eslint", null],\ - ["eslint", "npm:8.45.0"],\ + ["eslint", "npm:8.47.0"],\ ["eslint-utils", "npm:2.1.0"],\ ["regexpp", "npm:3.2.0"]\ ],\ @@ -4808,10 +4808,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "packageLocation": "./.yarn/__virtual__/eslint-plugin-es-x-virtual-7882922717/0/cache/eslint-plugin-es-x-npm-7.1.0-35735e8bbc-a19924313c.zip/node_modules/eslint-plugin-es-x/",\ "packageDependencies": [\ ["eslint-plugin-es-x", "virtual:adc54309e8e54b60324bd0d3562e4cdf4588bb7e8e9bf0e8567ae0b912e220b364ab900a1f69ea824481e4ed94aa6d687c737b8f554fa53b86231581c20d170a#npm:7.1.0"],\ - ["@eslint-community/eslint-utils", "virtual:a03a909c3f5870829b2a1f1c58cd72dd0904272c636f0500be601a3bd781404d19a891ad23156b2b680426d08dbfc464b1e4ab195d463ee4ff16262a9e851f5e#npm:4.4.0"],\ + ["@eslint-community/eslint-utils", "virtual:84c6b60ea80c2e474ae2eb1949a4b42a725b5ad125a348fd9ccd31d528ef15de82d28192a86b98baf21067fd8c90bd02753cac42e9ee96bf5f8084788455b3e4#npm:4.4.0"],\ ["@eslint-community/regexpp", "npm:4.5.1"],\ ["@types/eslint", null],\ - ["eslint", "npm:8.45.0"]\ + ["eslint", "npm:8.47.0"]\ ],\ "packagePeers": [\ "@types/eslint",\ @@ -4821,17 +4821,17 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]\ ]],\ ["eslint-plugin-import", [\ - ["npm:2.28.0", {\ - "packageLocation": "./.yarn/cache/eslint-plugin-import-npm-2.28.0-7894c48955-f9eba311b9.zip/node_modules/eslint-plugin-import/",\ + ["npm:2.28.1", {\ + "packageLocation": "./.yarn/cache/eslint-plugin-import-npm-2.28.1-2056ddf35c-e8ae6dd8f0.zip/node_modules/eslint-plugin-import/",\ "packageDependencies": [\ - ["eslint-plugin-import", "npm:2.28.0"]\ + ["eslint-plugin-import", "npm:2.28.1"]\ ],\ "linkType": "SOFT"\ }],\ - ["virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.28.0", {\ - "packageLocation": "./.yarn/__virtual__/eslint-plugin-import-virtual-ec3843619a/0/cache/eslint-plugin-import-npm-2.28.0-7894c48955-f9eba311b9.zip/node_modules/eslint-plugin-import/",\ + ["virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.28.1", {\ + "packageLocation": "./.yarn/__virtual__/eslint-plugin-import-virtual-ef2ff17f0a/0/cache/eslint-plugin-import-npm-2.28.1-2056ddf35c-e8ae6dd8f0.zip/node_modules/eslint-plugin-import/",\ "packageDependencies": [\ - ["eslint-plugin-import", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.28.0"],\ + ["eslint-plugin-import", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.28.1"],\ ["@types/eslint", null],\ ["@types/typescript-eslint__parser", null],\ ["@typescript-eslint/parser", null],\ @@ -4841,17 +4841,16 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["array.prototype.flatmap", "npm:1.3.1"],\ ["debug", "virtual:65bed195431eadffc59e2238eb20cc12d9a1665bc7458ce780a9320ff795091b03cb5c4c2094938315ddd967b5b02c0f1df67b3ed435c69b7457092b7cc06ed8#npm:3.2.7"],\ ["doctrine", "npm:2.1.0"],\ - ["eslint", "npm:8.45.0"],\ + ["eslint", "npm:8.47.0"],\ ["eslint-import-resolver-node", "npm:0.3.7"],\ - ["eslint-module-utils", "virtual:ec3843619a313054d408df3901c13ec8bb0acce27ef6bd14eee15f259bc019cfdb93e958a7f4ce4e64688e7e47232df540c3c57af900bead08c4578c9e8e4b3a#npm:2.8.0"],\ + ["eslint-module-utils", "virtual:ef2ff17f0affe5aeeb05f2e27f2212e975bb78d898c026b74cc62e05a17de36abb35a54f0831f2ff5fced26e6128bfc2c0cf332f7c60149823619b008d0ea480#npm:2.8.0"],\ ["has", "npm:1.0.3"],\ - ["is-core-module", "npm:2.12.1"],\ + ["is-core-module", "npm:2.13.0"],\ ["is-glob", "npm:4.0.3"],\ ["minimatch", "npm:3.1.2"],\ ["object.fromentries", "npm:2.0.6"],\ ["object.groupby", "npm:1.0.0"],\ ["object.values", "npm:1.1.6"],\ - ["resolve", "patch:resolve@npm%3A1.22.4#~builtin::version=1.22.4&hash=07638b"],\ ["semver", "npm:6.3.1"],\ ["tsconfig-paths", "npm:3.14.2"]\ ],\ @@ -4876,10 +4875,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "packageLocation": "./.yarn/__virtual__/eslint-plugin-n-virtual-adc54309e8/0/cache/eslint-plugin-n-npm-16.0.1-6a07bf1b46-407002bb06.zip/node_modules/eslint-plugin-n/",\ "packageDependencies": [\ ["eslint-plugin-n", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:16.0.1"],\ - ["@eslint-community/eslint-utils", "virtual:a03a909c3f5870829b2a1f1c58cd72dd0904272c636f0500be601a3bd781404d19a891ad23156b2b680426d08dbfc464b1e4ab195d463ee4ff16262a9e851f5e#npm:4.4.0"],\ + ["@eslint-community/eslint-utils", "virtual:84c6b60ea80c2e474ae2eb1949a4b42a725b5ad125a348fd9ccd31d528ef15de82d28192a86b98baf21067fd8c90bd02753cac42e9ee96bf5f8084788455b3e4#npm:4.4.0"],\ ["@types/eslint", null],\ ["builtins", "npm:5.0.1"],\ - ["eslint", "npm:8.45.0"],\ + ["eslint", "npm:8.47.0"],\ ["eslint-plugin-es-x", "virtual:adc54309e8e54b60324bd0d3562e4cdf4588bb7e8e9bf0e8567ae0b912e220b364ab900a1f69ea824481e4ed94aa6d687c737b8f554fa53b86231581c20d170a#npm:7.1.0"],\ ["ignore", "npm:5.2.4"],\ ["is-core-module", "npm:2.12.1"],\ @@ -4907,7 +4906,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "packageDependencies": [\ ["eslint-plugin-node", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:11.1.0"],\ ["@types/eslint", null],\ - ["eslint", "npm:8.45.0"],\ + ["eslint", "npm:8.47.0"],\ ["eslint-plugin-es", "virtual:5cccaf00e87dfff96dbbb5eaf7a3055373358b8114d6a1adfb32f54ed6b40ba06068d3aa1fdd8062899a0cad040f68c17cc6b72bac2cdbe9700f3d6330d112f3#npm:3.0.1"],\ ["eslint-utils", "npm:2.1.0"],\ ["ignore", "npm:5.2.0"],\ @@ -4935,7 +4934,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "packageDependencies": [\ ["eslint-plugin-promise", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:6.1.1"],\ ["@types/eslint", null],\ - ["eslint", "npm:8.45.0"]\ + ["eslint", "npm:8.47.0"]\ ],\ "packagePeers": [\ "@types/eslint",\ @@ -4945,25 +4944,25 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]\ ]],\ ["eslint-plugin-vue", [\ - ["npm:9.16.1", {\ - "packageLocation": "./.yarn/cache/eslint-plugin-vue-npm-9.16.1-4e9625bf90-b2f9d0deef.zip/node_modules/eslint-plugin-vue/",\ + ["npm:9.17.0", {\ + "packageLocation": "./.yarn/cache/eslint-plugin-vue-npm-9.17.0-c32115eab8-2ef53a0387.zip/node_modules/eslint-plugin-vue/",\ "packageDependencies": [\ - ["eslint-plugin-vue", "npm:9.16.1"]\ + ["eslint-plugin-vue", "npm:9.17.0"]\ ],\ "linkType": "SOFT"\ }],\ - ["virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:9.16.1", {\ - "packageLocation": "./.yarn/__virtual__/eslint-plugin-vue-virtual-3fd334a097/0/cache/eslint-plugin-vue-npm-9.16.1-4e9625bf90-b2f9d0deef.zip/node_modules/eslint-plugin-vue/",\ + ["virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:9.17.0", {\ + "packageLocation": "./.yarn/__virtual__/eslint-plugin-vue-virtual-e39e5d6bef/0/cache/eslint-plugin-vue-npm-9.17.0-c32115eab8-2ef53a0387.zip/node_modules/eslint-plugin-vue/",\ "packageDependencies": [\ - ["eslint-plugin-vue", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:9.16.1"],\ - ["@eslint-community/eslint-utils", "virtual:a03a909c3f5870829b2a1f1c58cd72dd0904272c636f0500be601a3bd781404d19a891ad23156b2b680426d08dbfc464b1e4ab195d463ee4ff16262a9e851f5e#npm:4.4.0"],\ + ["eslint-plugin-vue", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:9.17.0"],\ + ["@eslint-community/eslint-utils", "virtual:84c6b60ea80c2e474ae2eb1949a4b42a725b5ad125a348fd9ccd31d528ef15de82d28192a86b98baf21067fd8c90bd02753cac42e9ee96bf5f8084788455b3e4#npm:4.4.0"],\ ["@types/eslint", null],\ - ["eslint", "npm:8.45.0"],\ + ["eslint", "npm:8.47.0"],\ ["natural-compare", "npm:1.4.0"],\ ["nth-check", "npm:2.1.1"],\ ["postcss-selector-parser", "npm:6.0.13"],\ ["semver", "npm:7.5.4"],\ - ["vue-eslint-parser", "virtual:3fd334a0979036e65c7ec1ddc81d4f430fc73cf88b23447bbea68e11677926afefc90ff6a0eaff2ade480382733ea5c63f31601fb26346981b5cb3dc503d8c0f#npm:9.3.1"],\ + ["vue-eslint-parser", "virtual:e39e5d6bef7a93bd3b21c5c9ba6ef825c92fc73c8d9c9e01699e1dc11e40fd3bc150ba16509e2cf59495cb098c32b2e4a85c0c21802fddeffc3208b01f4f5a16#npm:9.3.1"],\ ["xml-name-validator", "npm:4.0.0"]\ ],\ "packagePeers": [\ @@ -4983,10 +4982,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ],\ "linkType": "HARD"\ }],\ - ["npm:7.2.0", {\ - "packageLocation": "./.yarn/cache/eslint-scope-npm-7.2.0-88784f5a38-64591a2d8b.zip/node_modules/eslint-scope/",\ + ["npm:7.2.2", {\ + "packageLocation": "./.yarn/cache/eslint-scope-npm-7.2.2-53cb0df8e8-ec97dbf5fb.zip/node_modules/eslint-scope/",\ "packageDependencies": [\ - ["eslint-scope", "npm:7.2.0"],\ + ["eslint-scope", "npm:7.2.2"],\ ["esrecurse", "npm:4.3.0"],\ ["estraverse", "npm:5.3.0"]\ ],\ @@ -5024,6 +5023,13 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["eslint-visitor-keys", "npm:3.4.1"]\ ],\ "linkType": "HARD"\ + }],\ + ["npm:3.4.3", {\ + "packageLocation": "./.yarn/cache/eslint-visitor-keys-npm-3.4.3-a356ac7e46-36e9ef87fc.zip/node_modules/eslint-visitor-keys/",\ + "packageDependencies": [\ + ["eslint-visitor-keys", "npm:3.4.3"]\ + ],\ + "linkType": "HARD"\ }]\ ]],\ ["espree", [\ @@ -5461,13 +5467,6 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]\ ]],\ ["globals", [\ - ["npm:11.12.0", {\ - "packageLocation": "./.yarn/cache/globals-npm-11.12.0-1fa7f41a6c-67051a45ec.zip/node_modules/globals/",\ - "packageDependencies": [\ - ["globals", "npm:11.12.0"]\ - ],\ - "linkType": "HARD"\ - }],\ ["npm:13.15.0", {\ "packageLocation": "./.yarn/cache/globals-npm-13.15.0-c0b0c83a7a-383ade0873.zip/node_modules/globals/",\ "packageDependencies": [\ @@ -5483,6 +5482,14 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["type-fest", "npm:0.20.2"]\ ],\ "linkType": "HARD"\ + }],\ + ["npm:13.21.0", {\ + "packageLocation": "./.yarn/cache/globals-npm-13.21.0-c0829ce1cb-86c92ca8a0.zip/node_modules/globals/",\ + "packageDependencies": [\ + ["globals", "npm:13.21.0"],\ + ["type-fest", "npm:0.20.2"]\ + ],\ + "linkType": "HARD"\ }]\ ]],\ ["globalthis", [\ @@ -5633,20 +5640,20 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]\ ]],\ ["html-validate", [\ - ["npm:8.1.0", {\ - "packageLocation": "./.yarn/cache/html-validate-npm-8.1.0-2e8bfe64f2-179443c0bd.zip/node_modules/html-validate/",\ + ["npm:8.2.0", {\ + "packageLocation": "./.yarn/cache/html-validate-npm-8.2.0-51da0ed7e6-793287a454.zip/node_modules/html-validate/",\ "packageDependencies": [\ - ["html-validate", "npm:8.1.0"]\ + ["html-validate", "npm:8.2.0"]\ ],\ "linkType": "SOFT"\ }],\ - ["virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:8.1.0", {\ - "packageLocation": "./.yarn/__virtual__/html-validate-virtual-bbfdcb87fd/0/cache/html-validate-npm-8.1.0-2e8bfe64f2-179443c0bd.zip/node_modules/html-validate/",\ + ["virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:8.2.0", {\ + "packageLocation": "./.yarn/__virtual__/html-validate-virtual-d54cf140bc/0/cache/html-validate-npm-8.2.0-51da0ed7e6-793287a454.zip/node_modules/html-validate/",\ "packageDependencies": [\ - ["html-validate", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:8.1.0"],\ + ["html-validate", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:8.2.0"],\ ["@babel/code-frame", "npm:7.16.7"],\ ["@html-validate/stylish", "npm:4.1.0"],\ - ["@sidvind/better-ajv-errors", "virtual:bbfdcb87fdcbacbba9ebe8ba4b476510d780b50c748b7a71307807b8e2c47cca6be20627a384f24b655b80a0ab5fd5b193ef3274afb79c45d120013674fc6a35#npm:2.0.0"],\ + ["@sidvind/better-ajv-errors", "virtual:d54cf140bc899b791890b50d03f9737577eb8c2e0b480e2b1bc40b168f05a300b97a0338d73f013a8f7410236526aba6ee56a063db404e7ae64ba5f1e4e85cb8#npm:2.0.0"],\ ["@types/jest", null],\ ["@types/jest-diff", null],\ ["@types/jest-snapshot", null],\ @@ -6683,10 +6690,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]\ ]],\ ["luxon", [\ - ["npm:3.3.0", {\ - "packageLocation": "./.yarn/cache/luxon-npm-3.3.0-bdbae9bfd5-50cf17a0dc.zip/node_modules/luxon/",\ + ["npm:3.4.0", {\ + "packageLocation": "./.yarn/cache/luxon-npm-3.4.0-8e0b97226e-ca9b6d0e0a.zip/node_modules/luxon/",\ "packageDependencies": [\ - ["luxon", "npm:3.3.0"]\ + ["luxon", "npm:3.4.0"]\ ],\ "linkType": "HARD"\ }]\ @@ -8014,16 +8021,6 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["supports-preserve-symlinks-flag", "npm:1.0.0"]\ ],\ "linkType": "HARD"\ - }],\ - ["patch:resolve@npm%3A1.22.4#~builtin::version=1.22.4&hash=07638b", {\ - "packageLocation": "./.yarn/cache/resolve-patch-5850eadd70-c45f2545fd.zip/node_modules/resolve/",\ - "packageDependencies": [\ - ["resolve", "patch:resolve@npm%3A1.22.4#~builtin::version=1.22.4&hash=07638b"],\ - ["is-core-module", "npm:2.13.0"],\ - ["path-parse", "npm:1.0.7"],\ - ["supports-preserve-symlinks-flag", "npm:1.0.0"]\ - ],\ - "linkType": "HARD"\ }]\ ]],\ ["resolve-from", [\ @@ -8100,9 +8097,9 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["@parcel/transformer-inline-string", "npm:2.9.3"],\ ["@parcel/transformer-sass", "npm:2.9.3"],\ ["@popperjs/core", "npm:2.11.8"],\ - ["@rollup/pluginutils", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:5.0.2"],\ + ["@rollup/pluginutils", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:5.0.3"],\ ["@twuni/emojify", "npm:1.0.2"],\ - ["@vitejs/plugin-vue", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:4.2.3"],\ + ["@vitejs/plugin-vue", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:4.3.3"],\ ["bootstrap", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:5.3.0"],\ ["bootstrap-icons", "npm:1.10.5"],\ ["browser-fs-access", "npm:0.34.1"],\ @@ -8110,17 +8107,17 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["c8", "npm:8.0.1"],\ ["caniuse-lite", "npm:1.0.30001519"],\ ["d3", "npm:7.8.5"],\ - ["eslint", "npm:8.45.0"],\ + ["eslint", "npm:8.47.0"],\ ["eslint-config-standard", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:17.1.0"],\ - ["eslint-plugin-cypress", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.13.3"],\ - ["eslint-plugin-import", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.28.0"],\ + ["eslint-plugin-cypress", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.14.0"],\ + ["eslint-plugin-import", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.28.1"],\ ["eslint-plugin-n", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:16.0.1"],\ ["eslint-plugin-node", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:11.1.0"],\ ["eslint-plugin-promise", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:6.1.1"],\ - ["eslint-plugin-vue", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:9.16.1"],\ + ["eslint-plugin-vue", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:9.17.0"],\ ["file-saver", "npm:2.0.5"],\ ["highcharts", "npm:11.1.0"],\ - ["html-validate", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:8.1.0"],\ + ["html-validate", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:8.2.0"],\ ["ical.js", "npm:1.5.0"],\ ["jquery", "npm:3.7.0"],\ ["jquery-migrate", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:3.4.1"],\ @@ -8128,7 +8125,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["list.js", "npm:2.3.1"],\ ["lodash", "npm:4.17.21"],\ ["lodash-es", "npm:4.17.21"],\ - ["luxon", "npm:3.3.0"],\ + ["luxon", "npm:3.4.0"],\ ["moment", "npm:2.29.4"],\ ["moment-timezone", "npm:0.5.43"],\ ["ms", "npm:2.1.3"],\ @@ -8138,7 +8135,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["pinia", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.1.6"],\ ["pinia-plugin-persist", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:1.0.0"],\ ["pug", "npm:3.0.2"],\ - ["sass", "npm:1.64.1"],\ + ["sass", "npm:1.66.1"],\ ["seedrandom", "npm:3.0.5"],\ ["select2", "npm:4.1.0-rc.0"],\ ["select2-bootstrap-5-theme", "npm:1.3.0"],\ @@ -8146,7 +8143,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["shepherd.js", "npm:11.1.1"],\ ["slugify", "npm:1.6.6"],\ ["sortablejs", "npm:1.15.0"],\ - ["vanillajs-datepicker", "npm:1.3.3"],\ + ["vanillajs-datepicker", "npm:1.3.4"],\ ["vite", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:4.4.9"],\ ["vue", "npm:3.3.4"],\ ["vue-router", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:4.2.4"],\ @@ -8235,10 +8232,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ],\ "linkType": "HARD"\ }],\ - ["npm:1.64.1", {\ - "packageLocation": "./.yarn/cache/sass-npm-1.64.1-d9daafa43e-e908f96f3d.zip/node_modules/sass/",\ + ["npm:1.66.1", {\ + "packageLocation": "./.yarn/cache/sass-npm-1.66.1-563acb4a8f-74fc11d0fc.zip/node_modules/sass/",\ "packageDependencies": [\ - ["sass", "npm:1.64.1"],\ + ["sass", "npm:1.66.1"],\ ["chokidar", "npm:3.5.3"],\ ["immutable", "npm:4.0.0"],\ ["source-map-js", "npm:1.0.2"]\ @@ -8965,10 +8962,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]\ ]],\ ["vanillajs-datepicker", [\ - ["npm:1.3.3", {\ - "packageLocation": "./.yarn/cache/vanillajs-datepicker-npm-1.3.3-c1fde0e681-be830750a5.zip/node_modules/vanillajs-datepicker/",\ + ["npm:1.3.4", {\ + "packageLocation": "./.yarn/cache/vanillajs-datepicker-npm-1.3.4-bc86e15a9c-830958f8af.zip/node_modules/vanillajs-datepicker/",\ "packageDependencies": [\ - ["vanillajs-datepicker", "npm:1.3.3"]\ + ["vanillajs-datepicker", "npm:1.3.4"]\ ],\ "linkType": "HARD"\ }]\ @@ -9021,7 +9018,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["lightningcss", null],\ ["postcss", "npm:8.4.27"],\ ["rollup", "npm:3.28.0"],\ - ["sass", "npm:1.64.1"],\ + ["sass", "npm:1.66.1"],\ ["stylus", null],\ ["sugarss", null],\ ["terser", null]\ @@ -9148,13 +9145,13 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ],\ "linkType": "SOFT"\ }],\ - ["virtual:3fd334a0979036e65c7ec1ddc81d4f430fc73cf88b23447bbea68e11677926afefc90ff6a0eaff2ade480382733ea5c63f31601fb26346981b5cb3dc503d8c0f#npm:9.3.1", {\ - "packageLocation": "./.yarn/__virtual__/vue-eslint-parser-virtual-6364f2b44e/0/cache/vue-eslint-parser-npm-9.3.1-a0feb51670-6d1476b45f.zip/node_modules/vue-eslint-parser/",\ + ["virtual:e39e5d6bef7a93bd3b21c5c9ba6ef825c92fc73c8d9c9e01699e1dc11e40fd3bc150ba16509e2cf59495cb098c32b2e4a85c0c21802fddeffc3208b01f4f5a16#npm:9.3.1", {\ + "packageLocation": "./.yarn/__virtual__/vue-eslint-parser-virtual-a1cfa0fa2e/0/cache/vue-eslint-parser-npm-9.3.1-a0feb51670-6d1476b45f.zip/node_modules/vue-eslint-parser/",\ "packageDependencies": [\ - ["vue-eslint-parser", "virtual:3fd334a0979036e65c7ec1ddc81d4f430fc73cf88b23447bbea68e11677926afefc90ff6a0eaff2ade480382733ea5c63f31601fb26346981b5cb3dc503d8c0f#npm:9.3.1"],\ + ["vue-eslint-parser", "virtual:e39e5d6bef7a93bd3b21c5c9ba6ef825c92fc73c8d9c9e01699e1dc11e40fd3bc150ba16509e2cf59495cb098c32b2e4a85c0c21802fddeffc3208b01f4f5a16#npm:9.3.1"],\ ["@types/eslint", null],\ ["debug", "virtual:b86a9fb34323a98c6519528ed55faa0d9b44ca8879307c0b29aa384bde47ff59a7d0c9051b31246f14521dfb71ba3c5d6d0b35c29fffc17bf875aa6ad977d9e8#npm:4.3.4"],\ - ["eslint", "npm:8.45.0"],\ + ["eslint", "npm:8.47.0"],\ ["eslint-scope", "npm:7.1.1"],\ ["eslint-visitor-keys", "npm:3.3.0"],\ ["espree", "npm:9.3.2"],\ diff --git a/.yarn/cache/@eslint-community-regexpp-npm-4.4.1-44c7391499-db97d8d08e.zip b/.yarn/cache/@eslint-community-regexpp-npm-4.4.1-44c7391499-db97d8d08e.zip deleted file mode 100644 index 7399004e87..0000000000 Binary files a/.yarn/cache/@eslint-community-regexpp-npm-4.4.1-44c7391499-db97d8d08e.zip and /dev/null differ diff --git a/.yarn/cache/@eslint-community-regexpp-npm-4.8.0-92ece47e3d-601e6d033d.zip b/.yarn/cache/@eslint-community-regexpp-npm-4.8.0-92ece47e3d-601e6d033d.zip new file mode 100644 index 0000000000..0cbfbf8d84 Binary files /dev/null and b/.yarn/cache/@eslint-community-regexpp-npm-4.8.0-92ece47e3d-601e6d033d.zip differ diff --git a/.yarn/cache/@eslint-js-npm-8.44.0-66b473d41b-fc53958322.zip b/.yarn/cache/@eslint-js-npm-8.48.0-cee42a7097-b2755f9c0e.zip similarity index 50% rename from .yarn/cache/@eslint-js-npm-8.44.0-66b473d41b-fc53958322.zip rename to .yarn/cache/@eslint-js-npm-8.48.0-cee42a7097-b2755f9c0e.zip index 894199cac8..fc49095695 100644 Binary files a/.yarn/cache/@eslint-js-npm-8.44.0-66b473d41b-fc53958322.zip and b/.yarn/cache/@eslint-js-npm-8.48.0-cee42a7097-b2755f9c0e.zip differ diff --git a/.yarn/cache/@rollup-pluginutils-npm-5.0.2-6aa9d0ddd4-edea15e543.zip b/.yarn/cache/@rollup-pluginutils-npm-5.0.2-6aa9d0ddd4-edea15e543.zip deleted file mode 100644 index d898c5035c..0000000000 Binary files a/.yarn/cache/@rollup-pluginutils-npm-5.0.2-6aa9d0ddd4-edea15e543.zip and /dev/null differ diff --git a/.yarn/cache/@rollup-pluginutils-npm-5.0.3-33f9e7f020-8efbdeac53.zip b/.yarn/cache/@rollup-pluginutils-npm-5.0.3-33f9e7f020-8efbdeac53.zip new file mode 100644 index 0000000000..e8af597352 Binary files /dev/null and b/.yarn/cache/@rollup-pluginutils-npm-5.0.3-33f9e7f020-8efbdeac53.zip differ diff --git a/.yarn/cache/@vitejs-plugin-vue-npm-4.2.3-f2af5ce2fe-1c70c1cd18.zip b/.yarn/cache/@vitejs-plugin-vue-npm-4.2.3-f2af5ce2fe-1c70c1cd18.zip deleted file mode 100644 index 4060d82440..0000000000 Binary files a/.yarn/cache/@vitejs-plugin-vue-npm-4.2.3-f2af5ce2fe-1c70c1cd18.zip and /dev/null differ diff --git a/.yarn/cache/@vitejs-plugin-vue-npm-4.3.3-ffc8f9f2ac-17f8d73708.zip b/.yarn/cache/@vitejs-plugin-vue-npm-4.3.3-ffc8f9f2ac-17f8d73708.zip new file mode 100644 index 0000000000..4f77fdcf56 Binary files /dev/null and b/.yarn/cache/@vitejs-plugin-vue-npm-4.3.3-ffc8f9f2ac-17f8d73708.zip differ diff --git a/.yarn/cache/eslint-npm-8.45.0-a03a909c3f-3e6dcce5cc.zip b/.yarn/cache/eslint-npm-8.47.0-84c6b60ea8-1988617f70.zip similarity index 87% rename from .yarn/cache/eslint-npm-8.45.0-a03a909c3f-3e6dcce5cc.zip rename to .yarn/cache/eslint-npm-8.47.0-84c6b60ea8-1988617f70.zip index 3b473d8f44..1f79008bdd 100644 Binary files a/.yarn/cache/eslint-npm-8.45.0-a03a909c3f-3e6dcce5cc.zip and b/.yarn/cache/eslint-npm-8.47.0-84c6b60ea8-1988617f70.zip differ diff --git a/.yarn/cache/eslint-plugin-cypress-npm-2.13.3-0ad3bff9c9-9affbcee29.zip b/.yarn/cache/eslint-plugin-cypress-npm-2.14.0-4d90862e1d-3fa118a757.zip similarity index 78% rename from .yarn/cache/eslint-plugin-cypress-npm-2.13.3-0ad3bff9c9-9affbcee29.zip rename to .yarn/cache/eslint-plugin-cypress-npm-2.14.0-4d90862e1d-3fa118a757.zip index 8ba449dd87..df90e603ba 100644 Binary files a/.yarn/cache/eslint-plugin-cypress-npm-2.13.3-0ad3bff9c9-9affbcee29.zip and b/.yarn/cache/eslint-plugin-cypress-npm-2.14.0-4d90862e1d-3fa118a757.zip differ diff --git a/.yarn/cache/eslint-plugin-import-npm-2.28.0-7894c48955-f9eba311b9.zip b/.yarn/cache/eslint-plugin-import-npm-2.28.1-2056ddf35c-e8ae6dd8f0.zip similarity index 74% rename from .yarn/cache/eslint-plugin-import-npm-2.28.0-7894c48955-f9eba311b9.zip rename to .yarn/cache/eslint-plugin-import-npm-2.28.1-2056ddf35c-e8ae6dd8f0.zip index 2611aaf350..694db7307d 100644 Binary files a/.yarn/cache/eslint-plugin-import-npm-2.28.0-7894c48955-f9eba311b9.zip and b/.yarn/cache/eslint-plugin-import-npm-2.28.1-2056ddf35c-e8ae6dd8f0.zip differ diff --git a/.yarn/cache/eslint-plugin-vue-npm-9.16.1-4e9625bf90-b2f9d0deef.zip b/.yarn/cache/eslint-plugin-vue-npm-9.17.0-c32115eab8-2ef53a0387.zip similarity index 92% rename from .yarn/cache/eslint-plugin-vue-npm-9.16.1-4e9625bf90-b2f9d0deef.zip rename to .yarn/cache/eslint-plugin-vue-npm-9.17.0-c32115eab8-2ef53a0387.zip index 72bb6a8fa2..2453c1f228 100644 Binary files a/.yarn/cache/eslint-plugin-vue-npm-9.16.1-4e9625bf90-b2f9d0deef.zip and b/.yarn/cache/eslint-plugin-vue-npm-9.17.0-c32115eab8-2ef53a0387.zip differ diff --git a/.yarn/cache/eslint-scope-npm-7.2.0-88784f5a38-64591a2d8b.zip b/.yarn/cache/eslint-scope-npm-7.2.2-53cb0df8e8-ec97dbf5fb.zip similarity index 64% rename from .yarn/cache/eslint-scope-npm-7.2.0-88784f5a38-64591a2d8b.zip rename to .yarn/cache/eslint-scope-npm-7.2.2-53cb0df8e8-ec97dbf5fb.zip index 466323f2bc..29b002eb98 100644 Binary files a/.yarn/cache/eslint-scope-npm-7.2.0-88784f5a38-64591a2d8b.zip and b/.yarn/cache/eslint-scope-npm-7.2.2-53cb0df8e8-ec97dbf5fb.zip differ diff --git a/.yarn/cache/eslint-visitor-keys-npm-3.4.3-a356ac7e46-36e9ef87fc.zip b/.yarn/cache/eslint-visitor-keys-npm-3.4.3-a356ac7e46-36e9ef87fc.zip new file mode 100644 index 0000000000..7c61b814bf Binary files /dev/null and b/.yarn/cache/eslint-visitor-keys-npm-3.4.3-a356ac7e46-36e9ef87fc.zip differ diff --git a/.yarn/cache/globals-npm-11.12.0-1fa7f41a6c-67051a45ec.zip b/.yarn/cache/globals-npm-11.12.0-1fa7f41a6c-67051a45ec.zip deleted file mode 100644 index 306b5aacad..0000000000 Binary files a/.yarn/cache/globals-npm-11.12.0-1fa7f41a6c-67051a45ec.zip and /dev/null differ diff --git a/.yarn/cache/globals-npm-13.21.0-c0829ce1cb-86c92ca8a0.zip b/.yarn/cache/globals-npm-13.21.0-c0829ce1cb-86c92ca8a0.zip new file mode 100644 index 0000000000..597f67a92e Binary files /dev/null and b/.yarn/cache/globals-npm-13.21.0-c0829ce1cb-86c92ca8a0.zip differ diff --git a/.yarn/cache/html-validate-npm-8.1.0-2e8bfe64f2-179443c0bd.zip b/.yarn/cache/html-validate-npm-8.1.0-2e8bfe64f2-179443c0bd.zip deleted file mode 100644 index 832eb25cc0..0000000000 Binary files a/.yarn/cache/html-validate-npm-8.1.0-2e8bfe64f2-179443c0bd.zip and /dev/null differ diff --git a/.yarn/cache/html-validate-npm-8.2.0-51da0ed7e6-793287a454.zip b/.yarn/cache/html-validate-npm-8.2.0-51da0ed7e6-793287a454.zip new file mode 100644 index 0000000000..818e294550 Binary files /dev/null and b/.yarn/cache/html-validate-npm-8.2.0-51da0ed7e6-793287a454.zip differ diff --git a/.yarn/cache/luxon-npm-3.3.0-bdbae9bfd5-50cf17a0dc.zip b/.yarn/cache/luxon-npm-3.3.0-bdbae9bfd5-50cf17a0dc.zip deleted file mode 100644 index e70d3dc06d..0000000000 Binary files a/.yarn/cache/luxon-npm-3.3.0-bdbae9bfd5-50cf17a0dc.zip and /dev/null differ diff --git a/.yarn/cache/luxon-npm-3.4.0-8e0b97226e-ca9b6d0e0a.zip b/.yarn/cache/luxon-npm-3.4.0-8e0b97226e-ca9b6d0e0a.zip new file mode 100644 index 0000000000..6be5a9ac07 Binary files /dev/null and b/.yarn/cache/luxon-npm-3.4.0-8e0b97226e-ca9b6d0e0a.zip differ diff --git a/.yarn/cache/resolve-npm-1.22.4-faa4f32bdd-23f25174c2.zip b/.yarn/cache/resolve-npm-1.22.4-faa4f32bdd-23f25174c2.zip deleted file mode 100644 index 68a76ad2e7..0000000000 Binary files a/.yarn/cache/resolve-npm-1.22.4-faa4f32bdd-23f25174c2.zip and /dev/null differ diff --git a/.yarn/cache/resolve-patch-5850eadd70-c45f2545fd.zip b/.yarn/cache/resolve-patch-5850eadd70-c45f2545fd.zip deleted file mode 100644 index b7fb862603..0000000000 Binary files a/.yarn/cache/resolve-patch-5850eadd70-c45f2545fd.zip and /dev/null differ diff --git a/.yarn/cache/sass-npm-1.64.1-d9daafa43e-e908f96f3d.zip b/.yarn/cache/sass-npm-1.64.1-d9daafa43e-e908f96f3d.zip deleted file mode 100644 index 91e2f8af25..0000000000 Binary files a/.yarn/cache/sass-npm-1.64.1-d9daafa43e-e908f96f3d.zip and /dev/null differ diff --git a/.yarn/cache/sass-npm-1.66.1-563acb4a8f-74fc11d0fc.zip b/.yarn/cache/sass-npm-1.66.1-563acb4a8f-74fc11d0fc.zip new file mode 100644 index 0000000000..6502f76bad Binary files /dev/null and b/.yarn/cache/sass-npm-1.66.1-563acb4a8f-74fc11d0fc.zip differ diff --git a/.yarn/cache/vanillajs-datepicker-npm-1.3.3-c1fde0e681-be830750a5.zip b/.yarn/cache/vanillajs-datepicker-npm-1.3.4-bc86e15a9c-830958f8af.zip similarity index 73% rename from .yarn/cache/vanillajs-datepicker-npm-1.3.3-c1fde0e681-be830750a5.zip rename to .yarn/cache/vanillajs-datepicker-npm-1.3.4-bc86e15a9c-830958f8af.zip index a48ca28cfa..151d4c9230 100644 Binary files a/.yarn/cache/vanillajs-datepicker-npm-1.3.3-c1fde0e681-be830750a5.zip and b/.yarn/cache/vanillajs-datepicker-npm-1.3.4-bc86e15a9c-830958f8af.zip differ diff --git a/dev/coverage-action/package-lock.json b/dev/coverage-action/package-lock.json index 062053d1d9..8de5686e3b 100644 --- a/dev/coverage-action/package-lock.json +++ b/dev/coverage-action/package-lock.json @@ -14,12 +14,12 @@ "chart.js": "3.5.1", "chartjs-node-canvas": "4.1.6", "lodash": "4.17.21", - "luxon": "3.3.0" + "luxon": "3.4.0" }, "devDependencies": { - "eslint": "8.45.0", + "eslint": "8.47.0", "eslint-config-standard": "17.1.0", - "eslint-plugin-import": "2.28.0", + "eslint-plugin-import": "2.28.1", "eslint-plugin-node": "11.1.0", "eslint-plugin-promise": "6.1.1", "npm-check-updates": "16.10.16" @@ -88,18 +88,18 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.4.0.tgz", - "integrity": "sha512-A9983Q0LnDGdLPjxyXQ00sbV+K+O+ko2Dr+CZigbHWtX9pNfxlaBkMR8X1CztI73zuEyEBXTVjx7CE+/VSwDiQ==", + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.8.0.tgz", + "integrity": "sha512-JylOEEzDiOryeUnFbQz+oViCXS0KsvR1mvHkoMiu5+UiBvy+RYX7tzlIIIEstF/gVa2tj9AQXk3dgnxv6KxhFg==", "dev": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/eslintrc": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.1.tgz", - "integrity": "sha512-9t7ZA7NGGK8ckelF0PQCfcxIUzs1Md5rrO6U/c+FIQNanea5UZC0wqKXH4vHBccmu4ZJgZ2idtPeW7+Q2npOEA==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", + "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", "dev": true, "dependencies": { "ajv": "^6.12.4", @@ -120,9 +120,9 @@ } }, "node_modules/@eslint/js": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.44.0.tgz", - "integrity": "sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw==", + "version": "8.48.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.48.0.tgz", + "integrity": "sha512-ZSjtmelB7IJfWD2Fvb7+Z+ChTIKWq6kjda95fLcQKNS5aheVHn4IkfgRQE3sIIzTcSLwLcLZUD9UBt+V7+h+Pw==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1765,27 +1765,27 @@ } }, "node_modules/eslint": { - "version": "8.45.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.45.0.tgz", - "integrity": "sha512-pd8KSxiQpdYRfYa9Wufvdoct3ZPQQuVuU5O6scNgMuOMYuxvH0IGaYK0wUFjo4UYYQQCUndlXiMbnxopwvvTiw==", + "version": "8.47.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.47.0.tgz", + "integrity": "sha512-spUQWrdPt+pRVP1TTJLmfRNJJHHZryFmptzcafwSvHsceV81djHOdnEeDmkdotZyLNjDhrOasNK8nikkoG1O8Q==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.1.0", - "@eslint/js": "8.44.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.2", + "@eslint/js": "^8.47.0", "@humanwhocodes/config-array": "^0.11.10", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.0", - "eslint-visitor-keys": "^3.4.1", - "espree": "^9.6.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -1913,9 +1913,9 @@ } }, "node_modules/eslint-plugin-import": { - "version": "2.28.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.28.0.tgz", - "integrity": "sha512-B8s/n+ZluN7sxj9eUf7/pRFERX0r5bnFA2dCaLHy2ZeaQEAz0k+ZZkFWRFHJAqxfxQDx6KLv9LeIki7cFdwW+Q==", + "version": "2.28.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.28.1.tgz", + "integrity": "sha512-9I9hFlITvOV55alzoKBI+K9q74kv0iKMeY6av5+umsNwayt59fz692daGyjR+oStBQgx6nwR9rXldDev3Clw+A==", "dev": true, "dependencies": { "array-includes": "^3.1.6", @@ -1927,13 +1927,12 @@ "eslint-import-resolver-node": "^0.3.7", "eslint-module-utils": "^2.8.0", "has": "^1.0.3", - "is-core-module": "^2.12.1", + "is-core-module": "^2.13.0", "is-glob": "^4.0.3", "minimatch": "^3.1.2", "object.fromentries": "^2.0.6", "object.groupby": "^1.0.0", "object.values": "^1.1.6", - "resolve": "^1.22.3", "semver": "^6.3.1", "tsconfig-paths": "^3.14.2" }, @@ -2117,9 +2116,9 @@ } }, "node_modules/eslint-scope": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", - "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, "dependencies": { "esrecurse": "^4.3.0", @@ -2157,9 +2156,9 @@ } }, "node_modules/eslint-visitor-keys": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", - "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2587,9 +2586,9 @@ } }, "node_modules/globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "version": "13.21.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", + "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -3551,9 +3550,9 @@ } }, "node_modules/luxon": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.3.0.tgz", - "integrity": "sha512-An0UCfG/rSiqtAIiBPO0Y9/zAnHUZxAMiCpTd5h2smgsj7GGmcenvrvww2cqNA8/4A5ZrD1gJpHN2mIHZQF+Mg==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.4.0.tgz", + "integrity": "sha512-7eDo4Pt7aGhoCheGFIuq4Xa2fJm4ZpmldpGhjTYBNUYNCN6TIEP6v7chwwwt3KRp7YR+rghbfvjyo3V5y9hgBw==", "engines": { "node": ">=12" } @@ -6124,15 +6123,15 @@ } }, "@eslint-community/regexpp": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.4.0.tgz", - "integrity": "sha512-A9983Q0LnDGdLPjxyXQ00sbV+K+O+ko2Dr+CZigbHWtX9pNfxlaBkMR8X1CztI73zuEyEBXTVjx7CE+/VSwDiQ==", + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.8.0.tgz", + "integrity": "sha512-JylOEEzDiOryeUnFbQz+oViCXS0KsvR1mvHkoMiu5+UiBvy+RYX7tzlIIIEstF/gVa2tj9AQXk3dgnxv6KxhFg==", "dev": true }, "@eslint/eslintrc": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.1.tgz", - "integrity": "sha512-9t7ZA7NGGK8ckelF0PQCfcxIUzs1Md5rrO6U/c+FIQNanea5UZC0wqKXH4vHBccmu4ZJgZ2idtPeW7+Q2npOEA==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", + "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", "dev": true, "requires": { "ajv": "^6.12.4", @@ -6147,9 +6146,9 @@ } }, "@eslint/js": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.44.0.tgz", - "integrity": "sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw==", + "version": "8.48.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.48.0.tgz", + "integrity": "sha512-ZSjtmelB7IJfWD2Fvb7+Z+ChTIKWq6kjda95fLcQKNS5aheVHn4IkfgRQE3sIIzTcSLwLcLZUD9UBt+V7+h+Pw==", "dev": true }, "@humanwhocodes/config-array": { @@ -7373,27 +7372,27 @@ "dev": true }, "eslint": { - "version": "8.45.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.45.0.tgz", - "integrity": "sha512-pd8KSxiQpdYRfYa9Wufvdoct3ZPQQuVuU5O6scNgMuOMYuxvH0IGaYK0wUFjo4UYYQQCUndlXiMbnxopwvvTiw==", + "version": "8.47.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.47.0.tgz", + "integrity": "sha512-spUQWrdPt+pRVP1TTJLmfRNJJHHZryFmptzcafwSvHsceV81djHOdnEeDmkdotZyLNjDhrOasNK8nikkoG1O8Q==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.1.0", - "@eslint/js": "8.44.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.2", + "@eslint/js": "^8.47.0", "@humanwhocodes/config-array": "^0.11.10", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.0", - "eslint-visitor-keys": "^3.4.1", - "espree": "^9.6.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -7488,9 +7487,9 @@ } }, "eslint-plugin-import": { - "version": "2.28.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.28.0.tgz", - "integrity": "sha512-B8s/n+ZluN7sxj9eUf7/pRFERX0r5bnFA2dCaLHy2ZeaQEAz0k+ZZkFWRFHJAqxfxQDx6KLv9LeIki7cFdwW+Q==", + "version": "2.28.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.28.1.tgz", + "integrity": "sha512-9I9hFlITvOV55alzoKBI+K9q74kv0iKMeY6av5+umsNwayt59fz692daGyjR+oStBQgx6nwR9rXldDev3Clw+A==", "dev": true, "requires": { "array-includes": "^3.1.6", @@ -7502,13 +7501,12 @@ "eslint-import-resolver-node": "^0.3.7", "eslint-module-utils": "^2.8.0", "has": "^1.0.3", - "is-core-module": "^2.12.1", + "is-core-module": "^2.13.0", "is-glob": "^4.0.3", "minimatch": "^3.1.2", "object.fromentries": "^2.0.6", "object.groupby": "^1.0.0", "object.values": "^1.1.6", - "resolve": "^1.22.3", "semver": "^6.3.1", "tsconfig-paths": "^3.14.2" }, @@ -7635,9 +7633,9 @@ "requires": {} }, "eslint-scope": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", - "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, "requires": { "esrecurse": "^4.3.0", @@ -7662,9 +7660,9 @@ } }, "eslint-visitor-keys": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", - "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true }, "espree": { @@ -7970,9 +7968,9 @@ } }, "globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "version": "13.21.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", + "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -8659,9 +8657,9 @@ } }, "luxon": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.3.0.tgz", - "integrity": "sha512-An0UCfG/rSiqtAIiBPO0Y9/zAnHUZxAMiCpTd5h2smgsj7GGmcenvrvww2cqNA8/4A5ZrD1gJpHN2mIHZQF+Mg==" + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.4.0.tgz", + "integrity": "sha512-7eDo4Pt7aGhoCheGFIuq4Xa2fJm4ZpmldpGhjTYBNUYNCN6TIEP6v7chwwwt3KRp7YR+rghbfvjyo3V5y9hgBw==" }, "make-dir": { "version": "3.1.0", diff --git a/dev/coverage-action/package.json b/dev/coverage-action/package.json index c2f0ed966b..37a889f803 100644 --- a/dev/coverage-action/package.json +++ b/dev/coverage-action/package.json @@ -11,12 +11,12 @@ "chart.js": "3.5.1", "chartjs-node-canvas": "4.1.6", "lodash": "4.17.21", - "luxon": "3.3.0" + "luxon": "3.4.0" }, "devDependencies": { - "eslint": "8.45.0", + "eslint": "8.47.0", "eslint-config-standard": "17.1.0", - "eslint-plugin-import": "2.28.0", + "eslint-plugin-import": "2.28.1", "eslint-plugin-node": "11.1.0", "eslint-plugin-promise": "6.1.1", "npm-check-updates": "16.10.16" diff --git a/dev/del-old-packages/package-lock.json b/dev/del-old-packages/package-lock.json index 6d846fb0bd..4675a41b61 100644 --- a/dev/del-old-packages/package-lock.json +++ b/dev/del-old-packages/package-lock.json @@ -10,7 +10,7 @@ "license": "ISC", "dependencies": { "@octokit/core": "^4.2.4", - "luxon": "^3.4.0" + "luxon": "^3.4.2" } }, "node_modules/@octokit/auth-token": { @@ -141,9 +141,9 @@ } }, "node_modules/luxon": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.4.0.tgz", - "integrity": "sha512-7eDo4Pt7aGhoCheGFIuq4Xa2fJm4ZpmldpGhjTYBNUYNCN6TIEP6v7chwwwt3KRp7YR+rghbfvjyo3V5y9hgBw==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.4.2.tgz", + "integrity": "sha512-uBoAVCVcajsrqy3pv7eo5jEUz1oeLmCcnMv8n4AJpT5hbpN9lUssAXibNElpbLce3Mhm9dyBzwYLs9zctM/0tA==", "engines": { "node": ">=12" } @@ -315,9 +315,9 @@ "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==" }, "luxon": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.4.0.tgz", - "integrity": "sha512-7eDo4Pt7aGhoCheGFIuq4Xa2fJm4ZpmldpGhjTYBNUYNCN6TIEP6v7chwwwt3KRp7YR+rghbfvjyo3V5y9hgBw==" + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.4.2.tgz", + "integrity": "sha512-uBoAVCVcajsrqy3pv7eo5jEUz1oeLmCcnMv8n4AJpT5hbpN9lUssAXibNElpbLce3Mhm9dyBzwYLs9zctM/0tA==" }, "node-fetch": { "version": "2.6.7", diff --git a/dev/del-old-packages/package.json b/dev/del-old-packages/package.json index 5b38fe6872..26fc4cec3f 100644 --- a/dev/del-old-packages/package.json +++ b/dev/del-old-packages/package.json @@ -11,6 +11,6 @@ "license": "ISC", "dependencies": { "@octokit/core": "^4.2.4", - "luxon": "^3.4.0" + "luxon": "^3.4.2" } } diff --git a/dev/diff/package-lock.json b/dev/diff/package-lock.json index db9112e460..08f85bca4e 100644 --- a/dev/diff/package-lock.json +++ b/dev/diff/package-lock.json @@ -15,7 +15,7 @@ "keypress": "^0.2.1", "listr2": "^6.6.1", "lodash-es": "^4.17.21", - "luxon": "^3.3.0", + "luxon": "^3.4.0", "pretty-bytes": "^6.1.1", "tar": "^6.1.15", "yargs": "^17.7.2" @@ -859,9 +859,9 @@ } }, "node_modules/luxon": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.3.0.tgz", - "integrity": "sha512-An0UCfG/rSiqtAIiBPO0Y9/zAnHUZxAMiCpTd5h2smgsj7GGmcenvrvww2cqNA8/4A5ZrD1gJpHN2mIHZQF+Mg==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.4.0.tgz", + "integrity": "sha512-7eDo4Pt7aGhoCheGFIuq4Xa2fJm4ZpmldpGhjTYBNUYNCN6TIEP6v7chwwwt3KRp7YR+rghbfvjyo3V5y9hgBw==", "engines": { "node": ">=12" } @@ -1950,9 +1950,9 @@ "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==" }, "luxon": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.3.0.tgz", - "integrity": "sha512-An0UCfG/rSiqtAIiBPO0Y9/zAnHUZxAMiCpTd5h2smgsj7GGmcenvrvww2cqNA8/4A5ZrD1gJpHN2mIHZQF+Mg==" + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.4.0.tgz", + "integrity": "sha512-7eDo4Pt7aGhoCheGFIuq4Xa2fJm4ZpmldpGhjTYBNUYNCN6TIEP6v7chwwwt3KRp7YR+rghbfvjyo3V5y9hgBw==" }, "mimic-fn": { "version": "2.1.0", diff --git a/dev/diff/package.json b/dev/diff/package.json index 0e88dcad9f..34749cb667 100644 --- a/dev/diff/package.json +++ b/dev/diff/package.json @@ -11,7 +11,7 @@ "keypress": "^0.2.1", "listr2": "^6.6.1", "lodash-es": "^4.17.21", - "luxon": "^3.3.0", + "luxon": "^3.4.0", "pretty-bytes": "^6.1.1", "tar": "^6.1.15", "yargs": "^17.7.2" diff --git a/docker/configs/settings_local.py b/docker/configs/settings_local.py index 8178db1eff..07c16c2e9a 100644 --- a/docker/configs/settings_local.py +++ b/docker/configs/settings_local.py @@ -8,7 +8,6 @@ from ietf.settings_postgresqldb import DATABASES # pyflakes:ignore IDSUBMIT_IDNITS_BINARY = "/usr/local/bin/idnits" -IDSUBMIT_REPOSITORY_PATH = "test/id/" IDSUBMIT_STAGING_PATH = "test/staging/" AGENDA_PATH = '/assets/www6s/proceedings/' @@ -50,6 +49,7 @@ INTERNET_DRAFT_ARCHIVE_DIR = '/assets/archive/id' INTERNET_ALL_DRAFTS_ARCHIVE_DIR = '/assets/archive/id' BIBXML_BASE_PATH = '/assets/ietfdata/derived/bibxml' +IDSUBMIT_REPOSITORY_PATH = INTERNET_DRAFT_PATH NOMCOM_PUBLIC_KEYS_DIR = 'data/nomcom_keys/public_keys/' SLIDE_STAGING_PATH = 'test/staging/' diff --git a/ietf/doc/tests.py b/ietf/doc/tests.py index f66d77681e..7e6be2f4f7 100644 --- a/ietf/doc/tests.py +++ b/ietf/doc/tests.py @@ -2799,7 +2799,7 @@ def should_succeed(self, argdict): url = urlreverse(self.view, kwargs=argdict) r = self.client.get(url) self.assertEqual(r.status_code,200) - self.assertEqual(r.get('Content-Type'),'application/pdf;charset=utf-8') + self.assertEqual(r.get('Content-Type'),'application/pdf') def should_404(self, argdict): url = urlreverse(self.view, kwargs=argdict) diff --git a/ietf/doc/views_doc.py b/ietf/doc/views_doc.py index b9b9d89176..1c42bfa963 100644 --- a/ietf/doc/views_doc.py +++ b/ietf/doc/views_doc.py @@ -976,7 +976,7 @@ def document_pdfized(request, name, rev=None, ext=None): pdf = doc.pdfized() if pdf: - return HttpResponse(pdf,content_type='application/pdf;charset=utf-8') + return HttpResponse(pdf,content_type='application/pdf') else: raise Http404 diff --git a/ietf/group/admin.py b/ietf/group/admin.py index afaa87c0bc..5095b6b24d 100644 --- a/ietf/group/admin.py +++ b/ietf/group/admin.py @@ -5,6 +5,8 @@ from functools import update_wrapper +from base64 import b64encode + import debug # pyflakes:ignore from django import forms @@ -12,6 +14,7 @@ from django.contrib import admin from django.contrib.admin.utils import unquote from django.core.management import load_command_class +from django.db.models import BinaryField from django.http import Http404 from django.shortcuts import render from django.utils.encoding import force_str @@ -20,7 +23,7 @@ from ietf.group.models import (Group, GroupFeatures, GroupHistory, GroupEvent, GroupURL, GroupMilestone, GroupMilestoneHistory, GroupStateTransitions, Role, RoleHistory, ChangeStateGroupEvent, - MilestoneGroupEvent, GroupExtResource, ) + MilestoneGroupEvent, GroupExtResource, Appeal, AppealArtifact ) from ietf.name.models import GroupTypeName from ietf.utils.validators import validate_external_resource_value @@ -291,3 +294,52 @@ class GroupExtResourceAdmin(admin.ModelAdmin): search_fields = ['group__acronym', 'value', 'display_name', 'name__slug',] raw_id_fields = ['group', ] admin.site.register(GroupExtResource, GroupExtResourceAdmin) + +class AppealAdmin(admin.ModelAdmin): + list_display = ["group", "date", "name"] + search_fields = ["group__acronym", "date", "name"] + raw_id_fields = ["group"] +admin.site.register(Appeal, AppealAdmin) + +# From https://stackoverflow.com/questions/58529099/adding-file-upload-widget-for-binaryfield-to-django-admin +class BinaryFileInput(forms.ClearableFileInput): + + def is_initial(self, value): + """ + Return whether value is considered to be initial value. + """ + return bool(value) + + def format_value(self, value): + """Format the size of the value in the db. + + We can't render it's name or url, but we'd like to give some information + as to wether this file is not empty/corrupt. + """ + if self.is_initial(value): + return f'{len(value)} bytes' + + + def value_from_datadict(self, data, files, name): + """Return the file contents so they can be put in the db.""" + upload = super().value_from_datadict(data, files, name) + if upload: + bits = upload.read() + return b64encode(bits).decode("ascii") # Who made this so hard? + +class RestrictContentTypeChoicesForm(forms.ModelForm): + content_type = forms.ChoiceField( + choices=( + ( "text/markdown;charset=utf-8", "Markdown"), + ( "application/pdf", "PDF") + ) + ) +class AppealArtifactAdmin(admin.ModelAdmin): + list_display = ["display_title", "appeal","date"] + ordering = ["-appeal__date", "date"] + formfield_overrides = { + BinaryField: { "widget": BinaryFileInput() }, + } + form = RestrictContentTypeChoicesForm + +admin.site.register(AppealArtifact, AppealArtifactAdmin) diff --git a/ietf/group/factories.py b/ietf/group/factories.py index d56fcf7212..8968b9b4c1 100644 --- a/ietf/group/factories.py +++ b/ietf/group/factories.py @@ -7,8 +7,16 @@ from django.utils import timezone -from ietf.group.models import Group, Role, GroupEvent, GroupMilestone, \ - GroupHistory, RoleHistory +from ietf.group.models import ( + Appeal, + AppealArtifact, + Group, + GroupEvent, + GroupMilestone, + GroupHistory, + Role, + RoleHistory +) from ietf.review.factories import ReviewTeamSettingsFactory from ietf.utils.timezone import date_today @@ -120,3 +128,34 @@ class Meta: person = factory.SubFactory('ietf.person.factories.PersonFactory') email = factory.LazyAttribute(lambda obj: obj.person.email()) +class AppealFactory(factory.django.DjangoModelFactory): + class Meta: + model=Appeal + + name=factory.Faker("sentence") + group=factory.SubFactory(GroupFactory, acronym="iab") + +class AppealArtifactFactory(factory.django.DjangoModelFactory): + class Meta: + model=AppealArtifact + + appeal = factory.SubFactory(AppealFactory) + artifact_type = factory.SubFactory("ietf.name.factories.AppealArtifactTypeNameFactory", slug="appeal") + content_type = "text/markdown;charset=utf-8" + # Needs newer factory_boy + # bits = factory.Transformer( + # "Some example **Markdown**", + # lambda o: memoryview(o.encode("utf-8") if isinstance(o,str) else o) + # ) + # + # Usage: a = AppealArtifactFactory(set_bits__using="foo bar") or + # a = AppealArtifactFactory(set_bits__using=b"foo bar") + @factory.post_generation + def set_bits(obj, create, extracted, **kwargs): + if not create: + return + using = kwargs.pop("using","Some example **Markdown**") + if isinstance(using, str): + using = using.encode("utf-8") + obj.bits = memoryview(using) + diff --git a/ietf/group/management/commands/import_iab_appeals.py b/ietf/group/management/commands/import_iab_appeals.py new file mode 100644 index 0000000000..bd62157c0f --- /dev/null +++ b/ietf/group/management/commands/import_iab_appeals.py @@ -0,0 +1,205 @@ +# Copyright The IETF Trust 2023, All Rights Reserved + +import debug # pyflakes: ignore + +import datetime +import shutil +import subprocess +import tempfile + +from pathlib import Path + +from django.core.management.base import BaseCommand + +from ietf.group.models import Appeal, AppealArtifact + +from ietf.name.models import AppealArtifactTypeName + + +PDF_FILES = [ + "2006-01-04-appeal.pdf", + "2006-08-24-appeal.pdf", + "2006-09-11-appeal.pdf", + "2008-11-29-appeal.pdf", + "2010-06-07-appeal.pdf", + "2010-06-07-response.pdf", + "2013-07-08-appeal.pdf", + "2015-06-22-appeal.pdf", + "2019-01-31-appeal.pdf", + "2019-01-31-response.pdf", +] + +NAME_PART_MAP = { + "appeal": "appeal", + "response": "response", + "appeal_with_response": "response", + "reply_to_response": "reply", +} + + +def bits_name(date, part): + part_type = part["type"] + name_fragment = NAME_PART_MAP[part_type] + prefix = f"{date:%Y-%m-%d}-{name_fragment}" + if f"{prefix}.pdf" in PDF_FILES: + ext = "pdf" + else: + ext = "md" + return f"{prefix}.{ext}" + + +def date_from_string(datestring): + year, month, day = [int(part) for part in datestring.split("-")] + return datetime.date(year, month, day) + + +def work_to_do(): + # Taken from https://www.iab.org/appeals/ on 2023-08-24 - some lines carved out below as exceptions + input = """ + 2020-07-31 IAB appeal for arpa assignment (Timothy McSweeney) IAB Response (2020-08-26) + 2019-01-31 An appeal to make the procedure related to Independent Submission Stream more transparent (Shyam Bandyopadhyay) IAB Response (2019-03-06) + 2015-06-22 Appeal to the IAB concerning the IESG response to his appeal concerning the IESG approval of the “draft-ietf-ianaplan-icg-response” (JFC Morfin) IAB Response (2015-07-08) + 2013-07-08 Appeal to the IAB irt. RFC 6852 (JFC Morfin) IAB Response (2013-07-17) + 2010-06-07 Appeal over the IESG Publication of the IDNA2008 Document Set Without Appropriate Explanation to the Internet Community (JFC Morfin) IAB Response (2010-08-20) + 2008-11-29 Appeal to the IAB Concerning the Way Users Are Not Permitted To Adequately Contribute to the IETF (JFC Morfin) IAB Response (2009-01-28) + 2006-10-10 Complaints about suspension from the ietf@ietf.org mailing list (Todd Glassey) IAB Response (2006-10-31) + 2006-09-11 Appeal to the IAB over IESG dismissed appeals from J-F C. Morfin (JFC Morfin) IAB Response (2006-12-05) + 2006-09-10 Appeal of IESG Decision of July 10, 2006 from Dean Anderson (Dean Anderson) IAB Response (2006-09-27) + 2006-08-24 Appeal Against the decision to consider expediting an RFC Publication from J-F C. Morfin (JFC Morfin) IAB Response (2006-09-07) + 2006-04-18 Appeal Against IESG PR-Action from Dean Anderson (Dean Anderson) IAB Response (2006-07-13) + 2006-02-08 Appeal Against IESG Decision by Julian Mehnle (Julian Mehnle) IAB Response (2006-03-02) + 2006-01-04 Appeal Against IESG Decision by Jefsey Morfin (JFC Morfin) IAB Response (2006-01-31) + 2003-01-04 Appeal against IESG decision (Robert Elz) IAB Response (includes original appeal)(2003-02-15) + 2000-11-15 Appeal Against IESG Action by Mr. D J Bernstein (D J Bernstein) IAB Response (2001-02-26) + 1999-10-23 Appeal against IESG Inaction by W.A. Simpson (William Allen Simpson) IAB Response (2000-01-11) + 1999-05-01 Appeal against IESG action (William Allen Simpson) IAB Response (1999-10-05) + 1996-03-06 Appeal SNMPv2 SMI Appeal by Mr. David T. Perkins, IAB consideration (David Perkins) IAB Response (includes original appeal) (1996-03-06) + """ + + work = [] + + for line in input.split("\n"): + line = line.strip() + if line == "": + continue + appeal_date = line[:10] + response_date = line[-11:-1] + title = line[11:-12].strip().split(")")[0] + ")" + item = dict(title=title, date=appeal_date, parts=[]) + if appeal_date in [ + "2006-10-10", + "2000-11-15", + "1999-10-23", + "1999-05-01", + "1996-03-06", + ]: + item["parts"].append(dict(type="appeal_with_response", date=response_date)) + else: + item["parts"].append(dict(type="appeal", date=appeal_date)) + item["parts"].append(dict(type="response", date=response_date)) + work.append(item) + + # Hand building the items for the following + # exceptions=""" + # 2003-10-09 Appeal to the IAB on the site-local issue (Tony Hain) + # IAB Response (2003-11-12) + # Tony Hain reply to IAB Response (2003-11-18) + # 1995-02-18 (etc.) Appeal Against IESG Inaction by Mr. Dave Cocker, Mr W. Simpson (Dave Crocker, William Allen Simpson) IAB Response (1995-04-04 and 1995-04-05) + # """ + item = dict( + title="Appeal to the IAB on the site-local issue (Tony Hain)", + date="2003-10-09", + parts=[], + ) + item["parts"].append( + dict( + type="appeal", + date="2003-10-09", + ) + ) + item["parts"].append( + dict( + type="response", + date="2003-11-12", + ) + ) + item["parts"].append( + dict( + type="reply_to_response", + date="2003-11-18", + ) + ) + work.append(item) + + item = dict( + title="Appeal Against IESG Inaction by Mr. Dave Cocker, Mr W. Simpson (Dave Crocker, William Allen Simpson)", + date="1995-02-18", + parts=[], + ) + item["parts"].append( + dict( + type="appeal", + date="1995-02-18", + ) + ) + item["parts"].append( + dict( + type="response", + date="1995-04-05", + ) + ) + work.append(item) + + for item in work: + item["date"] = date_from_string(item["date"]) + for part in item["parts"]: + part["date"] = date_from_string(part["date"]) + + work.sort(key=lambda o: o["date"]) + + return work + + +class Command(BaseCommand): + help = "Performs a one-time import of IAB appeals" + + def handle(self, *args, **options): + tmpdir = tempfile.mkdtemp() + process = subprocess.Popen( + ["git", "clone", "https://github.com/kesara/iab-scraper.git", tmpdir], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) + stdout, stderr = process.communicate() + if not Path(tmpdir).joinpath("iab_appeals", "1995-02-18-appeal.md").exists(): + print("Git clone of the iab-scraper directory did not go as expected") + print("stdout:", stdout) + print("stderr:", stderr) + print(f"Clean up {tmpdir} manually") + exit(-1) + + work = work_to_do() + + for item in work: + # IAB is group 7 + appeal = Appeal.objects.create(name=item["title"], date=item["date"], group_id=7) + for part in item["parts"]: + bits_file_name = bits_name(item["date"], part) + if bits_file_name.endswith(".pdf"): + content_type = "application/pdf" + else: + content_type = "text/markdown;charset=utf-8" + with Path(tmpdir).joinpath("iab_appeals", bits_file_name).open( + "rb" + ) as source_file: + bits = source_file.read() + artifact_type = AppealArtifactTypeName.objects.get(slug=part["type"]) + AppealArtifact.objects.create( + appeal = appeal, + artifact_type=artifact_type, + date=part["date"], + content_type=content_type, + bits=bits, + ) + + shutil.rmtree(tmpdir) diff --git a/ietf/group/migrations/0002_appeal.py b/ietf/group/migrations/0002_appeal.py new file mode 100644 index 0000000000..e993eba35b --- /dev/null +++ b/ietf/group/migrations/0002_appeal.py @@ -0,0 +1,83 @@ +# Copyright The IETF Trust 2023, All Rights Reserved + +from django.db import migrations, models +import django.db.models.deletion +import ietf.utils.models +import ietf.utils.timezone + + +class Migration(migrations.Migration): + dependencies = [ + ("name", "0007_appeal_artifact_typename"), + ("group", "0001_initial"), + ] + + operations = [ + migrations.CreateModel( + name="Appeal", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.CharField(max_length=512)), + ("date", models.DateField(default=ietf.utils.timezone.date_today)), + ( + "group", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to="group.group" + ), + ), + ], + options={ + "ordering": ["-date", "-id"], + }, + ), + migrations.CreateModel( + name="AppealArtifact", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("date", models.DateField(default=ietf.utils.timezone.date_today)), + ( + "title", + models.CharField( + blank=True, + help_text="The artifact_type.name will be used if this field is blank", + max_length=256, + ), + ), + ("order", models.IntegerField(default=0)), + ("content_type", models.CharField(max_length=32)), + ("bits", models.BinaryField(editable=True)), + ( + "appeal", + ietf.utils.models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="group.appeal" + ), + ), + ( + "artifact_type", + ietf.utils.models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="name.appealartifacttypename", + ), + ), + ], + options={ + "ordering": ["date", "order", "artifact_type__order"], + }, + ), + ] diff --git a/ietf/group/models.py b/ietf/group/models.py index 112522f2c9..52549e8cc1 100644 --- a/ietf/group/models.py +++ b/ietf/group/models.py @@ -13,16 +13,19 @@ from django.db.models.deletion import CASCADE, PROTECT from django.dispatch import receiver from django.utils import timezone +from django.utils.text import slugify import debug # pyflakes:ignore from ietf.name.models import (GroupStateName, GroupTypeName, DocTagName, GroupMilestoneStateName, RoleName, - AgendaTypeName, AgendaFilterTypeName, ExtResourceName, SessionPurposeName) + AgendaTypeName, AgendaFilterTypeName, ExtResourceName, SessionPurposeName, + AppealArtifactTypeName ) from ietf.person.models import Email, Person from ietf.utils.db import IETFJSONField from ietf.utils.mail import formataddr, send_mail_text from ietf.utils import log from ietf.utils.models import ForeignKey, OneToOneField +from ietf.utils.timezone import date_today from ietf.utils.validators import JSONForeignKeyListValidator @@ -409,6 +412,46 @@ def __str__(self): class Meta: verbose_name_plural = "role histories" +class Appeal(models.Model): + name = models.CharField(max_length=512) + group = models.ForeignKey(Group, on_delete=models.PROTECT) + date = models.DateField(default=date_today) + + class Meta: + ordering = ['-date', '-id'] + + def __str__(self): + return f"{self.date} - {self.name}" + +class AppealArtifact(models.Model): + appeal = ForeignKey(Appeal) + artifact_type = ForeignKey(AppealArtifactTypeName) + date = models.DateField(default=date_today) + title = models.CharField(max_length=256, blank=True, help_text="The artifact_type.name will be used if this field is blank") + order = models.IntegerField(default=0) + content_type = models.CharField(max_length=32) + # "Abusing" BinaryField (see the django docs) for the small number of + # these things we have on purpose. Later, any non-markdown content may + # move off into statics instead. + bits = models.BinaryField(editable=True) + + class Meta: + ordering = ['date', 'order', 'artifact_type__order'] + + def display_title(self): + if self.title != "": + return self.title + else: + return self.artifact_type.name + + def is_markdown(self): + return self.content_type == "text/markdown;charset=utf-8" + + def download_name(self): + return f"{self.date}-{slugify(self.display_title())}.{'md' if self.is_markdown() else 'pdf'}" + + def __str__(self): + return f"{self.date} {self.display_title()} : {self.appeal.name}" # --- Signal hooks for group models --- diff --git a/ietf/group/resources.py b/ietf/group/resources.py index 310fb5fb9b..698f50460a 100644 --- a/ietf/group/resources.py +++ b/ietf/group/resources.py @@ -13,7 +13,7 @@ from ietf.group.models import (Group, GroupStateTransitions, GroupMilestone, GroupHistory, # type: ignore GroupURL, Role, GroupEvent, RoleHistory, GroupMilestoneHistory, MilestoneGroupEvent, - ChangeStateGroupEvent, GroupFeatures, GroupExtResource) + ChangeStateGroupEvent, GroupFeatures, GroupExtResource, Appeal, AppealArtifact) from ietf.person.resources import PersonResource @@ -333,3 +333,42 @@ class Meta: "name": ALL_WITH_RELATIONS, } api.group.register(GroupExtResourceResource()) + + +class AppealResource(ModelResource): + group = ToOneField(GroupResource, 'group') + class Meta: + queryset = Appeal.objects.all() + serializer = api.Serializer() + cache = SimpleCache() + #resource_name = 'appeal' + ordering = ['id', ] + filtering = { + "id": ALL, + "name": ALL, + "date": ALL, + "group": ALL_WITH_RELATIONS, + } +api.group.register(AppealResource()) + +from ietf.name.resources import AppealArtifactTypeNameResource +class AppealArtifactResource(ModelResource): + appeal = ToOneField(AppealResource, 'appeal') + artifact_type = ToOneField(AppealArtifactTypeNameResource, 'artifact_type') + class Meta: + excludes= ("bits",) + queryset = AppealArtifact.objects.all() + serializer = api.Serializer() + cache = SimpleCache() + #resource_name = 'appealartifact' + ordering = [ "id", ] + filtering = { + "id": ALL, + "date": ALL, + "title": ALL, + "order": ALL, + "content_type": ALL, + "appeal": ALL_WITH_RELATIONS, + "artifact_type": ALL_WITH_RELATIONS, + } +api.group.register(AppealArtifactResource()) diff --git a/ietf/group/tests_appeals.py b/ietf/group/tests_appeals.py new file mode 100644 index 0000000000..ae6c54bf47 --- /dev/null +++ b/ietf/group/tests_appeals.py @@ -0,0 +1,71 @@ +# Copyright The IETF Trust 2023, All Rights Reserved + +import debug # pyflakes: ignore +import datetime + +from pyquery import PyQuery + +from django.urls import reverse as urlreverse + +from ietf.utils.test_utils import login_testing_unauthorized, TestCase +from ietf.group.factories import ( + AppealFactory, + AppealArtifactFactory, +) +class AppealTests(TestCase): + + def test_download_name(self): + artifact = AppealArtifactFactory() + self.assertEqual(artifact.download_name(),f"{artifact.date}-appeal.md") + artifact = AppealArtifactFactory(content_type="application/pdf",artifact_type__slug="response") + self.assertEqual(artifact.download_name(),f"{artifact.date}-response.pdf") + + + def test_appeal_list_view(self): + appeal_date = datetime.date.today()-datetime.timedelta(days=14) + response_date = appeal_date+datetime.timedelta(days=8) + appeal = AppealFactory(name="A name to look for", date=appeal_date) + appeal_artifact = AppealArtifactFactory(appeal=appeal, artifact_type__slug="appeal", date=appeal_date) + response_artifact = AppealArtifactFactory(appeal=appeal, artifact_type__slug="response", content_type="application/pdf", date=response_date) + + url = urlreverse("ietf.group.views.appeals", kwargs=dict(acronym="iab")) + r = self.client.get(url) + self.assertEqual(r.status_code, 200) + q = PyQuery(r.content) + self.assertEqual(len(q("#appeals > tbody > tr")), 1) + self.assertEqual(q("#appeal-1-date").text(), f"{appeal_date}") + self.assertEqual(f"{appeal_artifact.display_title()} - {appeal_date}", q("#artifact-1-1").text()) + self.assertEqual(f"{response_artifact.display_title()} - {response_date}", q("#artifact-1-2").text()) + self.assertIsNone(q("#artifact-1-1").attr("download")) + self.assertEqual(q("#artifact-1-2").attr("download"), response_artifact.download_name()) + + def test_markdown_view(self): + artifact = AppealArtifactFactory() + url = urlreverse("ietf.group.views.appeal_artifact", kwargs=dict(acronym="iab", artifact_id=artifact.pk)) + r = self.client.get(url) + self.assertEqual(r.status_code, 200) + q = PyQuery(r.content) + self.assertEqual(q("#content>p>strong").text(),"Markdown") + self.assertIsNone(q("#content a").attr("download")) + self.client.login(username='secretary', password='secretary+password') + r = self.client.get(url) + self.assertEqual(r.status_code, 200) + q = PyQuery(r.content) + self.assertEqual(q("#content a").attr("download"), artifact.download_name()) + + def test_markdown_download(self): + artifact = AppealArtifactFactory() + url = urlreverse("ietf.group.views.appeal_artifact_markdown", kwargs=dict(acronym="iab", artifact_id=artifact.pk)) + login_testing_unauthorized(self, "secretary", url) + r = self.client.get(url) + self.assertContains(r, "**Markdown**", status_code=200) + + def test_pdf_download(self): + artifact = AppealArtifactFactory(content_type="application/pdf") # The bits won't _really_ be pdf + url = urlreverse("ietf.group.views.appeal_artifact", kwargs=dict(acronym="iab", artifact_id=artifact.pk)) + r = self.client.get(url) + self.assertEqual(r.status_code, 200) + self.assertEqual(r.get("Content-Disposition"), f'attachment; filename="{artifact.download_name()}"') + self.assertEqual(r.get("Content-Type"), artifact.content_type) + self.assertEqual(r.content, artifact.bits.tobytes()) + diff --git a/ietf/group/urls.py b/ietf/group/urls.py index 814fb9733a..b2af8d9e2b 100644 --- a/ietf/group/urls.py +++ b/ietf/group/urls.py @@ -48,6 +48,11 @@ url(r'^reset_next_reviewer/$', views.reset_next_reviewer), url(r'^email-aliases/$', RedirectView.as_view(pattern_name=views.email,permanent=False),name='ietf.group.urls_info_details.redirect.email'), url(r'^statements/$', views.statements), + url(r'^appeals/$', views.appeals), + url(r'^appeals/artifact/(?P\d+)$', views.appeal_artifact), + url(r'^appeals/artifact/(?P\d+)/markdown$', views.appeal_artifact_markdown), + + ] diff --git a/ietf/group/utils.py b/ietf/group/utils.py index b82474b497..f7e4b2f175 100644 --- a/ietf/group/utils.py +++ b/ietf/group/utils.py @@ -235,6 +235,7 @@ def construct_group_menu_context(request, group, selected, group_type, others): entries.append(("Meetings", urlreverse("ietf.group.views.meetings", kwargs=kwargs))) if group.acronym in ["iab", "iesg"]: entries.append(("Statements", urlreverse("ietf.group.views.statements", kwargs=kwargs))) + entries.append(("Appeals", urlreverse("ietf.group.views.appeals", kwargs=kwargs))) entries.append(("History", urlreverse("ietf.group.views.history", kwargs=kwargs))) entries.append(("Photos", urlreverse("ietf.group.views.group_photos", kwargs=kwargs))) entries.append(("Email expansions", urlreverse("ietf.group.views.email", kwargs=kwargs))) diff --git a/ietf/group/views.py b/ietf/group/views.py index eb749bf9ce..2b93e07607 100644 --- a/ietf/group/views.py +++ b/ietf/group/views.py @@ -72,7 +72,7 @@ AddUnavailablePeriodForm, EndUnavailablePeriodForm, ReviewSecretarySettingsForm, ) from ietf.group.mails import email_admin_re_charter, email_personnel_change, email_comment from ietf.group.models import ( Group, Role, GroupEvent, GroupStateTransitions, - ChangeStateGroupEvent, GroupFeatures ) + ChangeStateGroupEvent, GroupFeatures, AppealArtifact ) from ietf.group.utils import (get_charter_text, can_manage_all_groups_of_type, milestone_reviewer_for_group_type, can_provide_status_update, can_manage_materials, group_attribute_change_desc, @@ -111,7 +111,7 @@ from ietf.name.models import ReviewAssignmentStateName from ietf.utils.mail import send_mail_text, parse_preformatted -from ietf.ietfauth.utils import user_is_person +from ietf.ietfauth.utils import user_is_person, role_required from ietf.dbtemplate.models import DBTemplate from ietf.mailtrigger.utils import gather_address_lists from ietf.mailtrigger.models import Recipient @@ -2119,5 +2119,48 @@ def statements(request, acronym, group_type=None): ), ) +def appeals(request, acronym, group_type=None): + if not acronym in ["iab", "iesg"]: + raise Http404 + group = get_group_or_404(acronym, group_type) + appeals = group.appeal_set.all() + return render( + request, + "group/appeals.html", + construct_group_menu_context( + request, + group, + "appeals", + group_type, + { + "group": group, + "appeals": appeals, + }, + ), + ) - +def appeal_artifact(request, acronym, artifact_id, group_type=None): + artifact = get_object_or_404(AppealArtifact, pk=artifact_id) + if artifact.is_markdown(): + artifact_html = markdown.markdown(artifact.bits.tobytes().decode("utf-8")) + return render( + request, + "group/appeal_artifact.html", + dict(artifact=artifact, artifact_html=artifact_html) + ) + else: + return HttpResponse( + artifact.bits, + headers = { + "Content-Type": artifact.content_type, + "Content-Disposition": f'attachment; filename="{artifact.download_name()}"' + } + ) + +@role_required("Secretariat") +def appeal_artifact_markdown(request, acronym, artifact_id, group_type=None): + artifact = get_object_or_404(AppealArtifact, pk=artifact_id) + if artifact.is_markdown(): + return HttpResponse(artifact.bits, content_type=artifact.content_type) + else: + raise Http404 diff --git a/ietf/meeting/management/commands/import_iab_agendas.py b/ietf/meeting/management/commands/import_iab_agendas.py new file mode 100644 index 0000000000..a1b78003ea --- /dev/null +++ b/ietf/meeting/management/commands/import_iab_agendas.py @@ -0,0 +1,240 @@ +# Copyright The IETF Trust 2023, All Rights Reserved + +import datetime +import os +import shutil +import subprocess +import tempfile + +from pathlib import Path + +from django.core.management.base import BaseCommand +from django.conf import settings + +from ietf.doc.models import Document, DocAlias, DocEvent +from ietf.meeting.models import Meeting, Session + + +def agendas_to_import(): + return [ + "2018-09-05.md", + "2018-09-12.md", + "2018-09-26.md", + "2018-10-03.md", + "2018-10-10.md", + "2018-10-24.md", + "2018-11-04.md", + "2018-11-05.md", + "2018-11-08.md", + "2018-11-21.md", + "2018-11-28.md", + "2018-12-05.md", + "2018-12-19.md", + "2019-01-09.md", + "2019-01-16.md", + "2019-01-23.md", + "2019-02-06.md", + "2019-02-13.md", + "2019-02-27.md", + "2019-03-06.md", + "2019-03-13.md", + "2019-03-24.md", + "2019-03-25.md", + "2019-03-28.md", + "2019-04-10.md", + "2019-04-17.md", + "2019-05-01.md", + "2019-05-08.md", + "2019-05-29.md", + "2019-06-12.md", + "2019-06-26.md", + "2019-07-10.md", + "2019-07-21.md", + "2019-07-25.md", + "2019-08-07.md", + "2019-08-21.md", + "2019-08-28.md", + "2019-09-04.md", + "2019-09-18.md", + "2019-10-02.md", + "2019-10-16.md", + "2019-10-30.md", + "2019-11-17.md", + "2019-11-18.md", + "2019-11-21.md", + "2019-12-04.md", + "2019-12-11.md", + "2019-12-18.md", + "2020-01-08.md", + "2020-01-15.md", + "2020-01-22.md", + "2020-02-05.md", + "2020-02-12.md", + "2020-02-19.md", + "2020-03-04.md", + "2020-03-11.md", + "2020-03-18.md", + "2020-04-01.md", + "2020-04-08.md", + "2020-04-15.md", + "2020-04-29.md", + "2020-05-13.md", + "2020-05-20.md", + "2020-05-27.md", + "2020-06-10.md", + "2020-06-17.md", + "2020-07-01.md", + "2020-07-15.md", + "2020-08-12.md", + "2020-08-26.md", + "2020-09-09.md", + "2020-09-23.md", + "2020-10-07.md", + "2020-10-14.md", + "2020-10-21.md", + "2020-11-04.md", + "2020-12-02.md", + "2020-12-16.md", + "2021-01-06.md", + "2021-01-13.md", + "2021-01-20.md", + "2021-01-27.md", + "2021-02-03.md", + "2021-02-10.md", + "2021-02-17.md", + "2021-02-24.md", + "2021-03-03.md", + "2021-03-24.md", + "2021-03-31.md", + "2021-04-07.md", + "2021-04-14.md", + "2021-04-21.md", + "2021-05-05.md", + "2021-05-12.md", + "2021-05-19.md", + "2021-05-26.md", + "2021-06-02.md", + "2021-06-16.md", + "2021-06-23.md", + "2021-06-30.md", + "2021-07-14.md", + "2021-07-21.md", + "2021-08-11.md", + "2021-08-25.md", + "2021-09-01.md", + "2021-09-08.md", + "2021-09-22.md", + "2021-10-06.md", + "2021-10-20.md", + "2021-10-27.md", + "2021-11-17.md", + "2021-12-01.md", + "2021-12-08.md", + "2021-12-15.md", + "2022-01-12.md", + "2022-01-19.md", + "2022-02-02.md", + "2022-02-16.md", + "2022-02-23.md", + "2022-03-02.md", + "2022-03-09.md", + "2022-03-20.md", + "2022-04-06.md", + "2022-04-13.md", + "2022-04-20.md", + "2022-04-27.md", + "2022-05-04.md", + "2022-05-11.md", + "2022-06-01.md", + "2022-06-15.md", + "2022-06-22.md", + "2022-06-29.md", + "2022-07-06.md", + "2022-07-24.md", + "2022-07-26.md", + "2022-08-10.md", + "2022-08-24.md", + "2022-09-07.md", + "2022-09-21.md", + "2022-09-28.md", + "2022-10-05.md", + "2022-10-12.md", + "2022-10-26.md", + "2022-11-06.md", + "2022-11-08.md", + "2022-11-10.md", + "2022-11-23.md", + "2022-12-07.md", + "2022-12-14.md", + ] + + +class Command(BaseCommand): + help = "Performs a one-time import of older IAB agendas" + + def handle(self, *args, **options): + if Document.objects.filter(name="agenda-interim-2018-iab-26-20180905").exists(): + print("Command has already been run - exiting") + exit(0) + + tmpdir = tempfile.mkdtemp() + process = subprocess.Popen( + ["git", "clone", "https://github.com/kesara/iab-scraper.git", tmpdir], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) + stdout, stderr = process.communicate() + if not Path(tmpdir).joinpath("iab_agendas", "2018-09-05.md").exists(): + print("Git clone of the iab-scraper directory did not go as expected") + print("stdout:", stdout) + print("stderr:", stderr) + print(f"Clean up {tmpdir} manually") + exit(-1) + + agendas = agendas_to_import() + for agenda in agendas: + [year, month, day] = [int(part) for part in agenda[:10].split("-")] + agenda_date = datetime.date(year, month, day) + meeting = Meeting.objects.get( + date=agenda_date, type_id="interim", session__group__acronym="iab" + ) + counter = int(meeting.number.split("-")[3]) + agenda_docname = ( + f"agenda-interim-{year}-iab-{counter:02d}-{agenda_date:%Y%m%d}" + ) + agenda_filename = f"{agenda_docname}-00.md" + # Create Document + doc = Document.objects.create( + name=agenda_docname, + type_id="agenda", + title=f"Agenda {meeting.number} {agenda_date:%Y-%m-%d}", + group_id=7, # The IAB group + rev="00", + uploaded_filename=agenda_filename, + ) + DocAlias.objects.create(name=doc.name).docs.add(doc) + e = DocEvent.objects.create( + type="comment", + doc=doc, + rev="00", + by_id=1, # The "(System)" person + desc="Agenda moved into datatracker from iab wordpress website", + ) + doc.save_with_history([e]) + + session = Session.objects.get(meeting=meeting) + # Add Document to Session + session.sessionpresentation_set.create(document=doc, rev=doc.rev) + + # Put file in place + source = Path(tmpdir).joinpath("iab_agendas", agenda) + dest = Path(settings.AGENDA_PATH).joinpath( + meeting.number, "agenda", agenda_filename + ) + if dest.exists(): + print(f"WARNING: {dest} already exists - not overwriting it.") + else: + os.makedirs(dest.parent, exist_ok=True) + shutil.copy(source, dest) + + shutil.rmtree(tmpdir) diff --git a/ietf/name/admin.py b/ietf/name/admin.py index 5a72dc22f7..2458da37d9 100644 --- a/ietf/name/admin.py +++ b/ietf/name/admin.py @@ -2,63 +2,141 @@ from django.contrib import admin from ietf.name.models import ( - AgendaTypeName, BallotPositionName, ConstraintName, ContinentName, CountryName, DBTemplateTypeName, - DocRelationshipName, DocReminderTypeName, DocTagName, DocTypeName, DraftSubmissionStateName, - FeedbackTypeName, FormalLanguageName, GroupMilestoneStateName, GroupStateName, GroupTypeName, - ImportantDateName, IntendedStdLevelName, IprDisclosureStateName, IprEventTypeName, - IprLicenseTypeName, LiaisonStatementEventTypeName, LiaisonStatementPurposeName, - LiaisonStatementState, LiaisonStatementTagName, MeetingTypeName, NomineePositionStateName, - ReviewRequestStateName, ReviewResultName, ReviewTypeName, RoleName, RoomResourceName, - SessionStatusName, StdLevelName, StreamName, TimeSlotTypeName, TopicAudienceName, - DocUrlTagName, ReviewAssignmentStateName, ReviewerQueuePolicyName, TimerangeName, - ExtResourceName, ExtResourceTypeName, SlideSubmissionStatusName, ProceedingsMaterialTypeName, - AgendaFilterTypeName, SessionPurposeName, TelechatAgendaSectionName ) + AgendaTypeName, + BallotPositionName, + ConstraintName, + ContinentName, + CountryName, + DBTemplateTypeName, + DocRelationshipName, + DocReminderTypeName, + DocTagName, + DocTypeName, + DraftSubmissionStateName, + FeedbackTypeName, + FormalLanguageName, + GroupMilestoneStateName, + GroupStateName, + GroupTypeName, + ImportantDateName, + IntendedStdLevelName, + IprDisclosureStateName, + IprEventTypeName, + IprLicenseTypeName, + LiaisonStatementEventTypeName, + LiaisonStatementPurposeName, + LiaisonStatementState, + LiaisonStatementTagName, + MeetingTypeName, + NomineePositionStateName, + ReviewRequestStateName, + ReviewResultName, + ReviewTypeName, + RoleName, + RoomResourceName, + SessionStatusName, + StdLevelName, + StreamName, + TimeSlotTypeName, + TopicAudienceName, + DocUrlTagName, + ReviewAssignmentStateName, + ReviewerQueuePolicyName, + TimerangeName, + ExtResourceName, + ExtResourceTypeName, + SlideSubmissionStatusName, + ProceedingsMaterialTypeName, + AgendaFilterTypeName, + SessionPurposeName, + TelechatAgendaSectionName, + AppealArtifactTypeName, +) from ietf.stats.models import CountryAlias + class NameAdmin(admin.ModelAdmin): list_display = ["slug", "name", "desc", "used", "order"] search_fields = ["slug", "name"] - prepopulate_from = { "slug": ("name",) } + prepopulate_from = {"slug": ("name",)} + class DocRelationshipNameAdmin(NameAdmin): list_display = ["slug", "name", "revname", "desc", "used"] + + admin.site.register(DocRelationshipName, DocRelationshipNameAdmin) - + + class DocTypeNameAdmin(NameAdmin): list_display = ["slug", "name", "prefix", "desc", "used"] + + admin.site.register(DocTypeName, DocTypeNameAdmin) + class GroupTypeNameAdmin(NameAdmin): list_display = ["slug", "name", "verbose_name", "desc", "used"] + + admin.site.register(GroupTypeName, GroupTypeNameAdmin) + class CountryAliasInline(admin.TabularInline): model = CountryAlias extra = 1 + class CountryNameAdmin(NameAdmin): list_display = ["slug", "name", "continent", "in_eu"] list_filter = ["continent", "in_eu"] inlines = [CountryAliasInline] + + admin.site.register(CountryName, CountryNameAdmin) + class ImportantDateNameAdmin(NameAdmin): list_display = ["slug", "name", "desc", "used", "default_offset_days"] - ordering = ('-used','default_offset_days',) -admin.site.register(ImportantDateName,ImportantDateNameAdmin) + ordering = ( + "-used", + "default_offset_days", + ) + + +admin.site.register(ImportantDateName, ImportantDateNameAdmin) + class ExtResourceNameAdmin(NameAdmin): - list_display = ["slug", "name", "type", "desc", "used",] -admin.site.register(ExtResourceName,ExtResourceNameAdmin) + list_display = [ + "slug", + "name", + "type", + "desc", + "used", + ] + + +admin.site.register(ExtResourceName, ExtResourceNameAdmin) + class ProceedingsMaterialTypeNameAdmin(NameAdmin): - list_display = ["slug", "name", "desc", "used", "order",] + list_display = [ + "slug", + "name", + "desc", + "used", + "order", + ] + + admin.site.register(ProceedingsMaterialTypeName, ProceedingsMaterialTypeNameAdmin) admin.site.register(AgendaFilterTypeName, NameAdmin) admin.site.register(AgendaTypeName, NameAdmin) +admin.site.register(AppealArtifactTypeName, NameAdmin) admin.site.register(BallotPositionName, NameAdmin) admin.site.register(ConstraintName, NameAdmin) admin.site.register(ContinentName, NameAdmin) diff --git a/ietf/name/factories.py b/ietf/name/factories.py new file mode 100644 index 0000000000..73399dcbb4 --- /dev/null +++ b/ietf/name/factories.py @@ -0,0 +1,13 @@ +# Copyright The IETF Trust 2023, All Rights Reserved +# -*- coding: utf-8 -*- + +import factory + +from .models import ( + AppealArtifactTypeName, +) + +class AppealArtifactTypeNameFactory(factory.django.DjangoModelFactory): + class Meta: + model = AppealArtifactTypeName + django_get_or_create = ("slug",) diff --git a/ietf/name/fixtures/names.json b/ietf/name/fixtures/names.json index f746231a4a..96e5266947 100644 --- a/ietf/name/fixtures/names.json +++ b/ietf/name/fixtures/names.json @@ -6615,6 +6615,56 @@ "model": "name.agendatypename", "pk": "workshop" }, + { + "fields": { + "desc": "The content of an appeal", + "name": "Appeal", + "order": 1, + "used": true + }, + "model": "name.appealartifacttypename", + "pk": "appeal" + }, + { + "fields": { + "desc": "The content of an appeal combined with the content of a response", + "name": "Response (with appeal included)", + "order": 2, + "used": true + }, + "model": "name.appealartifacttypename", + "pk": "appeal_with_response" + }, + { + "fields": { + "desc": "Other content related to an appeal", + "name": "Other content", + "order": 5, + "used": true + }, + "model": "name.appealartifacttypename", + "pk": "other_content" + }, + { + "fields": { + "desc": "The content of a reply to an appeal response", + "name": "Reply to response", + "order": 4, + "used": true + }, + "model": "name.appealartifacttypename", + "pk": "reply_to_response" + }, + { + "fields": { + "desc": "The content of a response to an appeal", + "name": "Response", + "order": 3, + "used": true + }, + "model": "name.appealartifacttypename", + "pk": "response" + }, { "fields": { "blocking": false, @@ -11773,13 +11823,24 @@ "model": "name.importantdatename", "pk": "draftwgagenda" }, + { + "fields": { + "default_offset_days": -12, + "desc": "Early registration and payment cut-off at UTC 23:59", + "name": "Early cutoff", + "order": 0, + "used": true + }, + "model": "name.importantdatename", + "pk": "early" + }, { "fields": { "default_offset_days": -47, "desc": "Early Bird registration and payment cut-off at UTC 23:59", "name": "Earlybird cutoff", "order": 0, - "used": true + "used": false }, "model": "name.importantdatename", "pk": "earlybird" @@ -11900,11 +11961,22 @@ "desc": "Standard rate registration and payment cut-off at UTC 23:59.", "name": "Standard rate registration ends", "order": 18, - "used": true + "used": false }, "model": "name.importantdatename", "pk": "stdratecutoff" }, + { + "fields": { + "default_offset_days": -47, + "desc": "Super Early registration cutoff at UTC 23:59", + "name": "Super Early cutoff", + "order": 0, + "used": true + }, + "model": "name.importantdatename", + "pk": "superearly" + }, { "fields": { "desc": "", @@ -16455,7 +16527,7 @@ "fields": { "command": "xym", "switch": "--version", - "time": "2023-07-17T07:09:47.664Z", + "time": "2023-08-22T07:09:39.542Z", "used": true, "version": "xym 0.7.0" }, @@ -16466,7 +16538,7 @@ "fields": { "command": "pyang", "switch": "--version", - "time": "2023-07-17T07:09:48.075Z", + "time": "2023-08-22T07:09:39.881Z", "used": true, "version": "pyang 2.5.3" }, @@ -16477,7 +16549,7 @@ "fields": { "command": "yanglint", "switch": "--version", - "time": "2023-07-17T07:09:48.104Z", + "time": "2023-08-22T07:09:39.899Z", "used": true, "version": "yanglint SO 1.9.2" }, @@ -16488,9 +16560,9 @@ "fields": { "command": "xml2rfc", "switch": "--version", - "time": "2023-07-17T07:09:49.075Z", + "time": "2023-08-22T07:09:40.791Z", "used": true, - "version": "xml2rfc 3.17.4" + "version": "xml2rfc 3.18.0" }, "model": "utils.versioninfo", "pk": 4 diff --git a/ietf/name/migrations/0007_appeal_artifact_typename.py b/ietf/name/migrations/0007_appeal_artifact_typename.py new file mode 100644 index 0000000000..1a604dad84 --- /dev/null +++ b/ietf/name/migrations/0007_appeal_artifact_typename.py @@ -0,0 +1,59 @@ +# Copyright The IETF Trust 2023, All Rights Reserved + +from django.db import migrations, models + + +def forward(apps, schema_editor): + AppealArtifactTypeName = apps.get_model("name", "AppealArtifactTypeName") + for slug, name, desc, order in [ + ("appeal", "Appeal", "The content of an appeal", 1), + ( + "appeal_with_response", + "Response (with appeal included)", + "The content of an appeal combined with the content of a response", + 2, + ), + ("response", "Response", "The content of a response to an appeal", 3), + ( + "reply_to_response", + "Reply to response", + "The content of a reply to an appeal response", + 4, + ), + ("other_content", "Other content", "Other content related to an appeal", 5), + ]: + AppealArtifactTypeName.objects.create( + slug=slug, name=name, desc=desc, order=order + ) + + +def reverse(apps, schema_editor): + AppealArtifactTypeName = apps.get_model("name", "AppealArtifactTypeName") + AppealArtifactTypeName.objects.delete() + + +class Migration(migrations.Migration): + dependencies = [ + ("name", "0006_feedbacktypename_data"), + ] + + operations = [ + migrations.CreateModel( + name="AppealArtifactTypeName", + fields=[ + ( + "slug", + models.CharField(max_length=32, primary_key=True, serialize=False), + ), + ("name", models.CharField(max_length=255)), + ("desc", models.TextField(blank=True)), + ("used", models.BooleanField(default=True)), + ("order", models.IntegerField(default=0)), + ], + options={ + "ordering": ["order", "name"], + "abstract": False, + }, + ), + migrations.RunPython(forward, reverse), + ] diff --git a/ietf/name/models.py b/ietf/name/models.py index 4eda88afda..b5adeccc63 100644 --- a/ietf/name/models.py +++ b/ietf/name/models.py @@ -150,4 +150,7 @@ class ExtResourceName(NameModel): class SlideSubmissionStatusName(NameModel): "Pending, Accepted, Rejected" class TelechatAgendaSectionName(NameModel): - "roll_call", "minutes", "action_items" + """roll_call, minutes, action_items""" + +class AppealArtifactTypeName(NameModel): + pass diff --git a/ietf/name/resources.py b/ietf/name/resources.py index 5624916f04..dffa7669db 100644 --- a/ietf/name/resources.py +++ b/ietf/name/resources.py @@ -18,7 +18,8 @@ ReviewAssignmentStateName, ReviewRequestStateName, ReviewResultName, ReviewTypeName, RoleName, RoomResourceName, SessionStatusName, StdLevelName, StreamName, TimeSlotTypeName, TopicAudienceName, ReviewerQueuePolicyName, TimerangeName, ExtResourceTypeName, ExtResourceName, - SlideSubmissionStatusName, ProceedingsMaterialTypeName, SessionPurposeName, TelechatAgendaSectionName ) + SlideSubmissionStatusName, ProceedingsMaterialTypeName, SessionPurposeName, TelechatAgendaSectionName, + AppealArtifactTypeName ) class TimeSlotTypeNameResource(ModelResource): class Meta: @@ -737,3 +738,17 @@ class Meta: "order": ALL, } api.name.register(TelechatAgendaSectionNameResource()) + +class AppealArtifactTypeNameResource(ModelResource): + class Meta: + cache = SimpleCache() + queryset = AppealArtifactTypeName.objects.all() + serializer = api.Serializer() + filtering = { + "slug": ALL, + "name": ALL, + "desc": ALL, + "used": ALL, + "order": ALL, + } +api.name.register(AppealArtifactTypeNameResource()) diff --git a/ietf/static/css/document_html.scss b/ietf/static/css/document_html.scss index d353908976..d34cae4ac1 100644 --- a/ietf/static/css/document_html.scss +++ b/ietf/static/css/document_html.scss @@ -1,7 +1,27 @@ @use "sass:map"; -$font-family-sans-serif: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; -$font-family-monospace: "Noto Sans Mono", SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; +$font-family-sans-serif: "Inter", +system-ui, +-apple-system, +"Segoe UI", +Roboto, +"Helvetica Neue", +"Noto Sans", +"Liberation Sans", +Arial, +sans-serif, +"Apple Color Emoji", +"Segoe UI Emoji", +"Segoe UI Symbol", +"Noto Color Emoji"; +$font-family-monospace: "Noto Sans Mono", +SFMono-Regular, +Menlo, +Monaco, +Consolas, +"Liberation Mono", +"Courier New", +monospace; @import "bootstrap/scss/functions"; @@ -25,7 +45,7 @@ $color-mode-type: data; @import "bootstrap/scss/forms"; @import "bootstrap/scss/buttons"; @import "bootstrap/scss/transitions"; -// @import "bootstrap/scss/dropdown"; +@import "bootstrap/scss/dropdown"; @import "bootstrap/scss/button-group"; @import "bootstrap/scss/nav"; @import "bootstrap/scss/navbar"; @@ -65,12 +85,16 @@ $color-mode-type: data; scrollbar-width: none; } -.sidebar-toggle[aria-expanded="true"] { +.sidebar-toggle[aria-expanded="true"] .sidebar-shown { display: none; } -.sidebar-toggle[aria-expanded="false"] { - display: inherit; +.sidebar-toggle[aria-expanded="false"] .sidebar-collapsed { + display: none; +} + +.sidebar-toolbar { + z-index: 1; } // Toggle classes for dark/light modes @@ -94,6 +118,11 @@ $color-mode-type: data; } } +// Show theme toggler checkbox +.dropdown-menu .active .bi { + display: block !important; +} + @media screen { @include media-breakpoint-down(md) { body { @@ -354,7 +383,7 @@ tbody.meta tr { page-break-inside: avoid; } -/* + /* a:link, a:visited { // color: inherit; diff --git a/ietf/static/js/theme.js b/ietf/static/js/theme.js index d244eec288..d10a472569 100644 --- a/ietf/static/js/theme.js +++ b/ietf/static/js/theme.js @@ -3,6 +3,7 @@ * Copyright 2011-2023 The Bootstrap Authors * Licensed under the Creative Commons Attribution 3.0 Unported License. * + * Based on the below, with some changes for the datatracker: * https://github.com/twbs/bootstrap/blob/main/site/static/docs/5.3/assets/js/color-modes.js */ @@ -45,9 +46,10 @@ // Commented-out lines are from the original bs5 js, which uses a more complicated pref dropdown. // Kept them here for easier future diffing. const themeSwitcherText = document.querySelector('#bd-theme-text') - // const activeThemeIcon = document.querySelector('.theme-icon-active use') + const activeThemeIcon = document.querySelector('.theme-icon-active') const btnToActive = document.querySelector(`[data-bs-theme-value="${theme}"]`) - // const svgOfActiveBtn = btnToActive.querySelector('svg use').getAttribute('href') + const iconPattern = new RegExp(/\bbi-[\w-]+\b/); + const iconOfActiveBtn = btnToActive.querySelector('i').className.match(iconPattern)[0] document.querySelectorAll('[data-bs-theme-value]').forEach(element => { element.classList.remove('active') @@ -56,10 +58,13 @@ btnToActive.classList.add('active') btnToActive.setAttribute('aria-pressed', 'true') - // activeThemeIcon.setAttribute('href', svgOfActiveBtn) - // const themeSwitcherLabel = `${themeSwitcherText.textContent} (${btnToActive.dataset.bsThemeValue})` - // themeSwitcher.setAttribute('aria-label', themeSwitcherLabel) - + if (activeThemeIcon) { + activeThemeIcon.className = activeThemeIcon.className.replace(iconPattern, iconOfActiveBtn) + } + if (themeSwitcherText) { + const themeSwitcherLabel = `${themeSwitcherText.textContent} (${btnToActive.dataset.bsThemeValue})` + themeSwitcher.setAttribute('aria-label', themeSwitcherLabel) + } if (focus) { themeSwitcher.focus() } diff --git a/ietf/submit/models.py b/ietf/submit/models.py index 0f9a86cd22..bb6d8b66b9 100644 --- a/ietf/submit/models.py +++ b/ietf/submit/models.py @@ -79,11 +79,18 @@ def existing_document(self): return Document.objects.filter(name=self.name).first() def latest_checks(self): - checks = [ self.checks.filter(checker=c).latest('time') for c in self.checks.values_list('checker', flat=True).distinct() ] - return checks + """Latest check of each type, excluding any that did not apply + + Ignores any checks where passed is None + """ + latest_for_each_checker = [ + self.checks.filter(checker=c).latest("time") + for c in self.checks.values_list("checker", flat=True).distinct() + ] + return [check for check in latest_for_each_checker if check.passed is not None] def has_yang(self): - return any ( [ c.checker=='yang validation' and c.passed is not None for c in self.latest_checks()] ) + return any(c.checker == "yang validation" for c in self.latest_checks()) @property def replaces_names(self): diff --git a/ietf/submit/tests.py b/ietf/submit/tests.py index 81534aaadc..ac8988053d 100644 --- a/ietf/submit/tests.py +++ b/ietf/submit/tests.py @@ -3808,3 +3808,54 @@ def test_submit_case_conflited_name_fails(self): files["xml"], _ = submission_file("draft-something-hascapitalletters-00", "draft-something-hascapitalletters-00.xml", None, "test_submission.xml") r = self.post_to_upload_submission(url, files) self.assertContains(r,"Case-conflicting draft name found",status_code=200) + + +class SubmissionStatusTests(BaseSubmitTestCase): + """Tests of the submission_status view + + Many tests are interspersed in the monolithic tests above. We can aspire to break these + out more modularly, though. + """ + + def test_submission_checks(self): + for state_slug in ("uploaded", "cancel", "posted"): + submission = SubmissionFactory(state_id=state_slug) + url = urlreverse( + "ietf.submit.views.submission_status", + kwargs={"submission_id": submission.pk}, + ) + # No checks + r = self.client.get(url) + self.assertContains( + r, + "No submission checks were applied to your Internet-Draft.", + status_code=200, + ) + # Inapplicable check + submission.checks.create( + checker="yang validation", passed=None, message="Yang message" + ) + r = self.client.get(url) + self.assertContains( + r, + "No submission checks were applied to your Internet-Draft.", + status_code=200, + ) + # Passed check + submission.checks.create( + checker="idnits check", passed=True, message="idnits ok" + ) + r = self.client.get(url) + self.assertContains( + r, + "Your Internet-Draft has been verified to pass the submission checks.", + status_code=200, + ) + # Failed check + passed check + submission.checks.filter(checker="yang validation").update(passed=False) + r = self.client.get(url) + self.assertContains( + r, + "Your Internet-Draft failed at least one submission check.", + status_code=200, + ) diff --git a/ietf/submit/utils.py b/ietf/submit/utils.py index ec5af8efe3..ebe79e4c43 100644 --- a/ietf/submit/utils.py +++ b/ietf/submit/utils.py @@ -11,6 +11,8 @@ import traceback import xml2rfc +from pathlib import Path +from shutil import move from typing import Optional, Union # pyflakes:ignore from unidecode import unidecode @@ -639,24 +641,27 @@ def cancel_submission(submission): submission.save() remove_submission_files(submission) + def rename_submission_files(submission, prev_rev, new_rev): for ext in settings.IDSUBMIT_FILE_TYPES: - source = os.path.join(settings.IDSUBMIT_STAGING_PATH, '%s-%s.%s' % (submission.name, prev_rev, ext)) - dest = os.path.join(settings.IDSUBMIT_STAGING_PATH, '%s-%s.%s' % (submission.name, new_rev, ext)) - if os.path.exists(source): - os.rename(source, dest) + staging_path = Path(settings.IDSUBMIT_STAGING_PATH) + source = staging_path / f"{submission.name}-{prev_rev}.{ext}" + dest = staging_path / f"{submission.name}-{new_rev}.{ext}" + if source.exists(): + move(source, dest) + def move_files_to_repository(submission): for ext in settings.IDSUBMIT_FILE_TYPES: - source = os.path.join(settings.IDSUBMIT_STAGING_PATH, '%s-%s.%s' % (submission.name, submission.rev, ext)) - dest = os.path.join(settings.IDSUBMIT_REPOSITORY_PATH, '%s-%s.%s' % (submission.name, submission.rev, ext)) - if os.path.exists(source): - os.rename(source, dest) - else: - if os.path.exists(dest): - log.log("Intended to move '%s' to '%s', but found source missing while destination exists.") - elif ext in submission.file_types.split(','): - raise ValueError("Intended to move '%s' to '%s', but found source and destination missing.") + fname = f"{submission.name}-{submission.rev}.{ext}" + source = Path(settings.IDSUBMIT_STAGING_PATH) / fname + dest = Path(settings.IDSUBMIT_REPOSITORY_PATH) / fname + if source.exists(): + move(source, dest) + elif dest.exists(): + log.log("Intended to move '%s' to '%s', but found source missing while destination exists.") + elif ext in submission.file_types.split(','): + raise ValueError("Intended to move '%s' to '%s', but found source and destination missing.") def remove_staging_files(name, rev, exts=None): diff --git a/ietf/submit/views.py b/ietf/submit/views.py index 798fbf307f..edb9773269 100644 --- a/ietf/submit/views.py +++ b/ietf/submit/views.py @@ -317,8 +317,13 @@ def submission_status(request, submission_id, access_token=None): if access_token and not key_matched: raise Http404 - errors = validate_submission(submission) - passes_checks = all([ c.passed!=False for c in submission.checks.all() ]) + if submission.state.slug == "cancel": + errors = {} + else: + errors = validate_submission(submission) + latest_checks = submission.latest_checks() + applied_any_checks = len(latest_checks) > 0 + passes_checks = applied_any_checks and all(c.passed for c in latest_checks) is_secretariat = has_role(request.user, "Secretariat") is_chair = submission.group and submission.group.has_role(request.user, "chair") @@ -353,7 +358,21 @@ def submission_status(request, submission_id, access_token=None): message = None if submission.state_id == "cancel": - message = ('error', 'This submission has been cancelled, modification is no longer possible.') + # would be nice to have a less heuristic mechansim for reporting async processing failure + async_processing_error = submission.submissionevent_set.filter( + desc__startswith="Submission rejected: A system error occurred" + ).exists() + if async_processing_error: + message = ( + "error", + "This submission has been cancelled due to a system error during processing. " + "Modification is no longer possible.", + ) + else: + message = ( + "error", + "This submission has been cancelled, modification is no longer possible.", + ) elif submission.state_id == "auth": message = ('success', 'The submission is pending email authentication. An email has been sent to: %s' % ", ".join(confirmation_list)) elif submission.state_id == "grp-appr": @@ -530,6 +549,7 @@ def submission_status(request, submission_id, access_token=None): 'selected': 'status', 'submission': submission, 'errors': errors, + 'applied_any_checks': applied_any_checks, 'passes_checks': passes_checks, 'submitter_form': submitter_form, 'replaces_form': replaces_form, diff --git a/ietf/templates/base.html b/ietf/templates/base.html index 1ccaf482dc..77a2fa9d96 100644 --- a/ietf/templates/base.html +++ b/ietf/templates/base.html @@ -50,7 +50,7 @@