diff --git a/frontend/i18next.config.ts b/frontend/i18next.config.ts new file mode 100644 index 00000000..38c090be --- /dev/null +++ b/frontend/i18next.config.ts @@ -0,0 +1,23 @@ +import { defineConfig } from 'i18next-cli'; + +export default defineConfig({ + locales: ['en', 'de', 'nl', 'pt', 'ru', 'fr'], + + extract: { + input: ['src/**/*.{ts,tsx,js,jsx}', '!src/**/*.{test,spec,d}.{ts,tsx}'], + output: 'src/i18n/locales/{{language}}.json', + defaultNS: false, + + primaryLanguage: 'en', + + removeUnusedKeys: true, + + // Dynamic keys to preserve (e.g.: t(`errors.${code}`)) + preservePatterns: [], + + preserveContextVariants: true, + + indentation: 2, + sort:false + }, +}); \ No newline at end of file diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 27a686eb..57f7f305 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -1,12 +1,12 @@ { "name": "picpeak-frontend", - "version": "3.42.2-beta.0", + "version": "3.42.2-beta.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "picpeak-frontend", - "version": "3.42.2-beta.0", + "version": "3.42.2-beta.1", "dependencies": { "@tanstack/react-query": "^5.0.0", "@tiptap/extension-character-count": "^2.26.1", @@ -62,6 +62,7 @@ "eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-react-refresh": "^0.4.20", "globals": "^16.2.0", + "i18next-cli": "^1.56.11", "jsdom": "^25.0.1", "postcss": "^8.5.10", "tailwindcss": "^3.3.0", @@ -146,7 +147,6 @@ "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", @@ -351,9 +351,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz", - "integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==", + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.2.tgz", + "integrity": "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -407,6 +407,23 @@ "node": ">=6.9.0" } }, + "node_modules/@croct/json": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@croct/json/-/json-2.1.0.tgz", + "integrity": "sha512-UrWfjNQVlBxN+OVcFwHmkjARMW55MBN04E9KfGac8ac8z1QnFVuiOOFtMWXCk3UwsyRqhsNaFoYLZC+xxqsVjQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@croct/json5-parser": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@croct/json5-parser/-/json5-parser-0.2.2.tgz", + "integrity": "sha512-0NJMLrbeLbQ0eCVj3UoH/kG2QckUgOASfwmfDTjyW1xAYPyTNJXcWVT/dssJdTJd0pRchW+qF0VFWQHcxs1OVw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@croct/json": "^2.1.0" + } + }, "node_modules/@csstools/color-helpers": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.1.0.tgz", @@ -495,7 +512,6 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": ">=18" }, @@ -519,7 +535,6 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": ">=18" } @@ -1182,6 +1197,377 @@ "url": "https://github.com/sponsors/nzakas" } }, + "node_modules/@inquirer/ansi": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-2.0.5.tgz", + "integrity": "sha512-doc2sWgJpbFQ64UflSVd17ibMGDuxO1yKgOgLMwavzESnXjFWJqUeG8saYosqKpHp4kWiM5x1nXvEjbpx90gzw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + } + }, + "node_modules/@inquirer/checkbox": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-5.1.4.tgz", + "integrity": "sha512-w6KF8ZYRvqHhROkOTHXYC3qIV/KYEu5o12oLqQySvch61vrYtRxNSHTONSdJqWiFJPlCUQAHT5OgOIyuTr+MHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^2.0.5", + "@inquirer/core": "^11.1.9", + "@inquirer/figures": "^2.0.5", + "@inquirer/type": "^4.0.5" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/confirm": { + "version": "6.0.12", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-6.0.12.tgz", + "integrity": "sha512-h9FgGun3QwVYNj5TWIZZ+slii73bMoBFjPfVIGtnFuL4t8gBiNDV9PcSfIzkuxvgquJKt9nr1QzszpBzTbH8Og==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^11.1.9", + "@inquirer/type": "^4.0.5" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/core": { + "version": "11.1.9", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-11.1.9.tgz", + "integrity": "sha512-BDE4fG22uYh1bGSifcj7JSx119TVYNViMhMu85usp4Fswrzh6M0DV3yld64jA98uOAa2GSQ4Bg4bZRm2d2cwSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^2.0.5", + "@inquirer/figures": "^2.0.5", + "@inquirer/type": "^4.0.5", + "cli-width": "^4.1.0", + "fast-wrap-ansi": "^0.2.0", + "mute-stream": "^3.0.0", + "signal-exit": "^4.1.0" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/editor": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-5.1.1.tgz", + "integrity": "sha512-6y11LgmNpmn5D2aB5FgnCfBUBK8ZstwLCalyJmORcJZ/WrhOjm16mu6eSqIx8DnErxDqSLr+Jkp+GP8/Nwd5tA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^11.1.9", + "@inquirer/external-editor": "^3.0.0", + "@inquirer/type": "^4.0.5" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/expand": { + "version": "5.0.13", + "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-5.0.13.tgz", + "integrity": "sha512-dF2zvrFo9LshkcB23/O1il13kBkBltWIXzut1evfbuBLXMiGIuC45c+ZQ0uukjCDsvI8OWqun4FRYMnzFCQa3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^11.1.9", + "@inquirer/type": "^4.0.5" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/external-editor": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-3.0.0.tgz", + "integrity": "sha512-lDSwMgg+M5rq6JKBYaJwSX6T9e/HK2qqZ1oxmOwn4AQoJE5D+7TumsxLGC02PWS//rkIVqbZv3XA3ejsc9FYvg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chardet": "^2.1.1", + "iconv-lite": "^0.7.2" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/external-editor/node_modules/iconv-lite": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", + "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/@inquirer/figures": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-2.0.5.tgz", + "integrity": "sha512-NsSs4kzfm12lNetHwAn3GEuH317IzpwrMCbOuMIVytpjnJ90YYHNwdRgYGuKmVxwuIqSgqk3M5qqQt1cDk0tGQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + } + }, + "node_modules/@inquirer/input": { + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-5.0.12.tgz", + "integrity": "sha512-uiMFBl4LqFzJClh80Q3f9hbOFJ6kgkDWI4LjAeBuyO6EanVVMF69AgOvpi1qdqjDSjDN6578B6nky9ceEpI+1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^11.1.9", + "@inquirer/type": "^4.0.5" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/number": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-4.0.12.tgz", + "integrity": "sha512-/vrwhEf7Xsuh+YlHF4IjSy3g1cyrQuPaSiHIxCEbLu8qnfvrcvJyCkoktOOF+xV9gSb77/G0n3h04RbMDW2sIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^11.1.9", + "@inquirer/type": "^4.0.5" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/password": { + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-5.0.12.tgz", + "integrity": "sha512-CBh7YHju623lxJRcAOo498ZUwIuMy63bqW/vVq0tQAZVv+lkWlHkP9ealYE1utWSisEShY5VMdzIXRmyEODzcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^2.0.5", + "@inquirer/core": "^11.1.9", + "@inquirer/type": "^4.0.5" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/prompts": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-8.4.2.tgz", + "integrity": "sha512-XJmn/wY4AX56l1BRU+ZjDrFtg9+2uBEi4JvJQj82kwJDQKiPgSn4CEsbfGGygS4Gw6rkL4W18oATjfVfaqub2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/checkbox": "^5.1.4", + "@inquirer/confirm": "^6.0.12", + "@inquirer/editor": "^5.1.1", + "@inquirer/expand": "^5.0.13", + "@inquirer/input": "^5.0.12", + "@inquirer/number": "^4.0.12", + "@inquirer/password": "^5.0.12", + "@inquirer/rawlist": "^5.2.8", + "@inquirer/search": "^4.1.8", + "@inquirer/select": "^5.1.4" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/rawlist": { + "version": "5.2.8", + "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-5.2.8.tgz", + "integrity": "sha512-Su7FQvp5buZmCymN3PPoYv31ZQQX4ve2j02k7piGgKAWgE+AQRB5YoYVveGXcl3TZ9ldgRMSxj56YfDFmmaqLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^11.1.9", + "@inquirer/type": "^4.0.5" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/search": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-4.1.8.tgz", + "integrity": "sha512-fGiHKGD6DyPIYUWxoXnQTeXeyYqSOUrasDMABBmMHUalH/LxkuzY0xVRtimXAt1sUeeyYkVuKQx1bebMuN11Kw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^11.1.9", + "@inquirer/figures": "^2.0.5", + "@inquirer/type": "^4.0.5" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/select": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-5.1.4.tgz", + "integrity": "sha512-2kWcGKPMLAXAWRp1AH1SLsQmX+j0QjeljyXMUji9WMZC8nRDO0b7qquIGr6143E7KMLt3VAIGNXzwa/6PXQs4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^2.0.5", + "@inquirer/core": "^11.1.9", + "@inquirer/figures": "^2.0.5", + "@inquirer/type": "^4.0.5" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/type": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-4.0.5.tgz", + "integrity": "sha512-aetVUNeKNc/VriqXlw1NRSW0zhMBB0W4bNbWRJgzRl/3d0QNDQFfk0GO5SDdtjMZVg6o8ZKEiadd7SCCzoOn5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@isaacs/cliui": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-9.0.0.tgz", + "integrity": "sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.13", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", @@ -1651,6 +2037,288 @@ "win32" ] }, + "node_modules/@sec-ant/readable-stream": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz", + "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@sindresorhus/merge-streams": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", + "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@swc/core": { + "version": "1.15.33", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.15.33.tgz", + "integrity": "sha512-jOlwnFV2xhuuZeAUILGFULeR6vDPfijEJ57evfocwznQldLU3w2cZ9bSDryY9ip+AsM3r1NJKzf47V2NXebkeQ==", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "@swc/counter": "^0.1.3", + "@swc/types": "^0.1.26" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/swc" + }, + "optionalDependencies": { + "@swc/core-darwin-arm64": "1.15.33", + "@swc/core-darwin-x64": "1.15.33", + "@swc/core-linux-arm-gnueabihf": "1.15.33", + "@swc/core-linux-arm64-gnu": "1.15.33", + "@swc/core-linux-arm64-musl": "1.15.33", + "@swc/core-linux-ppc64-gnu": "1.15.33", + "@swc/core-linux-s390x-gnu": "1.15.33", + "@swc/core-linux-x64-gnu": "1.15.33", + "@swc/core-linux-x64-musl": "1.15.33", + "@swc/core-win32-arm64-msvc": "1.15.33", + "@swc/core-win32-ia32-msvc": "1.15.33", + "@swc/core-win32-x64-msvc": "1.15.33" + }, + "peerDependencies": { + "@swc/helpers": ">=0.5.17" + }, + "peerDependenciesMeta": { + "@swc/helpers": { + "optional": true + } + } + }, + "node_modules/@swc/core-darwin-arm64": { + "version": "1.15.33", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.15.33.tgz", + "integrity": "sha512-N+L0uXhuO7FIfzqwgxmzv0zIpV0qEp8wPX3QQs2p4atjMoywup2JTeDlXPw+z9pWJGCae3JjM+tZ6myclI+2gA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-darwin-x64": { + "version": "1.15.33", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.15.33.tgz", + "integrity": "sha512-/Il4QHSOhV4FekbsDtkrNmKbsX26oSysvgrRswa/RYOHXAkwXDbB4jaeKq6PsJLSPkzJ2KzQ061gtBnk0vNHfA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm-gnueabihf": { + "version": "1.15.33", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.15.33.tgz", + "integrity": "sha512-C64hBnBxq4viOPQ8hlx+2lJ23bzZBGnjw7ryALmS+0Q3zHmwO8lw1/DArLENw4Q18/0w5wdEO1k3m1wWNtKGqQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-gnu": { + "version": "1.15.33", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.15.33.tgz", + "integrity": "sha512-TRJfnJbX3jqpxRDRoieMzRiCBS5jOmXNb3iQXmcgjFEHKLnAgK1RZRU8Cq1MsPqO4jAJp/ld1G4O3fXuxv85uw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-musl": { + "version": "1.15.33", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.15.33.tgz", + "integrity": "sha512-il7tYM+CpUNzieQbwAjFT1P8zqAhmGWNAGhQZBnxurXZ0aNn+5nqYFTEUKNZl7QibtT0uQXzTZrNGHCIj6Y1Og==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-ppc64-gnu": { + "version": "1.15.33", + "resolved": "https://registry.npmjs.org/@swc/core-linux-ppc64-gnu/-/core-linux-ppc64-gnu-1.15.33.tgz", + "integrity": "sha512-ZtNBwN0Z7CFj9Il0FcPaKdjgP7URyKu/3RfH46vq+0paOBqLj4NYldD6Qo//Duif/7IOtAraUfDOmp0PLAufog==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-s390x-gnu": { + "version": "1.15.33", + "resolved": "https://registry.npmjs.org/@swc/core-linux-s390x-gnu/-/core-linux-s390x-gnu-1.15.33.tgz", + "integrity": "sha512-De1IyajoOmhOYYjw/lx66bKlyDpHZTueqwpDrWgf5O7T6d1ODeJJO9/OqMBmrBQc5C+dNnlmIufHsp4QVCWufA==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-gnu": { + "version": "1.15.33", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.15.33.tgz", + "integrity": "sha512-mGTH0YxmUN+x6vRN/I6NOk5X0ogNktkwPnJ94IMvR7QjhRDwL0O8RXEDhyUM0YtwWrryBOqaJQBX4zruxEPRGw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-musl": { + "version": "1.15.33", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.15.33.tgz", + "integrity": "sha512-hj628ZkSEJf6zMf5VMbYrG2O6QqyTIp2qwY6VlCjvIa9lAEZ5c2lfPblCLVGYubTeLJDxadLB/CxqQYOQABeEQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-arm64-msvc": { + "version": "1.15.33", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.15.33.tgz", + "integrity": "sha512-GV2oohtN2/5+KSccl86VULu3aT+LrISC8uzgSq0FRnikpD+Zwc+sBlXmoKQ+Db6jI57ITUOIB8jRkdGMABC29g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-ia32-msvc": { + "version": "1.15.33", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.15.33.tgz", + "integrity": "sha512-gtyvzSNR8DHKfFEA2uqb8Ld1myqi6uEg2jyeUq3ikn5ytYs7H8RpZYC8mdy4NXr8hfcdJfCLXPlYaqqfBXpoEQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-x64-msvc": { + "version": "1.15.33", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.15.33.tgz", + "integrity": "sha512-d6fRqQSkJI+kmMEBWaDQ7TMl8+YjLYbwRUPZQ9DY0ORBJeTzOrG0twvfvlZ2xgw6jA0ScQKgfBm4vHLSLl5Hqg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/counter": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", + "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/@swc/types": { + "version": "0.1.26", + "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.26.tgz", + "integrity": "sha512-lyMwd7WGgG79RS7EERZV3T8wMdmPq3xwyg+1nmAM64kIhx5yl+juO2PYIHb7vTiPgPCj8LYjsNV2T5wiQHUEaw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@swc/counter": "^0.1.3" + } + }, "node_modules/@tanstack/query-core": { "version": "5.90.16", "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.90.16.tgz", @@ -1704,6 +2372,7 @@ "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", "dev": true, "license": "Apache-2.0", + "peer": true, "dependencies": { "dequal": "^2.0.3" } @@ -1713,7 +2382,8 @@ "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@testing-library/jest-dom": { "version": "6.9.1", @@ -1782,7 +2452,6 @@ "resolved": "https://registry.npmjs.org/@tiptap/core/-/core-2.27.1.tgz", "integrity": "sha512-nkerkl8syHj44ZzAB7oA2GPmmZINKBKCa79FuNvmGJrJ4qyZwlkDzszud23YteFZEytbc87kVd/fP76ROS6sLg==", "license": "MIT", - "peer": true, "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -1879,7 +2548,6 @@ "resolved": "https://registry.npmjs.org/@tiptap/extension-code-block/-/extension-code-block-2.27.1.tgz", "integrity": "sha512-wCI5VIOfSAdkenCWFvh4m8FFCJ51EOK+CUmOC/PWUjyo2Dgn8QC8HMi015q8XF7886T0KvYVVoqxmxJSUDAYNg==", "license": "MIT", - "peer": true, "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -2158,7 +2826,6 @@ "resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-2.27.1.tgz", "integrity": "sha512-ijKo3+kIjALthYsnBmkRXAuw2Tswd9gd7BUR5OMfIcjGp8v576vKxOxrRfuYiUM78GPt//P0sVc1WV82H5N0PQ==", "license": "MIT", - "peer": true, "dependencies": { "prosemirror-changeset": "^2.3.0", "prosemirror-collab": "^1.3.1", @@ -2245,7 +2912,8 @@ "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@types/babel__core": { "version": "7.20.5", @@ -2381,7 +3049,6 @@ "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.27.tgz", "integrity": "sha512-cisd7gxkzjBKU2GgdYrTdtQx1SORymWyaAFhaxQPK9bYO9ot3Y5OikQRvY0VYQtvwjeQnizCINJAenh/V7MK2w==", "license": "MIT", - "peer": true, "dependencies": { "@types/prop-types": "*", "csstype": "^3.2.2" @@ -2393,7 +3060,6 @@ "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==", "devOptional": true, "license": "MIT", - "peer": true, "peerDependencies": { "@types/react": "^18.0.0" } @@ -2471,7 +3137,6 @@ "integrity": "sha512-jCzKdm/QK0Kg4V4IK/oMlRZlY+QOcdjv89U2NgKHZk1CYTj82/RVSx1mV/0gqCVMJ/DA+Zf/S4NBWNF8GQ+eqQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.48.0", "@typescript-eslint/types": "8.48.0", @@ -2838,7 +3503,6 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -2889,6 +3553,7 @@ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=8" } @@ -3104,7 +3769,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -3217,6 +3881,13 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/chardet": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.1.tgz", + "integrity": "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==", + "dev": true, + "license": "MIT" + }, "node_modules/check-error": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", @@ -3265,6 +3936,45 @@ "node": ">= 6" } }, + "node_modules/cli-cursor": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-spinners": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-3.4.0.tgz", + "integrity": "sha512-bXfOC4QcT1tKXGorxL3wbJm6XJPDqEnij2gQ2m7ESQuE+/z9YFIWnl/5RpTiKWbMq3EVKR4fRLJGn6DVfu0mpw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 12" + } + }, "node_modules/clsx": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", @@ -3543,6 +4253,7 @@ "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=6" } @@ -3732,7 +4443,6 @@ "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -3914,6 +4624,33 @@ "node": ">=0.10.0" } }, + "node_modules/execa": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-9.6.1.tgz", + "integrity": "sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/merge-streams": "^4.0.0", + "cross-spawn": "^7.0.6", + "figures": "^6.1.0", + "get-stream": "^9.0.0", + "human-signals": "^8.0.1", + "is-plain-obj": "^4.1.0", + "is-stream": "^4.0.1", + "npm-run-path": "^6.0.0", + "pretty-ms": "^9.2.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^4.0.0", + "yoctocolors": "^2.1.1" + }, + "engines": { + "node": "^18.19.0 || >=20.5.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, "node_modules/expect-type": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.2.tgz", @@ -3974,6 +4711,33 @@ "dev": true, "license": "MIT" }, + "node_modules/fast-string-truncated-width": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fast-string-truncated-width/-/fast-string-truncated-width-3.0.3.tgz", + "integrity": "sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-string-width": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/fast-string-width/-/fast-string-width-3.0.2.tgz", + "integrity": "sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-string-truncated-width": "^3.0.2" + } + }, + "node_modules/fast-wrap-ansi": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/fast-wrap-ansi/-/fast-wrap-ansi-0.2.0.tgz", + "integrity": "sha512-rLV8JHxTyhVmFYhBJuMujcrHqOT2cnO5Zxj37qROj23CP39GXubJRBUFF0z8KFK77Uc0SukZUf7JZhsVEQ6n8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-string-width": "^3.0.2" + } + }, "node_modules/fastq": { "version": "1.19.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", @@ -4015,6 +4779,22 @@ } } }, + "node_modules/figures": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-6.1.0.tgz", + "integrity": "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-unicode-supported": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/file-entry-cache": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", @@ -4099,6 +4879,23 @@ } } }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/form-data": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", @@ -4198,6 +4995,19 @@ "node": ">=6.9.0" } }, + "node_modules/get-east-asian-width": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz", + "integrity": "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-intrinsic": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", @@ -4235,6 +5045,48 @@ "node": ">= 0.4" } }, + "node_modules/get-stream": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", + "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sec-ant/readable-stream": "^0.4.1", + "is-stream": "^4.0.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.1.0.tgz", + "integrity": "sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "foreground-child": "^3.3.1", + "jackspeak": "^4.1.1", + "minimatch": "^10.1.1", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^2.0.0" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -4248,6 +5100,45 @@ "node": ">=10.13.0" } }, + "node_modules/glob/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", + "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/globals": { "version": "16.5.0", "resolved": "https://registry.npmjs.org/globals/-/globals-16.5.0.tgz", @@ -4334,7 +5225,6 @@ "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.8.0.tgz", "integrity": "sha512-MedQhoqVdr0U6SSnWPzfiadUcDHfN/Wzq25AkXiQv9oiOO/sG0S7XkvpFIqWBl9Yq1UYyYOOVORs5UW2XlPyzg==", "license": "BSD-3-Clause", - "peer": true, "engines": { "node": ">=12.0.0" } @@ -4398,6 +5288,16 @@ "node": ">= 14" } }, + "node_modules/human-signals": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.1.tgz", + "integrity": "sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, "node_modules/i18next": { "version": "25.7.3", "resolved": "https://registry.npmjs.org/i18next/-/i18next-25.7.3.tgz", @@ -4417,7 +5317,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "@babel/runtime": "^7.28.4" }, @@ -4439,6 +5338,194 @@ "@babel/runtime": "^7.23.2" } }, + "node_modules/i18next-cli": { + "version": "1.56.11", + "resolved": "https://registry.npmjs.org/i18next-cli/-/i18next-cli-1.56.11.tgz", + "integrity": "sha512-SGYBCVtU8GrO08WCuxLFcySzQXRROEDFcfToywPiqicD8jUSF6qsqMA7wv5uO2KFnCSTCj+iEO4G2JD5XeEpkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@croct/json5-parser": "^0.2.2", + "@swc/core": "^1.15.26", + "chokidar": "^5.0.0", + "commander": "^14.0.3", + "execa": "^9.6.1", + "glob": "^13.0.6", + "i18next-resources-for-ts": "^2.1.0", + "inquirer": "^13.4.1", + "jiti": "^2.6.1", + "jsonc-parser": "^3.3.1", + "magic-string": "^0.30.21", + "minimatch": "^10.2.5", + "ora": "^9.3.0", + "react": "^19.2.5", + "react-i18next": "^17.0.7", + "yaml": "^2.8.3" + }, + "bin": { + "i18next-cli": "dist/esm/cli.js" + }, + "engines": { + "node": ">=22" + } + }, + "node_modules/i18next-cli/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/i18next-cli/node_modules/brace-expansion": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", + "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/i18next-cli/node_modules/chokidar": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz", + "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^5.0.0" + }, + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/i18next-cli/node_modules/commander": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz", + "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/i18next-cli/node_modules/i18next": { + "version": "26.0.10", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-26.0.10.tgz", + "integrity": "sha512-k3yGPAlWR2RdMYoVXJoDZDT87qeHIWKH7gVksdZMpRty7QX/D9QZeYGvN08KGbKHke9wn01eYT+EEsrqX/YTlw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://www.locize.com/i18next" + }, + { + "type": "individual", + "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project" + }, + { + "type": "individual", + "url": "https://www.locize.com" + } + ], + "license": "MIT", + "peer": true, + "peerDependencies": { + "typescript": "^5 || ^6" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/i18next-cli/node_modules/jiti": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz", + "integrity": "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/i18next-cli/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/i18next-cli/node_modules/react": { + "version": "19.2.6", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.6.tgz", + "integrity": "sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/i18next-cli/node_modules/react-i18next": { + "version": "17.0.7", + "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-17.0.7.tgz", + "integrity": "sha512-rwtPXsb/zwzDafN+gytcjF5YnqGQQIRmCQ6DctBC1VSipRB8GD/MWEVrFP42vjMyuYydxWxM8CZRt+yiNuuoHg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.29.2", + "html-parse-stringify": "^3.0.1", + "use-sync-external-store": "^1.6.0" + }, + "peerDependencies": { + "i18next": ">= 26.0.10", + "react": ">= 16.8.0", + "typescript": "^5 || ^6" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/i18next-cli/node_modules/readdirp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz", + "integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/i18next-http-backend": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/i18next-http-backend/-/i18next-http-backend-3.0.6.tgz", @@ -4448,6 +5535,52 @@ "cross-fetch": "4.1.0" } }, + "node_modules/i18next-resources-for-ts": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/i18next-resources-for-ts/-/i18next-resources-for-ts-2.1.0.tgz", + "integrity": "sha512-n5UexwEVt0OoIAhG2MWpSnAVJW1U8mQrQTmXyxc5DMAx+NLhcLZhSMJo/FnUsA5JQ3obTYqTgB7YIuZKWpDgow==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.28.6", + "@swc/core": "^1.15.18", + "chokidar": "^5.0.0", + "yaml": "^2.8.2" + }, + "bin": { + "i18next-resources-for-ts": "bin/i18next-resources-for-ts.js" + } + }, + "node_modules/i18next-resources-for-ts/node_modules/chokidar": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz", + "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^5.0.0" + }, + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/i18next-resources-for-ts/node_modules/readdirp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz", + "integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -4508,6 +5641,33 @@ "node": ">=8" } }, + "node_modules/inquirer": { + "version": "13.4.2", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-13.4.2.tgz", + "integrity": "sha512-ziXEKBO6nxsX9Z3XEh7LNiUvYN/o5PYuYK+27l69NpjSUOh6JXQsQAKEw2AnZq5xvHeb3ZwkpzOxvNOswIX1fg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^2.0.5", + "@inquirer/core": "^11.1.9", + "@inquirer/prompts": "^8.4.2", + "@inquirer/type": "^4.0.5", + "mute-stream": "^3.0.0", + "run-async": "^4.0.6", + "rxjs": "^7.8.2" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -4560,6 +5720,19 @@ "node": ">=0.10.0" } }, + "node_modules/is-interactive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", + "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -4570,6 +5743,19 @@ "node": ">=0.12.0" } }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-potential-custom-element-name": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", @@ -4577,6 +5763,32 @@ "dev": true, "license": "MIT" }, + "node_modules/is-stream": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", + "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-unicode-supported": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", + "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -4584,13 +5796,28 @@ "dev": true, "license": "ISC" }, + "node_modules/jackspeak": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.2.3.tgz", + "integrity": "sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^9.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/jiti": { "version": "1.21.7", "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", "dev": true, "license": "MIT", - "peer": true, "bin": { "jiti": "bin/jiti.js" } @@ -4739,6 +5966,13 @@ "node": ">=6" } }, + "node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "dev": true, + "license": "MIT" + }, "node_modules/justified-layout": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/justified-layout/-/justified-layout-4.1.0.tgz", @@ -4833,6 +6067,23 @@ "dev": true, "license": "MIT" }, + "node_modules/log-symbols": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-7.0.1.tgz", + "integrity": "sha512-ja1E3yCr9i/0hmBVaM0bfwDjnGy8I/s6PP4DFp+yP+a+mrHO4Rm7DtmnqROTUkHIkqffC84YY7AeqX6oFk0WFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-unicode-supported": "^2.0.0", + "yoctocolors": "^2.1.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -4857,7 +6108,6 @@ "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-2.9.0.tgz", "integrity": "sha512-OpcaUTCLmHuVuBcyNckKfH5B0oA4JUavb/M/8n9iAvanJYNQkrVm4pvyX0SUaqkBG4dnWHKt7p50B3ngAG2Rfw==", "license": "MIT", - "peer": true, "dependencies": { "@types/hast": "^2.0.0", "fault": "^2.0.0", @@ -4893,6 +6143,7 @@ "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", "dev": true, "license": "MIT", + "peer": true, "bin": { "lz-string": "bin/bin.js" } @@ -4997,6 +6248,19 @@ "node": ">= 0.6" } }, + "node_modules/mimic-function": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", + "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", @@ -5020,6 +6284,16 @@ "node": "*" } }, + "node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/motion-dom": { "version": "12.33.0", "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.33.0.tgz", @@ -5042,6 +6316,16 @@ "dev": true, "license": "MIT" }, + "node_modules/mute-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-3.0.0.tgz", + "integrity": "sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, "node_modules/mz": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", @@ -5117,6 +6401,36 @@ "node": ">=0.10.0" } }, + "node_modules/npm-run-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-6.0.0.tgz", + "integrity": "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^4.0.0", + "unicorn-magic": "^0.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/nwsapi": { "version": "2.2.22", "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.22.tgz", @@ -5143,6 +6457,22 @@ "node": ">= 6" } }, + "node_modules/onetime": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-function": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", @@ -5161,6 +6491,42 @@ "node": ">= 0.8.0" } }, + "node_modules/ora": { + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-9.4.0.tgz", + "integrity": "sha512-84cglkRILFxdtA8hAvLNdMrtBpPNBTrQ9/ulg0FA7xLMnD6mifv+enAIeRmvtv+WgdCE+LPGOfQmtJRrVaIVhQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^5.6.2", + "cli-cursor": "^5.0.0", + "cli-spinners": "^3.2.0", + "is-interactive": "^2.0.0", + "is-unicode-supported": "^2.1.0", + "log-symbols": "^7.0.1", + "stdin-discarder": "^0.3.2", + "string-width": "^8.1.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, "node_modules/orderedmap": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/orderedmap/-/orderedmap-2.1.1.tgz", @@ -5199,6 +6565,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -5212,6 +6585,19 @@ "node": ">=6" } }, + "node_modules/parse-ms": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-4.0.0.tgz", + "integrity": "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/parse5": { "version": "7.3.0", "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", @@ -5265,6 +6651,33 @@ "dev": true, "license": "MIT" }, + "node_modules/path-scurry": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "11.3.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.6.tgz", + "integrity": "sha512-Gf/KoL3C/MlI7Bt0PGI9I+TeTC/I6r/csU58N4BSNc4lppLBeKsOdFYkK+dX0ABDUMJNfCHTyPpzwwO21Awd3A==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, "node_modules/pathe": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", @@ -5304,7 +6717,6 @@ "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -5352,7 +6764,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -5512,6 +6923,7 @@ "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", @@ -5527,6 +6939,7 @@ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=10" }, @@ -5539,7 +6952,24 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true + }, + "node_modules/pretty-ms": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.3.0.tgz", + "integrity": "sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parse-ms": "^4.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/prop-types": { "version": "15.8.1", @@ -5664,7 +7094,6 @@ "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.25.4.tgz", "integrity": "sha512-PIM7E43PBxKce8OQeezAs9j4TP+5yDpZVbuurd1h5phUxEKIu+G2a+EUZzIC5nS1mJktDJWzbqS23n1tsAf5QA==", "license": "MIT", - "peer": true, "dependencies": { "orderedmap": "^2.0.0" } @@ -5694,7 +7123,6 @@ "resolved": "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.4.4.tgz", "integrity": "sha512-6jiYHH2CIGbCfnxdHbXZ12gySFY/fz/ulZE333G6bPqIZ4F+TXo9ifiR86nAHpWnfoNjOb3o5ESi7J8Uz1jXHw==", "license": "MIT", - "peer": true, "dependencies": { "prosemirror-model": "^1.0.0", "prosemirror-transform": "^1.0.0", @@ -5743,7 +7171,6 @@ "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.41.3.tgz", "integrity": "sha512-SqMiYMUQNNBP9kfPhLO8WXEk/fon47vc52FQsUiJzTBuyjKgEcoAwMyF04eQ4WZ2ArMn7+ReypYL60aKngbACQ==", "license": "MIT", - "peer": true, "dependencies": { "prosemirror-model": "^1.20.0", "prosemirror-state": "^1.0.0", @@ -5804,7 +7231,6 @@ "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "license": "MIT", - "peer": true, "dependencies": { "loose-envify": "^1.1.0" }, @@ -5843,7 +7269,6 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", "license": "MIT", - "peer": true, "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.2" @@ -6078,6 +7503,23 @@ "node": ">=4" } }, + "node_modules/restore-cursor": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/reusify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", @@ -6147,6 +7589,16 @@ "dev": true, "license": "MIT" }, + "node_modules/run-async": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-4.0.6.tgz", + "integrity": "sha512-IoDlSLTs3Yq593mb3ZoKWKXMNu3UpObxhgA/Xuid5p4bbfi2jdY1Hj0m1K+0/tEuQTxIGMhQDqGjKb7RuxGpAQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -6171,6 +7623,16 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -6240,6 +7702,19 @@ "dev": true, "license": "ISC" }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -6264,6 +7739,78 @@ "dev": true, "license": "MIT" }, + "node_modules/stdin-discarder": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.3.2.tgz", + "integrity": "sha512-eCPu1qRxPVkl5605OTWF8Wz40b4Mf45NY5LQmVPQ599knfs5QhASUm9GbJ5BDMDOXgrnh0wyEdvzmL//YMlw0A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.1.tgz", + "integrity": "sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.5.0", + "strip-ansi": "^7.1.2" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/strip-final-newline": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-4.0.0.tgz", + "integrity": "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/strip-indent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", @@ -6623,7 +8170,6 @@ "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", "devOptional": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -6662,6 +8208,19 @@ "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", "license": "MIT" }, + "node_modules/unicorn-magic": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", + "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/update-browserslist-db": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", @@ -6725,7 +8284,6 @@ "integrity": "sha512-/4XH147Ui7OGTjg3HbdWe5arnZQSbfuRzdr9Ec7TQi5I7R+ir0Rlc9GIvD4v0XZurELqA035KVXJXpR61xhiTA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", @@ -7047,6 +8605,22 @@ "dev": true, "license": "ISC" }, + "node_modules/yaml": { + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.4.tgz", + "integrity": "sha512-ml/JPOj9fOQK8RNnWojA67GbZ0ApXAUlN2UQclwv2eVgTgn7O9gg9o7paZWKMp4g0H3nTLtS9LVzhkpOFIKzog==", + "dev": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" + } + }, "node_modules/yet-another-react-lightbox": { "version": "3.28.0", "resolved": "https://registry.npmjs.org/yet-another-react-lightbox/-/yet-another-react-lightbox-3.28.0.tgz", @@ -7085,6 +8659,19 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/yoctocolors": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.2.tgz", + "integrity": "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } } } diff --git a/frontend/package.json b/frontend/package.json index 28f5af44..bcf50c7e 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -9,7 +9,10 @@ "build:check": "tsc -b && node ./scripts/build.js", "lint": "eslint .", "preview": "vite preview", - "test": "vitest run src/components/admin/__tests__/ThemeCustomizerEnhanced.test.tsx" + "test": "vitest run src/components/admin/__tests__/ThemeCustomizerEnhanced.test.tsx", + "i18n:extract": "i18next-cli extract", + "i18n:status": "i18next-cli status", + "i18n:ci": "i18next-cli extract --ci --dry-run" }, "dependencies": { "@tanstack/react-query": "^5.0.0", @@ -66,6 +69,7 @@ "eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-react-refresh": "^0.4.20", "globals": "^16.2.0", + "i18next-cli": "^1.56.11", "jsdom": "^25.0.1", "postcss": "^8.5.10", "tailwindcss": "^3.3.0", diff --git a/frontend/src/i18n/locales/en.json b/frontend/src/i18n/locales/en.json index dde48779..5c83fcbd 100644 --- a/frontend/src/i18n/locales/en.json +++ b/frontend/src/i18n/locales/en.json @@ -81,8 +81,6 @@ "delete": "Delete", "edit": "Edit", "add": "Add", - "search": "Search", - "filter": "Filter", "sortBy": "Sort by", "yes": "Yes", "no": "No", @@ -91,35 +89,41 @@ "previous": "Previous", "close": "Close", "logout": "Logout", - "menu": "Menu", "change": "Change", "remove": "Remove", "download": "Download", "downloadAll": "Download All", - "uploading": "Uploading...", - "uploaded": "Uploaded", "photo": "photo", "photos": "photos", "video": "video", - "videos": "videos", "media": "media", - "restore": "Restore", - "actions": "Actions", - "refresh": "Refresh", - "preview": "Preview", - "processing": "Processing...", "upload": "Upload", - "days": "days", "customize": "Customize", "hide": "Hide", "unknown": "Unknown", "notSet": "Not set", "of": "of", - "up": "Up", - "select": "Select", "selected": "Selected", "chunk": "Chunk", - "optional": "optional" + "optional": "optional", + "tryAgain": "Try Again", + "active": "Active", + "inactive": "Inactive", + "create": "Create", + "unknownDate": "Unknown date", + "pageOf": "Page {{current}} of {{total}}", + "collapse": "Collapse", + "expand": "Expand", + "submitting": "Submitting...", + "copy": "Copy", + "copied": "Copied!", + "applying": "Applying...", + "done": "Done", + "retry": "Retry", + "characters": "characters", + "saveChanges": "Save Changes", + "resetChanges": "Reset Changes", + "dismiss": "Dismiss" }, "upload": { "photoCategory": "Photo Category", @@ -127,48 +131,34 @@ "eventSpecific": "(Event specific)", "clickToUpload": "Click to upload or drag and drop", "fileRequirements": "JPEG, PNG or WebP (max 50MB per file, {{limit}} files per upload)", - "fileRequirementsMedia": "JPEG, PNG or WebP images, plus MP4/MOV/WEBM videos (max 50MB per file, {{limit}} files per upload)", - "unsupportedFiles": "Some files were skipped because the format is not supported (use JPEG/PNG/WebP/MP4/MOV/WEBM).", "selectedFiles": "Selected files", "uploading": "Uploading...", "transferring": "Transferring", "processing": "Processing photos...", "processingHint": "Files are uploaded. PicPeak is now generating thumbnails and reading metadata. You can leave this page — work continues in the background.", "processingProgress": "{{complete}} of {{total}} done", - "processingFailed": "{{count}} photo(s) failed to process", "retryFailed": "Retry failed", "uploadComplete": "Upload complete!", - "uploadFailed": "Upload failed", "someFilesFailed": "Some files failed to upload", "replaceByName": "Replace existing photos with same name", - "replacedFiles": "{{count}} photo(s) replaced", "uploadPhotos": "Upload Photos", "uploadMedia": "Upload Photos & Videos", - "importExternal": "Import from External Folder", - "externalImportInfo": "All pictures from the selected folder will be imported.", - "selectExternalFolder": "Select external folder under /external-media", - "importFromSelectedFolder": "Import from selected folder", "maxFilesReached": "Maximum {{limit}} files allowed", "someFilesSkipped": "Only {{allowed}} more files can be added (limit {{limit}})", "tooManyFiles": "Maximum {{limit}} files can be uploaded at once", "limitInfo": "{{selected}} of {{limit}} files selected ({{remaining}} remaining)", "limitReached": "Upload limit reached ({{limit}} files per batch)", - "uploadingChunks": "Uploading {{count}} files in {{total}} batches...", - "mediaCategory": "Media category", - "uploadAction": "Upload {{count}} files" + "replacedFiles_one": "{{count}} photo replaced", + "replacedFiles_other": "{{count}} photos replaced", + "processingFailed_one": "{{count}} photo failed to process", + "processingFailed_other": "{{count}} photos failed to process", + "uploadingChunks_one": "{{count}} chunk uploading", + "uploadingChunks_other": "{{count}} chunks uploading" }, "navigation": { "dashboard": "Dashboard", "events": "Events", - "archives": "Archives", - "settings": "Settings", - "eventTypes": "Event Types", - "branding": "Branding", - "analytics": "Analytics", - "emailSettings": "Email Settings", - "backup": "Backup & Restore", - "cmsPages": "CMS Pages", - "users": "Users" + "settings": "Settings" }, "archives": { "title": "Archives", @@ -211,67 +201,44 @@ "deleteSuccess": "Archive deleted permanently" }, "auth": { - "login": "Login", "password": "Password", "enterPassword": "Enter Gallery Password", "passwordPlaceholder": "Enter the gallery password", "invalidPassword": "Invalid password", "wrongPassword": "Incorrect password. Please check your password and try again.", "tooManyAttempts": "Too many failed login attempts. Please try again later.", - "sessionExpired": "Session expired", "pleaseEnterPassword": "Please enter a password", "passwordHint": "The password was provided by the event organizer. Contact them if you don't have it." }, "gallery": { - "title": "Photo Gallery", - "welcomeMessage": "Welcome Message", - "expiresOn": "Expires on", "expires": "Expires", "expired": "Expired", - "daysRemaining": "{{days}} days remaining", - "dayRemaining": "1 day remaining", - "hoursRemaining": "{{hours}} hours remaining", - "expiredMessage": "This gallery expired on {{date}}", "contactOrganizer": "Please contact the event organizer if you need access to these photos.", "searchPhotos": "Search photos by filename...", "sortByDate": "Sort by Date", "sortByName": "Sort by Name", "sortBySize": "Sort by Size", "allPhotos": "All Photos", - "filter": "Filter", "feedbackFilter": "Feedback Filter", "all": "All", "liked": "Liked", "favorited": "Favorited", "favorites": "Favorites", - "downloadSelected": "Download {{count}} Selected", - "shareGallery": "Share Gallery", "needHelp": "Need help? Contact us at", "noPhotosFound": "No photos found", "failedToLoad": "Failed to load photos", "tryAgain": "Try Again", "loading": "Loading gallery...", "expiredOn": "This gallery expired on {{date}}.", - "expiresIn": "Gallery expires in {{count}} day", - "expiresIn_plural": "Gallery expires in {{count}} days", "downloadBefore": "Download your photos before they're no longer available.", - "publicGalleryTitle": "This gallery is publicly accessible", - "publicGallerySubtitle": "Loading the photos now...", "viewGallery": "View Gallery", "downloadAll": "Download All", - "downloading": "Downloading {{count}} photo...", - "downloading_plural": "Downloading {{count}} photos...", - "downloadedPhotos": "Downloaded {{count}} photo!", - "downloadedPhotos_plural": "Downloaded {{count}} photos!", "downloadError": "Some photos failed to download", "selectPhotos": "Select Photos", "cancelSelection": "Cancel Selection", - "photosSelected": "{{count}} selected", "selectAll": "Select All", "deselectAll": "Deselect All", "deleteSelected": "Delete Selected", - "photosCount": "{{count}} photo", - "photosCount_plural": "{{count}} photos", "searchByFilename": "Search by filename...", "uncategorized": "Uncategorized", "sortAscending": "Sort ascending", @@ -279,8 +246,6 @@ "remaining": "remaining", "selectPhotosHint": "Tip: Use Ctrl+Click (Cmd+Click on Mac) to quickly select multiple photos", "filters": "Filters", - "openFilters": "Open filters", - "toggleSidebar": "Toggle sidebar", "toggleMenu": "Toggle menu", "allCategories": "All Categories", "categories": "Categories", @@ -313,14 +278,56 @@ "anonymous": "Anonymous" }, "rated": "Rated", - "commented": "Commented" + "commented": "Commented", + "expiresIn_one": "Gallery expires in {{count}} day", + "expiresIn_other": "Gallery expires in {{count}} days", + "downloading_one": "Downloading 1 photo...", + "downloading_other": "Downloading {{count}} photos...", + "guestRecovery": { + "invalidEmail": "Enter a valid email address", + "codeSent": "Check your inbox for a verification code.", + "requestError": "Could not send code. Try again.", + "invalidCode": "Enter the 6-digit code", + "verifyError": "Invalid or expired code.", + "back": "Back", + "title": "Recover your picks", + "emailStepDescription": "Enter the email you used before. We will send a 6-digit verification code.", + "codeStepDescription": "Enter the 6-digit code we sent to your email.", + "emailLabel": "Email", + "sendCode": "Send code", + "codeLabel": "Verification code", + "verifyCode": "Verify and continue" + }, + "guestPrompt": { + "nameRequired": "Name is required", + "invalidEmail": "Invalid email address", + "emailRequired": "Email is required", + "error": "Registration failed", + "title": "Welcome — what's your name?", + "description": "Your picks will be saved under this name so the photographer knows which photos you love.", + "nameLabel": "Your name", + "namePlaceholder": "Enter your name", + "emailLabelRequired": "Email", + "emailLabel": "Email (optional)", + "emailPlaceholder": "you@example.com", + "submit": "Continue", + "alreadyHere": "I've been here before" + }, + "footer": { + "forgetMeConfirm": "Your name and selections will be removed from this gallery.", + "forgetMe": "Forget me ({{name}})" + }, + "photosCount_one": "{{count}} photo", + "photosCount_other": "{{count}} photos", + "poweredBy": "Powered by PicPeak", + "photosSelected_one": "gallery.photosSelected", + "photosSelected_other": "gallery.photosSelected", + "downloadSelected_one": "gallery.downloadSelected", + "downloadSelected_other": "gallery.downloadSelected" }, "categories": { "title": "Photo Categories", - "global": "Global Categories", - "eventSpecific": "Event-Specific Categories", "addCategory": "Add Category", - "organizationInfo": "Organize your photos into categories. Categories help guests navigate and find specific types of photos.", "eventSpecificCategories": "Event-Specific Categories", "noEventSpecificCategories": "No event-specific categories. Global categories are available by default.", "globalCategoriesAlwaysAvailable": "Global Categories (always available):", @@ -330,10 +337,8 @@ "failedToCreateCategory": "Failed to create category", "failedToDeleteCategory": "Failed to delete category", "categoryName": "Category name", - "noCategory": "No category", "noCategoriesYet": "No categories yet. Create your first category to organize photos.", "deleteConfirm": "Are you sure you want to delete \"{{name}}\"?", - "cannotDelete": "Cannot delete category with photos. Please reassign photos first.", "setCoverPhoto": "Set Cover Photo", "removeCoverPhoto": "Remove Cover Photo", "coverPhotoSet": "Cover photo set successfully", @@ -348,36 +353,16 @@ "totalViews": "Total Views", "totalDownloads": "Total Downloads", "uniqueVisitors": "Unique Visitors", - "createNewEvent": "Create New Event", - "setupNewGallery": "Set up a new photo gallery for your event", - "createNewEventSubtitle": "Set up a new photo gallery for your event", "eventNamePlaceholder": "e.g., John & Jane's Wedding", - "welcomeMessageOptional": "Welcome Message (Optional)", "welcomeMessagePlaceholder": "Welcome to our special day! Feel free to download and share these memories...", "hostEmailPlaceholder": "customer@example.com", "adminEmailPlaceholder": "admin@example.com", "adminEmailPickFromAdmins": "Pick from admins:", "adminEmailCustom": "Custom email", - "securityAndAccess": "Security & Access", "accessAndSecurity": "Access & Security", "enterPassword": "Enter password", "passwordPlaceholder": "Enter a secure password", "confirmPasswordPlaceholder": "Confirm password", - "galleryExpiresOn": "Gallery will expire on {{date}}", - "guestsWillReceiveWarning": "Guests will receive a warning email 7 days before expiration.", - "types": { - "wedding": "Wedding", - "birthday": "Birthday", - "corporate": "Corporate", - "other": "Other" - }, - "themes": { - "default": "Default", - "oceanBlue": "Ocean Blue", - "royalPurple": "Royal Purple", - "roseGold": "Rose Gold", - "sunsetAmber": "Sunset Amber" - }, "eventDetails": "Event Details", "eventName": "Event Name", "eventType": "Event Type", @@ -386,11 +371,9 @@ "hostName": "Customer Name", "hostNamePlaceholder": "John Smith", "adminEmail": "Admin Email", - "adminNotificationEmail": "Admin Notification Email", "expirationDate": "Expiration Date", "active": "Active", "archived": "Archived", - "photoCount": "{{count}} photos", "totalSize": "Total Size", "shareLink": "Share Link", "copyLink": "Copy Link", @@ -403,10 +386,7 @@ "backToEvents": "Back to Events", "loadingEventDetails": "Loading event details...", "saveChanges": "Save Changes", - "eventExpired": "This event has expired", "eventExpiresIn": "This event expires in {{days}} days", - "guestsNoAccess": "Guests can no longer access the gallery. Consider archiving this event.", - "warningEmailsSent": "Warning emails have been sent to the customer.", "overview": "Overview", "photos": "Photos", "categories": "Categories", @@ -421,7 +401,6 @@ "externalFolderEmpty": "No subfolders", "clearSelection": "Clear", "welcomeMessage": "Welcome Message", - "noWelcomeMessage": "No welcome message set", "created": "Created", "expires": "Expires", "shareWithGuests": "Share this link with guests. They'll need the password to access the gallery.", @@ -435,28 +414,18 @@ "managePhotos": "Manage Photos", "actions": "Actions", "archivingInfo": "Archiving will create a ZIP file of all photos and remove the gallery from public access.", - "statistics": "Statistics", - "views": "Views", - "downloads": "Downloads", - "noStatistics": "No statistics available yet", - "archiveStatus": "Archive Status", "archivedOn": "Archived On", "downloadArchive": "Download Archive", "loadingPhotos": "Loading photos...", "photoCategories": "Photo Categories", "organizeCategoriesInfo": "Organize your photos into categories. Categories help guests navigate and find specific types of photos.", "categoriesTip": "Tip: Categories are specific to each event. You can create custom categories like \"Ceremony\", \"Reception\", \"Portraits\", etc.", - "contactInformation": "Contact Information", - "hostEmailHelp": "Customer will receive gallery creation and expiration notifications", - "adminEmailHelp": "Will receive system notifications and archive confirmations", - "securityAccess": "Security & Access", "galleryPassword": "Gallery Password", "requirePasswordToggle": "Require password for this gallery", "requirePasswordToggleHelp": "Disable this if you want to share the gallery without a password. Anyone with the link will be able to view the photos.", "publicGalleryWarning": "Public galleries are accessible to anyone with the link. Consider enabling download watermarks and monitoring activity.", "passwordHelperText": "You can use dates like \"04.07.2025\" or any text with 6+ characters", "confirmPassword": "Confirm Password", - "showPasswords": "Show passwords", "newPasswordLabel": "New Gallery Password", "passwordReset": { "title": "Reset Gallery Password", @@ -481,15 +450,10 @@ "errorMinLength": "Password must be at least 6 characters", "errorMismatch": "Passwords do not match" }, - "gallerySettings": "Gallery Settings", "themeAndStyle": "Theme & Style", - "colorTheme": "Color Theme", "galleryExpiration": "Gallery Expiration", - "galleryExpiresIn": "Gallery Expires In", "daysAfterEvent": "days after event date", "expiresOn": "Expires on", - "galleryWillExpireOn": "Gallery will expire on {{date}}", - "expirationWarning": "Guests will receive a warning email 7 days before expiration.", "noExpiration": "No Expiration", "noExpirationHelp": "This gallery will remain active until manually archived.", "photoCap": "Photo Limit", @@ -501,11 +465,7 @@ "uploadCategory": "Upload Category", "selectCategory": "Select a category for user uploads", "uploadCategoryHelp": "All user-uploaded photos will be added to this category", - "userUploadWarning": "User uploads will be moderated and can be removed by admins at any time.", "allowDownloads": "Allow photo downloads", - "allowDownloadsHelp": "Allow guests to download photos from this gallery", - "downloadPermissions": "Download Permissions", - "downloadsEnabled": "Downloads Enabled", "downloadsDisabled": "Downloads Disabled", "downloadProtection": "Download Protection", "disableRightClick": "Block right-click menu", @@ -554,15 +514,6 @@ "heroImageAnchorBottom": "Bottom", "heroPreview": "Hero preview", "noPhotosAvailable": "No photos available", - "processingRequest": "Processing your request...", - "eventTypeWedding": "Wedding", - "eventTypeBirthday": "Birthday", - "eventTypeCorporate": "Corporate", - "eventTypeOther": "Other", - "days30": "30 days", - "days60": "60 days", - "days90": "90 days", - "days365": "1 year", "inactive": "Inactive", "expired": "Expired", "draft": "Draft", @@ -570,31 +521,36 @@ "publishConfirm": "This will make the gallery accessible and send the notification email to the client. Continue?", "publishSuccess": "Gallery published and client notified!", "draftBanner": "This gallery is in draft mode. Upload your photos, then publish when ready.", - "daysLeft": "({{count}} day left)", - "daysLeft_plural": "({{count}} days left)", "subtitle": "Manage your photo galleries and events", - "loadingEvents": "Loading events...", "failedToLoadEvents": "Failed to load events", "tryAgain": "Try Again", - "bulkArchiveSuccess": "Successfully archived {{count}} events", "bulkArchivePartial": "Archived {{success}} events, {{failed}} failed", "deleteSelected": "Delete Selected", "bulkDelete": { - "title": "Permanently delete {{count}} events?", "warning": "This will permanently delete the selected events, all their photos, archives, and audit logs. This action cannot be undone.", + "passwordLabel": "Re-enter your password to confirm", + "passwordPlaceholder": "Your admin password", + "passwordHelp": "We require your password as a safeguard against accidental bulk deletions.", + "incorrectPassword": "Incorrect password. No events were deleted.", "confirmLabel": "Type {{literal}} to confirm", "confirmHelp": "A typed confirmation prevents accidental deletions and isn't affected by browser autofill or passkey shortcuts.", "submit": "Delete {{count}} events", "processing": "Deleting {{count}} events. This may take a few minutes — please don't close this window.", "successAll": "Permanently deleted {{count}} events", "successPartial": "Deleted {{success}} events, {{failed}} failed", - "errorGeneric": "Failed to delete events" + "errorGeneric": "Failed to delete events", + "successAll_one": "events.bulkDelete.successAll", + "successAll_other": "events.bulkDelete.successAll", + "title_one": "Permanently delete {{count}} events?", + "title_other": "Permanently delete {{count}} events?", + "processing_one": "Deleting {{count}} events. This may take a few minutes — please don't close this window.", + "processing_other": "Deleting {{count}} events. This may take a few minutes — please don't close this window.", + "submit_one": "Delete {{count}} events", + "submit_other": "Delete {{count}} events" }, "searchEventsPlaceholder": "Search events...", "all": "All", "expiring": "Expiring", - "eventsSelected": "{{count}} event selected", - "eventsSelected_plural": "{{count}} events selected", "clear": "Clear", "archiveSelected": "Archive Selected", "publicAccess": "Public access", @@ -623,22 +579,14 @@ "extendSevenDays": "Extend 7 Days", "welcomeMessageLabel": "Welcome Message", "noWelcomeMessageSet": "No welcome message set", - "createdOn": "Created", "copy": "Copy", "copied": "Copied!", - "organizingPhotosInfo": "Organize your photos into categories. Categories help guests navigate and find specific types of photos.", "archiveStatusTitle": "Archive Status", "downloadingArchive": "Downloading {{name}} archive...", "downloadStarted": "Download started", "failedToDownloadArchive": "Failed to download archive", - "statisticsNotAvailable": "No statistics available yet", - "photoFilters": "Photo Filters", - "noStatisticsAvailableYet": "No statistics available yet", - "addPlus": "Add+", "galleryTheme": "Gallery Theme", - "customizeTheme": "Customize Theme", "noThemeSet": "No theme configured", - "customizingTheme": "Customizing gallery theme", "customizingThemeFor": "Customizing theme for {{event}}", "customCssTemplate": "Custom CSS Template", "customCssTemplateDesc": "Apply a custom CSS template to style the gallery with unique visual effects.", @@ -652,26 +600,44 @@ "renamingFiles": "Renaming files...", "complete": "Complete!", "failed": "Rename failed", - "filesRenamed": "{{count}} files updated", - "confirm": "Rename Event" + "confirm": "Rename Event", + "success": "Event renamed successfully!", + "filesRenamed_one": "{{count}} files updated", + "filesRenamed_other": "{{count}} files updated", + "newLink": "New Gallery Link", + "currentName": "Current name:", + "newName": "New Event Name", + "enterNewName": "Enter new event name", + "newUrl": "New URL:", + "checkingAvailability": "Checking availability...", + "resendEmail": "Resend invitation email with new gallery link", + "emailTo": "Send updated gallery access email to", + "warningTitle": "Please note:", + "warning1": "The gallery URL will change", + "warning2": "Old URLs will automatically redirect to the new URL", + "warning3": "Photo files may be renamed" }, - "activeFilter": "Active", - "archivedFilter": "Archived", - "sortByName": "By Name", - "sortByDate": "By Date", - "sortByExpiration": "By Expiration", - "photosCount": "Photos", - "moreActions": "More Actions", - "copyLinkTooltip": "Copy Link", - "viewGalleryTooltip": "View Gallery", - "uploadPhotosTooltip": "Upload Photos", - "editTooltip": "Edit", - "archiveTooltip": "Archive", - "noEvents": "No events found", - "noEventsDescription": "Create your first event to get started.", - "bulkArchive": "Archive", - "confirmBulkArchive": "Are you sure you want to archive {{count}} event(s)?", - "confirmBulkArchiveDescription": "This action cannot be undone. Archived events will no longer be publicly accessible." + "bulkArchiveSuccess_one": "Successfully archived {{count}} event", + "bulkArchiveSuccess_other": "Successfully archived {{count}} events", + "daysLeft_one": "({{count}} day left)", + "daysLeft_other": "({{count}} days left)", + "eventsSelected_one": "{{count}} event selected", + "eventsSelected_other": "{{count}} events selected", + "paginationLabel": "{{from}}–{{to}} of {{total}}", + "filtered": "filtered", + "pageOf": "Page {{page}} of {{totalPages}}", + "notFound": "Event not found", + "customerPhone": "Customer Phone", + "customerPhonePlaceholder": "+1 555 555 1234", + "allowPresignedDownload": "Allow direct S3 download (no watermark, S3 mode only)", + "neverExpires": "Never", + "rightClickBlocked": "Right-click blocked", + "devtoolsDetection": "DevTools detection", + "watermarked": "Watermarked", + "importExternal": "Import from External Folder", + "externalImportInfo": "All pictures from the selected folder will be imported.", + "selectExternalFolder": "Select external folder under /external-media", + "importFromSelectedFolder": "Import from selected folder" }, "settings": { "title": "System Settings", @@ -683,9 +649,7 @@ "siteUrl": "Site URL", "siteUrlHelp": "Used for generating gallery links in emails", "defaultExpiration": "Default Expiration (days)", - "defaultExpirationHelp": "How long galleries remain active by default", "maxFileSize": "Max File Size (MB)", - "maxFileSizeHelp": "Maximum size per uploaded photo", "maxFilesPerUpload": "Max Files per Upload", "maxFilesPerUploadHelp": "Maximum number of photos allowed in a single upload batch (1-{{max}}).", "allowedFileTypes": "Allowed File Types", @@ -697,13 +661,7 @@ "enableShortGalleryUrlsHelp": "Removes the event slug from new share links while keeping existing links working.", "maintenanceMode": "Enable maintenance mode", "language": "Language", - "defaultLanguage": "Default Language", "defaultLanguageHelp": "Language shown to guests before login", - "defaultWelcomeMessage": "Default Welcome Message", - "welcomeMessage": "Welcome Message", - "welcomeMessagePlaceholder": "Enter a default welcome message that will be included in gallery creation emails", - "welcomeMessageHelp": "This message will be included in all gallery creation emails unless overridden when creating an event", - "saveSettings": "Save General Settings", "saveGeneralSettings": "Save General Settings", "dateTimeFormat": "Date & Time Format", "dateFormat": "Date Format", @@ -721,7 +679,6 @@ "accountSaveSuccess": "Account details updated" }, "publicSite": { - "tabLabel": "Public Site", "badge": "Public Landing", "title": "Public Landing Page", "subtitle": "Publish a customized landing page for guests when they visit your domain.", @@ -749,8 +706,6 @@ "htmlRequired": "Provide HTML content before enabling the public site." }, "storage": { - "title": "Storage", - "overview": "Storage Overview", "totalUsed": "Total Used", "archiveStorage": "Archive Storage", "storageLimit": "Storage Limit", @@ -762,7 +717,6 @@ "diskCapacityReported": "Disk Capacity (reported)", "diskAvailable": "Available", "diskAvailableReported": "Available (reported)", - "diskFree": "Free", "diskFreeReported": "Free (reported)", "diskMetricsUnavailable": "Disk metrics are not available in Docker Desktop or virtualized environments.", "applyRecommended": "Use recommended", @@ -781,17 +735,12 @@ "capacityRequiredForAvailable": "Enter a total capacity before setting available space.", "availableExceedsCapacity": "Available space cannot exceed the total capacity.", "storageUsage": "Storage Usage", - "storageByEvent": "Storage by Event", - "storageManagement": "Storage Management", - "storageManagementHelp": "Consider archiving or deleting old events to free up storage space. Archived events are compressed and use less storage than active galleries.", - "noEventsUsingStorage": "No events using storage", "unlimited": "Unlimited" }, "security": { "title": "Security", "passwordSettings": "Password Settings", "minPasswordLength": "Minimum Password Length", - "minPasswordLengthHelp": "Minimum number of characters for gallery passwords", "passwordComplexity": "Password Complexity", "passwordComplexityHelp": "Security level required for gallery passwords", "complexitySimple": "Simple (6+ chars, any text)", @@ -800,7 +749,6 @@ "complexityVeryStrong": "Very Strong (12+ chars, all character types)", "sessionAuth": "Session & Authentication", "sessionTimeout": "Session Timeout (minutes)", - "sessionTimeoutHelp": "Admin session timeout in minutes", "maxLoginAttempts": "Max Login Attempts", "maxLoginAttemptsHelp": "Maximum failed login attempts per IP before lockout", "attemptWindowMinutes": "Attempt Window (minutes)", @@ -811,11 +759,8 @@ "recaptchaSettings": "reCAPTCHA Settings", "enableRecaptcha": "Enable reCAPTCHA for login forms", "siteKey": "Site Key", - "siteKeyHelp": "Your reCAPTCHA v2 site key (public)", "secretKey": "Secret Key", - "secretKeyHelp": "Your reCAPTCHA v2 secret key (keep private)", "recaptchaHelp": "Get your reCAPTCHA keys from", - "saveSettings": "Save Security Settings", "saveSecuritySettings": "Save Security Settings" }, "categories": { @@ -857,8 +802,6 @@ "missingDimensions": "Missing Dimensions", "repairButton": "Repair Dimensions", "repairing": "Repairing...", - "alreadyRunning": "Repair is already running", - "started": "Started repairing {{count}} photos", "noneToRepair": "All photos already have dimensions", "resultSuccess": "Last repair: {{success}} updated, {{failed}} failed", "description": "Backfill missing width/height for photos uploaded before dimension tracking was added. Required for Masonry and Mosaic layouts." @@ -876,11 +819,12 @@ "sendTest": "Send Test Email", "saved": "Settings saved", "saveError": "Failed to save settings", - "emailSent": "Notification email sent to {{count}} recipients", "emailFailed": "Failed to send notification", "checkSuccess": "Notification sent for new version", "checkNoAction": "No notification needed: {{reason}}", - "checkError": "Failed to check for updates" + "checkError": "Failed to check for updates", + "emailSent_one": "Notification email sent to {{count}} recipients", + "emailSent_other": "Notification email sent to {{count}} recipients" }, "events": { "title": "Event Creation", @@ -902,7 +846,13 @@ "expirationWarning": "Galleries without expiration will remain active until manually archived", "saveSettings": "Save Event Settings", "noteTitle": "Note", - "noteText": "These settings only affect new event creation. Existing events are not affected. Default behavior requires all fields." + "noteText": "These settings only affect new event creation. Existing events are not affected. Default behavior requires all fields.", + "defaultRequirePassword": "Require password by default", + "defaultRequirePasswordHelp": "Pre-check \"Require password\" when creating new events. Disable for quicker creation of public galleries.", + "showGalleryFilterBar": "Show filter bar in galleries", + "showGalleryFilterBarHelp": "Display the search-by-filename and sort controls above grid-layout galleries. Disable for a cleaner layout.", + "enablePhoneField": "Enable phone number field", + "enablePhoneFieldHelp": "Adds an optional phone number input to the event form. Useful for downstream automations like WhatsApp delivery via n8n. Always optional even when enabled." }, "imageSecurity": { "title": "Image Protection", @@ -975,11 +925,6 @@ "format": "Format", "fit": "Fit Mode", "fitHelp": "How images are resized to fit the thumbnail dimensions. \"Cover\" crops to fill, \"Contain\" fits within bounds.", - "fit_cover": "Cover (crop to fill)", - "fit_contain": "Contain (fit within)", - "fit_fill": "Fill (stretch)", - "fit_inside": "Inside (shrink to fit)", - "fit_outside": "Outside (expand to cover)", "regenerateTitle": "Regenerate Thumbnails", "regenerateHelp": "After changing thumbnail settings, regenerate all existing thumbnails to apply the new configuration. This runs in the background and may take a while for large galleries.", "regenerateButton": "Regenerate All Thumbnails", @@ -1042,11 +987,57 @@ "deviceTypes": "Device types from user agents", "privacy": "Privacy", "privacyText": "IP addresses are hashed for privacy. No personal data is stored. Analytics data is retained for 90 days." - } + }, + "groups": { + "general": "General", + "display": "Display", + "privacySecurity": "Privacy & Security", + "integrations": "Integrations", + "system": "System" + }, + "apiTokens": { + "title": "API Tokens", + "createError": "Failed to create token", + "revoked": "Token revoked", + "subtitle": "Long-lived bearer tokens for the public /api/v1 surface — n8n integrations, custom apps, scripts. Tokens act as the admin user that minted them, intersected with the chosen scopes.", + "copyNow": "Copy this token now — it will not be shown again.", + "copied": "Copied", + "copyFailed": "Copy failed", + "name": "Name", + "namePlaceholder": "e.g. n8n production", + "scopes": "Scopes", + "generate": "Generate Token", + "scopeHint": "admin > write > read. A read-only token cannot mutate, even if its owner is super_admin.", + "existing": "Existing tokens", + "lastUsed": "Last used", + "created": "Created", + "status": "Status", + "statusRevoked": "Revoked", + "statusExpired": "Expired", + "statusActive": "Active", + "confirmRevoke": "settings.apiTokens.confirmRevoke", + "revoke": "Revoke", + "empty": "No tokens yet. Generate one above to get started." + }, + "webhooks": { + "title": "Webhooks", + "subtitle": "POST event notifications to your URL the moment something happens — gallery published, photo uploaded, event archived, etc. Signed with HMAC-SHA256 in the X-PicPeak-Signature header.", + "piiNotice": "event.* payloads include customer contact info (name, email, phone) and the gallery share token if you have stored them. Only point webhooks at receivers you trust — they have everything needed to message the customer or open the gallery.", + "copyNow": "Copy this signing secret now — it will not be shown again.", + "name": "Name", + "url": "Receiver URL", + "events": "Subscribe to events", + "filter": "Filter (JSON, optional)", + "template": "Template (optional)", + "create": "Create Webhook", + "existing": "Existing webhooks", + "empty": "No webhooks yet. Create one above to start receiving event notifications." + }, + "sectionLabel": "Settings section", + "navAriaLabel": "Settings navigation" }, "analytics": { "title": "Analytics Dashboard", - "titleSimple": "Analytics", "subtitle": "Track gallery performance and visitor engagement", "detailedSubtitle": "Detailed analytics powered by Umami", "loadingAnalytics": "Loading analytics...", @@ -1074,13 +1065,10 @@ "totalPhotos": "Total Photos", "activeEvents": "Active Events", "notConfigured": "Umami Analytics Not Configured", - "configureInstructions": "To see real analytics data, configure Umami in your environment variables and admin panel settings.", - "noData": "No data available", - "percentChange": "{{percent}}% from last period" + "configureInstructions": "To see real analytics data, configure Umami in your environment variables and admin panel settings." }, "branding": { "title": "Branding & Themes", - "titleFull": "Branding & Customization", "subtitle": "Customize the look and feel of your galleries", "loadingBranding": "Loading branding settings...", "themeAndStyle": "Theme & Style", @@ -1092,18 +1080,14 @@ "supportEmail": "Support Email", "supportEmailHelp": "Contact email for guest support", "footerText": "Footer Text", - "footerTextHelp": "Displayed at the bottom of galleries", "logo": "Logo", - "currentLogo": "Current logo", "uploadLogo": "Upload Logo", - "removeLogo": "Remove Logo", "logoHelp": "Recommended size: 200x60px, PNG or JPEG", "favicon": "Favicon", "currentFavicon": "Current favicon", "uploadFavicon": "Upload Favicon", "removeFavicon": "Remove Favicon", "faviconHelp": "PNG or ICO format, recommended size: 32x32px", - "watermark": "Watermark", "watermarkSettings": "Watermark Settings", "enableWatermarks": "Enable Watermarks", "watermarkHelp": "Add your company name as a watermark on downloaded photos", @@ -1120,11 +1104,7 @@ "watermarkSize": "Watermark Size", "theme": "Theme", "galleryTheme": "Gallery Theme", - "themeCustomization": "Theme Customization", - "selectPreset": "Select a preset theme", "colors": "Colors", - "primaryColor": "Primary Color", - "secondaryColor": "Secondary Color", "accentColor": "Accent Color", "backgroundColor": "Background Color", "textColor": "Text Color", @@ -1133,27 +1113,13 @@ "colorModeDark": "Dark", "colorModeAuto": "Auto", "colorModeHelp": "Auto follows the visitor's system preference.", - "customCSS": "Custom CSS", "preview": "Preview", - "previewInNewTab": "Preview in New Tab", - "reset": "Reset", "saveChanges": "Save Changes", "applyLivePreview": "Apply changes immediately (Live Preview)", "eventSpecificThemes": "Event-Specific Themes", "eventThemesInfo": "You can override these global theme settings for individual events when creating or editing them.", "themePresets": "Theme Presets", "galleryLayout": "Gallery Layout", - "layoutDescriptions": { - "grid": "Classic grid layout with consistent photo sizes", - "masonry": "Pinterest-style layout with varied heights", - "carousel": "Full-screen slideshow with navigation", - "timeline": "Photos organized by date", - "hero": "Featured image with grid below", - "mosaic": "Artistic layout with mixed sizes", - "justified": "Row-based layout preserving aspect ratios", - "gallery-premium": "Elegant light theme with hero and masonry (Beta)", - "gallery-story": "Cinematic dark theme with scene sections (Beta)" - }, "layoutSettings": "Layout Settings", "photoSpacing": "Photo Spacing", "spacing": { @@ -1210,16 +1176,6 @@ "xl": "XL — Largest photos" }, "thumbnailScaleHint": "Adjusts column count relative to the base grid columns", - "showHeroSection": "Show Hero Section", - "showHeroSectionHint": "Display a featured hero image above the justified gallery", - "heroHeight": "Hero Section Height", - "heroHeightOptions": { - "small": "Small (40-50%)", - "medium": "Medium (50-70%)", - "large": "Large (60-80%)" - }, - "heroOverlayOpacity": "Hero Overlay Opacity", - "heroOverlayHint": "Darken the hero image to improve text readability", "typographyAndStyle": "Typography & Style", "bodyFont": "Body Font", "headingFont": "Heading Font", @@ -1265,8 +1221,6 @@ }, "resetToDefault": "Reset to Default", "applyTheme": "Apply Theme", - "customTheme": "Custom Theme", - "customizeTheme": "Customize Theme", "saveTheme": "Save Theme", "previewLayout": "Preview Layout", "livePreview": "Live Preview", @@ -1284,9 +1238,6 @@ "logoMaxHeight": "Maximum Height (pixels)", "logoMaxHeightHelp": "Set a custom maximum height for the logo (20-200 pixels)", "logoPosition": "Logo Position in Header", - "positionLeft": "Left", - "positionCenter": "Center", - "positionRight": "Right", "logoDisplayMode": "Display Mode", "logoOnly": "Logo Only", "textOnly": "Company Name Only", @@ -1297,29 +1248,8 @@ "showLogoInHeroHelp": "Display the logo in hero sections (for non-grid layouts)", "headerStyle": "Header Style", "headerStyleDescription": "Choose how the gallery header appears. The header style is independent of the photo layout.", - "headerStyleOptions": { - "hero": "Hero Image", - "standard": "Standard", - "banner": "Banner", - "minimal": "Minimal", - "none": "No Header" - }, - "headerStyleDescriptions": { - "hero": "Full-height image with event info overlay", - "standard": "Compact inline header with event details", - "banner": "Standard header plus a colored banner above", - "minimal": "Compact header with essential info", - "none": "Hide header completely" - }, "heroDividerStyle": "Divider Style", "heroDividerDescription": "Choose how the transition between the hero image and gallery content looks.", - "dividerOptions": { - "wave": "Wave", - "straight": "Straight", - "angle": "Angle", - "curve": "Curve", - "none": "None" - }, "controlsStyle": "Controls Style", "controlsStyleDescription": "Choose how gallery filters and controls are displayed.", "controlsStyleOptions": { @@ -1333,15 +1263,43 @@ "controlsStyleHeroWarning": "Sidebar is recommended for hero headers to prevent controls appearing above the hero image.", "betaThumbnailWarningTitle": "Low thumbnail resolution detected", "betaThumbnailWarningText": "Your thumbnails are currently {{width}}×{{height}}px. Beta themes display photos at larger sizes and require at least {{recommended}}×{{recommended}}px for good quality. Increase the thumbnail dimensions in Settings > Thumbnails and regenerate.", - "betaThumbnailWarningLink": "Go to Thumbnail Settings" + "betaThumbnailWarningLink": "Go to Thumbnail Settings", + "logoSize": "Logo Size", + "surfaceColor": "Surface", + "elevatedColor": "Elevated", + "borderColor": "Border", + "mutedTextColor": "Muted text", + "accentDarkColor": "Accent (filled)", + "syncFromBranding": "Sync from Branding", + "forceColorMode": "Force color mode", + "forceColorModeHelp": "Lock the entire admin and public site to dark or light. The user-facing dark/light toggle is hidden whenever a lock is active. Per-event themes that try to override the colour mode are also forced to follow.", + "forceColorModeNone": "No force (user choice)", + "forceColorModeDark": "Force dark", + "forceColorModeLight": "Force light", + "colorGroupSurfaces": "Surfaces", + "colorGroupSurfacesHelp": "The neutral layers behind your content. Background sits furthest back; Surface and Elevated stack on top.", + "backgroundColorHelp": "The page itself — body background of every gallery, admin page and CMS page.", + "surfaceColorHelp": "Cards, sidebar, header bar and navigation. The first layer above Background.", + "elevatedColorHelp": "Panels that float above cards: image placeholders, hover/active rows, modal headers, code blocks.", + "borderColorHelp": "Dividers, table grid lines, card outlines, input borders.", + "colorGroupText": "Text", + "colorGroupTextHelp": "Foreground text colours. Primary is for everything readers focus on; Secondary is for supporting copy.", + "textColorHelp": "Headlines, body copy, table cells, form input values, navigation labels — the main text colour.", + "mutedTextColorHelp": "Captions, helper text under inputs, table column headers, footer links, dates and metadata.", + "colorGroupAccent": "Accent", + "colorGroupAccentHelp": "Brand colours that highlight interactive elements. Use a strong colour pair — Accent is for outlines/text, Accent Dark is for filled buttons.", + "accentColorHelp": "Links, icons, focus rings, hover states on primary buttons, active sidebar item underline. Should read clearly on both Background and Surface.", + "accentDarkColorHelp": "Filled CTA buttons, active sidebar item background, badges and tags. Needs enough contrast for white text to be readable on top.", + "cssTemplate": "CSS Template", + "cssTemplateDescription": "Select a pre-built CSS template to apply application-wide styling to this gallery. Templates can be managed in Settings > CSS Templates.", + "noTemplate": "No Template", + "noTemplateDescription": "Use only theme settings without a CSS template", + "templateSlot": "Slot {{slot}}", + "eventCustomCSS": "Event-specific Custom CSS" }, "admin": { "title": "Admin Panel", - "welcome": "Welcome back, {{name}}", "recentActivity": "Recent Activity", - "systemStatus": "System Status", - "totalEvents": "Total Events", - "activeGalleries": "Active Galleries", "storageUsed": "Storage Used", "totalPhotos": "Total Photos", "storagePercent": "{{percent}}% of limit {{limit}}", @@ -1351,9 +1309,6 @@ "archivedEvents": "Archived Events", "systemHealth": "System Health", "health": { - "healthy": "Healthy", - "warning": "Warning", - "error": "Error", "checking": "Checking..." }, "updates": { @@ -1366,9 +1321,7 @@ "beta": "BETA", "viewReleaseNotes": "View Release Notes", "updateAvailableShort": "v{{version}} available", - "checkForUpdates": "Check for Updates", "upToDate": "You're up to date", - "lastChecked": "Last checked: {{time}}", "updateNow": "Update Now", "updateDialog": { "title": "Update PicPeak", @@ -1382,8 +1335,6 @@ } }, "notifications": "Notifications", - "viewAllNotifications": "View all notifications", - "noNotifications": "No new notifications", "markAllRead": "Mark all read", "clearAll": "Clear all", "close": "Close", @@ -1393,16 +1344,13 @@ "eventArchived": "Event \"{{eventName}}\" was archived", "eventUpdated": "Event \"{{eventName}}\" was updated", "eventDeleted": "Event \"{{eventName}}\" was deleted", - "photosUploaded": "{{count}} photos uploaded to \"{{eventName}}\"", "photoDeleted": "Photo deleted from \"{{eventName}}\"", - "photosBulkDeleted": "{{count}} photos deleted from \"{{eventName}}\"", "eventExpiring": "Event \"{{eventName}}\" expires in {{days}} days", "eventExpired": "Event \"{{eventName}}\" has expired", "passwordChanged": "Password changed by {{actorName}}", "passwordReset": "Password reset for \"{{eventName}}\"", "settingsUpdated": "{{type}} settings updated", "emailTemplateUpdated": "Email template \"{{template}}\" updated", - "bulkDownload": "{{count}} photos downloaded from \"{{eventName}}\"", "storageWarning": "Storage usage at {{percentage}}%", "adminLogout": "Admin {{actorName}} logged out", "categoryCreated": "Category \"{{name}}\" created for \"{{eventName}}\"", @@ -1419,29 +1367,22 @@ "archiveDeleted": "Archive deleted for \"{{eventName}}\"", "archiveRestored": "Archive restored for \"{{eventName}}\"", "systemActivity": "System activity: {{type}}", - "adminProfileUpdated": "Admin profile updated by {{actorName}}" + "adminProfileUpdated": "Admin profile updated by {{actorName}}", + "photosUploaded_one": "{{count}} photo uploaded to \"{{eventName}}\"", + "photosUploaded_other": "{{count}} photos uploaded to \"{{eventName}}\"", + "photosBulkDeleted_one": "{{count}} photo deleted from \"{{eventName}}\"", + "photosBulkDeleted_other": "{{count}} photos deleted from \"{{eventName}}\"", + "bulkDownload_one": "{{count}} photo downloaded from \"{{eventName}}\"", + "bulkDownload_other": "{{count}} photos downloaded from \"{{eventName}}\"" }, "notificationToasts": { "markedAllRead": "All notifications marked as read", - "clearedAll": "Cleared {{count}} notifications", - "profileUpdated": "Admin profile updated" + "clearedAll_one": "Cleared {{count}} notification", + "clearedAll_other": "Cleared {{count}} notifications" }, - "markAsRead": "Mark as read", - "markAllAsRead": "Mark all as read", - "notificationSettings": "Notification Settings", "changePassword": "Change Password", "darkMode": "Switch to dark mode", "lightMode": "Switch to light mode", - "accountSettings": { - "title": "Admin account", - "description": "Update the credentials used to sign in to PicPeak.", - "username": "Username", - "usernamePlaceholder": "Admin", - "email": "Email", - "emailPlaceholder": "admin@example.com", - "updateButton": "Update profile" - }, - "profileUpdateError": "Unable to update admin profile. Please try again.", "loadingDashboard": "Loading dashboard...", "activeEvents": "Active Events", "expiringSoon": "Expiring Soon", @@ -1452,110 +1393,88 @@ "dashboardSubtitle": "Welcome back! Here's what's happening with your galleries.", "eventsExpiringSoon": "Events Expiring Soon", "noEventsExpiring": "No events expiring in the next 7 days", - "daysLeft": "{{count}} day left", - "daysLeft_plural": "{{count}} days left", - "viewAllExpiringEvents": "View all {{count}} expiring events", "noRecentActivity": "No recent activity", - "viewAllActivity": "View all activity", - "quickActions": "Quick Actions", - "viewArchives": "View Archives", - "analytics": "Analytics", - "activities": { - "event_created": "New event created: {{eventName}}", - "photos_uploaded": "{{count}} photos uploaded to {{eventName}}", - "event_archived": "Event archived: {{eventName}}", - "archive_restored": "Archive restored: {{eventName}}", - "archive_deleted": "Archive deleted: {{eventName}}", - "archive_downloaded": "Archive downloaded: {{eventName}}", - "email_config_updated": "Email configuration updated", - "email_template_updated": "Email template updated: {{template}}", - "branding_updated": "Branding settings updated", - "theme_updated": "Theme settings updated", - "bulk_download": "{{count}} photos downloaded from {{eventName}}", - "gallery_password_entry": "Password entered for {{eventName}}", - "expiration_warning_viewed": "Expiration warning viewed for {{eventName}}", - "feedback_settings_updated": "Feedback settings updated", - "feedback_moderated": "Feedback moderated", - "feedback_deleted": "Feedback deleted", - "photo_like": "Photo liked in {{eventName}}", - "photo_favorite": "Photo favorited in {{eventName}}", - "photo_rating": "Photo rated in {{eventName}}", - "photo_comment": "Photo commented in {{eventName}}", - "guest_feedback_like": "Guest liked a photo in {{eventName}}", - "guest_feedback_favorite": "Guest favorited a photo in {{eventName}}", - "guest_feedback_rating": "Guest rated a photo in {{eventName}}", - "guest_feedback_comment": "Guest commented on a photo in {{eventName}}", - "word_filter_added": "Word filter added", - "external_import_completed": "External media import completed ({{imported}} imported, {{skipped}} skipped)", - "bulk_archive_completed": "Bulk archive completed", - "event_activated": "Event activated: {{eventName}}", - "event_deactivated": "Event deactivated: {{eventName}}", - "photo_deleted": "Photo deleted from {{eventName}}", - "photos_bulk_deleted": "{{count}} photos deleted from {{eventName}}", - "settings_updated": "Settings updated", - "event_updated": "Event updated: {{eventName}}", - "event_renamed": "Event renamed: {{eventName}}", - "event_deleted": "Event deleted: {{eventName}}", - "password_changed": "Password changed", - "email_resent": "Creation email resent for: {{eventName}}", - "category_created": "Category created: {{categoryName}}", - "category_updated": "Category updated: {{categoryName}}", - "category_deleted": "Category deleted: {{categoryName}}", - "general_settings_updated": "General settings updated", - "favicon_uploaded": "Favicon uploaded", - "analytics_settings_updated": "Analytics settings updated", - "cms_page_updated": "CMS page updated: {{page}}", - "security_settings_updated": "Security settings updated", - "password_reset": "Password reset for: {{eventName}}", - "admin_logout": "Admin {{actorName}} logged out", - "system_activity": "System activity: {{type}}", - "unknown": "Unknown activity" - }, - "userManagement": "User Management", - "inviteUser": "Invite User", - "pendingInvitations": "Pending Invitations", - "roles": { - "super_admin": "Super Admin", - "admin": "Admin", - "editor": "Editor", - "viewer": "Viewer" - }, - "userStatus": { - "active": "Active", - "inactive": "Inactive" - }, - "inviteForm": { - "email": "Email Address", - "role": "Role", - "send": "Send Invitation" - }, - "acceptInvite": { - "title": "Accept Admin Invitation", - "username": "Choose a Username", - "password": "Create Password", - "submit": "Create Account" - }, "photos": { "hidden": "Hidden", "hideSelected": "Hide", "showSelected": "Show", "hiddenSuccess": "Photos hidden from guests", - "visibleSuccess": "Photos now visible to guests" + "visibleSuccess": "Photos now visible to guests", + "processingStatus": "Processing…", + "processingFailed": "Failed", + "retryQueued": "Retry queued" + }, + "events": { + "tabs": { + "guests": "Guests" + } + }, + "daysLeft_one": "{{count}} day left", + "daysLeft_other": "{{count}} days left", + "viewAllExpiringEvents_one": "View all {{count}} expiring events", + "viewAllExpiringEvents_other": "View all {{count}} expiring events", + "guests": { + "loading": "Loading...", + "aggregate": { + "empty": "No guest picks yet.", + "description": "Photos sorted by how many distinct guests liked or favorited them." + }, + "inviteCreated": "Invite created", + "inviteCreateError": "Failed to create invite", + "inviteRevoked": "Invite revoked", + "inviteRevokeError": "Failed to revoke invite", + "invitesTitle": "Guest invites", + "createInvite": "Create invite", + "inviteName": "Guest name", + "inviteEmail": "Email (optional)", + "generateInvite": "Generate invite link", + "existingInvites": "Existing invites", + "noInvites": "No invites yet", + "copyLink": "Copy link", + "revokeInvite": "Revoke", + "deletedToast": "Guest removed", + "deletedError": "Failed to remove guest", + "mergedToast": "Guests merged", + "mergedError": "Failed to merge guests", + "forgetGuestConfirm": "Remove this guest? Their picks will be anonymized but kept in aggregate totals.", + "exportError": "Export failed", + "mergeSelectAtLeastTwo": "Select at least 2 guests to merge", + "mergeConfirm_one": "Merge {{count}} guests into {{name}}? This cannot be undone.", + "mergeConfirm_other": "Merge {{count}} guests into {{name}}? This cannot be undone.", + "backToList": "Back to list", + "title": "Guests", + "mergeSelected_one": "{{count}} selected", + "mergeSelected_other": "{{count}} selected", + "mergeNow": "Merge selected", + "aggregateView": "By popularity", + "mergeMode": "Merge", + "exportAll": "Export all", + "empty": "No guests have registered yet.", + "columns": { + "name": "Name", + "email": "Email", + "likes": "Likes", + "favorites": "Favorites", + "comments": "Comments", + "ratings": "Ratings", + "lastSeen": "Last seen" + }, + "view": "View details", + "export": "Export", + "forgetGuest": "Remove guest", + "loadingDetail": "Loading selections...", + "detail": { + "noComments": "No comments", + "empty": "No selections in this category" + } } }, - "permissions": { - "insufficient": "You don't have permission to perform this action", - "viewOnly": "View Only" - }, "acceptInvitation": { "title": "Accept Invitation", "subtitle": "Create your admin account", "validating": "Validating invitation...", "invalidToken": "Invalid Invitation", "invalidTokenMessage": "This invitation link is invalid or has expired. Please contact your administrator for a new invitation.", - "expiredToken": "Invitation Expired", - "expiredTokenMessage": "This invitation has expired. Please request a new invitation from your administrator.", - "alreadyUsed": "Invitation Already Used", "alreadyUsedMessage": "This invitation has already been used to create an account.", "invitedAs": "You've been invited as", "expiresAt": "Invitation expires", @@ -1582,7 +1501,6 @@ "strong": "Strong" }, "createAccount": "Create Account", - "creating": "Creating account...", "success": "Account Created!", "successMessage": "Your account has been created successfully. You can now log in with your credentials.", "redirecting": "Redirecting to login in {{seconds}}...", @@ -1597,23 +1515,14 @@ "usernameTooLong": "Username must be at most 50 characters", "usernameInvalid": "Username can only contain letters, numbers, underscores, and hyphens", "passwordRequired": "Password is required", - "passwordTooShort": "Password must be at least 12 characters", "passwordsDoNotMatch": "Passwords do not match", "confirmPasswordRequired": "Please confirm your password", - "usernameTaken": "This username is already taken", - "emailTaken": "An account with this email already exists", "genericError": "Failed to create account. Please try again." } }, "errors": { - "notFound": "Not Found", "galleryNotFound": "Gallery Not Found", "galleryNotFoundMessage": "This gallery does not exist or has been removed.", - "galleryArchived": "Gallery Archived", - "galleryArchivedMessage": "This gallery has been archived and is no longer accessible. Please contact the event organizer if you need access to these photos.", - "unauthorized": "Unauthorized", - "forbidden": "Forbidden", - "serverError": "Server Error", "somethingWentWrong": "Something went wrong", "tryAgainLater": "Please try again later", "refreshPage": "Refresh Page", @@ -1623,10 +1532,9 @@ "errorDetails": "Error Details", "requiredFields": "Please fill in all required fields", "enterTestEmail": "Please enter a test email address", - "failedToCreateEvent": "Failed to create event", "eventCreationFailed": "Failed to create event", - "networkError": "Network error. Please check your connection and try again.", - "sessionExpired": "Session expired. Please login again." + "noShareLink": "No share link available", + "copyFailed": "Failed to copy link" }, "validation": { "eventNameRequired": "Event name is required", @@ -1637,14 +1545,15 @@ "passwordRequired": "Password is required", "passwordMinLength": "Password must be at least 6 characters", "passwordsDoNotMatch": "Passwords do not match", - "passwordSecurityRequirements": "Password does not meet security requirements", - "expirationRange": "Expiration must be between 1 and 365 days" + "expirationRange": "Expiration must be between 1 and 365 days", + "required": "This field is required", + "expirationRequired": "Expiration date is required.", + "eventDateRequired": "validation.eventDateRequired", + "passwordTooSimple": "Password cannot be just numbers. Consider using a date format like \"04.07.2025\"" }, "legal": { "impressum": "Legal Notice", - "datenschutz": "Privacy Policy", - "termsOfService": "Terms of Service", - "cookiePolicy": "Cookie Policy" + "datenschutz": "Privacy Policy" }, "toast": { "saveSuccess": "Changes saved successfully", @@ -1653,9 +1562,6 @@ "deleteError": "Failed to delete", "uploadSuccess": "Upload completed successfully", "uploadError": "Upload failed", - "loginSuccess": "Login successful", - "loginError": "Login failed", - "passwordChanged": "Password changed successfully", "linkCopied": "Link copied to clipboard", "eventCreated": "Event created successfully", "eventUpdated": "Event updated successfully", @@ -1663,14 +1569,10 @@ "settingsSaved": "Settings saved successfully", "themeUpdated": "Theme updated successfully", "brandingUpdated": "Branding updated successfully", - "categoryAdded": "Category added successfully", - "categoryDeleted": "Category deleted successfully", "categoryUpdated": "Category updated successfully", "emailConfigSaved": "Email configuration saved successfully", - "testEmailSent": "Test email sent successfully", - "pageUpdated": "Page updated successfully", - "archiveRestored": "Archive restored successfully", - "archiveDeleted": "Archive deleted permanently" + "brandingThemeMissing": "No branding theme has been saved yet.", + "brandingPaletteSynced": "Palette synced from Branding." }, "email": { "title": "Email Configuration", @@ -1678,28 +1580,9 @@ "loadingSettings": "Loading email settings...", "smtpConfiguration": "SMTP Configuration", "smtpHost": "SMTP Host", - "smtpHostHelp": "Your email server hostname", - "smtpPort": "SMTP Port", - "smtpPortHelp": "Usually 587 for TLS, 465 for SSL, 25 for unencrypted", - "smtpSecure": "Use SSL/TLS", - "smtpSecureHelp": "Enable for secure email transmission", - "smtpUsername": "SMTP Username", - "smtpUsernameHelp": "Your email account username", - "smtpPassword": "SMTP Password", - "smtpPasswordHelp": "Your email account password", - "fromDetails": "From Details", "fromEmail": "From Email", - "fromEmailHelp": "Email address that appears as sender", "fromName": "From Name", - "fromNameHelp": "Name that appears as sender", - "testConfiguration": "Test Configuration", - "testEmail": "Test Email Address", - "testEmailHelp": "Send a test email to verify settings", - "sendTestEmail": "Send Test Email", - "saveConfiguration": "Save Configuration", "emailTemplates": "Email Templates", - "templateVariables": "Available Variables", - "previewTemplate": "Preview Template", "smtpSettings": "SMTP Settings", "testEmailSuccess": "Test email sent successfully", "saveSmtpSettings": "Save SMTP Settings", @@ -1717,23 +1600,18 @@ "emailBody": "Email Body", "preview": "Preview", "save": "Save", - "saveChanges": "Save Changes", "templates": "Templates", - "variableHelp": "Use these variables in your template. They will be replaced with actual values when emails are sent.", "port": "Port", "security": "Security", "username": "Username", "password": "Password", "enterPassword": "Enter password", - "required": "required", "ignoreSslErrors": "Ignore SSL/TLS certificate errors", "ignoreSslWarning": "Warning: Disabling certificate verification makes the connection vulnerable to man-in-the-middle attacks. Only enable this if you trust the SMTP server and understand the security implications.", "brandingTitle": "Email Branding", "brandingDescription": "Customize the colors used in email templates. Changes apply to the header bar, buttons, links, and footer background.", "primaryColor": "Primary Color", - "primaryColorHint": "Used for header, buttons, and links", "secondaryColor": "Footer Background", - "secondaryColorHint": "Used for footer section background", "saveEmailColors": "Save Email Colors", "editor": { "bold": "Bold", @@ -1759,7 +1637,23 @@ "copiedFromLanguage": "Copied content from {{language}}", "noTranslation": "No translation yet", "noTranslationYet": "No translation exists for this language yet. Copy from an existing language to get started:", - "copyFrom": "Copy from" + "copyFrom": "Copy from", + "syncedFromBranding": "Email colours synced from Branding. Click Save to apply.", + "syncFromBranding": "Sync from Branding", + "primaryColorHelp": "Header bar, H2 headings, button background, link colour. Maps to Branding → Accent (filled).", + "secondaryColorHelp": "Footer bar background. Maps to Branding → Surface.", + "bodyBgColor": "Page background", + "bodyBgColorHelp": "The wrapper around the email card — what the recipient sees behind the email itself. Maps to Branding → Background.", + "containerBgColor": "Email card", + "containerBgColorHelp": "The white card that holds the email content. Maps to Branding → Surface.", + "listBgColor": "Info panel", + "listBgColorHelp": "Background of the bulleted info panels inside the email body. Maps to Branding → Elevated.", + "bodyTextColor": "Body text", + "bodyTextColorHelp": "Paragraph and bold text colour. Maps to Branding → Primary text.", + "mutedTextColor": "Footer text", + "mutedTextColorHelp": "Footer text and copyright line. Maps to Branding → Secondary text.", + "buttonTextColor": "Button text", + "buttonTextColorHelp": "Text colour on filled buttons. Should contrast cleanly against the Primary colour. No Branding equivalent — usually white." }, "cms": { "title": "CMS Pages", @@ -1773,17 +1667,22 @@ "pageTitle": "Page Title", "pageContent": "Page Content", "pageTitlePlaceholder": "Enter page title...", - "saveChanges": "Save Changes", "lastUpdated": "Last updated:", - "impressum": "Legal Notice", - "datenschutz": "Privacy Policy", "pageUpdated": "Page updated successfully", "useExternalUrl": "Use external URL", "useExternalUrlHelp": "Redirect visitors to an external page instead of showing the internal content. The internal title and content stay saved as a fallback.", "externalUrl": "External URL", "externalUrlPlaceholder": "https://example.com/impressum", "externalUrlInvalid": "Must be a valid https:// URL", - "externalUrlActive": "External URL is active — internal content is preserved but not shown to visitors." + "externalUrlActive": "External URL is active — internal content is preserved but not shown to visitors.", + "logoUploaded": "Logo uploaded", + "logoCleared": "Logo cleared", + "pageLogo": "Page Logo", + "pageLogoHelp": "Optional. If set, used in place of the global branding logo on this page.", + "noLogo": "no override", + "replaceLogo": "Replace Logo", + "uploadLogo": "Upload Logo", + "clearLogo": "Use site default" }, "eventTypes": { "title": "Event Types", @@ -1834,12 +1733,6 @@ } }, "backup": { - "external": { - "warning": { - "title": "External media excluded", - "body": "This installation references photos from /external-media. These originals are excluded from backups. Thumbnails and database are still backed up." - } - }, "title": "Backup Management", "subtitle": "Manage system backups, configure automated backups, and restore from previous backups.", "tabs": { @@ -1860,22 +1753,12 @@ "actions": { "runBackupNow": "Run Backup Now", "starting": "Starting...", - "running": "Running...", "testConnection": "Test Connection", - "save": "Save Configuration", "delete": "Delete", "view": "View Details", - "download": "Download", - "refresh": "Refresh" + "download": "Download" }, "dashboard": { - "backupHealth": "Backup Health", - "healthStatus": { - "excellent": "Excellent", - "good": "Good", - "warning": "Warning", - "critical": "Critical" - }, "health": { "title": "Backup Health" }, @@ -1885,9 +1768,7 @@ "upToDate": "Backup is up to date", "recent": "Backup is recent", "gettingOld": "Backup is getting old", - "outdated": "Backup is outdated", - "failed": "Last backup failed", - "old": "Backup is getting old" + "outdated": "Backup is outdated" }, "stats": { "totalBackups": "Total Backups", @@ -1896,7 +1777,6 @@ "backupStatus": "Backup Status", "last": "Last", "files": "files", - "minutes": "{{count}}m", "active": "Active", "inactive": "Inactive", "noBackupsYet": "No backups yet" @@ -1914,16 +1794,10 @@ }, "coverage": { "title": "Backup Coverage", - "database": "Database", - "photos": "Photos", - "archives": "Archives", - "systemFiles": "System Files", "included": "Included", - "excluded": "Excluded", - "optional": "Optional" + "excluded": "Excluded" }, "storageDestination": "Storage Destination", - "nextScheduledBackup": "Next Scheduled Backup", "backupType": "{{type}} backup", "noDestinationSet": "No destination set" }, @@ -1950,42 +1824,24 @@ "destinationPathHelp": "Local directory path for storing backups", "destinationPathPlaceholder": "/path/to/backup/directory", "rsyncHost": "Remote Host", - "rsyncHostHelp": "SSH hostname or IP address", "rsyncHostPlaceholder": "backup.example.com", "rsyncUser": "SSH User", - "rsyncUserHelp": "Username for SSH connection", "rsyncUserPlaceholder": "backup-user", "rsyncPath": "Remote Path", - "rsyncPathHelp": "Directory path on remote server", "rsyncPathPlaceholder": "/home/backup/photo-sharing", "rsyncSshKey": "SSH Private Key", "rsyncSshKeyHelp": "SSH private key for authentication (optional)", "rsyncSshKeyPlaceholder": "-----BEGIN RSA PRIVATE KEY-----", "s3Endpoint": "S3 Endpoint", "s3EndpointHelp": "S3 API endpoint (e.g., s3.amazonaws.com)", - "s3EndpointPlaceholder": "https://s3.amazonaws.com", "s3Bucket": "Bucket Name", - "s3BucketHelp": "S3 bucket for storing backups", - "s3BucketPlaceholder": "my-backup-bucket", "s3AccessKey": "Access Key ID", - "s3AccessKeyHelp": "AWS/S3 access key ID", - "s3AccessKeyPlaceholder": "AKIAIOSFODNN7EXAMPLE", "s3SecretKey": "Secret Access Key", - "s3SecretKeyHelp": "AWS/S3 secret access key", - "s3SecretKeyPlaceholder": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", - "s3Region": "Region", - "s3RegionHelp": "S3 region (e.g., us-east-1)", - "s3RegionPlaceholder": "us-east-1" + "s3Region": "Region" }, "schedule": { "title": "Backup Schedule", "scheduleType": "Schedule Type", - "scheduleOptions": { - "hourly": "Every hour", - "daily": "Daily", - "weekly": "Weekly", - "custom": "Custom cron expression" - }, "options": { "hourly": "Every hour", "daily": "Daily", @@ -2007,9 +1863,7 @@ "archives": "Archives", "archivesHelp": "Archived event ZIP files", "thumbnails": "Thumbnails", - "thumbnailsHelp": "Generated thumbnail images (can be recreated)", - "tempFiles": "Temporary Files", - "tempFilesHelp": "Temporary upload and processing files" + "thumbnailsHelp": "Generated thumbnail images (can be recreated)" }, "advancedOptions": { "title": "Advanced Options", @@ -2018,15 +1872,7 @@ "encryption": "Enable Encryption", "encryptionHelp": "Encrypt backups for additional security", "encryptionPassphrase": "Encryption Passphrase", - "encryptionPassphraseHelp": "Strong passphrase for backup encryption", - "confirmPassphrase": "Confirm Passphrase", - "passphrasesDontMatch": "Passphrases don't match" - }, - "validation": { - "requiredFields": "Please fill in all required fields", - "invalidCron": "Invalid cron expression", - "connectionTestFailed": "Connection test failed", - "connectionTestSuccess": "Connection test successful!" + "encryptionPassphraseHelp": "Strong passphrase for backup encryption" }, "messages": { "requiredFields": "Please fill in all required fields", @@ -2039,23 +1885,6 @@ }, "history": { "searchPlaceholder": "Search backups...", - "allStatus": "All Status", - "status": { - "completed": "Completed", - "failed": "Failed", - "running": "Running", - "partial": "Partial" - }, - "deleteConfirm": "Are you sure you want to delete this backup from {{date}}?", - "noBackups": "No backups found", - "tableHeaders": { - "date": "Date", - "type": "Type", - "status": "Status", - "size": "Size", - "duration": "Duration", - "actions": "Actions" - }, "columns": { "status": "Status", "dateTime": "Date & Time", @@ -2073,35 +1902,10 @@ "errorDetails": "Error Details", "manifest": "Manifest" }, - "statistics": "Statistics", - "errors": "Errors", - "backupDetails": { - "backupId": "Backup ID", - "startTime": "Start Time", - "endTime": "End Time", - "destination": "Destination", - "filesProcessed": "Files Processed", - "totalSize": "Total Size", - "compressionRatio": "Compression Ratio", - "errorLog": "Error Log", - "noErrors": "No errors occurred" - }, "pagination": { "showing": "Showing {{from}}-{{to}} of {{total}} backups", "previous": "Previous", "next": "Next" - }, - "filter": { - "allStatus": "All Status", - "completed": "Completed", - "failed": "Failed", - "running": "Running", - "partial": "Partial" - }, - "noBackupsFound": "No backups found", - "backupsWillAppear": "Backups will appear here once created", - "messages": { - "deleteSuccess": "Backup deleted successfully" } }, "restore": { @@ -2214,12 +2018,6 @@ "current": "Current", "statusDetails": "Status Details", "restoreLogs": "Restore Logs", - "steps": { - "completed": "Completed", - "running": "Running", - "failed": "Failed", - "pending": "Pending" - }, "success": { "title": "Restore Completed Successfully", "message": "Your data has been restored. Please verify everything is working correctly." @@ -2232,20 +2030,13 @@ "starting": "Starting...", "validating": "Validating...", "startNewRestore": "Start New Restore" - }, - "messages": { - "restoreStarted": "Restore started successfully" } }, "messages": { "backupStarted": "Backup started successfully", "backupFailed": "Failed to start backup", "configUpdated": "Backup configuration updated", - "configUpdateFailed": "Failed to update configuration", - "backupDeleted": "Backup deleted successfully", - "deleteFailed": "Failed to delete backup", - "testEmailSent": "Test connection successful!", - "testEmailFailed": "Connection test failed" + "configUpdateFailed": "Failed to update configuration" } }, "cssTemplates": { @@ -2272,8 +2063,6 @@ "maintenance": { "title": "System Maintenance", "message": "We're currently performing scheduled maintenance to improve our service. We'll be back online shortly.", - "expectedCompletion": "Expected completion time:", - "checkBackLater": "Please check back later", "urgentMatters": "For urgent matters, please contact" }, "passwordChange": { @@ -2352,18 +2141,7 @@ "pendingApproval": "Pending approval", "noComments": "No comments yet. Be the first to comment!", "rating": "Rating", - "ratePhoto": "Rate this photo", - "yourRating": "Your rating", - "averageRating": "Average rating", - "totalRatings": "ratings", "likes": "Likes", - "favorites": "Favorites", - "likePhoto": "Like this photo", - "favoritePhoto": "Add to favorites", - "photoFeedback": "Photo Feedback", - "hasFeedback": "Has feedback", - "hasComments": "Has comments", - "hasRating": "Has rating", "settings": { "title": "Guest Feedback Settings", "enableFeedback": "Enable feedback", @@ -2380,25 +2158,103 @@ "identityModeSimple": "Simple feedback", "identityModeSimpleDesc": "Anonymous, device-based. All visitors on the same device share state.", "identityModeGuest": "Per-guest selections", - "identityModeGuestDesc": "Each visitor enters their name. Enables per-guest tracking and admin insights." - } + "identityModeGuestDesc": "Each visitor enters their name. Enables per-guest tracking and admin insights.", + "privacyModeration": "Privacy & Moderation", + "requireInfo": "Require Name & Email", + "requireInfoDesc": "Guests must provide name and email to leave feedback", + "moderateComments": "Moderate Comments", + "moderateCommentsDesc": "Comments require approval before being visible", + "showToGuests": "Show Feedback to Guests", + "showToGuestsDesc": "Other guests can see ratings, likes, and approved comments", + "enableRateLimiting": "Enable Rate Limiting", + "rateLimitingDesc": "Prevent spam by limiting feedback frequency", + "timeWindow": "Time Window (minutes)", + "maxRequests": "Max Requests" + }, + "settingsUpdated": "Feedback settings updated", + "settingsUpdateError": "Failed to update settings", + "moderated": "Feedback moderated", + "deleted": "Feedback deleted", + "exported": "Feedback exported", + "exportError": "Failed to export feedback", + "title": "Feedback Management", + "exportCSV": "Export CSV", + "exportJSON": "Export JSON", + "tabs": { + "settings": "Settings", + "feedback": "Feedback", + "analytics": "Analytics", + "moderation": "Moderation" + }, + "allTypes": "All Types", + "types": { + "rating": "Ratings", + "like": "Likes", + "comment": "Comments", + "favorite": "Favorites" + }, + "allStatuses": "All Statuses", + "status": { + "pending": "Pending", + "approved": "Approved", + "hidden": "Hidden" + }, + "noFeedback": "No feedback found", + "approve": "Approve", + "hide": "Hide", + "unhide": "Unhide", + "confirmDelete": "Are you sure you want to delete this feedback?", + "avgRating": "Average Rating", + "totalRatings_one": "{{count}} ratings", + "totalRatings_other": "{{count}} ratings", + "totalLikes": "Total Likes", + "totalComments": "Total Comments", + "pendingModeration_one": "{{count}} pending", + "pendingModeration_other": "{{count}} pending", + "totalInteractions": "Total Interactions", + "topRated": "Top Rated Photos", + "recentComments": "Recent Comments", + "wordFilters": "Word Filters", + "wordFiltersDesc": "Manage blocked words for comment moderation", + "manageFilters": "Manage Word Filters", + "manage": "Manage Feedback", + "ratingSubmitted": "Rating submitted", + "ratingError": "Failed to submit rating", + "rateStar_one": "Rate {{count}} stars", + "rateStar_other": "Rate {{count}} stars", + "ratingsCount_one": "{{count}} ratings", + "ratingsCount_other": "{{count}} ratings", + "likeError": "Failed to update like", + "unlike": "Unlike", + "like": "Like", + "favoriteError": "Failed to update favorite", + "unfavorite": "Remove from favorites", + "favorite": "Add to favorites", + "invalidEmail": "Invalid email address", + "identityRequired": "Your Information Required", + "identityReason": "Please provide your name and email to submit {{type}}.", + "namePlaceholder": "Enter your name", + "emailPlaceholder": "Enter your email", + "submitFeedback": "Submit Feedback", + "moderationSuccess": "feedback.moderationSuccess", + "pendingModeration": "Pending Moderation", + "pending": "pending", + "noPendingComments": "No comments pending moderation", + "onPhoto": "On photo", + "showAll_one": "Show all {{count}} pending comments", + "showAll_other": "Show all {{count}} pending comments", + "viewAllFeedback": "View all feedback & settings" }, "filter": { "feedbackFilters": "Feedback Filters", "clear": "Clear", "rating": "Rating", - "allPhotos": "All Photos", - "anyRating": "Any Rating", - "oneStarPlus": "1+ Stars", - "twoStarsPlus": "2+ Stars", - "threeStarsPlus": "3+ Stars", - "fourStarsPlus": "4+ Stars", - "fiveStarsOnly": "5 Stars Only", "hasLikes": "Has likes", "hasFavorites": "Has favorites", "hasComments": "Has comments", "showingPhotos": "Total photos", - "withRatings": "With ratings" + "withRatings": "With ratings", + "combineWith": "Combine with" }, "adminLogin": { "title": "Admin Login", @@ -2413,7 +2269,6 @@ "passwordRequired": "Password is required", "passwordMinLength": "Password must be at least 6 characters", "rememberMe": "Remember me", - "forgotPassword": "Forgot password?", "signIn": "Sign In", "loginSuccess": "Login successful!", "networkError": "Network error. Please check your connection and try again.", @@ -2453,9 +2308,10 @@ "button": "Export", "success": "Export downloaded successfully", "error": "Export failed: ", - "exportSelected": "Export {{count}} selected", "exportFiltered": "Export filtered photos", - "hint": "Select photos or apply filters to export" + "hint": "Select photos or apply filters to export", + "exportSelected_one": "Export {{count}} selected", + "exportSelected_other": "Export {{count}} selected" }, "photoSort": { "defaultSort": "Default Photo Sort", @@ -2466,5 +2322,17 @@ "filenameAZ": "Filename (A-Z)", "filenameZA": "Filename (Z-A)", "dateTaken": "Date Taken" + }, + "photos": { + "moveToCategory_one": "Move {{count}} photos to category", + "moveToCategory_other": "Move {{count}} photos to category", + "selectCategory": "Select category", + "uncategorized": "Uncategorized", + "movePhotos": "Move Photos", + "selectedCategory": "selected category", + "movedToCategory_one": "{{count}} photos moved to {{category}}", + "movedToCategory_other": "{{count}} photos moved to {{category}}", + "moveToCategoryFailed": "Failed to move photos to category", + "moveToCategory": "Move to Category" } }