diff --git a/.github/workflows/chrome.yml b/.github/workflows/chrome.yml index 82f2fa919..a97925e73 100644 --- a/.github/workflows/chrome.yml +++ b/.github/workflows/chrome.yml @@ -16,7 +16,7 @@ jobs: steps: - uses: actions/checkout@v2 - name: Setup node - uses: actions/setup-node@v2.1.5 + uses: actions/setup-node@v2.2.0 with: node-version: ${{ matrix.node }} - uses: actions/checkout@v2 diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 7d0cfcf06..5fac0b5f9 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -16,7 +16,7 @@ jobs: steps: - uses: actions/checkout@v2 - name: Setup node - uses: actions/setup-node@v2.1.5 + uses: actions/setup-node@v2.2.0 with: node-version: ${{ matrix.node }} - uses: actions/checkout@v2 diff --git a/.github/workflows/eslint.yml b/.github/workflows/eslint.yml index 48a141482..46624bfaf 100644 --- a/.github/workflows/eslint.yml +++ b/.github/workflows/eslint.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v2 - name: Setup node - uses: actions/setup-node@v2.1.5 + uses: actions/setup-node@v2.2.0 with: node-version: ${{ matrix.node }} - name: Install dependencies diff --git a/.github/workflows/firefox.yml b/.github/workflows/firefox.yml index 14314d78c..b1fe97821 100644 --- a/.github/workflows/firefox.yml +++ b/.github/workflows/firefox.yml @@ -16,7 +16,7 @@ jobs: steps: - uses: actions/checkout@v2 - name: Setup node - uses: actions/setup-node@v2.1.5 + uses: actions/setup-node@v2.2.0 with: node-version: ${{ matrix.node }} - uses: actions/checkout@v2 diff --git a/.github/workflows/style.yml b/.github/workflows/style.yml index b5439e4f8..4202dafd9 100644 --- a/.github/workflows/style.yml +++ b/.github/workflows/style.yml @@ -15,7 +15,7 @@ jobs: steps: - uses: actions/checkout@v2 - name: Setup node - uses: actions/setup-node@v2.1.5 + uses: actions/setup-node@v2.2.0 with: node-version: ${{ matrix.node }} - uses: actions/checkout@v2 diff --git a/Dockerfile b/Dockerfile index 104e51e7c..653030d4a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM node:14.17.0-alpine3.12 as FRONTEND +FROM node:14.17.1-alpine3.12 as FRONTEND RUN apk add --update \ && apk add --no-cache build-base curl-dev linux-headers bash git\ diff --git a/Dockerfile-Devel b/Dockerfile-Devel index 58532b2d1..b1cdfb386 100644 --- a/Dockerfile-Devel +++ b/Dockerfile-Devel @@ -1,4 +1,4 @@ -FROM node:14.17.0-alpine3.12 as FRONTEND +FROM node:14.17.1-alpine3.12 as FRONTEND RUN apk add --update \ && apk add --no-cache build-base curl-dev linux-headers bash git\ diff --git a/Dockerfile-SD b/Dockerfile-SD index 786a99e60..165d98869 100644 --- a/Dockerfile-SD +++ b/Dockerfile-SD @@ -1,4 +1,4 @@ -FROM node:14.17.0-alpine3.12 as FRONTEND +FROM node:14.17.1-alpine3.12 as FRONTEND RUN apk add --update \ && apk add --no-cache build-base curl-dev linux-headers bash git\ diff --git a/docs/source/conf.py b/docs/source/conf.py index 90e5981de..166936121 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -28,7 +28,7 @@ author = "CSC Developers" # The full version, including alpha/beta/rc tags -version = release = "1.1.0b2" +version = release = "1.1.0b3" # -- General configuration --------------------------------------------------- diff --git a/requirements.txt b/requirements.txt index c86347bb3..d94c02f85 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,7 +3,7 @@ python-swiftclient==3.12.0 cryptography==3.4.7 keystoneauth1==4.3.1 click==8.0.1 -sphinx==4.0.2 +sphinx==4.0.3 sphinx_rtd_theme==0.5.2 uvloop==0.15.2 gunicorn>=20.0.1 diff --git a/setup.py b/setup.py index aefa25517..535ac9068 100644 --- a/setup.py +++ b/setup.py @@ -30,11 +30,11 @@ "coveralls==3.1.0", "flake8==3.9.2", "flake8-docstrings==1.6.0", - "pytest-xdist==2.2.1", + "pytest-xdist==2.3.0", "asynctest==0.13.0", "black==21.6b0", ], - "docs": ["sphinx==4.0.2", "sphinx_rtd_theme==0.5.2", "selenium==3.141.0"], + "docs": ["sphinx==4.0.3", "sphinx_rtd_theme==0.5.2", "selenium==3.141.0"], "ui_test": ["pytest==6.2.4", "selenium==3.141.0 ", "pytest-timeout==1.4.2"], }, packages=[__name__], diff --git a/swift_browser_ui/__init__.py b/swift_browser_ui/__init__.py index 54450a4b1..11e6bf1cf 100644 --- a/swift_browser_ui/__init__.py +++ b/swift_browser_ui/__init__.py @@ -7,6 +7,6 @@ __name__ = "swift_browser_ui" -__version__ = "1.1.0b2" +__version__ = "1.1.0b3" __author__ = "CSC Developers" __license__ = "MIT License" diff --git a/swift_browser_ui/_convenience.py b/swift_browser_ui/_convenience.py index 7f8a743c9..275226792 100644 --- a/swift_browser_ui/_convenience.py +++ b/swift_browser_ui/_convenience.py @@ -329,6 +329,27 @@ def initiate_os_session(unscoped: str, project: str) -> keystoneauth1.session.Se ) +def os_get_token_from_credentials( + username: str, + password: str, +) -> str: + """Get an unscoped token with provided credentials.""" + os_auth = v3.Password( + setd["auth_endpoint_url"], + username=username, + password=password, + user_domain_name=setd["os_user_domain"], + unscoped=True, + ) + + os_session = keystoneauth1.session.Session( + auth=os_auth, + verify=True, + ) + + return os_session.get_token() + + def initiate_os_service( os_session: keystoneauth1.session.Session, url: str = None ) -> swiftclient.service.SwiftService: diff --git a/swift_browser_ui/front.py b/swift_browser_ui/front.py index ef844cf89..21f273e0a 100644 --- a/swift_browser_ui/front.py +++ b/swift_browser_ui/front.py @@ -42,3 +42,25 @@ async def index( raise AttributeError except (AttributeError, InvalidToken, KeyError, aiohttp.web.HTTPUnauthorized): return aiohttp.web.FileResponse(str(setd["static_directory"]) + "/index.html") + + +async def loginpassword( + request: typing.Optional[aiohttp.web.Request], +) -> typing.Union[aiohttp.web.Response, aiohttp.web.FileResponse]: + """Serve the username and password login page.""" + try: + if request is not None: + session_check(request) + request.app["Log"].info("Redirecting an existing session to app") + return aiohttp.web.Response( + status=303, + headers={ + "Location": "/browse", + }, + ) + else: + raise AttributeError + except (AttributeError, InvalidToken, KeyError, aiohttp.web.HTTPUnauthorized): + return aiohttp.web.FileResponse( + str(setd["static_directory"]) + "/loginpassword.html" + ) diff --git a/swift_browser_ui/login.py b/swift_browser_ui/login.py index d754fc119..2e8352463 100644 --- a/swift_browser_ui/login.py +++ b/swift_browser_ui/login.py @@ -8,6 +8,7 @@ # aiohttp import aiohttp.web +import keystoneauth1.exceptions.http from multidict import MultiDictProxy import typing @@ -21,6 +22,7 @@ session_check, initiate_os_session, initiate_os_service, + os_get_token_from_credentials, test_swift_endpoint, clear_session_info, ) @@ -90,27 +92,129 @@ def test_token( f"from address {request.remote} :: {time.ctime()}" ) if unscoped is None: - raise aiohttp.web.HTTPClientError(reason="Token missing from query") + raise aiohttp.web.HTTPBadRequest(reason="Token missing from query") if not (re.match("[a-f0-9]{32}", unscoped) and len(unscoped) == 32): - raise aiohttp.web.HTTPClientError(reason="Token is malformed") + raise aiohttp.web.HTTPBadRequest(reason="Token is malformed") log.info("Got OS token in login return") return unscoped +async def credentials_login_end( + request: aiohttp.web.Request, +) -> typing.Union[aiohttp.web.Response, aiohttp.web.FileResponse]: + """Handle the login procedure with classic POST.""" + log = request.app["Log"] + log.info("Got login request with username, password") + + form = await request.post() + + try: + username = str(form["username"]) + password = str(form["password"]) + except KeyError: + raise aiohttp.web.HTTPBadRequest(reason="Username or password not provided") + + log.debug(f"username: {username}, password: {password}") + + # Get an unscoped token with credentials + try: + unscoped: str = os_get_token_from_credentials( + username, + password, + ) + except keystoneauth1.exceptions.http.BadRequest: + raise aiohttp.web.HTTPBadRequest(reason="No username or password provided.") + except keystoneauth1.exceptions.http.Unauthorized: + raise aiohttp.web.HTTPUnauthorized( + reason="Wrong username or password, or no access to the service." + ) + + log.debug(f"got token {unscoped}") + + return await login_with_token(request, unscoped) + + async def sso_query_end( request: aiohttp.web.Request, ) -> typing.Union[aiohttp.web.Response, aiohttp.web.FileResponse]: """Handle the login procedure return from SSO or user from POST.""" log = request.app["Log"] - response: typing.Union[aiohttp.web.Response, aiohttp.web.FileResponse] formdata = await request.post() log.debug(f"Got {formdata} in form.") # Declare the unscoped token unscoped = test_token(formdata, request) - # Establish connection and begin session + return await login_with_token(request, unscoped) + + +async def token_rescope(request: aiohttp.web.Request) -> aiohttp.web.Response: + """Rescope the requesting session's token to the new project.""" + session_check(request) + session = decrypt_cookie(request)["id"] + request.app["Log"].info( + f"Call to rescope token from {request.remote}, sess: {session} :: {time.ctime()}" + ) + + if request.query["project"] not in [ + p["id"] for p in request.app["Sessions"][session]["Avail"]["projects"] + ]: + raise aiohttp.web.HTTPForbidden( + reason="The project is not available for this token." + ) + + # Invalidate the old scoped token + request.app["Sessions"][session]["OS_sess"].invalidate( + request.app["Sessions"][session]["OS_sess"].auth + ) + # Overwrite the old session with a new one, with the updated project id + request.app["Sessions"][session]["OS_sess"] = initiate_os_session( + request.app["Sessions"][session]["Token"], + request.query["project"], + ) + # Overwrite the old connection with a new one, with the updated keystone + # session + request.app["Sessions"][session]["ST_conn"] = initiate_os_service( + request.app["Sessions"][session]["OS_sess"], + ) + + # Ditch the session download proxy if that exists + if "runner" in request.app["Sessions"][session].keys(): + request.app["Sessions"][session].pop("runner") + + # Save the new project as the active project in session + new_project_name = [ + i["name"] + for i in request.app["Sessions"][session]["Avail"]["projects"] + if i["id"] == request.query["project"] + ][0] + request.app["Sessions"][session]["active_project"] = { + "name": new_project_name, + "id": request.query["project"], + } + + response = aiohttp.web.Response(status=303, reason="Successfully rescoped token.") + response.headers["Location"] = "/browse" + if "Referer" in request.headers: + if len(request.headers["Referer"].split("/")) == 5: + response.headers["Location"] = request.headers["Referer"] + response.set_cookie( + "LAST_ACTIVE", + request.app["Sessions"][session]["active_project"]["id"], + expires=str(setd["history_lifetime"]), # type: ignore + ) + + return response + + +async def login_with_token( + request: aiohttp.web.Request, + token: str, +) -> typing.Union[aiohttp.web.Response, aiohttp.web.FileResponse]: + """Log in a session with token.""" + # Establish connection and begin user session + response: typing.Union[aiohttp.web.Response, aiohttp.web.FileResponse] response = aiohttp.web.Response(status=303) cookie, _ = generate_cookie(request) @@ -141,11 +245,11 @@ async def sso_query_end( request.app["Sessions"][session] = {} # Save the unscoped token to the session, as it's needed for re-scoping - request.app["Sessions"][session]["Token"] = unscoped + request.app["Sessions"][session]["Token"] = token try: # Check token availability - request.app["Sessions"][session]["Avail"] = get_availability_from_token(unscoped) + request.app["Sessions"][session]["Avail"] = get_availability_from_token(token) except urllib.error.HTTPError: raise aiohttp.web.HTTPUnauthorized( reason="Token no longer valid", @@ -169,9 +273,7 @@ async def sso_query_end( project_id = request.app["Sessions"][session]["Avail"]["projects"][0]["id"] # Open an OS session for the first project that's found for the user. - request.app["Sessions"][session]["OS_sess"] = initiate_os_session( - unscoped, project_id - ) + request.app["Sessions"][session]["OS_sess"] = initiate_os_session(token, project_id) test_swift_endpoint( request.app["Sessions"][session]["OS_sess"].get_endpoint( @@ -220,65 +322,6 @@ async def sso_query_end( return response -async def token_rescope(request: aiohttp.web.Request) -> aiohttp.web.Response: - """Rescope the requesting session's token to the new project.""" - session_check(request) - session = decrypt_cookie(request)["id"] - request.app["Log"].info( - f"Call to rescope token from {request.remote}, sess: {session} :: {time.ctime()}" - ) - - if request.query["project"] not in [ - p["id"] for p in request.app["Sessions"][session]["Avail"]["projects"] - ]: - raise aiohttp.web.HTTPForbidden( - reason="The project is not available for this token." - ) - - # Invalidate the old scoped token - request.app["Sessions"][session]["OS_sess"].invalidate( - request.app["Sessions"][session]["OS_sess"].auth - ) - # Overwrite the old session with a new one, with the updated project id - request.app["Sessions"][session]["OS_sess"] = initiate_os_session( - request.app["Sessions"][session]["Token"], - request.query["project"], - ) - # Overwrite the old connection with a new one, with the updated keystone - # session - request.app["Sessions"][session]["ST_conn"] = initiate_os_service( - request.app["Sessions"][session]["OS_sess"], - ) - - # Ditch the session download proxy if that exists - if "runner" in request.app["Sessions"][session].keys(): - request.app["Sessions"][session].pop("runner") - - # Save the new project as the active project in session - new_project_name = [ - i["name"] - for i in request.app["Sessions"][session]["Avail"]["projects"] - if i["id"] == request.query["project"] - ][0] - request.app["Sessions"][session]["active_project"] = { - "name": new_project_name, - "id": request.query["project"], - } - - response = aiohttp.web.Response(status=303, reason="Successfully rescoped token.") - response.headers["Location"] = "/browse" - if "Referer" in request.headers: - if len(request.headers["Referer"].split("/")) == 5: - response.headers["Location"] = request.headers["Referer"] - response.set_cookie( - "LAST_ACTIVE", - request.app["Sessions"][session]["active_project"]["id"], - expires=str(setd["history_lifetime"]), # type: ignore - ) - - return response - - async def handle_logout(request: aiohttp.web.Request) -> aiohttp.web.Response: """Properly kill the session for the user.""" session = "" diff --git a/swift_browser_ui/middlewares.py b/swift_browser_ui/middlewares.py index d474dae61..447d86930 100644 --- a/swift_browser_ui/middlewares.py +++ b/swift_browser_ui/middlewares.py @@ -32,6 +32,8 @@ async def error_middleware(request: web.Request, handler: AiohttpHandler) -> web """Return the correct HTTP Error page.""" try: response = await handler(request) + if response.status == 400: + return return_error_response(400) if response.status == 401: return return_error_response(401) if response.status == 403: @@ -40,6 +42,8 @@ async def error_middleware(request: web.Request, handler: AiohttpHandler) -> web return return_error_response(404) return response except web.HTTPException as ex: + if ex.status == 400: + return return_error_response(400) if ex.status == 401: return return_error_response(401) if ex.status == 403: diff --git a/swift_browser_ui/server.py b/swift_browser_ui/server.py index 8a0325dbb..3890b4f43 100644 --- a/swift_browser_ui/server.py +++ b/swift_browser_ui/server.py @@ -13,12 +13,13 @@ import cryptography.fernet import aiohttp.web -from .front import index, browse +from .front import index, browse, loginpassword from .login import ( handle_login, handle_logout, sso_query_begin, sso_query_end, + credentials_login_end, token_rescope, ) from .api import ( @@ -111,6 +112,7 @@ async def servinit() -> aiohttp.web.Application: app.add_routes( [ aiohttp.web.get("/", index), + aiohttp.web.get("/loginpassword", loginpassword), aiohttp.web.get("/browse", browse), # Route all URLs prefixed by /browse to the browser page, as this is # an spa @@ -126,6 +128,7 @@ async def servinit() -> aiohttp.web.Application: aiohttp.web.get("/login/front", sso_query_begin), aiohttp.web.post("/login/return", sso_query_end), aiohttp.web.post("/login/websso", sso_query_end), + aiohttp.web.post("/login/credentials", credentials_login_end), aiohttp.web.get("/login/rescope", token_rescope), ] ) diff --git a/swift_browser_ui/settings.py b/swift_browser_ui/settings.py index a5876cdb2..e3f63217b 100644 --- a/swift_browser_ui/settings.py +++ b/swift_browser_ui/settings.py @@ -69,6 +69,7 @@ "sharing_request_token": environ.get("SWIFT_UI_SHARING_REQUEST_TOKEN", None), "has_trust": environ.get("BROWSER_START_HAS_TRUST", False), "set_origin_address": environ.get("BROWSER_START_SET_ORIGIN_ADDRESS", None), + "os_user_domain": environ.get("OS_USER_DOMAIN_NAME", "Default"), "logfile": None, "port": 8080, "verbose": False, diff --git a/swift_browser_ui_frontend/config/sd_overrides.js b/swift_browser_ui_frontend/config/sd_overrides.js index 3ce08849a..26a59b840 100644 --- a/swift_browser_ui_frontend/config/sd_overrides.js +++ b/swift_browser_ui_frontend/config/sd_overrides.js @@ -2,21 +2,89 @@ let lang_overrides = { en: { message: { + index: { + formName: "CSC Account", + loginmethods: [ + { + msg: "Log In using Haka", + href: "/login", + }, + { + msg: "Log in with CSC Login", + href: "/loginpassword", + }, + ], + }, program_name: "SD Connect", program_description: "SD Connect provides a simple-to-use web user " + "interface, along with a command line interface, for storing " + "encrypted sensitive data for the duration of your research project " + "by allowing data uploads through drag-n-drop, and simple data " + "sharing.", + helplink: "https://docs.csc.fi/data/sensitive-data/", + dashboard: { + default_notify: "The information on consumed billing units and " + + "available quota is derived from the default CSC " + + "values. Default quota can be increased, and the " + + "increase will not reflect here.", + links: [ + { + msg: "Sensitive Data Services User Guide", + href: "https://docs.csc.fi/data/sensitive-data/", + }, + { + msg: "Billing Unit Calculator", + href: "https://research.csc.fi/pricing#buc", + }, + { + msg: "About Sensitive Data Services for Research", + href: "https://research.csc.fi/sensitive-data", + }, + ], + }, }, }, fi: { message: { + formName: "CSC Käyttäjä", + index: { + loginmethods: [ + { + msg: "Kirjaudu Haka:lla", + href: "/login", + }, + { + msg: "Kirjaudu CSC käyttäjällä", + href: "/loginpassword", + }, + ], + }, program_name: "SD Connect", program_description: "SD Connect tarjoaa yksinkertaisen " + "web-käyttöliittymän ja komentorivikäyttöliittymän sensitiivisen " + "datan säilyttämiseen tutkimusprojektin ajaksi, mahdollistamalla " + "tiedostojen lähettämisen raahaamalla ja yksinkertaisen jakamisen.", + helplink: "https://docs.csc.fi/data/sensitive-data/", + dashboard: { + default_notify: "Tieto laskutusyksiköiden kulutuksesta ja " + + "käyttörajasta on laskettu CSC:n Allas-palvelun " + + "oletusarvojen mukaan. Mahdollinen korotettu " + + "käyttöraja ei näy käyttöliittymässä.", + links: [ + { + msg: "Sensitive Data Services User Guide", + href: "https://docs.csc.fi/data/sensitive-data/", + }, + { + msg: "Billing Unit Calculator", + href: "https://research.csc.fi/pricing#buc", + }, + { + msg: "About Sensitive Data Services for Research", + href: "https://research.csc.fi/sensitive-data", + }, + ], + }, }, }, }; diff --git a/swift_browser_ui_frontend/package-lock.json b/swift_browser_ui_frontend/package-lock.json index f84684593..7d42baa01 100644 --- a/swift_browser_ui_frontend/package-lock.json +++ b/swift_browser_ui_frontend/package-lock.json @@ -1,26 +1,26 @@ { "name": "swift_browser_ui_frontend_npm", - "version": "1.1.0b2", + "version": "1.1.0b3", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "swift_browser_ui_frontend_npm", - "version": "1.1.0b2", + "version": "1.1.0b3", "dependencies": { "@vue/cli-service": "^5.0.0-beta.2", - "buefy": "^0.9.7", - "core-js": "^3.14.0", + "buefy": "^0.9.8", + "core-js": "^3.15.2", "lodash": "^4.17.21", "material-design-icons": "^3.0.1", - "node-sass": "^6.0.0", + "node-sass": "^6.0.1", "resumablejs": "^1.1.0", "sass-loader": "^12.1.0", "serve": "^12.0.0", "vue": "^2.6.14", - "vue-i18n": "^8.24.4", + "vue-i18n": "^8.24.5", "vue-material-design-icons": "^4.12.1", - "vue-router": "^3.5.1", + "vue-router": "^3.5.2", "vuex": "^3.6.2" }, "devDependencies": { @@ -29,8 +29,8 @@ "@vue/cli-service": "^5.0.0-beta.2", "babel-eslint": "^10.1.0", "cli-highlight": "^2.1.11", - "eslint": "^7.28.0", - "eslint-plugin-vue": "^7.11.1", + "eslint": "^7.30.0", + "eslint-plugin-vue": "^7.12.1", "eslint-utils": "^3.0.0", "vue-template-compiler": "^2.6.14" } @@ -1662,6 +1662,26 @@ "@hapi/hoek": "^9.0.0" } }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", + "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", + "dev": true + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -2950,14 +2970,6 @@ "node": ">=0.10.0" } }, - "node_modules/array-find-index": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", - "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/array-flatten": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", @@ -3494,11 +3506,11 @@ } }, "node_modules/buefy": { - "version": "0.9.7", - "resolved": "https://registry.npmjs.org/buefy/-/buefy-0.9.7.tgz", - "integrity": "sha512-Fli0ZjNDgtFtHm0LItWmfhNJ1oLjDwPzUWccvwXXoo2mADXaH8JQxyhY+drUuUV5/GMu5PtwqQSqPgZy942VZg==", + "version": "0.9.8", + "resolved": "https://registry.npmjs.org/buefy/-/buefy-0.9.8.tgz", + "integrity": "sha512-VBGAD6WtmgpPdiRnBXaTleS3ifpNu9rbInAr54YL8KJw1RhCb8JtGYYYVRjllnDQmN0jQjC5lYoPR9KpfTe+Cw==", "dependencies": { - "bulma": "0.9.2" + "bulma": "0.9.3" }, "engines": { "node": ">= 4.0.0", @@ -3547,9 +3559,9 @@ "integrity": "sha512-+jjPFVqyfF1esi9fvfUs3NqM0pH1ziZ36VP4hmA/y/Ssfo/5w5xHKfTw9BwQjoJ1w/oVtpLomqwUHKdefGyuHw==" }, "node_modules/bulma": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/bulma/-/bulma-0.9.2.tgz", - "integrity": "sha512-e14EF+3VSZ488yL/lJH0tR8mFWiEQVCMi/BQUMi2TGMBOk+zrDg4wryuwm/+dRSHJw0gMawp2tsW7X1JYUCE3A==" + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/bulma/-/bulma-0.9.3.tgz", + "integrity": "sha512-0d7GNW1PY4ud8TWxdNcP6Cc8Bu7MxcntD/RRLGWuiw/s0a9P+XlH/6QoOIrmbj6o8WWJzJYhytiu9nFjTszk1g==" }, "node_modules/bytes": { "version": "3.0.0", @@ -3639,23 +3651,27 @@ } }, "node_modules/camelcase-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", - "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", "dependencies": { - "camelcase": "^2.0.0", - "map-obj": "^1.0.0" + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/camelcase-keys/node_modules/camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "engines": { - "node": ">=0.10.0" + "node": ">=6" } }, "node_modules/caniuse-api": { @@ -4424,9 +4440,9 @@ } }, "node_modules/core-js": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.14.0.tgz", - "integrity": "sha512-3s+ed8er9ahK+zJpp9ZtuVcDoFzHNiZsPbNAAE4KXgrRHbjSqqNN6xGSXq6bq7TZIbKj4NLrLb6bJ5i+vSVjHA==", + "version": "3.15.2", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.15.2.tgz", + "integrity": "sha512-tKs41J7NJVuaya8DxIOCnl8QuPHx5/ZVbFo1oKgVl1qHFBBrDctzQGtuLjPpRdNTWmKPH6oEvgN/MUID+l485Q==", "hasInstallScript": true, "funding": { "type": "opencollective", @@ -4780,17 +4796,6 @@ "node": ">=8.0.0" } }, - "node_modules/currently-unhandled": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", - "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", - "dependencies": { - "array-find-index": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", @@ -4832,6 +4837,26 @@ "node": ">=0.10.0" } }, + "node_modules/decamelize-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", + "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", + "dependencies": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decamelize-keys/node_modules/map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/decode-uri-component": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", @@ -5353,13 +5378,14 @@ } }, "node_modules/eslint": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.28.0.tgz", - "integrity": "sha512-UMfH0VSjP0G4p3EWirscJEQ/cHqnT/iuH6oNZOB94nBjWbMnhGEPxsZm1eyIW0C/9jLI0Fow4W5DXLjEI7mn1g==", + "version": "7.30.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.30.0.tgz", + "integrity": "sha512-VLqz80i3as3NdloY44BQSJpFw534L9Oh+6zJOUaViV4JPd+DaHwutqP7tcpkW3YiXbK6s05RZl7yl7cQn+lijg==", "dev": true, "dependencies": { "@babel/code-frame": "7.12.11", "@eslint/eslintrc": "^0.4.2", + "@humanwhocodes/config-array": "^0.5.0", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -5409,9 +5435,9 @@ } }, "node_modules/eslint-plugin-vue": { - "version": "7.11.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-7.11.1.tgz", - "integrity": "sha512-lbw3vkEAGqYjqd1HpPFWHXtYaS8mILTJ5KOpJfRxO3Fo7o0wCf1zD7vSOasbm6nTA9xIgvZQ4VcyGIzQXxznHw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-7.12.1.tgz", + "integrity": "sha512-xHf/wCt88qmzqQerjaSteUFGASj7fPreglKD4ijnvoKRkoSJ3/H3kuJE8QFFtc+2wjw6hRDs834HH7vpuTJQzg==", "dev": true, "dependencies": { "eslint-utils": "^2.1.0", @@ -6805,6 +6831,14 @@ "node": ">=6" } }, + "node_modules/hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "engines": { + "node": ">=6" + } + }, "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -7280,14 +7314,11 @@ } }, "node_modules/indent-string": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", - "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", - "dependencies": { - "repeating": "^2.0.0" - }, + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, "node_modules/inflight": { @@ -7694,17 +7725,6 @@ "read-pkg-up": "^7.0.1" } }, - "node_modules/is-finite": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz", - "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==", - "engines": { - "node": ">=0.10.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", @@ -7836,11 +7856,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=" - }, "node_modules/is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", @@ -8121,40 +8136,6 @@ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=" }, - "node_modules/load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "dependencies": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/load-json-file/node_modules/parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dependencies": { - "error-ex": "^1.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/load-json-file/node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/loader-runner": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", @@ -8344,18 +8325,6 @@ "url": "https://tidelift.com/funding/github/npm/loglevel" } }, - "node_modules/loud-rejection": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", - "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", - "dependencies": { - "currently-unhandled": "^0.4.1", - "signal-exit": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/lower-case": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", @@ -8398,11 +8367,14 @@ } }, "node_modules/map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.2.1.tgz", + "integrity": "sha512-+WA2/1sPmDj1dlvvJmB5G6JKfY9dpn7EVBUL06+y6PoljPkh+6V1QihwxNkbcGxCRjt2b0F9K0taiCuo7MbdFQ==", "engines": { - "node": ">=0.10.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/map-visit": { @@ -8444,92 +8416,78 @@ } }, "node_modules/meow": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", - "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", - "dependencies": { - "camelcase-keys": "^2.0.0", - "decamelize": "^1.1.2", - "loud-rejection": "^1.0.0", - "map-obj": "^1.0.1", - "minimist": "^1.1.3", - "normalize-package-data": "^2.3.4", - "object-assign": "^4.0.1", - "read-pkg-up": "^1.0.1", - "redent": "^1.0.0", - "trim-newlines": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/meow/node_modules/find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz", + "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==", "dependencies": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize": "^1.2.0", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" }, "engines": { - "node": ">=0.10.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/meow/node_modules/path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "node_modules/meow/node_modules/hosted-git-info": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.0.2.tgz", + "integrity": "sha512-c9OGXbZ3guC/xOlCg1Ci/VgWlwsqDv1yMQL1CWqXDL0hDjXuNcq0zuR4xqPSuasI3kqFDhqSyTjREz5gzq0fXg==", "dependencies": { - "pinkie-promise": "^2.0.0" + "lru-cache": "^6.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=10" } }, - "node_modules/meow/node_modules/path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "node_modules/meow/node_modules/normalize-package-data": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.2.tgz", + "integrity": "sha512-6CdZocmfGaKnIHPVFhJJZ3GuR8SsLKvDANFp47Jmy51aKIr8akjAWTSxtpI+MBgBFdSMRyo4hMpDlT6dTffgZg==", "dependencies": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" + "hosted-git-info": "^4.0.1", + "resolve": "^1.20.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/meow/node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "engines": { - "node": ">=0.10.0" + "node": ">=10" } }, - "node_modules/meow/node_modules/read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "node_modules/meow/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dependencies": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" }, "engines": { - "node": ">=0.10.0" + "node": ">=10" } }, - "node_modules/meow/node_modules/read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "dependencies": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - }, + "node_modules/meow/node_modules/type-fest": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", "engines": { - "node": ">=0.10.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/merge-descriptors": { @@ -8624,6 +8582,14 @@ "node": ">=6" } }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "engines": { + "node": ">=4" + } + }, "node_modules/mini-css-extract-plugin": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-1.6.0.tgz", @@ -8695,6 +8661,35 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" }, + "node_modules/minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "dependencies": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/minimist-options/node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/minimist-options/node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/minipass": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", @@ -9007,9 +9002,9 @@ "integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==" }, "node_modules/node-sass": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-6.0.0.tgz", - "integrity": "sha512-GDzDmNgWNc9GNzTcSLTi6DU6mzSPupVJoStIi7cF3GjwSE9q1cVakbvAAVSt59vzUjV9JJoSZFKoo9krbjKd2g==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-6.0.1.tgz", + "integrity": "sha512-f+Rbqt92Ful9gX0cGtdYwjTrWAaGURgaK5rZCWOgCNyGWusFYHhbqCCBoFBeat+HKETOU02AyTxNhJV0YZf2jQ==", "hasInstallScript": true, "dependencies": { "async-foreach": "^0.1.3", @@ -9019,8 +9014,7 @@ "get-stdin": "^4.0.1", "glob": "^7.0.3", "lodash": "^4.17.15", - "meow": "^3.7.0", - "mkdirp": "^0.5.1", + "meow": "^9.0.0", "nan": "^2.13.2", "node-gyp": "^7.1.0", "npmlog": "^4.0.0", @@ -10453,6 +10447,14 @@ } ] }, + "node_modules/quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "engines": { + "node": ">=8" + } + }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -10748,15 +10750,15 @@ } }, "node_modules/redent": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", - "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", "dependencies": { - "indent-string": "^2.1.0", - "strip-indent": "^1.0.1" + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, "node_modules/regenerate": { @@ -10978,17 +10980,6 @@ "node": ">=0.10" } }, - "node_modules/repeating": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", - "dependencies": { - "is-finite": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/request": { "version": "2.88.2", "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", @@ -12242,17 +12233,6 @@ "node": ">=6" } }, - "node_modules/strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dependencies": { - "is-utf8": "^0.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/strip-eof": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", @@ -12270,17 +12250,14 @@ } }, "node_modules/strip-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", - "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", "dependencies": { - "get-stdin": "^4.0.1" - }, - "bin": { - "strip-indent": "cli.js" + "min-indent": "^1.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, "node_modules/strip-json-comments": { @@ -13061,11 +13038,11 @@ } }, "node_modules/trim-newlines": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", - "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, "node_modules/true-case-path": { @@ -13511,9 +13488,9 @@ "integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==" }, "node_modules/vue-i18n": { - "version": "8.24.4", - "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-8.24.4.tgz", - "integrity": "sha512-RZE94WUAGxEiBAANxQ0pptbRwDkNKNSXl3fnJslpFOxVMF6UkUtMDSuYGuW2blDrVgweIXVpethOVkYoNNT9xw==" + "version": "8.24.5", + "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-8.24.5.tgz", + "integrity": "sha512-p8W5xOmniuZ8fj76VXe0vBL3bRWVU87jHuC/v8VwmhKVH2iMQsKnheB1U+umxDBqC/5g9K+NwzokepcLxnBAVQ==" }, "node_modules/vue-loader": { "version": "16.2.0", @@ -13608,9 +13585,9 @@ "integrity": "sha512-IDGGV5fC2VPN3zPRNEpm47MjJL1CIPfK34wx3+SRTkUL8dt5/hONmQ2WguBivE1uZVExMVFHekNDnEJamkJ8hA==" }, "node_modules/vue-router": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.5.1.tgz", - "integrity": "sha512-RRQNLT8Mzr8z7eL4p7BtKvRaTSGdCbTy2+Mm5HTJvLGYSSeG9gDzNasJPP/yOYKLy+/cLG/ftrqq5fvkFwBJEw==" + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.5.2.tgz", + "integrity": "sha512-807gn82hTnjCYGrnF3eNmIw/dk7/GE4B5h69BlyCK9KHASwSloD1Sjcn06zg9fVG4fYH2DrsNBZkpLtb25WtaQ==" }, "node_modules/vue-style-loader": { "version": "4.1.3", @@ -15981,6 +15958,23 @@ "@hapi/hoek": "^9.0.0" } }, + "@humanwhocodes/config-array": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + } + }, + "@humanwhocodes/object-schema": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", + "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", + "dev": true + }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -17030,11 +17024,6 @@ "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=" }, - "array-find-index": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", - "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=" - }, "array-flatten": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", @@ -17441,11 +17430,11 @@ } }, "buefy": { - "version": "0.9.7", - "resolved": "https://registry.npmjs.org/buefy/-/buefy-0.9.7.tgz", - "integrity": "sha512-Fli0ZjNDgtFtHm0LItWmfhNJ1oLjDwPzUWccvwXXoo2mADXaH8JQxyhY+drUuUV5/GMu5PtwqQSqPgZy942VZg==", + "version": "0.9.8", + "resolved": "https://registry.npmjs.org/buefy/-/buefy-0.9.8.tgz", + "integrity": "sha512-VBGAD6WtmgpPdiRnBXaTleS3ifpNu9rbInAr54YL8KJw1RhCb8JtGYYYVRjllnDQmN0jQjC5lYoPR9KpfTe+Cw==", "requires": { - "bulma": "0.9.2" + "bulma": "0.9.3" } }, "buffer": { @@ -17473,9 +17462,9 @@ "integrity": "sha512-+jjPFVqyfF1esi9fvfUs3NqM0pH1ziZ36VP4hmA/y/Ssfo/5w5xHKfTw9BwQjoJ1w/oVtpLomqwUHKdefGyuHw==" }, "bulma": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/bulma/-/bulma-0.9.2.tgz", - "integrity": "sha512-e14EF+3VSZ488yL/lJH0tR8mFWiEQVCMi/BQUMi2TGMBOk+zrDg4wryuwm/+dRSHJw0gMawp2tsW7X1JYUCE3A==" + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/bulma/-/bulma-0.9.3.tgz", + "integrity": "sha512-0d7GNW1PY4ud8TWxdNcP6Cc8Bu7MxcntD/RRLGWuiw/s0a9P+XlH/6QoOIrmbj6o8WWJzJYhytiu9nFjTszk1g==" }, "bytes": { "version": "3.0.0", @@ -17541,18 +17530,19 @@ "dev": true }, "camelcase-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", - "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", "requires": { - "camelcase": "^2.0.0", - "map-obj": "^1.0.0" + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" }, "dependencies": { "camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=" + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" } } }, @@ -18155,9 +18145,9 @@ } }, "core-js": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.14.0.tgz", - "integrity": "sha512-3s+ed8er9ahK+zJpp9ZtuVcDoFzHNiZsPbNAAE4KXgrRHbjSqqNN6xGSXq6bq7TZIbKj4NLrLb6bJ5i+vSVjHA==" + "version": "3.15.2", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.15.2.tgz", + "integrity": "sha512-tKs41J7NJVuaya8DxIOCnl8QuPHx5/ZVbFo1oKgVl1qHFBBrDctzQGtuLjPpRdNTWmKPH6oEvgN/MUID+l485Q==" }, "core-js-compat": { "version": "3.14.0", @@ -18393,14 +18383,6 @@ "css-tree": "^1.1.2" } }, - "currently-unhandled": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", - "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", - "requires": { - "array-find-index": "^1.0.1" - } - }, "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", @@ -18428,6 +18410,22 @@ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" }, + "decamelize-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", + "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", + "requires": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "dependencies": { + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=" + } + } + }, "decode-uri-component": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", @@ -18835,13 +18833,14 @@ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, "eslint": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.28.0.tgz", - "integrity": "sha512-UMfH0VSjP0G4p3EWirscJEQ/cHqnT/iuH6oNZOB94nBjWbMnhGEPxsZm1eyIW0C/9jLI0Fow4W5DXLjEI7mn1g==", + "version": "7.30.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.30.0.tgz", + "integrity": "sha512-VLqz80i3as3NdloY44BQSJpFw534L9Oh+6zJOUaViV4JPd+DaHwutqP7tcpkW3YiXbK6s05RZl7yl7cQn+lijg==", "dev": true, "requires": { "@babel/code-frame": "7.12.11", "@eslint/eslintrc": "^0.4.2", + "@humanwhocodes/config-array": "^0.5.0", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -19010,9 +19009,9 @@ } }, "eslint-plugin-vue": { - "version": "7.11.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-7.11.1.tgz", - "integrity": "sha512-lbw3vkEAGqYjqd1HpPFWHXtYaS8mILTJ5KOpJfRxO3Fo7o0wCf1zD7vSOasbm6nTA9xIgvZQ4VcyGIzQXxznHw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-7.12.1.tgz", + "integrity": "sha512-xHf/wCt88qmzqQerjaSteUFGASj7fPreglKD4ijnvoKRkoSJ3/H3kuJE8QFFtc+2wjw6hRDs834HH7vpuTJQzg==", "dev": true, "requires": { "eslint-utils": "^2.1.0", @@ -19911,6 +19910,11 @@ "har-schema": "^2.0.0" } }, + "hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==" + }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -20254,12 +20258,9 @@ "dev": true }, "indent-string": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", - "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", - "requires": { - "repeating": "^2.0.0" - } + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==" }, "inflight": { "version": "1.0.6", @@ -20569,11 +20570,6 @@ "read-pkg-up": "^7.0.1" } }, - "is-finite": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz", - "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==" - }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", @@ -20660,11 +20656,6 @@ "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==" }, - "is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=" - }, "is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", @@ -20894,33 +20885,6 @@ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=" }, - "load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - }, - "dependencies": { - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "requires": { - "error-ex": "^1.2.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" - } - } - }, "loader-runner": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", @@ -21068,15 +21032,6 @@ "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.7.1.tgz", "integrity": "sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw==" }, - "loud-rejection": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", - "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", - "requires": { - "currently-unhandled": "^0.4.1", - "signal-exit": "^3.0.0" - } - }, "lower-case": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", @@ -21107,9 +21062,9 @@ "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=" }, "map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=" + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.2.1.tgz", + "integrity": "sha512-+WA2/1sPmDj1dlvvJmB5G6JKfY9dpn7EVBUL06+y6PoljPkh+6V1QihwxNkbcGxCRjt2b0F9K0taiCuo7MbdFQ==" }, "map-visit": { "version": "1.0.0", @@ -21144,72 +21099,55 @@ } }, "meow": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", - "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", - "requires": { - "camelcase-keys": "^2.0.0", - "decamelize": "^1.1.2", - "loud-rejection": "^1.0.0", - "map-obj": "^1.0.1", - "minimist": "^1.1.3", - "normalize-package-data": "^2.3.4", - "object-assign": "^4.0.1", - "read-pkg-up": "^1.0.1", - "redent": "^1.0.0", - "trim-newlines": "^1.0.0" - }, - "dependencies": { - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz", + "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==", + "requires": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize": "^1.2.0", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + }, + "dependencies": { + "hosted-git-info": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.0.2.tgz", + "integrity": "sha512-c9OGXbZ3guC/xOlCg1Ci/VgWlwsqDv1yMQL1CWqXDL0hDjXuNcq0zuR4xqPSuasI3kqFDhqSyTjREz5gzq0fXg==", "requires": { - "pinkie-promise": "^2.0.0" + "lru-cache": "^6.0.0" } }, - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "normalize-package-data": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.2.tgz", + "integrity": "sha512-6CdZocmfGaKnIHPVFhJJZ3GuR8SsLKvDANFp47Jmy51aKIr8akjAWTSxtpI+MBgBFdSMRyo4hMpDlT6dTffgZg==", "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" + "hosted-git-info": "^4.0.1", + "resolve": "^1.20.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" } }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" - }, - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" + "lru-cache": "^6.0.0" } }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - } + "type-fest": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==" } } }, @@ -21280,6 +21218,11 @@ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" }, + "min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==" + }, "mini-css-extract-plugin": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-1.6.0.tgz", @@ -21330,6 +21273,28 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" }, + "minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "requires": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "dependencies": { + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" + }, + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=" + } + } + }, "minipass": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", @@ -21579,9 +21544,9 @@ "integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==" }, "node-sass": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-6.0.0.tgz", - "integrity": "sha512-GDzDmNgWNc9GNzTcSLTi6DU6mzSPupVJoStIi7cF3GjwSE9q1cVakbvAAVSt59vzUjV9JJoSZFKoo9krbjKd2g==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-6.0.1.tgz", + "integrity": "sha512-f+Rbqt92Ful9gX0cGtdYwjTrWAaGURgaK5rZCWOgCNyGWusFYHhbqCCBoFBeat+HKETOU02AyTxNhJV0YZf2jQ==", "requires": { "async-foreach": "^0.1.3", "chalk": "^1.1.1", @@ -21590,8 +21555,7 @@ "get-stdin": "^4.0.1", "glob": "^7.0.3", "lodash": "^4.17.15", - "meow": "^3.7.0", - "mkdirp": "^0.5.1", + "meow": "^9.0.0", "nan": "^2.13.2", "node-gyp": "^7.1.0", "npmlog": "^4.0.0", @@ -22574,6 +22538,11 @@ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" }, + "quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==" + }, "randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -22814,12 +22783,12 @@ } }, "redent": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", - "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", "requires": { - "indent-string": "^2.1.0", - "strip-indent": "^1.0.1" + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" } }, "regenerate": { @@ -22996,14 +22965,6 @@ "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" }, - "repeating": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", - "requires": { - "is-finite": "^1.0.0" - } - }, "request": { "version": "2.88.2", "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", @@ -24018,14 +23979,6 @@ "ansi-regex": "^4.1.0" } }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "requires": { - "is-utf8": "^0.2.0" - } - }, "strip-eof": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", @@ -24037,11 +23990,11 @@ "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==" }, "strip-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", - "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", "requires": { - "get-stdin": "^4.0.1" + "min-indent": "^1.0.0" } }, "strip-json-comments": { @@ -24620,9 +24573,9 @@ } }, "trim-newlines": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", - "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=" + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==" }, "true-case-path": { "version": "1.0.3", @@ -24959,9 +24912,9 @@ "integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==" }, "vue-i18n": { - "version": "8.24.4", - "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-8.24.4.tgz", - "integrity": "sha512-RZE94WUAGxEiBAANxQ0pptbRwDkNKNSXl3fnJslpFOxVMF6UkUtMDSuYGuW2blDrVgweIXVpethOVkYoNNT9xw==" + "version": "8.24.5", + "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-8.24.5.tgz", + "integrity": "sha512-p8W5xOmniuZ8fj76VXe0vBL3bRWVU87jHuC/v8VwmhKVH2iMQsKnheB1U+umxDBqC/5g9K+NwzokepcLxnBAVQ==" }, "vue-loader": { "version": "16.2.0", @@ -25034,9 +24987,9 @@ "integrity": "sha512-IDGGV5fC2VPN3zPRNEpm47MjJL1CIPfK34wx3+SRTkUL8dt5/hONmQ2WguBivE1uZVExMVFHekNDnEJamkJ8hA==" }, "vue-router": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.5.1.tgz", - "integrity": "sha512-RRQNLT8Mzr8z7eL4p7BtKvRaTSGdCbTy2+Mm5HTJvLGYSSeG9gDzNasJPP/yOYKLy+/cLG/ftrqq5fvkFwBJEw==" + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.5.2.tgz", + "integrity": "sha512-807gn82hTnjCYGrnF3eNmIw/dk7/GE4B5h69BlyCK9KHASwSloD1Sjcn06zg9fVG4fYH2DrsNBZkpLtb25WtaQ==" }, "vue-style-loader": { "version": "4.1.3", diff --git a/swift_browser_ui_frontend/package.json b/swift_browser_ui_frontend/package.json index bd2e357c6..16b0bb017 100644 --- a/swift_browser_ui_frontend/package.json +++ b/swift_browser_ui_frontend/package.json @@ -1,6 +1,6 @@ { "name": "swift_browser_ui_frontend_npm", - "version": "1.1.0b2", + "version": "1.1.0b3", "private": true, "scripts": { "serve": "vue-cli-service serve", @@ -11,18 +11,18 @@ }, "dependencies": { "@vue/cli-service": "^5.0.0-beta.2", - "buefy": "^0.9.7", - "core-js": "^3.14.0", + "buefy": "^0.9.8", + "core-js": "^3.15.2", "lodash": "^4.17.21", "material-design-icons": "^3.0.1", - "node-sass": "^6.0.0", + "node-sass": "^6.0.1", "resumablejs": "^1.1.0", "sass-loader": "^12.1.0", "serve": "^12.0.0", "vue": "^2.6.14", - "vue-i18n": "^8.24.4", + "vue-i18n": "^8.24.5", "vue-material-design-icons": "^4.12.1", - "vue-router": "^3.5.1", + "vue-router": "^3.5.2", "vuex": "^3.6.2" }, "devDependencies": { @@ -31,8 +31,8 @@ "@vue/cli-service": "^5.0.0-beta.2", "babel-eslint": "^10.1.0", "cli-highlight": "^2.1.11", - "eslint": "^7.28.0", - "eslint-plugin-vue": "^7.11.1", + "eslint": "^7.30.0", + "eslint-plugin-vue": "^7.12.1", "eslint-utils": "^3.0.0", "vue-template-compiler": "^2.6.14" }, diff --git a/swift_browser_ui_frontend/src/common/lang.js b/swift_browser_ui_frontend/src/common/lang.js index 5ceafcd2c..9ada3d3f7 100644 --- a/swift_browser_ui_frontend/src/common/lang.js +++ b/swift_browser_ui_frontend/src/common/lang.js @@ -6,15 +6,27 @@ let default_translations = { en: { message: { index: { + formName: "Openstack Account", logIn: "Log In", + loginmethods: [ + { + msg: "Log In with SSO", + href: "/login", + }, + ], }, error: { frontPage: "To the Front Page", + BadRequest: "400 - Bad Request", + BadRequest_text: "Something was wrong with the request. This can " + + "be for example due to missing password and/or " + + "username.", UIdown: "503 - Service Unavailable", UIdown_text: "Allas User Interface is currently Unavailable", Unauthorized: "401 – Not logged in", Unauthorized_text: "The action requested requires logging " + - "in. Use the button below to Log in.", + "in, or the log in credentials were incorrect. " + + "Use the button below to Log in.", Notfound: "404 – Could not find the page that was requested.", Notfound_text: "The front page, however, can be found – in the link " + "below.", @@ -25,6 +37,8 @@ let default_translations = { "Otherwise head back to the front page from the " + "button below.", }, + help: "Help", + helplink: "", program_name: "Object Browser", program_description: "Web UI for browsing contents in Swift object " + "storage systems.", @@ -42,7 +56,7 @@ let default_translations = { fileHash: "Hash", fileType: "Type", fileDown: "File Download", - owner: "Bucket owner", + owner: "Owner Project Identifier", created: "Created", folderDetails: "No details for folders", clearChecked: "Clear checked", @@ -55,7 +69,7 @@ let default_translations = { }, dashboard: { prj_usage: "Project usage", - account: "Account", + account: "Project Identifier", containers: "Buckets", objects: "Objects", usage: "Usage", @@ -63,9 +77,6 @@ let default_translations = { prj_str_usag: "Project storage usage", equals: "Equals", more_info: "More information", - billing_info: "Pouta billing information", - quota_info: "Pouta default quotas", - avail_info: "Information on project billing unit availability etc.", dashboard: "User information", browser: "Browser", tooltip_disable: "Hide tooltip", @@ -75,19 +86,30 @@ let default_translations = { "values. If there's a separate pricing contract " + "with CSC for the project used, the values " + "specific the project may vary.", - pouta_accounting: "https://docs.csc.fi/cloud/pouta/accounting/", - pouta_obj_store_quota_info: "https://docs.csc.fi/data/Allas/introduction/#billing-and-quotas", - my_csc: "https://my.csc.fi", resources: "Resources", - tokens: "Tokens", + tokens: "Sharing API tokens", + links: [ + { + msg: "Pouta billing information", + href: "https://docs.csc.fi/cloud/pouta/accounting/", + }, + { + msg: "Pouta default quotas", + href: "https://docs.csc.fi/data/Allas/introduction/#billing-and-quotas", + }, + { + msg: "Information on project billing unit availability etc.", + href: "https://my.csc.fi", + }, + ], }, share: { share: "Share", share_cont: "Share the bucket", read_perm: "Grant read permissions", write_perm: "Grant write permissions", - field_label: "UUIDs to share with", - field_placeholder: "Add UUIDs here", + field_label: "Project Identifiers to share with", + field_placeholder: "Add Project Identifiers here", cancel: "Cancel", confirm: "Share", to_me: "Shared to the project", @@ -95,7 +117,7 @@ let default_translations = { request_sharing: "Request sharing", shared: "Shared", container: "Bucket", - owner: "Bucket owner", + owner: "Owner project identifier", shared_details_to: "Shared to: ", shared_details_address: "Bucket address: ", shared_details_rights: "Rights given: ", @@ -103,7 +125,7 @@ let default_translations = { shared_details_write: "Write access", created: "Created", fail_noperm: "Please select permissions to grant!", - fail_noid: "Please give at least one project ID!", + fail_noid: "Please give at least one Project Identifier!", fail_nocont: "Please specify the bucket!", fail_duplicate: "The project already has access to the bucket!", new_share_button: "Share a bucket", @@ -121,10 +143,10 @@ let default_translations = { project: "Project", container: "Bucket / Identfier", container_message: "The requested bucket name", - owner: "Owner", - owner_message: "The requested bucket owner", + owner: "Owner Project Identifier", + owner_message: "Project Identifier of the bucket owner", request: "Request", - multi_project: "Account has access to multiple projects. " + + multi_project: "Your account has access to multiple projects. " + "Please verify that the correct project is set " + "active in the menu, and submit the request with " + "the Request button.", @@ -207,10 +229,20 @@ let default_translations = { fi: { message: { index: { + formName: "Openstack Käyttäjä", logIn: "Kirjaudu sisään", + loginmethods: [ + { + msg: "Kirjaudu SSO:ta käyttäen", + href: "/login", + }, + ], }, error: { frontPage: "Etusivulle", + BadRequest: "400 - Virheellinen pyyntö", + BadRequest_text: "Virhe sivupyynnössä. Tämä voi johtua esimerkiksi " + + "puuttuvasta salasanasta ja/tai käyttäjänimestä ", UIdown: "503 - Palvelu ei ole käytettävissä", UIdown_text: "Allas-käyttöliittymä on tilapäisesti poissa käytöstä", Unauthorized: "401 – Kirjaudu sisään", @@ -225,6 +257,8 @@ let default_translations = { "paluu etusivulle on mahdollista oheisesta " + "painikkeesta", }, + help: "Apua", + helplink: "", program_name: "Object Browser", program_description: "Web-käyttöliittymä tallennettujen tiedostojen " + "selaamiseen Swift-objektitietojärjestelmissä.", @@ -242,7 +276,7 @@ let default_translations = { fileHash: "Tarkistussumma", fileType: "Tyyppi", fileDown: "Tiedoston lataus", - owner: "Säiliön omistaja", + owner: "Omistavan projektin tunniste", created: "Luotu", folderDetails: "Ei yksityiskohtia kansioille", clearChecked: "Poista valinnat", @@ -255,7 +289,7 @@ let default_translations = { }, dashboard: { prj_usage: "Projektin resurssienkäyttö", - account: "Käyttäjä", + account: "Projektin tunniste", containers: "Kontteja", objects: "Objekteja", usage: "Tilankäyttö", @@ -263,10 +297,6 @@ let default_translations = { prj_str_usag: "Projektin tilankäyttö", equals: "Tarkoittaen", more_info: "Lisätietoja", - billing_info: "Tietoa Pouta-palvelun laskutuksesta (englanniksi)", - quota_info: "Tietoa Pouta-palvelun käyttörajoista (englanniksi)", - avail_info: "Tietoa projektin laskutusyksiköiden määrästä jne. " + - "(englanniksi)", dashboard: "Käyttäjän tiedot", browser: "Selain", tooltip_disable: "Piilota ohje", @@ -276,19 +306,31 @@ let default_translations = { "mukaan. Jos käytetylle projektille on erillinen " + "sopimus laskutuksesta CSC:n kanssa, tarkat arvot " + "voivat poiketa näytetyistä.", - pouta_accounting: "https://docs.csc.fi/cloud/pouta/accounting/", - pouta_obj_store_quota_info: "https://docs.csc.fi/data/Allas/introduction/#billing-and-quotas", - my_csc: "https://my.csc.fi", resources: "Resurssit", - tokens: "Avaimet", + tokens: "Jaetun sisällön APIn avaimet", + links: [ + { + msg: "Tietoa Pouta-palvelun laskutuksesta (englanniksi)", + href: "https://docs.csc.fi/cloud/pouta/accounting/", + }, + { + msg: "Tietoa Pouta-palvelun käyttörajoista (englanniksi)", + href: "https://docs.csc.fi/data/Allas/introduction/#billing-and-quotas", + }, + { + msg: "Tietoa projektin laskutusyksiköiden määrästä jne." + + " (englanniksi)", + href: "https://my.csc.fi", + }, + ], }, share: { share: "Jaa", share_cont: "Jaa säiliö", read_perm: "Salli säiliön luku", write_perm: "Salli säiliöön kirjoitus", - field_label: "Jaa UUID:lle", - field_placeholder: "Lisää UUID:t", + field_label: "Jaa projektitunnisteille", + field_placeholder: "Lisää projektitunnisteet", cancel: "Peru", confirm: "Jaa", to_me: "Jaettu projektille", @@ -296,7 +338,7 @@ let default_translations = { request_sharing: "Pyydä jakamista", shared: "Jaettu", container: "Säiliö", - owner: "Säiliön omistaja", + owner: "Omistavan projektin tunniste", created: "Luotu", shared_details_to: "Jaettu projektille: ", shared_details_address: "Säiliön osoite: ", @@ -304,7 +346,8 @@ let default_translations = { shared_details_read: "Lukuoikeus", shared_details_write: "Kirjoitusoikeus", fail_noperm: "Valitse jaettavat oikeudet!", - fail_noid: "Anna vähintään yhden projektin tunnus (Project ID)!", + fail_noid: "Anna vähintään yhden projektin tunniste (Project " + + "Identifier)!", fail_nocont: "Anna jaettava säiliö!", fail_duplicate: "Säiliö on jo jaettu projektille!", new_share_button: "Jaa säiliö", @@ -321,8 +364,8 @@ let default_translations = { project: "Projekti", container: "Säiliö / tunniste", container_message: "Jaettavaksi pyydetyn säiliön nimi", - owner: "Omistaja", - owner_message: "Jaettavaksi pyydetyn säiliön omistaja", + owner: "Omistavan projektin tunniste", + owner_message: "Halutun säiliön omistavan projektin tunniste", request: "Pyydä jakoa", multi_project: "Käyttäjällä on pääsy useisiin projekteihin. " + "Tarkistathan, että haluttu projekti on valittu " + @@ -409,7 +452,12 @@ function nestedJoin (dst, src) { let to_assign = []; for (let [key, value] of Object.entries(src)) { if (typeof(value) == "object") { - to_assign.push([key, nestedJoin(dst[key], src[key])]); + if (key in dst) { + to_assign.push([key, nestedJoin(dst[key], src[key])]); + } + else { + to_assign.push([key, src[key]]); + } } else { to_assign.push([key, value]); } diff --git a/swift_browser_ui_frontend/src/components/BrowserNavbar.vue b/swift_browser_ui_frontend/src/components/BrowserNavbar.vue index 3d0c69102..969c59ce6 100644 --- a/swift_browser_ui_frontend/src/components/BrowserNavbar.vue +++ b/swift_browser_ui_frontend/src/components/BrowserNavbar.vue @@ -47,6 +47,18 @@