From 9a4327045c8144a5a3bb498f6c00650d9143caba Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Fri, 16 May 2025 19:11:18 +1000 Subject: [PATCH 001/189] feat(vscode): Add option to rebuild gRPC bindings --- .vscode/launch.json | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.vscode/launch.json b/.vscode/launch.json index 8c250e4a..06018eff 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -23,6 +23,13 @@ "env": { "PN_JUXTAPOSITION_UI_USE_PRESETS": "docker" } + }, + { + "type": "node-terminal", + "name": "Rebuild gRPC", + "request": "launch", + "command": "npm rebuild @repo/grpc-client", + "cwd": "${workspaceFolder}" } ], "compounds": [ From d6a5d2d53f14221a95ace07021b8dfbe0445acda Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Fri, 16 May 2025 19:14:04 +1000 Subject: [PATCH 002/189] feat(grpc): Move headers into the JSON object If we're putting the method and such in the JSON object, it makes sense to keep the headers at that layer rather than pushing them up to gRPC. This lets the Express router access those headers in the usual way. --- apps/juxtaposition-ui/src/fetch.ts | 2 +- apps/miiverse-api/src/services/internal/server.ts | 3 ++- protobufs/miiverse/v2/packet.proto | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/apps/juxtaposition-ui/src/fetch.ts b/apps/juxtaposition-ui/src/fetch.ts index e910bf50..5cc19d66 100644 --- a/apps/juxtaposition-ui/src/fetch.ts +++ b/apps/juxtaposition-ui/src/fetch.ts @@ -20,12 +20,12 @@ export async function apiFetch(path: string, options?: FetchOptions): Promise }; const metadata = Metadata({ - ...defaultedOptions.headers, 'X-API-Key': config.grpc.miiverse.apiKey }); const response = await grpcClient.sendPacket({ path, method: defaultedOptions.method, + headers: JSON.stringify(defaultedOptions.headers), payload: defaultedOptions.body ? JSON.stringify(defaultedOptions.body) : undefined }, { metadata diff --git a/apps/miiverse-api/src/services/internal/server.ts b/apps/miiverse-api/src/services/internal/server.ts index 0e63d0cc..f929c0af 100644 --- a/apps/miiverse-api/src/services/internal/server.ts +++ b/apps/miiverse-api/src/services/internal/server.ts @@ -37,9 +37,10 @@ export async function setupGrpc(): Promise { throw new ServerError(Status.UNIMPLEMENTED, 'Method not implemented'); } const method = request.method.toLowerCase() as AllowedMethods; + const headers = JSON.parse(request.headers); const hasBody = methodsWithBody.includes(method as any); - let baseRequest = superRequest(app)[method](request.path); + let baseRequest = superRequest(app)[method](request.path).set(headers); if (hasBody) { baseRequest = baseRequest.send(JSON.parse(request.payload)); } diff --git a/protobufs/miiverse/v2/packet.proto b/protobufs/miiverse/v2/packet.proto index e5ef416a..928253c9 100644 --- a/protobufs/miiverse/v2/packet.proto +++ b/protobufs/miiverse/v2/packet.proto @@ -5,7 +5,8 @@ package miiverse.v2; message Packet { string path = 1; string method = 2; - string payload = 3; + string headers = 3; + string payload = 4; } message PacketResponse { From f2b6938e4231a198ce44448f240da00254d49940 Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Fri, 16 May 2025 19:14:31 +1000 Subject: [PATCH 003/189] fix(grpc): Log the error object Easy mistake --- apps/miiverse-api/src/services/internal/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/miiverse-api/src/services/internal/utils.ts b/apps/miiverse-api/src/services/internal/utils.ts index dc31163b..24dfbc08 100644 --- a/apps/miiverse-api/src/services/internal/utils.ts +++ b/apps/miiverse-api/src/services/internal/utils.ts @@ -16,7 +16,7 @@ export function handle(handler: HandlerFunction) { res.status(200).json(result); return; } catch (error) { - logger.error('Unhandled exception in handler', error); + logger.error(error, 'Unhandled exception in handler'); res.status(500).json({ error: 'Internal Server Error' }); return; } From a4da3311eafbf42f4038b06356d2280520da8351 Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Fri, 16 May 2025 19:32:46 +1000 Subject: [PATCH 004/189] feat(grpc): helpers for responding with error codes --- apps/juxtaposition-ui/src/fetch.ts | 1 + apps/miiverse-api/src/errors.ts | 26 +++++++++++++++++++++++--- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/apps/juxtaposition-ui/src/fetch.ts b/apps/juxtaposition-ui/src/fetch.ts index 5cc19d66..17307ad5 100644 --- a/apps/juxtaposition-ui/src/fetch.ts +++ b/apps/juxtaposition-ui/src/fetch.ts @@ -31,6 +31,7 @@ export async function apiFetch(path: string, options?: FetchOptions): Promise metadata }); + // TODO don't throw away the response payload here if (isErrorHttpStatus(response.status)) { throw new Error(`HTTP error! status: ${response.status}`); } diff --git a/apps/miiverse-api/src/errors.ts b/apps/miiverse-api/src/errors.ts index 72cb9db8..60205f89 100644 --- a/apps/miiverse-api/src/errors.ts +++ b/apps/miiverse-api/src/errors.ts @@ -57,7 +57,7 @@ export enum ApiErrorCode { FAIL_POST_NOCOMMENT = 935 } -function sendError(response: express.Response, errorCode: ApiErrorCode, httpCode: number): void { +function sendXMLError(response: express.Response, errorCode: ApiErrorCode, httpCode: number): void { response.type('application/xml'); response.status(httpCode); // Save this for the logger @@ -74,10 +74,30 @@ function sendError(response: express.Response, errorCode: ApiErrorCode, httpCode }).end({ pretty: true })); } +function sendJSONError(response: express.Response, errorCode: ApiErrorCode, httpCode: number): void { + response.status(httpCode); + // Save this for the logger + response.errorCode = errorCode; + + // TODO actually design this object + response.json({ + error_code: errorCode, + message: ApiErrorCode[errorCode] + }); +} + export function badRequest(response: express.Response, errorCode: number, httpCode: number = 400): void { - return sendError(response, errorCode, httpCode); + return sendXMLError(response, errorCode, httpCode); } export function serverError(response: express.Response, errorCode: ApiErrorCode, httpCode: number = 500): void { - return sendError(response, errorCode, httpCode); + return sendXMLError(response, errorCode, httpCode); +} + +export function badRequestV2(response: express.Response, errorCode: number, httpCode: number = 400): void { + return sendJSONError(response, errorCode, httpCode); +} + +export function serverErrorV2(response: express.Response, errorCode: ApiErrorCode, httpCode: number = 500): void { + return sendJSONError(response, errorCode, httpCode); } From 93e3ad13f45c5b533f93faa5a8c577f0a0b84c99 Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Fri, 16 May 2025 19:33:15 +1000 Subject: [PATCH 005/189] feat(grpc): Work-in-progress authentication middleware --- apps/miiverse-api/src/middleware/authv2.ts | 24 +++++++++++++++++++ .../src/services/internal/server.ts | 2 ++ 2 files changed, 26 insertions(+) create mode 100644 apps/miiverse-api/src/middleware/authv2.ts diff --git a/apps/miiverse-api/src/middleware/authv2.ts b/apps/miiverse-api/src/middleware/authv2.ts new file mode 100644 index 00000000..8d93154a --- /dev/null +++ b/apps/miiverse-api/src/middleware/authv2.ts @@ -0,0 +1,24 @@ +import { ApiErrorCode, badRequestV2 } from '@/errors'; +import { getValueFromHeaders } from '@/util'; +import type express from 'express'; + +async function auth(request: express.Request, response: express.Response, next: express.NextFunction): Promise { + const serviceToken = getValueFromHeaders(request.headers, 'x-service-token'); + const oAuthToken = getValueFromHeaders(request.headers, 'x-oauth-token'); + + if (serviceToken && oAuthToken) { + return badRequestV2(response, ApiErrorCode.BAD_TOKEN); + } + + if (serviceToken) { + // TODO + } else if (oAuthToken) { + // TODO + } else { + return badRequestV2(response, ApiErrorCode.BAD_TOKEN); + } + + return next(); +} + +export default auth; diff --git a/apps/miiverse-api/src/services/internal/server.ts b/apps/miiverse-api/src/services/internal/server.ts index f929c0af..d78b186e 100644 --- a/apps/miiverse-api/src/services/internal/server.ts +++ b/apps/miiverse-api/src/services/internal/server.ts @@ -4,6 +4,7 @@ import express from 'express'; import { MiiverseServiceDefinition } from '@repo/grpc-client/out/miiverse_service'; import { config } from '@/config'; import { internalApiRouter } from '@/services/internal'; +import authv2 from '@/middleware/authv2'; import { logger } from '@/logger'; import type { CallContext, ServerMiddlewareCall } from 'nice-grpc'; @@ -22,6 +23,7 @@ export async function* apiKeyMiddleware( const app = express(); app.use(express.json()); +app.use(authv2); app.use(internalApiRouter); const allowedMethods = ['get', 'post', 'put', 'delete', 'patch'] as const; From a4f5153a173cb06a622d8b4226996fe2a32dffcb Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Fri, 16 May 2025 20:35:48 +1000 Subject: [PATCH 006/189] chore(internal): Refactor error handling --- apps/miiverse-api/src/errors.ts | 20 ------------ .../src/services/internal/errors.ts | 16 ++++++++++ .../internal/middleware/authentication.ts} | 6 ++-- .../src/services/internal/server.ts | 32 +++++++++++++++---- 4 files changed, 45 insertions(+), 29 deletions(-) create mode 100644 apps/miiverse-api/src/services/internal/errors.ts rename apps/miiverse-api/src/{middleware/authv2.ts => services/internal/middleware/authentication.ts} (71%) diff --git a/apps/miiverse-api/src/errors.ts b/apps/miiverse-api/src/errors.ts index 60205f89..6b730f07 100644 --- a/apps/miiverse-api/src/errors.ts +++ b/apps/miiverse-api/src/errors.ts @@ -74,18 +74,6 @@ function sendXMLError(response: express.Response, errorCode: ApiErrorCode, httpC }).end({ pretty: true })); } -function sendJSONError(response: express.Response, errorCode: ApiErrorCode, httpCode: number): void { - response.status(httpCode); - // Save this for the logger - response.errorCode = errorCode; - - // TODO actually design this object - response.json({ - error_code: errorCode, - message: ApiErrorCode[errorCode] - }); -} - export function badRequest(response: express.Response, errorCode: number, httpCode: number = 400): void { return sendXMLError(response, errorCode, httpCode); } @@ -93,11 +81,3 @@ export function badRequest(response: express.Response, errorCode: number, httpCo export function serverError(response: express.Response, errorCode: ApiErrorCode, httpCode: number = 500): void { return sendXMLError(response, errorCode, httpCode); } - -export function badRequestV2(response: express.Response, errorCode: number, httpCode: number = 400): void { - return sendJSONError(response, errorCode, httpCode); -} - -export function serverErrorV2(response: express.Response, errorCode: ApiErrorCode, httpCode: number = 500): void { - return sendJSONError(response, errorCode, httpCode); -} diff --git a/apps/miiverse-api/src/services/internal/errors.ts b/apps/miiverse-api/src/services/internal/errors.ts new file mode 100644 index 00000000..44b74909 --- /dev/null +++ b/apps/miiverse-api/src/services/internal/errors.ts @@ -0,0 +1,16 @@ +export class InternalAPIError extends Error { + status: number; + + constructor(status: number, message?: string) { + super(message); + this.status = status; + } +} + +export const errors = { + badRequest: InternalAPIError.bind(null, 400), + unauthorized: InternalAPIError.bind(null, 401), + forbidden: InternalAPIError.bind(null, 403), + + serverError: InternalAPIError.bind(null, 500) +}; diff --git a/apps/miiverse-api/src/middleware/authv2.ts b/apps/miiverse-api/src/services/internal/middleware/authentication.ts similarity index 71% rename from apps/miiverse-api/src/middleware/authv2.ts rename to apps/miiverse-api/src/services/internal/middleware/authentication.ts index 8d93154a..f185803b 100644 --- a/apps/miiverse-api/src/middleware/authv2.ts +++ b/apps/miiverse-api/src/services/internal/middleware/authentication.ts @@ -1,5 +1,5 @@ -import { ApiErrorCode, badRequestV2 } from '@/errors'; import { getValueFromHeaders } from '@/util'; +import { errors } from '@/services/internal/errors'; import type express from 'express'; async function auth(request: express.Request, response: express.Response, next: express.NextFunction): Promise { @@ -7,7 +7,7 @@ async function auth(request: express.Request, response: express.Response, next: const oAuthToken = getValueFromHeaders(request.headers, 'x-oauth-token'); if (serviceToken && oAuthToken) { - return badRequestV2(response, ApiErrorCode.BAD_TOKEN); + next(new errors.badRequest('Multiple authentication tokens provided')); } if (serviceToken) { @@ -15,7 +15,7 @@ async function auth(request: express.Request, response: express.Response, next: } else if (oAuthToken) { // TODO } else { - return badRequestV2(response, ApiErrorCode.BAD_TOKEN); + return next(new errors.unauthorized('Authentication token not provided')); } return next(); diff --git a/apps/miiverse-api/src/services/internal/server.ts b/apps/miiverse-api/src/services/internal/server.ts index d78b186e..b47a6f5a 100644 --- a/apps/miiverse-api/src/services/internal/server.ts +++ b/apps/miiverse-api/src/services/internal/server.ts @@ -4,10 +4,35 @@ import express from 'express'; import { MiiverseServiceDefinition } from '@repo/grpc-client/out/miiverse_service'; import { config } from '@/config'; import { internalApiRouter } from '@/services/internal'; -import authv2 from '@/middleware/authv2'; +import authentication from '@/services/internal/middleware/authentication'; import { logger } from '@/logger'; +import { InternalAPIError } from '@/services/internal/errors'; import type { CallContext, ServerMiddlewareCall } from 'nice-grpc'; +// API server + +const app = express(); +app.use(express.json()); +app.use(authentication); +app.use(internalApiRouter); + +// API error handler +app.use((err: Error, _request: express.Request, response: express.Response, next: express.NextFunction) => { + if (!(err instanceof InternalAPIError)) { + return next(); + } + + logger.warn(err, 'API error'); + response.status(err.status).json({ message: err.message }); +}); +// Javascript error handler +app.use((err: Error, _request: express.Request, response: express.Response, _next: express.NextFunction) => { + logger.error(err, 'Unhandled error!'); + response.status(500).json({ message: 'Internal server error' }); +}); + +// gRPC glue + export async function* apiKeyMiddleware( call: ServerMiddlewareCall, context: CallContext @@ -21,11 +46,6 @@ export async function* apiKeyMiddleware( return yield* call.next(call.request, context); } -const app = express(); -app.use(express.json()); -app.use(authv2); -app.use(internalApiRouter); - const allowedMethods = ['get', 'post', 'put', 'delete', 'patch'] as const; const methodsWithBody = ['post', 'put', 'delete', 'patch'] as const; type AllowedMethods = typeof allowedMethods[number]; From c695ef213aeb69a817fdbdc7d9ca0af2ecd5aaf3 Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Fri, 16 May 2025 22:17:06 +1000 Subject: [PATCH 007/189] feat(internal): Implement authentication and tweak error handling more --- apps/miiverse-api/package.json | 1 + apps/miiverse-api/src/server.ts | 1 + .../internal/middleware/authentication.ts | 44 ++++++++++++++++--- .../src/services/internal/server.ts | 7 +-- .../src/services/internal/utils.ts | 14 ++---- .../src/types/common/account-data.ts | 7 +++ apps/miiverse-api/src/util.ts | 18 +++++++- package-lock.json | 10 +++++ 8 files changed, 81 insertions(+), 21 deletions(-) create mode 100644 apps/miiverse-api/src/types/common/account-data.ts diff --git a/apps/miiverse-api/package.json b/apps/miiverse-api/package.json index af75d13d..46c6c494 100644 --- a/apps/miiverse-api/package.json +++ b/apps/miiverse-api/package.json @@ -21,6 +21,7 @@ "colors": "^1.4.0", "crc": "^4.3.2", "express": "^4.17.1", + "express-async-errors": "^3.1.1", "express-prom-bundle": "^7.0.2", "express-subdomain": "^1.0.5", "fs-extra": "^9.0.0", diff --git a/apps/miiverse-api/src/server.ts b/apps/miiverse-api/src/server.ts index 55703e3b..d2637c51 100644 --- a/apps/miiverse-api/src/server.ts +++ b/apps/miiverse-api/src/server.ts @@ -1,4 +1,5 @@ import express from 'express'; +import 'express-async-errors'; // See package docs import expressMetrics from 'express-prom-bundle'; import { connect as connectDatabase } from '@/database'; import { logger } from '@/logger'; diff --git a/apps/miiverse-api/src/services/internal/middleware/authentication.ts b/apps/miiverse-api/src/services/internal/middleware/authentication.ts index f185803b..b8019d04 100644 --- a/apps/miiverse-api/src/services/internal/middleware/authentication.ts +++ b/apps/miiverse-api/src/services/internal/middleware/authentication.ts @@ -1,24 +1,58 @@ -import { getValueFromHeaders } from '@/util'; +import { getPIDFromServiceToken, getUserAccountData, getUserDataFromToken, getValueFromHeaders } from '@/util'; import { errors } from '@/services/internal/errors'; +import { getUserSettings } from '@/database'; import type express from 'express'; +import type { AccountData } from '@/types/common/account-data'; async function auth(request: express.Request, response: express.Response, next: express.NextFunction): Promise { + // Used by console applets const serviceToken = getValueFromHeaders(request.headers, 'x-service-token'); + // Used by web frontend const oAuthToken = getValueFromHeaders(request.headers, 'x-oauth-token'); if (serviceToken && oAuthToken) { - next(new errors.badRequest('Multiple authentication tokens provided')); + throw new errors.badRequest('Multiple authentication tokens provided'); } if (serviceToken) { - // TODO + response.locals.account = await consoleAuth(serviceToken); } else if (oAuthToken) { - // TODO + response.locals.account = await webAuth(oAuthToken); } else { - return next(new errors.unauthorized('Authentication token not provided')); + throw new errors.unauthorized('Authentication token not provided'); } return next(); } +async function consoleAuth(serviceToken: string): Promise { + const pid = getPIDFromServiceToken(serviceToken); + if (pid === 0) { + throw new errors.unauthorized('Invalid service token'); + } + + const pnid = await getUserAccountData(pid); + // If the user has a valid token for an unknown PID, just let the exception bubble + + const settings = await getUserSettings(pid) ?? undefined; // Null doesn't play nice with TS ? + // Undef here just means the initial setup isn't done + + return { pnid, settings }; +} + +async function webAuth(oAuthToken: string): Promise { + // The "normal" getUserData API (used here) is mutually incompatible with the "backdoor" one. + // Since we can only use the backdoor one for consoles right now... + const pid = (await getUserDataFromToken(oAuthToken).catch(() => { + // TODO should probably check the error type here in case of e.g. connection refused + throw new errors.unauthorized('Invalid OAuth token!'); + })).pid; + // Ask the "backdoor" API, just use the above as a glorified token decryption. + const pnid = await getUserAccountData(pid); + + const settings = await getUserSettings(pid) ?? undefined; + + return { pnid, settings }; +} + export default auth; diff --git a/apps/miiverse-api/src/services/internal/server.ts b/apps/miiverse-api/src/services/internal/server.ts index b47a6f5a..56a812f6 100644 --- a/apps/miiverse-api/src/services/internal/server.ts +++ b/apps/miiverse-api/src/services/internal/server.ts @@ -7,27 +7,28 @@ import { internalApiRouter } from '@/services/internal'; import authentication from '@/services/internal/middleware/authentication'; import { logger } from '@/logger'; import { InternalAPIError } from '@/services/internal/errors'; +import { loggerHttp } from '@/loggerHttp'; import type { CallContext, ServerMiddlewareCall } from 'nice-grpc'; // API server const app = express(); app.use(express.json()); +app.use(loggerHttp); app.use(authentication); app.use(internalApiRouter); // API error handler app.use((err: Error, _request: express.Request, response: express.Response, next: express.NextFunction) => { if (!(err instanceof InternalAPIError)) { - return next(); + return next(err); } - logger.warn(err, 'API error'); response.status(err.status).json({ message: err.message }); }); // Javascript error handler app.use((err: Error, _request: express.Request, response: express.Response, _next: express.NextFunction) => { - logger.error(err, 'Unhandled error!'); + response.err = err; // For Pino response.status(500).json({ message: 'Internal server error' }); }); diff --git a/apps/miiverse-api/src/services/internal/utils.ts b/apps/miiverse-api/src/services/internal/utils.ts index 24dfbc08..94e5c0c8 100644 --- a/apps/miiverse-api/src/services/internal/utils.ts +++ b/apps/miiverse-api/src/services/internal/utils.ts @@ -1,4 +1,3 @@ -import { logger } from '@/logger'; import type { Request, Response } from 'express'; export type HandlerContext = { @@ -10,15 +9,8 @@ export type HandlerFunction = (ctx: HandlerContext) => any; export function handle(handler: HandlerFunction) { return async (req: Request, res: Response): Promise => { - try { - const ctx: HandlerContext = { req, res }; - const result = await handler(ctx); - res.status(200).json(result); - return; - } catch (error) { - logger.error(error, 'Unhandled exception in handler'); - res.status(500).json({ error: 'Internal Server Error' }); - return; - } + const ctx: HandlerContext = { req, res }; + const result = await handler(ctx); + res.status(200).json(result); }; } diff --git a/apps/miiverse-api/src/types/common/account-data.ts b/apps/miiverse-api/src/types/common/account-data.ts new file mode 100644 index 00000000..a1885706 --- /dev/null +++ b/apps/miiverse-api/src/types/common/account-data.ts @@ -0,0 +1,7 @@ +import type { HydratedSettingsDocument } from '@/types/mongoose/settings'; +import type { GetUserDataResponse } from '@pretendonetwork/grpc/account/get_user_data_rpc'; + +export interface AccountData { + pnid: GetUserDataResponse; + settings?: HydratedSettingsDocument; +} diff --git a/apps/miiverse-api/src/util.ts b/apps/miiverse-api/src/util.ts index b1e4aa0e..ce071380 100644 --- a/apps/miiverse-api/src/util.ts +++ b/apps/miiverse-api/src/util.ts @@ -8,10 +8,12 @@ import { createChannel, createClient, Metadata } from 'nice-grpc'; import crc32 from 'crc/crc32'; import { FriendsDefinition } from '@pretendonetwork/grpc/friends/friends_service'; import { AccountDefinition } from '@pretendonetwork/grpc/account/account_service'; +import { APIDefinition } from '@pretendonetwork/grpc/api/api_service'; import { config } from '@/config'; import { logger } from '@/logger'; import type { FriendRequest } from '@pretendonetwork/grpc/friends/friend_request'; -import type { GetUserDataResponse } from '@pretendonetwork/grpc/account/get_user_data_rpc'; +import type { GetUserDataResponse as AccountGetUserDataResponse } from '@pretendonetwork/grpc/account/get_user_data_rpc'; +import type { GetUserDataResponse as ApiGetUserDataResponse } from '@pretendonetwork/grpc/api/get_user_data_rpc'; import type { ParsedQs } from 'qs'; import type { IncomingHttpHeaders } from 'node:http'; import type { ParamPack } from '@/types/common/param-pack'; @@ -24,6 +26,9 @@ const gRPCFriendsClient = createClient(FriendsDefinition, gRPCFriendsChannel); const gRPCAccountChannel = createChannel(`${config.grpc.account.host}:${config.grpc.account.port}`); const gRPCAccountClient = createClient(AccountDefinition, gRPCAccountChannel); +const gRPCApiChannel = createChannel(`${config.grpc.account.host}:${config.grpc.account.port}`); +const gRPCApiClient = createClient(APIDefinition, gRPCApiChannel); + const s3 = new aws.S3({ endpoint: new aws.Endpoint(config.s3.endpoint), accessKeyId: config.s3.key, @@ -186,7 +191,7 @@ export async function getUserFriendRequestsIncoming(pid: number): Promise { +export function getUserAccountData(pid: number): Promise { return gRPCAccountClient.getUserData({ pid: pid }, { @@ -196,6 +201,15 @@ export function getUserAccountData(pid: number): Promise { }); } +export function getUserDataFromToken(token: string): Promise { + return gRPCApiClient.getUserData({}, { + metadata: Metadata({ + 'X-API-Key': config.grpc.account.apiKey, + 'X-Token': token + }) + }); +} + export function getValueFromQueryString(qs: ParsedQs, key: string): string[] { const property = qs[key] as string | string[]; diff --git a/package-lock.json b/package-lock.json index e936b6da..700c3f90 100644 --- a/package-lock.json +++ b/package-lock.json @@ -79,6 +79,7 @@ "colors": "^1.4.0", "crc": "^4.3.2", "express": "^4.17.1", + "express-async-errors": "^3.1.1", "express-prom-bundle": "^7.0.2", "express-subdomain": "^1.0.5", "fs-extra": "^9.0.0", @@ -7047,6 +7048,15 @@ "url": "https://opencollective.com/express" } }, + "node_modules/express-async-errors": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/express-async-errors/-/express-async-errors-3.1.1.tgz", + "integrity": "sha512-h6aK1da4tpqWSbyCa3FxB/V6Ehd4EEB15zyQq9qe75OZBp0krinNKuH4rAY+S/U/2I36vdLAUFSjQJ+TFmODng==", + "license": "ISC", + "peerDependencies": { + "express": "^4.16.2" + } + }, "node_modules/express-prom-bundle": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/express-prom-bundle/-/express-prom-bundle-7.0.2.tgz", From d9f70e9ca8c646d711f4bc149d3a26bacc202efe Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Fri, 16 May 2025 23:29:19 +1000 Subject: [PATCH 008/189] feat(internal): Check for banned accounts --- .../internal/middleware/authentication.ts | 4 ++++ .../internal/middleware/check-user-account.ts | 20 +++++++++++++++++++ .../src/services/internal/server.ts | 2 ++ 3 files changed, 26 insertions(+) create mode 100644 apps/miiverse-api/src/services/internal/middleware/check-user-account.ts diff --git a/apps/miiverse-api/src/services/internal/middleware/authentication.ts b/apps/miiverse-api/src/services/internal/middleware/authentication.ts index b8019d04..69e69b9f 100644 --- a/apps/miiverse-api/src/services/internal/middleware/authentication.ts +++ b/apps/miiverse-api/src/services/internal/middleware/authentication.ts @@ -4,6 +4,10 @@ import { getUserSettings } from '@/database'; import type express from 'express'; import type { AccountData } from '@/types/common/account-data'; +/** + * Handles authentication for service (NNAS/console) and OAuth (web) tokens. Sets locals.account to AccountData. + * Will error if tokens bad or account nonexistent, but otherwise does not check bans or setup status. + */ async function auth(request: express.Request, response: express.Response, next: express.NextFunction): Promise { // Used by console applets const serviceToken = getValueFromHeaders(request.headers, 'x-service-token'); diff --git a/apps/miiverse-api/src/services/internal/middleware/check-user-account.ts b/apps/miiverse-api/src/services/internal/middleware/check-user-account.ts new file mode 100644 index 00000000..e141efd9 --- /dev/null +++ b/apps/miiverse-api/src/services/internal/middleware/check-user-account.ts @@ -0,0 +1,20 @@ +import { errors } from '@/services/internal/errors'; +import type express from 'express'; +import type { AccountData } from '@/types/common/account-data'; + +/** + * Checks the user account is valid for this request (not banned, setup complete, etc.) + */ +async function checkUserAccount(request: express.Request, response: express.Response, next: express.NextFunction): Promise { + const account = response.locals!.account as AccountData; + + if (account.pnid.accessLevel < 0) { + throw new errors.unauthorized('Account has been banned'); + } + + // TODO account settings, temp bans, etc. + + return next(); +} + +export default checkUserAccount; diff --git a/apps/miiverse-api/src/services/internal/server.ts b/apps/miiverse-api/src/services/internal/server.ts index 56a812f6..32515f55 100644 --- a/apps/miiverse-api/src/services/internal/server.ts +++ b/apps/miiverse-api/src/services/internal/server.ts @@ -5,6 +5,7 @@ import { MiiverseServiceDefinition } from '@repo/grpc-client/out/miiverse_servic import { config } from '@/config'; import { internalApiRouter } from '@/services/internal'; import authentication from '@/services/internal/middleware/authentication'; +import checkUserAccount from '@/services/internal/middleware/check-user-account'; import { logger } from '@/logger'; import { InternalAPIError } from '@/services/internal/errors'; import { loggerHttp } from '@/loggerHttp'; @@ -16,6 +17,7 @@ const app = express(); app.use(express.json()); app.use(loggerHttp); app.use(authentication); +app.use(checkUserAccount); app.use(internalApiRouter); // API error handler From 06ab5620ea1a9f56adf18ac56be74b61ffed7dc7 Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Sat, 17 May 2025 00:16:20 +1000 Subject: [PATCH 009/189] feat(internal): WIP posts endpoint (auth not working) --- apps/juxtaposition-ui/src/fetch.ts | 15 +++++++++++++-- .../src/middleware/consoleAuth.js | 3 +++ .../src/services/juxt-web/routes/console/posts.js | 3 ++- apps/miiverse-api/src/services/internal/errors.ts | 1 + .../src/services/internal/routes/posts.ts | 15 +++++++++++++++ 5 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 apps/miiverse-api/src/services/internal/routes/posts.ts diff --git a/apps/juxtaposition-ui/src/fetch.ts b/apps/juxtaposition-ui/src/fetch.ts index 17307ad5..0968a159 100644 --- a/apps/juxtaposition-ui/src/fetch.ts +++ b/apps/juxtaposition-ui/src/fetch.ts @@ -31,10 +31,21 @@ export async function apiFetch(path: string, options?: FetchOptions): Promise metadata }); - // TODO don't throw away the response payload here if (isErrorHttpStatus(response.status)) { - throw new Error(`HTTP error! status: ${response.status}`); + throw new Error(`HTTP error! status: ${response.status} ${response.payload}`); } return JSON.parse(response.payload) as T; } + +export async function apiFetchUser(request: any, path: string, options?: FetchOptions): Promise { + options = { + ...options, + headers: { + 'x-service-token': request.serviceToken, + 'x-oauth-token': request.token, + ...options?.headers + } + }; + return apiFetch(path, options); +} diff --git a/apps/juxtaposition-ui/src/middleware/consoleAuth.js b/apps/juxtaposition-ui/src/middleware/consoleAuth.js index 36f815e1..5a0bf63a 100644 --- a/apps/juxtaposition-ui/src/middleware/consoleAuth.js +++ b/apps/juxtaposition-ui/src/middleware/consoleAuth.js @@ -7,12 +7,15 @@ async function auth(request, response, next) { if (request.session && request.session.user && request.session.pid && !request.isWrite) { request.user = request.session.user; request.pid = request.session.pid; + request.serviceToken = request.session.serviceToken; } else { request.pid = request.headers['x-nintendo-servicetoken'] ? await util.processServiceToken(request.headers['x-nintendo-servicetoken']) : null; request.user = request.pid ? await util.getUserDataFromPid(request.pid) : null; + request.serviceToken = request.headers['x-nintendo-servicetoken']; request.session.user = request.user; request.session.pid = request.pid; + request.session.serviceToken = request.serviceToken; } // Set headers diff --git a/apps/juxtaposition-ui/src/services/juxt-web/routes/console/posts.js b/apps/juxtaposition-ui/src/services/juxt-web/routes/console/posts.js index f4ab3035..c0f792ef 100644 --- a/apps/juxtaposition-ui/src/services/juxt-web/routes/console/posts.js +++ b/apps/juxtaposition-ui/src/services/juxt-web/routes/console/posts.js @@ -12,6 +12,7 @@ const upload = multer({ dest: 'uploads/' }); const redis = require('@/redisCache'); const { config } = require('@/config'); const router = express.Router(); +const { apiFetchUser } = require('@/fetch'); const postLimit = rateLimit({ windowMs: 15 * 1000, // 30 seconds @@ -108,7 +109,7 @@ router.post('/new', postLimit, upload.none(), async function (req, res) { router.get('/:post_id', async function (req, res) { const userSettings = await database.getUserSettings(req.pid); const userContent = await database.getUserContent(req.pid); - let post = await database.getPostByID(req.params.post_id.toString()); + let post = await apiFetchUser(req, `/api/v1/posts/${req.params.post_id}`); if (post === null) { return res.redirect('/404'); } diff --git a/apps/miiverse-api/src/services/internal/errors.ts b/apps/miiverse-api/src/services/internal/errors.ts index 44b74909..fa4a6aa2 100644 --- a/apps/miiverse-api/src/services/internal/errors.ts +++ b/apps/miiverse-api/src/services/internal/errors.ts @@ -11,6 +11,7 @@ export const errors = { badRequest: InternalAPIError.bind(null, 400), unauthorized: InternalAPIError.bind(null, 401), forbidden: InternalAPIError.bind(null, 403), + notFound: InternalAPIError.bind(null, 404), serverError: InternalAPIError.bind(null, 500) }; diff --git a/apps/miiverse-api/src/services/internal/routes/posts.ts b/apps/miiverse-api/src/services/internal/routes/posts.ts new file mode 100644 index 00000000..0c07adf5 --- /dev/null +++ b/apps/miiverse-api/src/services/internal/routes/posts.ts @@ -0,0 +1,15 @@ +import express from 'express'; +import { getPostByID } from '@/database'; +import { errors } from '@/services/internal/errors'; +import { handle } from '@/services/internal/utils'; + +export const postsRouter = express.Router(); + +postsRouter.get('/:post_id', handle(async ({ req }) => { + const post = await getPostByID(req.params.post_id); + if (!post || post.removed) { + throw new errors.notFound('Post not found'); + } + + return post; +})); From 2be4de289eda200e201771d4ba673b5e8f8dc12d Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Sat, 24 May 2025 22:55:30 +1000 Subject: [PATCH 010/189] fix(ui): Don't crash on promise rejection (please) This worked well for miiverse-api. It still just spits the stacktrace into the browser, but hey, at least it doesn't crash the server process --- apps/juxtaposition-ui/package.json | 1 + apps/juxtaposition-ui/src/server.js | 1 + package-lock.json | 1 + 3 files changed, 3 insertions(+) diff --git a/apps/juxtaposition-ui/package.json b/apps/juxtaposition-ui/package.json index 3d6a8b50..85542987 100644 --- a/apps/juxtaposition-ui/package.json +++ b/apps/juxtaposition-ui/package.json @@ -26,6 +26,7 @@ "ejs": "^3.1.10", "esbuild-plugin-copy": "^2.1.1", "express": "^4.21.2", + "express-async-errors": "^3.1.1", "express-prom-bundle": "^7.0.2", "express-rate-limit": "^7.5.0", "express-session": "^1.18.1", diff --git a/apps/juxtaposition-ui/src/server.js b/apps/juxtaposition-ui/src/server.js index c294d98e..bc97e38a 100644 --- a/apps/juxtaposition-ui/src/server.js +++ b/apps/juxtaposition-ui/src/server.js @@ -3,6 +3,7 @@ const cookieParser = require('cookie-parser'); const session = require('express-session'); const { RedisStore } = require('connect-redis'); const expressMetrics = require('express-prom-bundle'); +require('express-async-errors'); // See package docs const database = require('@/database'); const { logger } = require('@/logger'); const { loggerHttp } = require('@/loggerHttp'); diff --git a/package-lock.json b/package-lock.json index 700c3f90..42ec89d5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,6 +27,7 @@ "ejs": "^3.1.10", "esbuild-plugin-copy": "^2.1.1", "express": "^4.21.2", + "express-async-errors": "^3.1.1", "express-prom-bundle": "^7.0.2", "express-rate-limit": "^7.5.0", "express-session": "^1.18.1", From fc8204c77f239d418c63d97952db741fff81f122 Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Sat, 24 May 2025 23:04:10 +1000 Subject: [PATCH 011/189] fix(internal): enable posts route i'm not stupid i'm smart --- .../src/services/juxt-web/routes/console/posts.js | 2 +- apps/miiverse-api/src/services/internal/index.ts | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/services/juxt-web/routes/console/posts.js b/apps/juxtaposition-ui/src/services/juxt-web/routes/console/posts.js index c0f792ef..72b10dfa 100644 --- a/apps/juxtaposition-ui/src/services/juxt-web/routes/console/posts.js +++ b/apps/juxtaposition-ui/src/services/juxt-web/routes/console/posts.js @@ -114,7 +114,7 @@ router.get('/:post_id', async function (req, res) { return res.redirect('/404'); } if (post.parent) { - post = await database.getPostByID(post.parent); + post = await apiFetchUser(req, `/api/v1/posts/${post.parent}`); if (post === null) { return res.sendStatus(404); } diff --git a/apps/miiverse-api/src/services/internal/index.ts b/apps/miiverse-api/src/services/internal/index.ts index 96ffa763..b8c41cbb 100644 --- a/apps/miiverse-api/src/services/internal/index.ts +++ b/apps/miiverse-api/src/services/internal/index.ts @@ -1,5 +1,7 @@ import express from 'express'; import { testRouter } from '@/services/internal/routes/test'; +import { postsRouter } from '@/services/internal/routes/posts'; export const internalApiRouter = express.Router(); internalApiRouter.use('/api/v1', testRouter); +internalApiRouter.use('/api/v1/posts', postsRouter); From 5c91b11aa536daaf9d7f6905772ecd77096aad45 Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Sun, 8 Jun 2025 15:58:57 +1000 Subject: [PATCH 012/189] fix(server): Fix incorrect Express error handler --- apps/juxtaposition-ui/src/server.js | 22 ++++++++++++------- .../src/webfiles/web/error.ejs | 6 +++-- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/apps/juxtaposition-ui/src/server.js b/apps/juxtaposition-ui/src/server.js index bc97e38a..85a40772 100644 --- a/apps/juxtaposition-ui/src/server.js +++ b/apps/juxtaposition-ui/src/server.js @@ -76,23 +76,29 @@ app.use(juxt_web); logger.info('Creating 404 status handler'); app.use((req, res) => { req.log.warn('Page not found'); + res.status(404); res.render(req.directory + '/error.ejs', { code: 404, - message: 'Page not found' + message: 'Page not found', + id: req.id }); }); // non-404 error handler logger.info('Creating non-404 status handler'); -app.use((error, request, response) => { - const status = error.status || 500; +app.use((error, req, res, next) => { + if (res.headersSent) { + return next(error); + } - response.status(status); + const status = error.status || 500; + res.status(status); - response.json({ - app: 'api', - status, - error: error.message + req.log.error(error, 'Request failed!'); + res.render(req.directory + '/error.ejs', { + code: status, + message: 'Error', + id: req.id }); }); diff --git a/apps/juxtaposition-ui/src/webfiles/web/error.ejs b/apps/juxtaposition-ui/src/webfiles/web/error.ejs index 516e7086..d3d298dc 100644 --- a/apps/juxtaposition-ui/src/webfiles/web/error.ejs +++ b/apps/juxtaposition-ui/src/webfiles/web/error.ejs @@ -2,7 +2,7 @@ - Juxtaposition Log In + Juxt - Error @@ -67,7 +67,9 @@

<%= code %>: <%= message %>

-

View current server status here.

+

View current server status.

+

Or, go back to the homepage.

+

Request ID: <%= id %>

From 952c7583d778aea90075c0a8c39e518e386aeb33 Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Sun, 8 Jun 2025 16:07:28 +1000 Subject: [PATCH 013/189] feat(internal): Validate and use posts endpoint, tweak tokens handling some callsites to the old database method still exist, since the helpers on Post are used for things the backend doesn't have yet it's annoying to pass the whole Express request so just have a blob object for the things that the user is authenticated with --- apps/juxtaposition-ui/package.json | 3 +- apps/juxtaposition-ui/src/backend.ts | 10 +++ apps/juxtaposition-ui/src/fetch.ts | 29 +++++++-- .../src/middleware/consoleAuth.js | 6 +- .../src/middleware/webAuth.js | 2 +- apps/juxtaposition-ui/src/models/api/post.ts | 61 +++++++++++++++++++ .../services/juxt-web/routes/console/posts.js | 19 +++--- package-lock.json | 10 +-- 8 files changed, 114 insertions(+), 26 deletions(-) create mode 100644 apps/juxtaposition-ui/src/backend.ts create mode 100644 apps/juxtaposition-ui/src/models/api/post.ts diff --git a/apps/juxtaposition-ui/package.json b/apps/juxtaposition-ui/package.json index 85542987..82bc35c9 100644 --- a/apps/juxtaposition-ui/package.json +++ b/apps/juxtaposition-ui/package.json @@ -50,7 +50,8 @@ "redis": "^4.7.0", "sharp": "^0.33.5", "tga": "^1.0.7", - "tsx": "^4.19.3" + "tsx": "^4.19.3", + "zod": "^3.25.56" }, "devDependencies": { "@pretendonetwork/eslint-config": "^0.0.8", diff --git a/apps/juxtaposition-ui/src/backend.ts b/apps/juxtaposition-ui/src/backend.ts new file mode 100644 index 00000000..3ed71d4e --- /dev/null +++ b/apps/juxtaposition-ui/src/backend.ts @@ -0,0 +1,10 @@ +import { apiFetchUser } from '@/fetch'; +import { PostSchema } from '@/models/api/post'; +import type { UserTokens } from '@/fetch'; +import type { Post } from '@/models/api/post'; + +export async function getPostById(tokens: UserTokens, post_id: string): Promise { + const data = await apiFetchUser(tokens, `/api/v1/posts/${post_id}`); + const post = await PostSchema.parseAsync(data); // todo: what to do on validation fail..? + return post; +} diff --git a/apps/juxtaposition-ui/src/fetch.ts b/apps/juxtaposition-ui/src/fetch.ts index 0968a159..0ffe4050 100644 --- a/apps/juxtaposition-ui/src/fetch.ts +++ b/apps/juxtaposition-ui/src/fetch.ts @@ -1,13 +1,27 @@ import { Metadata } from 'nice-grpc'; import { config } from '@/config'; import { grpcClient } from '@/grpc'; +import type { PacketResponse } from '@repo/grpc-client/out/packet'; export type FetchOptions = { method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH'; - headers?: Record; + headers?: Record; body?: Record | undefined | null; }; +export interface FetchError extends Error { + name: 'FetchError'; + status: number; + response: any; +} +function FetchError(response: PacketResponse, message: string): FetchError { + const error = new Error(message) as FetchError; + error.name = 'FetchError'; + error.status = response.status; + error.response = response.payload; // parse json? + return error; +} + function isErrorHttpStatus(status: number): boolean { return status >= 400 && status < 600; } @@ -32,18 +46,23 @@ export async function apiFetch(path: string, options?: FetchOptions): Promise }); if (isErrorHttpStatus(response.status)) { - throw new Error(`HTTP error! status: ${response.status} ${response.payload}`); + throw FetchError(response, `HTTP error! status: ${response.status} ${response.payload}`); } return JSON.parse(response.payload) as T; } -export async function apiFetchUser(request: any, path: string, options?: FetchOptions): Promise { +export type UserTokens = { + serviceToken?: string; + oauthToken?: string; +}; + +export async function apiFetchUser(tokens: UserTokens, path: string, options?: FetchOptions): Promise { options = { ...options, headers: { - 'x-service-token': request.serviceToken, - 'x-oauth-token': request.token, + 'x-service-token': tokens.serviceToken, + 'x-oauth-token': tokens.oauthToken, ...options?.headers } }; diff --git a/apps/juxtaposition-ui/src/middleware/consoleAuth.js b/apps/juxtaposition-ui/src/middleware/consoleAuth.js index 5a0bf63a..2c74c3cb 100644 --- a/apps/juxtaposition-ui/src/middleware/consoleAuth.js +++ b/apps/juxtaposition-ui/src/middleware/consoleAuth.js @@ -7,15 +7,15 @@ async function auth(request, response, next) { if (request.session && request.session.user && request.session.pid && !request.isWrite) { request.user = request.session.user; request.pid = request.session.pid; - request.serviceToken = request.session.serviceToken; + request.tokens = request.session.tokens; } else { + request.tokens = { serviceToken: request.headers['x-nintendo-servicetoken'] }; request.pid = request.headers['x-nintendo-servicetoken'] ? await util.processServiceToken(request.headers['x-nintendo-servicetoken']) : null; request.user = request.pid ? await util.getUserDataFromPid(request.pid) : null; - request.serviceToken = request.headers['x-nintendo-servicetoken']; request.session.user = request.user; request.session.pid = request.pid; - request.session.serviceToken = request.serviceToken; + request.session.tokens = request.tokens; } // Set headers diff --git a/apps/juxtaposition-ui/src/middleware/webAuth.js b/apps/juxtaposition-ui/src/middleware/webAuth.js index 518bd65e..a772a402 100644 --- a/apps/juxtaposition-ui/src/middleware/webAuth.js +++ b/apps/juxtaposition-ui/src/middleware/webAuth.js @@ -31,7 +31,7 @@ async function webAuth(request, response, next) { } } - request.token = request.cookies.access_token; + request.tokens = { oauthToken: request.cookies.access_token }; // Open access pages if (isStartOfPath(request.path, '/users/') || diff --git a/apps/juxtaposition-ui/src/models/api/post.ts b/apps/juxtaposition-ui/src/models/api/post.ts new file mode 100644 index 00000000..9494a893 --- /dev/null +++ b/apps/juxtaposition-ui/src/models/api/post.ts @@ -0,0 +1,61 @@ +import { z } from 'zod'; + +const zBoolNumber = z.union([z.literal(0), z.literal(1)]); +// there are exactly two posts (of 550K) in the DB with IDs that are not 21 chars +const zPostId = z.string().min(19).max(22); +/* This schema (specifically the types and optionals) is trying to be 1:1 to the existing MongoDB, + * with the intent that we can incrementally fix it as the db is improved. + * The intent is to not do any transformation here, yet. + */ +export const PostSchema = z.object({ + id: zPostId, + title_id: z.string().optional(), // u64 + screen_name: z.string(), + body: z.string(), + app_data: z.string().optional(), // TODO nintendo base64 + + // base64, '' for posts without, undef for PMs + painting: z.string().optional(), + // URL fragment, '' for posts without, undef for PMs + screenshot: z.union([z.literal(''), z.string().startsWith('/')]).optional(), + screenshot_length: z.number().optional(), + + // sometimes missing, sometimes empty + search_key: z.array(z.string()).optional(), + // sometimes missing, sometimes empty + topic_tag: z.string().optional(), + + community_id: z.string(), // i64? + created_at: z.coerce.date(), + // missing on PMs + feeling_id: z.number().optional(), // todo enum + + is_autopost: zBoolNumber, // boolean + is_community_private_autopost: zBoolNumber, // boolean + is_spoiler: zBoolNumber, // boolean + is_app_jumpable: zBoolNumber, // boolean + + empathy_count: z.number().nonnegative(), + country_id: z.number(), + language_id: z.number(), + + mii: z.string(), // .base64(), TODO nintendo base64 + mii_face_url: z.string().url(), + + pid: z.number(), + platform_id: z.number().optional(), // missing on PMs + region_id: z.number().optional(), // missing on PMs + parent: zPostId.optional().nullable(), // both missing and null exist + + reply_count: z.number().nonnegative(), + verified: z.boolean(), + + message_to_pid: z.number().nullable(), + removed: z.boolean(), + removed_by: z.number().optional(), // pid + removed_at: z.coerce.date().optional(), + removed_reason: z.string().optional(), + yeahs: z.array(z.number()) +}); + +export type Post = z.infer; diff --git a/apps/juxtaposition-ui/src/services/juxt-web/routes/console/posts.js b/apps/juxtaposition-ui/src/services/juxt-web/routes/console/posts.js index 72b10dfa..61cfb540 100644 --- a/apps/juxtaposition-ui/src/services/juxt-web/routes/console/posts.js +++ b/apps/juxtaposition-ui/src/services/juxt-web/routes/console/posts.js @@ -12,7 +12,7 @@ const upload = multer({ dest: 'uploads/' }); const redis = require('@/redisCache'); const { config } = require('@/config'); const router = express.Router(); -const { apiFetchUser } = require('@/fetch'); +const backend = require('@/backend'); const postLimit = rateLimit({ windowMs: 15 * 1000, // 30 seconds @@ -42,7 +42,7 @@ const yeahLimit = rateLimit({ }); router.get('/:post_id/oembed.json', async function (req, res) { - const post = await database.getPostByID(req.params.post_id.toString()); + const post = await backend.getPostById(req.tokens, req.params.post_id); const doc = { author_name: post.screen_name, author_url: 'https://juxt.pretendo.network/users/show?pid=' + post.pid @@ -109,16 +109,11 @@ router.post('/new', postLimit, upload.none(), async function (req, res) { router.get('/:post_id', async function (req, res) { const userSettings = await database.getUserSettings(req.pid); const userContent = await database.getUserContent(req.pid); - let post = await apiFetchUser(req, `/api/v1/posts/${req.params.post_id}`); - if (post === null) { - return res.redirect('/404'); - } + + const post = await backend.getPostById(req.tokens, req.params.post_id); if (post.parent) { - post = await apiFetchUser(req, `/api/v1/posts/${post.parent}`); - if (post === null) { - return res.sendStatus(404); - } - return res.redirect(`/posts/${post.id}`); + const parent = await backend.getPostById(req.tokens, post.parent); + return res.redirect(`/posts/${parent.id}`); } const community = await database.getCommunityByID(post.community_id); const communityMap = await util.getCommunityHash(); @@ -166,7 +161,7 @@ router.post('/:post_id/new', postLimit, upload.none(), async function (req, res) router.post('/:post_id/report', upload.none(), async function (req, res) { const { reason, message, post_id } = req.body; - const post = await database.getPostByID(post_id); + const post = await backend.getPostByID(req.tokens, post_id); if (!reason || !post_id || !post) { return res.redirect('/404'); } diff --git a/package-lock.json b/package-lock.json index 42ec89d5..4bb26ec8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -51,7 +51,8 @@ "redis": "^4.7.0", "sharp": "^0.33.5", "tga": "^1.0.7", - "tsx": "^4.19.3" + "tsx": "^4.19.3", + "zod": "^3.25.56" }, "devDependencies": { "@pretendonetwork/eslint-config": "^0.0.8", @@ -13837,9 +13838,10 @@ } }, "node_modules/zod": { - "version": "3.24.4", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.4.tgz", - "integrity": "sha512-OdqJE9UDRPwWsrHjLN2F8bPxvwJBK22EHLWtanu0LSYr5YqzsaaW3RMgmjwr8Rypg5k+meEJdSPXJZXE/yqOMg==", + "version": "3.25.56", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.56.tgz", + "integrity": "sha512-rd6eEF3BTNvQnR2e2wwolfTmUTnp70aUTqr0oaGbHifzC3BKJsoV+Gat8vxUMR1hwOKBs6El+qWehrHbCpW6SQ==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/colinhacks" } From 771b6498f3564a8a5b4b0886889690de32e55231 Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Sun, 8 Jun 2025 17:54:20 +1000 Subject: [PATCH 014/189] feat(internal): Set up guest access controls per-endpoint --- .../middleware/authenticated-endpoints.ts | 39 +++++++++++++++++++ .../internal/middleware/authentication.ts | 3 +- .../internal/middleware/check-user-account.ts | 7 +++- .../src/services/internal/routes/posts.ts | 3 +- .../src/services/internal/routes/test.ts | 3 +- apps/miiverse-api/src/types/express.d.ts | 5 +++ 6 files changed, 55 insertions(+), 5 deletions(-) create mode 100644 apps/miiverse-api/src/services/internal/middleware/authenticated-endpoints.ts diff --git a/apps/miiverse-api/src/services/internal/middleware/authenticated-endpoints.ts b/apps/miiverse-api/src/services/internal/middleware/authenticated-endpoints.ts new file mode 100644 index 00000000..814659a1 --- /dev/null +++ b/apps/miiverse-api/src/services/internal/middleware/authenticated-endpoints.ts @@ -0,0 +1,39 @@ +import { errors } from '@/services/internal/errors'; +import type express from 'express'; + +/** + * Guest access is fine + */ +export async function authGuest(request: express.Request, response: express.Response, next: express.NextFunction): Promise { + return next(); +} + +/** + * Fail on guest access + */ +export async function authUsers(request: express.Request, response: express.Response, next: express.NextFunction): Promise { + const account = response.locals.account; + if (account === null) { + // Guest access + throw new errors.unauthorized('Authentication token not provided'); + } + + return next(); +} + +/** + * Moderators only + */ +export async function authModerators(request: express.Request, response: express.Response, next: express.NextFunction): Promise { + const account = response.locals.account; + if (account === null) { + // Guest access + throw new errors.unauthorized('Authentication token not provided'); + } + + if (account.pnid.accessLevel < 2) { + throw new errors.forbidden('You cannot access this endpoint'); + } + + return next(); +} diff --git a/apps/miiverse-api/src/services/internal/middleware/authentication.ts b/apps/miiverse-api/src/services/internal/middleware/authentication.ts index 69e69b9f..0a76b6ac 100644 --- a/apps/miiverse-api/src/services/internal/middleware/authentication.ts +++ b/apps/miiverse-api/src/services/internal/middleware/authentication.ts @@ -23,7 +23,8 @@ async function auth(request: express.Request, response: express.Response, next: } else if (oAuthToken) { response.locals.account = await webAuth(oAuthToken); } else { - throw new errors.unauthorized('Authentication token not provided'); + // Guest access + response.locals.account = null; } return next(); diff --git a/apps/miiverse-api/src/services/internal/middleware/check-user-account.ts b/apps/miiverse-api/src/services/internal/middleware/check-user-account.ts index e141efd9..e6bb08cf 100644 --- a/apps/miiverse-api/src/services/internal/middleware/check-user-account.ts +++ b/apps/miiverse-api/src/services/internal/middleware/check-user-account.ts @@ -1,12 +1,15 @@ import { errors } from '@/services/internal/errors'; import type express from 'express'; -import type { AccountData } from '@/types/common/account-data'; /** * Checks the user account is valid for this request (not banned, setup complete, etc.) */ async function checkUserAccount(request: express.Request, response: express.Response, next: express.NextFunction): Promise { - const account = response.locals!.account as AccountData; + const account = response.locals.account; + if (account === null) { + // Guest access + return next(); + } if (account.pnid.accessLevel < 0) { throw new errors.unauthorized('Account has been banned'); diff --git a/apps/miiverse-api/src/services/internal/routes/posts.ts b/apps/miiverse-api/src/services/internal/routes/posts.ts index 0c07adf5..980354eb 100644 --- a/apps/miiverse-api/src/services/internal/routes/posts.ts +++ b/apps/miiverse-api/src/services/internal/routes/posts.ts @@ -2,10 +2,11 @@ import express from 'express'; import { getPostByID } from '@/database'; import { errors } from '@/services/internal/errors'; import { handle } from '@/services/internal/utils'; +import { authGuest } from '@/services/internal/middleware/authenticated-endpoints'; export const postsRouter = express.Router(); -postsRouter.get('/:post_id', handle(async ({ req }) => { +postsRouter.get('/:post_id', authGuest, handle(async ({ req }) => { const post = await getPostByID(req.params.post_id); if (!post || post.removed) { throw new errors.notFound('Post not found'); diff --git a/apps/miiverse-api/src/services/internal/routes/test.ts b/apps/miiverse-api/src/services/internal/routes/test.ts index 297cee54..feeace02 100644 --- a/apps/miiverse-api/src/services/internal/routes/test.ts +++ b/apps/miiverse-api/src/services/internal/routes/test.ts @@ -1,9 +1,10 @@ import express from 'express'; import { handle } from '@/services/internal/utils'; +import { authUsers } from '@/services/internal/middleware/authenticated-endpoints'; export const testRouter = express.Router(); -testRouter.get('/test', handle(async () => { +testRouter.get('/test', authUsers, handle(async () => { return { message: 'Hello from the test route!' }; diff --git a/apps/miiverse-api/src/types/express.d.ts b/apps/miiverse-api/src/types/express.d.ts index 1782a372..31150624 100644 --- a/apps/miiverse-api/src/types/express.d.ts +++ b/apps/miiverse-api/src/types/express.d.ts @@ -1,6 +1,7 @@ import type { ParamPack } from '@/types/common/param-pack'; import type { GetUserDataResponse } from '@pretendonetwork/grpc/account/get_user_data_rpc'; import type { ApiErrorCode } from '@/errors'; +import type { AccountData } from '@/types/common/account-data'; declare global { namespace Express { @@ -13,5 +14,9 @@ declare global { interface Response { errorCode?: ApiErrorCode; } + // Locals used in internal/grpc + interface Locals { + account: AccountData | null; + } } } From 126378b7840d7b7515333211ccbe44cb040888a3 Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Sun, 8 Jun 2025 18:07:23 +1000 Subject: [PATCH 015/189] fix(server): Force re-login if backend rejects user token --- apps/juxtaposition-ui/src/middleware/webAuth.js | 2 +- apps/juxtaposition-ui/src/server.js | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/middleware/webAuth.js b/apps/juxtaposition-ui/src/middleware/webAuth.js index a772a402..788abf47 100644 --- a/apps/juxtaposition-ui/src/middleware/webAuth.js +++ b/apps/juxtaposition-ui/src/middleware/webAuth.js @@ -24,7 +24,7 @@ async function webAuth(request, response, next) { response.clearCookie('token_type', { domain: cookieDomain, path: '/' }); if (request.path === '/login') { response.locals.lang = util.processLanguage(); - request.token = request.cookies.access_token; + request.tokens = {}; request.paramPackData = null; return next(); } diff --git a/apps/juxtaposition-ui/src/server.js b/apps/juxtaposition-ui/src/server.js index 85a40772..cbc34dfd 100644 --- a/apps/juxtaposition-ui/src/server.js +++ b/apps/juxtaposition-ui/src/server.js @@ -91,6 +91,13 @@ app.use((error, req, res, next) => { return next(error); } + // small hack because token expiry is weird + if (error.status === 401) { + req.session.user = undefined; + req.session.pid = undefined; + return res.redirect('/login'); + } + const status = error.status || 500; res.status(status); From 9668d68ede524368e428b23c41b2dca2e51cc4d4 Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Sun, 8 Jun 2025 18:20:31 +1000 Subject: [PATCH 016/189] feat(ui): Support redirecting out of the login page --- apps/juxtaposition-ui/src/server.js | 2 +- .../src/services/juxt-web/routes/web/login.js | 14 +++++++------- apps/juxtaposition-ui/src/webfiles/web/login.ejs | 1 + 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/apps/juxtaposition-ui/src/server.js b/apps/juxtaposition-ui/src/server.js index cbc34dfd..08c3796f 100644 --- a/apps/juxtaposition-ui/src/server.js +++ b/apps/juxtaposition-ui/src/server.js @@ -95,7 +95,7 @@ app.use((error, req, res, next) => { if (error.status === 401) { req.session.user = undefined; req.session.pid = undefined; - return res.redirect('/login'); + return res.redirect(`/login?redirect=${req.originalUrl}`); } const status = error.status || 500; diff --git a/apps/juxtaposition-ui/src/services/juxt-web/routes/web/login.js b/apps/juxtaposition-ui/src/services/juxt-web/routes/web/login.js index 5aa45725..b4cf4cce 100644 --- a/apps/juxtaposition-ui/src/services/juxt-web/routes/web/login.js +++ b/apps/juxtaposition-ui/src/services/juxt-web/routes/web/login.js @@ -8,22 +8,22 @@ const { logger } = require('@/logger'); const cookieDomain = config.http.cookieDomain; router.get('/', async function (req, res) { - res.render(req.directory + '/login.ejs', { toast: null }); + res.render(req.directory + '/login.ejs', { toast: null, redirect: req.query.redirect ?? '/' }); }); router.post('/', async (req, res) => { - const { username, password } = req.body; + const { username, password, redirect } = req.body; const login = await util.login(username, password).catch((e) => { switch (e.details) { case 'INVALID_ARGUMENT: User not found': - res.render(req.directory + '/login.ejs', { toast: 'Username was invalid.' }); + res.render(req.directory + '/login.ejs', { toast: 'Username was invalid.', redirect }); break; case 'INVALID_ARGUMENT: Password is incorrect': - res.render(req.directory + '/login.ejs', { toast: 'Password was incorrect.' }); + res.render(req.directory + '/login.ejs', { toast: 'Password was incorrect.', redirect }); break; default: logger.error(e, `Login error for ${username}`); - res.render(req.directory + '/login.ejs', { toast: 'Invalid username or password.' }); + res.render(req.directory + '/login.ejs', { toast: 'Invalid username or password.', redirect }); break; } }); @@ -33,7 +33,7 @@ router.post('/', async (req, res) => { const PNID = await util.getUserDataFromToken(login.accessToken); if (!PNID) { - return res.render(req.directory + '/login.ejs', { toast: 'Invalid username or password.' }); + return res.render(req.directory + '/login.ejs', { toast: 'Invalid username or password.', redirect }); } let discovery = await database.getEndPoint(config.serverEnvironment); @@ -65,7 +65,7 @@ router.post('/', async (req, res) => { res.cookie('access_token', login.accessToken, { domain: cookieDomain, maxAge: expiration }); res.cookie('refresh_token', login.refreshToken, { domain: cookieDomain }); res.cookie('token_type', 'Bearer', { domain: cookieDomain }); - res.redirect('/'); + res.redirect(redirect); }); module.exports = router; diff --git a/apps/juxtaposition-ui/src/webfiles/web/login.ejs b/apps/juxtaposition-ui/src/webfiles/web/login.ejs index 308dc0da..9edc71a7 100644 --- a/apps/juxtaposition-ui/src/webfiles/web/login.ejs +++ b/apps/juxtaposition-ui/src/webfiles/web/login.ejs @@ -83,6 +83,7 @@ Don't have an account? + From 6d8eced05a4c7746389de56bb65406cc66b4c01c Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Tue, 10 Jun 2025 14:09:57 +1000 Subject: [PATCH 017/189] fix(login): Validate redirect path --- .../juxtaposition-ui/src/services/juxt-web/routes/web/login.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/services/juxt-web/routes/web/login.js b/apps/juxtaposition-ui/src/services/juxt-web/routes/web/login.js index b4cf4cce..294b9222 100644 --- a/apps/juxtaposition-ui/src/services/juxt-web/routes/web/login.js +++ b/apps/juxtaposition-ui/src/services/juxt-web/routes/web/login.js @@ -65,7 +65,8 @@ router.post('/', async (req, res) => { res.cookie('access_token', login.accessToken, { domain: cookieDomain, maxAge: expiration }); res.cookie('refresh_token', login.refreshToken, { domain: cookieDomain }); res.cookie('token_type', 'Bearer', { domain: cookieDomain }); - res.redirect(redirect); + + res.redirect(/^\/[^/.]/.test(redirect) ? redirect : '/'); }); module.exports = router; From 70907d2abbc5d63f97c64d6d0cb7862976478782 Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Wed, 11 Jun 2025 14:21:12 +1000 Subject: [PATCH 018/189] fix(api): Audit and fix schema to reflect real db I went through a copy of the prod db and found lots of optional fields that aren't marked as such, old documents missing fields, etc. Introduces an IPostInput type that accounts for the mongoose schema doing defaults and fixes, while also allowing IPost to reflect the real db type. Groundwork for a proper DTO structure. --- apps/miiverse-api/package.json | 2 +- apps/miiverse-api/src/database.ts | 4 +- apps/miiverse-api/src/models/post.ts | 91 +++++----- .../src/services/api/routes/communities.ts | 2 +- .../services/api/routes/friend_messages.ts | 8 +- .../src/services/api/routes/posts.ts | 4 +- apps/miiverse-api/src/types/mongoose/post.ts | 80 ++++++--- package-lock.json | 155 +++++++++++++++++- 8 files changed, 265 insertions(+), 81 deletions(-) diff --git a/apps/miiverse-api/package.json b/apps/miiverse-api/package.json index 46c6c494..0198fab0 100644 --- a/apps/miiverse-api/package.json +++ b/apps/miiverse-api/package.json @@ -26,7 +26,7 @@ "express-subdomain": "^1.0.5", "fs-extra": "^9.0.0", "moment": "^2.24.0", - "mongoose": "^6.10.1", + "mongoose": "^8.15.1", "multer": "^1.4.5-lts.1", "nice-grpc": "^2.1.12", "node-snowflake": "0.0.1", diff --git a/apps/miiverse-api/src/database.ts b/apps/miiverse-api/src/database.ts index 565857c8..f0f56d32 100644 --- a/apps/miiverse-api/src/database.ts +++ b/apps/miiverse-api/src/database.ts @@ -11,7 +11,7 @@ import type { HydratedConversationDocument } from '@/types/mongoose/conversation import type { HydratedContentDocument } from '@/types/mongoose/content'; import type { HydratedSettingsDocument } from '@/types/mongoose/settings'; import type { HydratedEndpointDocument } from '@/types/mongoose/endpoint'; -import type { HydratedPostDocument, IPost } from '@/types/mongoose/post'; +import type { HydratedPostDocument, IPostInput } from '@/types/mongoose/post'; import type { HydratedCommunityDocument } from '@/types/mongoose/community'; let connection: mongoose.Connection; @@ -97,7 +97,7 @@ export async function getPostReplies(postID: string, limit: number): Promise { +export async function getDuplicatePosts(pid: number, post: IPostInput): Promise { verifyConnected(); return Post.findOne({ diff --git a/apps/miiverse-api/src/models/post.ts b/apps/miiverse-api/src/models/post.ts index 11eb963a..9107011c 100644 --- a/apps/miiverse-api/src/models/post.ts +++ b/apps/miiverse-api/src/models/post.ts @@ -7,29 +7,28 @@ import type { HydratedCommunityDocument } from '@/types/mongoose/community'; import type { PostToJSONOptions } from '@/types/mongoose/post-to-json-options'; import type { PostData, PostPainting, PostScreenshot, PostTopicTag } from '@/types/miiverse/post'; +/* Constraints here (default, required etc.) apply to new documents being added + * See IPost for expected shape of query results + * If you add default: or required:, please also update IPost and IPostInput! + */ const PostSchema = new Schema({ - id: String, - title_id: String, - screen_name: String, - body: String, - app_data: String, - painting: String, - screenshot: String, - screenshot_length: Number, - search_key: { - type: [String], - default: undefined - }, - topic_tag: { - type: String, - default: undefined - }, - community_id: { - type: String, - default: undefined - }, - created_at: Date, - feeling_id: Number, + id: { type: String, required: true }, + title_id: { type: String }, + screen_name: { type: String, required: true }, + body: { type: String, required: true }, + app_data: { type: String }, + + painting: { type: String }, + screenshot: { type: String }, + screenshot_length: { type: Number }, + + search_key: { type: [String] }, + topic_tag: { type: String }, + + community_id: { type: String, required: true }, + created_at: { type: Date, required: true }, + feeling_id: { type: Number }, + is_autopost: { type: Number, default: 0 @@ -46,6 +45,7 @@ const PostSchema = new Schema({ type: Number, default: 0 }, + empathy_count: { type: Number, default: 0, @@ -59,12 +59,15 @@ const PostSchema = new Schema({ type: Number, default: 1 }, - mii: String, - mii_face_url: String, - pid: Number, - platform_id: Number, - region_id: Number, - parent: String, + + mii: { type: String, required: true }, + mii_face_url: { type: String, required: true }, + + pid: { type: Number, required: true }, + platform_id: { type: Number }, + region_id: { type: Number }, + parent: { type: String }, + reply_count: { type: Number, default: 0 @@ -73,17 +76,21 @@ const PostSchema = new Schema({ type: Boolean, default: false }, + message_to_pid: { type: String, default: null }, + removed: { type: Boolean, default: false }, - removed_reason: String, - yeahs: [Number], - number: Number + removed_reason: { type: String }, + removed_by: { type: Number }, + removed_at: { type: Date }, + + yeahs: { type: [Number], default: [] } }, { id: false // * Disables the .id() getter used by Mongoose in TypeScript. Needed to have our own .id field }); @@ -114,12 +121,12 @@ PostSchema.method('cleanedMiiData', function cleanedMiiDat return this.mii.replace(/[^A-Za-z0-9+/=]/g, '').replace(/[\n\r]+/gm, '').trim(); }); -PostSchema.method('cleanedPainting', function cleanedPainting(): string { - return this.painting.replace(/[\n\r]+/gm, '').trim(); +PostSchema.method('cleanedPainting', function cleanedPainting(): string | undefined { + return this.painting?.replace(/[\n\r]+/gm, '').trim(); }); -PostSchema.method('cleanedAppData', function cleanedAppData(): string { - return this.app_data.replace(/[^A-Za-z0-9+/=]/g, '').replace(/[\n\r]+/gm, '').trim(); +PostSchema.method('cleanedAppData', function cleanedAppData(): string | undefined { + return this.app_data?.replace(/[^A-Za-z0-9+/=]/g, '').replace(/[\n\r]+/gm, '').trim(); }); PostSchema.method('formatPainting', function formatPainting(): PostPainting | undefined { @@ -146,7 +153,7 @@ PostSchema.method('formatTopicTag', function formatTopicTa if (this.topic_tag?.trim()) { return { name: this.topic_tag, - title_id: this.title_id + title_id: this.title_id ?? '' }; } }); @@ -158,26 +165,26 @@ PostSchema.method('json', function json(options: PostToJSO community_id: this.community_id, // TODO - This sucks country_id: this.country_id, created_at: moment(this.created_at).format('YYYY-MM-DD HH:MM:SS'), - feeling_id: this.feeling_id, + feeling_id: this.feeling_id ?? 0, id: this.id, is_autopost: this.is_autopost ? 1 : 0, is_community_private_autopost: this.is_community_private_autopost ? 1 : 0, is_spoiler: this.is_spoiler ? 1 : 0, is_app_jumpable: this.is_app_jumpable ? 1 : 0, - empathy_count: this.empathy_count || 0, + empathy_count: this.empathy_count, language_id: this.language_id, mii: undefined, // * Conditionally set later mii_face_url: undefined, // * Conditionally set later number: 0, painting: this.formatPainting(), pid: this.pid, - platform_id: this.platform_id, - region_id: this.region_id, - reply_count: this.reply_count || 0, + platform_id: this.platform_id ?? 1, + region_id: this.region_id ?? 0, + reply_count: this.reply_count, screen_name: this.screen_name, screenshot: this.formatScreenshot(), topic_tag: undefined, // * Conditionally set later - title_id: this.title_id + title_id: this.title_id ?? '' }; if (options.app_data) { diff --git a/apps/miiverse-api/src/services/api/routes/communities.ts b/apps/miiverse-api/src/services/api/routes/communities.ts index 1d4479fa..af40c7c5 100644 --- a/apps/miiverse-api/src/services/api/routes/communities.ts +++ b/apps/miiverse-api/src/services/api/routes/communities.ts @@ -298,7 +298,7 @@ router.post('/', multer().none(), async function (request: express.Request, resp return badRequest(response, ApiErrorCode.CREATE_TOO_MANY_FAVORITES, 403); } - const communitiesCount = await Community.count(); + const communitiesCount = await Community.countDocuments(); const communityID = (parseInt(parentCommunity.community_id) + (5000 * communitiesCount)); // Change this to auto increment const community = await Community.create({ platform_id: 0, // WiiU diff --git a/apps/miiverse-api/src/services/api/routes/friend_messages.ts b/apps/miiverse-api/src/services/api/routes/friend_messages.ts index 8e9764d6..7d048510 100644 --- a/apps/miiverse-api/src/services/api/routes/friend_messages.ts +++ b/apps/miiverse-api/src/services/api/routes/friend_messages.ts @@ -245,20 +245,20 @@ router.get('/', async function (request: express.Request, response: express.Resp is_app_jumpable: message.is_app_jumpable, empathy_added: message.empathy_count, language_id: message.language_id, - message_to_pid: message.message_to_pid, + message_to_pid: message.message_to_pid ?? undefined, mii: message.mii, mii_face_url: message.mii_face_url, - number: message.number || 0, + number: 0, pid: message.pid, platform_id: message.platform_id || 0, region_id: message.region_id || 0, reply_count: message.reply_count, screen_name: message.screen_name, topic_tag: { - name: message.topic_tag, + name: message.topic_tag ?? '', title_id: 0 }, - title_id: message.title_id + title_id: message.title_id ?? '' } }); } diff --git a/apps/miiverse-api/src/services/api/routes/posts.ts b/apps/miiverse-api/src/services/api/routes/posts.ts index 9dde8a03..5d9c379a 100644 --- a/apps/miiverse-api/src/services/api/routes/posts.ts +++ b/apps/miiverse-api/src/services/api/routes/posts.ts @@ -22,7 +22,7 @@ import { Community } from '@/models/community'; import { config } from '@/config'; import { ApiErrorCode, badRequest, serverError } from '@/errors'; import type { PostRepliesResult } from '@/types/miiverse/post'; -import type { HydratedPostDocument } from '@/types/mongoose/post'; +import type { HydratedPostDocument, IPostInput } from '@/types/mongoose/post'; const newPostSchema = z.object({ community_id: z.string().optional(), @@ -312,7 +312,7 @@ async function newPost(request: express.Request, response: express.Response): Pr searchKey = [searchKey]; } - const document = { + const document: IPostInput = { id: '', // * This gets changed when saving the document for the first time title_id: request.paramPack.title_id, community_id: community.olive_community_id, diff --git a/apps/miiverse-api/src/types/mongoose/post.ts b/apps/miiverse-api/src/types/mongoose/post.ts index dffb3942..a9354c7d 100644 --- a/apps/miiverse-api/src/types/mongoose/post.ts +++ b/apps/miiverse-api/src/types/mongoose/post.ts @@ -3,41 +3,73 @@ import type { HydratedCommunityDocument } from '@/types/mongoose/community'; import type { PostToJSONOptions } from '@/types/mongoose/post-to-json-options'; import type { PostData, PostPainting, PostScreenshot, PostTopicTag } from '@/types/miiverse/post'; +/* This type needs to reflect "reality" as it is in the DB + * Thus, all the optionals, since some legacy documents are missing many fields + */ export interface IPost { id: string; - title_id: string; + title_id?: string; // u64 screen_name: string; body: string; - app_data: string; - painting: string; - screenshot: string; - screenshot_length: number; - search_key: string[]; - topic_tag: string; - community_id: string; + app_data?: string; // nintendo base64 + + painting?: string; // base64, can be empty or undefined + screenshot?: string; // url fragment (leading /), can be empty or undefined + screenshot_length?: number; + + search_key?: string[]; // can be empty or undefined + topic_tag?: string; + + community_id: string; // actually a number created_at: Date; - feeling_id: number; - is_autopost: number; - is_community_private_autopost?: number; - is_spoiler: number; - is_app_jumpable: number; - empathy_count?: number; + feeling_id?: number; // missing on PMs + + is_autopost: number; // 0 | 1 + is_community_private_autopost: number; // 0 | 1 + is_spoiler: number; // 0 | 1 + is_app_jumpable: number; // 0 | 1 + + empathy_count: number; country_id: number; language_id: number; - mii: string; - mii_face_url: string; + + mii: string; // nintendo base64 + mii_face_url: string; // fully qualified (usually cdn. or r2-cdn.) + pid: number; - platform_id: number; - region_id: number; - parent: string; - reply_count?: number; + platform_id?: number; // missing on PMs + region_id?: number; // missing on PMs + parent?: string | null; // both undef and null exist in db + + reply_count: number; verified: boolean; - message_to_pid?: string; + + message_to_pid: string | null; + removed: boolean; removed_reason?: string; - yeahs?: Types.Array; - number?: number; + removed_by?: number; + removed_at?: Date; + + yeahs: Types.Array; } +// Fields that have "default: " in the Mongoose schema should also be listed here to make them optional +// on input but not output +// We really need an ORM +type PostDefaultedFields = + 'is_autopost' | + 'is_community_private_autopost' | + 'is_spoiler' | + 'is_app_jumpable' | + 'empathy_count' | + 'country_id' | + 'language_id' | + 'reply_count' | + 'verified' | + 'message_to_pid' | + 'removed' | + 'yeahs'; +export type IPostInput = Omit & Partial>; export interface IPostMethods { del(reason: string): Promise; @@ -52,6 +84,6 @@ export interface IPostMethods { json(options: PostToJSONOptions, community?: HydratedCommunityDocument): PostData; } -export type PostModel = Model; +export type PostModel = Model; export type HydratedPostDocument = HydratedDocument; diff --git a/package-lock.json b/package-lock.json index 4bb26ec8..b39bdba7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -86,7 +86,7 @@ "express-subdomain": "^1.0.5", "fs-extra": "^9.0.0", "moment": "^2.24.0", - "mongoose": "^6.10.1", + "mongoose": "^8.15.1", "multer": "^1.4.5-lts.1", "nice-grpc": "^2.1.12", "node-snowflake": "0.0.1", @@ -123,6 +123,24 @@ "xmlbuilder2": "^3.1.0" } }, + "apps/miiverse-api/node_modules/@types/whatwg-url": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.5.tgz", + "integrity": "sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ==", + "license": "MIT", + "dependencies": { + "@types/webidl-conversions": "*" + } + }, + "apps/miiverse-api/node_modules/bson": { + "version": "6.10.4", + "resolved": "https://registry.npmjs.org/bson/-/bson-6.10.4.tgz", + "integrity": "sha512-WIsKqkSC0ABoBJuT1LEX+2HEvNmNKKgnTAyd0fL8qzK4SH2i9NXg+t08YtdZp/V9IZ33cxe3iV4yM0qg8lMQng==", + "license": "Apache-2.0", + "engines": { + "node": ">=16.20.1" + } + }, "apps/miiverse-api/node_modules/fs-extra": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", @@ -137,6 +155,105 @@ "node": ">=10" } }, + "apps/miiverse-api/node_modules/kareem": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.6.3.tgz", + "integrity": "sha512-C3iHfuGUXK2u8/ipq9LfjFfXFxAZMQJJq7vLS45r3D9Y2xQ/m4S8zaR4zMLFWh9AsNPXmcFfUDhTEO8UIC/V6Q==", + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "apps/miiverse-api/node_modules/mongodb": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.16.0.tgz", + "integrity": "sha512-D1PNcdT0y4Grhou5Zi/qgipZOYeWrhLEpk33n3nm6LGtz61jvO88WlrWCK/bigMjpnOdAUKKQwsGIl0NtWMyYw==", + "license": "Apache-2.0", + "dependencies": { + "@mongodb-js/saslprep": "^1.1.9", + "bson": "^6.10.3", + "mongodb-connection-string-url": "^3.0.0" + }, + "engines": { + "node": ">=16.20.1" + }, + "peerDependencies": { + "@aws-sdk/credential-providers": "^3.188.0", + "@mongodb-js/zstd": "^1.1.0 || ^2.0.0", + "gcp-metadata": "^5.2.0", + "kerberos": "^2.0.1", + "mongodb-client-encryption": ">=6.0.0 <7", + "snappy": "^7.2.2", + "socks": "^2.7.1" + }, + "peerDependenciesMeta": { + "@aws-sdk/credential-providers": { + "optional": true + }, + "@mongodb-js/zstd": { + "optional": true + }, + "gcp-metadata": { + "optional": true + }, + "kerberos": { + "optional": true + }, + "mongodb-client-encryption": { + "optional": true + }, + "snappy": { + "optional": true + }, + "socks": { + "optional": true + } + } + }, + "apps/miiverse-api/node_modules/mongodb-connection-string-url": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.2.tgz", + "integrity": "sha512-rMO7CGo/9BFwyZABcKAWL8UJwH/Kc2x0g72uhDWzG48URRax5TCIcJ7Rc3RZqffZzO/Gwff/jyKwCU9TN8gehA==", + "license": "Apache-2.0", + "dependencies": { + "@types/whatwg-url": "^11.0.2", + "whatwg-url": "^14.1.0 || ^13.0.0" + } + }, + "apps/miiverse-api/node_modules/mongoose": { + "version": "8.15.1", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.15.1.tgz", + "integrity": "sha512-RhQ4DzmBi5BNGcS0w4u1vdMRIKcteXTCNzDt1j7XRcdWYBz1MjMjulBhPaeC5jBCHOD1yinuOFTTSOWLLGexWw==", + "license": "MIT", + "dependencies": { + "bson": "^6.10.3", + "kareem": "2.6.3", + "mongodb": "~6.16.0", + "mpath": "0.9.0", + "mquery": "5.0.0", + "ms": "2.1.3", + "sift": "17.1.3" + }, + "engines": { + "node": ">=16.20.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mongoose" + } + }, + "apps/miiverse-api/node_modules/mquery": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/mquery/-/mquery-5.0.0.tgz", + "integrity": "sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg==", + "license": "MIT", + "dependencies": { + "debug": "4.x" + }, + "engines": { + "node": ">=14.0.0" + } + }, "apps/miiverse-api/node_modules/pako": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", @@ -150,6 +267,37 @@ "node": ">=10.13.0" } }, + "apps/miiverse-api/node_modules/sift": { + "version": "17.1.3", + "resolved": "https://registry.npmjs.org/sift/-/sift-17.1.3.tgz", + "integrity": "sha512-Rtlj66/b0ICeFzYTuNvX/EF1igRbbnGSvEyT79McoZa/DeGhMyC5pWKOEsZKnpkqtSeovd5FL/bjHWC3CIIvCQ==", + "license": "MIT" + }, + "apps/miiverse-api/node_modules/tr46": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz", + "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==", + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=18" + } + }, + "apps/miiverse-api/node_modules/whatwg-url": { + "version": "14.2.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz", + "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==", + "license": "MIT", + "dependencies": { + "tr46": "^5.1.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/@aws-crypto/crc32": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-5.2.0.tgz", @@ -2660,7 +2808,6 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.2.2.tgz", "integrity": "sha512-EB0O3SCSNRUFk66iRCpI+cXzIjdswfCs7F6nOC3RAGJ7xr5YhaicvsRwJ9eyzYvYRlCSDUO/c7g4yNulxKC1WA==", - "optional": true, "dependencies": { "sparse-bitfield": "^3.0.3" } @@ -9066,8 +9213,7 @@ "node_modules/memory-pager": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", - "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", - "optional": true + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==" }, "node_modules/memorystream": { "version": "0.3.1", @@ -12037,7 +12183,6 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", - "optional": true, "dependencies": { "memory-pager": "^1.0.2" } From 83221c9b41c85d3ad1724112db73e8588c8177cf Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Wed, 11 Jun 2025 19:45:49 +1000 Subject: [PATCH 019/189] fix(login): Validation for the validation gods --- apps/juxtaposition-ui/src/config.ts | 5 ++++- .../src/services/juxt-web/routes/web/login.js | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/apps/juxtaposition-ui/src/config.ts b/apps/juxtaposition-ui/src/config.ts index 4bc415b3..e7d99f8e 100644 --- a/apps/juxtaposition-ui/src/config.ts +++ b/apps/juxtaposition-ui/src/config.ts @@ -9,6 +9,8 @@ const schema = z.object({ logSensitive: zodCoercedBoolean().default(false), httpPort: z.coerce.number().default(8080), httpCookieDomain: z.string().default('.pretendo.network'), + /** "Safe" base origin for login-redirect validation */ + httpBaseUrl: z.string().default('https://juxt.pretendo.network'), /** Configures proxy trust (X-Forwarded-For etc.). Can be `true` to unconditionally trust, or * provide a numeric hop count, or comma-seperated CIDR ranges. * See https://expressjs.com/en/guide/behind-proxies.html @@ -94,7 +96,8 @@ export const config = { http: { port: unmappedConfig.httpPort, cookieDomain: unmappedConfig.httpCookieDomain, - trustProxy: unmappedConfig.httpTrustProxy + trustProxy: unmappedConfig.httpTrustProxy, + baseUrl: unmappedConfig.httpBaseUrl }, metrics: { enabled: unmappedConfig.metricsEnabled, diff --git a/apps/juxtaposition-ui/src/services/juxt-web/routes/web/login.js b/apps/juxtaposition-ui/src/services/juxt-web/routes/web/login.js index 294b9222..a852ad94 100644 --- a/apps/juxtaposition-ui/src/services/juxt-web/routes/web/login.js +++ b/apps/juxtaposition-ui/src/services/juxt-web/routes/web/login.js @@ -66,7 +66,10 @@ router.post('/', async (req, res) => { res.cookie('refresh_token', login.refreshToken, { domain: cookieDomain }); res.cookie('token_type', 'Bearer', { domain: cookieDomain }); - res.redirect(/^\/[^/.]/.test(redirect) ? redirect : '/'); + /* Only allow relative URLs (leading /) or absolute ones on config.http.baseUrl. */ + const safe_redirect = new URL(redirect, config.http.baseUrl).origin == config.http.baseUrl ? redirect : '/'; + + res.redirect(safe_redirect); }); module.exports = router; From 4b8ca00dab4ee4f31b0582c92cbe8661397c5a72 Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Wed, 11 Jun 2025 19:54:20 +1000 Subject: [PATCH 020/189] feat(api): Rate-limiting for the ratelimiting gods --- apps/miiverse-api/package.json | 1 + apps/miiverse-api/src/services/api/index.ts | 10 ++++++++++ package-lock.json | 2 ++ 3 files changed, 13 insertions(+) diff --git a/apps/miiverse-api/package.json b/apps/miiverse-api/package.json index 0198fab0..ba1c29bf 100644 --- a/apps/miiverse-api/package.json +++ b/apps/miiverse-api/package.json @@ -23,6 +23,7 @@ "express": "^4.17.1", "express-async-errors": "^3.1.1", "express-prom-bundle": "^7.0.2", + "express-rate-limit": "^7.5.0", "express-subdomain": "^1.0.5", "fs-extra": "^9.0.0", "moment": "^2.24.0", diff --git a/apps/miiverse-api/src/services/api/index.ts b/apps/miiverse-api/src/services/api/index.ts index 94faaa47..5e680da3 100644 --- a/apps/miiverse-api/src/services/api/index.ts +++ b/apps/miiverse-api/src/services/api/index.ts @@ -1,5 +1,6 @@ import express from 'express'; import subdomain from 'express-subdomain'; +import { rateLimit } from 'express-rate-limit'; import { LOG_INFO } from '@/logger'; import postsHandlers from '@/services/api/routes/posts'; import friendMessagesHandlers from '@/services/api/routes/friend_messages'; @@ -15,6 +16,15 @@ const router = express.Router(); // Router to handle the subdomain restriction const api = express.Router(); +// Global API ratelimit (todo: make this more fine-grained for heavy queries) +const limiter = rateLimit({ + windowMs: 15 * 60 * 1000, // 15 minutes + limit: 100, // 100 requests every 15 mins + standardHeaders: true, + legacyHeaders: true +}); +router.use(limiter); + // Create subdomains LOG_INFO('[MIIVERSE] Creating \'api\' subdomain'); router.use(subdomain('api.olv', api)); diff --git a/package-lock.json b/package-lock.json index b39bdba7..bf6703ea 100644 --- a/package-lock.json +++ b/package-lock.json @@ -83,6 +83,7 @@ "express": "^4.17.1", "express-async-errors": "^3.1.1", "express-prom-bundle": "^7.0.2", + "express-rate-limit": "^7.5.0", "express-subdomain": "^1.0.5", "fs-extra": "^9.0.0", "moment": "^2.24.0", @@ -7227,6 +7228,7 @@ "version": "7.5.0", "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.5.0.tgz", "integrity": "sha512-eB5zbQh5h+VenMPM3fh+nw1YExi5nMr6HUCR62ELSP11huvxm/Uir1H1QEyTkk5QX6A58pX6NmaTMceKZ0Eodg==", + "license": "MIT", "engines": { "node": ">= 16" }, From 299db632055695b4ecc32582e6e23361bc989ddf Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Thu, 12 Jun 2025 23:14:25 +1000 Subject: [PATCH 021/189] feat(internal): Introduce dto contract type This provides a layer of abstraction between the actual database implementation and the on-the-wire types which will be useful when the database is changed soon --- apps/juxtaposition-ui/src/api/post.ts | 65 +++++++++++ apps/juxtaposition-ui/src/backend.ts | 10 -- apps/juxtaposition-ui/src/models/api/post.ts | 61 ---------- .../services/juxt-web/routes/console/posts.js | 10 +- .../src/services/internal/contract/post.ts | 108 ++++++++++++++++++ .../src/services/internal/routes/posts.ts | 3 +- 6 files changed, 180 insertions(+), 77 deletions(-) create mode 100644 apps/juxtaposition-ui/src/api/post.ts delete mode 100644 apps/juxtaposition-ui/src/backend.ts delete mode 100644 apps/juxtaposition-ui/src/models/api/post.ts create mode 100644 apps/miiverse-api/src/services/internal/contract/post.ts diff --git a/apps/juxtaposition-ui/src/api/post.ts b/apps/juxtaposition-ui/src/api/post.ts new file mode 100644 index 00000000..7d7c1c8c --- /dev/null +++ b/apps/juxtaposition-ui/src/api/post.ts @@ -0,0 +1,65 @@ +import { apiFetchUser } from '@/fetch'; +import type { UserTokens } from '@/fetch'; + +/* !!! HEY + * This type lives in apps/miiverse-api/src/services/internal/contract/post.ts + * Modify it there and copy-paste here! */ + +/* This type is the contract for the frontend. If we make changes to the db, this shape should be kept. */ +export type PostDto = { + id: string; + title_id?: string; // number + screen_name: string; + body: string; + app_data?: string; // nintendo base64 + + painting?: string; // base64 or '', undef for PMs + screenshot?: string; // URL frag (leading /) or '', undef for PMs + screenshot_length?: number; + + search_key?: string[]; // can be [] + topic_tag?: string; // can be '' + + community_id: string; // number + created_at: string; // ISO Z + feeling_id?: number; + + is_autopost: boolean; + is_community_private_autopost: boolean; + is_spoiler: boolean; + is_app_jumpable: boolean; + + empathy_count: number; + country_id: number; + language_id: number; + + mii: string; // nintendo base64 + mii_face_url: string; // full URL (cdn., r2-cdn.) + + pid: number; + platform_id?: number; + region_id?: number; + parent: string | null; + + reply_count: number; + verified: boolean; + + message_to_pid: string | null; + removed: boolean; + removed_by?: number; + removed_at?: string; // ISO Z + removed_reason?: string; + + yeahs: number[]; +}; + +/** + * Fetches a Post for a given ID. + * @param tokens User to perform fetch as. Responses will be according to this users' permissions (user, moderator etc.) + * @param post_id The ID of the post to get. + * @returns Post object + */ +export async function getPostById(tokens: UserTokens, post_id: string): Promise { + const post = await apiFetchUser(tokens, `/api/v1/posts/${post_id}`); + return post; +} diff --git a/apps/juxtaposition-ui/src/backend.ts b/apps/juxtaposition-ui/src/backend.ts deleted file mode 100644 index 3ed71d4e..00000000 --- a/apps/juxtaposition-ui/src/backend.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { apiFetchUser } from '@/fetch'; -import { PostSchema } from '@/models/api/post'; -import type { UserTokens } from '@/fetch'; -import type { Post } from '@/models/api/post'; - -export async function getPostById(tokens: UserTokens, post_id: string): Promise { - const data = await apiFetchUser(tokens, `/api/v1/posts/${post_id}`); - const post = await PostSchema.parseAsync(data); // todo: what to do on validation fail..? - return post; -} diff --git a/apps/juxtaposition-ui/src/models/api/post.ts b/apps/juxtaposition-ui/src/models/api/post.ts deleted file mode 100644 index 9494a893..00000000 --- a/apps/juxtaposition-ui/src/models/api/post.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { z } from 'zod'; - -const zBoolNumber = z.union([z.literal(0), z.literal(1)]); -// there are exactly two posts (of 550K) in the DB with IDs that are not 21 chars -const zPostId = z.string().min(19).max(22); -/* This schema (specifically the types and optionals) is trying to be 1:1 to the existing MongoDB, - * with the intent that we can incrementally fix it as the db is improved. - * The intent is to not do any transformation here, yet. - */ -export const PostSchema = z.object({ - id: zPostId, - title_id: z.string().optional(), // u64 - screen_name: z.string(), - body: z.string(), - app_data: z.string().optional(), // TODO nintendo base64 - - // base64, '' for posts without, undef for PMs - painting: z.string().optional(), - // URL fragment, '' for posts without, undef for PMs - screenshot: z.union([z.literal(''), z.string().startsWith('/')]).optional(), - screenshot_length: z.number().optional(), - - // sometimes missing, sometimes empty - search_key: z.array(z.string()).optional(), - // sometimes missing, sometimes empty - topic_tag: z.string().optional(), - - community_id: z.string(), // i64? - created_at: z.coerce.date(), - // missing on PMs - feeling_id: z.number().optional(), // todo enum - - is_autopost: zBoolNumber, // boolean - is_community_private_autopost: zBoolNumber, // boolean - is_spoiler: zBoolNumber, // boolean - is_app_jumpable: zBoolNumber, // boolean - - empathy_count: z.number().nonnegative(), - country_id: z.number(), - language_id: z.number(), - - mii: z.string(), // .base64(), TODO nintendo base64 - mii_face_url: z.string().url(), - - pid: z.number(), - platform_id: z.number().optional(), // missing on PMs - region_id: z.number().optional(), // missing on PMs - parent: zPostId.optional().nullable(), // both missing and null exist - - reply_count: z.number().nonnegative(), - verified: z.boolean(), - - message_to_pid: z.number().nullable(), - removed: z.boolean(), - removed_by: z.number().optional(), // pid - removed_at: z.coerce.date().optional(), - removed_reason: z.string().optional(), - yeahs: z.array(z.number()) -}); - -export type Post = z.infer; diff --git a/apps/juxtaposition-ui/src/services/juxt-web/routes/console/posts.js b/apps/juxtaposition-ui/src/services/juxt-web/routes/console/posts.js index 61cfb540..203c9084 100644 --- a/apps/juxtaposition-ui/src/services/juxt-web/routes/console/posts.js +++ b/apps/juxtaposition-ui/src/services/juxt-web/routes/console/posts.js @@ -12,7 +12,7 @@ const upload = multer({ dest: 'uploads/' }); const redis = require('@/redisCache'); const { config } = require('@/config'); const router = express.Router(); -const backend = require('@/backend'); +const { getPostById } = require('@/api/post'); const postLimit = rateLimit({ windowMs: 15 * 1000, // 30 seconds @@ -42,7 +42,7 @@ const yeahLimit = rateLimit({ }); router.get('/:post_id/oembed.json', async function (req, res) { - const post = await backend.getPostById(req.tokens, req.params.post_id); + const post = await getPostById(req.tokens, req.params.post_id); const doc = { author_name: post.screen_name, author_url: 'https://juxt.pretendo.network/users/show?pid=' + post.pid @@ -110,9 +110,9 @@ router.get('/:post_id', async function (req, res) { const userSettings = await database.getUserSettings(req.pid); const userContent = await database.getUserContent(req.pid); - const post = await backend.getPostById(req.tokens, req.params.post_id); + const post = await getPostById(req.tokens, req.params.post_id); if (post.parent) { - const parent = await backend.getPostById(req.tokens, post.parent); + const parent = await getPostById(req.tokens, post.parent); return res.redirect(`/posts/${parent.id}`); } const community = await database.getCommunityByID(post.community_id); @@ -161,7 +161,7 @@ router.post('/:post_id/new', postLimit, upload.none(), async function (req, res) router.post('/:post_id/report', upload.none(), async function (req, res) { const { reason, message, post_id } = req.body; - const post = await backend.getPostByID(req.tokens, post_id); + const post = await getPostById(req.tokens, post_id); if (!reason || !post_id || !post) { return res.redirect('/404'); } diff --git a/apps/miiverse-api/src/services/internal/contract/post.ts b/apps/miiverse-api/src/services/internal/contract/post.ts new file mode 100644 index 00000000..8e953a36 --- /dev/null +++ b/apps/miiverse-api/src/services/internal/contract/post.ts @@ -0,0 +1,108 @@ +import type { IPost } from '@/types/mongoose/post'; + +/* !!! HEY + * This type has a copy in apps/juxtaposition-ui/src/models/api/post.ts + * Make sure to copy over any modifications! */ + +/* This type is the contract for the frontend. If we make changes to the db, this shape should be kept. */ +export type PostDto = { + id: string; + title_id?: string; // number + screen_name: string; + body: string; + app_data?: string; // nintendo base64 + + painting?: string; // base64 or '', undef for PMs + screenshot?: string; // URL frag (leading /) or '', undef for PMs + screenshot_length?: number; + + search_key?: string[]; // can be [] + topic_tag?: string; // can be '' + + community_id: string; // number + created_at: string; // ISO Z + feeling_id?: number; + + is_autopost: boolean; + is_community_private_autopost: boolean; + is_spoiler: boolean; + is_app_jumpable: boolean; + + empathy_count: number; + country_id: number; + language_id: number; + + mii: string; // nintendo base64 + mii_face_url: string; // full URL (cdn., r2-cdn.) + + pid: number; + platform_id?: number; + region_id?: number; + parent: string | null; + + reply_count: number; + verified: boolean; + + message_to_pid: string | null; + removed: boolean; + removed_by?: number; + removed_at?: string; // ISO Z + removed_reason?: string; + + yeahs: number[]; +}; + +/** + * Maps a Post from the databse to the frontend contract post type. + * Doesn't do much for now, but as the database changes, this abstraction will carry more. + * @param post Database post type + * @returns API/frontend post type + */ +export function mapPost(post: IPost): PostDto { + return { + id: post.id, + title_id: post.title_id, + screen_name: post.screen_name, + body: post.body, + app_data: post.app_data, + + painting: post.painting, + screenshot: post.screenshot, + screenshot_length: post.screenshot_length, + + search_key: post.search_key, + topic_tag: post.topic_tag, + + community_id: post.community_id, + created_at: post.created_at.toISOString(), + feeling_id: post.feeling_id, + + is_autopost: !!post.is_autopost, + is_community_private_autopost: !!post.is_community_private_autopost, + is_spoiler: !!post.is_spoiler, + is_app_jumpable: !!post.is_app_jumpable, + + empathy_count: post.empathy_count, + country_id: post.country_id, + language_id: post.language_id, + + mii: post.mii, + mii_face_url: post.mii_face_url, + + pid: post.pid, + platform_id: post.platform_id, + region_id: post.region_id, + parent: post.parent ?? null, + + reply_count: post.reply_count, + verified: post.verified, + + message_to_pid: post.message_to_pid, + removed: post.removed, + removed_by: post.removed_by, + removed_at: post.removed_at?.toISOString(), + removed_reason: post.removed_reason, + + yeahs: post.yeahs + }; +} diff --git a/apps/miiverse-api/src/services/internal/routes/posts.ts b/apps/miiverse-api/src/services/internal/routes/posts.ts index 980354eb..120e8b84 100644 --- a/apps/miiverse-api/src/services/internal/routes/posts.ts +++ b/apps/miiverse-api/src/services/internal/routes/posts.ts @@ -3,6 +3,7 @@ import { getPostByID } from '@/database'; import { errors } from '@/services/internal/errors'; import { handle } from '@/services/internal/utils'; import { authGuest } from '@/services/internal/middleware/authenticated-endpoints'; +import { mapPost } from '@/services/internal/contract/post'; export const postsRouter = express.Router(); @@ -12,5 +13,5 @@ postsRouter.get('/:post_id', authGuest, handle(async ({ req }) => { throw new errors.notFound('Post not found'); } - return post; + return mapPost(post); })); From 586e77d89873d7a747737dad16fd0165c9952b75 Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Thu, 12 Jun 2025 23:25:14 +1000 Subject: [PATCH 022/189] feat(internal): Add explicit nulls for 404s --- apps/juxtaposition-ui/src/api/post.ts | 2 +- apps/juxtaposition-ui/src/fetch.ts | 8 +++++--- .../src/services/juxt-web/routes/console/posts.js | 9 +++++++++ 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/apps/juxtaposition-ui/src/api/post.ts b/apps/juxtaposition-ui/src/api/post.ts index 7d7c1c8c..ec248fb4 100644 --- a/apps/juxtaposition-ui/src/api/post.ts +++ b/apps/juxtaposition-ui/src/api/post.ts @@ -59,7 +59,7 @@ export type PostDto = { * @param post_id The ID of the post to get. * @returns Post object */ -export async function getPostById(tokens: UserTokens, post_id: string): Promise { +export async function getPostById(tokens: UserTokens, post_id: string): Promise { const post = await apiFetchUser(tokens, `/api/v1/posts/${post_id}`); return post; } diff --git a/apps/juxtaposition-ui/src/fetch.ts b/apps/juxtaposition-ui/src/fetch.ts index 0ffe4050..cac0eb42 100644 --- a/apps/juxtaposition-ui/src/fetch.ts +++ b/apps/juxtaposition-ui/src/fetch.ts @@ -26,7 +26,7 @@ function isErrorHttpStatus(status: number): boolean { return status >= 400 && status < 600; } -export async function apiFetch(path: string, options?: FetchOptions): Promise { +export async function apiFetch(path: string, options?: FetchOptions): Promise { const defaultedOptions = { method: 'GET', headers: {}, @@ -45,7 +45,9 @@ export async function apiFetch(path: string, options?: FetchOptions): Promise metadata }); - if (isErrorHttpStatus(response.status)) { + if (response.status === 404) { + return null; + } else if (isErrorHttpStatus(response.status)) { throw FetchError(response, `HTTP error! status: ${response.status} ${response.payload}`); } @@ -57,7 +59,7 @@ export type UserTokens = { oauthToken?: string; }; -export async function apiFetchUser(tokens: UserTokens, path: string, options?: FetchOptions): Promise { +export async function apiFetchUser(tokens: UserTokens, path: string, options?: FetchOptions): Promise { options = { ...options, headers: { diff --git a/apps/juxtaposition-ui/src/services/juxt-web/routes/console/posts.js b/apps/juxtaposition-ui/src/services/juxt-web/routes/console/posts.js index 203c9084..d4fcd62d 100644 --- a/apps/juxtaposition-ui/src/services/juxt-web/routes/console/posts.js +++ b/apps/juxtaposition-ui/src/services/juxt-web/routes/console/posts.js @@ -43,6 +43,9 @@ const yeahLimit = rateLimit({ router.get('/:post_id/oembed.json', async function (req, res) { const post = await getPostById(req.tokens, req.params.post_id); + if (!post) { + return res.sendStatus(404); + } const doc = { author_name: post.screen_name, author_url: 'https://juxt.pretendo.network/users/show?pid=' + post.pid @@ -111,8 +114,14 @@ router.get('/:post_id', async function (req, res) { const userContent = await database.getUserContent(req.pid); const post = await getPostById(req.tokens, req.params.post_id); + if (!post) { + return res.redirect('/404'); + } if (post.parent) { const parent = await getPostById(req.tokens, post.parent); + if (!parent) { + return res.redirect('/404'); + } return res.redirect(`/posts/${parent.id}`); } const community = await database.getCommunityByID(post.community_id); From 77d331c132c1123a79d33aae4f09c79b50182a9e Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Fri, 13 Jun 2025 00:07:09 +1000 Subject: [PATCH 023/189] fix(internal): Restructure auth and guard middlewares Mostly naming tweaks for clarity --- .../src/services/internal/index.ts | 2 +- ...ck-user-account.ts => auth-accesscheck.ts} | 4 +--- .../{authentication.ts => auth-populate.ts} | 23 +++++++++---------- .../{authenticated-endpoints.ts => guards.ts} | 12 +++++++--- .../src/services/internal/routes/posts.ts | 4 ++-- .../src/services/internal/routes/test.ts | 4 ++-- .../src/services/internal/server.ts | 8 +++---- .../src/types/common/account-data.ts | 2 +- 8 files changed, 31 insertions(+), 28 deletions(-) rename apps/miiverse-api/src/services/internal/middleware/{check-user-account.ts => auth-accesscheck.ts} (73%) rename apps/miiverse-api/src/services/internal/middleware/{authentication.ts => auth-populate.ts} (70%) rename apps/miiverse-api/src/services/internal/middleware/{authenticated-endpoints.ts => guards.ts} (66%) diff --git a/apps/miiverse-api/src/services/internal/index.ts b/apps/miiverse-api/src/services/internal/index.ts index b8c41cbb..d0f22722 100644 --- a/apps/miiverse-api/src/services/internal/index.ts +++ b/apps/miiverse-api/src/services/internal/index.ts @@ -4,4 +4,4 @@ import { postsRouter } from '@/services/internal/routes/posts'; export const internalApiRouter = express.Router(); internalApiRouter.use('/api/v1', testRouter); -internalApiRouter.use('/api/v1/posts', postsRouter); +internalApiRouter.use('/api/v1', postsRouter); diff --git a/apps/miiverse-api/src/services/internal/middleware/check-user-account.ts b/apps/miiverse-api/src/services/internal/middleware/auth-accesscheck.ts similarity index 73% rename from apps/miiverse-api/src/services/internal/middleware/check-user-account.ts rename to apps/miiverse-api/src/services/internal/middleware/auth-accesscheck.ts index e6bb08cf..daa96fb7 100644 --- a/apps/miiverse-api/src/services/internal/middleware/check-user-account.ts +++ b/apps/miiverse-api/src/services/internal/middleware/auth-accesscheck.ts @@ -4,7 +4,7 @@ import type express from 'express'; /** * Checks the user account is valid for this request (not banned, setup complete, etc.) */ -async function checkUserAccount(request: express.Request, response: express.Response, next: express.NextFunction): Promise { +export async function authAccessCheck(request: express.Request, response: express.Response, next: express.NextFunction): Promise { const account = response.locals.account; if (account === null) { // Guest access @@ -19,5 +19,3 @@ async function checkUserAccount(request: express.Request, response: express.Resp return next(); } - -export default checkUserAccount; diff --git a/apps/miiverse-api/src/services/internal/middleware/authentication.ts b/apps/miiverse-api/src/services/internal/middleware/auth-populate.ts similarity index 70% rename from apps/miiverse-api/src/services/internal/middleware/authentication.ts rename to apps/miiverse-api/src/services/internal/middleware/auth-populate.ts index 0a76b6ac..faeb3210 100644 --- a/apps/miiverse-api/src/services/internal/middleware/authentication.ts +++ b/apps/miiverse-api/src/services/internal/middleware/auth-populate.ts @@ -8,7 +8,7 @@ import type { AccountData } from '@/types/common/account-data'; * Handles authentication for service (NNAS/console) and OAuth (web) tokens. Sets locals.account to AccountData. * Will error if tokens bad or account nonexistent, but otherwise does not check bans or setup status. */ -async function auth(request: express.Request, response: express.Response, next: express.NextFunction): Promise { +export async function authPopulate(request: express.Request, response: express.Response, next: express.NextFunction): Promise { // Used by console applets const serviceToken = getValueFromHeaders(request.headers, 'x-service-token'); // Used by web frontend @@ -19,9 +19,9 @@ async function auth(request: express.Request, response: express.Response, next: } if (serviceToken) { - response.locals.account = await consoleAuth(serviceToken); + response.locals.account = await consoleAuth(request, serviceToken); } else if (oAuthToken) { - response.locals.account = await webAuth(oAuthToken); + response.locals.account = await webAuth(request, oAuthToken); } else { // Guest access response.locals.account = null; @@ -30,34 +30,33 @@ async function auth(request: express.Request, response: express.Response, next: return next(); } -async function consoleAuth(serviceToken: string): Promise { +async function consoleAuth(_request: express.Request, serviceToken: string): Promise { const pid = getPIDFromServiceToken(serviceToken); if (pid === 0) { throw new errors.unauthorized('Invalid service token'); } - const pnid = await getUserAccountData(pid); // If the user has a valid token for an unknown PID, just let the exception bubble + const pnid = await getUserAccountData(pid); - const settings = await getUserSettings(pid) ?? undefined; // Null doesn't play nice with TS ? - // Undef here just means the initial setup isn't done + // Null here just means the initial setup isn't done + const settings = await getUserSettings(pid); return { pnid, settings }; } -async function webAuth(oAuthToken: string): Promise { +async function webAuth(request: express.Request, oAuthToken: string): Promise { // The "normal" getUserData API (used here) is mutually incompatible with the "backdoor" one. // Since we can only use the backdoor one for consoles right now... - const pid = (await getUserDataFromToken(oAuthToken).catch(() => { + const pid = (await getUserDataFromToken(oAuthToken).catch((e) => { // TODO should probably check the error type here in case of e.g. connection refused + request.log.error(e, 'Failed to get user data from OAuth token'); throw new errors.unauthorized('Invalid OAuth token!'); })).pid; // Ask the "backdoor" API, just use the above as a glorified token decryption. const pnid = await getUserAccountData(pid); - const settings = await getUserSettings(pid) ?? undefined; + const settings = await getUserSettings(pid); return { pnid, settings }; } - -export default auth; diff --git a/apps/miiverse-api/src/services/internal/middleware/authenticated-endpoints.ts b/apps/miiverse-api/src/services/internal/middleware/guards.ts similarity index 66% rename from apps/miiverse-api/src/services/internal/middleware/authenticated-endpoints.ts rename to apps/miiverse-api/src/services/internal/middleware/guards.ts index 814659a1..5f9a4a7c 100644 --- a/apps/miiverse-api/src/services/internal/middleware/authenticated-endpoints.ts +++ b/apps/miiverse-api/src/services/internal/middleware/guards.ts @@ -4,14 +4,14 @@ import type express from 'express'; /** * Guest access is fine */ -export async function authGuest(request: express.Request, response: express.Response, next: express.NextFunction): Promise { +export async function guest(request: express.Request, response: express.Response, next: express.NextFunction): Promise { return next(); } /** * Fail on guest access */ -export async function authUsers(request: express.Request, response: express.Response, next: express.NextFunction): Promise { +export async function user(request: express.Request, response: express.Response, next: express.NextFunction): Promise { const account = response.locals.account; if (account === null) { // Guest access @@ -24,7 +24,7 @@ export async function authUsers(request: express.Request, response: express.Resp /** * Moderators only */ -export async function authModerators(request: express.Request, response: express.Response, next: express.NextFunction): Promise { +export async function moderator(request: express.Request, response: express.Response, next: express.NextFunction): Promise { const account = response.locals.account; if (account === null) { // Guest access @@ -37,3 +37,9 @@ export async function authModerators(request: express.Request, response: express return next(); } + +export const guards = { + guest, + user, + moderator +}; diff --git a/apps/miiverse-api/src/services/internal/routes/posts.ts b/apps/miiverse-api/src/services/internal/routes/posts.ts index 120e8b84..ab1e4fdd 100644 --- a/apps/miiverse-api/src/services/internal/routes/posts.ts +++ b/apps/miiverse-api/src/services/internal/routes/posts.ts @@ -2,12 +2,12 @@ import express from 'express'; import { getPostByID } from '@/database'; import { errors } from '@/services/internal/errors'; import { handle } from '@/services/internal/utils'; -import { authGuest } from '@/services/internal/middleware/authenticated-endpoints'; +import { guards } from '@/services/internal/middleware/guards'; import { mapPost } from '@/services/internal/contract/post'; export const postsRouter = express.Router(); -postsRouter.get('/:post_id', authGuest, handle(async ({ req }) => { +postsRouter.get('/posts/:post_id', guards.guest, handle(async ({ req }) => { const post = await getPostByID(req.params.post_id); if (!post || post.removed) { throw new errors.notFound('Post not found'); diff --git a/apps/miiverse-api/src/services/internal/routes/test.ts b/apps/miiverse-api/src/services/internal/routes/test.ts index feeace02..8a766ac3 100644 --- a/apps/miiverse-api/src/services/internal/routes/test.ts +++ b/apps/miiverse-api/src/services/internal/routes/test.ts @@ -1,10 +1,10 @@ import express from 'express'; import { handle } from '@/services/internal/utils'; -import { authUsers } from '@/services/internal/middleware/authenticated-endpoints'; +import { guards } from '@/services/internal/middleware/guards'; export const testRouter = express.Router(); -testRouter.get('/test', authUsers, handle(async () => { +testRouter.get('/test', guards.user, handle(async () => { return { message: 'Hello from the test route!' }; diff --git a/apps/miiverse-api/src/services/internal/server.ts b/apps/miiverse-api/src/services/internal/server.ts index 32515f55..eca7b22d 100644 --- a/apps/miiverse-api/src/services/internal/server.ts +++ b/apps/miiverse-api/src/services/internal/server.ts @@ -4,11 +4,11 @@ import express from 'express'; import { MiiverseServiceDefinition } from '@repo/grpc-client/out/miiverse_service'; import { config } from '@/config'; import { internalApiRouter } from '@/services/internal'; -import authentication from '@/services/internal/middleware/authentication'; -import checkUserAccount from '@/services/internal/middleware/check-user-account'; import { logger } from '@/logger'; import { InternalAPIError } from '@/services/internal/errors'; import { loggerHttp } from '@/loggerHttp'; +import { authPopulate } from '@/services/internal/middleware/auth-populate'; +import { authAccessCheck } from '@/services/internal/middleware/auth-accesscheck'; import type { CallContext, ServerMiddlewareCall } from 'nice-grpc'; // API server @@ -16,8 +16,8 @@ import type { CallContext, ServerMiddlewareCall } from 'nice-grpc'; const app = express(); app.use(express.json()); app.use(loggerHttp); -app.use(authentication); -app.use(checkUserAccount); +app.use(authPopulate); +app.use(authAccessCheck); app.use(internalApiRouter); // API error handler diff --git a/apps/miiverse-api/src/types/common/account-data.ts b/apps/miiverse-api/src/types/common/account-data.ts index a1885706..e0365402 100644 --- a/apps/miiverse-api/src/types/common/account-data.ts +++ b/apps/miiverse-api/src/types/common/account-data.ts @@ -3,5 +3,5 @@ import type { GetUserDataResponse } from '@pretendonetwork/grpc/account/get_user export interface AccountData { pnid: GetUserDataResponse; - settings?: HydratedSettingsDocument; + settings: HydratedSettingsDocument | null; } From eda12fbf764714d273efa1ddc5c88f88d58a5dc7 Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Fri, 13 Jun 2025 16:48:07 +1000 Subject: [PATCH 024/189] fix(api): Tweak ratelimits --- apps/miiverse-api/src/services/api/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/miiverse-api/src/services/api/index.ts b/apps/miiverse-api/src/services/api/index.ts index 5e680da3..da0ada28 100644 --- a/apps/miiverse-api/src/services/api/index.ts +++ b/apps/miiverse-api/src/services/api/index.ts @@ -19,7 +19,7 @@ const api = express.Router(); // Global API ratelimit (todo: make this more fine-grained for heavy queries) const limiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15 minutes - limit: 100, // 100 requests every 15 mins + limit: 400, // 26 per minute standardHeaders: true, legacyHeaders: true }); From e81f230bdf4a95e3514b0548bcc8ec7e4505473b Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Fri, 13 Jun 2025 22:37:49 +1000 Subject: [PATCH 025/189] feat(internal): Stronger checks on account status + mod mode --- .../internal/middleware/auth-accesscheck.ts | 26 ++++++++++-- .../internal/middleware/auth-populate.ts | 41 ++++++++++++++----- .../services/internal/middleware/guards.ts | 12 +++++- .../src/types/common/account-data.ts | 1 + 4 files changed, 65 insertions(+), 15 deletions(-) diff --git a/apps/miiverse-api/src/services/internal/middleware/auth-accesscheck.ts b/apps/miiverse-api/src/services/internal/middleware/auth-accesscheck.ts index daa96fb7..d25a4c33 100644 --- a/apps/miiverse-api/src/services/internal/middleware/auth-accesscheck.ts +++ b/apps/miiverse-api/src/services/internal/middleware/auth-accesscheck.ts @@ -11,11 +11,31 @@ export async function authAccessCheck(request: express.Request, response: expres return next(); } - if (account.pnid.accessLevel < 0) { - throw new errors.unauthorized('Account has been banned'); + if (account.pnid.deleted) { + throw new errors.unauthorized('Account does not exist'); } - // TODO account settings, temp bans, etc. + if (account.pnid.accessLevel < 0 || + account.pnid.permissions?.bannedAllPermanently === true || + account.pnid.permissions?.bannedAllTemporarily === true) { + throw new errors.forbidden('Account has been banned'); + } + + // TODO console linking check (needs account server support) + + if (account.settings === null) { + // Account hasn't completed initial setup yet + // User guard will check this for endpoints that care + // Still.. spooky + return next(); + } + + // 0 = normal, 1 = limited from posting, 2 = temp ban, 3 = perma ban + if (account.settings.account_status !== 0 && account.settings.account_status !== 1) { + throw new errors.forbidden('Account has been banned from Juxtaposition'); + } + + // TODO lift expired temporary bans and post limits (frontend's responsibility for now) return next(); } diff --git a/apps/miiverse-api/src/services/internal/middleware/auth-populate.ts b/apps/miiverse-api/src/services/internal/middleware/auth-populate.ts index faeb3210..3d06cfb9 100644 --- a/apps/miiverse-api/src/services/internal/middleware/auth-populate.ts +++ b/apps/miiverse-api/src/services/internal/middleware/auth-populate.ts @@ -2,7 +2,7 @@ import { getPIDFromServiceToken, getUserAccountData, getUserDataFromToken, getVa import { errors } from '@/services/internal/errors'; import { getUserSettings } from '@/database'; import type express from 'express'; -import type { AccountData } from '@/types/common/account-data'; +import type { GetUserDataResponse } from '@pretendonetwork/grpc/account/get_user_data_rpc'; /** * Handles authentication for service (NNAS/console) and OAuth (web) tokens. Sets locals.account to AccountData. @@ -18,10 +18,20 @@ export async function authPopulate(request: express.Request, response: express.R throw new errors.badRequest('Multiple authentication tokens provided'); } + let pnid: GetUserDataResponse | null = null; if (serviceToken) { - response.locals.account = await consoleAuth(request, serviceToken); + pnid = await consoleAuth(request, serviceToken); } else if (oAuthToken) { - response.locals.account = await webAuth(request, oAuthToken); + pnid = await webAuth(request, oAuthToken); + } + + if (pnid !== null) { + // Null here just means the initial setup isn't done + const settings = await getUserSettings(pnid.pid); + + const moderator = accountIsModerator(pnid); + + response.locals.account = { pnid, settings, moderator }; } else { // Guest access response.locals.account = null; @@ -30,7 +40,7 @@ export async function authPopulate(request: express.Request, response: express.R return next(); } -async function consoleAuth(_request: express.Request, serviceToken: string): Promise { +async function consoleAuth(_request: express.Request, serviceToken: string): Promise { const pid = getPIDFromServiceToken(serviceToken); if (pid === 0) { throw new errors.unauthorized('Invalid service token'); @@ -39,13 +49,10 @@ async function consoleAuth(_request: express.Request, serviceToken: string): Pro // If the user has a valid token for an unknown PID, just let the exception bubble const pnid = await getUserAccountData(pid); - // Null here just means the initial setup isn't done - const settings = await getUserSettings(pid); - - return { pnid, settings }; + return pnid; } -async function webAuth(request: express.Request, oAuthToken: string): Promise { +async function webAuth(request: express.Request, oAuthToken: string): Promise { // The "normal" getUserData API (used here) is mutually incompatible with the "backdoor" one. // Since we can only use the backdoor one for consoles right now... const pid = (await getUserDataFromToken(oAuthToken).catch((e) => { @@ -56,7 +63,19 @@ async function webAuth(request: express.Request, oAuthToken: string): Promise= 2) { + return true; + } + + // Lower-level accounts can also have permission granted + if (pnid.permissions?.moderateMiiverse === true) { + return true; + } - return { pnid, settings }; + return false; } diff --git a/apps/miiverse-api/src/services/internal/middleware/guards.ts b/apps/miiverse-api/src/services/internal/middleware/guards.ts index 5f9a4a7c..5feb88f0 100644 --- a/apps/miiverse-api/src/services/internal/middleware/guards.ts +++ b/apps/miiverse-api/src/services/internal/middleware/guards.ts @@ -18,6 +18,12 @@ export async function user(request: express.Request, response: express.Response, throw new errors.unauthorized('Authentication token not provided'); } + if (account.settings === null) { + // Most endpoints expect users to have completed the account setup flow + // TODO eventually this will need a carveout for the setup flow itself + throw new errors.forbidden('Account setup not complete'); + } + return next(); } @@ -31,7 +37,11 @@ export async function moderator(request: express.Request, response: express.Resp throw new errors.unauthorized('Authentication token not provided'); } - if (account.pnid.accessLevel < 2) { + if (account.settings === null) { + throw new errors.forbidden('Account setup not complete'); + } + + if (account.moderator !== true) { throw new errors.forbidden('You cannot access this endpoint'); } diff --git a/apps/miiverse-api/src/types/common/account-data.ts b/apps/miiverse-api/src/types/common/account-data.ts index e0365402..3f885a64 100644 --- a/apps/miiverse-api/src/types/common/account-data.ts +++ b/apps/miiverse-api/src/types/common/account-data.ts @@ -4,4 +4,5 @@ import type { GetUserDataResponse } from '@pretendonetwork/grpc/account/get_user export interface AccountData { pnid: GetUserDataResponse; settings: HydratedSettingsDocument | null; + moderator: boolean; } From 1e1f0bf69cc1bded832c90805bb816e8cd383687 Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Fri, 13 Jun 2025 22:40:18 +1000 Subject: [PATCH 026/189] feat(internal): Show moderators removed posts --- apps/miiverse-api/src/services/internal/routes/posts.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/miiverse-api/src/services/internal/routes/posts.ts b/apps/miiverse-api/src/services/internal/routes/posts.ts index ab1e4fdd..5a0216a0 100644 --- a/apps/miiverse-api/src/services/internal/routes/posts.ts +++ b/apps/miiverse-api/src/services/internal/routes/posts.ts @@ -7,9 +7,9 @@ import { mapPost } from '@/services/internal/contract/post'; export const postsRouter = express.Router(); -postsRouter.get('/posts/:post_id', guards.guest, handle(async ({ req }) => { +postsRouter.get('/posts/:post_id', guards.guest, handle(async ({ req, res }) => { const post = await getPostByID(req.params.post_id); - if (!post || post.removed) { + if (!post || (post.removed && res.locals.account?.moderator !== true)) { throw new errors.notFound('Post not found'); } From dad0b140eb3052d52066abf9626e9b2a960ce07a Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Fri, 13 Jun 2025 22:56:37 +1000 Subject: [PATCH 027/189] fix(web): Provide redirect on all paths Some paths use the login template to render errors (?) and this now requires a redirect URL. Provide one. --- apps/juxtaposition-ui/src/middleware/checkBan.js | 4 ++-- apps/juxtaposition-ui/src/middleware/discovery.js | 2 +- apps/juxtaposition-ui/src/webfiles/web/login.ejs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/juxtaposition-ui/src/middleware/checkBan.js b/apps/juxtaposition-ui/src/middleware/checkBan.js index 30993899..dae1b2a3 100644 --- a/apps/juxtaposition-ui/src/middleware/checkBan.js +++ b/apps/juxtaposition-ui/src/middleware/checkBan.js @@ -38,7 +38,7 @@ async function checkBan(request, response, next) { if (!accessAllowed) { response.status(500); if (request.directory === 'web') { - return response.render('web/login.ejs', { toast: 'No access. Must be tester or dev' }); + return response.render('web/login.ejs', { toast: 'No access. Must be tester or dev', redirect: request.originalUrl }); } else { return response.render('portal/partials/ban_notification.ejs', { user: null, @@ -66,7 +66,7 @@ async function checkBan(request, response, next) { default: banMessage = `${request.user.username} has been banned. \n\nIf you have any questions contact the moderators in the Discord server or forum.`; } - return response.render('web/login.ejs', { toast: banMessage }); + return response.render('web/login.ejs', { toast: banMessage, redirect: request.originalUrl }); } else { return response.render(request.directory + '/partials/ban_notification.ejs', { user: userSettings, diff --git a/apps/juxtaposition-ui/src/middleware/discovery.js b/apps/juxtaposition-ui/src/middleware/discovery.js index b6e939d0..53325f5f 100644 --- a/apps/juxtaposition-ui/src/middleware/discovery.js +++ b/apps/juxtaposition-ui/src/middleware/discovery.js @@ -19,7 +19,7 @@ async function checkDiscovery(request, response, next) { break; } if (request.directory === 'web') { - return response.render('web/login.ejs', { toast: message }); + return response.render('web/login.ejs', { toast: message, redirect: request.originalUrl }); } else { return response.render('portal/partials/ban_notification.ejs', { user: null, diff --git a/apps/juxtaposition-ui/src/webfiles/web/login.ejs b/apps/juxtaposition-ui/src/webfiles/web/login.ejs index 9edc71a7..6e39cd70 100644 --- a/apps/juxtaposition-ui/src/webfiles/web/login.ejs +++ b/apps/juxtaposition-ui/src/webfiles/web/login.ejs @@ -83,7 +83,7 @@ Don't have an account? - + From ed447585aaf11998bf56ca55f68a4a5091e9e975 Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Wed, 25 Jun 2025 16:11:43 +1000 Subject: [PATCH 028/189] feat(docker): Export proxy certs for 3ds Place `.docker/mitmproxy-data/mitmproxy-ca-cert.pem` into `sdmc:/3ds/juxt-prod.pem` --- .docker/docker-compose.yml | 8 +++++++- .gitignore | 2 ++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.docker/docker-compose.yml b/.docker/docker-compose.yml index 1f820b0c..c3bad3d0 100644 --- a/.docker/docker-compose.yml +++ b/.docker/docker-compose.yml @@ -67,12 +67,18 @@ services: proxy: image: mitmproxy/mitmproxy - command: mitmweb --mode regular@8888 -s /data/mitmproxy-local.py -v --web-host 0.0.0.0 -k --set tls_version_client_min=UNBOUNDED --set tls_version_server_min=UNBOUNDED --set web_password=letmein + command: > + mitmweb -v --mode regular@8888 + -s /data/mitmproxy-local.py + --web-host 0.0.0.0 --set web_password=letmein + -k --set tls_version_client_min=UNBOUNDED --set tls_version_server_min=UNBOUNDED + --set key_size=1024 ports: - 8888:8888 - 127.0.0.1:8081:8081 volumes: - "./mitmproxy-local.py:/data/mitmproxy-local.py" + - "./mitmproxy-data/:/home/mitmproxy/.mitmproxy/" extra_hosts: - "host.docker.internal:host-gateway" diff --git a/.gitignore b/.gitignore index 75f4be01..13e00578 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,5 @@ dist/ newman config.json uploads/ + +.docker/mitmproxy-data \ No newline at end of file From 6739f58e9694d1eb6f98505b314ab28a9a38d6f4 Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Wed, 25 Jun 2025 21:02:39 +1000 Subject: [PATCH 029/189] chore(util): Convert to TypeScript fix: Use ParamPack type fix: typo in getUserFriendPIDs --- apps/juxtaposition-ui/src/images.ts | 123 ++++ apps/juxtaposition-ui/src/loggerHttp.ts | 3 +- .../src/middleware/consoleAuth.js | 4 +- .../services/juxt-web/routes/admin/admin.js | 27 +- .../juxt-web/routes/console/messages.jsx | 21 +- .../juxt-web/routes/console/notifications.js | 3 +- .../services/juxt-web/routes/console/posts.js | 7 +- .../services/juxt-web/routes/console/show.js | 2 +- .../juxt-web/routes/console/userpage.js | 9 +- .../src/types/common/param-pack.ts | 16 + .../src/types/common/token.ts | 8 + .../src/types/juxt/notification.ts | 9 + apps/juxtaposition-ui/src/util.js | 567 ------------------ apps/juxtaposition-ui/src/util.ts | 444 ++++++++++++++ 14 files changed, 641 insertions(+), 602 deletions(-) create mode 100644 apps/juxtaposition-ui/src/images.ts create mode 100644 apps/juxtaposition-ui/src/types/common/param-pack.ts create mode 100644 apps/juxtaposition-ui/src/types/common/token.ts create mode 100644 apps/juxtaposition-ui/src/types/juxt/notification.ts delete mode 100644 apps/juxtaposition-ui/src/util.js create mode 100644 apps/juxtaposition-ui/src/util.ts diff --git a/apps/juxtaposition-ui/src/images.ts b/apps/juxtaposition-ui/src/images.ts new file mode 100644 index 00000000..598e9d01 --- /dev/null +++ b/apps/juxtaposition-ui/src/images.ts @@ -0,0 +1,123 @@ +import { Buffer } from 'node:buffer'; +// @ts-expect-error Missing upstream types for this library +import TGA from 'tga'; +// @ts-expect-error Missing upstream types for this library +import imagePixels from 'image-pixels'; +import { inflate, deflate } from 'pako'; +import { PNG } from 'pngjs'; +import bmp from 'bmp-js'; +import sharp from 'sharp'; +import { logger } from '@/logger'; + +/** Ingests a BMP-format painting and converts it to the usual TGA format. + * @param painting base64-encoded bmp image + * @returns base64-encoded zlib-compressed TGA + */ +export async function processBmpPainting(painting: string): Promise { + const paintingBuffer = Buffer.from(painting, 'base64'); + const bitmap = bmp.decode(paintingBuffer); + const tga = createTgaFromPixelData(bitmap.width, bitmap.height, bitmap.data, false); + + let output: Uint8Array; + try { + output = deflate(tga, { level: 6 }); + } catch (err) { + logger.error(err, 'Could not compress painting'); + return null; + } + return Buffer.from(output.buffer).toString('base64'); +} + +/** + * Ingests a raw painting and converts it for CDN upload. + * @param painting base64-encoded zlib-compressed TGA + * @returns PNG in buffer + */ +export async function processPainting(painting: string): Promise { + const paintingBuffer = Buffer.from(painting, 'base64'); + let output: Uint8Array; + try { + output = inflate(paintingBuffer); + } catch (err) { + logger.error(err, 'Could not decompress painting'); + return null; + } + let tga; + try { + tga = new TGA(Buffer.from(output.buffer)); + } catch (e) { + logger.error(e, 'Could not parse painting'); + return null; + } + const png = new PNG({ + width: tga.width, + height: tga.height + }); + png.data = tga.pixels; + return PNG.sync.write(png); +} + +export async function resizeImage(file: string, width: number, height: number): Promise { + return new Promise(function (resolve) { + const image = Buffer.from(file, 'base64'); + sharp(image) + .resize({ height: height, width: width }) + .toBuffer() + .then((data) => { + resolve(data); + }).catch(err => logger.error(err, 'Could not resize image')); + }); +} + +export async function getTGAFromPNG(image: Buffer): Promise { + const pngData = await imagePixels(Buffer.from(image)); + const tga = TGA.createTgaBuffer(pngData.width, pngData.height, pngData.data); + let output; + try { + output = deflate(tga, { level: 6 }); + } catch (err) { + logger.error(err, 'Could not decompress image'); + return null; + } + return Buffer.from(output.buffer).toString('base64').trim(); +} + +/** + * Makes a new TGA from BGRX pixel data + * @param width Width of the data + * @param height Height of the data + * @param pixels [B1, G1, R1, X1, B2, R2, G2, X2...] + * @param dontFlipY Invert the y-axis + * @returns Buffer with TGA data + * + * Modified from https://github.com/steel1990/tga/blob/dcd2bff6536c1c75719ed4309389cd66f991d8d3/src/index.js#L16-L45 + */ +function createTgaFromPixelData(width: number, height: number, pixels: Buffer, dontFlipY: boolean): Buffer { + const buffer = Buffer.alloc(18 + pixels.length); + // write header + buffer.writeInt8(0, 0); + buffer.writeInt8(0, 1); + buffer.writeInt8(2, 2); + buffer.writeInt16LE(0, 3); + buffer.writeInt16LE(0, 5); + buffer.writeInt8(0, 7); + buffer.writeInt16LE(0, 8); + buffer.writeInt16LE(0, 10); + buffer.writeInt16LE(width, 12); + buffer.writeInt16LE(height, 14); + buffer.writeInt8(32, 16); + buffer.writeInt8(8, 17); + + let offset = 18; + for (let i = 0; i < height; i++) { + for (let j = 0; j < width; j++) { + const idx = ((dontFlipY ? i : height - i - 1) * width + j) * 4; + buffer.writeUInt8(pixels[idx + 1], offset++); // b + buffer.writeUInt8(pixels[idx + 2], offset++); // g + buffer.writeUInt8(pixels[idx + 3], offset++); // r + buffer.writeUInt8(255, offset++); // a + } + } + + return buffer; +} diff --git a/apps/juxtaposition-ui/src/loggerHttp.ts b/apps/juxtaposition-ui/src/loggerHttp.ts index fd0ab64e..cf21e05a 100644 --- a/apps/juxtaposition-ui/src/loggerHttp.ts +++ b/apps/juxtaposition-ui/src/loggerHttp.ts @@ -4,8 +4,9 @@ import { config } from '@/config'; import { decodeParamPack } from '@/util'; import type { SerializedRequest, SerializedResponse } from 'pino'; import type { Request } from 'express'; +import type { ParamPack } from '@/types/common/param-pack'; -type SerializedNintendoRequest = SerializedRequest & { param_pack?: Record }; +type SerializedNintendoRequest = SerializedRequest & { param_pack?: ParamPack }; function redactHeaders(headers: Record, allowlist: string[]): Record { if (!config.log.sensitive) { diff --git a/apps/juxtaposition-ui/src/middleware/consoleAuth.js b/apps/juxtaposition-ui/src/middleware/consoleAuth.js index 36f815e1..1d3c7237 100644 --- a/apps/juxtaposition-ui/src/middleware/consoleAuth.js +++ b/apps/juxtaposition-ui/src/middleware/consoleAuth.js @@ -8,8 +8,8 @@ async function auth(request, response, next) { request.user = request.session.user; request.pid = request.session.pid; } else { - request.pid = request.headers['x-nintendo-servicetoken'] ? await util.processServiceToken(request.headers['x-nintendo-servicetoken']) : null; - request.user = request.pid ? await util.getUserDataFromPid(request.pid) : null; + request.pid = request.headers['x-nintendo-servicetoken'] ? await util.getPIDFromServiceToken(request.headers['x-nintendo-servicetoken']) : null; + request.user = request.pid ? await util.getUserAccountData(request.pid) : null; request.session.user = request.user; request.session.pid = request.pid; diff --git a/apps/juxtaposition-ui/src/services/juxt-web/routes/admin/admin.js b/apps/juxtaposition-ui/src/services/juxt-web/routes/admin/admin.js index 50cee82d..7577f327 100644 --- a/apps/juxtaposition-ui/src/services/juxt-web/routes/admin/admin.js +++ b/apps/juxtaposition-ui/src/services/juxt-web/routes/admin/admin.js @@ -2,6 +2,7 @@ const crypto = require('crypto'); const express = require('express'); const moment = require('moment'); const multer = require('multer'); +const { resizeImage, getTGAFromPNG } = require('@/images'); const database = require('@/database'); const { POST } = require('@/models/post'); const { SETTINGS } = require('@/models/settings'); @@ -78,7 +79,7 @@ router.get('/accounts/:pid', async function (req, res) { if (!res.locals.moderator) { return res.redirect('/titles/show'); } - const pnid = await util.getUserDataFromPid(req.params.pid).catch((e) => { + const pnid = await util.getUserAccountData(req.params.pid).catch((e) => { logger.error(e, `Could not fetch userdata for ${req.params.pid}`); }); const userContent = await database.getUserContent(req.params.pid); @@ -319,9 +320,9 @@ router.post('/communities/new', upload.fields([{ name: 'browserIcon', maxCount: } // browser icon - const icon128 = await util.resizeImage(req.files.browserIcon[0].buffer.toString('base64'), 128, 128); - const icon64 = await util.resizeImage(req.files.browserIcon[0].buffer.toString('base64'), 64, 64); - const icon32 = await util.resizeImage(req.files.browserIcon[0].buffer.toString('base64'), 32, 32); + const icon128 = await resizeImage(req.files.browserIcon[0].buffer.toString('base64'), 128, 128); + const icon64 = await resizeImage(req.files.browserIcon[0].buffer.toString('base64'), 64, 64); + const icon32 = await resizeImage(req.files.browserIcon[0].buffer.toString('base64'), 32, 32); if (!await util.uploadCDNAsset(`icons/${communityID}/128.png`, icon128, 'public-read') || !await util.uploadCDNAsset(`icons/${communityID}/64.png`, icon64, 'public-read') || @@ -330,11 +331,11 @@ router.post('/communities/new', upload.fields([{ name: 'browserIcon', maxCount: } // TGA icon - const tgaIcon = await util.getTGAFromPNG(icon128); + const tgaIcon = await getTGAFromPNG(icon128); // 3DS Header - const CTRHeader = await util.resizeImage(req.files.CTRbrowserHeader[0].buffer.toString('base64'), 400, 220); + const CTRHeader = await resizeImage(req.files.CTRbrowserHeader[0].buffer.toString('base64'), 400, 220); // Wii U Header - const WiiUHeader = await util.resizeImage(req.files.WiiUbrowserHeader[0].buffer.toString('base64'), 1280, 180); + const WiiUHeader = await resizeImage(req.files.WiiUbrowserHeader[0].buffer.toString('base64'), 1280, 180); if (!await util.uploadCDNAsset(`headers/${communityID}/3DS.png`, CTRHeader, 'public-read') || !await util.uploadCDNAsset(`headers/${communityID}/WiiU.png`, WiiUHeader, 'public-read')) { @@ -444,9 +445,9 @@ router.post('/communities/:id', upload.fields([{ name: 'browserIcon', maxCount: // browser icon if (req.files.browserIcon) { - const icon128 = await util.resizeImage(req.files.browserIcon[0].buffer.toString('base64'), 128, 128); - const icon64 = await util.resizeImage(req.files.browserIcon[0].buffer.toString('base64'), 64, 64); - const icon32 = await util.resizeImage(req.files.browserIcon[0].buffer.toString('base64'), 32, 32); + const icon128 = await resizeImage(req.files.browserIcon[0].buffer.toString('base64'), 128, 128); + const icon64 = await resizeImage(req.files.browserIcon[0].buffer.toString('base64'), 64, 64); + const icon32 = await resizeImage(req.files.browserIcon[0].buffer.toString('base64'), 32, 32); if (!await util.uploadCDNAsset(`icons/${communityID}/128.png`, icon128, 'public-read') || !await util.uploadCDNAsset(`icons/${communityID}/64.png`, icon64, 'public-read') || @@ -455,11 +456,11 @@ router.post('/communities/:id', upload.fields([{ name: 'browserIcon', maxCount: } // TGA icon - tgaIcon = await util.getTGAFromPNG(icon128); + tgaIcon = await getTGAFromPNG(icon128); } // 3DS Header if (req.files.CTRbrowserHeader) { - const CTRHeader = await util.resizeImage(req.files.CTRbrowserHeader[0].buffer.toString('base64'), 400, 220); + const CTRHeader = await resizeImage(req.files.CTRbrowserHeader[0].buffer.toString('base64'), 400, 220); if (!await util.uploadCDNAsset(`headers/${communityID}/3DS.png`, CTRHeader, 'public-read')) { return res.sendStatus(422); } @@ -467,7 +468,7 @@ router.post('/communities/:id', upload.fields([{ name: 'browserIcon', maxCount: // Wii U Header if (req.files.WiiUbrowserHeader) { - const WiiUHeader = await util.resizeImage(req.files.WiiUbrowserHeader[0].buffer.toString('base64'), 1280, 180); + const WiiUHeader = await resizeImage(req.files.WiiUbrowserHeader[0].buffer.toString('base64'), 1280, 180); if (!await util.uploadCDNAsset(`headers/${communityID}/WiiU.png`, WiiUHeader, 'public-read')) { return res.sendStatus(422); } diff --git a/apps/juxtaposition-ui/src/services/juxt-web/routes/console/messages.jsx b/apps/juxtaposition-ui/src/services/juxt-web/routes/console/messages.jsx index 0619eb2b..6fc81549 100644 --- a/apps/juxtaposition-ui/src/services/juxt-web/routes/console/messages.jsx +++ b/apps/juxtaposition-ui/src/services/juxt-web/routes/console/messages.jsx @@ -3,12 +3,13 @@ import { buildContext } from '@/services/juxt-web/views/context'; import { CtrMessagesView } from '@/services/juxt-web/views/ctr/messages'; import { PortalMessagesView } from '@/services/juxt-web/views/portal/messages'; import { WebMessagesView } from '@/services/juxt-web/views/web/messages'; +import { processPainting } from '@/images'; +import { getUserFriendPIDs, getUserAccountData, getUserHash, uploadCDNAsset, INVALID_POST_BODY_REGEX } from '@/util'; const crypto = require('crypto'); const express = require('express'); const moment = require('moment'); const snowflake = require('node-snowflake').Snowflake; const database = require('@/database'); -const util = require('@/util'); const { POST } = require('@/models/post'); const { CONVERSATION } = require('@/models/conversation'); const { config } = require('@/config'); @@ -26,9 +27,9 @@ router.get('/', async function (req, res) { router.post('/new', async function (req, res) { let conversation = await database.getConversationByID(req.body.community_id); - const user2 = await util.getUserDataFromPid(req.body.message_to_pid); + const user2 = await getUserAccountData(req.body.message_to_pid); const postID = await generatePostUID(21); - const friends = await util.getFriends(user2.pid); + const friends = await getUserFriendPIDs(user2.pid); if (req.body.community_id === 0) { return res.sendStatus(404); } @@ -70,8 +71,8 @@ router.post('/new', async function (req, res) { let screenshot = null; if (req.body._post_type === 'painting' && req.body.painting) { painting = req.body.painting.replace(/\0/g, '').trim(); - paintingURI = await util.processPainting(painting, true); - if (!await util.uploadCDNAsset(`paintings/${req.pid}/${postID}.png`, paintingURI, 'public-read')) { + paintingURI = await processPainting(painting, true); + if (!await uploadCDNAsset(`paintings/${req.pid}/${postID}.png`, paintingURI, 'public-read')) { res.status(422); return res.render(req.directory + '/error.ejs', { code: 422, @@ -81,7 +82,7 @@ router.post('/new', async function (req, res) { } if (req.body.screenshot) { screenshot = req.body.screenshot.replace(/\0/g, '').trim(); - if (await util.uploadCDNAsset(`screenshots/${req.pid}/${postID}.jpg`, Buffer.from(screenshot, 'base64'), 'public-read')) { + if (await uploadCDNAsset(`screenshots/${req.pid}/${postID}.jpg`, Buffer.from(screenshot, 'base64'), 'public-read')) { res.status(422); return res.render(req.directory + '/error.ejs', { code: 422, @@ -112,7 +113,7 @@ router.post('/new', async function (req, res) { break; } const body = req.body.body; - if (body && util.INVALID_POST_BODY_REGEX.test(body)) { + if (body && INVALID_POST_BODY_REGEX.test(body)) { // TODO - Log this error return res.sendStatus(422); } @@ -163,8 +164,8 @@ router.post('/new', async function (req, res) { }); router.get('/new/:pid', async function (req, res) { - const user2 = await util.getUserDataFromPid(req.params.pid); - const friends = await util.getFriends(user2.pid); + const user2 = await getUserAccountData(req.params.pid); + const friends = await getUserFriendPIDs(user2.pid); if (!req.user || !user2) { return res.sendStatus(422); } @@ -226,7 +227,7 @@ router.get('/:message_id', async function (req, res) { res.redirect('/'); } const messages = await database.getConversationMessages(conversation.id, 200, 0); - const userMap = await util.getUserHash(); + const userMap = await getUserHash(); res.render(req.directory + '/message_thread.ejs', { moment: moment, user2: user2, diff --git a/apps/juxtaposition-ui/src/services/juxt-web/routes/console/notifications.js b/apps/juxtaposition-ui/src/services/juxt-web/routes/console/notifications.js index cdead472..0accbe74 100644 --- a/apps/juxtaposition-ui/src/services/juxt-web/routes/console/notifications.js +++ b/apps/juxtaposition-ui/src/services/juxt-web/routes/console/notifications.js @@ -2,6 +2,7 @@ const express = require('express'); const moment = require('moment'); const database = require('@/database'); const util = require('@/util'); +const { getUserFriendRequestsIncoming } = util; const router = express.Router(); router.get('/my_news', async function (req, res) { @@ -31,7 +32,7 @@ router.get('/my_news', async function (req, res) { }); router.get('/friend_requests', async function (req, res) { - let requests = (await util.getFriendRequests(req.pid)).reverse(); + let requests = (await getUserFriendRequestsIncoming(req.pid)).reverse(); const now = new Date(); requests = requests.filter(request => new Date(Number(request.expires) * 1000) > new Date(now.getTime() - 29 * 24 * 60 * 60 * 1000)); const userMap = util.getUserHash(); diff --git a/apps/juxtaposition-ui/src/services/juxt-web/routes/console/posts.js b/apps/juxtaposition-ui/src/services/juxt-web/routes/console/posts.js index 18fc31c3..ef246940 100644 --- a/apps/juxtaposition-ui/src/services/juxt-web/routes/console/posts.js +++ b/apps/juxtaposition-ui/src/services/juxt-web/routes/console/posts.js @@ -11,6 +11,7 @@ const { REPORT } = require('@/models/report'); const upload = multer({ dest: 'uploads/' }); const redis = require('@/redisCache'); const { config } = require('@/config'); +const { processBmpPainting, processPainting } = require('@/images'); const router = express.Router(); const postLimit = rateLimit({ @@ -122,7 +123,7 @@ router.get('/:post_id', async function (req, res) { const community = await database.getCommunityByID(post.community_id); const communityMap = await util.getCommunityHash(); const replies = await database.getPostReplies(req.params.post_id.toString(), 25); - const postPNID = await util.getUserDataFromPid(post.pid); + const postPNID = await util.getUserAccountData(post.pid); res.render(req.directory + '/post.ejs', { moment: moment, userSettings: userSettings, @@ -254,11 +255,11 @@ async function newPost(req, res) { let screenshot = null; if (req.body._post_type === 'painting' && req.body.painting) { if (req.body.bmp === 'true') { - painting = await util.processPainting(req.body.painting.replace(/\0/g, '').trim(), false); + painting = await processBmpPainting(req.body.painting.replace(/\0/g, '').trim()); } else { painting = req.body.painting; } - paintingURI = await util.processPainting(painting, true); + paintingURI = await processPainting(painting, true); if (!await util.uploadCDNAsset(`paintings/${req.pid}/${postID}.png`, paintingURI, 'public-read')) { res.status(422); return res.render(req.directory + '/error.ejs', { diff --git a/apps/juxtaposition-ui/src/services/juxt-web/routes/console/show.js b/apps/juxtaposition-ui/src/services/juxt-web/routes/console/show.js index 69d7b609..4ae73ded 100644 --- a/apps/juxtaposition-ui/src/services/juxt-web/routes/console/show.js +++ b/apps/juxtaposition-ui/src/services/juxt-web/routes/console/show.js @@ -44,7 +44,7 @@ router.post('/newUser', async function (req, res) { return res.sendStatus(504); } - await util.create_user(req.pid, req.body.experience, req.body.notifications); + await util.createUser(req.pid, req.body.experience, req.body.notifications); if (await database.getUserSettings(req.pid) !== null) { res.sendStatus(200); } else { diff --git a/apps/juxtaposition-ui/src/services/juxt-web/routes/console/userpage.js b/apps/juxtaposition-ui/src/services/juxt-web/routes/console/userpage.js index 99c77257..10807e95 100644 --- a/apps/juxtaposition-ui/src/services/juxt-web/routes/console/userpage.js +++ b/apps/juxtaposition-ui/src/services/juxt-web/routes/console/userpage.js @@ -3,6 +3,7 @@ const multer = require('multer'); const moment = require('moment'); const database = require('@/database'); const util = require('@/util'); +const { getUserFriendPIDs } = util; const { POST } = require('@/models/post'); const { SETTINGS } = require('@/models/settings'); const redis = require('@/redisCache'); @@ -138,7 +139,7 @@ async function userPage(req, res, userID) { } const pnid = userID === req.pid ? req.user - : await util.getUserDataFromPid(userID).catch((e) => { + : await util.getUserAccountData(userID).catch((e) => { logger.error(e, `Could not fetch userdata for ${req.params.pid}`); }); const userContent = await database.getUserContent(userID); @@ -155,7 +156,7 @@ async function userPage(req, res, userID) { const numPosts = await database.getTotalPostsByUserID(userID); const communityMap = await util.getCommunityHash(); - const friends = await util.getFriends(userID); + const friends = await getUserFriendPIDs(userID); let parentUserContent; if (pnid.pid !== req.pid) { @@ -194,12 +195,12 @@ async function userPage(req, res, userID) { } async function userRelations(req, res, userID) { - const pnid = userID === req.pid ? req.user : await util.getUserDataFromPid(userID); + const pnid = userID === req.pid ? req.user : await util.getUserAccountData(userID); const userContent = await database.getUserContent(userID); const link = (pnid.pid === req.pid) ? '/users/me/' : `/users/${userID}/`; const userSettings = await database.getUserSettings(userID); const numPosts = await database.getTotalPostsByUserID(userID); - const friends = await util.getFriends(userID); + const friends = await getUserFriendPIDs(userID); let parentUserContent; if (pnid.pid !== req.pid) { parentUserContent = await database.getUserContent(req.pid); diff --git a/apps/juxtaposition-ui/src/types/common/param-pack.ts b/apps/juxtaposition-ui/src/types/common/param-pack.ts new file mode 100644 index 00000000..bf28b254 --- /dev/null +++ b/apps/juxtaposition-ui/src/types/common/param-pack.ts @@ -0,0 +1,16 @@ +export interface ParamPack { + title_id: string; + access_key: string; + platform_id: string; + region_id: string; + language_id: string; + country_id: string; + area_id: string; + network_restriction: string; + friend_restriction: string; + rating_restriction: string; + rating_organization: string; + transferable_id: string; + tz_name: string; + utc_offset: string; +} diff --git a/apps/juxtaposition-ui/src/types/common/token.ts b/apps/juxtaposition-ui/src/types/common/token.ts new file mode 100644 index 00000000..985f08ae --- /dev/null +++ b/apps/juxtaposition-ui/src/types/common/token.ts @@ -0,0 +1,8 @@ +export interface ServiceToken { + system_type: number; + token_type: number; + pid: number; + access_level: number; + title_id: bigint; + issue_time: bigint; +} diff --git a/apps/juxtaposition-ui/src/types/juxt/notification.ts b/apps/juxtaposition-ui/src/types/juxt/notification.ts new file mode 100644 index 00000000..93e0e1ea --- /dev/null +++ b/apps/juxtaposition-ui/src/types/juxt/notification.ts @@ -0,0 +1,9 @@ +export type Notification = { + pid: number; + type: 'notice' | 'yeah' | 'reply' | 'follow'; + text: string; + image: string; + link: string; + objectID: string; + userPID: number; +}; diff --git a/apps/juxtaposition-ui/src/util.js b/apps/juxtaposition-ui/src/util.js deleted file mode 100644 index 75c59459..00000000 --- a/apps/juxtaposition-ui/src/util.js +++ /dev/null @@ -1,567 +0,0 @@ -const crypto = require('crypto'); -const grpc = require('nice-grpc'); -const { AccountDefinition } = require('@pretendonetwork/grpc/account/account_service'); -const { FriendsDefinition } = require('@pretendonetwork/grpc/friends/friends_service'); -const { APIDefinition } = require('@pretendonetwork/grpc/api/api_service'); -const HashMap = require('hashmap'); -const TGA = require('tga'); -const imagePixels = require('image-pixels'); -const pako = require('pako'); -const PNG = require('pngjs').PNG; -const bmp = require('bmp-js'); -const sharp = require('sharp'); -const { S3Client, PutObjectCommand } = require('@aws-sdk/client-s3'); -const crc32 = require('crc/crc32'); -const translations = require('./translations'); -const database = require('@/database'); -const { COMMUNITY } = require('@/models/communities'); -const { NOTIFICATION } = require('@/models/notifications'); -const { logger } = require('@/logger'); -const { CONTENT } = require('@/models/content'); -const { SETTINGS } = require('@/models/settings'); -const { LOGS } = require('@/models/logs'); -const { config } = require('@/config'); -const communityMap = new HashMap(); -const userMap = new HashMap(); - -const { host: friendsIP, port: friendsPort, apiKey: friendsKey } = config.grpc.friends; -const friendsChannel = grpc.createChannel(`${friendsIP}:${friendsPort}`); -const friendsClient = grpc.createClient(FriendsDefinition, friendsChannel); - -const { host: apiIP, port: apiPort, apiKey: apiKey } = config.grpc.account; -const apiChannel = grpc.createChannel(`${apiIP}:${apiPort}`); -const apiClient = grpc.createClient(APIDefinition, apiChannel); - -const accountChannel = grpc.createChannel(`${apiIP}:${apiPort}`); -const accountClient = grpc.createClient(AccountDefinition, accountChannel); - -const s3 = new S3Client({ - endpoint: config.s3.endpoint, - forcePathStyle: true, - region: config.s3.region, - credentials: { - accessKeyId: config.s3.key, - secretAccessKey: config.s3.secret - } -}); - -nameCache(); - -function nameCache() { - database.connect().then(async () => { - const communities = await COMMUNITY.find(); - if (communities !== null) { - for (let i = 0; i < communities.length; i++) { - if (communities[i].title_id !== null) { - for (let j = 0; j < communities[i].title_id.length; j++) { - communityMap.set(communities[i].title_id[j], communities[i].name); - communityMap.set(communities[i].title_id[j] + '-id', communities[i].olive_community_id); - } - communityMap.set(communities[i].olive_community_id, communities[i].name); - } - } - logger.success('Created community index of ' + communities.length + ' communities'); - } - const users = await database.getUsersSettings(-1); - if (users !== null) { - for (let i = 0; i < users.length; i++) { - if (users[i].pid !== null) { - userMap.set(users[i].pid, users[i].screen_name.replace(/[\u{0080}-\u{FFFF}]/gu, '').replace(/\u202e/g, '')); - } - } - logger.success('Created user index of ' + users.length + ' users'); - } - }).catch((error) => { - logger.error(error); - }); -} - -// TODO - This doesn't belong here, just hacking it in. Gonna redo this whole server anyway so fuck it -const INVALID_POST_BODY_REGEX = /[^\p{L}\p{P}\d\n\r$^¨←→↑↓√¦⇒⇔¤¢€£¥™©®+×÷=±∞˘˙¸˛˜°¹²³♭♪¬¯¼½¾♡♥●◆■▲▼☆★♀♂<> ]/gu; -async function create_user(pid, experience, notifications) { - const pnid = await this.getUserDataFromPid(pid); - if (!pnid) { - return; - } - const newSettings = { - pid: pid, - screen_name: pnid.mii.name, - game_skill: experience, - receive_notifications: notifications - }; - const newContent = { - pid: pid - }; - const newSettingsObj = new SETTINGS(newSettings); - await newSettingsObj.save(); - - const newContentObj = new CONTENT(newContent); - await newContentObj.save(); - - this.setName(pid, pnid.mii.name); -} - -/** - * Decodes and converts a Nintendo param pack to a JavaScript object. - * @param {string} paramPack base64-encoded param pack - * @returns {Record} - */ -function decodeParamPack(paramPack) { - /* Decode base64 */ - let dec = Buffer.from(paramPack, 'base64').toString('ascii'); - /* Remove starting and ending '/', split into array */ - dec = dec.slice(1, -1).split('\\'); - /* Parameters are in the format [name, val, name, val]. Copy into out{}. */ - const out = {}; - for (let i = 0; i < dec.length; i += 2) { - out[dec[i].trim()] = dec[i + 1].trim(); - } - return out; -} -function processServiceToken(encryptedToken) { - try { - const B64token = Buffer.from(encryptedToken, 'base64'); - const decryptedToken = this.decryptToken(B64token); - const token = this.unpackServiceToken(decryptedToken); - - // * Only allow token types 1 (Wii U) and 2 (3DS) - if (token.system_type !== 1 && token.system_type !== 2) { - return null; - } - - // * Check if the token is expired - if (token.issue_time + (24n * 3600n * 1000n) < Date.now()) { - return null; - } - - return token.pid; - } catch (e) { - logger.error(e, 'Could not process service token'); - return null; - } -} -function decryptToken(token) { - if (!config.aesKey) { - throw new Error('Service token AES key not found. Set config.aesKey'); - } - - const iv = Buffer.alloc(16); - const key = Buffer.from(config.aesKey, 'hex'); - - const expectedChecksum = token.readUint32BE(); - const encryptedBody = token.subarray(4); - - const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv); - - const decrypted = Buffer.concat([ - decipher.update(encryptedBody), - decipher.final() - ]); - - if (expectedChecksum !== crc32(decrypted)) { - throw new Error('Checksum did not match. Failed decrypt. Are you using the right key?'); - } - - return decrypted; -} -function unpackServiceToken(token) { - return { - system_type: token.readUInt8(0x0), - token_type: token.readUInt8(0x1), - pid: token.readUInt32LE(0x2), - issue_time: token.readBigUInt64LE(0x6), - title_id: token.readBigUInt64LE(0xE), - access_level: token.readInt8(0x16) - }; -} -async function processPainting(painting, isTGA) { - if (isTGA) { - const paintingBuffer = Buffer.from(painting, 'base64'); - let output = ''; - try { - output = pako.inflate(paintingBuffer); - } catch (err) { - logger.error(err, 'Could not decompress painting'); - return null; - } - let tga; - try { - tga = new TGA(Buffer.from(output)); - } catch (e) { - logger.error(e, 'Could not parse painting'); - return null; - } - const png = new PNG({ - width: tga.width, - height: tga.height - }); - png.data = tga.pixels; - return PNG.sync.write(png); - // return `data:image/png;base64,${pngBuffer.toString('base64')}`; - } else { - const paintingBuffer = Buffer.from(painting, 'base64'); - const bitmap = bmp.decode(paintingBuffer); - const tga = this.createBMPTgaBuffer(bitmap.width, bitmap.height, bitmap.data, false); - - let output; - try { - output = pako.deflate(tga, { level: 6 }); - } catch (err) { - logger.error(err, 'Could not compress painting'); - return null; - } - return new Buffer(output).toString('base64'); - } -} -function nintendoPasswordHash(password, pid) { - const pidBuffer = Buffer.alloc(4); - pidBuffer.writeUInt32LE(pid); - - const unpacked = Buffer.concat([ - pidBuffer, - Buffer.from('\x02\x65\x43\x46'), - Buffer.from(password) - ]); - return crypto.createHash('sha256').update(unpacked).digest().toString('hex'); -} -function getCommunityHash() { - return communityMap; -} -function getUserHash() { - return userMap; -} -function refreshCache() { - nameCache(); -} -function setName(pid, name) { - if (!pid || !name) { - return; - } - userMap.delete(pid); - userMap.set(pid, name.replace(/[\u{0080}-\u{FFFF}]/gu, '').replace(/\u202e/g, '')); -} - -function updateCommunityHash(community) { - if (!community) { - return; - } - for (let i = 0; i < community.title_id.length; i++) { - communityMap.set(community.title_id[i], community.name); - communityMap.set(community.title_id[i] + '-id', community.olive_community_id); - } - communityMap.set(community.olive_community_id, community.name); -} - -function getReasonMap() { - return [ - 'Spoiler', - 'Personal Information', - 'Violent Content', - 'Inappropriate/Harmful Conduct', - 'Hateful/Bullying', - 'Advertising', - 'Sexually Explicit', - 'Piracy', - 'Inappropriate Behavior in Game', - 'Other', - 'Missing Images; Reach out to Jemma with post link to fix' - ]; -} - -async function resizeImage(file, width, height) { - return new Promise(function (resolve) { - const image = Buffer.from(file, 'base64'); - sharp(image) - .resize({ height: height, width: width }) - .toBuffer() - .then((data) => { - resolve(data); - }).catch(err => logger.error(err, 'Could not resize image')); - }); -} - -async function getTGAFromPNG(image) { - const pngData = await imagePixels(Buffer.from(image)); - const tga = TGA.createTgaBuffer(pngData.width, pngData.height, pngData.data); - let output; - try { - output = pako.deflate(tga, { level: 6 }); - } catch (err) { - logger.error(err, 'Could not decompress image'); - return null; - } - return new Buffer(output).toString('base64').trim(); -} - -function createBMPTgaBuffer(width, height, pixels, dontFlipY) { - const buffer = Buffer.alloc(18 + pixels.length); - // write header - buffer.writeInt8(0, 0); - buffer.writeInt8(0, 1); - buffer.writeInt8(2, 2); - buffer.writeInt16LE(0, 3); - buffer.writeInt16LE(0, 5); - buffer.writeInt8(0, 7); - buffer.writeInt16LE(0, 8); - buffer.writeInt16LE(0, 10); - buffer.writeInt16LE(width, 12); - buffer.writeInt16LE(height, 14); - buffer.writeInt8(32, 16); - buffer.writeInt8(8, 17); - - let offset = 18; - for (let i = 0; i < height; i++) { - for (let j = 0; j < width; j++) { - const idx = ((dontFlipY ? i : height - i - 1) * width + j) * 4; - buffer.writeUInt8(pixels[idx + 1], offset++); // b - buffer.writeUInt8(pixels[idx + 2], offset++); // g - buffer.writeUInt8(pixels[idx + 3], offset++); // r - buffer.writeUInt8(255, offset++); // a - } - } - - return buffer; -} -function processLanguage(paramPackData) { - if (!paramPackData) { - return translations.EN; - } - switch (paramPackData.language_id) { - case '0': - return translations.JA; - case '1': - return translations.EN; - case '2': - return translations.FR; - case '3': - return translations.DE; - case '4': - return translations.IT; - case '5': - return translations.ES; - case '6': - return translations.ZH; - case '7': - return translations.KO; - case '8': - return translations.NL; - case '9': - return translations.PT; - case '10': - return translations.RU; - case '11': - return translations.ZH; - default: - return translations.EN; - } -} -async function uploadCDNAsset(key, data, acl) { - const awsPutParams = new PutObjectCommand({ - Body: data, - Key: key, - Bucket: config.s3.bucket, - ACL: acl - }); - try { - await s3.send(awsPutParams); - return true; - } catch (e) { - logger.error(e, 'Could not upload to CDN'); - return false; - } -} -async function newNotification(notification) { - const now = new Date(); - if (notification.type === 'follow') { - // { pid: userToFollowContent.pid, type: "follow", objectID: req.pid, link: `/users/${req.pid}` } - let existingNotification = await NOTIFICATION.findOne({ pid: notification.pid, objectID: notification.objectID }); - if (existingNotification) { - existingNotification.lastUpdated = now; - existingNotification.read = false; - return await existingNotification.save(); - } - const last60min = new Date(now.getTime() - 60 * 60 * 1000); - existingNotification = await NOTIFICATION.findOne({ pid: notification.pid, type: 'follow', lastUpdated: { $gte: last60min } }); - if (existingNotification) { - existingNotification.users.push({ - user: notification.objectID, - timeStamp: now - }); - existingNotification.lastUpdated = now; - existingNotification.link = notification.link; - existingNotification.objectID = notification.objectID; - existingNotification.read = false; - return await existingNotification.save(); - } else { - const newNotification = new NOTIFICATION({ - pid: notification.pid, - type: notification.type, - users: [{ - user: notification.objectID, - timestamp: now - }], - link: notification.link, - objectID: notification.objectID, - read: false, - lastUpdated: now - }); - await newNotification.save(); - } - } else if (notification.type == 'notice') { - const newNotification = new NOTIFICATION({ - pid: notification.pid, - type: notification.type, - text: notification.text, - image: notification.image, - link: notification.link, - read: false, - lastUpdated: now - }); - await newNotification.save(); - } - /* else if(notification.type === 'yeah') { - // { pid: userToFollowContent.pid, type: "follow", objectID: req.pid, link: `/users/${req.pid}` } - let existingNotification = await NOTIFICATION.findOne({ pid: notification.pid, objectID: notification.objectID }) - if(existingNotification) { - existingNotification.lastUpdated = new Date(); - return await existingNotification.save(); - } - existingNotification = await NOTIFICATION.findOne({ pid: notification.pid, type: 'yeah' }); - if(existingNotification) { - existingNotification.users.push({ - user: notification.objectID, - timeStamp: new Date() - }); - existingNotification.lastUpdated = new Date(); - existingNotification.link = notification.link; - existingNotification.objectID = notification.objectID; - return await existingNotification.save(); - } - else { - let newNotification = new NOTIFICATION({ - pid: notification.pid, - type: notification.type, - users: [{ - user: notification.objectID, - timestamp: new Date() - }], - link: notification.link, - objectID: notification.objectID, - read: false, - lastUpdated: new Date() - }); - await newNotification.save(); - } - } */ -} -async function getFriends(pid) { - try { - const pids = await friendsClient.getUserFriendPIDs({ - pid: pid - }, { - metadata: grpc.Metadata({ - 'X-API-Key': friendsKey - }) - }); - return pids.pids; - } catch (e) { - logger.error(e, `Failed to get friends for ${pid}`); - return []; - } -} -async function getFriendRequests(pid) { - try { - const requests = await friendsClient.getUserFriendRequestsIncoming({ - pid: pid - }, { - metadata: grpc.Metadata({ - 'X-API-Key': friendsKey - }) - }); - return requests.friendRequests; - } catch (e) { - logger.error(e, `Failed to get friend requests for ${pid}`); - return []; - } -} -async function login(username, password) { - return await apiClient.login({ - username: username, - password: password, - grantType: 'password' - }, { - metadata: grpc.Metadata({ - 'X-API-Key': apiKey - }) - }); -} -async function refreshLogin(refreshToken) { - return await apiClient.login({ - refreshToken: refreshToken - }, { - metadata: grpc.Metadata({ - 'X-API-Key': apiKey - }) - }); -} -async function getUserDataFromToken(token) { - return apiClient.getUserData({}, { - metadata: grpc.Metadata({ - 'X-API-Key': apiKey, - 'X-Token': token - }) - }); -} -async function getUserDataFromPid(pid) { - return accountClient.getUserData({ - pid: pid - }, { - metadata: grpc.Metadata({ - 'X-API-Key': apiKey - }) - }); -} -async function getPid(token) { - const user = await this.getUserDataFromToken(token); - return user.pid; -} -async function createLogEntry(actor, action, target, context, fields) { - const newLog = new LOGS({ - actor: actor, - action: action, - target: target, - context: context, - changed_fields: fields - }); - await newLog.save(); -} -module.exports = { - decodeParamPack, - processServiceToken, - decryptToken, - unpackServiceToken, - processPainting, - nintendoPasswordHash, - getCommunityHash, - getUserHash, - refreshCache, - setName, - updateCommunityHash, - getReasonMap, - resizeImage, - getTGAFromPNG, - createBMPTgaBuffer, - processLanguage, - uploadCDNAsset, - newNotification, - getFriends, - getFriendRequests, - login, - refreshLogin, - getUserDataFromToken, - getUserDataFromPid, - getPid, - create_user, - INVALID_POST_BODY_REGEX, - createLogEntry -}; diff --git a/apps/juxtaposition-ui/src/util.ts b/apps/juxtaposition-ui/src/util.ts new file mode 100644 index 00000000..5058adde --- /dev/null +++ b/apps/juxtaposition-ui/src/util.ts @@ -0,0 +1,444 @@ +import crypto from 'crypto'; +import { createChannel, createClient, Metadata } from 'nice-grpc'; +import { AccountDefinition } from '@pretendonetwork/grpc/account/account_service'; +import { FriendsDefinition } from '@pretendonetwork/grpc/friends/friends_service'; +import { APIDefinition } from '@pretendonetwork/grpc/api/api_service'; +import HashMap from 'hashmap'; +import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3'; +import crc32 from 'crc/crc32'; +import database from '@/database'; +import { COMMUNITY } from '@/models/communities'; +import { NOTIFICATION } from '@/models/notifications'; +import { logger } from '@/logger'; +import { CONTENT } from '@/models/content'; +import { SETTINGS } from '@/models/settings'; +import { LOGS } from '@/models/logs'; +import { config } from '@/config'; +import translations from './translations'; +import type { ObjectCannedACL } from '@aws-sdk/client-s3'; +import type { NotificationSchema } from '@/models/notifications'; +import type { CommunitySchema } from '@/models/communities'; +import type { ParamPack } from '@/types/common/param-pack'; +import type { ServiceToken } from '@/types/common/token'; +import type { InferSchemaType } from 'mongoose'; +import type { Notification } from '@/types/juxt/notification'; +import type { GetUserDataResponse as AccountGetUserDataResponse } from '@pretendonetwork/grpc/account/get_user_data_rpc'; +import type { GetUserDataResponse as ApiGetUserDataResponse } from '@pretendonetwork/grpc/api/get_user_data_rpc'; +import type { FriendRequest } from '@pretendonetwork/grpc/friends/friend_request'; +import type { LoginResponse } from '@pretendonetwork/grpc/api/login_rpc'; + +const gRPCFriendsChannel = createChannel(`${config.grpc.friends.host}:${config.grpc.friends.port}`); +const gRPCFriendsClient = createClient(FriendsDefinition, gRPCFriendsChannel); + +const gRPCAccountChannel = createChannel(`${config.grpc.account.host}:${config.grpc.account.port}`); +const gRPCAccountClient = createClient(AccountDefinition, gRPCAccountChannel); + +const gRPCApiChannel = createChannel(`${config.grpc.account.host}:${config.grpc.account.port}`); +const gRPCApiClient = createClient(APIDefinition, gRPCApiChannel); + +const s3 = new S3Client({ + endpoint: config.s3.endpoint, + forcePathStyle: true, + region: config.s3.region, + credentials: { + accessKeyId: config.s3.key, + secretAccessKey: config.s3.secret + } +}); + +const communityMap = new HashMap(); +const userMap = new HashMap(); + +/** + * Map from {olive_community_id, title_id} to name + * and also title_id + '-id' to olive_community_id + */ +export function getCommunityHash(): HashMap { + return communityMap; +} +/** + * Map from pid to screen_name (transformed) + */ +export function getUserHash(): HashMap { + return userMap; +} + +refreshCache(); + +function refreshCache(): void { + database.connect().then(async () => { + for await (const community of COMMUNITY.find()) { + updateCommunityHash(community); + } + logger.success('Created community index'); + + const users = await database.getUsersSettings(-1); + + for (const user of users) { + if (user.pid === undefined || user.screen_name === undefined) { + continue; + } + + setName(user.pid, user.screen_name); + } + logger.success('Created user index of ' + users.length + ' users'); + }).catch((error) => { + logger.error(error); + }); +} + +/** + * Updates a user's name in the user map. + */ +export function setName(pid: number, name: string): void { + userMap.set(pid, name.replace(/[\u{0080}-\u{FFFF}]/gu, '').replace(/\u202e/g, '')); +} + +/** + * Updates a community's info in the map. + */ +export function updateCommunityHash(community: InferSchemaType): void { + if (community.title_id === undefined || + community.olive_community_id === undefined || + community.name === undefined + ) { + return; + } + + for (const title_id of community.title_id) { + communityMap.set(title_id, community.name); + communityMap.set(title_id + '-id', community.olive_community_id); + } + communityMap.set(community.olive_community_id, community.name); +} + +// TODO - This doesn't belong here, just hacking it in. Gonna redo this whole server anyway so fuck it +export const INVALID_POST_BODY_REGEX = /[^\p{L}\p{P}\d\n\r$^¨←→↑↓√¦⇒⇔¤¢€£¥™©®+×÷=±∞˘˙¸˛˜°¹²³♭♪¬¯¼½¾♡♥●◆■▲▼☆★♀♂<> ]/gu; + +export async function createUser(pid: number, experience: number, notifications: boolean): Promise { + const pnid = await getUserAccountData(pid); + if (!pnid) { + return; + } + + const name = pnid.mii?.name ?? 'Default'; + + const newSettings = { + pid: pid, + screen_name: name, + game_skill: experience, + receive_notifications: notifications + }; + const newContent = { + pid: pid + }; + const newSettingsObj = new SETTINGS(newSettings); + await newSettingsObj.save(); + + const newContentObj = new CONTENT(newContent); + await newContentObj.save(); + + setName(pid, name); +} + +export function decodeParamPack(paramPack: string): ParamPack { + const values = Buffer.from(paramPack, 'base64').toString().split('\\'); + const entries = values.filter(value => value).reduce((entries: string[][], value: string, index: number) => { + if (0 === index % 2) { + entries.push([value]); + } else { + entries[Math.ceil(index / 2 - 1)].push(value); + } + + return entries; + }, []); + + return Object.fromEntries(entries); +} + +export function getPIDFromServiceToken(token: string): number | null { + try { + const decryptedToken = decryptToken(Buffer.from(token, 'base64')); + + if (!decryptedToken) { + return null; + } + + const unpackedToken = unpackServiceToken(decryptedToken); + + // * Only allow token types 1 (Wii U) and 2 (3DS) + if (unpackedToken.system_type !== 1 && unpackedToken.system_type !== 2) { + return null; + } + + // * Check if the token is expired + if (unpackedToken.issue_time + (24n * 3600n * 1000n) < Date.now()) { + return null; + } + + return unpackedToken.pid; + } catch (e) { + logger.error(e, 'Failed to extract PID from service token'); + return null; + } +} + +function decryptToken(token: Buffer): Buffer { + const iv = Buffer.alloc(16); + + const expectedChecksum = token.readUint32BE(); + const encryptedBody = token.subarray(4); + + const decipher = crypto.createDecipheriv('aes-256-cbc', Buffer.from(config.aesKey, 'hex'), iv); + + const decrypted = Buffer.concat([ + decipher.update(encryptedBody), + decipher.final() + ]); + + if (expectedChecksum !== crc32(decrypted)) { + throw new Error('Checksum did not match. Failed decrypt. Are you using the right key?'); + } + + return decrypted; +} + +export function unpackServiceToken(token: Buffer): ServiceToken { + return { + system_type: token.readUInt8(0x0), + token_type: token.readUInt8(0x1), + pid: token.readUInt32LE(0x2), + issue_time: token.readBigUInt64LE(0x6), + title_id: token.readBigUInt64LE(0xE), + access_level: token.readInt8(0x16) + }; +} + +export function getReasonMap(): string[] { + return [ + 'Spoiler', + 'Personal Information', + 'Violent Content', + 'Inappropriate/Harmful Conduct', + 'Hateful/Bullying', + 'Advertising', + 'Sexually Explicit', + 'Piracy', + 'Inappropriate Behavior in Game', + 'Other', + 'Missing Images; Reach out to Jemma with post link to fix' + ]; +} + +export function processLanguage(paramPack?: ParamPack): typeof translations.EN { + if (!paramPack) { + return translations.EN; + } + switch (paramPack.language_id) { + case '0': + return translations.JA; + case '1': + return translations.EN; + case '2': + return translations.FR; + case '3': + return translations.DE; + case '4': + return translations.IT; + case '5': + return translations.ES; + case '6': + return translations.ZH; + case '7': + return translations.KO; + case '8': + return translations.NL; + case '9': + return translations.PT; + case '10': + return translations.RU; + case '11': + return translations.ZH; + default: + return translations.EN; + } +} + +export async function uploadCDNAsset(key: string, data: Buffer, acl: ObjectCannedACL): Promise { + const awsPutParams = new PutObjectCommand({ + Body: data, + Key: key, + Bucket: config.s3.bucket, + ACL: acl + }); + try { + await s3.send(awsPutParams); + return true; + } catch (e) { + logger.error(e, 'Could not upload to CDN'); + return false; + } +} + +export async function newNotification(notification: Notification): Promise | null> { + const now = new Date(); + if (notification.type === 'follow') { + // { pid: userToFollowContent.pid, type: "follow", objectID: req.pid, link: `/users/${req.pid}` } + let existingNotification = await NOTIFICATION.findOne({ pid: notification.pid, objectID: notification.objectID }); + if (existingNotification) { + existingNotification.lastUpdated = now; + existingNotification.read = false; + return existingNotification.save(); + } + const last60min = new Date(now.getTime() - 60 * 60 * 1000); + existingNotification = await NOTIFICATION.findOne({ pid: notification.pid, type: 'follow', lastUpdated: { $gte: last60min } }); + if (existingNotification) { + existingNotification.users.push({ + user: notification.objectID, + timestamp: now + }); + existingNotification.lastUpdated = now; + existingNotification.link = notification.link; + existingNotification.objectID = notification.objectID; + existingNotification.read = false; + return existingNotification.save(); + } else { + const newNotification = new NOTIFICATION({ + pid: notification.pid, + type: notification.type, + users: [{ + user: notification.objectID, + timestamp: now + }], + link: notification.link, + objectID: notification.objectID, + read: false, + lastUpdated: now + }); + return newNotification.save(); + } + } else if (notification.type == 'notice') { + const newNotification = new NOTIFICATION({ + pid: notification.pid, + type: notification.type, + text: notification.text, + image: notification.image, + link: notification.link, + read: false, + lastUpdated: now + }); + return newNotification.save(); + } + /* else if(notification.type === 'yeah') { + // { pid: userToFollowContent.pid, type: "follow", objectID: req.pid, link: `/users/${req.pid}` } + let existingNotification = await NOTIFICATION.findOne({ pid: notification.pid, objectID: notification.objectID }) + if(existingNotification) { + existingNotification.lastUpdated = new Date(); + return await existingNotification.save(); + } + existingNotification = await NOTIFICATION.findOne({ pid: notification.pid, type: 'yeah' }); + if(existingNotification) { + existingNotification.users.push({ + user: notification.objectID, + timeStamp: new Date() + }); + existingNotification.lastUpdated = new Date(); + existingNotification.link = notification.link; + existingNotification.objectID = notification.objectID; + return await existingNotification.save(); + } + else { + let newNotification = new NOTIFICATION({ + pid: notification.pid, + type: notification.type, + users: [{ + user: notification.objectID, + timestamp: new Date() + }], + link: notification.link, + objectID: notification.objectID, + read: false, + lastUpdated: new Date() + }); + await newNotification.save(); + } + } */ + return null; +} + +export async function getUserFriendPIDs(pid: number): Promise { + const response = await gRPCFriendsClient.getUserFriendPIDs({ + pid: pid + }, { + metadata: Metadata({ + 'X-API-Key': config.grpc.friends.apiKey + }) + }); + + return response.pids; +} + +export async function getUserFriendRequestsIncoming(pid: number): Promise { + const response = await gRPCFriendsClient.getUserFriendRequestsIncoming({ + pid: pid + }, { + metadata: Metadata({ + 'X-API-Key': config.grpc.friends.apiKey + }) + }); + + return response.friendRequests; +} + +export function getUserAccountData(pid: number): Promise { + return gRPCAccountClient.getUserData({ + pid: pid + }, { + metadata: Metadata({ + 'X-API-Key': config.grpc.account.apiKey + }) + }); +} + +export async function getUserDataFromToken(token: string): Promise { + return gRPCApiClient.getUserData({}, { + metadata: Metadata({ + 'X-API-Key': config.grpc.account.apiKey, + 'X-Token': token + }) + }); +} + +export async function login(username: string, password: string): Promise { + return await gRPCApiClient.login({ + username: username, + password: password, + grantType: 'password' + }, { + metadata: Metadata({ + 'X-API-Key': config.grpc.account.apiKey + }) + }); +} + +/* Unused until refresh token auth is implemented */ +// export async function refreshLogin(refreshToken: string): Promise { +// return await gRPCApiClient.login({ +// refreshToken: refreshToken +// }, { +// metadata: Metadata({ +// 'X-API-Key': config.grpc.account.apiKey +// }) +// }); +// } + +export async function createLogEntry(actor: number, action: string, target: string, context: string, fields: string[]): Promise { + const newLog = new LOGS({ + actor: actor, + action: action, + target: target, + context: context, + changed_fields: fields + }); + await newLog.save(); +} From 63bcbf221e8912c582f9b66b4ae8f8adecc044e4 Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Fri, 27 Jun 2025 23:05:35 +1000 Subject: [PATCH 030/189] chore(auth): Intorduce enums for token/system type, enforce service tokens --- .../common/{token.ts => service-token.ts} | 0 .../src/types/common/system-types.ts | 6 +++++ .../src/types/common/token-types.ts | 7 +++++ apps/juxtaposition-ui/src/util.ts | 16 +++++++++--- apps/miiverse-api/src/middleware/auth.ts | 4 +-- .../common/{token.ts => service-token.ts} | 0 .../src/types/common/system-types.ts | 6 +++++ .../src/types/common/token-types.ts | 7 +++++ apps/miiverse-api/src/util.ts | 26 +++++++++++++------ 9 files changed, 59 insertions(+), 13 deletions(-) rename apps/juxtaposition-ui/src/types/common/{token.ts => service-token.ts} (100%) create mode 100644 apps/juxtaposition-ui/src/types/common/system-types.ts create mode 100644 apps/juxtaposition-ui/src/types/common/token-types.ts rename apps/miiverse-api/src/types/common/{token.ts => service-token.ts} (100%) create mode 100644 apps/miiverse-api/src/types/common/system-types.ts create mode 100644 apps/miiverse-api/src/types/common/token-types.ts diff --git a/apps/juxtaposition-ui/src/types/common/token.ts b/apps/juxtaposition-ui/src/types/common/service-token.ts similarity index 100% rename from apps/juxtaposition-ui/src/types/common/token.ts rename to apps/juxtaposition-ui/src/types/common/service-token.ts diff --git a/apps/juxtaposition-ui/src/types/common/system-types.ts b/apps/juxtaposition-ui/src/types/common/system-types.ts new file mode 100644 index 00000000..1edbac75 --- /dev/null +++ b/apps/juxtaposition-ui/src/types/common/system-types.ts @@ -0,0 +1,6 @@ +export enum SystemType { + WUP = 1, + CTR = 2, + API = 3, + PasswordReset = 0xFF // * This kinda blows +} diff --git a/apps/juxtaposition-ui/src/types/common/token-types.ts b/apps/juxtaposition-ui/src/types/common/token-types.ts new file mode 100644 index 00000000..241372c2 --- /dev/null +++ b/apps/juxtaposition-ui/src/types/common/token-types.ts @@ -0,0 +1,7 @@ +export enum TokenType { + OAuthAccess = 1, + OAuthRefresh = 2, + NEX = 3, + IndependentService = 4, + PasswordReset = 5 +} diff --git a/apps/juxtaposition-ui/src/util.ts b/apps/juxtaposition-ui/src/util.ts index 5058adde..1e3bbc7a 100644 --- a/apps/juxtaposition-ui/src/util.ts +++ b/apps/juxtaposition-ui/src/util.ts @@ -14,12 +14,14 @@ import { CONTENT } from '@/models/content'; import { SETTINGS } from '@/models/settings'; import { LOGS } from '@/models/logs'; import { config } from '@/config'; +import { SystemType } from '@/types/common/system-types'; +import { TokenType } from '@/types/common/token-types'; import translations from './translations'; import type { ObjectCannedACL } from '@aws-sdk/client-s3'; import type { NotificationSchema } from '@/models/notifications'; import type { CommunitySchema } from '@/models/communities'; import type { ParamPack } from '@/types/common/param-pack'; -import type { ServiceToken } from '@/types/common/token'; +import type { ServiceToken } from '@/types/common/service-token'; import type { InferSchemaType } from 'mongoose'; import type { Notification } from '@/types/juxt/notification'; import type { GetUserDataResponse as AccountGetUserDataResponse } from '@pretendonetwork/grpc/account/get_user_data_rpc'; @@ -165,9 +167,12 @@ export function getPIDFromServiceToken(token: string): number | null { } const unpackedToken = unpackServiceToken(decryptedToken); + if (unpackedToken === null) { + return null; + } // * Only allow token types 1 (Wii U) and 2 (3DS) - if (unpackedToken.system_type !== 1 && unpackedToken.system_type !== 2) { + if (unpackedToken.system_type !== SystemType.CTR && unpackedToken.system_type !== SystemType.WUP) { return null; } @@ -203,7 +208,12 @@ function decryptToken(token: Buffer): Buffer { return decrypted; } -export function unpackServiceToken(token: Buffer): ServiceToken { +export function unpackServiceToken(token: Buffer): ServiceToken | null { + const token_type = token.readUInt8(0x1); + if (token_type !== TokenType.IndependentService) { + return null; + } + return { system_type: token.readUInt8(0x0), token_type: token.readUInt8(0x1), diff --git a/apps/miiverse-api/src/middleware/auth.ts b/apps/miiverse-api/src/middleware/auth.ts index dd8a67f7..5cda8b68 100644 --- a/apps/miiverse-api/src/middleware/auth.ts +++ b/apps/miiverse-api/src/middleware/auth.ts @@ -43,8 +43,8 @@ async function auth(request: express.Request, response: express.Response, next: return badRequest(response, ApiErrorCode.NO_TOKEN); } - const pid: number = getPIDFromServiceToken(encryptedToken); - if (pid === 0) { + const pid = getPIDFromServiceToken(encryptedToken); + if (pid === null) { return badRequest(response, ApiErrorCode.BAD_TOKEN); } diff --git a/apps/miiverse-api/src/types/common/token.ts b/apps/miiverse-api/src/types/common/service-token.ts similarity index 100% rename from apps/miiverse-api/src/types/common/token.ts rename to apps/miiverse-api/src/types/common/service-token.ts diff --git a/apps/miiverse-api/src/types/common/system-types.ts b/apps/miiverse-api/src/types/common/system-types.ts new file mode 100644 index 00000000..1edbac75 --- /dev/null +++ b/apps/miiverse-api/src/types/common/system-types.ts @@ -0,0 +1,6 @@ +export enum SystemType { + WUP = 1, + CTR = 2, + API = 3, + PasswordReset = 0xFF // * This kinda blows +} diff --git a/apps/miiverse-api/src/types/common/token-types.ts b/apps/miiverse-api/src/types/common/token-types.ts new file mode 100644 index 00000000..241372c2 --- /dev/null +++ b/apps/miiverse-api/src/types/common/token-types.ts @@ -0,0 +1,7 @@ +export enum TokenType { + OAuthAccess = 1, + OAuthRefresh = 2, + NEX = 3, + IndependentService = 4, + PasswordReset = 5 +} diff --git a/apps/miiverse-api/src/util.ts b/apps/miiverse-api/src/util.ts index d15a4b08..d42d53e6 100644 --- a/apps/miiverse-api/src/util.ts +++ b/apps/miiverse-api/src/util.ts @@ -10,12 +10,14 @@ import { FriendsDefinition } from '@pretendonetwork/grpc/friends/friends_service import { AccountDefinition } from '@pretendonetwork/grpc/account/account_service'; import { config } from '@/config'; import { logger } from '@/logger'; +import { SystemType } from '@/types/common/system-types'; +import { TokenType } from '@/types/common/token-types'; import type { FriendRequest } from '@pretendonetwork/grpc/friends/friend_request'; import type { GetUserDataResponse } from '@pretendonetwork/grpc/account/get_user_data_rpc'; import type { ParsedQs } from 'qs'; import type { IncomingHttpHeaders } from 'node:http'; import type { ParamPack } from '@/types/common/param-pack'; -import type { ServiceToken } from '@/types/common/token'; +import type { ServiceToken } from '@/types/common/service-token'; // * nice-grpc doesn't export ChannelImplementation so this can't be typed const gRPCFriendsChannel = createChannel(`${config.grpc.friends.host}:${config.grpc.friends.port}`); @@ -48,30 +50,33 @@ export function decodeParamPack(paramPack: string): ParamPack { return Object.fromEntries(entries); } -export function getPIDFromServiceToken(token: string): number { +export function getPIDFromServiceToken(token: string): number | null { try { const decryptedToken = decryptToken(Buffer.from(token, 'base64')); if (!decryptedToken) { - return 0; + return null; } const unpackedToken = unpackServiceToken(decryptedToken); + if (unpackedToken === null) { + return null; + } // * Only allow token types 1 (Wii U) and 2 (3DS) - if (unpackedToken.system_type !== 1 && unpackedToken.system_type !== 2) { - return 0; + if (unpackedToken.system_type !== SystemType.CTR && unpackedToken.system_type !== SystemType.WUP) { + return null; } // * Check if the token is expired if (unpackedToken.issue_time + (24n * 3600n * 1000n) < Date.now()) { - return 0; + return null; } return unpackedToken.pid; } catch (e) { logger.error(e, 'Failed to extract PID from service token'); - return 0; + return null; } } @@ -95,7 +100,12 @@ export function decryptToken(token: Buffer): Buffer { return decrypted; } -export function unpackServiceToken(token: Buffer): ServiceToken { +export function unpackServiceToken(token: Buffer): ServiceToken | null { + const token_type = token.readUInt8(0x1); + if (token_type !== TokenType.IndependentService) { + return null; + } + return { system_type: token.readUInt8(0x0), token_type: token.readUInt8(0x1), From 054c43dfe575b65ba5ff0b97aee28f40bfe6e4a2 Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Mon, 30 Jun 2025 16:37:24 +1000 Subject: [PATCH 031/189] fix(internal): Null safety on auth check --- .../src/services/internal/middleware/auth-populate.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/miiverse-api/src/services/internal/middleware/auth-populate.ts b/apps/miiverse-api/src/services/internal/middleware/auth-populate.ts index 3d06cfb9..21969a8e 100644 --- a/apps/miiverse-api/src/services/internal/middleware/auth-populate.ts +++ b/apps/miiverse-api/src/services/internal/middleware/auth-populate.ts @@ -42,7 +42,7 @@ export async function authPopulate(request: express.Request, response: express.R async function consoleAuth(_request: express.Request, serviceToken: string): Promise { const pid = getPIDFromServiceToken(serviceToken); - if (pid === 0) { + if (pid === null) { throw new errors.unauthorized('Invalid service token'); } From a2406f2dee6e18ddf2739f18832ad291a185615c Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Mon, 30 Jun 2025 17:25:44 +1000 Subject: [PATCH 032/189] chore(util): Make decodeParamPack much less clever dumb fox wants dumb code. filter reduce? index math? pls just put the things in the struct --- apps/juxtaposition-ui/src/util.ts | 38 +++++++++++++++++++++++-------- apps/miiverse-api/src/util.ts | 38 +++++++++++++++++++++++-------- 2 files changed, 58 insertions(+), 18 deletions(-) diff --git a/apps/juxtaposition-ui/src/util.ts b/apps/juxtaposition-ui/src/util.ts index 1e3bbc7a..73715a0c 100644 --- a/apps/juxtaposition-ui/src/util.ts +++ b/apps/juxtaposition-ui/src/util.ts @@ -144,18 +144,38 @@ export async function createUser(pid: number, experience: number, notifications: } export function decodeParamPack(paramPack: string): ParamPack { - const values = Buffer.from(paramPack, 'base64').toString().split('\\'); - const entries = values.filter(value => value).reduce((entries: string[][], value: string, index: number) => { - if (0 === index % 2) { - entries.push([value]); - } else { - entries[Math.ceil(index / 2 - 1)].push(value); + const values = Buffer.from(paramPack, 'base64').toString().split('\\').filter(v => v.length > 0).values(); + const entries: Record = {}; + for (let i = 0; i < 16; i++) { /* Enforce an upper limit on ParamPack decoding */ + // Keys and values are sibling list entries + const paramKey = values.next().value; + const paramVal = values.next().value; + // We hit the end of the list + if (paramKey === undefined || paramVal === undefined) { + break; } - return entries; - }, []); + entries[paramKey] = paramVal; + } - return Object.fromEntries(entries); + // normalize and prevent any funny businiess from clients + // one day this can be a proper DTO + return { + title_id: entries.title_id ?? '', + access_key: entries.access_key ?? '', + platform_id: entries.platform_id ?? '', + region_id: entries.region_id ?? '', + language_id: entries.language_id ?? '', + country_id: entries.country_id ?? '', + area_id: entries.area_id ?? '', + network_restriction: entries.network_restriction ?? '', + friend_restriction: entries.friend_restriction ?? '', + rating_restriction: entries.rating_restriction ?? '', + rating_organization: entries.rating_organization ?? '', + transferable_id: entries.transferable_id ?? '', + tz_name: entries.tz_name ?? '', + utc_offset: entries.utc_offset ?? '' + }; } export function getPIDFromServiceToken(token: string): number | null { diff --git a/apps/miiverse-api/src/util.ts b/apps/miiverse-api/src/util.ts index 570d4bd0..8e0033a0 100644 --- a/apps/miiverse-api/src/util.ts +++ b/apps/miiverse-api/src/util.ts @@ -41,18 +41,38 @@ const s3 = new aws.S3({ export const INVALID_POST_BODY_REGEX = /[^\p{L}\p{P}\d\n\r$^¨←→↑↓√¦⇒⇔¤¢€£¥™©®+×÷=±∞˘˙¸˛˜°¹²³♭♪¬¯¼½¾♡♥●◆■▲▼☆★♀♂<> ]/gu; export function decodeParamPack(paramPack: string): ParamPack { - const values = Buffer.from(paramPack, 'base64').toString().split('\\'); - const entries = values.filter(value => value).reduce((entries: string[][], value: string, index: number) => { - if (0 === index % 2) { - entries.push([value]); - } else { - entries[Math.ceil(index / 2 - 1)].push(value); + const values = Buffer.from(paramPack, 'base64').toString().split('\\').filter(v => v.length > 0).values(); + const entries: Record = {}; + for (let i = 0; i < 16; i++) { /* Enforce an upper limit on ParamPack decoding */ + // Keys and values are sibling list entries + const paramKey = values.next().value; + const paramVal = values.next().value; + // We hit the end of the list + if (paramKey === undefined || paramVal === undefined) { + break; } - return entries; - }, []); + entries[paramKey] = paramVal; + } - return Object.fromEntries(entries); + // normalize and prevent any funny businiess from clients + // one day this can be a proper DTO + return { + title_id: entries.title_id ?? '', + access_key: entries.access_key ?? '', + platform_id: entries.platform_id ?? '', + region_id: entries.region_id ?? '', + language_id: entries.language_id ?? '', + country_id: entries.country_id ?? '', + area_id: entries.area_id ?? '', + network_restriction: entries.network_restriction ?? '', + friend_restriction: entries.friend_restriction ?? '', + rating_restriction: entries.rating_restriction ?? '', + rating_organization: entries.rating_organization ?? '', + transferable_id: entries.transferable_id ?? '', + tz_name: entries.tz_name ?? '', + utc_offset: entries.utc_offset ?? '' + }; } export function getPIDFromServiceToken(token: string): number | null { From eb044b5755487a061cd93b40d9f016ee6d11d197 Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Mon, 30 Jun 2025 17:34:49 +1000 Subject: [PATCH 033/189] chore(util): Refactor processLanguage --- apps/juxtaposition-ui/src/util.ts | 45 ++++++++++++------------------- 1 file changed, 17 insertions(+), 28 deletions(-) diff --git a/apps/juxtaposition-ui/src/util.ts b/apps/juxtaposition-ui/src/util.ts index 73715a0c..92ec8e19 100644 --- a/apps/juxtaposition-ui/src/util.ts +++ b/apps/juxtaposition-ui/src/util.ts @@ -264,34 +264,23 @@ export function processLanguage(paramPack?: ParamPack): typeof translations.EN { if (!paramPack) { return translations.EN; } - switch (paramPack.language_id) { - case '0': - return translations.JA; - case '1': - return translations.EN; - case '2': - return translations.FR; - case '3': - return translations.DE; - case '4': - return translations.IT; - case '5': - return translations.ES; - case '6': - return translations.ZH; - case '7': - return translations.KO; - case '8': - return translations.NL; - case '9': - return translations.PT; - case '10': - return translations.RU; - case '11': - return translations.ZH; - default: - return translations.EN; - } + const languageIdMap: Record = { + 0: 'JA', + 1: 'EN', + 2: 'FR', + 3: 'DE', + 4: 'IT', + 5: 'ES', + 6: 'ZH', + 7: 'KO', + 8: 'NL', + 9: 'PT', + 10: 'RU', + 11: 'ZH' + }; + + const language = languageIdMap[paramPack.language_id] ?? 'EN'; + return translations[language]; } export async function uploadCDNAsset(key: string, data: Buffer, acl: ObjectCannedACL): Promise { From 0d03a12c51d54e753ef9fc17fb5cd953d0184c7e Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Mon, 30 Jun 2025 17:41:25 +1000 Subject: [PATCH 034/189] fix: don't hang in resizeImage --- apps/juxtaposition-ui/src/images.ts | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/apps/juxtaposition-ui/src/images.ts b/apps/juxtaposition-ui/src/images.ts index 598e9d01..70f21b7a 100644 --- a/apps/juxtaposition-ui/src/images.ts +++ b/apps/juxtaposition-ui/src/images.ts @@ -57,16 +57,22 @@ export async function processPainting(painting: string): Promise return PNG.sync.write(png); } -export async function resizeImage(file: string, width: number, height: number): Promise { - return new Promise(function (resolve) { - const image = Buffer.from(file, 'base64'); - sharp(image) - .resize({ height: height, width: width }) - .toBuffer() - .then((data) => { - resolve(data); - }).catch(err => logger.error(err, 'Could not resize image')); - }); +/** + * Rezise an image. + * @param data base64-encoded input image, most codecs OK (check Sharp docs) + * @param width Target width in pixels + * @param height Target height in pixels + * @returns New image, same codec as the input (not base64'd!) + */ +export async function resizeImage(data: string, width: number, height: number): Promise { + const image = Buffer.from(data, 'base64'); + return sharp(image) + .resize({ height, width }) + .toBuffer() + .catch((err) => { + logger.error(err, 'Could not resize image!'); + throw err; + }); } export async function getTGAFromPNG(image: Buffer): Promise { From 9491bb097ce82f1ee4de3c7247c7351af3037178 Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Mon, 30 Jun 2025 17:42:18 +1000 Subject: [PATCH 035/189] fix: Fix callsites for processPainting we removed the bool argument earlier but forgot to delete it from some files --- .../src/services/juxt-web/routes/console/messages.jsx | 2 +- .../src/services/juxt-web/routes/console/posts.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/juxtaposition-ui/src/services/juxt-web/routes/console/messages.jsx b/apps/juxtaposition-ui/src/services/juxt-web/routes/console/messages.jsx index 6fc81549..e377a933 100644 --- a/apps/juxtaposition-ui/src/services/juxt-web/routes/console/messages.jsx +++ b/apps/juxtaposition-ui/src/services/juxt-web/routes/console/messages.jsx @@ -71,7 +71,7 @@ router.post('/new', async function (req, res) { let screenshot = null; if (req.body._post_type === 'painting' && req.body.painting) { painting = req.body.painting.replace(/\0/g, '').trim(); - paintingURI = await processPainting(painting, true); + paintingURI = await processPainting(painting); if (!await uploadCDNAsset(`paintings/${req.pid}/${postID}.png`, paintingURI, 'public-read')) { res.status(422); return res.render(req.directory + '/error.ejs', { diff --git a/apps/juxtaposition-ui/src/services/juxt-web/routes/console/posts.js b/apps/juxtaposition-ui/src/services/juxt-web/routes/console/posts.js index 6eb29c58..8a67c99e 100644 --- a/apps/juxtaposition-ui/src/services/juxt-web/routes/console/posts.js +++ b/apps/juxtaposition-ui/src/services/juxt-web/routes/console/posts.js @@ -264,7 +264,7 @@ async function newPost(req, res) { } else { painting = req.body.painting; } - paintingURI = await processPainting(painting, true); + paintingURI = await processPainting(painting); if (!await util.uploadCDNAsset(`paintings/${req.pid}/${postID}.png`, paintingURI, 'public-read')) { res.status(422); return res.render(req.directory + '/error.ejs', { From 69017e22ff087ebe5c12e23774cc1c810b950691 Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Mon, 30 Jun 2025 17:43:12 +1000 Subject: [PATCH 036/189] fix: Add type annotiation for TGA --- apps/juxtaposition-ui/src/images.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/juxtaposition-ui/src/images.ts b/apps/juxtaposition-ui/src/images.ts index 70f21b7a..e2f87133 100644 --- a/apps/juxtaposition-ui/src/images.ts +++ b/apps/juxtaposition-ui/src/images.ts @@ -42,7 +42,7 @@ export async function processPainting(painting: string): Promise logger.error(err, 'Could not decompress painting'); return null; } - let tga; + let tga: TGA; try { tga = new TGA(Buffer.from(output.buffer)); } catch (e) { @@ -78,7 +78,7 @@ export async function resizeImage(data: string, width: number, height: number): export async function getTGAFromPNG(image: Buffer): Promise { const pngData = await imagePixels(Buffer.from(image)); const tga = TGA.createTgaBuffer(pngData.width, pngData.height, pngData.data); - let output; + let output: Uint8Array; try { output = deflate(tga, { level: 6 }); } catch (err) { From 1604600ef9c34743fb417af3b4d22dbc82f24651 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnau=20B=C3=A0rcia?= Date: Fri, 3 Nov 2023 02:14:14 +0000 Subject: [PATCH 037/189] locales(update): Updated Catalan locale --- .../juxtaposition-ui/src/translations/ca.json | 79 ++++++++++++++++++- 1 file changed, 78 insertions(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/ca.json b/apps/juxtaposition-ui/src/translations/ca.json index 0967ef42..54ac82fd 100644 --- a/apps/juxtaposition-ui/src/translations/ca.json +++ b/apps/juxtaposition-ui/src/translations/ca.json @@ -1 +1,78 @@ -{} +{ + "global": { + "communities": "Comunitats", + "more": "Carregar més publicacions", + "next": "Següent", + "messages": "Missatges", + "activity_feed": "Registre d'activitat", + "exit": "Sortir", + "back": "Enrere", + "notifications": "Notificacions", + "save": "Desa", + "no_posts": "No hi ha publicacions", + "private": "Privat", + "close": "Tancar", + "user_page": "Pàgina d'usuari", + "go_back": "Torna" + }, + "notifications": { + "none": "No hi ha notificacions.", + "new_follower": "t'ha seguit!" + }, + "user_page": { + "follow_user": "Seguir", + "game_experience": "Experiència jugant", + "no_following": "No segueix a ningú", + "befriend": "Fes-te amic", + "posts": "Publicacions", + "friends": "Amics", + "following_user": "Seguint", + "pending": "Pendent", + "followers": "Seguidors", + "no_followers": "No hi ha seguidors", + "no_friends": "Sense amics", + "birthday": "Aniversari", + "country": "País", + "following": "Seguint" + }, + "community": { + "new": "Publicació nova", + "posts": "Publicacions", + "tags": "Etiquetes", + "followers": "Seguidors", + "following": "Seguint", + "follow": "Segueix aquesta comunitat", + "verified": "Publicacions verificades", + "recent": "Publicaciones recents", + "popular": "Publicacions populars" + }, + "user_settings": { + "show_game": "Mostrar experiència al perfil", + "show_comment": "Mostra el teu comentari al perfil", + "show_birthday": "Mostra el teu aniversari al perfil", + "profile_settings": "Configuració del perfil", + "profile_comment": "Comentari del perfil", + "swearing": "El comentari del perfil no pot contenir llenguatge explícit o inapropiat.", + "show_country": "Mostra el teu país al perfil" + }, + "new_post": { + "text_hint": "Toca aquí per fer una publicació.", + "new_post_text": "Publicació nova", + "post_to": "Publica a" + }, + "all_communities": { + "show_all": "Mostrar tot", + "search": "Cerca comunitats...", + "text": "Totes les comunitats", + "ann_string": "Toca aquí per veure els anuncis recents!", + "new_communities": "Noves Comunitats", + "popular_places": "Comunitats Populars" + }, + "language": "Català", + "activity_feed": { + "empty": "Aquí està buit. Pots provar de seguir algú!" + }, + "setup": { + "welcome": "Benvingut a Juxtaposition!" + } +} From c1564554da03e27d1cb56019714c6b0045d0ddcc Mon Sep 17 00:00:00 2001 From: Maxime Tourneur Date: Sun, 19 Nov 2023 16:54:15 +0000 Subject: [PATCH 038/189] locales(update): Updated French locale --- apps/juxtaposition-ui/src/translations/fr.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/fr.json b/apps/juxtaposition-ui/src/translations/fr.json index 5e806591..010492ee 100644 --- a/apps/juxtaposition-ui/src/translations/fr.json +++ b/apps/juxtaposition-ui/src/translations/fr.json @@ -1,15 +1,15 @@ { "language": "Français", "global": { - "user_page": "Profil", + "user_page": "Page utilisateur", "activity_feed": "Fil d'Actualité", "communities": "Communautés", "messages": "Messages", "notifications": "Notifications", "go_back": "Retour", "back": "Retour", - "yeahs": "Ouais", - "more": "Afficher Plus", + "yeahs": "Ouais !", + "more": "Afficher plus de publications", "no_posts": "Aucune Publication", "private": "Privés", "close": "Fermer", From b1bf73f91aa487f7d4fae0f59c50cb3d11a53530 Mon Sep 17 00:00:00 2001 From: Daniel Adam Coats Date: Tue, 21 Nov 2023 20:17:26 +0000 Subject: [PATCH 039/189] locales(update): Updated Czech locale --- apps/juxtaposition-ui/src/translations/cs.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/cs.json b/apps/juxtaposition-ui/src/translations/cs.json index 64d44c35..3416c753 100644 --- a/apps/juxtaposition-ui/src/translations/cs.json +++ b/apps/juxtaposition-ui/src/translations/cs.json @@ -70,7 +70,7 @@ "new_post": { "new_post_text": "Nový příspěvek", "swearing": "Příspěvky nesmí obsahovat nevhodné výrazy.", - "text_hint": "Klikněte zde pro vytvoření příspěvku.", + "text_hint": "Klikněte sem pro vytvoření příspěvku.", "post_to": "Přispět do" }, "setup": { From 13c16c90b9277e56da7666d9288701cf0d05dfea Mon Sep 17 00:00:00 2001 From: Antonio Carter Date: Fri, 24 Nov 2023 14:17:42 +0000 Subject: [PATCH 040/189] locales(update): Updated Greek locale --- apps/juxtaposition-ui/src/translations/el.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/el.json b/apps/juxtaposition-ui/src/translations/el.json index addfdfa8..ac057ac0 100644 --- a/apps/juxtaposition-ui/src/translations/el.json +++ b/apps/juxtaposition-ui/src/translations/el.json @@ -1,12 +1,12 @@ { "global": { "back": "Πίσω", - "communities": "κοινότητες", + "communities": "Κοινότητες", "exit": "Έξοδος", "activity_feed": "Ροή δραστηριότητας", "messages": "Μηνύματα", "notifications": "Ειδοποιήσεις", - "go_back": "Πίσω", + "go_back": "Πήγαινε Πίσω", "yeahs": "Ναιs", "no_posts": "Δεν υπάρχουν δημοσιεύσεις", "more": "Φόρτωση περισσότερων δημοσιεύσεων", @@ -25,7 +25,7 @@ "search": "Αναζήτηση κοινοτήτων...", "show_all": "Προβολή όλων" }, - "language": "Γλώσσα", + "language": "Ελληνικά", "community": { "follow": "Εγγραφή στην κοινότητα", "following": "Εγγραφήκατε", @@ -104,7 +104,7 @@ "ninth": "Μερικοί άνθρωποι έρχονται στο Juxt αναζητώντας συμβουλές και κόλπα για παιχνίδια, αλλά άλλοι θέλουν να ανακαλύψουν τα μυστικά ενός παιχνιδιού μόνοι τους. Οι δημοσιεύσεις που αποκαλύπτουν μυστικά ενός παιχνιδιού ή της ιστορίας του ονομάζονται \"σπόιλερ\". Εάν δημοσιεύετε κάτι για ένα παιχνίδι που μπορεί να είναι spoiler, φροντίστε να ελέγξετε το πλαίσιο Spoilers πριν στείλετε τη δημοσίευσή σας. Με αυτόν τον τρόπο, τα άτομα που δεν θέλουν να κακομαθαίνουν δεν θα βλέπουν την ανάρτησή σας." }, "welcome": "Καλώς ήρθατε στο Juxtaposition!", - "info_text": "Το Juxt είναι μια κοινότητα παιχνιδιών με γνώμονα τον χρήστη, όπου μπορείτε να αλληλεπιδράσετε με ανθρώπους σε όλο τον κόσμο. Μπορείτε να γράφετε ή να σχεδιάζετε αναρτήσεις σε κοινότητες παιχνιδιών ή να στέλνετε μηνύματα απευθείας στους φίλους σας.", + "info_text": "Το Juxt είναι μια κοινότητα παιχνιδιών με γνώμονα τον χρήστη, όπου μπορείτε να αλληλεπιδράσετε με ανθρώπους\nσε όλο τον κόσμο. Μπορείτε να γράφετε ή να σχεδιάζετε αναρτήσεις σε κοινότητες παιχνιδιών ή να στέλνετε μηνύματα απευθείας στους φίλους σας.", "welcome_text": "Το Juxt είναι μια gaming κοινότητα που συνδέει ανθρώπους από όλο τον κόσμο χρησιμοποιώντας χαρακτήρες Mii. Χρησιμοποιήστε το Juxt για να μοιραστείτε τις εμπειρίες σας στα παιχνίδια και να γνωρίσετε άτομα από όλο τον κόσμο.", "google_text": "Το juxtaposition χρησιμοποιεί την υπηρεσία Google Analytics έτσι ώστε να συλλέγει πληροφορίες σχετικά με το πως οι χρήστες χρησιμοποιούν την υπηρεσία μας. Οι πληροφορίες περιλαμβάνουν τον χρόνο επίσκεψης ιστότοπων. Οι πληροφορίες δεν χρησιμοποιούνται εναντίων σας και δεν χρησιμοποιούνται για διαφημίσεις από εμάς ή από την Google.", "experience": "Εμπειρία παιχνιδιού", From 1f71366594b3dd56972ed74768355cb5be8bb4c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wandrille=20Doutt=C3=A9?= Date: Thu, 23 Nov 2023 15:01:52 +0000 Subject: [PATCH 041/189] locales(update): Updated Asturian locale --- .../src/translations/ast.json | 39 ++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/ast.json b/apps/juxtaposition-ui/src/translations/ast.json index 0967ef42..4b2ab7dc 100644 --- a/apps/juxtaposition-ui/src/translations/ast.json +++ b/apps/juxtaposition-ui/src/translations/ast.json @@ -1 +1,38 @@ -{} +{ + "global": { + "communities": "Comunidades", + "more": "Cargar más publicaciones", + "next": "Próximo", + "yeahs": "Sí", + "messages": "Mensajes", + "activity_feed": "Fuente de actividades", + "exit": "Salida", + "back": "Atrás", + "notifications": "Notificaciones", + "save": "Salvar", + "no_posts": "Sin publicaciones", + "private": "Privado", + "close": "Cerrar", + "user_page": "Página de usuario", + "go_back": "Volver" + }, + "community": { + "posts": "Publicaciones", + "tags": "Etiquetas", + "followers": "Seguidores", + "following": "Siguiente", + "follow": "Seguir a la comunidad", + "recent": "Publicaciones recientes", + "popular": "Publicaciones populares" + }, + "all_communities": { + "show_all": "Mostrar todo", + "announcements": "Anuncios", + "search": "Buscar comunidades...", + "text": "Todas las comunidades", + "ann_string": "¡Haga clic aquí para ver los anuncios recientes!", + "new_communities": "Nuevas comunidades", + "popular_places": "Lugares populares" + }, + "language": "Asturies" +} From 1736e0f1844803b3eae4d302e64d98ea834c8091 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wandrille=20Doutt=C3=A9?= Date: Thu, 23 Nov 2023 15:29:46 +0000 Subject: [PATCH 042/189] locales(update): Updated Romanian locale --- apps/juxtaposition-ui/src/translations/ro.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/ro.json b/apps/juxtaposition-ui/src/translations/ro.json index eed8e4f7..fb973113 100644 --- a/apps/juxtaposition-ui/src/translations/ro.json +++ b/apps/juxtaposition-ui/src/translations/ro.json @@ -43,9 +43,9 @@ "game_experience": "Experiență", "posts": "Postări", "friends": "Prieteni", - "following": "Urmărește", + "following": "Următor", "followers": "Urmăritori", - "follow_user": "Urmărește", + "follow_user": "Următor", "following_user": "Urmărești deja", "befriend": "Deveniți prieteni", "unfriend": "Șterge prieten", @@ -86,7 +86,7 @@ }, "info": "Ce e Juxtaposition?", "welcome_text": "Juxt este o comunitate de jocuri care conectează oamenii din jurul lumii folosind personaje Mii. Folosește Juxt pentru a-ți împărtăși experiențele tale din jocuri și a cunoaște oameni din toată lumea.", - "info_text": "Juxt este o comunitate de jocuri de noroc condusă de utilizatori, unde puteți interacționa cu oameni din întreaga lume. Puteți scrie sau desena postări în comunitățile de jocuri sau puteți trimite mesaje direct prietenilor dumneavoastră.", + "info_text": "Juxt este o comunitate de jocuri condusă de utilizatori, unde puteți interacționa cu oamenii\n peste tot în lume. Puteți scrie sau desena postări în comunitățile de jocuri sau puteți trimite mesaje direct prietenilor.", "rules": "Regurile Juxt", "rules_text": { "first": "Următoarele sunt câteva orientări importante pentru a face din Juxt o experiență plăcută și distractivă pentru toată lumea. Codul de conduită Juxt conține informații detaliate, așa că vă rugăm să îl citiți cu atenție.", From b26207040e92e1a86c76ff242ac1c3a7e335bbd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wandrille=20Doutt=C3=A9?= Date: Sun, 26 Nov 2023 18:36:35 +0000 Subject: [PATCH 043/189] locales(update): Updated German locale --- apps/juxtaposition-ui/src/translations/de.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/de.json b/apps/juxtaposition-ui/src/translations/de.json index 863b1b8a..6a4afb93 100644 --- a/apps/juxtaposition-ui/src/translations/de.json +++ b/apps/juxtaposition-ui/src/translations/de.json @@ -8,7 +8,7 @@ "notifications": "Mitteilungen", "go_back": "Zurück", "back": "Zurück", - "yeahs": "Yeahs", + "yeahs": "Jaaa", "more": "Mehr Beiträge laden", "no_posts": "Keine Beiträge", "private": "Privat", From 60ed035dcc0afba42eaa8294aca25c7f002930e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wandrille=20Doutt=C3=A9?= Date: Sun, 26 Nov 2023 18:34:24 +0000 Subject: [PATCH 044/189] locales(update): Updated French locale --- apps/juxtaposition-ui/src/translations/fr.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/fr.json b/apps/juxtaposition-ui/src/translations/fr.json index 010492ee..c5b5b619 100644 --- a/apps/juxtaposition-ui/src/translations/fr.json +++ b/apps/juxtaposition-ui/src/translations/fr.json @@ -6,7 +6,7 @@ "communities": "Communautés", "messages": "Messages", "notifications": "Notifications", - "go_back": "Retour", + "go_back": "aller Retour", "back": "Retour", "yeahs": "Ouais !", "more": "Afficher plus de publications", From 10c0302190a2272fb2f761ddabc20510482fdff8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wandrille=20Doutt=C3=A9?= Date: Mon, 27 Nov 2023 07:28:17 +0000 Subject: [PATCH 045/189] locales(update): Updated Asturian locale --- .../src/translations/ast.json | 92 ++++++++++++++++++- 1 file changed, 90 insertions(+), 2 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/ast.json b/apps/juxtaposition-ui/src/translations/ast.json index 4b2ab7dc..a9f0bdba 100644 --- a/apps/juxtaposition-ui/src/translations/ast.json +++ b/apps/juxtaposition-ui/src/translations/ast.json @@ -23,7 +23,9 @@ "following": "Siguiente", "follow": "Seguir a la comunidad", "recent": "Publicaciones recientes", - "popular": "Publicaciones populares" + "popular": "Publicaciones populares", + "new": "Nueva publicación", + "verified": "Publicaciones verificadas" }, "all_communities": { "show_all": "Mostrar todo", @@ -34,5 +36,91 @@ "new_communities": "Nuevas comunidades", "popular_places": "Lugares populares" }, - "language": "Asturies" + "language": "Asturies", + "setup": { + "rules_text": { + "eleventh": "Nuestro objetivo es hacer que Juxt sea divertido y agradable para todos. En el caso de que alguien infrinja el Código de conducta de Juxt, tomaremos las medidas adecuadas, incluido el bloqueo del usuario o la consola infractores.", + "tenth": "Violaciones del Código de Conducta", + "third": "Juxt contiene muchas comunidades de juegos donde personas de todo el mundo pueden compartir sus opiniones. Cuando publiques en una comunidad, recuerda que todos pueden verlo, así que exprésate de una manera que todos puedan disfrutar. Utilice el sentido común y piense antes de publicar. Juxt es un servicio al que también se puede acceder desde Internet, así que ten en cuenta que las personas que no usan Juxt también pueden ver tus publicaciones. Además, cualquier comentario que hagas en las publicaciones de tus amigos será visto no sólo por tus amigos sino también por personas de todo el mundo. Por favor tenga esto en cuenta.", + "thirteenth": "Si estás publicando en la comunidad de un juego que has jugado, tus publicaciones tendrán un icono que indica que lo has jugado.", + "fifth": "Para que Juxt siga siendo un lugar divertido para todos, le pedimos que sea considerado con otros usuarios. Ayúdanos a mantener una experiencia agradable en Juxt al no publicar nada inapropiado u ofensivo.", + "ninth": "Algunas personas acuden a Juxt en busca de consejos y trucos para juegos, pero otras quieren descubrir los secretos de un juego por su cuenta. Las publicaciones que revelan secretos de un juego o su historia se denominan \"spoilers\". Si estás publicando algo sobre un juego que podría ser un spoiler, asegúrate de marcar la casilla Spoilers antes de enviar tu publicación. De esta manera, las personas que no quieren ser mimadas no verán tu publicación.", + "fourth": "Sean amables los unos con los otros", + "second": "Las publicaciones se pueden ver en todo el mundo", + "sixth": "No publique información personal, suya o de otros", + "first": "Las siguientes son algunas pautas importantes para hacer de Juxt una experiencia divertida y agradable para todos. El Código de Conducta de Juxt contiene información detallada, así que léalo detenidamente.", + "eighth": "No publiques spoilers", + "seventh": "Recuerda, conocer a alguien en Juxt no es lo mismo que conocerlo en la vida real. Nunca comparta su dirección de correo electrónico, dirección particular, nombre del trabajo o la escuela, u otra información de identificación personal con nadie en Juxt, y nunca comparta la información de nadie más. Además, si alguien que conoces en Juxt te invita a conocerlo en el mundo real, no aceptes. Juxt es una comunidad en línea y no debe usarse para organizar reuniones en el mundo real.", + "twelfth": "¿Has jugado a ese juego?" + }, + "beta_text": { + "third": "El sitio web, su software y todo el contenido que se encuentra en él se proporcionan \"tal cual\" y \"según disponibilidad\". Pretendo Network no ofrece ninguna garantía, ya sea expresa o implícita, en cuanto a la idoneidad o usabilidad del sitio web, su software o cualquiera de sus contenidos.", + "second": "Esto puede incluir un borrado total de la base de datos al final o durante el período beta.", + "first": "Estás a punto de probar la primera beta pública de Juxt. Esto significa que todavía hay muchas cosas en el aire, y muchas cosas pueden cambiar en cualquier momento." + }, + "experience_text": { + "expert": "Experto", + "info": "Cuéntanos cómo describirías tu nivel de experiencia con los juegos. Puede cambiar esta configuración más adelante.", + "intermediate": "Intermedio", + "beginner": "Principiante" + }, + "guest_button": "Entiendo", + "done_button": "¡Vamos!", + "guest": "Modo invitado", + "ready": "Listo para empezar a usar Juxt", + "guest_text": "No podemos verificar tu cuenta en este momento, lo que probablemente significa que estás iniciando sesión con una cuenta de Nintendo Network. Podrás seguir navegando por Juxt, pero no podrás hacerlo ¡sí! publica o haz tus propias publicaciones hasta que inicies sesión con una cuenta de Pretendo Network. Para obtener más información, consulte el servidor de Discord.", + "experience": "Experiencia de juego", + "google": "Google Analytics", + "rules": "Reglas de Juxt", + "welcome_text": "Juxt es una comunidad de jugadores que conecta a personas de todo el mundo que usan personajes Mii. Usa Juxt para compartir tus experiencias de juego y conocer gente de todo el mundo.", + "google_text": "Juxtaposition utiliza Google Analytics para realizar un seguimiento de cómo los usuarios utilizan nuestro servicio. Los datos recopilados incluyen, entre otros, el tiempo de visita, las páginas visitadas y el tiempo de permanencia en el sitio. Estos datos no se adjuntan a usted de ninguna manera y no se utilizan para publicidad por nuestra parte o por parte de Google.", + "info": "¿Qué es la yuxtaposición?", + "info_text": "Juxt es una comunidad de juegos impulsada por el usuario en la que puedes interactuar con la gente\n en todo el mundo. Puedes escribir o dibujar publicaciones en las comunidades del juego o enviar mensajes directamente a tus amigos.", + "ready_text": "Primero, echa un vistazo a algunas comunidades y mira sobre qué publican personas de todo el mundo. Aproveche esta oportunidad para familiarizarse con Juxt. ¡Es posible que hagas nuevos descubrimientos en el camino!", + "done": "¡Diviértete en Juxt!", + "beta": "Descargo de responsabilidad de la beta", + "welcome": "¡Bienvenido a la yuxtaposición!" + }, + "notifications": { + "none": "No hay notificaciones.", + "new_follower": "¡Te seguí!" + }, + "user_page": { + "follow_user": "Seguir", + "game_experience": "Experiencia de juego", + "no_following": "No seguir a nadie", + "befriend": "Ofrecer amistad", + "posts": "publicación", + "friends": "Amigos", + "following_user": "Siguiente", + "pending": "Pendiente", + "followers": "Seguidores", + "unfriend": "Dejar de ser amigo", + "no_followers": "Sin seguidores", + "no_friends": "Sin amigos", + "birthday": "Cumpleaños", + "country": "País", + "following": "Siguiente" + }, + "new_post": { + "swearing": "La publicación no puede contener lenguaje explícito.", + "text_hint": "Pulsa aquí para hacer una publicación.", + "new_post_text": "Nueva publicación", + "post_to": "Publicar en" + }, + "user_settings": { + "show_game": "Mostrar experiencia de juego en el perfil", + "show_comment": "Mostrar comentario en el perfil", + "show_birthday": "Mostrar cumpleaños en el perfil", + "profile_settings": "Configuración perfil", + "profile_comment": "Comentario de perfil", + "swearing": "El comentario de perfil no puede contener lenguaje explícito.", + "show_country": "Mostrar país en el perfil" + }, + "activity_feed": { + "empty": "Está vacío aquí. ¡Intenta seguir a alguien!" + }, + "messages": { + "coming_soon": "Mensajes aún no está listo. ¡Vuelve pronto!" + } } From bbcf1210c570e88db0bb83e65258a42eb3061e82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnau=20B=C3=A0rcia?= Date: Mon, 4 Dec 2023 01:08:22 +0000 Subject: [PATCH 046/189] locales(update): Updated Spanish locale --- apps/juxtaposition-ui/src/translations/es.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/es.json b/apps/juxtaposition-ui/src/translations/es.json index 2435cf69..ff201a4a 100644 --- a/apps/juxtaposition-ui/src/translations/es.json +++ b/apps/juxtaposition-ui/src/translations/es.json @@ -46,7 +46,7 @@ "following": "Siguiendo", "followers": "Seguidores", "follow_user": "Seguir", - "following_user": "Seguidores", + "following_user": "Siguiendo", "befriend": "Ser amigos", "pending": "Pendiente", "unfriend": "Eliminar amigo", @@ -58,7 +58,7 @@ "profile_settings": "Preferencias del perfil", "show_country": "Mostrar país en tu perfil", "show_birthday": "Mostrar cumpleaños en tu perfil", - "show_game": "Mostrar experiencia en tu perfil", + "show_game": "Mostrar experiencia de juego en tu perfil", "show_comment": "Mostrar comentario en tu perfil", "profile_comment": "Comentario del perfil", "swearing": "Los comentarios no pueden tener lenguaje inapropiado." @@ -81,7 +81,7 @@ }, "setup": { "welcome": "¡Bienvenido a Juxtaposition!", - "welcome_text": "Juxt es una comunidad de videojuegos para conectar a personas de todo el mundo usando personajes Mii. Juxt se puede usar para compartir tus experiencias Gaming y conocer personas de todo el mundo.", + "welcome_text": "Juxt es una comunidad de videojuegos para conectar a personas de todo el mundo usando personajes Mii. Juxt se puede usar para compartir tus experiencias de juego y conocer personas de todo el mundo.", "beta": "Información de la beta", "beta_text": { "first": "Estás a punto de probar la primera beta pública de Juxt. Esto significa que todavía quedan muchas cosas en el aire, y pueden haber grandes cambios en cualquier momento.", @@ -99,8 +99,8 @@ "fifth": "Para que Juxt sea un lugar divertido para todos, te pedimos que seas considerado con los demás usuarios. Ayúdanos a que Juxt sea una experiencia agradable: no publiques nada inapropiado ni ofensivo.", "sixth": "No publiques información personal - tuya o de otras personas", "seventh": "Recuerda, conocer a alguien en Juxt no es lo mismo que conocerlo en la vida real. Nunca compartas tu dirección de correo electrónico, domicilio, nombre de tu trabajo o escuela u otra información de identificación personal con nadie en Juxt, y tampoco compartas la información de nadie más. Además, si alguien que conoces en Juxt te invita a conocerlo en el mundo real, no lo aceptes. Juxt es una comunidad en línea y no debe usarse para organizar reuniones en el mundo real.", - "eighth": "No publiques spoilers", - "ninth": "Algunas personas vienen a Juxt en busca de consejos y trucos para juegos, pero otras quieren descubrir los secretos de un juego por su cuenta. Las publicaciones que revelan secretos de un juego o su historia se denominan \"spoilers\". Si estás publicando algo sobre un juego que podría ser un spoiler, asegúrate de marcar la casilla \"Spoilers\" antes de enviar tu publicación. De esta forma, las personas que no quieran ver detalles del juego no verán tu publicación.", + "eighth": "No publiques revelaciones", + "ninth": "Algunas personas vienen a Juxt en busca de consejos y trucos para juegos, pero otras quieren descubrir los secretos de un juego por su cuenta. Las publicaciones que revelan secretos de un juego o su historia se denominan \"Revelaciones\". Si estás publicando algo sobre un juego que podría ser una revelación, asegúrate de marcar la casilla \"Revelaciones\" antes de enviar tu publicación. De esta forma, las personas que no quieran ver detalles del juego no verán tu publicación.", "tenth": "Violaciones del Código de conducta", "eleventh": "Nuestro objetivo es hacer que Juxt sea divertido y agradable para todos. En el caso de que alguien viole el Código de conducta de Juxt tomaremos las medidas adecuadas, incluyendo el bloqueo del usuario o la consola infractores.", "twelfth": "¿Has jugado a este juego?", @@ -120,7 +120,7 @@ "done": "¡Que te diviertas en Juxt!", "done_button": "¡Vamos!", "guest": "Modo invitado", - "guest_text": "No podemos verificar tu cuenta en este momento, lo que probablemente significa que estás iniciando sesión con una cuenta de Nintendo Network. Podrás seguir navegando por Juxt, pero no podrás indicar ¡Genial! o crear publicaciones hasta que inicies sesión con una cuenta de Pretendo Network. Para obtener más información, consulta el servidor de Discord.", + "guest_text": "No podemos verificar tu cuenta en este momento, lo que probablemente significa que estás iniciando sesión con una cuenta de Nintendo Network. Podrás seguir navegando por Juxt, pero no podrás indicar ¡Mola! o crear publicaciones hasta que inicies sesión con una cuenta de Pretendo Network. Para obtener más información, consulta el servidor de Discord.", "guest_button": "Entendido" } } From a581b45881ebf74b5db278630f91eed2d4ebfe2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wandrille=20Doutt=C3=A9?= Date: Sun, 3 Dec 2023 15:40:47 +0000 Subject: [PATCH 047/189] locales(update): Updated French locale --- apps/juxtaposition-ui/src/translations/fr.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/fr.json b/apps/juxtaposition-ui/src/translations/fr.json index c5b5b619..31037161 100644 --- a/apps/juxtaposition-ui/src/translations/fr.json +++ b/apps/juxtaposition-ui/src/translations/fr.json @@ -8,7 +8,7 @@ "notifications": "Notifications", "go_back": "aller Retour", "back": "Retour", - "yeahs": "Ouais !", + "yeahs": "Ouais", "more": "Afficher plus de publications", "no_posts": "Aucune Publication", "private": "Privés", From b2a286ab34802c99082e4b8ebe31e93117fde21b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wandrille=20Doutt=C3=A9?= Date: Sun, 3 Dec 2023 16:35:44 +0000 Subject: [PATCH 048/189] locales(update): Updated Catalan locale --- .../juxtaposition-ui/src/translations/ca.json | 68 ++++++++++++++++--- 1 file changed, 58 insertions(+), 10 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/ca.json b/apps/juxtaposition-ui/src/translations/ca.json index 54ac82fd..80249e03 100644 --- a/apps/juxtaposition-ui/src/translations/ca.json +++ b/apps/juxtaposition-ui/src/translations/ca.json @@ -4,7 +4,7 @@ "more": "Carregar més publicacions", "next": "Següent", "messages": "Missatges", - "activity_feed": "Registre d'activitat", + "activity_feed": "Feed d'activitats", "exit": "Sortir", "back": "Enrere", "notifications": "Notificacions", @@ -13,7 +13,8 @@ "private": "Privat", "close": "Tancar", "user_page": "Pàgina d'usuari", - "go_back": "Torna" + "go_back": "Torna", + "yeahs": "Sí" }, "notifications": { "none": "No hi ha notificacions.", @@ -21,7 +22,7 @@ }, "user_page": { "follow_user": "Seguir", - "game_experience": "Experiència jugant", + "game_experience": "Experiència de joc", "no_following": "No segueix a ningú", "befriend": "Fes-te amic", "posts": "Publicacions", @@ -33,7 +34,8 @@ "no_friends": "Sense amics", "birthday": "Aniversari", "country": "País", - "following": "Seguint" + "following": "Seguint", + "unfriend": "Eliminar de la llista d'amics" }, "community": { "new": "Publicació nova", @@ -43,11 +45,11 @@ "following": "Seguint", "follow": "Segueix aquesta comunitat", "verified": "Publicacions verificades", - "recent": "Publicaciones recents", + "recent": "Entrades recents", "popular": "Publicacions populars" }, "user_settings": { - "show_game": "Mostrar experiència al perfil", + "show_game": "Mostra experiència de joc al perfil", "show_comment": "Mostra el teu comentari al perfil", "show_birthday": "Mostra el teu aniversari al perfil", "profile_settings": "Configuració del perfil", @@ -58,21 +60,67 @@ "new_post": { "text_hint": "Toca aquí per fer una publicació.", "new_post_text": "Publicació nova", - "post_to": "Publica a" + "post_to": "Publica a", + "swearing": "L'entrada no pot contenir llenguatge explícit." }, "all_communities": { - "show_all": "Mostrar tot", + "show_all": "Mostra-ho tot", "search": "Cerca comunitats...", "text": "Totes les comunitats", "ann_string": "Toca aquí per veure els anuncis recents!", "new_communities": "Noves Comunitats", - "popular_places": "Comunitats Populars" + "popular_places": "Comunitats Populars", + "announcements": "Anuncis" }, "language": "Català", "activity_feed": { "empty": "Aquí està buit. Pots provar de seguir algú!" }, "setup": { - "welcome": "Benvingut a Juxtaposition!" + "welcome": "Benvingut a Juxtaposition!", + "rules_text": { + "eleventh": "El nostre objectiu és mantenir Juxt divertit i agradable per a tothom. En el cas que algú infringeixi el Codi de Conducta de Juxt, prendrem les mesures adequades, fins i tot bloquejant l'usuari o la consola infractors.", + "tenth": "Infraccions del codi de conducta", + "third": "Juxt conté moltes comunitats de jocs on persones de tot el món poden compartir els seus pensaments. Quan publiqueu en una comunitat, recordeu que tothom ho pot veure, així que si us plau, expresseu-vos d'una manera que tothom pugui gaudir. Fes servir el sentit comú i pensa abans de publicar. Juxt és un servei que també és accessible des d'Internet, així que tingueu en compte que les persones que no utilitzin Juxt també poden veure les vostres publicacions. A més, els comentaris que feu a les publicacions dels vostres amics no només els veuran els vostres amics, sinó també gent d'arreu del món. Si us plau, tingueu això en compte.", + "thirteenth": "Si publiques a la comunitat un joc al qual has jugat, a les teves publicacions hi haurà una icona que indica que l'has jugat.", + "fifth": "Per tal de mantenir Juxt un lloc divertit per a tothom, us demanem que sigueu considerats amb els altres usuaris. Ajudeu-nos a mantenir Juxt una experiència agradable no publicant res inadequat o ofensiu.", + "ninth": "Algunes persones vénen a Juxt buscant consells i trucs per als jocs, però altres volen descobrir els secrets d'un joc pel seu compte. Les publicacions que revelen secrets d'un joc o la seva història s'anomenen \"spoilers\". Si publiqueu alguna cosa sobre un joc que podria ser un spoiler, assegureu-vos de marcar la casella Spoilers abans d'enviar la vostra publicació. D'aquesta manera, les persones que no vulguin ser espatllades no veuran la vostra publicació.", + "fourth": "Sigueu amables els uns amb els altres", + "second": "Les publicacions es poden veure a tot el món", + "sixth": "No publiquis informació personal, teva o d'altres persones", + "first": "A continuació es detallen algunes pautes importants per fer de Juxt una experiència divertida i agradable per a tothom. El Codi de Conducta de Juxt conté informació detallada, així que llegiu-la atentament.", + "eighth": "No publiqueu spoilers", + "seventh": "Recordeu, no és el mateix conèixer algú a Juxt que conèixer-lo a la vida real. No compartiu mai la vostra adreça de correu electrònic, adreça de casa, nom de la feina o de l'escola, ni cap altra informació d'identificació personal amb ningú a Juxt, i mai compartiu la informació de ningú més. A més, si algú que coneixes a Juxt et convida a conèixer-lo al món real, no acceptis. Juxt és una comunitat en línia i no s'ha d'utilitzar per organitzar trobades del món real.", + "twelfth": "Has jugat a aquest joc?" + }, + "beta_text": { + "third": "El lloc web, el seu programari i tot el contingut que s'hi troba es proporcionen \"tal qual\" i \"segons estigui disponible\". The Pretendo Network no dóna cap garantia, ja sigui expressa o implícita, sobre la idoneïtat o usabilitat del lloc web, el seu programari o qualsevol dels seus continguts.", + "second": "Això pot incloure i pot incloure una eliminació total de la base de dades al final o durant el període beta.", + "first": "Esteu a punt de provar la primera beta pública de Juxt. Això vol dir que encara hi ha moltes coses en l'aire, i moltes coses poden canviar en qualsevol moment." + }, + "experience_text": { + "expert": "Expert", + "info": "Si us plau, explica'ns com descriuries el teu nivell d'experiència amb els jocs. Podeu canviar aquesta configuració més endavant.", + "intermediate": "Intermedi", + "beginner": "Principiant" + }, + "guest_button": "Comprenc", + "done_button": "Som-hi!", + "guest": "Mode convidat", + "ready": "A punt per començar a utilitzar Juxt", + "guest_text": "No podem verificar el vostre compte en aquest moment, cosa que probablement significa que actualment esteu iniciant la sessió amb un compte de Nintendo Network. Encara podreu navegar per Juxt, però no podreu fer-ho. publica o fes publicacions pròpies fins que iniciïs sessió amb un compte de Pretendo Network. Per obtenir més informació, consulteu el servidor de Discord.", + "experience": "Experiència de joc", + "google": "Google Analytics", + "rules": "Regles de Juxt", + "welcome_text": "Juxt és una comunitat de jocs que connecta persones de tot el món mitjançant personatges Mii. Utilitzeu Juxt per compartir les vostres experiències de joc i conèixer gent de tot el món.", + "google_text": "La juxtaposició utilitza Google Analytics per tal de fer un seguiment de com els usuaris utilitzen el nostre servei. Les dades recopilades inclouen, entre d'altres, el temps de visita, les pàgines visitades i el temps dedicat al lloc. Aquestes dades no se li adjunten de cap manera, i no s'utilitzen per a anuncis per nosaltres o Google.", + "info": "Què és la juxtaposició?", + "info_text": "Juxt és una comunitat de jocs impulsada per l'usuari on podeu interactuar amb la gent\n a tot el món. Pots escriure o dibuixar publicacions en comunitats de jocs o enviar missatges directament als teus amics.", + "ready_text": "En primer lloc, fes un cop d'ull a algunes comunitats i descobreix què publiquen persones de tot el món. Aprofita aquesta oportunitat per familiaritzar-te amb Juxt. Podeu fer alguns descobriments nous al llarg del camí!", + "done": "Diverteix-te a Juxt!", + "beta": "Exempció de responsabilitat beta" + }, + "messages": { + "coming_soon": "L'opció Missatges encara no està preparada. Torna-ho a comprovar aviat!" } } From 9581feff5b164cf697f9ccdefb40b062271fe737 Mon Sep 17 00:00:00 2001 From: Daniel Adam Coats Date: Sat, 2 Dec 2023 20:15:36 +0000 Subject: [PATCH 049/189] locales(update): Updated Czech locale --- apps/juxtaposition-ui/src/translations/cs.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/cs.json b/apps/juxtaposition-ui/src/translations/cs.json index 3416c753..40e01419 100644 --- a/apps/juxtaposition-ui/src/translations/cs.json +++ b/apps/juxtaposition-ui/src/translations/cs.json @@ -95,9 +95,9 @@ "first": "Chystáte se vyzkoušet první veřejnou betu Juxtu. To znamená, že mnohé je stále ve hvězdách a mnohé se může kdykoli změnit." }, "experience_text": { - "expert": "Expert", + "expert": "Pokročilý", "info": "Sdělte nám, prosím, jak byste popsal(a) Vaši zkušenost s hraním. Toto nastavení můžete změnit později.", - "intermediate": "Pokročilý", + "intermediate": "Středně pokročilý", "beginner": "Začátečník" }, "guest_button": "Rozumím", From c538b2e273de17aada705c26a3c69f33f1141a02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wandrille=20Doutt=C3=A9?= Date: Sun, 3 Dec 2023 16:53:23 +0000 Subject: [PATCH 050/189] locales(update): Updated Serbian locale --- apps/juxtaposition-ui/src/translations/sr.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/sr.json b/apps/juxtaposition-ui/src/translations/sr.json index 836e50f5..f9eab702 100644 --- a/apps/juxtaposition-ui/src/translations/sr.json +++ b/apps/juxtaposition-ui/src/translations/sr.json @@ -19,7 +19,7 @@ "follow": "Zaprati zajednicu", "following": "Praćenje", "followers": "Pratioci", - "posts": "Objave", + "posts": "Knjiži", "tags": "Oznake", "recent": "Nedavne objave", "popular": "Popularne objave", @@ -29,7 +29,7 @@ "birthday": "Rođendan", "following_user": "Praćenje", "country": "Zemlja", - "posts": "Objave", + "posts": "Knjiži", "friends": "Prijatelji", "follow_user": "Zaprati", "followers": "Pratioci", From f138ba39480ceeba93a4d7001e1fe2dcba8838fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnau=20B=C3=A0rcia?= Date: Thu, 7 Dec 2023 05:33:53 +0000 Subject: [PATCH 051/189] locales(update): Updated Spanish locale --- apps/juxtaposition-ui/src/translations/es.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/es.json b/apps/juxtaposition-ui/src/translations/es.json index ff201a4a..1beb1ad4 100644 --- a/apps/juxtaposition-ui/src/translations/es.json +++ b/apps/juxtaposition-ui/src/translations/es.json @@ -40,7 +40,7 @@ "user_page": { "country": "País", "birthday": "Cumpleaños", - "game_experience": "Experiencia jugando", + "game_experience": "Experiencia de juego", "posts": "Publicaciones", "friends": "Amigos", "following": "Siguiendo", From 1417ac75cce19b72bc81405d70899b6d2b8fe933 Mon Sep 17 00:00:00 2001 From: UKRMate Date: Mon, 15 Jan 2024 21:26:44 +0000 Subject: [PATCH 052/189] locales(update): Updated Ukrainian locale --- apps/juxtaposition-ui/src/translations/uk.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/uk.json b/apps/juxtaposition-ui/src/translations/uk.json index cd34419a..3be972ad 100644 --- a/apps/juxtaposition-ui/src/translations/uk.json +++ b/apps/juxtaposition-ui/src/translations/uk.json @@ -91,11 +91,11 @@ "info": "Що таке Juxtaposition?", "welcome": "Ласкаво просимо до Juxtaposition!", "welcome_text": "Juxt — це ігрова спільнота, яка об’єднує людей з усього світу за допомогою персонажів Mii. Використовуйте Juxt, щоб ділитися своїм ігровим досвідом і зустрічатися з людьми з усього світу.", - "info_text": "Juxt — це ігрова спільнота, орієнтована на користувачів, де ви можете спілкуватися з людьми\n по всьому світу. Ви можете писати чи малювати пости в ігрових спільнотах або надсилати повідомлення безпосередньо друзям.", + "info_text": "Juxt — це ігрова спільнота, орієнтована на користувачів, де ви можете спілкуватися з людьми\n по всьому світу. Ви можете писати чи малювати пости в ігрових спільнотах або надсилати повідомлення безпосередньо друзям.", "experience": "Ігровий Досвід", "google": "Google Analytics", "google_text": "Juxtaposition використовує Google Analytics, щоб відстежувати, як користувачі використовують наш сервіс. Зібрані дані включають, але не обмежуються, час відвідування, відвідані сторінки та час, проведений на сайті. Ці дані жодним чином не пов’язані з вами та не використовуються для реклами ні нами, ні Google.", - "guest_text": "Наразі ми не можемо підтвердити ваш обліковий запис, що, ймовірно, означає, що ви зараз входите в обліковий запис Nintendo Network. Ви все ще зможете переглядати Juxt, але не зможете Yeah! публікації або створюйте власні публікації, доки не ввійдете в обліковий запис Pretendo Network. Для отримання додаткової інформації відвідайте сервер Discord." + "guest_text": "Наразі ми не можемо підтвердити ваш обліковий запис, що, ймовірно, означає, що ви ввійшли за допомогою облікового запису Nintendo Network. Ви зможете переглядати Juxt, але не зможете реагувати на дописи або створювати власні дописи, доки не ввійдете в систему за допомогою облікового запису Pretendo Network. Докладнішу інформацію можна знайти на сервері Discord." }, "language": "Українська", "user_settings": { From 5cf821d0659a243139430810837928b275727cd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnau=20B=C3=A0rcia?= Date: Tue, 23 Jan 2024 11:47:48 +0000 Subject: [PATCH 053/189] locales(update): Updated Spanish locale --- apps/juxtaposition-ui/src/translations/es.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/es.json b/apps/juxtaposition-ui/src/translations/es.json index 1beb1ad4..48050d1a 100644 --- a/apps/juxtaposition-ui/src/translations/es.json +++ b/apps/juxtaposition-ui/src/translations/es.json @@ -88,7 +88,7 @@ "second": "Esto puede incluir que todos los datos que almacenamos sean completamente eliminados durante o al acabar el periodo de beta.", "third": "El sitio web, su software y todo el contenido que se encuentra en él se proporcionan 'tal cual' y 'según esté disponible'. Pretendo Network no ofrece ninguna garantía, ya sea expresa o implícita, en cuanto a la integridad o usabilidad del sitio web, su software o cualquiera de sus contenidos." }, - "info": "¿Que es Juxtaposition?", + "info": "¿Qué es Juxtaposition?", "info_text": "Juxt es una comunidad de videojuegos dirigida por usuarios donde puedes interactuar con personas\n de todo el mundo. Puedes escribir y dibujar publicaciones en comunidades enfocadas a los videojuegos y enviar mensajes directamente a tus amigos.", "rules": "Reglas de Juxt", "rules_text": { From 0602e229c066e25c2d7f2425318ee8726b4d3268 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnau=20B=C3=A0rcia?= Date: Tue, 23 Jan 2024 11:53:09 +0000 Subject: [PATCH 054/189] locales(update): Updated Catalan locale --- apps/juxtaposition-ui/src/translations/ca.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/ca.json b/apps/juxtaposition-ui/src/translations/ca.json index 80249e03..851bd779 100644 --- a/apps/juxtaposition-ui/src/translations/ca.json +++ b/apps/juxtaposition-ui/src/translations/ca.json @@ -49,7 +49,7 @@ "popular": "Publicacions populars" }, "user_settings": { - "show_game": "Mostra experiència de joc al perfil", + "show_game": "Mostra la experiència de joc al perfil", "show_comment": "Mostra el teu comentari al perfil", "show_birthday": "Mostra el teu aniversari al perfil", "profile_settings": "Configuració del perfil", @@ -94,9 +94,9 @@ "twelfth": "Has jugat a aquest joc?" }, "beta_text": { - "third": "El lloc web, el seu programari i tot el contingut que s'hi troba es proporcionen \"tal qual\" i \"segons estigui disponible\". The Pretendo Network no dóna cap garantia, ja sigui expressa o implícita, sobre la idoneïtat o usabilitat del lloc web, el seu programari o qualsevol dels seus continguts.", - "second": "Això pot incloure i pot incloure una eliminació total de la base de dades al final o durant el període beta.", - "first": "Esteu a punt de provar la primera beta pública de Juxt. Això vol dir que encara hi ha moltes coses en l'aire, i moltes coses poden canviar en qualsevol moment." + "third": "El lloc web, el seu programari i tot el contingut que s'hi troba es proporcionen \"tal qual\" i \"segons estigui disponible\". La Pretendo Network no dóna cap garantia, ja sigui expressa o implícita, sobre la idoneïtat o usabilitat del lloc web, el seu programari o qualsevol dels seus continguts.", + "second": "Això pot incloure una eliminació total de la base de dades al final o durant el període beta.", + "first": "Estàs a punt de provar la primera beta pública de Juxt. Això vol dir que encara hi ha moltes coses en l'aire, i moltes coses poden canviar en qualsevol moment." }, "experience_text": { "expert": "Expert", @@ -114,8 +114,8 @@ "rules": "Regles de Juxt", "welcome_text": "Juxt és una comunitat de jocs que connecta persones de tot el món mitjançant personatges Mii. Utilitzeu Juxt per compartir les vostres experiències de joc i conèixer gent de tot el món.", "google_text": "La juxtaposició utilitza Google Analytics per tal de fer un seguiment de com els usuaris utilitzen el nostre servei. Les dades recopilades inclouen, entre d'altres, el temps de visita, les pàgines visitades i el temps dedicat al lloc. Aquestes dades no se li adjunten de cap manera, i no s'utilitzen per a anuncis per nosaltres o Google.", - "info": "Què és la juxtaposició?", - "info_text": "Juxt és una comunitat de jocs impulsada per l'usuari on podeu interactuar amb la gent\n a tot el món. Pots escriure o dibuixar publicacions en comunitats de jocs o enviar missatges directament als teus amics.", + "info": "Què és Juxtaposition?", + "info_text": "Juxt és una comunitat de jocs impulsada per l'usuari on es pot interactuar amb la gent\n a tot el món. Pots escriure o dibuixar publicacions en comunitats de jocs o enviar missatges directament als teus amics.", "ready_text": "En primer lloc, fes un cop d'ull a algunes comunitats i descobreix què publiquen persones de tot el món. Aprofita aquesta oportunitat per familiaritzar-te amb Juxt. Podeu fer alguns descobriments nous al llarg del camí!", "done": "Diverteix-te a Juxt!", "beta": "Exempció de responsabilitat beta" From c217fa6c84e8d25f9f2ab0eade41809ee04ac067 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9mence?= Date: Sat, 3 Feb 2024 15:27:21 +0000 Subject: [PATCH 055/189] locales(update): Updated French locale --- apps/juxtaposition-ui/src/translations/fr.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/fr.json b/apps/juxtaposition-ui/src/translations/fr.json index 31037161..166639d8 100644 --- a/apps/juxtaposition-ui/src/translations/fr.json +++ b/apps/juxtaposition-ui/src/translations/fr.json @@ -6,7 +6,7 @@ "communities": "Communautés", "messages": "Messages", "notifications": "Notifications", - "go_back": "aller Retour", + "go_back": "Revenir en arrière", "back": "Retour", "yeahs": "Ouais", "more": "Afficher plus de publications", From 4fc1d4d7e7aa6cd1926ce16b5273d8a38053f32b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9mence?= Date: Sat, 10 Feb 2024 13:47:43 +0000 Subject: [PATCH 056/189] locales(update): Updated French locale --- apps/juxtaposition-ui/src/translations/fr.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/fr.json b/apps/juxtaposition-ui/src/translations/fr.json index 166639d8..1e5591fa 100644 --- a/apps/juxtaposition-ui/src/translations/fr.json +++ b/apps/juxtaposition-ui/src/translations/fr.json @@ -1,7 +1,7 @@ { "language": "Français", "global": { - "user_page": "Page utilisateur", + "user_page": "Profil", "activity_feed": "Fil d'Actualité", "communities": "Communautés", "messages": "Messages", From 583a93c3a9ecf73fcf24f0412ea7e10a34e07702 Mon Sep 17 00:00:00 2001 From: Harvey Marshall Date: Fri, 16 Feb 2024 01:34:24 +0100 Subject: [PATCH 057/189] locales(add): Added Welsh locale --- apps/juxtaposition-ui/src/translations/cy.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/juxtaposition-ui/src/translations/cy.json diff --git a/apps/juxtaposition-ui/src/translations/cy.json b/apps/juxtaposition-ui/src/translations/cy.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/apps/juxtaposition-ui/src/translations/cy.json @@ -0,0 +1 @@ +{} From 86947609abde14937c071e7378fda668a70493e8 Mon Sep 17 00:00:00 2001 From: Harvey Marshall Date: Fri, 16 Feb 2024 00:59:14 +0000 Subject: [PATCH 058/189] locales(update): Updated Welsh locale --- .../juxtaposition-ui/src/translations/cy.json | 97 ++++++++++++++++++- 1 file changed, 96 insertions(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/cy.json b/apps/juxtaposition-ui/src/translations/cy.json index 0967ef42..3490c2ef 100644 --- a/apps/juxtaposition-ui/src/translations/cy.json +++ b/apps/juxtaposition-ui/src/translations/cy.json @@ -1 +1,96 @@ -{} +{ + "user_page": { + "country": "Gwlad", + "game_experience": "Profiad gem", + "followers": "Dilynwyr", + "following": "Dilynwch", + "pending": "Yn yr arfaeth", + "unfriend": "Ddim bod yn ffrind", + "no_friends": "Dim Ffrindiau", + "no_following": "Ddim yn dilynwch unrhyw", + "posts": "Swyddi", + "friends": "Ffrindiau", + "follow_user": "Dilyn", + "following_user": "Yn dilyn", + "befriend": "Bod yn ffrind", + "no_followers": "Ddim dilynwyr", + "birthday": "Penblwydd" + }, + "global": { + "back": "Yn ôl", + "yeahs": "Ydychau", + "more": "Swyddi mwy llwyth", + "no_posts": "Dim llwythau", + "private": "Preifat", + "close": "Cau", + "save": "Safiwch", + "exit": "Adael", + "next": "Nesaf", + "user_page": "Tudalen Defnyddiwr", + "activity_feed": "Porthiant gweithgaredd", + "communities": "Cymunedau", + "messages": "Negeuseon", + "notifications": "Hysbysiadau", + "go_back": "Fynd Yn ôl" + }, + "language": "Cymraeg", + "all_communities": { + "announcements": "Cyhoeddiad", + "ann_string": "Clicwch yma i spio cyhoeddiad newydd!", + "show_all": "Dangos Pob beth", + "search": "Chwilio Cymunedau...", + "text": "Pob cymunedau", + "popular_places": "Lleoedd Poblogaidd", + "new_communities": "Gymunedau Newydd" + }, + "community": { + "followers": "Dilynwyr", + "follow": "Dilyn Cymuned", + "popular": "Llwythyr poblogaidd", + "verified": "Swyddi gwirio", + "new": "Swydd newydd", + "following": "Dilynwch", + "posts": "Llywythau", + "tags": "Tagiau", + "recent": "Llywthau diweddar" + }, + "user_settings": { + "show_comment": "Ddangos sylwadau ar profil", + "profile_settings": "Gosodiadau profil", + "show_country": "Ddangos Gwlad Ar Profil", + "show_birthday": "Ddangos Penblwydd Ar Profil", + "profile_comment": "Sylwadau profil", + "swearing": "Ni all gynnwys iaith eglur ar sylwadau profil." + }, + "new_post": { + "new_post_text": "Llwyth newydd", + "post_to": "Llwyth I", + "text_hint": "Tapiwch yma i creu llwyth.", + "swearing": "Llwyth ddim gallu cynnwys iaith eglur." + }, + "setup": { + "rules_text": { + "second": "Pobol dros y byd yn gallu spio ar eich llwythau", + "eighth": "Ddim Llwythio Sbeilwyr", + "twelfth": "Ydach chi wedi chwarae gem yna?" + }, + "ready": "Barod I i ddechrau defnyddio juxt", + "done": "Cael Hwyl Yn Juxt!", + "done_button": "Fynd!", + "guest": "Modd gwestai", + "guest_button": "Dwi'n Deall", + "welcome": "Croeso I Jusxtaposition!", + "rules": "Rheol Juxt", + "info": "Beth ydy juxtaposition?" + }, + "activity_feed": { + "empty": "Maen wag yma. Ceishwch dilyn rhywun!" + }, + "notifications": { + "none": "Ddim hysbysiadau.", + "new_follower": "Wedi dilynwch chdi!" + }, + "messages": { + "coming_soon": "Nif yw negeseuon yn barod. eto gwiriwch yn ol yn fuan!" + } +} From 0d1c2a3adebabdaf853aee60c255fb8d209981af Mon Sep 17 00:00:00 2001 From: Florian Gerling Date: Tue, 27 Feb 2024 08:04:34 +0000 Subject: [PATCH 059/189] locales(update): Updated German locale --- apps/juxtaposition-ui/src/translations/de.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/de.json b/apps/juxtaposition-ui/src/translations/de.json index 6a4afb93..863b1b8a 100644 --- a/apps/juxtaposition-ui/src/translations/de.json +++ b/apps/juxtaposition-ui/src/translations/de.json @@ -8,7 +8,7 @@ "notifications": "Mitteilungen", "go_back": "Zurück", "back": "Zurück", - "yeahs": "Jaaa", + "yeahs": "Yeahs", "more": "Mehr Beiträge laden", "no_posts": "Keine Beiträge", "private": "Privat", From a3dcf81c9aa23a6d39ce357da58444aef1b62672 Mon Sep 17 00:00:00 2001 From: PlayerLoler Date: Mon, 26 Feb 2024 13:54:29 +0000 Subject: [PATCH 060/189] locales(update): Updated Portuguese locale --- .../juxtaposition-ui/src/translations/pt.json | 242 +++++++++--------- 1 file changed, 121 insertions(+), 121 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/pt.json b/apps/juxtaposition-ui/src/translations/pt.json index 91b5367a..873573dc 100644 --- a/apps/juxtaposition-ui/src/translations/pt.json +++ b/apps/juxtaposition-ui/src/translations/pt.json @@ -1,126 +1,126 @@ { - "language": "Português", - "global": { - "user_page": "Perfil do Utilizador", - "activity_feed": "Atividade", - "communities": "Comunidades", - "messages": "Mensagens", - "notifications": "Notificações", - "go_back": "Voltar", - "back": "Anterior", - "yeahs": "Fixes", - "more": "Carregar mais publicações", - "no_posts": "Sem publicações", - "private": "Privado", - "close": "Fechar", - "save": "Guardar", - "exit": "Sair", - "next": "Seguinte" - }, - "all_communities": { - "text": "Todas as comunidades", - "announcements": "Anúncios", - "ann_string": "Clica aqui para veres os anúncios recentes!", - "popular_places": "Lugares Populares", - "new_communities": "Novas Comunidades", - "show_all": "Mostrar todas", - "search": "Procurar comunidades..." - }, - "community": { - "follow": "Seguir Comunidade", - "following": "A seguir", - "followers": "Seguidores", - "posts": "Publicações", - "tags": "Tags", - "recent": "Publicações Recentes", - "popular": "Publicações Populares", - "verified": "Publicações Verificadas", - "new": "Nova Publicação" - }, - "user_page": { - "country": "País", - "birthday": "Aniversário", - "game_experience": "Experiência de Jogo", - "posts": "Publicações", - "friends": "Amigos", - "following": "A seguir", - "followers": "Seguidores", - "follow_user": "Seguir", - "following_user": "Seguidores", - "befriend": "Tornar-se Amigo", - "pending": "Pendente", - "unfriend": "Remover Amizade", - "no_friends": "Sem Amigos", - "no_following": "Não segue ninguém", - "no_followers": "Sem seguidores" - }, - "user_settings": { - "profile_settings": "Preferências de Perfil", - "show_country": "Mostrar país no perfil", - "show_birthday": "Mostrar data de aniversário no perfil", - "show_game": "Mostrar experiência de jogo no perfil", - "show_comment": "Mostrar comentário no perfil", - "profile_comment": "Comentário do Perfil", - "swearing": "O comentário do perfil não pode ter linguagem obscena." - }, - "activity_feed": { - "empty": "Isto está muito vazio. Começa a seguir alguém!" - }, - "notifications": { - "none": "Sem notificações.", - "new_follower": "seguiu-te!" - }, - "new_post": { - "new_post_text": "Nova publicação", - "post_to": "Publicar em", - "text_hint": "Toca aqui para criar uma publicação.", - "swearing": "A publicação não pode ter linguagem obscena." - }, - "messages": { - "coming_soon": "A funcionalidade de mensagens ainda não está disponível. Volta em breve!" - }, - "setup": { - "welcome": "Bem-vindo a Juxtaposition!", - "welcome_text": "Juxt é uma comunidade de jogadores que liga pessoas de todo o mundo utilizando personagens Mii. Usa Juxt para partilhar as tuas experiências de jogo e conhecer novas pessoas de todo o mundo.", - "beta": "Nota sobre Beta", - "beta_text": { - "first": "Estás prestes a experimentar a primeira versão beta pública de Juxt. Isto significa que ainda há muito a fazer e que muitas coisas ainda poderão mudar a qualquer momento.", - "second": "No final do período beta, os dados registados na plataforma poderão vir a ser apagados.", - "third": "Este website, o seu software e todos os conteúdos nele conteúdos são disponibilizados “tal como estão” e “quando disponíveis”. A Pretendo Network não oferece quaisquer garantias, quer expressas quer implícitas, a respeito da integridade ou disponibilidade do website, do seu software ou dos seus conteúdos." + "language": "Português", + "global": { + "user_page": "Perfil do Utilizador", + "activity_feed": "Atividade", + "communities": "Comunidades", + "messages": "Mensagens", + "notifications": "Notificações", + "go_back": "Voltar", + "back": "Anterior", + "yeahs": "Fixes", + "more": "Carregar mais publicações", + "no_posts": "Sem publicações", + "private": "Privado", + "close": "Fechar", + "save": "Guardar", + "exit": "Sair", + "next": "Seguinte" }, - "info": "O que é Juxtaposition?", - "info_text": "Juxt é uma comunidade de utilizadores que liga pessoas\n de todo o mundo. Podes escrever ou desenhar publicações nas comunidades dos jogos ou enviar mensagens diretamente aos teus amigos.", - "rules": "Regras de Juxt", - "rules_text": { - "first": "Estas são algumas regras que permitem que Juxt seja uma experiência divertida para todos. O código de conduta Juxt contém informação detalhada, por isso lê-o com atenção.", - "second": "Publicações podem ser vistas em todo o mundo", - "third": "Juxt contém várias comunidades de jogadores onde pessoas de todo o mundo podem partilhar as suas ideias. Quando publicas numa comunidade, lembra-te que todos podem ver as tuas publicações, por isso expressa-te de uma maneira que possa ser divertida para todos. Usa o senso comum e pensa antes de publicar. Juxt é um serviço que também está acessível pela Internet, por isso pessoas que não usam Juxt também podem ver as tuas publicações. Adicionalmente, quaisquer comentários que faças em publicações de amigos são visíveis não só por estes, mas também por pessoas de todo o mundo. Tem isto em consideração.", - "fourth": "Sê simpático com os outros", - "fifth": "De forma a mantermos Juxt um lugar divertido para todos, pedimos-te que penses nas outras pessoas. Ajuda-nos a manter Juxt uma boa experiência ao não fazer publicações impróprias ou ofensivas.", - "sixth": "Não partilhes informações pessoas tuas nem de ninguém", - "seventh": "Lembra-te, conhecer alguém em Juxt não é o mesmo que conhecer alguém na vida real. Nunca partilhes com ninguém em Juxt o teu endereço de e-mail, morada, trabalho, nome da escola ou qualquer outra informação que te possa identificar nem partilhes informação de outras pessoas. Adicionalmente, se alguém que conheceres em Juxt te convidar para que se conheçam no mundo real, não aceites. Juxt é uma comunidade online e não deve ser usada para marcar encontros presenciais.", - "eighth": "Não publiques Spoilers", - "ninth": "Algumas pessoas vêm a Juxt à procura de dicas e truques para jogos, mas outras preferem descobrir os jogos por si mesmas. Publicações que revelam segredos de um jogo ou a sua história são chaamdas de \"spoilers.\" Se vais publicar algo sobre um jogo que pode ser um spoiler, marca a respetiva caixa antes de enviares a tua publicação. Desta forma, pessoas que não querem ver spoilers não verão a tua publicação.", - "tenth": "Violações do código de conduta", - "eleventh": "O nosso objetivo é fazer de Juxt uma comunidade divertida para todos. No caso de alguém violar o Código de Conduta de Juxt, iremos tomar as medidas necessárias que poderão incluir banir o utilizador ou a consola.", - "twelfth": "Já jogaste este jogo?", - "thirteenth": "Se publicares numa comunidade de um jogo que já jogaste, as tuas publicações irão incluir um íncone que indica que já o jogaste." + "all_communities": { + "text": "Todas as comunidades", + "announcements": "Anúncios", + "ann_string": "Clica aqui para veres os anúncios recentes!", + "popular_places": "Lugares Populares", + "new_communities": "Novas Comunidades", + "show_all": "Mostrar todas", + "search": "Procurar comunidades..." }, - "experience": "Experiência de jogo", - "experience_text": { - "info": "Fala-nos um pouco da tua experiência com jogos. Podes alterar estas definições mais tarde.", - "beginner": "Iniciante", - "intermediate": "Intermédio", - "expert": "Avançado" + "community": { + "follow": "Seguir Comunidade", + "following": "A seguir", + "followers": "Seguidores", + "posts": "Publicações", + "tags": "Tags", + "recent": "Publicações Recentes", + "popular": "Publicações Populares", + "verified": "Publicações Verificadas", + "new": "Nova Publicação" }, - "google": "Google Analytics", - "google_text": "Juxtaposition usa Google Analytics de forma a recolher informações de como os utilizadores usam o serviço. Os dados recolhidos incluem, mas não estão limitados a, hora da visita, páginas visitadas e tempo passado no site. Estes dados não estão associados a ti de maneira nenhuma e não são usados para anúncios por nós nem pela Google.", - "ready": "Pronto para usar Juxt", - "ready_text": "Começa por explorar algumas comunidades e ver o que as pessoas de todo o mundo estão a publicar. Aproveita esta oportunidade para te familiarizares com Juxt. Pode ser que descubras algo novo pelo caminho!", - "done": "Diverte-te com Juxt!", - "done_button": "Vamos a isso!", - "guest": "Modo de convidado", - "guest_text": "Não nos foi possível verificar a tua conta de momento, o que provavelmente significa que tens sessão iniciada com uma conta Nintendo Network. Podes explorar Juxt, mas não te será possível marcar publicações com Fixe! ou fazer publicações até que inicies sessão com uma conta Pretendo Network. Para mais informações visita o nosso servidor Discord.", - "guest_button": "Compreendo" - } + "user_page": { + "country": "País", + "birthday": "Aniversário", + "game_experience": "Experiência de Jogo", + "posts": "Publicações", + "friends": "Amigos", + "following": "A seguir", + "followers": "Seguidores", + "follow_user": "Seguir", + "following_user": "Seguidores", + "befriend": "Tornar-se Amigo", + "pending": "Pendente", + "unfriend": "Remover Amizade", + "no_friends": "Sem Amigos", + "no_following": "Não segue ninguém", + "no_followers": "Sem seguidores" + }, + "user_settings": { + "profile_settings": "Preferências de Perfil", + "show_country": "Mostrar país no perfil", + "show_birthday": "Mostrar data de aniversário no perfil", + "show_game": "Mostrar experiência de jogo no perfil", + "show_comment": "Mostrar comentário no perfil", + "profile_comment": "Comentário do Perfil", + "swearing": "O comentário do perfil não pode ter linguagem obscena." + }, + "activity_feed": { + "empty": "Isto está muito vazio. Começa a seguir alguém!" + }, + "notifications": { + "none": "Sem notificações.", + "new_follower": "seguiu-te!" + }, + "new_post": { + "new_post_text": "Nova publicação", + "post_to": "Publicar em", + "text_hint": "Toca aqui para criar uma publicação.", + "swearing": "A publicação não pode ter linguagem obscena." + }, + "messages": { + "coming_soon": "A funcionalidade de mensagens ainda não está disponível. Volta em breve!" + }, + "setup": { + "welcome": "Bem-vindo a Juxtaposition!", + "welcome_text": "Juxt é uma comunidade de jogadores que liga pessoas de todo o mundo utilizando personagens Mii. Usa Juxt para partilhar as tuas experiências de jogo e conhecer novas pessoas de todo o mundo.", + "beta": "Nota sobre Beta", + "beta_text": { + "first": "Estás prestes a experimentar a primeira versão beta pública de Juxt. Isto significa que ainda há muito a fazer e que muitas coisas ainda poderão mudar a qualquer momento.", + "second": "No final do período beta, os dados registados na plataforma poderão vir a ser apagados.", + "third": "Este website, o seu software e todos os conteúdos nele conteúdos são disponibilizados “tal como estão” e “quando disponíveis”. A Pretendo Network não oferece quaisquer garantias, quer expressas quer implícitas, a respeito da integridade ou disponibilidade do website, do seu software ou dos seus conteúdos." + }, + "info": "O que é Juxtaposition?", + "info_text": "Juxt é uma comunidade de utilizadores que liga pessoas\n de todo o mundo. Podes escrever ou desenhar publicações nas comunidades dos jogos ou enviar mensagens diretamente aos teus amigos.", + "rules": "Regras de Juxt", + "rules_text": { + "first": "Estas são algumas regras que permitem que Juxt seja uma experiência divertida para todos. O código de conduta Juxt contém informação detalhada, por isso lê-o com atenção.", + "second": "Publicações podem ser vistas em todo o mundo", + "third": "Juxt contém várias comunidades de jogadores onde pessoas de todo o mundo podem partilhar as suas ideias. Quando publicas numa comunidade, lembra-te que todos podem ver as tuas publicações, por isso expressa-te de uma maneira que possa ser divertida para todos. Usa o senso comum e pensa antes de publicar. Juxt é um serviço que também está acessível pela Internet, por isso pessoas que não usam Juxt também podem ver as tuas publicações. Adicionalmente, quaisquer comentários que faças em publicações de amigos são visíveis não só por estes, mas também por pessoas de todo o mundo. Tem isto em consideração.", + "fourth": "Sê simpático com os outros", + "fifth": "De forma a mantermos Juxt um lugar divertido para todos, pedimos-te que penses nas outras pessoas. Ajuda-nos a manter Juxt uma boa experiência ao não fazer publicações impróprias ou ofensivas.", + "sixth": "Não partilhes informações pessoais", + "seventh": "Lembra-te, conhecer alguém em Juxt não é o mesmo que conhecer alguém na vida real. Nunca partilhes com ninguém em Juxt o teu endereço de e-mail, morada, trabalho, nome da escola ou qualquer outra informação que te possa identificar nem partilhes informação de outras pessoas. Adicionalmente, se alguém que conheceres em Juxt te convidar para que se conheçam no mundo real, não aceites. Juxt é uma comunidade online e não deve ser usada para marcar encontros presenciais.", + "eighth": "Não publiques Spoilers", + "ninth": "Algumas pessoas vêm a Juxt à procura de dicas e truques para jogos, mas outras preferem descobrir os jogos por si mesmas. Publicações que revelam segredos de um jogo ou a sua história são chaamdas de \"spoilers.\" Se vais publicar algo sobre um jogo que pode ser um spoiler, marca a respetiva caixa antes de enviares a tua publicação. Desta forma, pessoas que não querem ver spoilers não verão a tua publicação.", + "tenth": "Violações do código de conduta", + "eleventh": "O nosso objetivo é fazer de Juxt uma comunidade divertida para todos. No caso de alguém violar o Código de Conduta de Juxt, iremos tomar as medidas necessárias que poderão incluir banir o utilizador ou a consola.", + "twelfth": "Já jogaste este jogo?", + "thirteenth": "Se publicares numa comunidade de um jogo que já jogaste, as tuas publicações irão incluir um ícone que indica que já o jogaste." + }, + "experience": "Experiência de jogo", + "experience_text": { + "info": "Fala-nos um pouco da tua experiência com jogos. Podes alterar estas definições mais tarde.", + "beginner": "Iniciante", + "intermediate": "Intermédio", + "expert": "Avançado" + }, + "google": "Google Analytics", + "google_text": "Juxtaposition usa Google Analytics de forma a recolher informações de como os utilizadores usam o serviço. Os dados recolhidos incluem, mas não estão limitados a, hora da visita, páginas visitadas e tempo passado no site. Estes dados não estão associados a ti de maneira nenhuma e não são usados para anúncios por nós nem pela Google.", + "ready": "Pronto para usar Juxt", + "ready_text": "Começa por explorar algumas comunidades e ver o que as pessoas de todo o mundo estão a publicar. Aproveita esta oportunidade para te familiarizares com Juxt. Pode ser que descubras algo novo pelo caminho!", + "done": "Diverte-te com Juxt!", + "done_button": "Vamos a isso!", + "guest": "Modo de convidado", + "guest_text": "Não nos foi possível verificar a tua conta de momento, o que provavelmente significa que tens sessão iniciada com uma conta Nintendo Network. Podes explorar Juxt, mas não te será possível marcar publicações com Fixe! ou fazer publicações até que inicies sessão com uma conta Pretendo Network. Para mais informações visita o nosso servidor Discord.", + "guest_button": "Compreendo" + } } From 4ea125d32a204652d10fdeef8d43524b1a668efb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=94=A1=E6=98=8E=E4=BF=AE?= <19470andy@gmail.com> Date: Tue, 12 Mar 2024 10:28:48 +0000 Subject: [PATCH 061/189] locales(update): Updated Chinese (Traditional) locale --- .../src/translations/zh_Hant.json | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/apps/juxtaposition-ui/src/translations/zh_Hant.json b/apps/juxtaposition-ui/src/translations/zh_Hant.json index 804b6bb4..093ba81c 100644 --- a/apps/juxtaposition-ui/src/translations/zh_Hant.json +++ b/apps/juxtaposition-ui/src/translations/zh_Hant.json @@ -16,5 +16,49 @@ "no_posts": "沒有帖子", "close": "關閉", "save": "保存" + }, + "all_communities": { + "text": "所有社區", + "announcements": "公告", + "ann_string": "點擊這裡查看最新公告!", + "popular_places": "熱門地點" + }, + "activity_feed": { + "empty": "這裡是空的。 嘗試關注某人!" + }, + "messages": { + "coming_soon": "消息尚未準備好。 稍後檢查!" + }, + "setup": { + "welcome": "歡迎來到Juxtaposition!", + "beta": "測試版免責聲明", + "beta_text": { + "first": "您即將嘗試 Juxt 的首個公開測試版。這意味著許多事情仍然不確定,並且隨時可能會有很多變化。", + "second": "這可能包括在測試版期間或結束時對數據庫進行完全清除。", + "third": "本網站、其軟件及其上的所有內容均以“現狀”和“可用性”為基礎提供。Pretendo Network 不提供任何明示或暗示的保證,包括對該網站、其軟件或任何內容的適用性或可用性。" + }, + "info": "什么是Juxtaposition?", + "info_text": "Juxt 是一個由用戶驅動的遊戲社區,您可以與世界各地的人互動。\n您可以在遊戲社區中撰寫或繪製帖子,或直接向您的朋友發送消息。", + "rules": "Juxt 規則", + "rules_text": { + "first": "以下是一些重要的指南,可讓 Juxt 成為每個人都能享受的有趣體驗。Juxt 行為準則包含詳細信息,請仔細閱讀。", + "second": "帖子可以在全球範圍內被查看", + "fourth": "彼此友善", + "fifth": "為了讓 Juxt 成為每個人都能享受的有趣場所,我們要求您對其他用戶予以考慮。請不要發布任何不適當或冒犯性的內容,幫助我們保持 Juxt 的愉快體驗。", + "sixth": "請不要發布個人信息—無論是您自己的還是他人的", + "eighth": "請不要發佈劇透貼文", + "tenth": "違反行為準則", + "eleventh": "我們的目標是保持 Juxt 對每個人都是有趣且愉快的。如果有人違反了 Juxt 行為準則,我們將採取適當的措施,包括封鎖違規用戶或主機。", + "twelfth": "你玩過那個遊戲嗎?", + "thirteenth": "如果您在玩過的遊戲社群中發帖,您的帖子將有一個圖標顯示您已經玩過它。", + "third": "Juxt 包含許多遊戲社群,來自世界各地的人們可以在這裡分享他們的想法。當你在社群中發帖時,請記住每個人都可以看到它,所以請以一種讓每個人都能享受的方式表達自己。請遵循常識,三思而後發。Juxt 是一個也可以從互聯網訪問的服務,所以請記住,那些不使用 Juxt 的人也可能看到你的帖子。此外,你對朋友帖子的任何評論都不僅僅只有你的朋友能看到,還有全世界的人。請謹記這一點。", + "seventh": "請記住,在 Juxt 認識的人與現實生活中認識的人是不同的。絕對不要在 Juxt 上與任何人分享您的電子郵件地址、家庭地址、工作或學校名稱,或其他個人身份識別信息,也絕對不要分享任何其他人的信息。此外,如果您在 Juxt 上遇到的某人邀請您在現實世界中見面,請不要接受。Juxt 是一個在線社區,不應該用於安排現實世界的見面。", + "ninth": "有些人來到 Juxt 尋找遊戲的技巧和訣竅,但其他人則希望自己探索遊戲的秘密。揭示遊戲或其故事秘密的帖子被稱為“劇透”。如果您要發佈可能是劇透的遊戲相關內容,請在發送帖子之前勾選“劇透”框。這樣,那些不想被劇透的人就不會看到您的帖子。" + }, + "experience": "遊戲經驗", + "experience_text": { + "info": "請告訴我們您如何描述自己在遊戲方面的經驗水平。您可以稍後更改此設置。" + }, + "welcome_text": "Juxt 是一個遊戲社區,它通過 Mii 角色將來自世界各地的人聯繫在一起。使用 Juxt 分享你的遊戲經驗,並結識來自世界各地的人。" } } From bdc12d950b09fac7c6a295442f9d03beb3bab0d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=9A=CF=8E=CF=83=CF=84=CE=B1=CF=82=20=CE=A3=CF=86=CF=85?= =?UTF-8?q?=CF=81=CE=AC=CE=BA=CE=B7=CF=82?= Date: Wed, 13 Mar 2024 21:38:11 +0000 Subject: [PATCH 062/189] locales(update): Updated Greek locale --- .../juxtaposition-ui/src/translations/el.json | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/el.json b/apps/juxtaposition-ui/src/translations/el.json index ac057ac0..2399b10e 100644 --- a/apps/juxtaposition-ui/src/translations/el.json +++ b/apps/juxtaposition-ui/src/translations/el.json @@ -17,7 +17,7 @@ "user_page": "Προφίλ Χρήστη" }, "all_communities": { - "ann_string": "Πατήστε για περισσότερες ανακοινώσεις!", + "ann_string": "Πατήστε εδώ για να δείτε πρόσφατες ανακοινώσεις!", "text": "Όλες οι κοινότητες", "announcements": "Ανακοινώσεις", "popular_places": "Δημοφιλή μέρη", @@ -27,24 +27,24 @@ }, "language": "Ελληνικά", "community": { - "follow": "Εγγραφή στην κοινότητα", - "following": "Εγγραφήκατε", - "followers": "Συνδρομητές", + "follow": "Ακολουθήστε την κοινότητα", + "following": "Ακολουθείτε", + "followers": "Ακόλουθοι", "posts": "Δημοσιεύσεις", "tags": "Ετικέτες", "recent": "Πρόσφατες δημοσιεύσεις", - "popular": "Δημοφιλείς Αναρτήσεις", + "popular": "Δημοφιλείς Δημοσιεύσεις", "verified": "Επαληθευμένες δημοσιεύσεις", - "new": "Σύνταξη δημοσίευσης" + "new": "Νέα δημοσίευση" }, "user_page": { "birthday": "Γενέθλια", - "game_experience": "Εμπειρία παιχνιδιού", + "game_experience": "Εμπειρία παιχνιδιών", "posts": "Δημοσιεύσεις", "friends": "Φίλοι", "following": "Ακολουθεί", "followers": "Ακόλουθοι", - "follow_user": "Εγγραφή", + "follow_user": "Ακολουθείστε", "following_user": "Ακολουθεί", "befriend": "Αποστολή αιτήματος φιλίας", "pending": "Εκκρεμεί", @@ -56,19 +56,19 @@ }, "user_settings": { "profile_settings": "Ρυθμίσεις προφίλ", - "show_country": "Προβολή χώρας στο προσωπικό προφίλ", - "show_birthday": "Προβολή Γενεθλίων στο προσωπικό προφίλ", - "show_game": "Προβολή Εμπειρίας παιχνιδιού στο προφίλ", - "show_comment": "Προβολή σχολίου στο προσωπικό προφίλ", + "show_country": "Προβολή χώρας στο προφίλ σας", + "show_birthday": "Προβολή Γενεθλίων στο προφίλ σας", + "show_game": "Προβολή Εμπειρίας παιχνιδιού στο προφίλ σας", + "show_comment": "Προβολή σχολίου στο προφίλ σας", "profile_comment": "Σχόλιο προφίλ", - "swearing": "Το σχόλιο του προφίλ δεν μπορεί να περιέχει ακατάλληλη γλώσσα." + "swearing": "Το σχόλιο του προφίλ σας δεν μπορεί να περιέχει ακατάλληλη γλώσσα." }, "activity_feed": { - "empty": "Το μέρος είναι άδειο. Δοκιμάστε να ακολουθήσετε κάποιον χρήστη!" + "empty": "Δεν υπάρχει κανένας εδώ. Δοκιμάστε να ακολουθήσετε κάποιον χρήστη!" }, "notifications": { "none": "Δεν υπάρχουν ειδοποιήσεις.", - "new_follower": "Σας ακολουθεί!" + "new_follower": "σας ακολουθεί!" }, "new_post": { "new_post_text": "Σύνταξη νέας δημοσίευσης", @@ -80,31 +80,31 @@ "coming_soon": "Τα μηνύματα δεν είναι διαθέσιμα προς το παρόν. Δοκιμάστε ξανά σύντομα!" }, "setup": { - "beta": "αποποίηση έκδοσης Beta", + "beta": "Αποποίηση ευθυνών έκδοσης Beta", "beta_text": { "first": "Πρόκειται να δοκιμάσετε την πρώτη δημόσια έκδοση beta του Juxt. Αυτό σημαίνει ότι πολλά πράγματα ενδέχεται να αλλάξουν ανά πάσα στιγμή.", "second": "Αυτό μπορεί και μπορεί να περιλαμβάνει μια πλήρη διαγραφή της βάσης δεδομένων προς το τέλος ή κατά τη διάρκεια της έκδοσης beta.", - "third": "Ο ιστότοπος, το λογισμικό του και όλο το περιεχόμενο που βρίσκεται σε αυτόν παρέχονται σε βάση «ως έχει» και «ως διαθέσιμο». Το Pretendo Network δεν παρέχει καμία εγγύηση, ρητή ή σιωπηρή, ως προς την καταλληλότητα ή τη χρηστικότητα του ιστότοπου, του λογισμικού του ή οποιουδήποτε περιεχομένου του." + "third": "Ο ιστότοπος, το λογισμικό του και όλο το περιεχόμενο που βρίσκεται σε αυτόν παρέχονται σε βάση «όπως είναι» και «όπως διατίθενται». Το Pretendo Network δεν παρέχει καμία εγγύηση, ρητή ή σιωπηρή, ως προς την καταλληλότητα ή τη χρηστικότητα του ιστότοπου, του λογισμικού του ή οποιουδήποτε περιεχομένου του." }, "info": "Τι είναι το Juxtaposition;", - "rules": "Κανόνες", + "rules": "Κανόνες Juxt", "rules_text": { "second": "Οι δημοσιεύσεις μπορούν να προβληθούν δημόσια", "fourth": "Να είστε ευγενικοί με όλους", "fifth": "Για να γίνει το Juxt ένα ευχάριστο μέρος για όλους, παρακαλούμε να είστε ευγενικοί με τους άλλους χρήστες. Βοηθήστε μας να διατηρήσουμε το Juxt ένα ευχάριστο μέρος χωρίς προσβλητικές δημοσιεύσεις ή ακατάλληλο περιεχόμενο.", "sixth": "Ποτέ μην δημοσιεύετε προσωπικές πληροφορίες-είτε δικές σας είτε των άλλων", - "eighth": "Μην δημοσιεύετε spoilers", + "eighth": "Μην δημοσιεύετε σπόιλερ", "tenth": "Παραβιάσεις του Κώδικα Δεοντολογίας", - "eleventh": "Στόχος μας είναι να διατηρήσουμε το Juxt διασκεδαστικό και ευχάριστο για όλους. Σε περίπτωση που κάποιος παραβιάσει τον Κώδικα Συμπεριφοράς της Juxt, θα λάβουμε τα κατάλληλα μέτρα, έως και τον αποκλεισμό του παραβάτη χρήστη ή κονσόλας.", + "eleventh": "Στόχος μας είναι να διατηρήσουμε το Juxt διασκεδαστικό και ευχάριστο για όλους. Σε περίπτωση που κάποιος παραβιάσει τον Κώδικα Συμπεριφοράς του Juxt, θα λάβουμε τα κατάλληλα μέτρα, έως και τον αποκλεισμό του παραβάτη χρήστη ή κονσόλας.", "twelfth": "Έχετε παίξει αυτό το παιχνίδι;", "thirteenth": "Εάν δημοσιεύετε στην κοινότητα ένα παιχνίδι που έχετε παίξει, οι αναρτήσεις σας θα έχουν ένα εικονίδιο που θα υποδεικνύει ότι το έχετε παίξει.", - "first": "Ακολουθούν ορισμένες σημαντικές οδηγίες για να κάνετε το Juxt μια διασκεδαστική και ευχάριστη εμπειρία για όλους. Ο Κώδικας Δεοντολογίας Juxt περιέχει λεπτομερείς πληροφορίες, γι' αυτό παρακαλούμε διαβάστε τον προσεκτικά.", + "first": "Ακολουθούν ορισμένες σημαντικές οδηγίες για να κάνετε το Juxt μια διασκεδαστική και ευχάριστη εμπειρία για όλους. Ο Κώδικας Δεοντολογίας του Juxt περιέχει λεπτομερείς πληροφορίες, γι' αυτό παρακαλούμε διαβάστε τον προσεκτικά.", "third": "Το Juxt περιέχει πολλές κοινότητες παιχνιδιών όπου άνθρωποι από όλο τον κόσμο μπορούν να μοιραστούν τις σκέψεις τους. Όταν δημοσιεύετε σε μια κοινότητα, να θυμάστε ότι μπορούν να το δουν όλοι, γι' αυτό εκφραστείτε με τρόπο που να μπορούν να απολαύσουν όλοι. Χρησιμοποιήστε την κοινή λογική και σκεφτείτε πριν δημοσιεύσετε. Το Juxt είναι μια υπηρεσία που είναι επίσης προσβάσιμη από το Διαδίκτυο, επομένως έχετε κατά νου ότι τα άτομα που δεν χρησιμοποιούν το Juxt μπορούν επίσης να δουν τις αναρτήσεις σας. Επιπλέον, τυχόν σχόλια που κάνετε στις αναρτήσεις των φίλων σας θα τα δουν όχι μόνο οι φίλοι σας αλλά και άνθρωποι σε όλο τον κόσμο. Παρακαλώ να το έχετε υπόψη σας.", "seventh": "Θυμηθείτε, το να γνωρίζετε κάποιον στο Juxt δεν είναι το ίδιο με το να τον γνωρίζετε στην πραγματική ζωή. Ποτέ μην μοιράζεστε τη διεύθυνση e-mail, τη διεύθυνση κατοικίας, το όνομα εργασίας ή σχολείου σας ή άλλες πληροφορίες προσωπικής ταυτοποίησης με κανέναν στο Juxt και ποτέ μην κοινοποιείτε τις πληροφορίες κανενός άλλου. Επιπλέον, αν κάποιος που συναντάτε στο Juxt σας προσκαλεί να τον γνωρίσετε στον πραγματικό κόσμο, μην το δεχθείτε. Το Juxt είναι μια διαδικτυακή κοινότητα και δεν πρέπει να χρησιμοποιείται για την οργάνωση πραγματικών συναντήσεων.", - "ninth": "Μερικοί άνθρωποι έρχονται στο Juxt αναζητώντας συμβουλές και κόλπα για παιχνίδια, αλλά άλλοι θέλουν να ανακαλύψουν τα μυστικά ενός παιχνιδιού μόνοι τους. Οι δημοσιεύσεις που αποκαλύπτουν μυστικά ενός παιχνιδιού ή της ιστορίας του ονομάζονται \"σπόιλερ\". Εάν δημοσιεύετε κάτι για ένα παιχνίδι που μπορεί να είναι spoiler, φροντίστε να ελέγξετε το πλαίσιο Spoilers πριν στείλετε τη δημοσίευσή σας. Με αυτόν τον τρόπο, τα άτομα που δεν θέλουν να κακομαθαίνουν δεν θα βλέπουν την ανάρτησή σας." + "ninth": "Μερικοί άνθρωποι έρχονται στο Juxt αναζητώντας συμβουλές και κόλπα για παιχνίδια, αλλά άλλοι θέλουν να ανακαλύψουν τα μυστικά ενός παιχνιδιού μόνοι τους. Οι δημοσιεύσεις που αποκαλύπτουν μυστικά ενός παιχνιδιού ή της ιστορίας του ονομάζονται «σπόιλερ». Εάν δημοσιεύετε κάτι για ένα παιχνίδι που μπορεί να είναι σπόιλερ, φροντίστε να ελέγξετε το πλαίσιο «Spoiler» πριν στείλετε τη δημοσίευσή σας. Με αυτόν τον τρόπο, τα άτομα που δεν θέλουν να κακομαθαίνουν δεν θα βλέπουν την ανάρτησή σας." }, "welcome": "Καλώς ήρθατε στο Juxtaposition!", - "info_text": "Το Juxt είναι μια κοινότητα παιχνιδιών με γνώμονα τον χρήστη, όπου μπορείτε να αλληλεπιδράσετε με ανθρώπους\nσε όλο τον κόσμο. Μπορείτε να γράφετε ή να σχεδιάζετε αναρτήσεις σε κοινότητες παιχνιδιών ή να στέλνετε μηνύματα απευθείας στους φίλους σας.", + "info_text": "Το Juxt είναι μια κοινότητα παιχνιδιών με γνώμονα τον χρήστη, όπου μπορείτε να αλληλεπιδράσετε με ανθρώπους\n από όλο τον κόσμο. Μπορείτε να γράφετε ή να σχεδιάζετε αναρτήσεις σε κοινότητες παιχνιδιών ή να στέλνετε μηνύματα απευθείας στους φίλους σας.", "welcome_text": "Το Juxt είναι μια gaming κοινότητα που συνδέει ανθρώπους από όλο τον κόσμο χρησιμοποιώντας χαρακτήρες Mii. Χρησιμοποιήστε το Juxt για να μοιραστείτε τις εμπειρίες σας στα παιχνίδια και να γνωρίσετε άτομα από όλο τον κόσμο.", "google_text": "Το juxtaposition χρησιμοποιεί την υπηρεσία Google Analytics έτσι ώστε να συλλέγει πληροφορίες σχετικά με το πως οι χρήστες χρησιμοποιούν την υπηρεσία μας. Οι πληροφορίες περιλαμβάνουν τον χρόνο επίσκεψης ιστότοπων. Οι πληροφορίες δεν χρησιμοποιούνται εναντίων σας και δεν χρησιμοποιούνται για διαφημίσεις από εμάς ή από την Google.", "experience": "Εμπειρία παιχνιδιού", @@ -115,7 +115,7 @@ "expert": "Εξπέρ" }, "google": "Google Analytics", - "ready": "Έτοιμοι να ξεκινήσετε τη χρήση του Juxt", + "ready": "Είστε έτοιμοι να ξεκινήσετε τη χρήση του Juxt", "ready_text": "Πρώτα ελέγξτε μερικές κοινότητες και δείτε τι δημοσιεύουν άνθρωποι από όλο τον κόσμο. Εκμεταλλευτείτε αυτήν την ευκαιρία για να εξοικειωθείτε με το Juxt. Ίσως κάνετε κάποιες νέες ανακαλύψεις στην πορεία!", "done": "Καλή διασκέδαση στο Juxt!", "done_button": "Ας αρχίσουμε!", From 5ee01908ac5d9a82cafef677947032a460eeab18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9listine=20Oosting?= Date: Wed, 27 Mar 2024 16:08:44 +0000 Subject: [PATCH 063/189] locales(update): Updated Dutch locale --- .../juxtaposition-ui/src/translations/nl.json | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/nl.json b/apps/juxtaposition-ui/src/translations/nl.json index 1f40e945..cfb0fbe3 100644 --- a/apps/juxtaposition-ui/src/translations/nl.json +++ b/apps/juxtaposition-ui/src/translations/nl.json @@ -18,16 +18,16 @@ "next": "Volgende" }, "all_communities": { - "text": "Alle Gemeenschappen", + "text": "Alle Communities", "announcements": "Aankondigingen", "ann_string": "Klik hier om recente aankondigen te bekijken!", - "popular_places": "Populaire Gemeenschappen", - "new_communities": "Nieuwe Gemeenschappen", + "popular_places": "Populaire Communities", + "new_communities": "Nieuwe Communities", "show_all": "Alles weergeven", - "search": "Zoek gemeenschappen..." + "search": "Zoek communities..." }, "community": { - "follow": "Volg gemeenschap", + "follow": "Volg Community", "following": "Volgend", "followers": "Volgers", "posts": "Posts", @@ -39,7 +39,7 @@ }, "user_page": { "country": "Land", - "birthday": "Geboortedatum", + "birthday": "Verjaardag", "game_experience": "Game Ervaring", "posts": "Posts", "friends": "Vrienden", @@ -56,10 +56,10 @@ }, "user_settings": { "profile_settings": "Profiel instellingen", - "show_country": "Weergeef Land op Profiel", - "show_birthday": "Weergeef Geboortedatum op Profiel", - "show_game": "Weergeef Game Ervaring op Profiel", - "show_comment": "Weergeef Omschrijving op Profiel", + "show_country": "Geef Land op Profiel weer", + "show_birthday": "Geef Verjaardag op Profiel weer", + "show_game": "Geef Game Ervaring op Profiel weer", + "show_comment": "Geef Omschrijving op Profiel weer", "profile_comment": "Profiel Omschrijving", "swearing": "Profiel omschrijving kan geen expliciete tekst bevatten." }, @@ -85,7 +85,7 @@ "beta": "Beta-disclaimer", "beta_text": { "first": "Je staat op het punt de eerste publieke beta van Juxt te gebruiken. Dit betekent dat veel onzeker is en ook van alles kan veranderen.", - "second": "Dit kan mogelijk een volledige reset van de database bevatten aan het einde van de beta periode of tijdens deze periode.", + "second": "Dit kan mogelijk een volledige reset van de database aan het einde van de beta periode of tijdens deze periode omvatten.", "third": "De website, de software die het bevat, alsook alle content dat te vinden is op deze website, worden geleverd op een \"as is\" en \"as available\" basis. Pretendo Network geeft geen garantstellingen, ofwel expliciet ofwel impliciet, met betrekking tot de geschiktheid of bruikbaarheid van de website, de software die het bevat of de content op de website." }, "info": "Wat is Juxtaposition?", From 5ed028e20b8b6c16f3e361de3aa3b87e310b2117 Mon Sep 17 00:00:00 2001 From: Terezija Zivkovic Date: Sun, 31 Mar 2024 05:52:31 +0200 Subject: [PATCH 064/189] locales(add): Added Croatian locale --- apps/juxtaposition-ui/src/translations/hr.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/juxtaposition-ui/src/translations/hr.json diff --git a/apps/juxtaposition-ui/src/translations/hr.json b/apps/juxtaposition-ui/src/translations/hr.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/apps/juxtaposition-ui/src/translations/hr.json @@ -0,0 +1 @@ +{} From 20da34a85bd9cd2223c6bed1c17e6394f06c29c0 Mon Sep 17 00:00:00 2001 From: Terezija Zivkovic Date: Sun, 31 Mar 2024 03:55:25 +0000 Subject: [PATCH 065/189] locales(update): Updated Croatian locale --- .../juxtaposition-ui/src/translations/hr.json | 95 ++++++++++++++++++- 1 file changed, 94 insertions(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/hr.json b/apps/juxtaposition-ui/src/translations/hr.json index 0967ef42..0673b36d 100644 --- a/apps/juxtaposition-ui/src/translations/hr.json +++ b/apps/juxtaposition-ui/src/translations/hr.json @@ -1 +1,94 @@ -{} +{ + "global": { + "go_back": "Idi Natrag", + "back": "Natrag", + "yeahs": "Da", + "more": "Učitaj Više Postova", + "no_posts": "Nema Postova", + "close": "Zatvoriti", + "save": "Sačuvati", + "exit": "Izlaženje", + "private": "Privatno", + "next": "Idući", + "activity_feed": "Feed Aktivnosti", + "user_page": "Korisnička Stranica", + "communities": "Zajednice", + "messages": "Poruke", + "notifications": "Obavijesti" + }, + "all_communities": { + "text": "Sve Zajednice", + "announcements": "Najavljivanja", + "ann_string": "Kliknite Ovdje Za Pregled Nedavnih Najava!", + "popular_places": "Popularna Mjesta", + "new_communities": "Novi Zajednice", + "show_all": "Pokaži Sve", + "search": "Traži Zajednice..." + }, + "community": { + "follow": "Slijediti Zajednič", + "tags": "Označiti", + "posts": "Postovi", + "recent": "Najnovije Objave", + "popular": "Popularan Objave", + "verified": "Potvrđeni Objave", + "new": "Novi Objave", + "following": "Sljedeći", + "followers": "Sljedbenik" + }, + "user_page": { + "country": "Domovina", + "birthday": "Rođendan", + "game_experience": "Iskustvo Igre", + "posts": "Postovi", + "friends": "Prijatelji", + "follow_user": "Pratiti", + "unfriend": "Ukinuti Prijateljstvo", + "no_friends": "Bez Prijatelja", + "following": "Sljedeći", + "following_user": "Sljedeći", + "no_following": "Ne Slijedeći Nikoga", + "followers": "Sljedbenik", + "no_followers": "Nema Sljedbenika", + "befriend": "Steći Prijatelje", + "pending": "U Tijeku" + }, + "user_settings": { + "profile_settings": "Profil Opcije", + "show_country": "Pokazati Nacija Na Profil", + "show_birthday": "Pokazati Rođendan Na Profil", + "show_game": "Pokazati Iskustvo Igre Na Profil", + "profile_comment": "Profil Primjedba", + "swearing": "Komentar Profila Ne Smije Sadržavati Eksplicitan Jezik.", + "show_comment": "Pokazati Primjedba Na Profil" + }, + "notifications": { + "none": "Nema Obavijestia.", + "new_follower": "Pratio Te!" + }, + "new_post": { + "new_post_text": "Nova Postova", + "post_to": "Postov do", + "swearing": "Post Ne Smije Sadržavati Eksplicitan Jezik.", + "text_hint": "Dodirnite ovdje za napraviti a poštov." + }, + "messages": { + "coming_soon": "Poruke Ne Spremne Još. Vrati Se Kasnije!" + }, + "setup": { + "welcome": "Dobrodošli u Juxtaposition!", + "beta": "Beta Odricanje", + "beta_text": { + "first": "Upravo ćete Isprobati Javnu Beta Verziju Juxt. To Znači da se Još Mnogo Toga Može Promijeniti u Bilo Kojem Vrijeme.", + "second": "To Mogla Značiti da se Podaci Mogu Izbrisati u Bilo Kojem Vrijem Tijekom Beta Razdoblja.", + "third": "Web Stranica, Njezin Softver i Sav Sadržaj Koji se na Njoj Nalazi Dostupni su na Temelju \"Kakvi Jesu\" i \"Kako su Dostupni\". Pretendo Network ne Daje Nikakva Jamstva, Izričita Ili Prešutna, u Pogledu Prikladnosti Ili Upotrebljivosti Web Stranice, Njezinog Softvera Ili Bilo Kojeg Njezinog Sadržaja." + }, + "info": "Što je Juxtaposition?", + "welcome_text": "Juxt Je Igraća Zajednica Koji Povezuje ljudi iz Diljem Svijeta Koristeći Mii Likovi. Koristite Juxt do Podijelite Svoje Iskustvo Igranja i Upoznati Ljude iz Diljem Svijeta.", + "info_text": "Juxt je Zajednica Igara Vođena Korisnicima u Kojoj Možete Komunicirati s Ljudima \nDiljem Svijeta" + }, + "language": "Hrvatski", + "activity_feed": { + "empty": "to je prazno ovdje. Pokušajte Pratiti Nekoga!" + } +} From 7367c0ccb8df6cc4fb56a3cc234af7a26cee12a9 Mon Sep 17 00:00:00 2001 From: hamsterbot Date: Wed, 3 Apr 2024 17:49:36 +0000 Subject: [PATCH 066/189] locales(update): Updated Korean locale --- apps/juxtaposition-ui/src/translations/ko.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/ko.json b/apps/juxtaposition-ui/src/translations/ko.json index 254f0775..0aa71c1b 100644 --- a/apps/juxtaposition-ui/src/translations/ko.json +++ b/apps/juxtaposition-ui/src/translations/ko.json @@ -8,8 +8,8 @@ "notifications": "알림", "go_back": "뒤로 가기", "back": "뒤로", - "yeahs": "맞네", - "more": "추가 포스트 로드", + "yeahs": "좋아요", + "more": "포스트 더보기", "no_posts": "포스트 없음", "private": "비공개", "close": "닫기", @@ -23,7 +23,7 @@ "ann_string": "여기를 클릭해서 최근 공지를 확인하세요!", "popular_places": "유명한 곳", "new_communities": "새로운 커뮤니티", - "show_all": "모두 보이기", + "show_all": "모두 보기", "search": "커뮤니티 검색..." }, "community": { From 0283d45edca8d4cef40d8973f373b4e439436a47 Mon Sep 17 00:00:00 2001 From: Jau CR Date: Mon, 8 Apr 2024 18:14:15 +0000 Subject: [PATCH 067/189] locales(update): Updated Spanish locale --- apps/juxtaposition-ui/src/translations/es.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/es.json b/apps/juxtaposition-ui/src/translations/es.json index 48050d1a..2489fee6 100644 --- a/apps/juxtaposition-ui/src/translations/es.json +++ b/apps/juxtaposition-ui/src/translations/es.json @@ -1,8 +1,8 @@ { "language": "Español", "global": { - "user_page": "Perfil", - "activity_feed": "Registro de actividad", + "user_page": "Menú de usuario", + "activity_feed": "Actividad", "communities": "Comunidades", "messages": "Mensajes", "notifications": "Notificaciones", From bb70f36fcdaed13ea60d09ddedef49e7fe40fbe6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=9A=CF=8E=CF=83=CF=84=CE=B1=CF=82=20=CE=A3=CF=86=CF=85?= =?UTF-8?q?=CF=81=CE=AC=CE=BA=CE=B7=CF=82?= Date: Wed, 10 Apr 2024 21:18:23 +0000 Subject: [PATCH 068/189] locales(update): Updated Greek locale --- apps/juxtaposition-ui/src/translations/el.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/el.json b/apps/juxtaposition-ui/src/translations/el.json index 2399b10e..c1c5051e 100644 --- a/apps/juxtaposition-ui/src/translations/el.json +++ b/apps/juxtaposition-ui/src/translations/el.json @@ -7,7 +7,7 @@ "messages": "Μηνύματα", "notifications": "Ειδοποιήσεις", "go_back": "Πήγαινε Πίσω", - "yeahs": "Ναιs", + "yeahs": "Τέλειο", "no_posts": "Δεν υπάρχουν δημοσιεύσεις", "more": "Φόρτωση περισσότερων δημοσιεύσεων", "private": "Ιδιωτικό", From 7b1e97ce9602f21f33d9daa06859b85f6e493ee8 Mon Sep 17 00:00:00 2001 From: serrinuma Date: Wed, 10 Apr 2024 21:20:40 +0000 Subject: [PATCH 069/189] locales(update): Updated Greek locale --- apps/juxtaposition-ui/src/translations/el.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/el.json b/apps/juxtaposition-ui/src/translations/el.json index c1c5051e..f53411d0 100644 --- a/apps/juxtaposition-ui/src/translations/el.json +++ b/apps/juxtaposition-ui/src/translations/el.json @@ -44,7 +44,7 @@ "friends": "Φίλοι", "following": "Ακολουθεί", "followers": "Ακόλουθοι", - "follow_user": "Ακολουθείστε", + "follow_user": "Ακολουθήστε", "following_user": "Ακολουθεί", "befriend": "Αποστολή αιτήματος φιλίας", "pending": "Εκκρεμεί", @@ -56,10 +56,10 @@ }, "user_settings": { "profile_settings": "Ρυθμίσεις προφίλ", - "show_country": "Προβολή χώρας στο προφίλ σας", - "show_birthday": "Προβολή Γενεθλίων στο προφίλ σας", - "show_game": "Προβολή Εμπειρίας παιχνιδιού στο προφίλ σας", - "show_comment": "Προβολή σχολίου στο προφίλ σας", + "show_country": "Προβολή χώρας στο προφίλ", + "show_birthday": "Προβολή Γενεθλίων στο προφίλ", + "show_game": "Προβολή Εμπειρίας παιχνιδιού στο προφίλ", + "show_comment": "Προβολή σχολίου στο προφίλ", "profile_comment": "Σχόλιο προφίλ", "swearing": "Το σχόλιο του προφίλ σας δεν μπορεί να περιέχει ακατάλληλη γλώσσα." }, @@ -106,7 +106,7 @@ "welcome": "Καλώς ήρθατε στο Juxtaposition!", "info_text": "Το Juxt είναι μια κοινότητα παιχνιδιών με γνώμονα τον χρήστη, όπου μπορείτε να αλληλεπιδράσετε με ανθρώπους\n από όλο τον κόσμο. Μπορείτε να γράφετε ή να σχεδιάζετε αναρτήσεις σε κοινότητες παιχνιδιών ή να στέλνετε μηνύματα απευθείας στους φίλους σας.", "welcome_text": "Το Juxt είναι μια gaming κοινότητα που συνδέει ανθρώπους από όλο τον κόσμο χρησιμοποιώντας χαρακτήρες Mii. Χρησιμοποιήστε το Juxt για να μοιραστείτε τις εμπειρίες σας στα παιχνίδια και να γνωρίσετε άτομα από όλο τον κόσμο.", - "google_text": "Το juxtaposition χρησιμοποιεί την υπηρεσία Google Analytics έτσι ώστε να συλλέγει πληροφορίες σχετικά με το πως οι χρήστες χρησιμοποιούν την υπηρεσία μας. Οι πληροφορίες περιλαμβάνουν τον χρόνο επίσκεψης ιστότοπων. Οι πληροφορίες δεν χρησιμοποιούνται εναντίων σας και δεν χρησιμοποιούνται για διαφημίσεις από εμάς ή από την Google.", + "google_text": "Το Juxtaposition χρησιμοποιεί την υπηρεσία Google Analytics έτσι ώστε να συλλέγει πληροφορίες σχετικά με το πως οι χρήστες χρησιμοποιούν την υπηρεσία μας. Οι πληροφορίες περιλαμβάνουν τον χρόνο επίσκεψης ιστότοπων. Οι πληροφορίες δεν χρησιμοποιούνται εναντίων σας και δεν χρησιμοποιούνται για διαφημίσεις από εμάς ή από την Google.", "experience": "Εμπειρία παιχνιδιού", "experience_text": { "info": "Πείτε μας πώς θα περιγράφατε το επίπεδο εμπειρίας σας με τα παιχνίδια. Μπορείτε να αλλάξετε αυτήν τη ρύθμιση αργότερα.", @@ -121,6 +121,6 @@ "done_button": "Ας αρχίσουμε!", "guest": "Λειτουργία καλεσμένου", "guest_button": "Το κατάλαβα", - "guest_text": "Δεν μπορούμε να επαληθεύσουμε τον λογαριασμό σας αυτήν τη στιγμή, πράγμα που πιθανότατα σημαίνει ότι αυτή τη στιγμή συνδέεστε με λογαριασμό Nintendo Network. Θα εξακολουθείτε να μπορείτε να περιηγηθείτε στο Juxt, αλλά δεν θα μπορείτε να αλληλεπιδράσετε με Yeah! δημοσιεύετε ή κάνετε δικές σας αναρτήσεις μέχρι να συνδεθείτε με έναν λογαριασμό Pretendo Network. Για περισσότερες πληροφορίες, ελέγξτε τον διακομιστή μας στο Discord." + "guest_text": "Δεν μπορούμε να επαληθεύσουμε τον λογαριασμό σας αυτήν τη στιγμή, πράγμα που πιθανότατα σημαίνει ότι αυτή τη στιγμή συνδέεστε με λογαριασμό Nintendo Network. Θα εξακολουθείτε να μπορείτε να περιηγηθείτε στο Juxt, αλλά δεν θα μπορείτε να αλληλεπιδράσετε με Τέλειο!, δημοσιεύετε ή κάνετε δικές σας αναρτήσεις μέχρι να συνδεθείτε με έναν λογαριασμό Pretendo Network. Για περισσότερες πληροφορίες, ελέγξτε τον διακομιστή μας στο Discord." } } From c4d8ced8471b5eaf1ba71638980cf444ee44cc7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=9A=CF=8E=CF=83=CF=84=CE=B1=CF=82=20=CE=A3=CF=86=CF=85?= =?UTF-8?q?=CF=81=CE=AC=CE=BA=CE=B7=CF=82?= Date: Wed, 10 Apr 2024 21:26:02 +0000 Subject: [PATCH 070/189] locales(update): Updated Greek locale --- apps/juxtaposition-ui/src/translations/el.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/el.json b/apps/juxtaposition-ui/src/translations/el.json index f53411d0..52e29099 100644 --- a/apps/juxtaposition-ui/src/translations/el.json +++ b/apps/juxtaposition-ui/src/translations/el.json @@ -3,7 +3,7 @@ "back": "Πίσω", "communities": "Κοινότητες", "exit": "Έξοδος", - "activity_feed": "Ροή δραστηριότητας", + "activity_feed": "Δραστηριότητες", "messages": "Μηνύματα", "notifications": "Ειδοποιήσεις", "go_back": "Πήγαινε Πίσω", From 03dde31c4db2394621864b47df9ea5c251ec1f01 Mon Sep 17 00:00:00 2001 From: niko Date: Fri, 12 Apr 2024 02:26:17 +0200 Subject: [PATCH 071/189] locales(add): Added French (Canada) locale --- apps/juxtaposition-ui/src/translations/fr_CA.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/juxtaposition-ui/src/translations/fr_CA.json diff --git a/apps/juxtaposition-ui/src/translations/fr_CA.json b/apps/juxtaposition-ui/src/translations/fr_CA.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/apps/juxtaposition-ui/src/translations/fr_CA.json @@ -0,0 +1 @@ +{} From ed7f74d4786ea91024971fa6aeb8828a2223ff78 Mon Sep 17 00:00:00 2001 From: Evan Lie Date: Fri, 12 Apr 2024 19:20:24 +0200 Subject: [PATCH 072/189] locales(add): Added Indonesian locale --- apps/juxtaposition-ui/src/translations/id.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/juxtaposition-ui/src/translations/id.json diff --git a/apps/juxtaposition-ui/src/translations/id.json b/apps/juxtaposition-ui/src/translations/id.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/apps/juxtaposition-ui/src/translations/id.json @@ -0,0 +1 @@ +{} From c2727068d75e08766b7c61ba939c262ed826f7bc Mon Sep 17 00:00:00 2001 From: Trevlin Morris Date: Fri, 12 Apr 2024 00:33:31 +0000 Subject: [PATCH 073/189] locales(update): Updated French (Canada) locale --- .../src/translations/fr_CA.json | 88 ++++++++++++++++++- 1 file changed, 87 insertions(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/fr_CA.json b/apps/juxtaposition-ui/src/translations/fr_CA.json index 0967ef42..f342b198 100644 --- a/apps/juxtaposition-ui/src/translations/fr_CA.json +++ b/apps/juxtaposition-ui/src/translations/fr_CA.json @@ -1 +1,87 @@ -{} +{ + "global": { + "user_page": "Page de Utilisateur", + "activity_feed": "Flux d'activité", + "communities": "Communauté", + "messages": "Messages", + "notifications": "Notifications", + "go_back": "Retourner", + "back": "Revenir", + "yeahs": "Ouias", + "more": "Charger plus posts", + "no_posts": "Sans Posts", + "private": "Privé", + "close": "Fermer", + "save": "Enregistrer", + "exit": "Sortir", + "next": "Prochain" + }, + "all_communities": { + "announcements": "Annonce", + "popular_places": "Endroit Populaire", + "new_communities": "Nouveau Communautés", + "show_all": "Tout Montrer", + "search": "Chercher Communautés...", + "text": "Tout Communautés", + "ann_string": "Cliquer Ici à Vue Annonce Récent!" + }, + "community": { + "follow": "Suivre Communauté", + "following": "Suivant", + "followers": "Followers", + "tags": "Taguer", + "posts": "Posters", + "recent": "Posters Récent", + "popular": "Posters de Populaire", + "verified": "Posters de Vérifié", + "new": "Nouveau Poster" + }, + "user_page": { + "country": "Pays", + "birthday": "Anniversaire", + "game_experience": "Expérience de Jeux", + "posts": "Posters", + "friends": "Amis", + "following": "Suivants", + "followers": "Followers", + "follow_user": "Suivre", + "following_user": "Suivants", + "befriend": "Devenir Amis", + "pending": "En Attente", + "unfriend": "Enlever Amis", + "no_friends": "Sans Amis", + "no_following": "Pas Suivants Quiconque", + "no_followers": "Sans Followers" + }, + "user_settings": { + "profile_settings": "Préférences de Profil", + "show_country": "Montrer Pays Sur Profil", + "show_birthday": "Montrer Anniversaire Sur Profil", + "show_game": "Montrer Expérience de Jeux Sur Profil", + "show_comment": "Montrer Commentaire Sur Profile", + "profile_comment": "Commentaire de Profil", + "swearing": "Commentaire de Profil Pouvoir Pas Contenir Langue Explicite." + }, + "activity_feed": { + "empty": "Son Vide Ici. Essayer Suivants Quelqu'un!" + }, + "notifications": { + "none": "Sans Notifications.", + "new_follower": "suivi tu!" + }, + "new_post": { + "new_post_text": "Nouveau Poster", + "post_to": "Poster à", + "text_hint": "Cliquez Ici à Créer Une Poster.", + "swearing": "Poster Pouvoir Pas Contenir Langue Explicite." + }, + "messages": { + "coming_soon": "Messages N'est Pas Prêt Maintenant. Revenir Bientôt!" + }, + "setup": { + "welcome": "Bienvenue à Juxtaposition!", + "welcome_text": "Juxt Est un Communauté de Jeux ça Relier Gens de Tout le Monde Utiliser Personnage Mii. Utiliser Juxt à Partager Ton Expérience de Jeux et Retrouver Gens de Tout le Monde.", + "beta": "Bêta Avertissement" + }, + "language": "Français (CA)" +} From 372d24a7f99abaf87995bd6391fbc6fecb4287f7 Mon Sep 17 00:00:00 2001 From: Trevlin Morris Date: Fri, 12 Apr 2024 17:26:21 +0000 Subject: [PATCH 074/189] locales(update): Updated French (Canada) locale --- apps/juxtaposition-ui/src/translations/fr_CA.json | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/fr_CA.json b/apps/juxtaposition-ui/src/translations/fr_CA.json index f342b198..1a38fbde 100644 --- a/apps/juxtaposition-ui/src/translations/fr_CA.json +++ b/apps/juxtaposition-ui/src/translations/fr_CA.json @@ -81,7 +81,15 @@ "setup": { "welcome": "Bienvenue à Juxtaposition!", "welcome_text": "Juxt Est un Communauté de Jeux ça Relier Gens de Tout le Monde Utiliser Personnage Mii. Utiliser Juxt à Partager Ton Expérience de Jeux et Retrouver Gens de Tout le Monde.", - "beta": "Bêta Avertissement" + "beta": "Bêta Avertissement", + "beta_text": { + "first": "Tu es Tester la Premier public Bêta de Juxt. Ceci Signifier ça Beucoup est Encore au air, et ça Beucoup Pouvoir Changer à de Temps.", + "second": "Ceci Pouvoir et il se Peut Que Comprendre un Effacer total à le Conclusion ou Pendant le Période Bêta.", + "third": "Le site, et ça est Logiciel et Tout Content Trouvé dans il es Fourni il un \"tel quel\" et \"tel disponible\" base. Le Pretendo Network Pouvoir pas Donner du Clause, si Formel ou Impliquer, Aussi à le Convenir ou Convivialité de le site, et C'est Logiciel ou si de Contenu." + }, + "info": "Qu'est que Juxtaposition?", + "info_text": "Juxt est un Utilisateur-Motivé Communauté où tu Pouvoir Interagir avec Gens\nPartout le Montrer. Tu Pouvoir écrire et Dessiner Poster dans Communauté de Jeux ou Envoyer Messages Directement à ton amis.", + "rules": "Règle de Juxt" }, "language": "Français (CA)" } From 1a77d20734697963e6e32aa60dc1377347186321 Mon Sep 17 00:00:00 2001 From: Evan Lie Date: Fri, 12 Apr 2024 17:22:45 +0000 Subject: [PATCH 075/189] locales(update): Updated Indonesian locale --- apps/juxtaposition-ui/src/translations/id.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/id.json b/apps/juxtaposition-ui/src/translations/id.json index 0967ef42..660bda7d 100644 --- a/apps/juxtaposition-ui/src/translations/id.json +++ b/apps/juxtaposition-ui/src/translations/id.json @@ -1 +1,15 @@ -{} +{ + "global": { + "user_page": "Halaman Pengguna", + "communities": "Komunitas", + "activity_feed": "Halaman Aktivitas", + "messages": "Pesan", + "notifications": "Notifikasi", + "go_back": "Kembali", + "back": "Kembali", + "yeahs": "Ya", + "more": "Memuat Postingan", + "no_posts": "Tidak ada Postingan" + }, + "language": "Bahasa Indonesia" +} From d3efe9558b8880f8c23727f1b81a81ee04c5ffc5 Mon Sep 17 00:00:00 2001 From: nyajiiro Date: Sat, 13 Apr 2024 06:34:48 +0000 Subject: [PATCH 076/189] locales(update): Updated Chinese (Traditional) locale --- .../src/translations/zh_Hant.json | 144 +++++++++++++----- 1 file changed, 103 insertions(+), 41 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/zh_Hant.json b/apps/juxtaposition-ui/src/translations/zh_Hant.json index 093ba81c..a2425534 100644 --- a/apps/juxtaposition-ui/src/translations/zh_Hant.json +++ b/apps/juxtaposition-ui/src/translations/zh_Hant.json @@ -1,64 +1,126 @@ { - "language": "中文", + "language": "繁體中文", "global": { - "user_page": "用戶頁面", - "exit": "退出", - "activity_feed": "活動提要", - "messages": "通知", - "notifications": "通知", - "communities": "社區", - "go_back": "返回", - "yeahs": "同意", + "user_page": "個人檔案", + "exit": "離開", + "activity_feed": "動態消息", + "messages": "聊天訊息", + "notifications": "通知中心", + "communities": "社群子板", + "go_back": "返回上層", + "yeahs": "我贊同", "back": "返回", - "more": "加載更多帖子", + "more": "繼續載入投稿", "private": "私人", "next": "繼續", - "no_posts": "沒有帖子", + "no_posts": "查無投稿", "close": "關閉", - "save": "保存" + "save": "儲存" }, "all_communities": { - "text": "所有社區", + "text": "所有社群子板", "announcements": "公告", - "ann_string": "點擊這裡查看最新公告!", - "popular_places": "熱門地點" + "ann_string": "點選此處查看近期公告!", + "popular_places": "熱門子板", + "new_communities": "新設子板", + "show_all": "顯示所有", + "search": "搜尋子板……" }, "activity_feed": { - "empty": "這裡是空的。 嘗試關注某人!" + "empty": "這裡空空如也。先去跟隨其他人吧!" }, "messages": { - "coming_soon": "消息尚未準備好。 稍後檢查!" + "coming_soon": "聊天功能尚未準備就緒。敬請期待!" }, "setup": { - "welcome": "歡迎來到Juxtaposition!", - "beta": "測試版免責聲明", + "welcome": "歡迎來到 Juxtaposition!", + "beta": "《Beta 免責聲明》", "beta_text": { - "first": "您即將嘗試 Juxt 的首個公開測試版。這意味著許多事情仍然不確定,並且隨時可能會有很多變化。", - "second": "這可能包括在測試版期間或結束時對數據庫進行完全清除。", - "third": "本網站、其軟件及其上的所有內容均以“現狀”和“可用性”為基礎提供。Pretendo Network 不提供任何明示或暗示的保證,包括對該網站、其軟件或任何內容的適用性或可用性。" + "first": "您即將使用之 Juxt 首個公開測試 Beta 版本,即知曉許多功能仍未開發完全,且可能隨時變動。", + "second": "您應知曉 Beta 期間之資料庫數據,日後可能遭到擦除。", + "third": "本網站及其軟體與附屬內容,均基於「現況性」與「可提供性」為開展。Pretendo Network 絕不保證(無論其明示抑或暗示)本網站及其軟體與附屬內容之合用性或可用性。" }, - "info": "什么是Juxtaposition?", - "info_text": "Juxt 是一個由用戶驅動的遊戲社區,您可以與世界各地的人互動。\n您可以在遊戲社區中撰寫或繪製帖子,或直接向您的朋友發送消息。", - "rules": "Juxt 規則", + "info": "什麼是 Juxtaposition?", + "info_text": "Juxt 是由玩家們自發組成的遊戲社群;是能與全世界的人們相互交流的好所在。\n 您可以在遊戲子板投稿您的書寫文章以及繪畫作品,或者傳送訊息給好友。", + "rules": "《Juxt 社群守則》", "rules_text": { - "first": "以下是一些重要的指南,可讓 Juxt 成為每個人都能享受的有趣體驗。Juxt 行為準則包含詳細信息,請仔細閱讀。", - "second": "帖子可以在全球範圍內被查看", - "fourth": "彼此友善", - "fifth": "為了讓 Juxt 成為每個人都能享受的有趣場所,我們要求您對其他用戶予以考慮。請不要發布任何不適當或冒犯性的內容,幫助我們保持 Juxt 的愉快體驗。", - "sixth": "請不要發布個人信息—無論是您自己的還是他人的", - "eighth": "請不要發佈劇透貼文", - "tenth": "違反行為準則", - "eleventh": "我們的目標是保持 Juxt 對每個人都是有趣且愉快的。如果有人違反了 Juxt 行為準則,我們將採取適當的措施,包括封鎖違規用戶或主機。", - "twelfth": "你玩過那個遊戲嗎?", - "thirteenth": "如果您在玩過的遊戲社群中發帖,您的帖子將有一個圖標顯示您已經玩過它。", - "third": "Juxt 包含許多遊戲社群,來自世界各地的人們可以在這裡分享他們的想法。當你在社群中發帖時,請記住每個人都可以看到它,所以請以一種讓每個人都能享受的方式表達自己。請遵循常識,三思而後發。Juxt 是一個也可以從互聯網訪問的服務,所以請記住,那些不使用 Juxt 的人也可能看到你的帖子。此外,你對朋友帖子的任何評論都不僅僅只有你的朋友能看到,還有全世界的人。請謹記這一點。", - "seventh": "請記住,在 Juxt 認識的人與現實生活中認識的人是不同的。絕對不要在 Juxt 上與任何人分享您的電子郵件地址、家庭地址、工作或學校名稱,或其他個人身份識別信息,也絕對不要分享任何其他人的信息。此外,如果您在 Juxt 上遇到的某人邀請您在現實世界中見面,請不要接受。Juxt 是一個在線社區,不應該用於安排現實世界的見面。", - "ninth": "有些人來到 Juxt 尋找遊戲的技巧和訣竅,但其他人則希望自己探索遊戲的秘密。揭示遊戲或其故事秘密的帖子被稱為“劇透”。如果您要發佈可能是劇透的遊戲相關內容,請在發送帖子之前勾選“劇透”框。這樣,那些不想被劇透的人就不會看到您的帖子。" + "first": "為了讓 Juxt 的大家都能享受樂趣,敬請詳閱《Juxt 社群守則》。以下將羅列數條為務必遵守的規範。", + "second": "投稿應全球皆宜", + "fourth": "人們應彼此共好", + "fifth": "為了讓 Juxt 的大家享受到樂趣,請您多對其他使用者關愛與包容。不投稿不適當或冒犯性的內容,和我們一同保持 Juxt 的優質氛圍。", + "sixth": "切勿投稿您或他人之個人資料", + "eighth": "切勿投稿劇透內容", + "tenth": "違反《守則》懲處", + "eleventh": "我們的目標是讓 Juxt 的大家都能享受樂趣。如果有人違反《Juxt 社群守則》,我們會採取適當行動,封鎖違規使用者或整臺遊戲機。", + "twelfth": "玩過遊戲了嗎?", + "thirteenth": "如果您在有玩過的遊戲上投稿,其內文將會附有一個圖示表明您曾經玩過。", + "third": "Juxt 匯聚了全世界人們對諸多遊戲的觀點。請您謹記,在遊戲子板投稿時既要真誠表達自己,也要考慮到他人感受,因為所有人都能看見您的投稿。投稿前應三思而後行。Juxt 服務範圍也包括網際網路,即使是不使用 Juxt 的人也能看見您的投稿。此外,您在好友投稿上的回應不僅是好友能看見,而是所有人。敬請留意。", + "seventh": "請您謹記,從 Juxt 認識某人不代表也從現實生活認識了他。切勿在 Juxt 共享您或他人的個人資料,包括電子郵件地址、工作場域、學校名稱等等。如果您在 Juxt 上收到某個人的線下見面邀請,請不要接受。Juxt 只是一個線上社群平臺,不應用於安排線下聚會。", + "ninth": "有些人來到 Juxt 找尋遊戲的技巧和訣竅,但也有些人只想自己發掘遊戲裡的各種隱藏要素。將遊戲隱藏要素或劇情透露的投稿,稱作\"劇透。\" 如果要投稿劇透內容,請確保該文已被勾選為劇透投稿。如此一來,不想被劇透的人就不會看到您的投稿。" }, - "experience": "遊戲經驗", + "experience": "遊戲上手程度", "experience_text": { - "info": "請告訴我們您如何描述自己在遊戲方面的經驗水平。您可以稍後更改此設置。" + "info": "選擇您自認對遊戲的上手程度。您可以在之後更改此設定。", + "beginner": "初來乍到", + "intermediate": "休閒業餘", + "expert": "技藝高超" }, - "welcome_text": "Juxt 是一個遊戲社區,它通過 Mii 角色將來自世界各地的人聯繫在一起。使用 Juxt 分享你的遊戲經驗,並結識來自世界各地的人。" + "welcome_text": "Juxt 旨在讓世界各地的人們以 Mii 化身串聯遊戲社群。使用 Juxt,向全世界分享您獨到的遊戲經歷。", + "guest": "訪客模式", + "google": "Google Analytics(分析)", + "ready": "開始使用 Juxt", + "done": "祝您在 Juxt 玩得愉快!", + "done_button": "走吧!", + "guest_button": "我明白了", + "google_text": "Juxtaposition 使用 Google Analytics(分析)來追蹤使用者存取服務的情況。收集的資料包括但不限於拜訪時間、拜訪的頁面以及停留頁面的時間。這些資料不會以任何方式與您關連,也不會被我們或 Google 用於分析廣告投放。", + "ready_text": "先到社群子板,觀摩來自全世界的投稿作品吧。還能趁機熟悉 Juxt 的介面。您也可能就此發現新世界!", + "guest_text": "目前無法驗證您的帳號(可能是因為您使用了 Nintendo Network 帳號)。您可以繼續瀏覽 Juxt,但在登入 Pretendo Network 前,將無法進行「我贊同!」或投稿內容。詳情請前往 Discord 伺服器瞭解。" + }, + "community": { + "recent": "近期投稿", + "popular": "熱門投稿", + "verified": "名人投稿", + "new": "投稿", + "follow": "跟隨子板", + "following": "跟隨中", + "followers": "跟隨者", + "posts": "投稿", + "tags": "標籤" + }, + "user_page": { + "game_experience": "遊戲上手程度", + "posts": "投稿", + "friends": "好友", + "following": "跟隨中", + "followers": "跟隨者", + "follow_user": "跟隨", + "befriend": "成為好友", + "pending": "待回應", + "unfriend": "取消好友", + "no_friends": "查無好友", + "country": "居住地", + "birthday": "生日", + "following_user": "跟隨中", + "no_following": "查無跟隨了哪些人", + "no_followers": "查無跟隨者" + }, + "user_settings": { + "show_country": "在個人檔案顯示居住地", + "show_birthday": "在個人檔案顯示生日", + "show_game": "在個人檔案顯示遊戲上手程度", + "show_comment": "在個人檔案顯示自我介紹", + "profile_comment": "自我介紹", + "profile_settings": "個人檔案設定", + "swearing": "自我介紹不得包含露骨內容。" + }, + "notifications": { + "none": "查無通知。", + "new_follower": "成為了您的跟隨者!" + }, + "new_post": { + "swearing": "投稿不得包含露骨內容。", + "new_post_text": "新投稿", + "post_to": "投稿至", + "text_hint": "點選此處進行投稿。" } } From ce100305cec2bc22b583381b57e07a2fc771fee9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnau=20B=C3=A0rcia?= Date: Mon, 15 Apr 2024 14:04:30 +0000 Subject: [PATCH 077/189] locales(update): Updated Spanish locale --- apps/juxtaposition-ui/src/translations/es.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/es.json b/apps/juxtaposition-ui/src/translations/es.json index 2489fee6..e435c5f3 100644 --- a/apps/juxtaposition-ui/src/translations/es.json +++ b/apps/juxtaposition-ui/src/translations/es.json @@ -1,7 +1,7 @@ { "language": "Español", "global": { - "user_page": "Menú de usuario", + "user_page": "Página de usuario", "activity_feed": "Actividad", "communities": "Comunidades", "messages": "Mensajes", From 5804c332f5fd45e2e442cf1fa1bc8850179bc251 Mon Sep 17 00:00:00 2001 From: Deko Kiyo Date: Sun, 14 Apr 2024 14:09:21 +0000 Subject: [PATCH 078/189] locales(update): Updated Japanese locale --- .../juxtaposition-ui/src/translations/ja.json | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/ja.json b/apps/juxtaposition-ui/src/translations/ja.json index d5998a67..7781de71 100644 --- a/apps/juxtaposition-ui/src/translations/ja.json +++ b/apps/juxtaposition-ui/src/translations/ja.json @@ -5,14 +5,14 @@ "activity_feed": "みんなの活動", "communities": "コミュニティ", "messages": "メッセージ", - "notifications": "おしらせ", - "go_back": "もどる", - "back": "もどる", + "notifications": "お知らせ", + "go_back": "戻る", + "back": "戻る", "yeahs": "そうだね", - "more": "もっと読み込む", + "more": "さらに読み込む", "no_posts": "投稿がありません", "private": "非公開", - "close": "おわる", + "close": "閉じる", "save": "保存", "exit": "閉じる", "next": "次へ" @@ -20,9 +20,9 @@ "all_communities": { "text": "すべてのコミュニティ", "announcements": "おしらせ", - "ann_string": "最新のお知らせはこちら!", - "popular_places": "人気コミュニティ", - "new_communities": "新着コミュニティ", + "ann_string": "最新のお知らせはこちら!", + "popular_places": "人気のコミュニティ", + "new_communities": "新しいコミュニティ", "show_all": "すべて見る", "search": "コミュニティをさがす..." }, @@ -32,9 +32,9 @@ "followers": "フォロワー", "posts": "投稿", "tags": "タグ", - "recent": "新しい投稿", + "recent": "最近の投稿", "popular": "人気の投稿", - "verified": "プレイ済みの投稿", + "verified": "確認済みの投稿", "new": "投稿する" }, "user_page": { @@ -51,7 +51,7 @@ "pending": "承認待機中", "unfriend": "フレンドから外す", "no_friends": "フレンドがいません", - "no_following": "フォローがいません", + "no_following": "誰もフォローしていません", "no_followers": "フォロワーがいません" }, "user_settings": { @@ -61,7 +61,7 @@ "show_game": "プロフィールにゲームの腕前を表示", "show_comment": "プロフィールに自己紹介を表示", "profile_comment": "自己紹介", - "swearing": "自己紹介に悪口を含めることはできません。" + "swearing": "自己紹介に悪口を含めないでください。" }, "activity_feed": { "empty": "空っぽです。誰かをフォローしてみましょう!" @@ -74,13 +74,13 @@ "new_post_text": "投稿する", "post_to": "次に投稿する:", "text_hint": "ここをタップして投稿します。", - "swearing": "投稿に露骨な表現を含めることはできません。" + "swearing": "投稿に露骨な表現を含めないでください。" }, "messages": { - "coming_soon": "メッセージはまだ準備ができていません。すぐにもう一度チェックしてください!" + "coming_soon": "メッセージはまだ準備ができていません。すぐにもう一度確認してください!" }, "setup": { - "welcome": "Juxtapositionへようこそ!", + "welcome": "Juxtapositionへようこそ!", "welcome_text": "Juxtは、Miiキャラクターを使って世界中の人々をつなぐゲームコミュニティです。 Juxt を使用して、ゲーム体験を共有し、世界中の人々と出会いましょう。", "beta": "ベータ版免責事項", "beta_text": { @@ -88,7 +88,7 @@ "second": "これはベータ期間中や終了後、データベースの完全な消去に繋がることがあります。", "third": "このウェブサイト、そのソフトウェア及びその中のすべてのコンテンツは「そのまま」、「利用できる状態で」提供されます。Pretendo Networkは、ウェブサイト、ソフトウェア及びその中のコンテンツの適切性や有用性についていかなる明示的、黙示的保証もしません。" }, - "info": "Juxtってなんですか?", + "info": "Juxtとは?", "info_text": "Juxtは世界中の人々と交流できる、ユーザー主導のゲームコミュニティです。ゲームコミュニティで\n 文字や絵を用いて投稿をしたり、直接友達とメッセージ交換ができます。", "rules": "Juxtのルール", "rules_text": { From 7e2c56960ca732b2bb007f66624a7c8e9e54d552 Mon Sep 17 00:00:00 2001 From: Trevlin Morris Date: Mon, 15 Apr 2024 10:14:34 +0000 Subject: [PATCH 079/189] locales(update): Updated French (Canada) locale --- apps/juxtaposition-ui/src/translations/fr_CA.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/fr_CA.json b/apps/juxtaposition-ui/src/translations/fr_CA.json index 1a38fbde..e2df538d 100644 --- a/apps/juxtaposition-ui/src/translations/fr_CA.json +++ b/apps/juxtaposition-ui/src/translations/fr_CA.json @@ -85,7 +85,7 @@ "beta_text": { "first": "Tu es Tester la Premier public Bêta de Juxt. Ceci Signifier ça Beucoup est Encore au air, et ça Beucoup Pouvoir Changer à de Temps.", "second": "Ceci Pouvoir et il se Peut Que Comprendre un Effacer total à le Conclusion ou Pendant le Période Bêta.", - "third": "Le site, et ça est Logiciel et Tout Content Trouvé dans il es Fourni il un \"tel quel\" et \"tel disponible\" base. Le Pretendo Network Pouvoir pas Donner du Clause, si Formel ou Impliquer, Aussi à le Convenir ou Convivialité de le site, et C'est Logiciel ou si de Contenu." + "third": "Le site, son Logiciel et Tout Content Trouvé dans il es Fourni il un \"tel quel\" et \"tel disponible\" base. Le Pretendo Network Pouvoir pas Donner du Garantie, si Formel ou Impliquer, Aussi à le Convenir ou Convivialité de le site, et son Logiciel ou si de son Contenu." }, "info": "Qu'est que Juxtaposition?", "info_text": "Juxt est un Utilisateur-Motivé Communauté où tu Pouvoir Interagir avec Gens\nPartout le Montrer. Tu Pouvoir écrire et Dessiner Poster dans Communauté de Jeux ou Envoyer Messages Directement à ton amis.", From a6562cc8cbda9780d8d696f6e76817570de2797a Mon Sep 17 00:00:00 2001 From: Alex Game 2112 Date: Tue, 16 Apr 2024 15:53:55 +0000 Subject: [PATCH 080/189] locales(update): Updated Italian locale --- apps/juxtaposition-ui/src/translations/it.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/it.json b/apps/juxtaposition-ui/src/translations/it.json index 69bfc2ef..e8dc1853 100644 --- a/apps/juxtaposition-ui/src/translations/it.json +++ b/apps/juxtaposition-ui/src/translations/it.json @@ -28,8 +28,8 @@ }, "community": { "follow": "Segui community", - "following": "Stanno seguendo", - "followers": "Follower", + "following": "Seguiti", + "followers": "Seguaci", "posts": "Post", "tags": "Etichette", "recent": "Post recenti", From b520492a8a9e1f1850acf080726d5b3e0bf6a3f7 Mon Sep 17 00:00:00 2001 From: Trevlin Morris Date: Mon, 15 Apr 2024 17:44:14 +0000 Subject: [PATCH 081/189] locales(update): Updated French (Canada) locale --- apps/juxtaposition-ui/src/translations/fr_CA.json | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/fr_CA.json b/apps/juxtaposition-ui/src/translations/fr_CA.json index e2df538d..94d409ad 100644 --- a/apps/juxtaposition-ui/src/translations/fr_CA.json +++ b/apps/juxtaposition-ui/src/translations/fr_CA.json @@ -89,7 +89,19 @@ }, "info": "Qu'est que Juxtaposition?", "info_text": "Juxt est un Utilisateur-Motivé Communauté où tu Pouvoir Interagir avec Gens\nPartout le Montrer. Tu Pouvoir écrire et Dessiner Poster dans Communauté de Jeux ou Envoyer Messages Directement à ton amis.", - "rules": "Règle de Juxt" + "rules": "Règle de Juxt", + "rules_text": { + "first": "Le suivant sommes quelques lignes directrices d'important pour fabrication de Juxt une expérience de sympa et plaisant pour tout le monde. Le Code de Conduite contenir informations détaillé, donc lire lui minutieusement merci.", + "second": "Posters Peut être Regardé à Travers le Monde", + "fourth": "Sois Gentil à Un Autre", + "fifth": "Afin de garder Juxt un endroit gentil pour tout le monde, nous demander que tu être prévenant à autre utilisateurs. Aider nous garder Juxt un expérience plaisant par poster pas n'importe quoi inapproprié ou offensant.", + "sixth": "Poster pas informations personnel—Votres ou Autres", + "eighth": "Ne Poster pas spoilers", + "tenth": "Violation du Code de Conduite", + "third": "Juxt contenir beaucoup communautés de jeux où gens de à travers le monde pouvoir partager leur idées. Quand tu poster dans le communauté, se souvenir de tout le monde pouvoir vois-le, exprimer donc vous dans les manière que tout le monde pouvoir apprécier. Utiliser bon sens, et penser avant de poster. Juxt est une service que est accessible dans l'internet, donc ne pas perdre de vue gens qui utiliser pas Juxt il se peut que voir ton posters. De plus, tous commentaire tu créer dans ton amis posters aller être voir seulement pas ton amis mais par gens de à travers le monde, aussi. s'il vous plaît ne pas oublier.", + "seventh": "N'oubliez pas, connaître quelqu'un dans Juxt n'est pas la même chose aussi connaître dans le vraie vie. Jamais partager ton adresse e-mail, adresse de maison, nom de travail ou ecole, ou autre informations de identifier personnellement avec n'importe qui sur Juxt, et Jamais partager l'autre n'importe quis informations, de plus, si quelqu'un tu rencontrer dans Juxt inviter tu rencontrer lui ou elle dans le vraie vie, ne accepter pas. Juxt est un communauté en ligne et devoir pas utiliser à vraie vie se retrouver.", + "ninth": "Quelques gens venir à Juxt recherche pour \"tips et tricks\" pour jeux, mais autres vouloir faire découvrir secrets de jeux sur leur propre.Posters que révéler secrets de jeux ou intrigue es qui s'appelle \"spoilers.\" si tu es poster quelque chose sur un jeux que il se pourrait que être un spoiler, être sûr à cocher le boîte de spoiler avant de poster tu. Ce façon, gens qui ne vouloir pas à spoiled ne voir pas ton poster." + } }, "language": "Français (CA)" } From 603bc9f868853c748ef635c16f75516e1fc70c83 Mon Sep 17 00:00:00 2001 From: Trevlin Morris Date: Tue, 16 Apr 2024 18:05:22 +0000 Subject: [PATCH 082/189] locales(update): Updated French (Canada) locale --- apps/juxtaposition-ui/src/translations/fr_CA.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/fr_CA.json b/apps/juxtaposition-ui/src/translations/fr_CA.json index 94d409ad..9049d993 100644 --- a/apps/juxtaposition-ui/src/translations/fr_CA.json +++ b/apps/juxtaposition-ui/src/translations/fr_CA.json @@ -100,7 +100,9 @@ "tenth": "Violation du Code de Conduite", "third": "Juxt contenir beaucoup communautés de jeux où gens de à travers le monde pouvoir partager leur idées. Quand tu poster dans le communauté, se souvenir de tout le monde pouvoir vois-le, exprimer donc vous dans les manière que tout le monde pouvoir apprécier. Utiliser bon sens, et penser avant de poster. Juxt est une service que est accessible dans l'internet, donc ne pas perdre de vue gens qui utiliser pas Juxt il se peut que voir ton posters. De plus, tous commentaire tu créer dans ton amis posters aller être voir seulement pas ton amis mais par gens de à travers le monde, aussi. s'il vous plaît ne pas oublier.", "seventh": "N'oubliez pas, connaître quelqu'un dans Juxt n'est pas la même chose aussi connaître dans le vraie vie. Jamais partager ton adresse e-mail, adresse de maison, nom de travail ou ecole, ou autre informations de identifier personnellement avec n'importe qui sur Juxt, et Jamais partager l'autre n'importe quis informations, de plus, si quelqu'un tu rencontrer dans Juxt inviter tu rencontrer lui ou elle dans le vraie vie, ne accepter pas. Juxt est un communauté en ligne et devoir pas utiliser à vraie vie se retrouver.", - "ninth": "Quelques gens venir à Juxt recherche pour \"tips et tricks\" pour jeux, mais autres vouloir faire découvrir secrets de jeux sur leur propre.Posters que révéler secrets de jeux ou intrigue es qui s'appelle \"spoilers.\" si tu es poster quelque chose sur un jeux que il se pourrait que être un spoiler, être sûr à cocher le boîte de spoiler avant de poster tu. Ce façon, gens qui ne vouloir pas à spoiled ne voir pas ton poster." + "ninth": "Quelques gens venir à Juxt recherche pour \"tips et tricks\" pour jeux, mais autres vouloir faire découvrir secrets de jeux sur leur propre.Posters que révéler secrets de jeux ou intrigue es qui s'appelle \"spoilers.\" si tu es poster quelque chose sur un jeux que il se pourrait que être un spoiler, être sûr à cocher le boîte de spoiler avant de poster tu. Ce façon, gens qui ne vouloir pas à spoiled ne voir pas ton poster.", + "eleventh": "Nos objectif est à garder sympa et plaisant dans Juxt. Dans l'événement ça quelqu'un Violer du Juxt Code de Conduite, nous aller agir approprié, allant jusqu'à et inclure bouchage le choquant utilisateur ou console.", + "twelfth": "Avez-vous que tu Jeux ces Jeux?" } }, "language": "Français (CA)" From af46801793b9ed0c738ce3ac48cb7ba415dca666 Mon Sep 17 00:00:00 2001 From: Meeto YT77 Date: Wed, 17 Apr 2024 21:22:16 +0000 Subject: [PATCH 083/189] locales(update): Updated Kazakh locale --- apps/juxtaposition-ui/src/translations/kk.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/kk.json b/apps/juxtaposition-ui/src/translations/kk.json index 0967ef42..f827473a 100644 --- a/apps/juxtaposition-ui/src/translations/kk.json +++ b/apps/juxtaposition-ui/src/translations/kk.json @@ -1 +1,3 @@ -{} +{ + "language": "қазақша" +} From 954361393eff1c4ff1debc2f3261b2883996a862 Mon Sep 17 00:00:00 2001 From: Meeto YT77 Date: Wed, 17 Apr 2024 22:05:23 +0000 Subject: [PATCH 084/189] locales(update): Updated French (Canada) locale --- .../src/translations/fr_CA.json | 29 +++++++++++++++---- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/fr_CA.json b/apps/juxtaposition-ui/src/translations/fr_CA.json index 9049d993..d4fc6b98 100644 --- a/apps/juxtaposition-ui/src/translations/fr_CA.json +++ b/apps/juxtaposition-ui/src/translations/fr_CA.json @@ -2,7 +2,7 @@ "global": { "user_page": "Page de Utilisateur", "activity_feed": "Flux d'activité", - "communities": "Communauté", + "communities": "Communautés", "messages": "Messages", "notifications": "Notifications", "go_back": "Retourner", @@ -12,18 +12,18 @@ "no_posts": "Sans Posts", "private": "Privé", "close": "Fermer", - "save": "Enregistrer", + "save": "Sauvegarder", "exit": "Sortir", "next": "Prochain" }, "all_communities": { - "announcements": "Annonce", + "announcements": "Annonces", "popular_places": "Endroit Populaire", "new_communities": "Nouveau Communautés", "show_all": "Tout Montrer", "search": "Chercher Communautés...", "text": "Tout Communautés", - "ann_string": "Cliquer Ici à Vue Annonce Récent!" + "ann_string": "Cliquer Ici à Vue Annonces Récent!" }, "community": { "follow": "Suivre Communauté", @@ -102,8 +102,25 @@ "seventh": "N'oubliez pas, connaître quelqu'un dans Juxt n'est pas la même chose aussi connaître dans le vraie vie. Jamais partager ton adresse e-mail, adresse de maison, nom de travail ou ecole, ou autre informations de identifier personnellement avec n'importe qui sur Juxt, et Jamais partager l'autre n'importe quis informations, de plus, si quelqu'un tu rencontrer dans Juxt inviter tu rencontrer lui ou elle dans le vraie vie, ne accepter pas. Juxt est un communauté en ligne et devoir pas utiliser à vraie vie se retrouver.", "ninth": "Quelques gens venir à Juxt recherche pour \"tips et tricks\" pour jeux, mais autres vouloir faire découvrir secrets de jeux sur leur propre.Posters que révéler secrets de jeux ou intrigue es qui s'appelle \"spoilers.\" si tu es poster quelque chose sur un jeux que il se pourrait que être un spoiler, être sûr à cocher le boîte de spoiler avant de poster tu. Ce façon, gens qui ne vouloir pas à spoiled ne voir pas ton poster.", "eleventh": "Nos objectif est à garder sympa et plaisant dans Juxt. Dans l'événement ça quelqu'un Violer du Juxt Code de Conduite, nous aller agir approprié, allant jusqu'à et inclure bouchage le choquant utilisateur ou console.", - "twelfth": "Avez-vous que tu Jeux ces Jeux?" - } + "twelfth": "Avez-vous que tu Jeux ces Jeux?", + "thirteenth": "Si vous publier dans la communauté pour un jeu auquel tu as joué, tes publications aura une icône indiquant que vous l'avez joué." + }, + "experience": "Expérience de jeu", + "experience_text": { + "info": "S'il vous plait dites-nous comment décririez-vous votre niveau d'expérience avec les jeux. Tu peux changer ce paramètre plus tard.", + "beginner": "Débutant/Débutante", + "intermediate": "Intermédiaire", + "expert": "Expert/Experte" + }, + "google": "Google Analytics", + "ready": "Prêt à commencer à utiliser Juxt", + "ready_text": "Consultez d’abord certaines communautés et voyez ce que les gens du tout le monde entier publient. Profitez de cette occasion pour vous familiariser avec Juxt. Vous ferez peut-être de nouvelles découvertes en cours de route !", + "done": "Amusez-vous dans Juxt !", + "done_button": "Allons-y!", + "guest": "Mode Invité", + "guest_button": "Je Comprends", + "guest_text": "Nous ne pouvons pas vérifier votre compte pour le moment, ce qui signifie probablement que vous êtes connecté avec un compte Nintendo Network. Vous pourrez toujours parcourir Juxt, mais vous ne pourrez pas accéder à Yeah! des publiez ou créez vos propres publications jusqu'à ce que vous vous connectiez avec un compte Pretendo Network. Pour plus d'informations, consultez le serveur Discord.", + "google_text": "Juxtaposition utilise Google Analytics pour suivre comment les utilisateurs utilisent notre service.Les données collectées incluent, sans toutefois s'y limiter, le temps de visite, les pages visitées et le temps passé sur le site ne vous sont en aucun cas associées et ne sont pas utilisées à des fins publicitaires par nous ou par Google.\nCommunity Verified icon" }, "language": "Français (CA)" } From f832906f4f7a34260e9a96a13361d50dc1cba129 Mon Sep 17 00:00:00 2001 From: Huang Date: Sat, 20 Apr 2024 08:04:54 +0000 Subject: [PATCH 085/189] locales(update): Updated Chinese (Simplified) locale --- apps/juxtaposition-ui/src/translations/zh.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/zh.json b/apps/juxtaposition-ui/src/translations/zh.json index 26ea00a5..9454c22a 100644 --- a/apps/juxtaposition-ui/src/translations/zh.json +++ b/apps/juxtaposition-ui/src/translations/zh.json @@ -74,7 +74,7 @@ "new_post_text": "新建帖子", "post_to": "发布到", "text_hint": "点击此处发布帖子。", - "swearing": "帖子不能包含明确的语言。" + "swearing": "请勿在帖子中包含露骨语言。" }, "messages": { "coming_soon": "消息尚未准备好。稍后检查!" From ce53f84706b33705a799bcbad05e1e0b84f862dc Mon Sep 17 00:00:00 2001 From: Evan Lie Date: Sat, 20 Apr 2024 02:34:56 +0000 Subject: [PATCH 086/189] locales(update): Updated Indonesian locale --- .../juxtaposition-ui/src/translations/id.json | 80 ++++++++++++++++++- 1 file changed, 78 insertions(+), 2 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/id.json b/apps/juxtaposition-ui/src/translations/id.json index 660bda7d..d8523179 100644 --- a/apps/juxtaposition-ui/src/translations/id.json +++ b/apps/juxtaposition-ui/src/translations/id.json @@ -9,7 +9,83 @@ "back": "Kembali", "yeahs": "Ya", "more": "Memuat Postingan", - "no_posts": "Tidak ada Postingan" + "no_posts": "Tidak ada Postingan", + "private": "Pribadi", + "close": "Tutup", + "save": "Simpan", + "exit": "Keluar", + "next": "Berikut" }, - "language": "Bahasa Indonesia" + "language": "Bahasa Indonesia", + "all_communities": { + "show_all": "Tunjuk Semua", + "text": "Semua Komunitas", + "announcements": "Pengumuman", + "ann_string": "Klik sini untuk melihat pengumuman terkini!", + "popular_places": "Tempat Populer", + "new_communities": "Komunitas Baru", + "search": "Cari Komunitas..." + }, + "user_settings": { + "show_game": "Tunjuk Pengalaman Permainan di Profil", + "show_comment": "Tunjuk Komentar di Profil", + "profile_comment": "Komentar Profil", + "profile_settings": "Pengaturan Profil", + "show_country": "Tunjuk Negara di Profil", + "show_birthday": "Tunjuk Ulang Tahun di Profil", + "swearing": "Komentar Profil tidak boleh mengandung bahasa eksplisit." + }, + "setup": { + "welcome_text": "Juxt adalah komunitas game yang menghubungan orang-orang dari seluruh dunia menggunakan karakter Mii. Gunakan Juxt untuk berbagi pengalaman bermain game anda dan bertemu orang-orang dari seluruh dunia.", + "beta_text": { + "first": "Anda akan mencoba versi beta publik pertama Juxt. Artinya, masih banyak hal yang belum terealisasi, dan banyak hal yang bisa berubah kapan saja.", + "second": "Hal ini dapat dan mungkin mencakup penghapusan total basis data para akhir atau selama periode beta." + }, + "welcome": "Selamat datang ke Juxtaposition (Juxt)!", + "beta": "Pembertitahuan Beta" + }, + "community": { + "follow": "Ikut Komunitas", + "following": "Mengikuti", + "followers": "Pengikutas", + "posts": "Postingan", + "tags": "Tags", + "recent": "Postingan Terkini", + "popular": "Postingan Populer", + "verified": "Postingan Diverifikasi", + "new": "Postingan Baru" + }, + "user_page": { + "country": "Negara", + "birthday": "Ulang Tahun", + "game_experience": "Pengalaman Permainan", + "posts": "Postingan", + "friends": "Teman", + "following": "Mengikuti", + "followers": "Pengikutas", + "follow_user": "Mengikut", + "following_user": "Mengikuti", + "befriend": "Nambah Teman", + "pending": "Tertunda", + "unfriend": "Hapus Teman", + "no_friends": "Tidak ada Teman", + "no_following": "Tidak Mengikuti Orang", + "no_followers": "Tidak ada Pengikutas" + }, + "activity_feed": { + "empty": "Tidak ada apa-apa di sini. Coba mengikut orang!" + }, + "notifications": { + "none": "Tidak ada notificasi.", + "new_follower": "diikuti kamu!" + }, + "new_post": { + "new_post_text": "Postingan Baru", + "post_to": "Posting ke", + "text_hint": "Klik sini untuk membuat postingan.", + "swearing": "Postingan tidak boleh mengandung bahasa eksplisit." + }, + "messages": { + "coming_soon": "Pessan belum siap sekarang. Segara periksa kembali!" + } } From 3bdb5c80bf667e4062523aa509fed86fd1034859 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnau=20B=C3=A0rcia?= Date: Tue, 23 Apr 2024 09:49:58 +0000 Subject: [PATCH 087/189] locales(update): Updated Spanish locale --- apps/juxtaposition-ui/src/translations/es.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/es.json b/apps/juxtaposition-ui/src/translations/es.json index e435c5f3..4f1b0ce1 100644 --- a/apps/juxtaposition-ui/src/translations/es.json +++ b/apps/juxtaposition-ui/src/translations/es.json @@ -32,9 +32,9 @@ "followers": "Seguidores", "posts": "Publicaciones", "tags": "Etiquetas", - "recent": "Publicaciones recientes", - "popular": "Publicaciones populares", - "verified": "Publicaciones verificadas", + "recent": "Mensajes recientes", + "popular": "Mensajes populares", + "verified": "Mensajes verificados", "new": "Nueva publicación" }, "user_page": { @@ -58,7 +58,7 @@ "profile_settings": "Preferencias del perfil", "show_country": "Mostrar país en tu perfil", "show_birthday": "Mostrar cumpleaños en tu perfil", - "show_game": "Mostrar experiencia de juego en tu perfil", + "show_game": "Mostrar el nivel como jugador en tu perfil", "show_comment": "Mostrar comentario en tu perfil", "profile_comment": "Comentario del perfil", "swearing": "Los comentarios no pueden tener lenguaje inapropiado." @@ -106,9 +106,9 @@ "twelfth": "¿Has jugado a este juego?", "thirteenth": "Si publicas en una comunidad sobre algún juego que has jugado, tus publicaciones tendrán un icono que indica que has jugado a ese juego." }, - "experience": "Experiencia de juego", + "experience": "Nivel como jugador", "experience_text": { - "info": "Por favor, indica cuánta experiencia tienes jugando. Puedes cambiarlo después en Ajustes.", + "info": "Por favor, indica tu nivel como jugador. Puedes cambiarlo después en Ajustes.", "beginner": "Principiante", "intermediate": "Intermedio", "expert": "Experto" From 29dac0454cf4b830f06339e8335eb53232317984 Mon Sep 17 00:00:00 2001 From: Viktor Varga Date: Sun, 28 Apr 2024 23:26:34 +0200 Subject: [PATCH 088/189] locales(add): Added Hungarian locale --- apps/juxtaposition-ui/src/translations/hu.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/juxtaposition-ui/src/translations/hu.json diff --git a/apps/juxtaposition-ui/src/translations/hu.json b/apps/juxtaposition-ui/src/translations/hu.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/apps/juxtaposition-ui/src/translations/hu.json @@ -0,0 +1 @@ +{} From 4761f870c8f9949b2d705b36b01f23e3a7b83e73 Mon Sep 17 00:00:00 2001 From: Viktor Varga Date: Sun, 28 Apr 2024 21:34:31 +0000 Subject: [PATCH 089/189] locales(update): Updated Hungarian locale --- .../juxtaposition-ui/src/translations/hu.json | 127 +++++++++++++++++- 1 file changed, 126 insertions(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/hu.json b/apps/juxtaposition-ui/src/translations/hu.json index 0967ef42..7f7305a8 100644 --- a/apps/juxtaposition-ui/src/translations/hu.json +++ b/apps/juxtaposition-ui/src/translations/hu.json @@ -1 +1,126 @@ -{} +{ + "global": { + "user_page": "Profil", + "activity_feed": "Tevékenység hírcsatorna", + "communities": "Közösségek", + "go_back": "Vissza", + "back": "Vissza", + "yeahs": "Yeahs", + "no_posts": "Nincs bejegyzés", + "private": "Privát", + "close": "Bezár", + "exit": "Kilépés", + "next": "Tovább", + "messages": "Üzenetek", + "more": "Több bejegyzés betöltése", + "save": "Mentés", + "notifications": "Értesítések" + }, + "all_communities": { + "ann_string": "Kattints ide a legfrissebb bejelentések megtekintéséhez!", + "popular_places": "Népszerű helyek", + "show_all": "Mindet mutatja", + "text": "Minden közösség", + "new_communities": "Új közösségek", + "announcements": "Bejelentések", + "search": "Közösségek keresése..." + }, + "community": { + "follow": "Közösség követése", + "following": "Követed", + "posts": "Bejegyzés", + "tags": "Címke", + "recent": "Legutolsó bejegyzések", + "followers": "Követő", + "popular": "Népszerű bejegyzések", + "verified": "Ellenőrzött bejegyzések", + "new": "Új bejegyzés" + }, + "user_page": { + "country": "Ország", + "game_experience": "Játék tapasztalat", + "posts": "Bejegyzések", + "friends": "Barátok", + "followers": "Követő", + "follow_user": "Követ", + "following_user": "Követve", + "befriend": "Barátnak jelöl", + "pending": "Folyamatban", + "unfriend": "Barátok közül töröl", + "no_friends": "Nincsennek barátok", + "no_following": "Nem követ senkit", + "no_followers": "Nincsennek követők", + "birthday": "Születésnap", + "following": "Követed" + }, + "user_settings": { + "show_country": "Ország megjelenítése a Profilon", + "show_birthday": "Születésnap megjelenítése a Profilon", + "profile_comment": "Profil megjegyzés", + "profile_settings": "Profil beállítások", + "show_game": "Játéktapasztalat megjelenítése a Profilon", + "show_comment": "Megjegyzés megjelenítése a Profilon", + "swearing": "A profil megjegyzés nem tartalmazhat csúnya beszédet." + }, + "notifications": { + "none": "Nincsennek értesítések.", + "new_follower": "követ téged!" + }, + "new_post": { + "new_post_text": "Új bejegyzés", + "post_to": "Bejegyzés ehhez:", + "swearing": "A bejegyzés nem tartalmazhat csúnya beszédet.", + "text_hint": "Koppints ide egy új bejegyzés létrehozásához." + }, + "messages": { + "coming_soon": "Az Üzenetek még nincs kész. Nézz vissza később!" + }, + "setup": { + "welcome": "Köszöntünk Juxtaposition-ben!", + "beta": "Béta Jogi nyilatkozat", + "beta_text": { + "first": "A Juxt első publikus bétáját fogod kipróbálni. Ez azt jelenti, hogy egy csomó minden lóg a levegőben, és változhat idővel.", + "third": "A weboldal, a szoftver és mindent tartalom “as is” és “as available” alapon biztosított. A Pretendo Network nem biztosít semmilyen garanciát, akár közvetlen, akár beleértett, a megfelelőségéről és használhatóságáról a weboldalnak a szoftvernek, vagy bármilyen tartalomnak.", + "second": "Ez jelentheti az adatbázis teljes törlését valamilyen döntést követően vagy a béta periódus végén." + }, + "info": "Mi az a Juxtaposition?", + "info_text": "A Juxt egy felhasználó alapú játék közösség, ahol kapcsolatba léphetsz emberekkel\n a világ minden tájáról. Írhatsz és rajzolhatsz bejegyzéseket a játék közösségekbe, vagy küldhetsz közvetlen üzenetet barátaidnak.", + "rules": "Juxt szabályok", + "rules_text": { + "second": "A bejegyzéseket az egész világon megtekinthetik", + "fourth": "Legyetek kedvesek egymáshoz", + "fifth": "Annak érdekében, hogy a Juxt mindenki számára szórakoztató hely maradjon, kérjük, légy figyelmes más felhasználókkal szemben. Segíts nekünk abban, hogy a Juxt élvezetes élmény legyen azáltal, hogy nem teszel közzé semmi nem helyénvalót vagy sértőt.", + "sixth": "Ne posztolj személyes információt - se sajátodat, se másokét", + "tenth": "Magatartási kódex megsértése", + "eighth": "Ne posztolj spoilereket", + "eleventh": "Célunk, hogy a Juxt szórakoztató és élvezetes legyen mindenki számára. Abban az esetben, ha valaki megsérti a Juxt magatartási kódexét, megtesszük a megfelelő lépéseket, beleértve a jogsértő felhasználó vagy konzol letiltását is.", + "twelfth": "Játszottál már azzal a játékkal?", + "thirteenth": "Ha a közösségbe posztolod egy játékról, hogy játszottad, a posztjaid tartalmazni fognak egy ikont, hogy játszottál vele.", + "seventh": "Ne feledd, hogy valakit a Juxt-ban ismerni nem ugyanaz, mint a való életben. Soha ne oszd meg e-mail címed, otthoni címed, munkahelyed vagy iskolád nevét vagy más személyazonosításra alkalmas adatod senkivel a Juxt-on, és soha ne oszd meg más adatait sem. Továbbá, ha valaki, akivel a Juxt-ban találkozol, meghív, hogy találkozz vele a való világban, ne fogadd el. A Juxt egy online közösség, és nem javasolt valós találkozók szervezésére használni.", + "ninth": "Vannak, akik azért jönnek a Juxt-hoz, hogy tippeket és trükköket keressenek a játékokhoz, de mások egyedül szeretnék felfedezni egy játék titkait. Azokat a bejegyzéseket, amelyek egy játék vagy annak történetének titkait fedik fel, „spoilereknek” nevezzük. Ha egy játékról teszel közzé valamit, ami spoiler lehet, a bejegyzés elküldése előtt feltétlenül jelöld be a \"spoilers\" négyzetet. Így azok, akik nem akarnak spoilert látni, nem fogják látni a bejegyzésedet.", + "first": "Az alábbiakban felsorolunk néhány fontos irányelvet, amelyekkel a Juxt mindenki számára szórakoztató és élvezetes élmény lehet. A Juxt magatartási kódexe részletes információkat tartalmaz, ezért kérjük, figyelmesen olvassa el azt.", + "third": "A Juxt számos játékközösséget tartalmaz, ahol az emberek a világ minden tájáról megoszthatják gondolataikat. Amikor közzé teszel valamit egy közösségben, ne feledd, hogy mindenki láthatja, ezért kérjük, fejezd ki magad úgy, hogy az mindenki számára élvezetes legyen. Használd a józan eszedet, és gondolkozz, mielőtt posztolsz. A Juxt egy olyan szolgáltatás, amely az internetről is elérhető, ezért ne feledd, hogy azok is láthatják a bejegyzéseid, akik nem használják a Juxt-ot. Ezenkívül az ismerőseid bejegyzéseihez írt megjegyzéseid nemcsak az ismerőseid, hanem a világ minden tájáról. Kérjük, tartsd ezt szem előtt." + }, + "experience": "Játék tapasztalat", + "experience_text": { + "info": "Kérjük írd le magadról hogy milyen szinten van tapasztalatod a játékokkal. Módosíthatod ezt később.", + "beginner": "Kezdő", + "intermediate": "Középszint", + "expert": "Profi" + }, + "google": "Google Analytics", + "ready": "Készen állsz használni a Juxt-ot", + "ready_text": "Először nézz meg néhány közösséget, és nézd meg, miről posztolnak az emberek a világ minden tájáról. Használd ki az alkalmat, hogy megismerkedj a Juxttal. Útközben új felfedezéseket tehetsz!", + "done": "Jó szórakozást a Juxt-ban!", + "done_button": "Kezdjük!", + "guest": "Vendég mód", + "guest_text": "Jelenleg nem tudjuk ellenőrizni fiókod, ami valószínűleg azt jelenti, hogy egy Nintendo Network fiókkal vagy bejelentkezve. Továbbra is böngészhetsz a Juxtban, de nem fogsz tudni a Yeah! bejegyzéseket vagy saját bejegyzéseket készíteni, amíg be nem jelentkezel egy Pretendo Network fiókkal. További információkért nézd meg a Discord szervert.", + "guest_button": "Megértettem", + "welcome_text": "A Juxt egy játék közösség, ami összeköti az embereket a világ minden tájáról Mii karakterek használatával. Használd a Juxt-ot, hogy megoszd játék tapasztalataid és találkozz emberekkel a világ minden tájáról.", + "google_text": "A Juxtaposition a Google Analytics szolgáltatást használja annak nyomon követésére, hogy a felhasználók hogyan használják szolgáltatásunkat. Az összegyűjtött adatok magukban foglalják, de nem kizárólagosan a látogatás idejét, a meglátogatott oldalakat és az oldalon töltött időt. Ezeket az adatokat semmilyen módon nem kapcsoljuk Önhöz, és sem mi, sem a Google nem használja fel hirdetésekhez." + }, + "activity_feed": { + "empty": "Nagyon üres itt. Próbálj meg valakit követni!" + }, + "language": "Magyar" +} From b143571aca8527858a01d48908d5c685fa28fea2 Mon Sep 17 00:00:00 2001 From: Claudia De Caprio Date: Wed, 1 May 2024 10:26:01 +0000 Subject: [PATCH 090/189] locales(update): Updated Italian locale --- apps/juxtaposition-ui/src/translations/it.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/it.json b/apps/juxtaposition-ui/src/translations/it.json index e8dc1853..93d9d84e 100644 --- a/apps/juxtaposition-ui/src/translations/it.json +++ b/apps/juxtaposition-ui/src/translations/it.json @@ -29,7 +29,7 @@ "community": { "follow": "Segui community", "following": "Seguiti", - "followers": "Seguaci", + "followers": "seguiti", "posts": "Post", "tags": "Etichette", "recent": "Post recenti", @@ -43,7 +43,7 @@ "game_experience": "Esperienza di gioco", "posts": "Post", "friends": "Amici", - "following": "Sta seguendo", + "following": "Seguiti", "followers": "Follower", "follow_user": "Segui", "following_user": "Stai seguendo", From 3b40162f369b0081028e462bb4ea0c95df7faf47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnau=20B=C3=A0rcia?= Date: Fri, 3 May 2024 20:49:09 +0000 Subject: [PATCH 091/189] locales(update): Updated Spanish locale --- apps/juxtaposition-ui/src/translations/es.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/es.json b/apps/juxtaposition-ui/src/translations/es.json index 4f1b0ce1..d93b125a 100644 --- a/apps/juxtaposition-ui/src/translations/es.json +++ b/apps/juxtaposition-ui/src/translations/es.json @@ -22,7 +22,7 @@ "announcements": "Anuncios", "ann_string": "¡Toca para ver los anuncios recientes!", "popular_places": "Lugares populares", - "new_communities": "Nuevas comunidades", + "new_communities": "Comunidades nuevas", "show_all": "Mostrar todo", "search": "Buscar comunidades..." }, @@ -32,9 +32,9 @@ "followers": "Seguidores", "posts": "Publicaciones", "tags": "Etiquetas", - "recent": "Mensajes recientes", - "popular": "Mensajes populares", - "verified": "Mensajes verificados", + "recent": "Publicaciones recientes", + "popular": "Publicaciones populares", + "verified": "Publicaciones verificados", "new": "Nueva publicación" }, "user_page": { From fe3eaae25c1b89cbc279c138b6072468f3789b5c Mon Sep 17 00:00:00 2001 From: Kaoru Isamu Date: Sat, 4 May 2024 13:26:10 +0000 Subject: [PATCH 092/189] locales(update): Updated Dutch locale --- apps/juxtaposition-ui/src/translations/nl.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/nl.json b/apps/juxtaposition-ui/src/translations/nl.json index cfb0fbe3..54598ed6 100644 --- a/apps/juxtaposition-ui/src/translations/nl.json +++ b/apps/juxtaposition-ui/src/translations/nl.json @@ -100,7 +100,7 @@ "sixth": "Post Geen Persoonlijke Gegevens—Die van Jezelf of Van Anderen", "seventh": "Onthoud, iemand in Juxt kennen is niet hetzelfde als iemand in het echt kennen. Deel nooit je e-mail adres, huisadres, de naam van je school of werk of wat voor een persoonlijke identificeerbare informatie dan ook met een ander en deel ook geen van deze gegevens van iemand anders. Daarnaast, als iemand die je ontmoet hebt op Juxt je vraagt om diegene in het echt te ontmoeten, accepteer dit niet. Juxt is een online community en moet niet gebruikt worden om ontmoetingen in het echt te faciliteren.", "eighth": "Post Geen Spoilers", - "ninth": "Engels\nSommige mensen komen naar Juxt voor tips en trucs voor games, anderen willen zelf de geheimen van een game ontdekken. Berichten die geheimen van een game of het verhaal ervan onthullen, worden 'spoilers' genoemd. Als je iets post over een game dat een spoiler zou kunnen zijn, zorg er dan voor dat je het vakje Spoilers aanvinkt voordat je je post verstuurt. Zo zien mensen die niet verwend willen worden je bericht niet.", + "ninth": "Sommige mensen komen naar Juxt voor tips en trucs voor games, anderen willen zelf de geheimen van een game ontdekken. Berichten die geheimen van een game of het verhaal ervan onthullen, worden 'spoilers' genoemd. Als je iets post over een game dat een spoiler zou kunnen zijn, zorg er dan voor dat je het vakje Spoilers aanvinkt voordat je je post verstuurt. Zo zien mensen die geen spoilers willen zien je bericht niet.", "tenth": "Gedragscode overtredingen", "eleventh": "Ons doel is om Juxt leuk en gezellig voor iedereen te houden. Mocht iemand de Juxt Gedragscode overtreden, dan zullen wij gepaste maatregelen nemen. Deze maatregelen omvatten onder andere het blokkeren van toegang voor het account of de console van de gebruiker die de gedragscode overtreedt.", "twelfth": "Heb Je Dat Spel Gespeeld?", @@ -120,7 +120,7 @@ "done": "Veel plezier in Juxt!", "done_button": "Laten We Beginnen!", "guest": "Gast Modus", - "guest_text": "We kunnen momenteel jouw account niet verifiëren, dit betekent waarschijnlijk dat je probeert in te loggen met een Nintendo Network account. Je kan nog steeds Juxt bezoeken, maar je kan geen Yeah!s geven op posts, daarnaast kan je geen posts maken totdat je inlogt met een Pretendo Network account. Bezoek de Discord server voor meer informatie.", + "guest_text": "We kunnen momenteel jouw account niet verifiëren, dit betekent waarschijnlijk dat je probeert in te loggen met een Nintendo Network account. Je kan nog steeds Juxt bezoeken, maar je kan posts geen Ja! geven. Daarnaast kan je geen posts maken totdat je inlogt met een Pretendo Network account. Bezoek de Discord server voor meer informatie.", "guest_button": "Begrepen" } } From 89c55c9a395f657e1bf755fc0894d668b4e9f79b Mon Sep 17 00:00:00 2001 From: Milo Ivir Date: Thu, 9 May 2024 11:16:59 +0000 Subject: [PATCH 093/189] locales(update): Updated Croatian locale --- apps/juxtaposition-ui/src/translations/hr.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/hr.json b/apps/juxtaposition-ui/src/translations/hr.json index 0673b36d..0b10b105 100644 --- a/apps/juxtaposition-ui/src/translations/hr.json +++ b/apps/juxtaposition-ui/src/translations/hr.json @@ -69,7 +69,7 @@ "new_post": { "new_post_text": "Nova Postova", "post_to": "Postov do", - "swearing": "Post Ne Smije Sadržavati Eksplicitan Jezik.", + "swearing": "Objava ne smije sadržavati prostačke izraze.", "text_hint": "Dodirnite ovdje za napraviti a poštov." }, "messages": { @@ -85,7 +85,7 @@ }, "info": "Što je Juxtaposition?", "welcome_text": "Juxt Je Igraća Zajednica Koji Povezuje ljudi iz Diljem Svijeta Koristeći Mii Likovi. Koristite Juxt do Podijelite Svoje Iskustvo Igranja i Upoznati Ljude iz Diljem Svijeta.", - "info_text": "Juxt je Zajednica Igara Vođena Korisnicima u Kojoj Možete Komunicirati s Ljudima \nDiljem Svijeta" + "info_text": "Juxt je korisnički vođena zajednica za igranje u kojoj možeš komunicirati s ljudima diljem svijeta. U zajednicama igara možeš pisati i crtati objave ili slati poruke izravno svojim prijateljima." }, "language": "Hrvatski", "activity_feed": { From 0fbacfdecf0d048b8899d92aa88404a18b4780a1 Mon Sep 17 00:00:00 2001 From: Milo Ivir Date: Thu, 9 May 2024 15:29:02 +0000 Subject: [PATCH 094/189] locales(update): Updated Croatian locale --- .../juxtaposition-ui/src/translations/hr.json | 144 +++++++++++------- 1 file changed, 88 insertions(+), 56 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/hr.json b/apps/juxtaposition-ui/src/translations/hr.json index 0b10b105..1c73f8a0 100644 --- a/apps/juxtaposition-ui/src/translations/hr.json +++ b/apps/juxtaposition-ui/src/translations/hr.json @@ -1,94 +1,126 @@ { "global": { - "go_back": "Idi Natrag", + "go_back": "Idi natrag", "back": "Natrag", "yeahs": "Da", - "more": "Učitaj Više Postova", - "no_posts": "Nema Postova", - "close": "Zatvoriti", - "save": "Sačuvati", - "exit": "Izlaženje", + "more": "Učitaj još objava", + "no_posts": "Nema objava", + "close": "Zatvori", + "save": "Spremi", + "exit": "Zatvori", "private": "Privatno", - "next": "Idući", - "activity_feed": "Feed Aktivnosti", - "user_page": "Korisnička Stranica", + "next": "Dalje", + "activity_feed": "Kanal aktivnosti", + "user_page": "Korisnička stranica", "communities": "Zajednice", "messages": "Poruke", "notifications": "Obavijesti" }, "all_communities": { - "text": "Sve Zajednice", - "announcements": "Najavljivanja", - "ann_string": "Kliknite Ovdje Za Pregled Nedavnih Najava!", - "popular_places": "Popularna Mjesta", - "new_communities": "Novi Zajednice", - "show_all": "Pokaži Sve", - "search": "Traži Zajednice..." + "text": "Sve zajednice", + "announcements": "Najave", + "ann_string": "Pritisni ovdje za prikaz nedavnih najava!", + "popular_places": "Popularna mjesta", + "new_communities": "Nove zajednice", + "show_all": "Pokaži sve", + "search": "Traži zajednice …" }, "community": { - "follow": "Slijediti Zajednič", - "tags": "Označiti", - "posts": "Postovi", - "recent": "Najnovije Objave", - "popular": "Popularan Objave", - "verified": "Potvrđeni Objave", - "new": "Novi Objave", - "following": "Sljedeći", - "followers": "Sljedbenik" + "follow": "Prati zajednicu", + "tags": "Oznake", + "posts": "Objave", + "recent": "Nedavne objave", + "popular": "Popularane objave", + "verified": "Potvrđene objave", + "new": "Nove objave", + "following": "Praćenje", + "followers": "Sljedbenici" }, "user_page": { - "country": "Domovina", + "country": "Zemlja", "birthday": "Rođendan", - "game_experience": "Iskustvo Igre", - "posts": "Postovi", + "game_experience": "Iskustvo igranja", + "posts": "Objave", "friends": "Prijatelji", - "follow_user": "Pratiti", - "unfriend": "Ukinuti Prijateljstvo", - "no_friends": "Bez Prijatelja", - "following": "Sljedeći", - "following_user": "Sljedeći", - "no_following": "Ne Slijedeći Nikoga", - "followers": "Sljedbenik", - "no_followers": "Nema Sljedbenika", - "befriend": "Steći Prijatelje", - "pending": "U Tijeku" + "follow_user": "Prati", + "unfriend": "Ukini prijateljstvo", + "no_friends": "Nema prijatelja", + "following": "Praćenje", + "following_user": "Praćenje", + "no_following": "Ne pratiš nikoga", + "followers": "Sljedbenici", + "no_followers": "Nema sljedbenika", + "befriend": "Sprijatelji se", + "pending": "Na čekanju" }, "user_settings": { - "profile_settings": "Profil Opcije", - "show_country": "Pokazati Nacija Na Profil", - "show_birthday": "Pokazati Rođendan Na Profil", - "show_game": "Pokazati Iskustvo Igre Na Profil", + "profile_settings": "Postavke profila", + "show_country": "Prikaži zemlju u profilu", + "show_birthday": "Prikaži rođendan u profilu", + "show_game": "Prikaži iskustvo igranja u profilu", "profile_comment": "Profil Primjedba", - "swearing": "Komentar Profila Ne Smije Sadržavati Eksplicitan Jezik.", + "swearing": "Komentar profila ne smije sadržavati prostačke izraze.", "show_comment": "Pokazati Primjedba Na Profil" }, "notifications": { - "none": "Nema Obavijestia.", - "new_follower": "Pratio Te!" + "none": "Nema obavijesti.", + "new_follower": "te je pratio/la!" }, "new_post": { - "new_post_text": "Nova Postova", - "post_to": "Postov do", + "new_post_text": "Nova objava", + "post_to": "Objava za", "swearing": "Objava ne smije sadržavati prostačke izraze.", - "text_hint": "Dodirnite ovdje za napraviti a poštov." + "text_hint": "Dodirni ovdje za izradu objave." }, "messages": { - "coming_soon": "Poruke Ne Spremne Još. Vrati Se Kasnije!" + "coming_soon": "Poruke još ne radi. Navrati kasnije!" }, "setup": { "welcome": "Dobrodošli u Juxtaposition!", - "beta": "Beta Odricanje", + "beta": "Odricanje odgovornosti za beta izdanje", "beta_text": { - "first": "Upravo ćete Isprobati Javnu Beta Verziju Juxt. To Znači da se Još Mnogo Toga Može Promijeniti u Bilo Kojem Vrijeme.", - "second": "To Mogla Značiti da se Podaci Mogu Izbrisati u Bilo Kojem Vrijem Tijekom Beta Razdoblja.", - "third": "Web Stranica, Njezin Softver i Sav Sadržaj Koji se na Njoj Nalazi Dostupni su na Temelju \"Kakvi Jesu\" i \"Kako su Dostupni\". Pretendo Network ne Daje Nikakva Jamstva, Izričita Ili Prešutna, u Pogledu Prikladnosti Ili Upotrebljivosti Web Stranice, Njezinog Softvera Ili Bilo Kojeg Njezinog Sadržaja." + "first": "Isprobavaš prvu javnu Juxt beta verziju. To znači da će vjerojatno biti još puno promjena.", + "second": "To može uključivati potpuno brisanje baze podataka na kraju ili tijekom razvoja beta verzije.", + "third": "Web stranica, softver i sav sadržaj pružaju se na osnovi „kao što je” i „kao što je dostupno”. Mreža Pretendo ne jamči, bilo izričito ili implicirano, prikladnost ili upotrebljivost web stranice, softvera ili bilo kojeg njenog sadržaja." }, "info": "Što je Juxtaposition?", - "welcome_text": "Juxt Je Igraća Zajednica Koji Povezuje ljudi iz Diljem Svijeta Koristeći Mii Likovi. Koristite Juxt do Podijelite Svoje Iskustvo Igranja i Upoznati Ljude iz Diljem Svijeta.", - "info_text": "Juxt je korisnički vođena zajednica za igranje u kojoj možeš komunicirati s ljudima diljem svijeta. U zajednicama igara možeš pisati i crtati objave ili slati poruke izravno svojim prijateljima." + "welcome_text": "Juxt je zajednica za igranje koja povezuje ljude iz cijelog svijeta koristeći Mii likove. Koristi Juxt za dijeljenje tvojih iskustva igranja i upoznaj ljude iz cijelog svijeta.", + "info_text": "Juxt je korisnički vođena zajednica za igranje u kojoj možeš komunicirati s ljudima\n diljem svijeta. U zajednicama igara možeš pisati i crtati objave ili slati poruke izravno svojim prijateljima.", + "rules_text": { + "sixth": "Nemoj objavljivati osobne podatke – vlastite ili drugih osoba", + "third": "Juxt sadrži mnoge zajednice za igranje u kojima ljudi iz cijelog svijeta mogu podijeliti svoja razmišljanja. Kada šalješ obavijesti, imaj na umu da to svi mogu vidjeti, stoga se izrazi na pristojan način. Koristi zdrav razum i razmisli prije slanja objave. Juxt je usluga kojoj se također može pristupiti s interneta, stoga imaj na umu da osobe koje ne koriste Juxt također mogu vidjeti tvoje objave. Osim toga, svu tvoji komentari na objave tvojih prijatelja vidjet će ne samo tvoji prijatelji, već i ljudi diljem svijeta.", + "seventh": "Poznavati nekoga u Juxtu nije isto kao poznati osobu u stvarnom životu. Nikada nemoj dijeliti tvoju e-mail adresu, kućnu adresu, naziv posla ili škole ili druge osobne podatke s bilo kim na Juxtu. Također nemoj dijeliti tuđe podatke. Osim toga, ako te netko koga upoznaš u Juxtu pozove da ga upoznaš u stvarnom svijetu, nemoj prihvatiti poziv. Juxt je internetska zajednica i ne bi se trebala koristiti za organiziranje susreta u stvarnom svijetu.", + "eighth": "Nemoj objavljivati tajne igre", + "ninth": "Neki ljudi traže savjete i trikove za igre, drugi žele otkriti tajne igre samostalno. Objave koje otkrivaju tajne igre ili njezinu priču nazivaju se „spojleri”. Ako objavljuješ nešto o igri koja bi mogla biti spojler, prije slanja označi kvadratić spojlera. Na taj način, ljudi koji ne žele spojlere neće vidjeti tvoju objavu.", + "tenth": "Kršenja kodeksa ponašanja", + "eleventh": "Želimo da Juxt bude zabavan i ugodan za sve. U slučaju da netko prekrši kodeks ponašanja Juxta, poduzet ćemo odgovarajuće mjere, sve do blokiranja korisnika ili njegove konzole.", + "twelfth": "Jesi li igrao/la tu igru?", + "thirteenth": "Ako u zajednici objavljuješ igru koju si igrao/la, tvoje će objave dobiti ikonu koja ukazuje na to da si je igralo/la.", + "first": "Slijede neke važne smjernice za stvaranje zabavnog i ugodnog iskustva za sve. Kodeks ponašanja Juxta sadrži detaljne informacije, pa ih pažljivo pročitaj.", + "second": "Objave se mogu prikazati širom svijeta", + "fourth": "Budite uljudni jedni prema drugima", + "fifth": "Kako bismo održali zabavno mjesto za sve, budite uljudni jedni prema drugima. Pomognite nam zadržati ugodno iskustvo ne objavljujući ništa što je neprimjereno ili uvredljivo." + }, + "experience": "Iskustvo igranja", + "experience_text": { + "info": "Ocijeni tvoju razinu iskustva s igrama. Ovu postavku možeš kasnije promijeniti.", + "beginner": "Početnik", + "intermediate": "Napredni", + "expert": "Profesionalac" + }, + "google": "Google Analytics", + "google_text": "Juxtaposition koristi Google Analytics kako bi pratio način na koji korisnici koriste našu uslugu. Prikupljeni podaci uključuju, ali nisu ograničeni na vrijeme posjete, posjećene stranice i provedeno vrijeme na web stranici. Ovi podaci nisu na nikoji način s tobom povezani i mi niti Google ih ne koristimo za oglase.", + "ready": "Sve je spremno za početak korištenja Juxta", + "ready_text": "Najprije pogledaj neke zajednice i vidi što ljudi iz cijelog svijeta objavljuju. Iskoristi ovu priliku da upoznaš Juxt. Možda ćeš otkriti nešto novo!", + "done": "Uživaj u Juxtu!", + "done_button": "Krenimo!", + "guest": "Modus gosta", + "guest_text": "Trenutačno ne možemo provjeriti tvoj račun, što vjerojatno znači da se trenutačno prijavljuješ na Nintendo Network račun. I dalje ćeš moći pregledavati Juxt, ali nećeš moći odgovoriti na objave s „Da!” ili izraditi objave dok se ne prijaviš s Pretendo Network računom. Pregledaj Discord server za više informacija.", + "guest_button": "Razumijem", + "rules": "Juxt pravila" }, "language": "Hrvatski", "activity_feed": { - "empty": "to je prazno ovdje. Pokušajte Pratiti Nekoga!" + "empty": "Ovdje je prazno. Pokušaj nekoga pratiti!" } } From 81e62fbdd5a85bb46324748cdb52cdf89e14d35e Mon Sep 17 00:00:00 2001 From: RISC-VLIW Date: Thu, 9 May 2024 13:51:44 +0000 Subject: [PATCH 095/189] locales(update): Updated French (Canada) locale --- apps/juxtaposition-ui/src/translations/fr_CA.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/fr_CA.json b/apps/juxtaposition-ui/src/translations/fr_CA.json index d4fc6b98..97c4a3bd 100644 --- a/apps/juxtaposition-ui/src/translations/fr_CA.json +++ b/apps/juxtaposition-ui/src/translations/fr_CA.json @@ -120,7 +120,7 @@ "guest": "Mode Invité", "guest_button": "Je Comprends", "guest_text": "Nous ne pouvons pas vérifier votre compte pour le moment, ce qui signifie probablement que vous êtes connecté avec un compte Nintendo Network. Vous pourrez toujours parcourir Juxt, mais vous ne pourrez pas accéder à Yeah! des publiez ou créez vos propres publications jusqu'à ce que vous vous connectiez avec un compte Pretendo Network. Pour plus d'informations, consultez le serveur Discord.", - "google_text": "Juxtaposition utilise Google Analytics pour suivre comment les utilisateurs utilisent notre service.Les données collectées incluent, sans toutefois s'y limiter, le temps de visite, les pages visitées et le temps passé sur le site ne vous sont en aucun cas associées et ne sont pas utilisées à des fins publicitaires par nous ou par Google.\nCommunity Verified icon" + "google_text": "Juxtaposition utilise Google Analytics pour suivre comment les utilisateurs utilisent notre service.Les données collectées incluent, sans toutefois s'y limiter, le temps de visite, les pages visitées et le temps passé sur le site ne vous sont en aucun cas associées et ne sont pas utilisées à des fins publicitaires par nous ou par Google." }, "language": "Français (CA)" } From fb8c14c6a4c090c283a3de9dfcd5e085c120c9ff Mon Sep 17 00:00:00 2001 From: Milo Ivir Date: Thu, 16 May 2024 14:53:20 +0000 Subject: [PATCH 096/189] locales(update): Updated Croatian locale --- apps/juxtaposition-ui/src/translations/hr.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/hr.json b/apps/juxtaposition-ui/src/translations/hr.json index 1c73f8a0..7a25cc5f 100644 --- a/apps/juxtaposition-ui/src/translations/hr.json +++ b/apps/juxtaposition-ui/src/translations/hr.json @@ -58,9 +58,9 @@ "show_country": "Prikaži zemlju u profilu", "show_birthday": "Prikaži rođendan u profilu", "show_game": "Prikaži iskustvo igranja u profilu", - "profile_comment": "Profil Primjedba", + "profile_comment": "Komentar profila", "swearing": "Komentar profila ne smije sadržavati prostačke izraze.", - "show_comment": "Pokazati Primjedba Na Profil" + "show_comment": "Prikaži komentar u profilu" }, "notifications": { "none": "Nema obavijesti.", @@ -76,7 +76,7 @@ "coming_soon": "Poruke još ne radi. Navrati kasnije!" }, "setup": { - "welcome": "Dobrodošli u Juxtaposition!", + "welcome": "Dobro došli u Juxtaposition!", "beta": "Odricanje odgovornosti za beta izdanje", "beta_text": { "first": "Isprobavaš prvu javnu Juxt beta verziju. To znači da će vjerojatno biti još puno promjena.", From 444646d4d886fc81505569d20bf3415acb4ca156 Mon Sep 17 00:00:00 2001 From: silver_volt4 Date: Thu, 23 May 2024 16:16:47 +0200 Subject: [PATCH 097/189] locales(add): Added Slovak locale --- apps/juxtaposition-ui/src/translations/sk.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/juxtaposition-ui/src/translations/sk.json diff --git a/apps/juxtaposition-ui/src/translations/sk.json b/apps/juxtaposition-ui/src/translations/sk.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/apps/juxtaposition-ui/src/translations/sk.json @@ -0,0 +1 @@ +{} From 502a348ee570505f20717e7daef2fc00394f97b9 Mon Sep 17 00:00:00 2001 From: silver_volt4 Date: Thu, 23 May 2024 14:21:27 +0000 Subject: [PATCH 098/189] locales(update): Updated Slovak locale --- apps/juxtaposition-ui/src/translations/sk.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/sk.json b/apps/juxtaposition-ui/src/translations/sk.json index 0967ef42..a771fe37 100644 --- a/apps/juxtaposition-ui/src/translations/sk.json +++ b/apps/juxtaposition-ui/src/translations/sk.json @@ -1 +1,3 @@ -{} +{ + "language": "Slovenčina" +} From 21009ddc6ef90c58100778a3aea74c77385fe15c Mon Sep 17 00:00:00 2001 From: TeraByte38 Date: Thu, 23 May 2024 14:28:15 +0000 Subject: [PATCH 099/189] locales(update): Updated Slovak locale --- .../juxtaposition-ui/src/translations/sk.json | 75 ++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/sk.json b/apps/juxtaposition-ui/src/translations/sk.json index a771fe37..0768a82a 100644 --- a/apps/juxtaposition-ui/src/translations/sk.json +++ b/apps/juxtaposition-ui/src/translations/sk.json @@ -1,3 +1,76 @@ { - "language": "Slovenčina" + "language": "Slovenčina", + "global": { + "communities": "Komunity", + "notifications": "Pripomienky", + "private": "Súkromné", + "close": "Zavrieť", + "save": "Uložiť", + "exit": "Ukončiť", + "next": "Ďalší", + "no_posts": "Žiadne príspevky", + "messages": "Správy" + }, + "community": { + "following": "Odoberané", + "followers": "Odoberatelia", + "posts": "Príspevky", + "recent": "Čerstvé príspevky", + "popular": "Populárne príspevky", + "verified": "Overené príspevky", + "new": "Nové príspevky", + "follow": "Odoberané komunity" + }, + "user_page": { + "country": "Krajina", + "friends": "Priatelia", + "following": "Odoberané", + "followers": "Odoberatelia", + "follow_user": "Odoberať", + "following_user": "Odoberané", + "unfriend": "Odstrániť priateľa", + "no_friends": "Žiadny priatelia", + "posts": "Príspevky", + "birthday": "Dátum narodenia", + "no_followers": "Žiadni odoberatelia" + }, + "all_communities": { + "text": "Všetky komunity", + "popular_places": "Populárne miesta", + "show_all": "Ukázať všetky", + "new_communities": "Nové komunity" + }, + "user_settings": { + "profile_settings": "Nastavenia profilu", + "show_country": "Ukázať krajinu na profile", + "show_birthday": "Ukázať dátum narodenia na profile" + }, + "notifications": { + "new_follower": "vás odoberá!", + "none": "Žiadne pripomienky." + }, + "new_post": { + "text_hint": "Ťuknite sem na vytvorenie príspevku.", + "swearing": "Príspevok nemôže obsahovať nadávky.", + "new_post_text": "Nový príspevok" + }, + "setup": { + "welcome": "Vitajte v Juxtaposition!", + "info": "Čo je Juxtaposition?", + "rules": "Pravidlá Juxta", + "rules_text": { + "eighth": "Neposielajte spoilery" + }, + "experience_text": { + "beginner": "Začiatočník", + "expert": "Expert" + }, + "guest_button": "Rozumiem", + "ready": "Pripavený začať používať Juxt", + "done_button": "Poďme do toho!", + "guest": "Režim návštevníka" + }, + "activity_feed": { + "empty": "Je to tu prázdne. Skúste niekoho odoberať!" + } } From e2ff14a19c48749905c0bfa170aeb1961683dd90 Mon Sep 17 00:00:00 2001 From: Nikolaj Vedel Thage Date: Tue, 28 May 2024 15:10:07 +0200 Subject: [PATCH 100/189] locales(add): Added Danish locale --- apps/juxtaposition-ui/src/translations/da.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/juxtaposition-ui/src/translations/da.json diff --git a/apps/juxtaposition-ui/src/translations/da.json b/apps/juxtaposition-ui/src/translations/da.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/apps/juxtaposition-ui/src/translations/da.json @@ -0,0 +1 @@ +{} From 1e2be929c8d0728eb7f3ddeb741bdcb95268a03d Mon Sep 17 00:00:00 2001 From: Nikolaj Vedel Thage Date: Tue, 28 May 2024 19:46:41 +0000 Subject: [PATCH 101/189] locales(update): Updated Danish locale --- .../juxtaposition-ui/src/translations/da.json | 116 +++++++++++++++++- 1 file changed, 115 insertions(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/da.json b/apps/juxtaposition-ui/src/translations/da.json index 0967ef42..fd12e448 100644 --- a/apps/juxtaposition-ui/src/translations/da.json +++ b/apps/juxtaposition-ui/src/translations/da.json @@ -1 +1,115 @@ -{} +{ + "new_post": { + "swearing": "Opslag må ikke indeholde upassende sprog.", + "new_post_text": "Ny Post", + "post_to": "Post til", + "text_hint": "Tryk her for at lave et opslag." + }, + "setup": { + "welcome": "Velkommen til Juxtaposition!", + "welcome_text": "Juxt er et spilfællesskab, der forbinder folk over hele verdenen ved brug af Mii karakterer. Brug Juxt til at dele dine spiloplevelser og mød nye folk over hele verdenen rundt.", + "rules": "Juxt Regler", + "info": "Hvad er Juxtaposition?", + "beta_text": { + "first": "Du er i gang med at prøve den første offentlige beta af Juxt. Dette betyder at der kan foretages en masse ændringer hen af vejen.", + "third": "Hjemmesiden, dets software og alt indhold der findes på siden er stillet til rådighed på en \"som der er\" og \"som tilgængeligt\" grundlag. Pretendo Netværket udsteder ikke nogen garantier, eten direkte udtrykt eller underforstået, for at egnetheden eller brugbarheden af hjemmesiden, dets software eller noget at dets indhold.", + "second": "Dette kan inkludere en fuldstændig fjernelse af alt data i løbet af eller i slutningen betaen." + }, + "rules_text": { + "first": "Det følgende er nogle vigtige retningslinjer, der sørger for at Juxt er en god oplevelse for alle. Juxts adfærdskodeks indeholder vigtig information, så vær rar med at give dig selv tid til at læse det omhyggeligt.", + "sixth": "Del ikke personlige oplysninger - Dine eller Andres", + "twelfth": "Har du spillet det spil?", + "fourth": "Vær sød or rare ved hinanden", + "second": "Oplæg Kan Ses Verdenen Over", + "eighth": "Del ikke Spoilere", + "tenth": "Retningslinjer Overtrædelser" + }, + "beta": "Beta Ansvarsfralæggelse", + "done_button": "Lad os komme i gang!", + "guest_button": "Jeg forstår", + "experience": "Spilerfaring", + "experience_text": { + "info": "Fortæl os hvordan du ville forklare dit niveau af erfaring med spil. Du kan ændre denne indstilling senere.", + "beginner": "Begynder", + "intermediate": "Øvet", + "expert": "Ekspert" + }, + "ready_text": "Først og fremmest check ud nogle af fællesskaberne for at se hvad folk rund om verdenen snakker om. Brug det øjeblik til at gøre dig mere bekendt med Juxt. Måske opstår der endda nogle nye opdagelser på vejen!", + "done": "Mor dig i Juxt!", + "info_text": "Juxt er et brugerdrevet spilfællesskab, hvor du kan kommunikere med folk\nfra hele verdenen. Du kan skrive eller tegne oplag i spilfælleskaber eller sende beskeder direkte til dine venner." + }, + "user_page": { + "followers": "Følgere", + "country": "Land", + "birthday": "Fødselsdag", + "friends": "Venner", + "pending": "Afventer", + "no_friends": "Ingen Venner", + "no_followers": "Ingen Følgere", + "game_experience": "Spilerfaring", + "posts": "Oplæg", + "following": "Følger", + "follow_user": "Følg", + "following_user": "Følger", + "befriend": "Bliv Venner", + "unfriend": "Afslut Venskab", + "no_following": "Følger Ikke Nogen" + }, + "user_settings": { + "swearing": "Kommentaren må ikke indeholde upassende sprog.", + "profile_settings": "Profilindstillinger", + "show_birthday": "Vis Fødselsdag på Profil", + "show_country": "Vis Land på Profil", + "show_game": "Vis Spilerfaring på Profil", + "show_comment": "Vis Kommentar på Profil", + "profile_comment": "Profilkommentar" + }, + "global": { + "no_posts": "Ingen Opslag", + "communities": "Fællesskaber", + "notifications": "Notifikationer", + "go_back": "Gå Tilbage", + "yeahs": "Yeah'er", + "more": "Indlæs Flere Opslag", + "exit": "Afslut", + "next": "Næste", + "user_page": "Bruger Side", + "activity_feed": "Aktivitetsside", + "messages": "Beskeder", + "back": "Tilbage", + "private": "Privat", + "close": "Luk", + "save": "Gem" + }, + "all_communities": { + "announcements": "Meddelelser", + "popular_places": "Populære Steder", + "new_communities": "Nye Fællesskaber", + "search": "Søg efter fællesskaber...", + "text": "Alle Fællesskaber", + "ann_string": "Klik her for at se nye meddelelser!", + "show_all": "Vis Alle" + }, + "community": { + "following": "Følger", + "followers": "Følgere", + "tags": "Etiketter", + "verified": "Verificerede Opslag", + "popular": "Populære Opslag", + "new": "Nyt Opslag", + "follow": "Følg Fællesskab", + "posts": "Opslag", + "recent": "Nylige Opslag" + }, + "activity_feed": { + "empty": "Det ser tomt ud her. Prøv at følge nogen!" + }, + "notifications": { + "none": "Ingen notifikationer.", + "new_follower": "følger dig!" + }, + "messages": { + "coming_soon": "Beskeder er ikke klar endnu. Prøv igen senere!" + }, + "language": "Dansk" +} From 949668f0059f30cd895cb6c7c9e08fc35e3bb711 Mon Sep 17 00:00:00 2001 From: LNLenost Date: Tue, 4 Jun 2024 16:11:04 +0000 Subject: [PATCH 102/189] locales(update): Updated Italian locale --- .../juxtaposition-ui/src/translations/it.json | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/it.json b/apps/juxtaposition-ui/src/translations/it.json index 93d9d84e..723e626b 100644 --- a/apps/juxtaposition-ui/src/translations/it.json +++ b/apps/juxtaposition-ui/src/translations/it.json @@ -2,14 +2,14 @@ "language": "Italiano", "global": { "user_page": "Pagina dell'utente", - "activity_feed": "Feed delle attività", - "communities": "Community", + "activity_feed": "Attività", + "communities": "Comunità", "messages": "Messaggi", "notifications": "Notifiche", "go_back": "Torna indietro", "back": "Indietro", "yeahs": "Sìì", - "more": "Carica più post", + "more": "Carica altri post", "no_posts": "Nessun post", "private": "Privato", "close": "Chiudi", @@ -18,18 +18,18 @@ "next": "Avanti" }, "all_communities": { - "text": "Tutte le community", + "text": "Tutte le comunità", "announcements": "Annunci", "ann_string": "Clicca qui per vedere gli annunci più recenti!", "popular_places": "Luoghi popolari", - "new_communities": "Nuove community", + "new_communities": "Nuove comunità", "show_all": "Mostra tutto", - "search": "Cerca community..." + "search": "Cerca comunità..." }, "community": { - "follow": "Segui community", + "follow": "Segui comunità", "following": "Seguiti", - "followers": "seguiti", + "followers": "Seguitori", "posts": "Post", "tags": "Etichette", "recent": "Post recenti", @@ -44,14 +44,14 @@ "posts": "Post", "friends": "Amici", "following": "Seguiti", - "followers": "Follower", + "followers": "Seguitore", "follow_user": "Segui", "following_user": "Stai seguendo", "befriend": "Chiedi amicizia", "pending": "In attesa", "unfriend": "Rimuovi amicizia", "no_friends": "Nessun amico", - "no_following": "Non segue nessuno", + "no_following": "Non segui nessuno", "no_followers": "Nessun follower" }, "user_settings": { From 459afbe6ce9059177340de2bcbfa2509c7901ab8 Mon Sep 17 00:00:00 2001 From: lenyet Date: Mon, 17 Jun 2024 22:49:01 +0000 Subject: [PATCH 103/189] locales(update): Updated French locale --- .../juxtaposition-ui/src/translations/fr.json | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/fr.json b/apps/juxtaposition-ui/src/translations/fr.json index 1e5591fa..ffe47a9f 100644 --- a/apps/juxtaposition-ui/src/translations/fr.json +++ b/apps/juxtaposition-ui/src/translations/fr.json @@ -11,7 +11,7 @@ "yeahs": "Ouais", "more": "Afficher plus de publications", "no_posts": "Aucune Publication", - "private": "Privés", + "private": "Privé", "close": "Fermer", "save": "Sauvegarder", "exit": "Quitter", @@ -21,7 +21,7 @@ "text": "Toutes les Communautés", "announcements": "Annonces", "ann_string": "Cliquez-ici pour voir les dernières annonces !", - "popular_places": "Lieux Populaires", + "popular_places": "Communautés Populaires", "new_communities": "Nouvelles Communautés", "show_all": "Afficher Tout", "search": "Rechercher des Communautés..." @@ -50,9 +50,9 @@ "befriend": "Devenir Amis", "pending": "En Attente", "unfriend": "Retirer des Amis", - "no_friends": "Aucun Amis", + "no_friends": "Aucun Ami", "no_following": "Ne Suit Personne", - "no_followers": "Aucun Abonnés" + "no_followers": "Aucun Abonné" }, "user_settings": { "profile_settings": "Paramètres du Profil", @@ -67,7 +67,7 @@ "empty": "C'est vide ici. Essaie de suivre quelqu'un !" }, "notifications": { - "none": "Aucune notifications.", + "none": "Aucune notification.", "new_follower": "vous suit !" }, "new_post": { @@ -77,14 +77,14 @@ "swearing": "Les publications ne peuvent pas contenir de language explicite." }, "messages": { - "coming_soon": "Les messages ne sont pas encore prêt pour le moment. Revenez bientôt !" + "coming_soon": "Les messages ne sont pas encore prêts pour le moment. Revenez bientôt !" }, "setup": { "welcome": "Bienvenue sur Juxtaposition !", - "welcome_text": "Juxt est une communauté de jeu qui connecte les personnes du monde entier à l'aide de personnages Mii. Utilisez Juxt pour partager votre expériences de jeu et rencontrer les gens autour du globe.", + "welcome_text": "Juxt est une communauté de jeu qui connecte les personnes du monde entier à l'aide de personnages Mii. Utilisez Juxt pour partager votre expérience de jeu et rencontrer des gens autour du globe.", "beta": "Avertissement Beta", "beta_text": { - "first": "Vous êtes sur le point d'essayer la première version bêta publique de Juxt. Cela signifie que beaucoup de choses sont encore en suspens et qu'elles peuvent changer à tout moment.", + "first": "Vous êtes sur le point d'essayer la première version bêta publique de Juxt. Cela signifie que beaucoup de choses sont encore en développement et qu'elles peuvent changer à tout moment.", "second": "Cela peut inclure un effacement total de la base de données à la fin ou pendant la période bêta.", "third": "Le site web, son logiciel et tout le contenu qui s'y trouve sont fournis sur une base \"telle quelle\" et \"telle que disponible\". Le Réseau Pretendo ne donne aucune garantie, expresse ou implicite, quant à l'adéquation ou à la facilité d'utilisation du site web, de son logiciel ou de son contenu." }, @@ -92,13 +92,13 @@ "info_text": "Juxt est une communauté de jeu gérée par les utilisateurs où vous pouvez interagir avec des personnes du monde entier.\nVous pouvez écrire ou dessiner des messages dans les communautés de jeu ou envoyer des messages directement à vos amis.", "rules": "Règles de Juxt", "rules_text": { - "first": "Voici quelques directives importantes pour faire de Juxt une expérience amusante et agréable pour tous. Le code de conduite de Juxt contient des informations détaillées. Veuillez les lires attentivement.", - "second": "Les publications peuvent être consultés dans le monde entier", + "first": "Voici quelques directives importantes pour faire de Juxt une expérience amusante et agréable pour tous. Le code de conduite de Juxt contient des informations détaillées. Veuillez les lire attentivement.", + "second": "Les publications peuvent être consultées dans le monde entier", "third": "Juxt contient de nombreuses communautés de jeu où des personnes du monde entier peuvent partager leurs idées. Lorsque vous publiez un message dans une communauté, n'oubliez pas que tout le monde peut le voir, alors exprimez-vous de manière à ce que tout le monde puisse l'apprécier. Faites preuve de bon sens et réfléchissez avant de publier. Juxt est un service qui est également accessible sur Internet, alors n'oubliez pas que les personnes qui n'utilisent pas Juxt peuvent également voir vos messages. De plus, les commentaires que vous faites sur les messages de vos amis seront vus non seulement par vos amis mais aussi par des personnes autour du globe. Gardez cela à l'esprit.", "fourth": "Soyez gentils les uns envers les autres", "fifth": "Afin que Juxt reste un endroit agréable pour tous, nous vous demandons d'être soucieux des autres utilisateurs. Aidez-nous à faire de Juxt une expérience agréable en ne publiant rien d'inapproprié ou d'offensant.", "sixth": "Ne publiez pas d'informations personnelles - les vôtres ou celles des autres", - "seventh": "N'oubliez pas que connaître quelqu'un sur Juxt n'est pas la même chose que de le connaître dans la vie réelle. Ne partagez jamais votre adresse électronique, votre adresse personnelle, le nom de votre travail ou école, ou toute autre information permettant de vous identifier personnellement avec quelqu'un sur Juxt, et ne partagez jamais non plus les informations de quelqu'un d'autre. Si une personne rencontrée sur Juxt vous invite à la rencontrer dans le monde réel, n'acceptez pas. Juxt est une communauté en ligne et ne doit pas être utilisé pour organiser des rencontres dans le monde réel.", + "seventh": "N'oubliez pas que connaître quelqu'un sur Juxt n'est pas la même chose que de le connaître dans la vie réelle. Ne partagez jamais votre adresse électronique, votre adresse personnelle, le nom de votre lieu de travail ou école, ou toute autre information permettant de vous identifier personnellement avec quelqu'un sur Juxt, et ne partagez jamais non plus les informations de quelqu'un d'autre. Si une personne rencontrée sur Juxt vous invite à la rencontrer dans le monde réel, n'acceptez pas. Juxt est une communauté en ligne et ne doit pas être utilisé pour organiser des rencontres dans le monde réel.", "eighth": "Ne postez pas les secrets d'un jeu", "ninth": "Certaines personnes viennent sur Juxt à la recherche de conseils et d'astuces pour les jeux, mais d'autres veulent découvrir les secrets d'un jeu par elles-mêmes. Les messages qui révèlent les secrets d'un jeu ou de son histoire sont appelés \"spoilers\". Si vous publiez quelque chose sur un jeu qui pourrait être un spoiler, assurez-vous de cocher la case Spoilers avant d'envoyer votre message. Ainsi, les personnes qui ne veulent pas être spoilées ne verront pas votre message.", "tenth": "Violations du Code de Conduite", From f3b183de196d91cdd99c2ffd34a1b937a2db62e4 Mon Sep 17 00:00:00 2001 From: "M.L.D" Date: Thu, 20 Jun 2024 00:46:17 +0000 Subject: [PATCH 104/189] locales(update): Updated Catalan locale --- apps/juxtaposition-ui/src/translations/ca.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/ca.json b/apps/juxtaposition-ui/src/translations/ca.json index 851bd779..96904edf 100644 --- a/apps/juxtaposition-ui/src/translations/ca.json +++ b/apps/juxtaposition-ui/src/translations/ca.json @@ -4,7 +4,7 @@ "more": "Carregar més publicacions", "next": "Següent", "messages": "Missatges", - "activity_feed": "Feed d'activitats", + "activity_feed": "Taxes d'activitat", "exit": "Sortir", "back": "Enrere", "notifications": "Notificacions", @@ -14,7 +14,7 @@ "close": "Tancar", "user_page": "Pàgina d'usuari", "go_back": "Torna", - "yeahs": "Sí" + "yeahs": "Mola" }, "notifications": { "none": "No hi ha notificacions.", @@ -35,7 +35,7 @@ "birthday": "Aniversari", "country": "País", "following": "Seguint", - "unfriend": "Eliminar de la llista d'amics" + "unfriend": "Eliminar amic" }, "community": { "new": "Publicació nova", @@ -45,7 +45,7 @@ "following": "Seguint", "follow": "Segueix aquesta comunitat", "verified": "Publicacions verificades", - "recent": "Entrades recents", + "recent": "Publicacions recents", "popular": "Publicacions populars" }, "user_settings": { @@ -61,7 +61,7 @@ "text_hint": "Toca aquí per fer una publicació.", "new_post_text": "Publicació nova", "post_to": "Publica a", - "swearing": "L'entrada no pot contenir llenguatge explícit." + "swearing": "La teva publicació no pot contenir llenguatge explícit." }, "all_communities": { "show_all": "Mostra-ho tot", @@ -89,7 +89,7 @@ "second": "Les publicacions es poden veure a tot el món", "sixth": "No publiquis informació personal, teva o d'altres persones", "first": "A continuació es detallen algunes pautes importants per fer de Juxt una experiència divertida i agradable per a tothom. El Codi de Conducta de Juxt conté informació detallada, així que llegiu-la atentament.", - "eighth": "No publiqueu spoilers", + "eighth": "No publiqueu revelacions", "seventh": "Recordeu, no és el mateix conèixer algú a Juxt que conèixer-lo a la vida real. No compartiu mai la vostra adreça de correu electrònic, adreça de casa, nom de la feina o de l'escola, ni cap altra informació d'identificació personal amb ningú a Juxt, i mai compartiu la informació de ningú més. A més, si algú que coneixes a Juxt et convida a conèixer-lo al món real, no acceptis. Juxt és una comunitat en línia i no s'ha d'utilitzar per organitzar trobades del món real.", "twelfth": "Has jugat a aquest joc?" }, @@ -118,7 +118,7 @@ "info_text": "Juxt és una comunitat de jocs impulsada per l'usuari on es pot interactuar amb la gent\n a tot el món. Pots escriure o dibuixar publicacions en comunitats de jocs o enviar missatges directament als teus amics.", "ready_text": "En primer lloc, fes un cop d'ull a algunes comunitats i descobreix què publiquen persones de tot el món. Aprofita aquesta oportunitat per familiaritzar-te amb Juxt. Podeu fer alguns descobriments nous al llarg del camí!", "done": "Diverteix-te a Juxt!", - "beta": "Exempció de responsabilitat beta" + "beta": "Exempció de responsabilitat sobre la beta" }, "messages": { "coming_soon": "L'opció Missatges encara no està preparada. Torna-ho a comprovar aviat!" From eb0179f6f5299458fa375a1f1c7844f26431fd96 Mon Sep 17 00:00:00 2001 From: John Birtch Date: Mon, 1 Jul 2024 04:58:02 +0200 Subject: [PATCH 105/189] locales(add): Added Latvian locale --- apps/juxtaposition-ui/src/translations/lv.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/juxtaposition-ui/src/translations/lv.json diff --git a/apps/juxtaposition-ui/src/translations/lv.json b/apps/juxtaposition-ui/src/translations/lv.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/apps/juxtaposition-ui/src/translations/lv.json @@ -0,0 +1 @@ +{} From 26241aed0068395ecc2ef5ead475fa7fe664ce56 Mon Sep 17 00:00:00 2001 From: Deko Kiyo Date: Tue, 2 Jul 2024 03:15:40 +0000 Subject: [PATCH 106/189] locales(update): Updated Japanese locale --- apps/juxtaposition-ui/src/translations/ja.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/ja.json b/apps/juxtaposition-ui/src/translations/ja.json index 7781de71..9cc03aba 100644 --- a/apps/juxtaposition-ui/src/translations/ja.json +++ b/apps/juxtaposition-ui/src/translations/ja.json @@ -1,7 +1,7 @@ { "language": "日本語", "global": { - "user_page": "マイメニュー", + "user_page": "ユーザーページ", "activity_feed": "みんなの活動", "communities": "コミュニティ", "messages": "メッセージ", From 0f7c6b175e58faa22b6eb0273670f85b41721534 Mon Sep 17 00:00:00 2001 From: John Birtch Date: Mon, 1 Jul 2024 04:43:33 +0000 Subject: [PATCH 107/189] locales(update): Updated Latvian locale --- .../juxtaposition-ui/src/translations/lv.json | 127 +++++++++++++++++- 1 file changed, 126 insertions(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/lv.json b/apps/juxtaposition-ui/src/translations/lv.json index 0967ef42..df3b1cf9 100644 --- a/apps/juxtaposition-ui/src/translations/lv.json +++ b/apps/juxtaposition-ui/src/translations/lv.json @@ -1 +1,126 @@ -{} +{ + "global": { + "activity_feed": "Aktivitātes saraksts", + "messages": "Ziņas", + "notifications": "Paziņojumi", + "go_back": "Doties Atpakaļ", + "back": "Atpakaļ", + "no_posts": "Nav ziņojumu", + "private": "Privāts", + "close": "Aizvērt", + "exit": "Iziet", + "more": "Ielādēt vairāk ziņojumus", + "save": "Saglabāt", + "next": "Nākamais", + "yeahs": "Reakcijas", + "communities": "Kopienas", + "user_page": "Lietotāju Lapa" + }, + "all_communities": { + "announcements": "Paziņojumi", + "ann_string": "Spied šeit, lai skatītu nesen sūtītos ziņojumus!", + "new_communities": "Jaunas kopienas", + "show_all": "Rādīt visus", + "text": "Visas kopienas", + "search": "Meklēt kopienas...", + "popular_places": "Bieži apmeklētas vietas" + }, + "community": { + "follow": "Sekot kopienai", + "following": "Seko līdzi", + "followers": "Sekotāji", + "posts": "Ziņojumi", + "tags": "Birkas", + "recent": "Nesen sūtītie ziņojumi", + "new": "Jauna ziņa", + "verified": "Apstiprinātās ziņas", + "popular": "Bieži skatītie ziņojumi" + }, + "user_page": { + "birthday": "Dzimšanas diena", + "posts": "Ziņojumi", + "friends": "Draugi", + "following": "Seko", + "follow_user": "Sekot", + "following_user": "Seko", + "befriend": "Pievienot draugu sarakstam", + "pending": "Gaidošie", + "unfriend": "Noņemt no draugu saraksta", + "no_following": "Nevienam neseko", + "country": "Valsts", + "followers": "Sekotāji", + "no_friends": "Nav neviena drauga", + "no_followers": "Nav neviena sekotāja", + "game_experience": "Spēles spēlēšanas pieredze" + }, + "user_settings": { + "profile_settings": "Profila iestatījumi", + "show_country": "Rādīt valsti profilā", + "show_birthday": "Rādīt dzimšanas dienu profilā", + "show_comment": "Radīt komentārus pie profila", + "profile_comment": "Profila komentāri", + "swearing": "Profila komentārs nedrīkst saturēt necenzētu valodu.", + "show_game": "Rādīt spēļu pieredzi profilā" + }, + "activity_feed": { + "empty": "Te ir tukšs. Pamēģini kādam sekot!" + }, + "notifications": { + "none": "Nav ziņojumi.", + "new_follower": "sāka tev sekot!" + }, + "new_post": { + "post_to": "Nosūtīt uz", + "new_post_text": "Jauns ziņojums", + "text_hint": "Spied šeit, lai rakstītu ziņojumu.", + "swearing": "Ziņojums nedrīkst saturēt necenzētu valodu." + }, + "setup": { + "welcome": "Laipni lūgts Juxtaposition!", + "beta": "Beta brīdinājums", + "info": "Kas ir Juxtaposition?", + "rules": "Juxt noteikumi", + "rules_text": { + "second": "Ziņas var tikt skatītas visā pasaulē", + "fourth": "Esi jauks pret citiem", + "sixth": "Neraksti neviena cilvēka personīgo informāciju", + "eighth": "Neraksti spoilerus", + "tenth": "Uzvedības kodeksa pārkāpumi", + "first": "Turpmāk minētās ir svarīgas vadlīnijas, kas ir ieviestas ar mērķi padarīt Juxt par aizraujošu un baudāmu pieredzi visiem. Juxt uzvedības kodekss satur detalizētu informāciju, tādēļ lūdzu izlasiet to uzmanīgi.", + "third": "Juxt satur daudzas spēlētāju kopienas, kurās cilvēki no visas pasaules var dalīties ar savām domām. Kad tu raksti kopienai, atceries, ka visi var to redzēt, tādēļ, lūdzu, izpaud sevi veidā, kas visiem ir patīkams. Izmanto vispārējo saprātu, un padomā pirms raksti. Juxt ir serviss, kas ir pieejams caur internetu, tādēļ paturi prātā, ka arī cilvēki, kas neizmanto Juxt var redzēt tavas ziņas. Papildus tam, visi komentāri, ko tu raksti pie savu draugu ziņām būs redzami arī visiem citiem. Lūdzu atceries šo.", + "fifth": "Lai paturētu Juxt par foršu vietu visiem, mēs prasām, lai tu esi saudzīgs pret citiem lietotājiem. Palīdzi mums saglabāt Juxt patīkamu, nerakstot neko neatbilstošu vai aizvainošu.", + "seventh": "Atcerieties, ka zināt kādu Juxt nav tas pats, kas viņu personīgi pazīt reālajā dzīvē. Nekad nevienam neraksti savu e-pasta adresi, dzīvesvietas adresi, darba vai skolas nosaukumu vai citu personisku informāciju caur Juxt, un nekad nedalieties arī ar citu personu personīgo informāciju. Turklāt, ja kāds, ar ko esat iepazinies Juxt, aicina tevi tikties reālajā pasaulē, nepieņem to. Juxt ir tiešsaistes kopiena, un to nevajadzētu izmantot, lai organizētu reālas tikšanās.", + "ninth": "Daži cilvēki ierodas Juxt meklējot padomus un trikus priekš spēlēm, bet citi grib paši atklāt spēles noslēpumus. Ziņas, kas atklāj šos noslēpumus par spēli vai tās scenāriju sauc par \"spoileriem\". Ja tu raksti kaut ko, kas varētu būt spoileris, pārliecinies, ka atzīmējiet spoilera izvēles rūtiņu. Tādā veidā, cilvēki, kas nevēlas tikt spoiloti neredzēs šo ziņu.", + "eleventh": "Mūsu mērķis ir saglabāt Juxt par draudzīgu un patīkamu visiem. Ja kāds pārkāps Juxt rīcības kodeksu, mēs veiksim atbilstošus pasākumus, tostarp bloķēsim pārkāpēju lietotāju un/vai konsoli.", + "twelfth": "Vai tu esi spēlējis šo spēli?", + "thirteenth": "Ja tu raksti kopienā par spēli, kuru tu esi spēlējis, tavām ziņām būs ikona, kas norāda, ka tu esi to spēlēji." + }, + "experience": "Spēļu spēlēšanas pieredze", + "experience_text": { + "beginner": "Iesācējs", + "info": "Lūdzu pastāsti mums, kā tu aprakstītu savu pieredzi ar videospēlēm. Tu vari vēlāk mainīt šo iestatījumu.", + "intermediate": "Piepratējs", + "expert": "Eksperts" + }, + "ready": "Gatavs sākt izmantot Juxt", + "ready_text": "Vispirms apskati dažas kopienas un noskaidro par ko citi cilvēki raksta. Izmanto šo iespēju, lai iepazīstinātu sevi ar Juxt. Tu pa ceļam varētu veikt jaunus atklājumus!", + "done": "Priecājies izmantojot Juxt servisu!", + "done_button": "Aiziet!", + "guest": "Viesa režīms", + "guest_text": "Mēs pašlaik nevaram apstiprināt tavu kontu, kas visticamāk nozīmē, ka tu pašlaik esi ielogojies ar Nintendo Network kontu. Tu varēsi apskatīt Juxt, bet nevarēsi reaģēt uz ziņām vai rakstīt tās pats, līdz ielogosies ar Pretendo Network kontu. Lai iegūtu vairāk informāciju apskati mūsu Discord serveri.", + "guest_button": "Es saprotu", + "beta_text": { + "first": "Tu izmēģināsi pirmo Juxt publisko beta versiju. Tas nozīmē, ka daudz lietas vēl nav pabeigtas, un daudz, kas vēl tiks mainīts.", + "third": "Mājaslapa, tās programmatūra un viss tajā atrodamais saturs tiek nodrošināts pēc \"tā, kā ir\" un \"kā pieejams\" principa. Pretendo Network nesniedz nekādas garantijas - ne tiešas, ne netiešas - par tīmekļa vietnes, tās programmatūras vai jebkāda tās satura piemērotību vai lietojamību.", + "second": "Tas var saturēt absolūtu datubāžu izdzēšanu beta testēšanas perioda laikā vai pēc tā." + }, + "info_text": "Juxt ir lietotāju vadīta spēlētāju kopiena, kurā tu vari mijiedarboties ar cilvēkiem\n no visas pasaules. Tu vari rakstīt vai uzzīmēt ziņas spēļu kopienām vai arī sūtīt ziņas tieši draugiem.", + "google": "Google analītika", + "google_text": "Juxtaposition izmanto \"Google Analytics\", lai izsekotu, kā lietotāji izmanto mūsu pakalpojumus. Savāktie dati ietver, bet neaprobežojas ar apmeklējuma laiku, apmeklētajām lapām un vietnē pavadīto laiku. Šie dati nav nekādā veidā saistīti ar jums(?), un mēs vai Google(?) tos neizmanto reklāmām.", + "welcome_text": "Juxt ir spēlētāju kopiena, kas savieno cilvēkus no visas pasaules, izmantojot Mii varoņus. Izmanto Juxt, lai dalītos savā spēlēšanas pieredzē un satiktu cilvēkus no visas pasaules." + }, + "language": "Latviešu valoda", + "messages": { + "coming_soon": "Ziņas vēl nav gatavas. Apskati atkal pēc kāda laika!" + } +} From ec3cc1a9ee5cd9784fe036091001682e691f7363 Mon Sep 17 00:00:00 2001 From: AlgerianGerman Date: Thu, 4 Jul 2024 06:13:02 +0000 Subject: [PATCH 108/189] locales(update): Updated Kazakh locale --- .../juxtaposition-ui/src/translations/kk.json | 42 ++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/kk.json b/apps/juxtaposition-ui/src/translations/kk.json index f827473a..7d21ca3b 100644 --- a/apps/juxtaposition-ui/src/translations/kk.json +++ b/apps/juxtaposition-ui/src/translations/kk.json @@ -1,3 +1,43 @@ { - "language": "қазақша" + "language": "қазақша", + "global": { + "go_back": "Артқа", + "more": "Қосымша хабарламаларды жүктеңіз", + "yeahs": "Иә", + "user_page": "Пайдаланушы беті", + "activity_feed": "Белсенділік арнасы", + "communities": "Қауымдастықтар", + "messages": "Хабарламалар", + "notifications": "Хабарландырулар", + "back": "Артқа", + "no_posts": "Посттар жоқ", + "private": "Жеке", + "close": "Жабу", + "save": "Сақтаңыз", + "exit": "Шығу", + "next": "Келесі" + }, + "all_communities": { + "text": "Барлық қауымдастықтар", + "announcements": "Хабарландырулар", + "ann_string": "Соңғы хабарландыруларды көру үшін осы жерді басыңыз!", + "popular_places": "Танымал орындар", + "new_communities": "Жаңа қауымдастықтар", + "show_all": "Барлығын көрсетіңіз", + "search": "Қауымдастықтарды іздеу..." + }, + "community": { + "follow": "Қауымдастықты бақылаңыз", + "following": "Төменде", + "followers": "Ізбасарлар", + "posts": "Хабарламалар", + "tags": "Тегтер", + "recent": "Соңғы жазбалар", + "popular": "Танымал жазбалар", + "verified": "Тексерілген хабарламалар", + "new": "Жаңа пост" + }, + "user_page": { + "country": "Ел" + } } From daddc958b99842ffce764cdf86fc2735fd46416c Mon Sep 17 00:00:00 2001 From: AlgerianGerman Date: Thu, 4 Jul 2024 06:37:59 +0000 Subject: [PATCH 109/189] locales(update): Updated Belarusian locale --- apps/juxtaposition-ui/src/translations/be.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/be.json b/apps/juxtaposition-ui/src/translations/be.json index 8d174e04..5b86e3d0 100644 --- a/apps/juxtaposition-ui/src/translations/be.json +++ b/apps/juxtaposition-ui/src/translations/be.json @@ -43,7 +43,11 @@ "posts": "Пасты", "friends": "Сябры", "following": "Падпіскі", - "followers": "Падпісчыкі" + "followers": "Падпісчыкі", + "follow_user": "Сачыць", + "following_user": "Далей", + "befriend": "Сябраваць", + "pending": "Дапытлівы" }, "language": "Беларуская" } From 1665a9d69a315ead72ecfdceec17ed3e9b851f13 Mon Sep 17 00:00:00 2001 From: Stefan Zimmermann Date: Sun, 21 Jul 2024 10:16:41 +0000 Subject: [PATCH 110/189] locales(update): Updated German locale --- apps/juxtaposition-ui/src/translations/de.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/de.json b/apps/juxtaposition-ui/src/translations/de.json index 863b1b8a..a00aa31b 100644 --- a/apps/juxtaposition-ui/src/translations/de.json +++ b/apps/juxtaposition-ui/src/translations/de.json @@ -45,7 +45,7 @@ "friends": "Freunde", "following": "Folge ich", "followers": "Follower", - "follow_user": "Gefolgt von", + "follow_user": "Folgen", "following_user": "Folgt", "befriend": "Befreunden", "pending": "Ausstehend", From 9ec1aee2e8d4f40e6b46fed3fc779a2e8a9e6e4c Mon Sep 17 00:00:00 2001 From: Susie Caine McPeak Date: Tue, 23 Jul 2024 22:15:00 +0200 Subject: [PATCH 111/189] locales(add): Added Esperanto locale --- apps/juxtaposition-ui/src/translations/eo.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/juxtaposition-ui/src/translations/eo.json diff --git a/apps/juxtaposition-ui/src/translations/eo.json b/apps/juxtaposition-ui/src/translations/eo.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/apps/juxtaposition-ui/src/translations/eo.json @@ -0,0 +1 @@ +{} From 08f6e0a50dc7507ba97f7b908c273d96fe260224 Mon Sep 17 00:00:00 2001 From: Susie Caine McPeak Date: Tue, 23 Jul 2024 20:21:57 +0000 Subject: [PATCH 112/189] locales(update): Updated Esperanto locale --- .../juxtaposition-ui/src/translations/eo.json | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/eo.json b/apps/juxtaposition-ui/src/translations/eo.json index 0967ef42..6a1abc55 100644 --- a/apps/juxtaposition-ui/src/translations/eo.json +++ b/apps/juxtaposition-ui/src/translations/eo.json @@ -1 +1,20 @@ -{} +{ + "global": { + "user_page": "Profilo", + "activity_feed": "Novaĵoj", + "communities": "Komunumoj", + "messages": "Mesaĝoj", + "notifications": "Avizoj", + "go_back": "Reveni", + "back": "Malantaŭ", + "yeahs": "Ŝatoj", + "more": "Vidigi pli de afiŝoj", + "no_posts": "Neniu afiŝoj", + "private": "Privata", + "close": "Fermi", + "save": "Konservi", + "exit": "Eliri", + "next": "Sekvanto" + }, + "language": "Esperanto" +} From 72092f5aacab4091a49a6f3699f9e95e4dac51a9 Mon Sep 17 00:00:00 2001 From: Susie Caine McPeak Date: Fri, 26 Jul 2024 00:27:41 +0000 Subject: [PATCH 113/189] locales(update): Updated Spanish locale --- apps/juxtaposition-ui/src/translations/es.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/es.json b/apps/juxtaposition-ui/src/translations/es.json index d93b125a..7d127eb8 100644 --- a/apps/juxtaposition-ui/src/translations/es.json +++ b/apps/juxtaposition-ui/src/translations/es.json @@ -56,7 +56,7 @@ }, "user_settings": { "profile_settings": "Preferencias del perfil", - "show_country": "Mostrar país en tu perfil", + "show_country": "", "show_birthday": "Mostrar cumpleaños en tu perfil", "show_game": "Mostrar el nivel como jugador en tu perfil", "show_comment": "Mostrar comentario en tu perfil", From b2c46a2f0d7b38d24a4321e40d3292df1fd3dad5 Mon Sep 17 00:00:00 2001 From: Susie Caine McPeak Date: Thu, 25 Jul 2024 19:16:44 +0000 Subject: [PATCH 114/189] locales(update): Updated Esperanto locale --- .../juxtaposition-ui/src/translations/eo.json | 44 ++++++++++++++++++- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/eo.json b/apps/juxtaposition-ui/src/translations/eo.json index 6a1abc55..d791f8a7 100644 --- a/apps/juxtaposition-ui/src/translations/eo.json +++ b/apps/juxtaposition-ui/src/translations/eo.json @@ -8,7 +8,7 @@ "go_back": "Reveni", "back": "Malantaŭ", "yeahs": "Ŝatoj", - "more": "Vidigi pli de afiŝoj", + "more": "Vidigi pli de afiŝojn", "no_posts": "Neniu afiŝoj", "private": "Privata", "close": "Fermi", @@ -16,5 +16,45 @@ "exit": "Eliri", "next": "Sekvanto" }, - "language": "Esperanto" + "language": "Esperanto", + "all_communities": { + "text": "Ĉiuj Komunumoj", + "announcements": "Anoncoj", + "ann_string": "Klaku ĉi tie, por vidi lastatempaj anoncoj!", + "new_communities": "Novaj Komunumoj", + "show_all": "Vidi ĉi tie", + "search": "Serĉi komunumoj...", + "popular_places": "Popularaj Komunumoj" + }, + "community": { + "followers": "Abonantoj", + "following": "Abonanta", + "follow": "Aboni komunumo", + "posts": "Afiŝoj", + "tags": "Etikedoj", + "recent": "Lastatempaj afiŝoj", + "popular": "Popularaj afiŝoj", + "verified": "Kontrolita afiŝoj", + "new": "Nova afiŝo" + }, + "user_page": { + "country": "Lando", + "birthday": "Naskiĝtago", + "game_experience": "Sperto de Ludo", + "posts": "Afiŝoj", + "friends": "Amikoj", + "following": "Abonanta", + "followers": "Abonantoj", + "follow_user": "Aboni", + "following_user": "Abonanta", + "befriend": "Amikiĝi", + "pending": "Atendanta", + "unfriend": "Malamikiĝi", + "no_friends": "Neniu Amikoj", + "no_following": "Ne abonu iun", + "no_followers": "Neniu Abonantoj" + }, + "user_settings": { + "profile_settings": "Agordoj de Profilo" + } } From bedfc9a7871603c4b6e736b251892ee15c971bf6 Mon Sep 17 00:00:00 2001 From: gallegonovato Date: Fri, 26 Jul 2024 12:48:39 +0000 Subject: [PATCH 115/189] locales(update): Updated Spanish locale --- apps/juxtaposition-ui/src/translations/es.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/es.json b/apps/juxtaposition-ui/src/translations/es.json index 7d127eb8..440a5cb6 100644 --- a/apps/juxtaposition-ui/src/translations/es.json +++ b/apps/juxtaposition-ui/src/translations/es.json @@ -56,7 +56,7 @@ }, "user_settings": { "profile_settings": "Preferencias del perfil", - "show_country": "", + "show_country": "Mostrar el país en el perfil", "show_birthday": "Mostrar cumpleaños en tu perfil", "show_game": "Mostrar el nivel como jugador en tu perfil", "show_comment": "Mostrar comentario en tu perfil", From e2c2def71ba969f25fa466fcb3ee7c915ae954a8 Mon Sep 17 00:00:00 2001 From: Susie Caine McPeak Date: Sat, 27 Jul 2024 14:24:24 +0000 Subject: [PATCH 116/189] locales(update): Updated Esperanto locale --- apps/juxtaposition-ui/src/translations/eo.json | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/eo.json b/apps/juxtaposition-ui/src/translations/eo.json index d791f8a7..71c9edb4 100644 --- a/apps/juxtaposition-ui/src/translations/eo.json +++ b/apps/juxtaposition-ui/src/translations/eo.json @@ -50,11 +50,20 @@ "befriend": "Amikiĝi", "pending": "Atendanta", "unfriend": "Malamikiĝi", - "no_friends": "Neniu Amikoj", - "no_following": "Ne abonu iun", - "no_followers": "Neniu Abonantoj" + "no_friends": "Neniu amikoj", + "no_following": "Ne abonas iun", + "no_followers": "Neniu abonantoj" }, "user_settings": { - "profile_settings": "Agordoj de Profilo" + "profile_settings": "Agordoj de Profilo", + "profile_comment": "Komento de Profil", + "show_country": "Montri landon en profilo", + "show_birthday": "Montri naskiĝtagon en profilo", + "show_game": "Montri sperton de ludo en profilo", + "swearing": "La komento devas ne ampleksi maldecan lingvon.", + "show_comment": "Montri komenton en profilo" + }, + "activity_feed": { + "empty": "Ĝi estas malplena ĉi tie. Abonu iu!" } } From 75e2a5efb48cb263006a2b282d468a08056a1748 Mon Sep 17 00:00:00 2001 From: A Dev Date: Wed, 31 Jul 2024 12:52:49 +0000 Subject: [PATCH 117/189] locales(update): Updated Korean locale --- .../juxtaposition-ui/src/translations/ko.json | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/ko.json b/apps/juxtaposition-ui/src/translations/ko.json index 0aa71c1b..7c9d1bc7 100644 --- a/apps/juxtaposition-ui/src/translations/ko.json +++ b/apps/juxtaposition-ui/src/translations/ko.json @@ -8,9 +8,9 @@ "notifications": "알림", "go_back": "뒤로 가기", "back": "뒤로", - "yeahs": "좋아요", - "more": "포스트 더보기", - "no_posts": "포스트 없음", + "yeahs": "당근이지", + "more": "게시물 더보기", + "no_posts": "게시물 없음", "private": "비공개", "close": "닫기", "save": "저장", @@ -21,7 +21,7 @@ "text": "모든 커뮤니티", "announcements": "공지", "ann_string": "여기를 클릭해서 최근 공지를 확인하세요!", - "popular_places": "유명한 곳", + "popular_places": "유명한 커뮤니티", "new_communities": "새로운 커뮤니티", "show_all": "모두 보기", "search": "커뮤니티 검색..." @@ -30,18 +30,18 @@ "follow": "커뮤니티 팔로우", "following": "팔로잉", "followers": "팔로워", - "posts": "포스트", + "posts": "게시물", "tags": "태그", - "recent": "최근 포스트", - "popular": "인기 포스트", - "verified": "인증된 포스트", - "new": "새로운 포스트" + "recent": "최근 게시물", + "popular": "인기 게시물", + "verified": "인증된 게시물", + "new": "새로운 게시물" }, "user_page": { "country": "국가", "birthday": "생년월일", "game_experience": "게임 경험", - "posts": "포스트", + "posts": "게시물", "friends": "친구", "following": "팔로잉", "followers": "팔로워", @@ -71,10 +71,10 @@ "new_follower": "가 당신을 팔로우했습니다!" }, "new_post": { - "new_post_text": "새 포스트", - "post_to": "여기로 게시하기’", - "text_hint": "여기를 눌러서 포스트를 만드세요.", - "swearing": "포스트는 노골적인 단어를 포함할 수 없습니다." + "new_post_text": "새 게시물", + "post_to": "여기로 게시하기", + "text_hint": "여기를 눌러서 게시물을 만드세요.", + "swearing": "게시물에는 노골적인 단어를 포함할 수 없습니다." }, "messages": { "coming_soon": "응 아직 개발 안됨 ㅅㄱ 나중에 다시 와 보세요!" @@ -89,22 +89,22 @@ "third": "이 웹사이트 및 그 소프트웨어, 그 외 모든 컨텐츠는 “있는 그대로” 및 “사용 가능한 상태로” 제공됩니다. Pretendo Network는 어떠한 웹사이트, 소프트웨어 또는 콘텐츠의 적합성 및 유용성에 대해 어떠한 명시적·묵시적 보증도 하지 않습니다." }, "info": "Juxtaposition가 무엇이죠?", - "info_text": "Juxt는 당신이 전 세계의 사람들과 상호작용할 수 있는, 유저에 의해 운영되고 있는\n 게임 커뮤니티입니다. 게임 커뮤니티 내에서 포스트를 작성하거나, 친구에게 직접 메시지를 보낼 수 있습니다.", + "info_text": "유저들이 직접 운영하는 Juxt는 당신이 전 세계의 사람들과 상호 작용할 수 있는\n 게임 커뮤니티입니다. 게임 커뮤니티 내에서 게시물을 작성하거나, 친구에게 직접 메시지를 보낼 수 있습니다.", "rules": "Juxt 규칙", "rules_text": { "first": "이하 내용은 Juxt를 모두가 재미있고 편안한 커뮤니티로 만들 수 있기에 앞서, 중요한 내용들입니다. Juxt 행동 강령에는 각 항목에 대해 보다 자세한 내용이 적혀 있으므로, 참고하며 조심히 읽어 주시기 바랍니다.", - "second": "포스트는 전 세계에서 볼 수 있다", - "third": "Juxt는 전 세계 사람들이 생각을 나눌 수 있는 게임 커뮤니티가 아주 많이 포함되어 있습니다. 커뮤니티에 포스트를 작성할 시, 모두가 볼 수 있다는 것을 잊지 마시고, 모두가 즐길 수 있는 방식으로 표현해 주시기 바랍니다. 상식적인 포스트를 작성해 주시기 바라며, 게시 전에 반드시 다시 한번 더 고려해 주시기 바랍니다. Juxt는 인터넷에서도 액세스가 가능하므로, Juxt를 사용하지 않는 사람들도 당신의 포스트를 볼 수 있다는 사실을 기억해 주시기 바랍니다. 추가적으로, 당신이 친구의 포스트에 단 댓글도 친구 뿐만 아니라, 전 세계의 분들도 열람할 수 있습니다. 마음에 새겨 주시기 바랍니다.", + "second": "게시물은 전 세계에서 볼 수 있습니다", + "third": "Juxt는 전 세계 사람들이 생각을 나눌 수 있는 게임 커뮤니티가 아주 많이 있습니다. 커뮤니티에 게시물을 작성할 시, 모두가 볼 수 있다는 것을 잊지 마시고, 모두가 즐길 수 있는 방식으로 표현해 주시기 바랍니다. 상식적인 게시물들을 작성해 주시기 바라며, 게시 전에 반드시 다시 한번 더 고려해 주시기 바랍니다. Juxt는 인터넷에서도 액세스가 가능하므로, Juxt를 사용하지 않는 사람들도 당신의 게시물를 볼 수 있다는 사실을 기억해 주시기 바랍니다. 추가적으로, 당신이 친구의 게시물에 단 댓글도 친구 뿐만 아니라, 전 세계의 분들도 열람할 수 있습니다. 어떻게 해서든 꼭 기억해주시길 바랍니다.", "fourth": "타인에게 잘 하자", - "fifth": "Juxt를 모두에게 즐거운 곳으로 하기 위해, 당신이 다른 유저들에게 사려 깊게 행동해 주시는 것을 부탁드립니다. 부적절하거나, 공격적인 내용은 게시를 하지 말아 주세요.", - "sixth": "자신이든 타인이든, 개인 정보를 게시하지 말자’", + "fifth": "Juxt를 모두가 다 같이 즐거운 곳으로 만들기 위해서, 다른 사용자들에게 사려 깊게 행동해 주시는 것을 부탁드립니다. 부적절하거나, 공격적인 내용은 게시를 하지 말아 주세요.", + "sixth": "개인정보를 올리지 말자. 내 개인정보여도’", "seventh": "명심해 주세요, Juxt에서 누군가를 아는 것은 실제 생활에서 누군가를 아는 것이랑 전혀 다릅니다. 절대로 메일 주소, 집 주소, 회사 및 학교명, 타 개인 정보를 Juxt의 누구와도 공유하지 마시고, 타인의 정보도 보내지 마시기 바랍니다. 추가적으로, 만약 Juxt에서 만난 누군가가 실제 생활에서 만나자고 했다면, 승탁하지 마세요. Juxt는 온라인 커뮤니티이며, 실제 생활에서의 미팅을 만드는 용도로 쓰이지 말아야 합니다.", - "eighth": "스포일러는 게시하지 말자", - "ninth": "몇몇 사람들은 게임 내 팁 등을 찾으러 Juxt에 오지만, 다른 사람들은 게임 시크릿을 직접 찾고 싶을 겁니다. 게임 내 시크릿이나 스토리를 밝히는 포스트는 \"스포일러\"라고 불립니다. 만약 게임과 관련된, 스포가 될 만한 정보를 게시하려고 하고 있다면, 포스트를 게시하기 전에 스포일러 박스를 체크하는 것을 잊지 마세요. 이렇게 하면, 스포당하고 싶지 않은 사람들은 당신의 포스트를 보지 않을 겁니다.", + "eighth": "스포는 게시하지 말자", + "ninth": "몇몇 사람들은 게임 내 팁 등을 찾으러 Juxt에 오지만, 다른 사람들은 게임의 비밀을 직접 찾고 싶을 겁니다. 게임 내 비밀이나 스토리를 밝히는 게시물을 \"스포일러\"라고 불립니다. 만약 게임과 관련된, 스포가 될 만한 정보를 게시하려고 하고 있다면, 게시물을 게시하기 전에 스포일러 박스를 체크하는 것을 잊지 마세요. 이렇게 하면, 스포당하고 싶지 않은 사람들은 당신의 게시물을 보지 않을 겁니다.", "tenth": "행동 강령 위반", "eleventh": "저희의 목표는 Juxt가 모두가 재미있고 즐길 수 있는 커뮤니티임을 유지하는 것입니다. 만약 누군가가 Juxt 행동 강령을 위반했다면, 저희가 적절하다고 판단한 조치를 취할 것입니다. 잘못하면 그 유저나 콘솔을 차단할 수도 있죠.", "twelfth": "그 게임 해봤어?", - "thirteenth": "만약 당신이 해본 게임의 커뮤니티에 포스트를 작생했을 시, 포스트에 당신이 플레이했다는 아이콘이 뜰 것입니다." + "thirteenth": "만약 당신이 해본 게임의 커뮤니티에 게시물을 작성하면, 작성한 게시물에 이 게임을 플레이 했다는 아이콘이 뜰 것입니다." }, "experience": "게임 경험", "experience_text": { @@ -116,11 +116,11 @@ "google": "Google Analytics", "google_text": "Juxtaposition은 사용자들이 어떻게 저희의 서비스를 활용하고 있는지 트래킹하기 위해 Google Analytics를 사용합니다. 수집하고 있는 데이터는 방문 횟수, 방문 페이지, 사이트에서 보낸 시간 등을 포함합니다. 이 데이터는 당신과 어떠한 연결도 없으며, 저희나 Google의 광고에 쓰이지도 않습니다.", "ready": "Juxt 사용 준비 완료", - "ready_text": "처음으로, 몇몇 커뮤니티를 확인하여, 사람들이 무엇을 게시하고 있는지 보세요. 이번 기회에 Juxt 내 사람들을 숙지하세요. 새로운 발견을 할 수도 있어요!", + "ready_text": "먼저 유명한 커뮤니티부터 찾아보세요! 사람들이 뭘 올리는지 확인하고, 그리고 이번 기회에 사람들이 어떤 걸 하는지 찾아보세요. 새로운 발견이 될 수도 있으니까요!", "done": "Juxt에서 좋은 시간을 보내시기 바랍니다!", "done_button": "가자!", "guest": "게스트 모드", - "guest_text": "현재로서는 당신의 계정을 조회할 수 없으며, 아마 지금 Nintendo Network 계정으로 로그인하고 있다는 것입니다. Juxt를 둘러볼 수는 있지만, Pretendo Network 계정으로 로그인할 때까지 “맞네!“를 달거나 자신의 포스트를 게시할 수는 없습니다. 자세한 정보는 Discord 서버에서 확인하실 수 있습니다.", + "guest_text": "어라? 계정을 확인할 수 없네요. 닌텐도 네트워크로 로그인을 하신 걸 수도 있어요. Juxt를 둘러보실 수는 있지만, '당근이지!'를 게시물에 달거나 게시물을 만드는 것은 Pretendo 네트워크로 로그인하면 Juxt의 모든 기능을 사용하실 수 있어요. 더 많은 정보는 디스코드 서버를 확인해주세요.", "guest_button": "알겠어요" } } From 1c364d32076469eb7fc7db08165353727aa9587e Mon Sep 17 00:00:00 2001 From: Susie Caine McPeak Date: Thu, 1 Aug 2024 04:05:54 +0000 Subject: [PATCH 118/189] locales(update): Updated Esperanto locale --- apps/juxtaposition-ui/src/translations/eo.json | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/apps/juxtaposition-ui/src/translations/eo.json b/apps/juxtaposition-ui/src/translations/eo.json index 71c9edb4..9bb1810c 100644 --- a/apps/juxtaposition-ui/src/translations/eo.json +++ b/apps/juxtaposition-ui/src/translations/eo.json @@ -65,5 +65,15 @@ }, "activity_feed": { "empty": "Ĝi estas malplena ĉi tie. Abonu iu!" + }, + "notifications": { + "none": "Neniu avizoj.", + "new_follower": "abonis vin!" + }, + "new_post": { + "new_post_text": "Novo afiŝo", + "post_to": "Afiŝi al", + "text_hint": "Tuŝu ĉi tie por ke afiŝi.", + "swearing": "La afiŝo devas ne ampleksi maldecan lingvon." } } From 9fcc39f5cd0b8916a13bf8635bd718f2c1856e37 Mon Sep 17 00:00:00 2001 From: Andres Joel Date: Sun, 4 Aug 2024 16:15:24 +0000 Subject: [PATCH 119/189] locales(update): Updated Spanish locale --- apps/juxtaposition-ui/src/translations/es.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/es.json b/apps/juxtaposition-ui/src/translations/es.json index 440a5cb6..6a4c0f6a 100644 --- a/apps/juxtaposition-ui/src/translations/es.json +++ b/apps/juxtaposition-ui/src/translations/es.json @@ -8,7 +8,7 @@ "notifications": "Notificaciones", "go_back": "Volver", "back": "Atrás", - "yeahs": "Ajá", + "yeahs": "\"Mola\" concedidos", "more": "Cargar más publicaciones", "no_posts": "No hay publicaciones", "private": "Privado", From 1249d590a1574149f702e0b974e4f46b6d72272a Mon Sep 17 00:00:00 2001 From: Andres Joel Date: Mon, 5 Aug 2024 03:18:30 +0200 Subject: [PATCH 120/189] locales(add): Added Galician locale --- apps/juxtaposition-ui/src/translations/gl.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/juxtaposition-ui/src/translations/gl.json diff --git a/apps/juxtaposition-ui/src/translations/gl.json b/apps/juxtaposition-ui/src/translations/gl.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/apps/juxtaposition-ui/src/translations/gl.json @@ -0,0 +1 @@ +{} From 0b6a2357ef7d8417ac2708cce9d1e7fe7cb41789 Mon Sep 17 00:00:00 2001 From: Andres Joel Date: Mon, 5 Aug 2024 11:30:01 +0000 Subject: [PATCH 121/189] locales(update): Updated Galician locale --- .../juxtaposition-ui/src/translations/gl.json | 51 ++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/gl.json b/apps/juxtaposition-ui/src/translations/gl.json index 0967ef42..0ae3384a 100644 --- a/apps/juxtaposition-ui/src/translations/gl.json +++ b/apps/juxtaposition-ui/src/translations/gl.json @@ -1 +1,50 @@ -{} +{ + "global": { + "activity_feed": "Rexistro de actividades", + "communities": "Comunidades", + "messages": "Mensaxes", + "notifications": "Notificacións", + "go_back": "Volver", + "back": "De volta", + "private": "Privado", + "close": "Pechar", + "save": "Manteña", + "exit": "Saia", + "next": "Seguindo", + "user_page": "Páxina de usuario", + "yeahs": "Guay", + "more": "Cargar máis publicacións", + "no_posts": "Non hai publicacións" + }, + "all_communities": { + "text": "Todas as comunidades", + "announcements": "Anuncios", + "show_all": "Mostra todo", + "search": "Busca comunidades...", + "ann_string": "Fai clic para ver os últimos anuncios!", + "new_communities": "Novas comunidades", + "popular_places": "Lugares populares" + }, + "community": { + "follow": "Sigue a comunidade", + "following": "Continuar", + "followers": "Seguidores", + "posts": "Publicacións", + "tags": "Etiquetas", + "recent": "Mensaxes recentes", + "popular": "Publicacións populares", + "verified": "Publicacións verificadas", + "new": "Nova publicación" + }, + "user_page": { + "country": "Pais", + "game_experience": "Experiencia de xogo", + "posts": "Publicacións", + "friends": "Amigos", + "following": "Seguindo", + "followers": "Seguidores", + "follow_user": "Segue", + "birthday": "Aniversario" + }, + "language": "Galego" +} From 6d870100548120146c7bbb65f9ebecac33b17f88 Mon Sep 17 00:00:00 2001 From: Hendrik Vanvelk Date: Tue, 13 Aug 2024 21:47:14 +0000 Subject: [PATCH 122/189] locales(update): Updated Esperanto locale --- .../juxtaposition-ui/src/translations/eo.json | 54 +++++++++++-------- 1 file changed, 31 insertions(+), 23 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/eo.json b/apps/juxtaposition-ui/src/translations/eo.json index 9bb1810c..5c1ae2bd 100644 --- a/apps/juxtaposition-ui/src/translations/eo.json +++ b/apps/juxtaposition-ui/src/translations/eo.json @@ -5,11 +5,11 @@ "communities": "Komunumoj", "messages": "Mesaĝoj", "notifications": "Avizoj", - "go_back": "Reveni", - "back": "Malantaŭ", + "go_back": "Reiri", + "back": "Reen", "yeahs": "Ŝatoj", - "more": "Vidigi pli de afiŝojn", - "no_posts": "Neniu afiŝoj", + "more": "Videbligi pli da afiŝoj", + "no_posts": "Neniuj afiŝoj", "private": "Privata", "close": "Fermi", "save": "Konservi", @@ -20,22 +20,22 @@ "all_communities": { "text": "Ĉiuj Komunumoj", "announcements": "Anoncoj", - "ann_string": "Klaku ĉi tie, por vidi lastatempaj anoncoj!", + "ann_string": "Klaku ĉi tie, por vidi lastatempajn anoncojn!", "new_communities": "Novaj Komunumoj", - "show_all": "Vidi ĉi tie", - "search": "Serĉi komunumoj...", + "show_all": "Montri Ĉiun", + "search": "Serĉi Komunumojn...", "popular_places": "Popularaj Komunumoj" }, "community": { "followers": "Abonantoj", "following": "Abonanta", - "follow": "Aboni komunumo", + "follow": "Aboni Komunumon", "posts": "Afiŝoj", "tags": "Etikedoj", - "recent": "Lastatempaj afiŝoj", - "popular": "Popularaj afiŝoj", - "verified": "Kontrolita afiŝoj", - "new": "Nova afiŝo" + "recent": "Lastatempaj Afiŝoj", + "popular": "Popularaj Afiŝoj", + "verified": "Kontrolitaj Afiŝoj", + "new": "Nova Afiŝo" }, "user_page": { "country": "Lando", @@ -50,30 +50,38 @@ "befriend": "Amikiĝi", "pending": "Atendanta", "unfriend": "Malamikiĝi", - "no_friends": "Neniu amikoj", - "no_following": "Ne abonas iun", - "no_followers": "Neniu abonantoj" + "no_friends": "Neniuj Amikoj", + "no_following": "Ne Abonas Iun", + "no_followers": "Neniuj Abonantoj" }, "user_settings": { "profile_settings": "Agordoj de Profilo", - "profile_comment": "Komento de Profil", - "show_country": "Montri landon en profilo", - "show_birthday": "Montri naskiĝtagon en profilo", - "show_game": "Montri sperton de ludo en profilo", + "profile_comment": "Komento de Profilo", + "show_country": "Montri Landon en Profilo", + "show_birthday": "Montri Naskiĝtagon en Profilo", + "show_game": "Montri Sperton de Ludo en Profilo", "swearing": "La komento devas ne ampleksi maldecan lingvon.", "show_comment": "Montri komenton en profilo" }, "activity_feed": { - "empty": "Ĝi estas malplena ĉi tie. Abonu iu!" + "empty": "Estas malplena ĉi tie. Abonu iun!" }, "notifications": { - "none": "Neniu avizoj.", + "none": "Neniuj avizoj.", "new_follower": "abonis vin!" }, "new_post": { - "new_post_text": "Novo afiŝo", + "new_post_text": "Novo Afiŝo", "post_to": "Afiŝi al", - "text_hint": "Tuŝu ĉi tie por ke afiŝi.", + "text_hint": "Tuŝu ĉi tie por afiŝi.", "swearing": "La afiŝo devas ne ampleksi maldecan lingvon." + }, + "messages": { + "coming_soon": "Mesaĝoj ankoraŭ ne estas disponeblaj. Baldaŭ revenu!" + }, + "setup": { + "welcome": "Bonvenu en Juxtaposition!", + "beta": "Beta-disklerigo", + "welcome_text": "Juxt estas videoludado-komunumo kuniganta homojn el ĉiuj partoj de la mondo per Mii-figuroj. Uzu Juxt por diskonigi viajn ludadospertojn kaj renkontiĝi homojn el ĉiu angulo de la mondo." } } From 6ac9e50a2e146adf291506a3e9b25935e1b71ae1 Mon Sep 17 00:00:00 2001 From: Hendrik Vanvelk Date: Tue, 13 Aug 2024 22:59:09 +0000 Subject: [PATCH 123/189] locales(update): Updated Esperanto locale --- apps/juxtaposition-ui/src/translations/eo.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/eo.json b/apps/juxtaposition-ui/src/translations/eo.json index 5c1ae2bd..b308f55b 100644 --- a/apps/juxtaposition-ui/src/translations/eo.json +++ b/apps/juxtaposition-ui/src/translations/eo.json @@ -82,6 +82,10 @@ "setup": { "welcome": "Bonvenu en Juxtaposition!", "beta": "Beta-disklerigo", - "welcome_text": "Juxt estas videoludado-komunumo kuniganta homojn el ĉiuj partoj de la mondo per Mii-figuroj. Uzu Juxt por diskonigi viajn ludadospertojn kaj renkontiĝi homojn el ĉiu angulo de la mondo." + "welcome_text": "Juxt estas videoludado-komunumo kuniganta homojn el ĉiuj partoj de la mondo per Mii-figuroj. Uzu Juxt por diskonigi viajn ludadospertojn kaj renkontiĝi homojn el ĉiu angulo de la mondo.", + "beta_text": { + "first": "Vi tuj provas unuan publikan beton de Juxt. Tio signifas ke multe ankoraŭ ne estas klara, kaj iam ajn multe povas ŝanĝiĝi.", + "second": "Tio povas enteni totalan forviŝon de la datenbankon je la konludo de, aŭ dum la betoperiodo." + } } } From 6ee0fdb11a7d13011e43cbe1dbe4cafca5348929 Mon Sep 17 00:00:00 2001 From: Hendrik Vanvelk Date: Wed, 14 Aug 2024 10:50:22 +0000 Subject: [PATCH 124/189] locales(update): Updated Dutch locale --- .../juxtaposition-ui/src/translations/nl.json | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/nl.json b/apps/juxtaposition-ui/src/translations/nl.json index 54598ed6..a2b61797 100644 --- a/apps/juxtaposition-ui/src/translations/nl.json +++ b/apps/juxtaposition-ui/src/translations/nl.json @@ -2,13 +2,13 @@ "language": "Nederlands", "global": { "user_page": "Gebruikerspagina", - "activity_feed": "Activiteitenfeed", - "communities": "Gemeenschappen", + "activity_feed": "Overzicht", + "communities": "Community's", "messages": "Berichten", "notifications": "Notificaties", "go_back": "Ga Terug", "back": "Terug", - "yeahs": "Ja", + "yeahs": "Ja's", "more": "Laad Meer Posts", "no_posts": "Geen Posts", "private": "Privé", @@ -18,13 +18,13 @@ "next": "Volgende" }, "all_communities": { - "text": "Alle Communities", + "text": "Alle Community's", "announcements": "Aankondigingen", "ann_string": "Klik hier om recente aankondigen te bekijken!", - "popular_places": "Populaire Communities", - "new_communities": "Nieuwe Communities", + "popular_places": "Populaire Community's", + "new_communities": "Nieuwe Community's", "show_all": "Alles weergeven", - "search": "Zoek communities..." + "search": "Zoek community's..." }, "community": { "follow": "Volg Community", @@ -40,34 +40,34 @@ "user_page": { "country": "Land", "birthday": "Verjaardag", - "game_experience": "Game Ervaring", + "game_experience": "Game-ervaring", "posts": "Posts", "friends": "Vrienden", - "following": "Volgend", + "following": "Gevolgde gebruikers", "followers": "Volgers", - "follow_user": "Volg", + "follow_user": "Volgen", "following_user": "Volgend", "befriend": "Bevriend", "pending": "Wachtend", "unfriend": "Ontvriend", "no_friends": "Geen vrienden", - "no_following": "Volgt niemand", - "no_followers": "Geen volgers" + "no_following": "Volgt Niemand", + "no_followers": "Geen Volgers" }, "user_settings": { - "profile_settings": "Profiel instellingen", + "profile_settings": "Profielinstellingen", "show_country": "Geef Land op Profiel weer", "show_birthday": "Geef Verjaardag op Profiel weer", - "show_game": "Geef Game Ervaring op Profiel weer", + "show_game": "Geef Game-ervaring op Profiel weer", "show_comment": "Geef Omschrijving op Profiel weer", - "profile_comment": "Profiel Omschrijving", - "swearing": "Profiel omschrijving kan geen expliciete tekst bevatten." + "profile_comment": "Profielomschrijving", + "swearing": "Profielomschrijving kan geen expliciete tekst bevatten." }, "activity_feed": { "empty": "Het is eenzaam hier. Probeer iemand te volgen!" }, "notifications": { - "none": "Geen notificaties.", + "none": "Geen meldingen.", "new_follower": "volgt jou nu!" }, "new_post": { @@ -86,7 +86,7 @@ "beta_text": { "first": "Je staat op het punt de eerste publieke beta van Juxt te gebruiken. Dit betekent dat veel onzeker is en ook van alles kan veranderen.", "second": "Dit kan mogelijk een volledige reset van de database aan het einde van de beta periode of tijdens deze periode omvatten.", - "third": "De website, de software die het bevat, alsook alle content dat te vinden is op deze website, worden geleverd op een \"as is\" en \"as available\" basis. Pretendo Network geeft geen garantstellingen, ofwel expliciet ofwel impliciet, met betrekking tot de geschiktheid of bruikbaarheid van de website, de software die het bevat of de content op de website." + "third": "De website, de software die het bevat, alsook alle content die te vinden is op deze website, worden geleverd op een \"as is\" en \"as available\" basis. Pretendo Network geeft geen garantstellingen, ofwel expliciet ofwel impliciet, met betrekking tot de geschiktheid of bruikbaarheid van de website, de software die het bevat of de content op de website." }, "info": "Wat is Juxtaposition?", "info_text": "Juxt is een gebruikers-gedreven gaming community waar je kan communiceren met mensen\n over de hele wereld. Je kan posts schrijven of tekenen in game communities of berichten rechtstreeks naar je vrienden sturen.", @@ -94,10 +94,10 @@ "rules_text": { "first": "De volgende tekst bevat belangrijke richtlijnen om Juxt een leuke en gezellige omgeving voor iedereen te maken. De Juxt gedragscode bevat belangrijke gedetailleerde informatie, dus lees het aandachtig door.", "second": "Posts Kunnen Overal Ter Wereld Bekeken Worden", - "third": "Juxt bevat vele gaming communities waar mensen over de hele wereld hun gedachten kunnen delen. Als je in een community post, onthoud dan dat iedereen dit kan zien, dus uit je alsjeblieft op een manier die voor iedereen prettig is. Gebruik je gezonde verstand en denk eerst na voor je iets post. Juxt is daarnaast ook een dienst welk bereikbaar is via het internet, dus houd rekening met het feit dat mensen die Juxt niet gebruiken ook je posts mogelijk kunnen zien. Daarnaast zijn reacties die je maakt op posts van je vrienden niet alleen zichtbaar voor je vrienden, maar ook voor mensen over de hele wereld. Houd hier rekening mee.", + "third": "Juxt bevat vele gaming community's waar mensen over de hele wereld hun gedachten kunnen delen. Als je in een community post, onthoud dan dat iedereen dit kan zien, dus uit je alsjeblieft op een manier die voor iedereen prettig is. Gebruik je gezonde verstand en denk eerst na voor je iets post. Juxt is daarnaast ook een dienst die bereikbaar is via het internet, dus houd rekening met het feit dat mensen die Juxt niet gebruiken ook je posts mogelijk kunnen zien. Daarnaast zijn reacties die je maakt op posts van je vrienden niet alleen zichtbaar voor je vrienden, maar ook voor mensen over de hele wereld. Houd hier rekening mee.", "fourth": "Wees Aardig Tegen Elkaar", "fifth": "Om Juxt een leuke omgeving voor iedereen te houden vragen wij van jou om rekening te houden met anderen. Help ons om Juxt zo leuk mogelijk te houden door niets ongepasts of beledigend te posten.", - "sixth": "Post Geen Persoonlijke Gegevens—Die van Jezelf of Van Anderen", + "sixth": "Post Geen Persoonlijke Gegevens—Die van Jezelf of van Anderen", "seventh": "Onthoud, iemand in Juxt kennen is niet hetzelfde als iemand in het echt kennen. Deel nooit je e-mail adres, huisadres, de naam van je school of werk of wat voor een persoonlijke identificeerbare informatie dan ook met een ander en deel ook geen van deze gegevens van iemand anders. Daarnaast, als iemand die je ontmoet hebt op Juxt je vraagt om diegene in het echt te ontmoeten, accepteer dit niet. Juxt is een online community en moet niet gebruikt worden om ontmoetingen in het echt te faciliteren.", "eighth": "Post Geen Spoilers", "ninth": "Sommige mensen komen naar Juxt voor tips en trucs voor games, anderen willen zelf de geheimen van een game ontdekken. Berichten die geheimen van een game of het verhaal ervan onthullen, worden 'spoilers' genoemd. Als je iets post over een game dat een spoiler zou kunnen zijn, zorg er dan voor dat je het vakje Spoilers aanvinkt voordat je je post verstuurt. Zo zien mensen die geen spoilers willen zien je bericht niet.", @@ -106,7 +106,7 @@ "twelfth": "Heb Je Dat Spel Gespeeld?", "thirteenth": "Als je post in een community voor een game welk je hebt gespeeld, bevat je post een icoontje dat aangeeft dat je deze game hebt gespeeld." }, - "experience": "Game Ervaring", + "experience": "Game-ervaring", "experience_text": { "info": "Vertel ons alstublieft hoe u uw ervaringsniveau met games zou omschrijven. U kunt deze instelling later wijzigen.", "beginner": "Beginner", @@ -116,10 +116,10 @@ "google": "Google Analytics", "google_text": "Juxtaposition gebruikt Google Analytics om bij te houden hoe gebruikers onze dienst gebruiken. De data die we verzamelen bevat onder andere tijd van bezoek, bezochte pagina's en hoe lang het bezoek duurde. Deze data is op geen enkele manier gekoppeld aan jou en wordt niet gebruikt door Google of ons om advertenties aan jou te tonen.", "ready": "Klaar om Juxt te Gebruiken", - "ready_text": "Bekijk allereerst wat communities en zie waar mensen van over de hele wereld over posten. Gebruik deze kans om je bekend te maken met Juxt. Mogelijk ontdek je iets nieuws op deze manier!", + "ready_text": "Bekijk allereerst wat community's en zie waar mensen van over de hele wereld over posten. Gebruik deze kans om je bekend te maken met Juxt. Mogelijk ontdek je iets nieuws op deze manier!", "done": "Veel plezier in Juxt!", "done_button": "Laten We Beginnen!", - "guest": "Gast Modus", + "guest": "Gastmodus", "guest_text": "We kunnen momenteel jouw account niet verifiëren, dit betekent waarschijnlijk dat je probeert in te loggen met een Nintendo Network account. Je kan nog steeds Juxt bezoeken, maar je kan posts geen Ja! geven. Daarnaast kan je geen posts maken totdat je inlogt met een Pretendo Network account. Bezoek de Discord server voor meer informatie.", "guest_button": "Begrepen" } From 90d770280a4ed0ecc393dc1c403258be89e4db1a Mon Sep 17 00:00:00 2001 From: Kaoru Isamu Date: Wed, 14 Aug 2024 10:24:09 +0000 Subject: [PATCH 125/189] locales(update): Updated Dutch locale --- apps/juxtaposition-ui/src/translations/nl.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/nl.json b/apps/juxtaposition-ui/src/translations/nl.json index a2b61797..2eed4d06 100644 --- a/apps/juxtaposition-ui/src/translations/nl.json +++ b/apps/juxtaposition-ui/src/translations/nl.json @@ -5,7 +5,7 @@ "activity_feed": "Overzicht", "communities": "Community's", "messages": "Berichten", - "notifications": "Notificaties", + "notifications": "Meldingen", "go_back": "Ga Terug", "back": "Terug", "yeahs": "Ja's", From 076f6a8408a0fb3f71526d03deb89b6f8ca5a5a6 Mon Sep 17 00:00:00 2001 From: Hendrik Vanvelk Date: Wed, 14 Aug 2024 10:07:05 +0000 Subject: [PATCH 126/189] locales(update): Updated Esperanto locale --- apps/juxtaposition-ui/src/translations/eo.json | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/eo.json b/apps/juxtaposition-ui/src/translations/eo.json index b308f55b..b39e6389 100644 --- a/apps/juxtaposition-ui/src/translations/eo.json +++ b/apps/juxtaposition-ui/src/translations/eo.json @@ -85,7 +85,19 @@ "welcome_text": "Juxt estas videoludado-komunumo kuniganta homojn el ĉiuj partoj de la mondo per Mii-figuroj. Uzu Juxt por diskonigi viajn ludadospertojn kaj renkontiĝi homojn el ĉiu angulo de la mondo.", "beta_text": { "first": "Vi tuj provas unuan publikan beton de Juxt. Tio signifas ke multe ankoraŭ ne estas klara, kaj iam ajn multe povas ŝanĝiĝi.", - "second": "Tio povas enteni totalan forviŝon de la datenbankon je la konludo de, aŭ dum la betoperiodo." - } + "second": "Tio povas enteni totalan forviŝon de la datenbankon je la konludo de, aŭ dum la betoperiodo.", + "third": "La retejo, ĝia programaro kaj ĉiom da ĝia enhavo proviziĝas kiel ili estas kaj laŭ havebleco. La Pretendo-reto donas neniajn garantiojn, nek eksplicitajn nek implicitajn, pri la taŭgeco aŭ uzebleco de la retejo, ĝia programaro aŭ iom da ĝia enhavo." + }, + "rules_text": { + "third": "Juxt enhavas multajn videoludokomunumojn kie homoj de la tuta mondo povas dividi siajn pensojn. Afiŝante en komunumo, memoru ke ĉiu povas vidi ĝin, do bonvolu esprimi vin kiel ĉiu povas ĝui ĝin. Prudente agu, kaj pensu antaŭ ol vi afiŝas. Juxt estas medio ankaŭ disponebla per la Interreto, do konsideru ke neuzantoj de Juxt ankaŭ povus vidi viajn afiŝojn. Krome ĉiujn komentojn faritajn sub la afiŝoj de viaj amikoj ne nur viaj amikoj, sed ankaŭ homoj tra mondo vidos. Bonvolu pripensi ĉi tion.", + "second": "Afiŝoj Estas Videblaj Tra la Mondo", + "first": "Sekvante kelkaj gravaj gvidlinioj por ke Juxt estu amuza kaj ĝuable sperto por ĉiuj. La kodo de konduto de Juxt enhavas detalajn informojn, do bonvolu diligente legi.", + "fourth": "Estu Agrabla Unu al la Alia", + "fifth": "Por ke Juxt restu agrabla loko por ĉiu, ni petas ke vi estu konsiderema al aliaj uzantoj. Asistu nin restigi Juxt agrablan sperton per afiŝi nek maldecaĵojn nek ofendaĵojn.", + "sixth": "Ne afiŝu privataj informoj, nek viaj, nek alies" + }, + "info": "Kio estas Juxtaposition?", + "info_text": "Juxt estas uzantobazita videoludokomunumo kie oni povas interagi kun homoj\n de la tuta mondo. Oni povas skribi aŭ desegni afiŝojn en videoludokomunumoj aŭ rekte mesaĝi al viaj amikoj.", + "rules": "reguloj de Juxt" } } From 0c0b0fd79df2074d1a9d8d215e606c7c717cebcd Mon Sep 17 00:00:00 2001 From: Marius P Date: Thu, 15 Aug 2024 16:01:56 +0000 Subject: [PATCH 127/189] locales(update): Updated Lithuanian locale --- apps/juxtaposition-ui/src/translations/lt.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/lt.json b/apps/juxtaposition-ui/src/translations/lt.json index 287e1c0d..48767b7d 100644 --- a/apps/juxtaposition-ui/src/translations/lt.json +++ b/apps/juxtaposition-ui/src/translations/lt.json @@ -4,7 +4,7 @@ "notifications": "Pranešimai", "communities": "Bendruomenės", "messages": "Žinutės", - "go_back": "Sugryšti", + "go_back": "Sugrįžti", "exit": "Išeiti", "user_page": "Vartotojo puslapis", "more": "Užkrauti daugiau įkelimų", @@ -12,7 +12,7 @@ "close": "Uždaryti", "save": "Išsaugoti", "activity_feed": "Įrašų puslapis", - "private": "Privati", + "private": "Privatus", "yeahs": "Patiktukai", "next": "Toliau" }, @@ -35,7 +35,7 @@ "popular": "Populiarus įkelimai", "new": "Naujas įkelimas", "recent": "Naujausi įkelimai", - "verified": "Verifikuoti įkelimai" + "verified": "Patvirtinti įkėlimai" }, "user_page": { "country": "Šalis", @@ -83,9 +83,9 @@ "welcome": "Sveiki atvykę į Juxtaposition!", "beta": "Įspėjimas dėl Beta versijos", "beta_text": { - "first": "Tu tuoj išbandysi pirmają Juxt beta versiją. Tai reiškia kad, dalykai gali pasikeisti betkuriuo metu kai tu naudojant Juxt.", - "second": "Tai gali apimti visišką databazės išvalymą betos pabaigoje arba perijodo metu.", - "third": "Svetainė, jos programinis turinys, ir visas čia rastas turinys yra paduota \"kaip yra\" ir \"kaip pasiekiama\".Pretendo tinklas nesuteikia jokių tiesioginių ar numanomų garantijų dėl svetainės, jos programinės įrangos ar bet kokio turinio tinkamumo ar tinkamumo naudoti." + "first": "Tu tuoj išbandysi pirmają Juxt beta versiją. Tai reiškia kad, dalykai gali pasikeisti betkuriuo metu.", + "second": "Tai gali apimti visišką duomenų bazės išvalymą Betos stafijos pabaigoje arba periodo metu.", + "third": "Svetainė, jos programinis turinys, ir visas čia rastas turinys yra paduota \"kaip yra\" ir \"kaip pasiekiama\". Pretendo tinklas nesuteikia jokių tiesioginių ar numanomų garantijų dėl svetainės, jos programinės įrangos ar bet kokio turinio tinkamumo ar tinkamumo naudoti." }, "info": "Kas yra Juxtaposition?", "rules_text": { From dfe675141f78fc7df4d5941b2781d5e7d85a624d Mon Sep 17 00:00:00 2001 From: Rudinn Date: Thu, 15 Aug 2024 23:30:17 +0000 Subject: [PATCH 128/189] locales(update): Updated Kazakh locale --- apps/juxtaposition-ui/src/translations/kk.json | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/apps/juxtaposition-ui/src/translations/kk.json b/apps/juxtaposition-ui/src/translations/kk.json index 7d21ca3b..96ca7c61 100644 --- a/apps/juxtaposition-ui/src/translations/kk.json +++ b/apps/juxtaposition-ui/src/translations/kk.json @@ -39,5 +39,16 @@ }, "user_page": { "country": "Ел" + }, + "setup": { + "experience_text": { + "info": "Ойындар бойынша тәжірибе деңгейіңізді қалай сипаттайтыныңызды айтыңыз. Бұл параметрді кейінірек өзгертуге болады.", + "intermediate": "Орташа" + }, + "google": "Google Analytics", + "rules_text": { + "eighth": "Спойлер жазбаңыз" + }, + "ready": "Juxt пайдалануды бастауға дайын" } } From a4bf4d83176b2162f0df07079d39586da1c7c9b1 Mon Sep 17 00:00:00 2001 From: Rudinn Date: Thu, 15 Aug 2024 23:30:34 +0000 Subject: [PATCH 129/189] locales(update): Updated Belarusian locale --- apps/juxtaposition-ui/src/translations/be.json | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/be.json b/apps/juxtaposition-ui/src/translations/be.json index 5b86e3d0..0f28522f 100644 --- a/apps/juxtaposition-ui/src/translations/be.json +++ b/apps/juxtaposition-ui/src/translations/be.json @@ -49,5 +49,16 @@ "befriend": "Сябраваць", "pending": "Дапытлівы" }, - "language": "Беларуская" + "language": "Беларуская", + "setup": { + "experience_text": { + "beginner": "Пачатковец", + "expert": "Эксперт" + }, + "rules_text": { + "tenth": "Парушэнні Кодэкса паводзін", + "thirteenth": "Калі вы размяшчаеце паведамленні ў суполцы аб гульні, у якую вы гулялі, вашы паведамленні будуць мець значок, які паказвае, што вы ў яе гулялі." + }, + "experience": "Вопыт гульні" + } } From e41fc9af78fc56c1c42b932ced5219bae6240fda Mon Sep 17 00:00:00 2001 From: Rudinn Date: Thu, 15 Aug 2024 23:37:05 +0000 Subject: [PATCH 130/189] locales(update): Updated Slovak locale --- .../juxtaposition-ui/src/translations/sk.json | 67 ++++++++++++++++--- 1 file changed, 58 insertions(+), 9 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/sk.json b/apps/juxtaposition-ui/src/translations/sk.json index 0768a82a..cd75332b 100644 --- a/apps/juxtaposition-ui/src/translations/sk.json +++ b/apps/juxtaposition-ui/src/translations/sk.json @@ -9,7 +9,12 @@ "exit": "Ukončiť", "next": "Ďalší", "no_posts": "Žiadne príspevky", - "messages": "Správy" + "messages": "Správy", + "user_page": "Používateľská stránka", + "activity_feed": "Informačný kanál aktivity", + "go_back": "Choď späť", + "back": "Späť", + "more": "Načítať ďalšie príspevky" }, "community": { "following": "Odoberané", @@ -19,7 +24,8 @@ "popular": "Populárne príspevky", "verified": "Overené príspevky", "new": "Nové príspevky", - "follow": "Odoberané komunity" + "follow": "Odoberané komunity", + "tags": "Tagy" }, "user_page": { "country": "Krajina", @@ -32,18 +38,29 @@ "no_friends": "Žiadny priatelia", "posts": "Príspevky", "birthday": "Dátum narodenia", - "no_followers": "Žiadni odoberatelia" + "no_followers": "Žiadni odoberatelia", + "game_experience": "Herný zážitok", + "befriend": "Spriateliť sa", + "pending": "Čaká na spracovanie", + "no_following": "Nikoho nesledujem" }, "all_communities": { "text": "Všetky komunity", "popular_places": "Populárne miesta", "show_all": "Ukázať všetky", - "new_communities": "Nové komunity" + "new_communities": "Nové komunity", + "announcements": "Oznamy", + "ann_string": "Kliknutím sem zobrazíte najnovšie oznámenia!", + "search": "Hľadať komunity..." }, "user_settings": { "profile_settings": "Nastavenia profilu", "show_country": "Ukázať krajinu na profile", - "show_birthday": "Ukázať dátum narodenia na profile" + "show_birthday": "Ukázať dátum narodenia na profile", + "show_game": "Zobraziť herný zážitok na profile", + "show_comment": "Zobraziť komentár k profilu", + "profile_comment": "Komentár k profilu", + "swearing": "Komentár profilu nemôže obsahovať explicitné výrazy." }, "notifications": { "new_follower": "vás odoberá!", @@ -52,25 +69,57 @@ "new_post": { "text_hint": "Ťuknite sem na vytvorenie príspevku.", "swearing": "Príspevok nemôže obsahovať nadávky.", - "new_post_text": "Nový príspevok" + "new_post_text": "Nový príspevok", + "post_to": "Uverejniť na" }, "setup": { "welcome": "Vitajte v Juxtaposition!", "info": "Čo je Juxtaposition?", "rules": "Pravidlá Juxta", "rules_text": { - "eighth": "Neposielajte spoilery" + "eighth": "Neposielajte spoilery", + "third": "Juxt obsahuje mnoho herných komunít, kde môžu ľudia z celého sveta zdieľať svoje myšlienky. Keď uverejňujete príspevok v komunite, pamätajte na to, že ho môže vidieť každý, preto sa prosím vyjadrite spôsobom, ktorý bude baviť každého. Použite zdravý rozum a premýšľajte skôr, ako uverejníte príspevok. Juxt je služba, ktorá je dostupná aj z internetu, takže majte na pamäti, že vaše príspevky môžu vidieť aj ľudia, ktorí nepoužívajú Juxt. Navyše, všetky komentáre, ktoré pridáte k príspevkom svojich priateľov, uvidia nielen vaši priatelia, ale aj ľudia na celom svete. Majte to prosím na pamäti.", + "seventh": "Pamätajte, že poznať niekoho v Juxte nie je to isté ako poznať ho v skutočnom živote. Nikdy nezdieľajte svoju e-mailovú adresu, domácu adresu, meno do práce alebo školy ani iné osobné identifikačné údaje s nikým na Juxt a nikdy nezdieľajte informácie nikoho iného. Navyše, ak vás niekto, koho stretnete v Juxte, pozve, aby ste sa s ním stretli v skutočnom svete, neprijmite ho. Juxt je online komunita a nemala by sa používať na organizovanie stretnutí v reálnom svete.", + "ninth": "Niektorí ľudia prichádzajú do Juxtu hľadať tipy a triky pre hry, no iní chcú objaviť tajomstvá hry úplne sami. Príspevky, ktoré odhaľujú tajomstvá hry alebo jej príbeh, sa nazývajú „spoilery“. Ak uverejňujete niečo o hre, ktorá by mohla byť spoilerom, pred odoslaním príspevku nezabudnite zaškrtnúť políčko Spoilers. Týmto spôsobom ľudia, ktorí nechcú byť rozmaznaní, neuvidia váš príspevok.", + "first": "Nasleduje niekoľko dôležitých pokynov na to, aby bol Juxt zábavný a príjemný pre každého. Etický kódex Juxt obsahuje podrobné informácie, preto si ho pozorne prečítajte.", + "second": "Príspevky je možné prezerať po celom svete", + "fourth": "Buďte k sebe milí", + "fifth": "Aby bol Juxt zábavným miestom pre každého, žiadame vás, aby ste boli ohľaduplní k ostatným používateľom. Pomôžte nám udržať Juxt príjemný zážitok tým, že nebudete uverejňovať nič nevhodné alebo urážlivé.", + "sixth": "Neuverejňujte osobné informácie – vaše alebo iných", + "tenth": "Porušenie kódexu správania", + "eleventh": "Naším cieľom je, aby bol Juxt zábavný a príjemný pre každého. V prípade, že niekto poruší Etický kódex Juxt, podnikneme príslušné kroky, vrátane zablokovania porušujúceho používateľa alebo konzoly.", + "twelfth": "Hrali ste túto hru?", + "thirteenth": "Ak uverejňujete príspevok v komunite pre hru, ktorú ste hrali, vaše príspevky budú mať ikonu označujúcu, že ste ju hrali." }, "experience_text": { "beginner": "Začiatočník", - "expert": "Expert" + "expert": "Expert", + "info": "Povedzte nám, ako by ste opísali úroveň svojich skúseností s hrami. Toto nastavenie môžete neskôr zmeniť.", + "intermediate": "Stredne pokročilý" }, "guest_button": "Rozumiem", "ready": "Pripavený začať používať Juxt", "done_button": "Poďme do toho!", - "guest": "Režim návštevníka" + "guest": "Režim návštevníka", + "beta_text": { + "first": "Chystáte sa vyskúšať prvú verejnú beta verziu Juxtu. To znamená, že veľa je stále vo vzduchu a veľa sa môže kedykoľvek zmeniť.", + "third": "Webová lokalita, jej softvér a všetok obsah, ktorý sa na nej nachádza, sú poskytované „tak ako sú“ a „ako sú dostupné“. Sieť Pretendo neposkytuje žiadne záruky, či už výslovné alebo predpokladané, pokiaľ ide o vhodnosť alebo použiteľnosť webovej stránky, jej softvéru alebo akéhokoľvek obsahu.", + "second": "To môže a môže zahŕňať úplné vymazanie databázy na konci alebo počas beta obdobia." + }, + "welcome_text": "Juxt je herná komunita, ktorá spája ľudí z celého sveta pomocou postavičiek Mii. Pomocou Juxt môžete zdieľať svoje herné zážitky a stretnúť sa s ľuďmi z celého sveta.", + "beta": "Vyhlásenie beta verzie", + "info_text": "Juxt je herná komunita riadená používateľmi, kde môžete komunikovať s ľuďmi\n po celom svete. Môžete písať alebo kresliť príspevky v herných komunitách alebo posielať správy priamo svojim priateľom.", + "ready_text": "Najprv si pozrite niektoré komunity a zistite, o čom píšu ľudia z celého sveta. Využite túto príležitosť a zoznámte sa s Juxtom. Na ceste môžete urobiť nejaké nové objavy!", + "experience": "Herný zážitok", + "google": "Google Analytics", + "google_text": "Juxtaposition používa Google Analytics na sledovanie toho, ako používatelia používajú našu službu. Zhromaždené údaje zahŕňajú, ale nie sú obmedzené na čas návštevy, navštívené stránky a čas strávený na stránke. Tieto údaje sa k vám žiadnym spôsobom nepripájajú a nepoužívajú sa ani my, ani spoločnosť Google.", + "done": "Bavte sa v Juxte!", + "guest_text": "Momentálne nemôžeme overiť váš účet, čo pravdepodobne znamená, že sa momentálne prihlasujete pomocou účtu Nintendo Network. Stále budete môcť prehliadať Juxt, ale nebudete môcť Áno! príspevky alebo vytvorte vlastné príspevky, kým sa neprihlásite pomocou účtu Pretendo Network. Pre viac informácií skontrolujte Discord server." }, "activity_feed": { "empty": "Je to tu prázdne. Skúste niekoho odoberať!" + }, + "messages": { + "coming_soon": "Správy ešte nie sú pripravené. Vráťte sa sem čoskoro!" } } From 669d6dcb5a94e7b084e6446c7e1acb65a5bd0534 Mon Sep 17 00:00:00 2001 From: Rudinn Date: Thu, 15 Aug 2024 23:32:29 +0000 Subject: [PATCH 131/189] locales(update): Updated Esperanto locale --- apps/juxtaposition-ui/src/translations/eo.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/eo.json b/apps/juxtaposition-ui/src/translations/eo.json index b39e6389..ad678dee 100644 --- a/apps/juxtaposition-ui/src/translations/eo.json +++ b/apps/juxtaposition-ui/src/translations/eo.json @@ -94,10 +94,12 @@ "first": "Sekvante kelkaj gravaj gvidlinioj por ke Juxt estu amuza kaj ĝuable sperto por ĉiuj. La kodo de konduto de Juxt enhavas detalajn informojn, do bonvolu diligente legi.", "fourth": "Estu Agrabla Unu al la Alia", "fifth": "Por ke Juxt restu agrabla loko por ĉiu, ni petas ke vi estu konsiderema al aliaj uzantoj. Asistu nin restigi Juxt agrablan sperton per afiŝi nek maldecaĵojn nek ofendaĵojn.", - "sixth": "Ne afiŝu privataj informoj, nek viaj, nek alies" + "sixth": "Ne afiŝu privataj informoj, nek viaj, nek alies", + "ninth": "Kelkaj homoj venas al Juxt serĉante konsilojn kaj lertaĵojn por ludoj, sed aliaj volas malkovri la sekretojn de ludo tute memstare. Afiŝoj kiuj rivelas sekretojn de ludo aŭ ĝia rakonto estas nomitaj \"spoilers\". Se vi afiŝas ion pri ludo, kiu povus esti spoiler, nepre kontrolu la skatolon Spoilers antaŭ sendi vian afiŝon. Tiel homoj, kiuj ne volas esti difektitaj, ne vidos vian afiŝon." }, "info": "Kio estas Juxtaposition?", "info_text": "Juxt estas uzantobazita videoludokomunumo kie oni povas interagi kun homoj\n de la tuta mondo. Oni povas skribi aŭ desegni afiŝojn en videoludokomunumoj aŭ rekte mesaĝi al viaj amikoj.", - "rules": "reguloj de Juxt" + "rules": "reguloj de Juxt", + "google_text": "Juntapozicio uzas Google Analytics por spuri kiel uzantoj uzas nian servon. La datumoj kolektitaj inkluzivas sed ne estas limigitaj al tempo de vizito, paĝoj vizititaj kaj tempo pasigita en la retejo. Ĉi tiuj datumoj neniel estas ligitaj al vi, kaj ne estas uzataj por reklamoj de ni aŭ Guglo." } } From e61b18ddaa4904e83da25d3225709edcb9af314e Mon Sep 17 00:00:00 2001 From: Hendrik Vanvelk Date: Sun, 18 Aug 2024 23:01:35 +0000 Subject: [PATCH 132/189] locales(update): Updated Esperanto locale --- .../juxtaposition-ui/src/translations/eo.json | 41 ++++++++++++++----- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/eo.json b/apps/juxtaposition-ui/src/translations/eo.json index ad678dee..25208f4e 100644 --- a/apps/juxtaposition-ui/src/translations/eo.json +++ b/apps/juxtaposition-ui/src/translations/eo.json @@ -40,7 +40,7 @@ "user_page": { "country": "Lando", "birthday": "Naskiĝtago", - "game_experience": "Sperto de Ludo", + "game_experience": "Ludosperto", "posts": "Afiŝoj", "friends": "Amikoj", "following": "Abonanta", @@ -55,16 +55,16 @@ "no_followers": "Neniuj Abonantoj" }, "user_settings": { - "profile_settings": "Agordoj de Profilo", - "profile_comment": "Komento de Profilo", + "profile_settings": "Profilagordoj", + "profile_comment": "Profilrimarko", "show_country": "Montri Landon en Profilo", "show_birthday": "Montri Naskiĝtagon en Profilo", - "show_game": "Montri Sperton de Ludo en Profilo", - "swearing": "La komento devas ne ampleksi maldecan lingvon.", + "show_game": "Montri Ludosperton en Profilo", + "swearing": "La profilrimarko ne povas enhavi maldecaĵojn.", "show_comment": "Montri komenton en profilo" }, "activity_feed": { - "empty": "Estas malplena ĉi tie. Abonu iun!" + "empty": "Malplenas ĉi tie. Provu aboni iun!" }, "notifications": { "none": "Neniuj avizoj.", @@ -74,7 +74,7 @@ "new_post_text": "Novo Afiŝo", "post_to": "Afiŝi al", "text_hint": "Tuŝu ĉi tie por afiŝi.", - "swearing": "La afiŝo devas ne ampleksi maldecan lingvon." + "swearing": "La afiŝo ne povas enhavi maldecaĵojn" }, "messages": { "coming_soon": "Mesaĝoj ankoraŭ ne estas disponeblaj. Baldaŭ revenu!" @@ -94,12 +94,33 @@ "first": "Sekvante kelkaj gravaj gvidlinioj por ke Juxt estu amuza kaj ĝuable sperto por ĉiuj. La kodo de konduto de Juxt enhavas detalajn informojn, do bonvolu diligente legi.", "fourth": "Estu Agrabla Unu al la Alia", "fifth": "Por ke Juxt restu agrabla loko por ĉiu, ni petas ke vi estu konsiderema al aliaj uzantoj. Asistu nin restigi Juxt agrablan sperton per afiŝi nek maldecaĵojn nek ofendaĵojn.", - "sixth": "Ne afiŝu privataj informoj, nek viaj, nek alies", - "ninth": "Kelkaj homoj venas al Juxt serĉante konsilojn kaj lertaĵojn por ludoj, sed aliaj volas malkovri la sekretojn de ludo tute memstare. Afiŝoj kiuj rivelas sekretojn de ludo aŭ ĝia rakonto estas nomitaj \"spoilers\". Se vi afiŝas ion pri ludo, kiu povus esti spoiler, nepre kontrolu la skatolon Spoilers antaŭ sendi vian afiŝon. Tiel homoj, kiuj ne volas esti difektitaj, ne vidos vian afiŝon." + "sixth": "Ne afiŝu privatajn informojn, nek viajn, nek alies", + "ninth": "Kelkaj homoj venas al Juxt serĉante konsilojn kaj lertaĵojn por ludoj, sed aliaj volas malkovri la sekretojn de ludo tute memstare. Afiŝoj kiuj rivelas sekretojn de ludo aŭ ĝia rakonto estas nomitaj \"spoilers\". Se vi afiŝas ion pri ludo, kiu povus esti spoiler, nepre kontrolu la skatolon Spoilers antaŭ sendi vian afiŝon. Tiel homoj, kiuj ne volas esti difektitaj, ne vidos vian afiŝon.", + "eighth": "Ne Afiŝu Fimalkaŝojn", + "tenth": "Malrespekti la Kondutkodon", + "twelfth": "Ĉu Vi Ludis Tiun Ludon?", + "seventh": "Memoru, koni iun je Juxt ne egalas koni tiun realvive. Neniam distvastigu vian retpoŝtadreson, hejmadreson, la nomon de via laborejo aŭ lernejo, aŭ iajn aliajn persone identigeblajn informojn al iun ajn je Juxt kaj neniam dividu la informojn de iu alia ajn. Cetere, se iu, kiun vi renkontas je Juxt, invitas vin renkonti tiun en la reala mondo, ne akceptu. Juxt estas interreta komunumo kaj ne estu uzata por organizi realmondajn kunvenojn.", + "eleventh": "Nia celo estas teni Juxt agrabla kaj ĝuebla por ĉiu. En la kazo ke iu malrespektas la Juxt-an Kondutkodon, ni adekvate agu, ĝis kaj inkluzive bari la malrespektintan uzanton aŭ konzolon.", + "thirteenth": "Se vi afiŝas en komunumo por ludo ludita de vi, viaj afiŝoj havos piktogramon indikantan ke vi jam ludis ĝin." }, "info": "Kio estas Juxtaposition?", "info_text": "Juxt estas uzantobazita videoludokomunumo kie oni povas interagi kun homoj\n de la tuta mondo. Oni povas skribi aŭ desegni afiŝojn en videoludokomunumoj aŭ rekte mesaĝi al viaj amikoj.", "rules": "reguloj de Juxt", - "google_text": "Juntapozicio uzas Google Analytics por spuri kiel uzantoj uzas nian servon. La datumoj kolektitaj inkluzivas sed ne estas limigitaj al tempo de vizito, paĝoj vizititaj kaj tempo pasigita en la retejo. Ĉi tiuj datumoj neniel estas ligitaj al vi, kaj ne estas uzataj por reklamoj de ni aŭ Guglo." + "google_text": "Juntapozicio uzas Google Analytics por spuri kiel uzantoj uzas nian servon. La datumoj kolektitaj inkluzivas sed ne estas limigitaj al tempo de vizito, paĝoj vizititaj kaj tempo pasigita en la retejo. Ĉi tiuj datumoj neniel estas ligitaj al vi, kaj ne estas uzataj por reklamoj de ni aŭ Guglo.", + "experience": "Ludosperto", + "experience_text": { + "expert": "Eksperto", + "beginner": "Komencanto", + "intermediate": "Mezo", + "info": "Bonvolu rakonti al ni kiel vi priskribus vian spertonivelon pri ludoj. Vi povas poste ŝanĝi tiun ĉi agordon." + }, + "google": "Google Analytics", + "ready_text": "Komence, miru kelkajn komunumojn kaj vidu pri kio afiŝadas homoj de la tuta mondo. Profitu ĉi tiun ŝancon por kutimiĝi kun Juxt. Eble kutimiĝante vi malkovrus ion aŭ iojn!", + "done": "Amuziĝu en Juxt!", + "ready": "Preta por Uzi Juxt", + "done_button": "Ni Iru!", + "guest": "Gastmodo", + "guest_button": "Mi Komprenas", + "guest_text": "Ni ĉi-momente ne povas konfirmi vian konton. Tio verŝajne signifas ke vi enŝultadas per Nintendo Network-konto. Vi povos paĝumi Juxt-e, sed vi ne povos Jes-i afiŝojn aŭ fari viajn proprajn afiŝojn ĝis vi enŝultas per Pretendo Network-konto. Por pli da informoj vidu en la Discord-servilo." } } From 0e7dad5e8f5b6ae7efffa9280f77103e60aed1e5 Mon Sep 17 00:00:00 2001 From: EarthPenguin 861 Date: Wed, 28 Aug 2024 00:09:38 +0000 Subject: [PATCH 133/189] locales(update): Updated Catalan locale --- apps/juxtaposition-ui/src/translations/ca.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/ca.json b/apps/juxtaposition-ui/src/translations/ca.json index 96904edf..12c23740 100644 --- a/apps/juxtaposition-ui/src/translations/ca.json +++ b/apps/juxtaposition-ui/src/translations/ca.json @@ -94,7 +94,7 @@ "twelfth": "Has jugat a aquest joc?" }, "beta_text": { - "third": "El lloc web, el seu programari i tot el contingut que s'hi troba es proporcionen \"tal qual\" i \"segons estigui disponible\". La Pretendo Network no dóna cap garantia, ja sigui expressa o implícita, sobre la idoneïtat o usabilitat del lloc web, el seu programari o qualsevol dels seus continguts.", + "third": "El lloc web, el seu programari i tot el contingut que s'hi troba es proporcionen \"tal qual\" i \"segons estigui disponible\". La Xarxa de Pretendo no dóna cap garantia, ja sigui expressa o implícita, sobre la idoneïtat o usabilitat del lloc web, el seu programari o qualsevol dels seus continguts.", "second": "Això pot incloure una eliminació total de la base de dades al final o durant el període beta.", "first": "Estàs a punt de provar la primera beta pública de Juxt. Això vol dir que encara hi ha moltes coses en l'aire, i moltes coses poden canviar en qualsevol moment." }, From 07796c9a5ace6b30e299a3e4afb452a9846e825f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D7=AA=D7=95=D7=9E=D7=A8=20=D7=A8=D7=A4=D7=90=D7=9C?= Date: Mon, 2 Sep 2024 13:35:34 +0200 Subject: [PATCH 134/189] locales(add): Added Hebrew locale --- apps/juxtaposition-ui/src/translations/he.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/juxtaposition-ui/src/translations/he.json diff --git a/apps/juxtaposition-ui/src/translations/he.json b/apps/juxtaposition-ui/src/translations/he.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/apps/juxtaposition-ui/src/translations/he.json @@ -0,0 +1 @@ +{} From 23cc67e458e7bccb6127ebedcd47d414e8984d73 Mon Sep 17 00:00:00 2001 From: Hendrik Vanvelk Date: Thu, 12 Sep 2024 08:43:27 +0000 Subject: [PATCH 135/189] locales(update): Updated Dutch locale --- apps/juxtaposition-ui/src/translations/nl.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/nl.json b/apps/juxtaposition-ui/src/translations/nl.json index 2eed4d06..7e7aab43 100644 --- a/apps/juxtaposition-ui/src/translations/nl.json +++ b/apps/juxtaposition-ui/src/translations/nl.json @@ -81,12 +81,12 @@ }, "setup": { "welcome": "Welkom op Juxtaposition!", - "welcome_text": "Juxt is een gaming community welk mensen van over de hele wereld verbind doormiddel van Mii karakters. Gebruik Juxt om jouw ervaringen tijdens het gamen te delen en mensen te ontmoeten over de hele wereld.", + "welcome_text": "Juxt is een gaming community welk mensen van over de hele wereld verbind door middel van Mii karakters. Gebruik Juxt om jouw ervaringen tijdens het gamen te delen en mensen te ontmoeten over de hele wereld.", "beta": "Beta-disclaimer", "beta_text": { "first": "Je staat op het punt de eerste publieke beta van Juxt te gebruiken. Dit betekent dat veel onzeker is en ook van alles kan veranderen.", - "second": "Dit kan mogelijk een volledige reset van de database aan het einde van de beta periode of tijdens deze periode omvatten.", - "third": "De website, de software die het bevat, alsook alle content die te vinden is op deze website, worden geleverd op een \"as is\" en \"as available\" basis. Pretendo Network geeft geen garantstellingen, ofwel expliciet ofwel impliciet, met betrekking tot de geschiktheid of bruikbaarheid van de website, de software die het bevat of de content op de website." + "second": "Dit kan mogelijk een volledige reset van de database aan het einde van of tijdens de beta periode omvatten.", + "third": "De website, de software die het bevat, alsook alle content die te vinden is op deze website, worden geleverd op een \"as is\" en \"as available\" basis. Pretendo Network geeft geen garantstellingen, noch expliciet noch impliciet, met betrekking tot de geschiktheid of bruikbaarheid van de website, de software die het bevat of de content op de website." }, "info": "Wat is Juxtaposition?", "info_text": "Juxt is een gebruikers-gedreven gaming community waar je kan communiceren met mensen\n over de hele wereld. Je kan posts schrijven of tekenen in game communities of berichten rechtstreeks naar je vrienden sturen.", @@ -98,7 +98,7 @@ "fourth": "Wees Aardig Tegen Elkaar", "fifth": "Om Juxt een leuke omgeving voor iedereen te houden vragen wij van jou om rekening te houden met anderen. Help ons om Juxt zo leuk mogelijk te houden door niets ongepasts of beledigend te posten.", "sixth": "Post Geen Persoonlijke Gegevens—Die van Jezelf of van Anderen", - "seventh": "Onthoud, iemand in Juxt kennen is niet hetzelfde als iemand in het echt kennen. Deel nooit je e-mail adres, huisadres, de naam van je school of werk of wat voor een persoonlijke identificeerbare informatie dan ook met een ander en deel ook geen van deze gegevens van iemand anders. Daarnaast, als iemand die je ontmoet hebt op Juxt je vraagt om diegene in het echt te ontmoeten, accepteer dit niet. Juxt is een online community en moet niet gebruikt worden om ontmoetingen in het echt te faciliteren.", + "seventh": "Onthoud, iemand in Juxt kennen is niet hetzelfde als iemand in het echt kennen. Deel nooit je e-mail adres, huisadres, de naam van je school of werk of wat voor een persoonlijke identificeerbare informatie dan ook met een ander en deel zulke gegevens van iemand anders niet. Daarnaast, als iemand die je ontmoet hebt op Juxt je vraagt om diegene in het echt te ontmoeten, accepteer dit niet. Juxt is een online community en moet niet gebruikt worden om ontmoetingen in het echt te faciliteren.", "eighth": "Post Geen Spoilers", "ninth": "Sommige mensen komen naar Juxt voor tips en trucs voor games, anderen willen zelf de geheimen van een game ontdekken. Berichten die geheimen van een game of het verhaal ervan onthullen, worden 'spoilers' genoemd. Als je iets post over een game dat een spoiler zou kunnen zijn, zorg er dan voor dat je het vakje Spoilers aanvinkt voordat je je post verstuurt. Zo zien mensen die geen spoilers willen zien je bericht niet.", "tenth": "Gedragscode overtredingen", @@ -116,7 +116,7 @@ "google": "Google Analytics", "google_text": "Juxtaposition gebruikt Google Analytics om bij te houden hoe gebruikers onze dienst gebruiken. De data die we verzamelen bevat onder andere tijd van bezoek, bezochte pagina's en hoe lang het bezoek duurde. Deze data is op geen enkele manier gekoppeld aan jou en wordt niet gebruikt door Google of ons om advertenties aan jou te tonen.", "ready": "Klaar om Juxt te Gebruiken", - "ready_text": "Bekijk allereerst wat community's en zie waar mensen van over de hele wereld over posten. Gebruik deze kans om je bekend te maken met Juxt. Mogelijk ontdek je iets nieuws op deze manier!", + "ready_text": "Bekijk eerst wat community's en zie waar mensen van over de hele wereld over posten. Gebruik deze kans om je bekend te maken met Juxt. Misschien ontdek je iets nieuws op deze manier!", "done": "Veel plezier in Juxt!", "done_button": "Laten We Beginnen!", "guest": "Gastmodus", From 5eec6c1fddb4b4d7d6ec371ee48bd814882eb779 Mon Sep 17 00:00:00 2001 From: Hendrik Vanvelk Date: Thu, 12 Sep 2024 08:55:56 +0000 Subject: [PATCH 136/189] locales(update): Updated Esperanto locale --- apps/juxtaposition-ui/src/translations/eo.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/eo.json b/apps/juxtaposition-ui/src/translations/eo.json index 25208f4e..e3d4426c 100644 --- a/apps/juxtaposition-ui/src/translations/eo.json +++ b/apps/juxtaposition-ui/src/translations/eo.json @@ -99,7 +99,7 @@ "eighth": "Ne Afiŝu Fimalkaŝojn", "tenth": "Malrespekti la Kondutkodon", "twelfth": "Ĉu Vi Ludis Tiun Ludon?", - "seventh": "Memoru, koni iun je Juxt ne egalas koni tiun realvive. Neniam distvastigu vian retpoŝtadreson, hejmadreson, la nomon de via laborejo aŭ lernejo, aŭ iajn aliajn persone identigeblajn informojn al iun ajn je Juxt kaj neniam dividu la informojn de iu alia ajn. Cetere, se iu, kiun vi renkontas je Juxt, invitas vin renkonti tiun en la reala mondo, ne akceptu. Juxt estas interreta komunumo kaj ne estu uzata por organizi realmondajn kunvenojn.", + "seventh": "Memoru, koni iun sur Juxt ne estas la sama kiel koni tiun en la reala vivo. Neniam dividu vian retpoŝtadreson, hejman adreson, laboran aŭ lernejan nomon, aŭ aliajn persone identigeblajn informojn kun iu ajn sur Juxt, kaj ankaŭ neniam dividu la informojn de iu alia. Aldone, se iu, kiun vi renkontas en Juxt, invitas vin renkonti tiun en la reala mondo, ne akceptu. Juxt estas interreta komunumo kaj ne estu uzata por aranĝi verajn kunvenojn.", "eleventh": "Nia celo estas teni Juxt agrabla kaj ĝuebla por ĉiu. En la kazo ke iu malrespektas la Juxt-an Kondutkodon, ni adekvate agu, ĝis kaj inkluzive bari la malrespektintan uzanton aŭ konzolon.", "thirteenth": "Se vi afiŝas en komunumo por ludo ludita de vi, viaj afiŝoj havos piktogramon indikantan ke vi jam ludis ĝin." }, From feccda71eb7dfc0662d797d090d767948f7efa3b Mon Sep 17 00:00:00 2001 From: Viktor Varga Date: Sun, 15 Sep 2024 13:44:45 +0000 Subject: [PATCH 137/189] locales(update): Updated Hungarian locale --- apps/juxtaposition-ui/src/translations/hu.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/hu.json b/apps/juxtaposition-ui/src/translations/hu.json index 7f7305a8..86942f2b 100644 --- a/apps/juxtaposition-ui/src/translations/hu.json +++ b/apps/juxtaposition-ui/src/translations/hu.json @@ -1,7 +1,7 @@ { "global": { "user_page": "Profil", - "activity_feed": "Tevékenység hírcsatorna", + "activity_feed": "Tevékenység csatorna", "communities": "Közösségek", "go_back": "Vissza", "back": "Vissza", From df7555164f64f0a926ecf2e95fa91aac08563df1 Mon Sep 17 00:00:00 2001 From: Fresh octo Date: Sun, 22 Sep 2024 10:35:19 +0000 Subject: [PATCH 138/189] locales(update): Updated Chinese (Traditional Han script) locale --- .../src/translations/zh_Hant.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/zh_Hant.json b/apps/juxtaposition-ui/src/translations/zh_Hant.json index a2425534..ee8c46d5 100644 --- a/apps/juxtaposition-ui/src/translations/zh_Hant.json +++ b/apps/juxtaposition-ui/src/translations/zh_Hant.json @@ -6,11 +6,11 @@ "activity_feed": "動態消息", "messages": "聊天訊息", "notifications": "通知中心", - "communities": "社群子板", + "communities": "社群", "go_back": "返回上層", "yeahs": "我贊同", "back": "返回", - "more": "繼續載入投稿", + "more": "載入更多投稿", "private": "私人", "next": "繼續", "no_posts": "查無投稿", @@ -18,13 +18,13 @@ "save": "儲存" }, "all_communities": { - "text": "所有社群子板", + "text": "所有社群", "announcements": "公告", "ann_string": "點選此處查看近期公告!", - "popular_places": "熱門子板", - "new_communities": "新設子板", + "popular_places": "熱門社群", + "new_communities": "新設社群", "show_all": "顯示所有", - "search": "搜尋子板……" + "search": "搜尋社群……" }, "activity_feed": { "empty": "這裡空空如也。先去跟隨其他人吧!" @@ -41,7 +41,7 @@ "third": "本網站及其軟體與附屬內容,均基於「現況性」與「可提供性」為開展。Pretendo Network 絕不保證(無論其明示抑或暗示)本網站及其軟體與附屬內容之合用性或可用性。" }, "info": "什麼是 Juxtaposition?", - "info_text": "Juxt 是由玩家們自發組成的遊戲社群;是能與全世界的人們相互交流的好所在。\n 您可以在遊戲子板投稿您的書寫文章以及繪畫作品,或者傳送訊息給好友。", + "info_text": "Juxt 是由玩家們自發組成的遊戲社群;是能與全世界的人們相互交流的好所在。\n 您可以在遊戲社群投稿您的書寫文章以及繪畫作品,或者傳送訊息給好友。", "rules": "《Juxt 社群守則》", "rules_text": { "first": "為了讓 Juxt 的大家都能享受樂趣,敬請詳閱《Juxt 社群守則》。以下將羅列數條為務必遵守的規範。", @@ -54,11 +54,11 @@ "eleventh": "我們的目標是讓 Juxt 的大家都能享受樂趣。如果有人違反《Juxt 社群守則》,我們會採取適當行動,封鎖違規使用者或整臺遊戲機。", "twelfth": "玩過遊戲了嗎?", "thirteenth": "如果您在有玩過的遊戲上投稿,其內文將會附有一個圖示表明您曾經玩過。", - "third": "Juxt 匯聚了全世界人們對諸多遊戲的觀點。請您謹記,在遊戲子板投稿時既要真誠表達自己,也要考慮到他人感受,因為所有人都能看見您的投稿。投稿前應三思而後行。Juxt 服務範圍也包括網際網路,即使是不使用 Juxt 的人也能看見您的投稿。此外,您在好友投稿上的回應不僅是好友能看見,而是所有人。敬請留意。", + "third": "Juxt 匯聚了全世界人們對諸多遊戲的觀點。請您謹記,在遊戲社群投稿時既要真誠表達自己,也要考慮到他人感受,因為所有人都能看見您的投稿。投稿前應三思而後行。Juxt 服務範圍也包括網際網路,即使是不使用 Juxt 的人也能看見您的投稿。此外,您在好友投稿上的回應不僅是好友能看見,而是所有人。敬請留意。", "seventh": "請您謹記,從 Juxt 認識某人不代表也從現實生活認識了他。切勿在 Juxt 共享您或他人的個人資料,包括電子郵件地址、工作場域、學校名稱等等。如果您在 Juxt 上收到某個人的線下見面邀請,請不要接受。Juxt 只是一個線上社群平臺,不應用於安排線下聚會。", "ninth": "有些人來到 Juxt 找尋遊戲的技巧和訣竅,但也有些人只想自己發掘遊戲裡的各種隱藏要素。將遊戲隱藏要素或劇情透露的投稿,稱作\"劇透。\" 如果要投稿劇透內容,請確保該文已被勾選為劇透投稿。如此一來,不想被劇透的人就不會看到您的投稿。" }, - "experience": "遊戲上手程度", + "experience": "遊戲經驗", "experience_text": { "info": "選擇您自認對遊戲的上手程度。您可以在之後更改此設定。", "beginner": "初來乍到", @@ -73,7 +73,7 @@ "done_button": "走吧!", "guest_button": "我明白了", "google_text": "Juxtaposition 使用 Google Analytics(分析)來追蹤使用者存取服務的情況。收集的資料包括但不限於拜訪時間、拜訪的頁面以及停留頁面的時間。這些資料不會以任何方式與您關連,也不會被我們或 Google 用於分析廣告投放。", - "ready_text": "先到社群子板,觀摩來自全世界的投稿作品吧。還能趁機熟悉 Juxt 的介面。您也可能就此發現新世界!", + "ready_text": "先到社群頁面,觀摩來自全世界的投稿作品吧。還能趁機熟悉 Juxt 的介面。您也可能就此發現新世界!", "guest_text": "目前無法驗證您的帳號(可能是因為您使用了 Nintendo Network 帳號)。您可以繼續瀏覽 Juxt,但在登入 Pretendo Network 前,將無法進行「我贊同!」或投稿內容。詳情請前往 Discord 伺服器瞭解。" }, "community": { @@ -81,14 +81,14 @@ "popular": "熱門投稿", "verified": "名人投稿", "new": "投稿", - "follow": "跟隨子板", + "follow": "跟隨社群", "following": "跟隨中", "followers": "跟隨者", "posts": "投稿", "tags": "標籤" }, "user_page": { - "game_experience": "遊戲上手程度", + "game_experience": "遊戲經驗", "posts": "投稿", "friends": "好友", "following": "跟隨中", @@ -107,7 +107,7 @@ "user_settings": { "show_country": "在個人檔案顯示居住地", "show_birthday": "在個人檔案顯示生日", - "show_game": "在個人檔案顯示遊戲上手程度", + "show_game": "在個人檔案顯示遊戲經驗", "show_comment": "在個人檔案顯示自我介紹", "profile_comment": "自我介紹", "profile_settings": "個人檔案設定", From b7df9e1b238dad1e33a18b1c68de51284d76c672 Mon Sep 17 00:00:00 2001 From: Algimantas Date: Mon, 23 Sep 2024 20:22:17 +0000 Subject: [PATCH 139/189] locales(update): Updated Lithuanian locale --- apps/juxtaposition-ui/src/translations/lt.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/lt.json b/apps/juxtaposition-ui/src/translations/lt.json index 48767b7d..911f8cf6 100644 --- a/apps/juxtaposition-ui/src/translations/lt.json +++ b/apps/juxtaposition-ui/src/translations/lt.json @@ -4,7 +4,7 @@ "notifications": "Pranešimai", "communities": "Bendruomenės", "messages": "Žinutės", - "go_back": "Sugrįžti", + "go_back": "Grįžti", "exit": "Išeiti", "user_page": "Vartotojo puslapis", "more": "Užkrauti daugiau įkelimų", From 5077eb52edd431ae8b2759c5da7f549c35c248c4 Mon Sep 17 00:00:00 2001 From: Bryan Mainardi Date: Wed, 2 Oct 2024 13:10:34 +0000 Subject: [PATCH 140/189] locales(update): Updated Italian locale --- apps/juxtaposition-ui/src/translations/it.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/it.json b/apps/juxtaposition-ui/src/translations/it.json index 723e626b..412c050b 100644 --- a/apps/juxtaposition-ui/src/translations/it.json +++ b/apps/juxtaposition-ui/src/translations/it.json @@ -44,7 +44,7 @@ "posts": "Post", "friends": "Amici", "following": "Seguiti", - "followers": "Seguitore", + "followers": "Seguaci", "follow_user": "Segui", "following_user": "Stai seguendo", "befriend": "Chiedi amicizia", From 2cb0c46f2aecf3f38e2c64d93313a073f506db5a Mon Sep 17 00:00:00 2001 From: Rudinn Date: Thu, 10 Oct 2024 20:19:41 +0000 Subject: [PATCH 141/189] locales(update): Updated Kazakh locale --- apps/juxtaposition-ui/src/translations/kk.json | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/kk.json b/apps/juxtaposition-ui/src/translations/kk.json index 96ca7c61..62ef6be6 100644 --- a/apps/juxtaposition-ui/src/translations/kk.json +++ b/apps/juxtaposition-ui/src/translations/kk.json @@ -38,7 +38,11 @@ "new": "Жаңа пост" }, "user_page": { - "country": "Ел" + "country": "Ел", + "birthday": "Туған күн", + "game_experience": "Ойын тәжірибесі", + "friends": "Достар", + "posts": "Жазбалар" }, "setup": { "experience_text": { @@ -49,6 +53,7 @@ "rules_text": { "eighth": "Спойлер жазбаңыз" }, - "ready": "Juxt пайдалануды бастауға дайын" + "ready": "Juxt пайдалануды бастауға дайын", + "guest_button": "Мен түссіндім" } } From 9ec6ab0f8a609e2fcbc8fcd998851deb588bba27 Mon Sep 17 00:00:00 2001 From: Rudinn Date: Thu, 10 Oct 2024 20:24:14 +0000 Subject: [PATCH 142/189] locales(update): Updated Hebrew locale --- .../juxtaposition-ui/src/translations/he.json | 55 ++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/he.json b/apps/juxtaposition-ui/src/translations/he.json index 0967ef42..337e4072 100644 --- a/apps/juxtaposition-ui/src/translations/he.json +++ b/apps/juxtaposition-ui/src/translations/he.json @@ -1 +1,54 @@ -{} +{ + "global": { + "user_page": "עמוד משתמש", + "communities": "קהילות", + "no_posts": "אין פוסטים", + "activity_feed": "עדכון פעילות", + "exit": "יְצִיאָה", + "next": "הַבָּא", + "messages": "הודעות", + "notifications": "התראות", + "go_back": "לַחֲזוֹר", + "back": "בְּחֲזָרָה", + "yeahs": "כן", + "more": "טען עוד פוסטים", + "private": "פְּרָטִי", + "close": "לִסְגוֹר", + "save": "לְהַצִיל" + }, + "all_communities": { + "text": "כל הקהילות", + "announcements": "הכרזות", + "ann_string": "לחץ כאן לצפייה בהכרזות האחרונות!", + "popular_places": "מקומות פופולריים", + "new_communities": "קהילות חדשות", + "show_all": "הצג הכל", + "search": "חפש קהילות..." + }, + "community": { + "new": "פוסט חדש", + "follow": "עקוב אחר הקהילה", + "following": "עוקבים", + "posts": "פוסטים", + "recent": "פוסטים אחרונים", + "popular": "פוסטים פופולריים", + "verified": "פוסטים מאומתים" + }, + "user_page": { + "birthday": "יוֹם הוּלֶדֶת", + "game_experience": "חווית משחק", + "posts": "פוסטים", + "friends": "חברים", + "following": "עוקבים", + "follow_user": "לַעֲקוֹב", + "following_user": "עוקבים", + "pending": "תָלוּי וְעוֹמֵד", + "no_friends": "אין חברים", + "no_following": "לא עוקב אחרי אף אחד", + "no_followers": "אין עוקבים" + }, + "user_settings": { + "profile_settings": "הגדרות פרופיל", + "show_birthday": "הצג יום הולדת בפרופיל" + } +} From 2646f3e02951b0283b2bb3aea09f23026ea6a704 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnau=20B=C3=A0rcia?= Date: Thu, 31 Oct 2024 04:35:34 +0000 Subject: [PATCH 143/189] locales(update): Updated Spanish locale --- apps/juxtaposition-ui/src/translations/es.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/es.json b/apps/juxtaposition-ui/src/translations/es.json index 6a4c0f6a..1d723783 100644 --- a/apps/juxtaposition-ui/src/translations/es.json +++ b/apps/juxtaposition-ui/src/translations/es.json @@ -57,9 +57,9 @@ "user_settings": { "profile_settings": "Preferencias del perfil", "show_country": "Mostrar el país en el perfil", - "show_birthday": "Mostrar cumpleaños en tu perfil", - "show_game": "Mostrar el nivel como jugador en tu perfil", - "show_comment": "Mostrar comentario en tu perfil", + "show_birthday": "Mostrar cumpleaños en el perfil", + "show_game": "Mostrar tu nivel de experiencia como jugador en el perfil", + "show_comment": "Mostrar comentario en el perfil", "profile_comment": "Comentario del perfil", "swearing": "Los comentarios no pueden tener lenguaje inapropiado." }, From 5307641426955b6a736ce13078848929387e19b8 Mon Sep 17 00:00:00 2001 From: Jay C <21anicheallachain@lccgmail.com> Date: Wed, 13 Nov 2024 18:20:27 +0100 Subject: [PATCH 144/189] locales(add): Added Irish locale --- apps/juxtaposition-ui/src/translations/ga.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/juxtaposition-ui/src/translations/ga.json diff --git a/apps/juxtaposition-ui/src/translations/ga.json b/apps/juxtaposition-ui/src/translations/ga.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/apps/juxtaposition-ui/src/translations/ga.json @@ -0,0 +1 @@ +{} From 7141c87ac2079b159a09743eda368738d592711a Mon Sep 17 00:00:00 2001 From: jc <21anicheallachain@lccgmail.com> Date: Wed, 13 Nov 2024 17:31:48 +0000 Subject: [PATCH 145/189] locales(update): Updated Irish locale --- .../juxtaposition-ui/src/translations/ga.json | 85 ++++++++++++++++++- 1 file changed, 84 insertions(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/ga.json b/apps/juxtaposition-ui/src/translations/ga.json index 0967ef42..d3ddae02 100644 --- a/apps/juxtaposition-ui/src/translations/ga.json +++ b/apps/juxtaposition-ui/src/translations/ga.json @@ -1 +1,84 @@ -{} +{ + "global": { + "communities": "Pobail", + "messages": "Teachtaireachtaí", + "user_page": "Leathnach Úsáideora", + "go_back": "Téigh Ar Ais", + "activity_feed": "Fotha Gníomhaíochtaí", + "private": "Príobháideach", + "close": "Dún", + "exit": "Amach", + "more": "Lódáil Níos Mó", + "next": "Ar Aghaidh", + "notifications": "Fógraí", + "yeahs": "Sea", + "save": "Sábháil", + "back": "Ar Ais", + "no_posts": "Gan Postálacha" + }, + "all_communities": { + "announcements": "Fógraí", + "ann_string": "Cliceáil anseo chun na fograí is deanaí a fheceáil!", + "text": "Gach Phobail", + "popular_places": "Áiteanna bhfuil gnaoi an phobail air", + "new_communities": "Pobail Nua", + "show_all": "Taispeáin Gach Rud", + "search": "Cuardaigh pobail..." + }, + "community": { + "follow": "Lean Pobail", + "following": "Ag Leanúint", + "followers": "Leantóirí", + "posts": "Postálacha", + "tags": "Clibeanna", + "recent": "Postálacha Is Deanaí", + "verified": "Postálacha Deimhnithe", + "new": "Postáil Nua", + "popular": "Postálacha bhfuil gnaoi an phobail air" + }, + "user_page": { + "birthday": "Lá Breithe", + "game_experience": "Taithí Cluiche", + "posts": "Postálacha", + "friends": "Cairde", + "following": "Ag Leanúint", + "followers": "Leantóirí", + "follow_user": "Lean", + "following_user": "Ag Leanúint", + "befriend": "Cairde a deanamh leo", + "pending": "Ar Feitheamh", + "unfriend": "Stop ag bheith cairde leo", + "no_following": "Ag leanúint duine ar bith", + "no_followers": "Gan Leantóirí", + "country": "Tír", + "no_friends": "Gan Cairde" + }, + "user_settings": { + "show_country": "Taispeán Tír ar do Phroifíl", + "show_game": "Taispeán Taithí Cluiche ar do Phroifíl", + "show_birthday": "Taispeán Lá Breithe ar do Phroifíl", + "show_comment": "Taispeán Nóta Tráchta ar do Phrofíl", + "profile_comment": "Nóta Tráchta Proifíl", + "swearing": "Ní feidir le teanga follasach a bheith sa nóta tráchta proifíl.", + "profile_settings": "Socruithe Proifíl" + }, + "activity_feed": { + "empty": "Tá sé follamh anseo. Trial ag leanúint duine éigin!" + }, + "notifications": { + "none": "Gan fógraí." + }, + "new_post": { + "post_to": "Postáil chuig", + "text_hint": "Tapáil anseo chun postáil a cruthú.", + "swearing": "Ní feidir le teanga follasach a bheith sa phostáil.", + "new_post_text": "Postáil Nua" + }, + "setup": { + "welcome": "Fáilte chuig Juxtaposition!" + }, + "language": "Gaeilge", + "messages": { + "coming_soon": "Níl teachtaireachtaí réidh fós. Seiceáil ar ais go luath!" + } +} From 30bcec10e3929db1d826889c11cbfe52b74a388f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnau=20B=C3=A0rcia?= Date: Sat, 16 Nov 2024 22:59:25 +0000 Subject: [PATCH 146/189] locales(update): Updated Spanish locale --- apps/juxtaposition-ui/src/translations/es.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/es.json b/apps/juxtaposition-ui/src/translations/es.json index 1d723783..29ec99e7 100644 --- a/apps/juxtaposition-ui/src/translations/es.json +++ b/apps/juxtaposition-ui/src/translations/es.json @@ -40,13 +40,13 @@ "user_page": { "country": "País", "birthday": "Cumpleaños", - "game_experience": "Experiencia de juego", + "game_experience": "Nivel como jugador", "posts": "Publicaciones", "friends": "Amigos", - "following": "Siguiendo", + "following": "Sigue a", "followers": "Seguidores", "follow_user": "Seguir", - "following_user": "Siguiendo", + "following_user": "Sigue a", "befriend": "Ser amigos", "pending": "Pendiente", "unfriend": "Eliminar amigo", From f05957ed6b1b2c854b9acecaf174d3874fbd622a Mon Sep 17 00:00:00 2001 From: Dimitri A Date: Mon, 9 Dec 2024 23:19:41 +0000 Subject: [PATCH 147/189] locales(update): Updated French locale --- .../juxtaposition-ui/src/translations/fr.json | 96 +++++++++---------- 1 file changed, 48 insertions(+), 48 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/fr.json b/apps/juxtaposition-ui/src/translations/fr.json index ffe47a9f..714e77d9 100644 --- a/apps/juxtaposition-ui/src/translations/fr.json +++ b/apps/juxtaposition-ui/src/translations/fr.json @@ -2,15 +2,15 @@ "language": "Français", "global": { "user_page": "Profil", - "activity_feed": "Fil d'Actualité", + "activity_feed": "Fil d'actualité", "communities": "Communautés", "messages": "Messages", "notifications": "Notifications", - "go_back": "Revenir en arrière", - "back": "Retour", + "go_back": "Retour", + "back": "Précedent", "yeahs": "Ouais", - "more": "Afficher plus de publications", - "no_posts": "Aucune Publication", + "more": "Voir plus de publications", + "no_posts": "Aucune publication", "private": "Privé", "close": "Fermer", "save": "Sauvegarder", @@ -18,83 +18,83 @@ "next": "Suivant" }, "all_communities": { - "text": "Toutes les Communautés", + "text": "Toutes les communautés", "announcements": "Annonces", - "ann_string": "Cliquez-ici pour voir les dernières annonces !", - "popular_places": "Communautés Populaires", - "new_communities": "Nouvelles Communautés", - "show_all": "Afficher Tout", - "search": "Rechercher des Communautés..." + "ann_string": "Cliquez ici pour voir les dernières annonces !", + "popular_places": "Populaires", + "new_communities": "Nouvelles communautés", + "show_all": "Tout afficher", + "search": "Rechercher des communautés..." }, "community": { - "follow": "Suivre la Communauté", - "following": "Abonné", + "follow": "Suivre la communauté", + "following": "Suivie", "followers": "Abonnés", "posts": "Publications", "tags": "Tags", - "recent": "Publications Récentes", - "popular": "Publications Populaires", - "verified": "Publications Vérifiées", - "new": "Nouvelle Publication" + "recent": "Posts récents", + "popular": "Posts populaires", + "verified": "Publications vérifiées", + "new": "Publier" }, "user_page": { "country": "Pays", "birthday": "Anniversaire", - "game_experience": "Expérience de Jeu", + "game_experience": "Expérience de joueur", "posts": "Publications", "friends": "Amis", "following": "Abonnements", "followers": "Abonnés", - "follow_user": "S'abonner", - "following_user": "Abonné", + "follow_user": "Suivre", + "following_user": "Suivi(e)", "befriend": "Devenir Amis", - "pending": "En Attente", - "unfriend": "Retirer des Amis", - "no_friends": "Aucun Ami", - "no_following": "Ne Suit Personne", - "no_followers": "Aucun Abonné" + "pending": "En attente", + "unfriend": "Retirer des amis", + "no_friends": "Aucun ami", + "no_following": "Ne suit aucun utilisateur", + "no_followers": "Aucun abonné" }, "user_settings": { - "profile_settings": "Paramètres du Profil", - "show_country": "Afficher le Pays sur le Profil", - "show_birthday": "Afficher l'Anniversaire sur le Profil", - "show_game": "Afficher l'Expérience de Jeu sur le Profil", - "show_comment": "Afficher les Commentaires sur le Profil", - "profile_comment": "Commentaires du Profil", - "swearing": "Les commentaires de profil ne peuvent pas contenir de language explicite." + "profile_settings": "Paramètres du profil", + "show_country": "Afficher mon pays sur le profil", + "show_birthday": "Afficher mon anniversaire sur le profil", + "show_game": "Afficher mon expérience de joueur sur le profil", + "show_comment": "Rendre visible le commentaire de mon profil", + "profile_comment": "Commentaire du profil", + "swearing": "Le commentaire du profil ne doit pas contenir de language explicite." }, "activity_feed": { - "empty": "C'est vide ici. Essaie de suivre quelqu'un !" + "empty": "C'est vide ici. Essaie de suivre quelqu'un !" }, "notifications": { "none": "Aucune notification.", - "new_follower": "vous suit !" + "new_follower": "vous suit !" }, "new_post": { "new_post_text": "Nouvelle Publication", "post_to": "Poster sur", - "text_hint": "Cliquez-ici pour poster un message.", + "text_hint": "Touchez ici pour commencer à poster.", "swearing": "Les publications ne peuvent pas contenir de language explicite." }, "messages": { - "coming_soon": "Les messages ne sont pas encore prêts pour le moment. Revenez bientôt !" + "coming_soon": "Les messages privés ne sont pas encore disponibles. Revenez bientôt !" }, "setup": { - "welcome": "Bienvenue sur Juxtaposition !", + "welcome": "Bienvenue sur Juxtaposition !", "welcome_text": "Juxt est une communauté de jeu qui connecte les personnes du monde entier à l'aide de personnages Mii. Utilisez Juxt pour partager votre expérience de jeu et rencontrer des gens autour du globe.", - "beta": "Avertissement Beta", + "beta": "BÊTA : AVIS DE NON-GARANTIE", "beta_text": { "first": "Vous êtes sur le point d'essayer la première version bêta publique de Juxt. Cela signifie que beaucoup de choses sont encore en développement et qu'elles peuvent changer à tout moment.", "second": "Cela peut inclure un effacement total de la base de données à la fin ou pendant la période bêta.", "third": "Le site web, son logiciel et tout le contenu qui s'y trouve sont fournis sur une base \"telle quelle\" et \"telle que disponible\". Le Réseau Pretendo ne donne aucune garantie, expresse ou implicite, quant à l'adéquation ou à la facilité d'utilisation du site web, de son logiciel ou de son contenu." }, - "info": "C'est quoi Juxtaposition ?", + "info": "C'est quoi, Juxtaposition ?", "info_text": "Juxt est une communauté de jeu gérée par les utilisateurs où vous pouvez interagir avec des personnes du monde entier.\nVous pouvez écrire ou dessiner des messages dans les communautés de jeu ou envoyer des messages directement à vos amis.", "rules": "Règles de Juxt", "rules_text": { "first": "Voici quelques directives importantes pour faire de Juxt une expérience amusante et agréable pour tous. Le code de conduite de Juxt contient des informations détaillées. Veuillez les lire attentivement.", - "second": "Les publications peuvent être consultées dans le monde entier", - "third": "Juxt contient de nombreuses communautés de jeu où des personnes du monde entier peuvent partager leurs idées. Lorsque vous publiez un message dans une communauté, n'oubliez pas que tout le monde peut le voir, alors exprimez-vous de manière à ce que tout le monde puisse l'apprécier. Faites preuve de bon sens et réfléchissez avant de publier. Juxt est un service qui est également accessible sur Internet, alors n'oubliez pas que les personnes qui n'utilisent pas Juxt peuvent également voir vos messages. De plus, les commentaires que vous faites sur les messages de vos amis seront vus non seulement par vos amis mais aussi par des personnes autour du globe. Gardez cela à l'esprit.", + "second": "Le monde entier pourra voir vos publications", + "third": "Juxt contient de nombreuses communautés de jeu où des personnes du monde entier peuvent partager leurs idées. Lorsque vous publiez du contenu dans une communauté, n'oubliez pas que tout le monde peut le voir, alors exprimez-vous de manière à ce que tout le monde puisse l'apprécier. Faites preuve de bon sens et réfléchissez avant de le publier. Juxt est un service qui est également accessible sur Internet, alors n'oubliez pas que les personnes qui n'utilisent pas Juxt peuvent également voir vos publications. De plus, les commentaires que vous enverrez sur les publications de vos amis seront visibles non seulement par vos amis mais aussi par des personnes autour du globe. Gardez cela à l'esprit.", "fourth": "Soyez gentils les uns envers les autres", "fifth": "Afin que Juxt reste un endroit agréable pour tous, nous vous demandons d'être soucieux des autres utilisateurs. Aidez-nous à faire de Juxt une expérience agréable en ne publiant rien d'inapproprié ou d'offensant.", "sixth": "Ne publiez pas d'informations personnelles - les vôtres ou celles des autres", @@ -106,21 +106,21 @@ "twelfth": "Avez-vous joué à ce jeu ?", "thirteenth": "Si vous postez dans la communauté pour un jeu auquel vous avez joué, vos messages auront une icône indiquant que vous y avez joué." }, - "experience": "Expérience de Jeu", + "experience": "Expérience de joueur", "experience_text": { - "info": "Comment décririez-vous votre niveau de compétences avec les jeux ? Vous pourrez changer ce paramètre plus tard.", + "info": "Comment décririez-vous votre niveau de compétence avec les jeux ? Vous pourrez changer ce paramètre plus tard.", "beginner": "Débutant", "intermediate": "Connaisseur", "expert": "Adepte" }, "google": "Google Analytics", - "google_text": "Juxtaposition utilise Google Analytics afin de déterminer comment les utilisateurs utilisent notre service. Les données recueillies comprennent, sans s'y limiter, l'heure de la visite, les pages visitées et le temps passé sur le site. Ces données ne sont en aucun cas rattachées à votre personne et ne sont pas utilisées à des fins publicitaires par nous ou par Google.", + "google_text": "Juxtaposition utilise Google Analytics afin de savoir comment les visiteurs interagissent avec notre service. Les données recueillies comprennent, sans s'y limiter, l'heure de visite, les pages visitées et le temps passé sur le site. Ces données ne sont en aucun cas rattachées à votre personne et ne seront pas utilisées à des fins publicitaires, ni par nous ni par Google.", "ready": "Prêt à Utiliser Juxt", - "ready_text": "Commencez par consulter quelques communautés et voyez ce que les gens du monde entier publient. Profitez de cette occasion pour vous familiariser avec Juxt. Vous pourriez faire de nouvelles découvertes en cours de route !", - "done": "Amusez-vous bien sur Juxtaposition !", - "done_button": "C'est Parti !", + "ready_text": "Commencez par consulter quelques communautés et voyez ce que les gens du monde entier publient. Profitez de cette occasion pour vous familiariser avec Juxt. Vous pourriez faire de nouvelles découvertes en cours de route !", + "done": "Amusez-vous bien sur Juxtaposition !", + "done_button": "C'est parti !", "guest": "Mode Invité", "guest_text": "Nous ne pouvons pas vérifier votre compte pour le moment, ce qui signifie probablement que vous vous connectez actuellement avec un compte Nintendo Network. Vous pourrez toujours naviguer sur Juxt, mais vous ne pourrez pas donner des \"Ouais!\" aux publications, ni créer les vôtres tant que vous ne vous serez pas connecté avec un compte Pretendo Network. Pour plus d'informations, consultez le Serveur Discord.", - "guest_button": "Je Comprends" + "guest_button": "Je comprends" } } From 8ecf1edeea38f1032c4c79aa5ef470c42a06dc40 Mon Sep 17 00:00:00 2001 From: lenyet Date: Mon, 9 Dec 2024 21:38:16 +0000 Subject: [PATCH 148/189] locales(update): Updated French locale --- apps/juxtaposition-ui/src/translations/fr.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/fr.json b/apps/juxtaposition-ui/src/translations/fr.json index 714e77d9..e0601fb9 100644 --- a/apps/juxtaposition-ui/src/translations/fr.json +++ b/apps/juxtaposition-ui/src/translations/fr.json @@ -47,7 +47,7 @@ "followers": "Abonnés", "follow_user": "Suivre", "following_user": "Suivi(e)", - "befriend": "Devenir Amis", + "befriend": "Demander en ami", "pending": "En attente", "unfriend": "Retirer des amis", "no_friends": "Aucun ami", From e6216d29d7e9a9f00bac82547c1c69a04ecb4eeb Mon Sep 17 00:00:00 2001 From: Dimitri A Date: Mon, 9 Dec 2024 20:55:46 +0000 Subject: [PATCH 149/189] locales(update): Updated French (Canada) locale --- apps/juxtaposition-ui/src/translations/fr_CA.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/fr_CA.json b/apps/juxtaposition-ui/src/translations/fr_CA.json index 97c4a3bd..b39b498c 100644 --- a/apps/juxtaposition-ui/src/translations/fr_CA.json +++ b/apps/juxtaposition-ui/src/translations/fr_CA.json @@ -30,7 +30,7 @@ "following": "Suivant", "followers": "Followers", "tags": "Taguer", - "posts": "Posters", + "posts": "Publications", "recent": "Posters Récent", "popular": "Posters de Populaire", "verified": "Posters de Vérifié", @@ -40,7 +40,7 @@ "country": "Pays", "birthday": "Anniversaire", "game_experience": "Expérience de Jeux", - "posts": "Posters", + "posts": "Publications", "friends": "Amis", "following": "Suivants", "followers": "Followers", @@ -67,7 +67,7 @@ }, "notifications": { "none": "Sans Notifications.", - "new_follower": "suivi tu!" + "new_follower": "vous suit!" }, "new_post": { "new_post_text": "Nouveau Poster", From c180a6bcec4ffae6dc7155b20eff4f0b47c927a7 Mon Sep 17 00:00:00 2001 From: Dimitri A Date: Tue, 10 Dec 2024 22:03:59 +0000 Subject: [PATCH 150/189] locales(update): Updated French locale --- apps/juxtaposition-ui/src/translations/fr.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/fr.json b/apps/juxtaposition-ui/src/translations/fr.json index e0601fb9..ac8c6eac 100644 --- a/apps/juxtaposition-ui/src/translations/fr.json +++ b/apps/juxtaposition-ui/src/translations/fr.json @@ -71,22 +71,22 @@ "new_follower": "vous suit !" }, "new_post": { - "new_post_text": "Nouvelle Publication", + "new_post_text": "Nouvelle publication", "post_to": "Poster sur", "text_hint": "Touchez ici pour commencer à poster.", "swearing": "Les publications ne peuvent pas contenir de language explicite." }, "messages": { - "coming_soon": "Les messages privés ne sont pas encore disponibles. Revenez bientôt !" + "coming_soon": "Les messages ne sont pas encore disponibles. Revenez bientôt !" }, "setup": { "welcome": "Bienvenue sur Juxtaposition !", - "welcome_text": "Juxt est une communauté de jeu qui connecte les personnes du monde entier à l'aide de personnages Mii. Utilisez Juxt pour partager votre expérience de jeu et rencontrer des gens autour du globe.", + "welcome_text": "Juxt est une communauté de jeu qui rassemble les personnes du monde entier à l'aide de personnages Mii. Utilisez Juxt pour partager votre expérience de jeu et rencontrer des gens autour du globe.", "beta": "BÊTA : AVIS DE NON-GARANTIE", "beta_text": { "first": "Vous êtes sur le point d'essayer la première version bêta publique de Juxt. Cela signifie que beaucoup de choses sont encore en développement et qu'elles peuvent changer à tout moment.", "second": "Cela peut inclure un effacement total de la base de données à la fin ou pendant la période bêta.", - "third": "Le site web, son logiciel et tout le contenu qui s'y trouve sont fournis sur une base \"telle quelle\" et \"telle que disponible\". Le Réseau Pretendo ne donne aucune garantie, expresse ou implicite, quant à l'adéquation ou à la facilité d'utilisation du site web, de son logiciel ou de son contenu." + "third": "Le site web, son logiciel et tout le contenu qui s'y trouve sont fournis « en l'état » et selon leur disponibilité. Le Pretendo Network ne fait aucune garantie, expresse ou implicite, quant à l'adéquation ou à la facilité d'utilisation du site web, de son logiciel ou de son contenu." }, "info": "C'est quoi, Juxtaposition ?", "info_text": "Juxt est une communauté de jeu gérée par les utilisateurs où vous pouvez interagir avec des personnes du monde entier.\nVous pouvez écrire ou dessiner des messages dans les communautés de jeu ou envoyer des messages directement à vos amis.", @@ -117,7 +117,7 @@ "google_text": "Juxtaposition utilise Google Analytics afin de savoir comment les visiteurs interagissent avec notre service. Les données recueillies comprennent, sans s'y limiter, l'heure de visite, les pages visitées et le temps passé sur le site. Ces données ne sont en aucun cas rattachées à votre personne et ne seront pas utilisées à des fins publicitaires, ni par nous ni par Google.", "ready": "Prêt à Utiliser Juxt", "ready_text": "Commencez par consulter quelques communautés et voyez ce que les gens du monde entier publient. Profitez de cette occasion pour vous familiariser avec Juxt. Vous pourriez faire de nouvelles découvertes en cours de route !", - "done": "Amusez-vous bien sur Juxtaposition !", + "done": "Profitez bien de Juxt !", "done_button": "C'est parti !", "guest": "Mode Invité", "guest_text": "Nous ne pouvons pas vérifier votre compte pour le moment, ce qui signifie probablement que vous vous connectez actuellement avec un compte Nintendo Network. Vous pourrez toujours naviguer sur Juxt, mais vous ne pourrez pas donner des \"Ouais!\" aux publications, ni créer les vôtres tant que vous ne vous serez pas connecté avec un compte Pretendo Network. Pour plus d'informations, consultez le Serveur Discord.", From b59cdcff578d7e4045da8f98879c813ecd2ba19c Mon Sep 17 00:00:00 2001 From: Dimitri A Date: Tue, 10 Dec 2024 22:27:16 +0000 Subject: [PATCH 151/189] locales(update): Updated French (Canada) locale --- .../src/translations/fr_CA.json | 98 +++++++++---------- 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/fr_CA.json b/apps/juxtaposition-ui/src/translations/fr_CA.json index b39b498c..af8b192c 100644 --- a/apps/juxtaposition-ui/src/translations/fr_CA.json +++ b/apps/juxtaposition-ui/src/translations/fr_CA.json @@ -1,85 +1,85 @@ { "global": { - "user_page": "Page de Utilisateur", + "user_page": "Page de l'utilisateur", "activity_feed": "Flux d'activité", "communities": "Communautés", "messages": "Messages", "notifications": "Notifications", - "go_back": "Retourner", + "go_back": "Retour", "back": "Revenir", - "yeahs": "Ouias", - "more": "Charger plus posts", - "no_posts": "Sans Posts", + "yeahs": "Ouais", + "more": "Charger plus de publications", + "no_posts": "Aucune publication", "private": "Privé", "close": "Fermer", "save": "Sauvegarder", "exit": "Sortir", - "next": "Prochain" + "next": "Suivant" }, "all_communities": { "announcements": "Annonces", - "popular_places": "Endroit Populaire", - "new_communities": "Nouveau Communautés", - "show_all": "Tout Montrer", - "search": "Chercher Communautés...", - "text": "Tout Communautés", - "ann_string": "Cliquer Ici à Vue Annonces Récent!" + "popular_places": "Communautés populaires", + "new_communities": "Nouvelles communautés", + "show_all": "Tout afficher", + "search": "Rechercher des communautés...", + "text": "Toutes les communautés", + "ann_string": "Cliquez ici pour voir les annonces récentes!" }, "community": { - "follow": "Suivre Communauté", - "following": "Suivant", - "followers": "Followers", - "tags": "Taguer", + "follow": "Suivre la communauté", + "following": "Suivie", + "followers": "Abonnés", + "tags": "Tags", "posts": "Publications", - "recent": "Posters Récent", - "popular": "Posters de Populaire", - "verified": "Posters de Vérifié", - "new": "Nouveau Poster" + "recent": "Publi. récentes", + "popular": "Publi. populaires", + "verified": "Publi. vérifiées", + "new": "Nouvelle publication" }, "user_page": { "country": "Pays", "birthday": "Anniversaire", - "game_experience": "Expérience de Jeux", + "game_experience": "Expérience de joueur", "posts": "Publications", "friends": "Amis", - "following": "Suivants", - "followers": "Followers", + "following": "Abonnements", + "followers": "Abonnés", "follow_user": "Suivre", - "following_user": "Suivants", - "befriend": "Devenir Amis", - "pending": "En Attente", - "unfriend": "Enlever Amis", - "no_friends": "Sans Amis", - "no_following": "Pas Suivants Quiconque", - "no_followers": "Sans Followers" + "following_user": "Suivi(e)", + "befriend": "Demander en ami", + "pending": "En attente", + "unfriend": "Retirer des amis", + "no_friends": "Aucun ami", + "no_following": "Ne suit personne", + "no_followers": "Aucun abonné" }, "user_settings": { - "profile_settings": "Préférences de Profil", - "show_country": "Montrer Pays Sur Profil", - "show_birthday": "Montrer Anniversaire Sur Profil", - "show_game": "Montrer Expérience de Jeux Sur Profil", - "show_comment": "Montrer Commentaire Sur Profile", - "profile_comment": "Commentaire de Profil", + "profile_settings": "Paramètres du profil", + "show_country": "Afficher mon pays sur le profil", + "show_birthday": "Afficher mon anniversaire sur le profil", + "show_game": "Afficher mon expérience de joueur sur le profil", + "show_comment": "Rendre visible le commentaire de mon profil", + "profile_comment": "Commentaire du profil", "swearing": "Commentaire de Profil Pouvoir Pas Contenir Langue Explicite." }, "activity_feed": { "empty": "Son Vide Ici. Essayer Suivants Quelqu'un!" }, "notifications": { - "none": "Sans Notifications.", + "none": "Aucune notification.", "new_follower": "vous suit!" }, "new_post": { - "new_post_text": "Nouveau Poster", + "new_post_text": "Nouvelle publication", "post_to": "Poster à", - "text_hint": "Cliquez Ici à Créer Une Poster.", + "text_hint": "Entrez ici le texte que vous allez publier.", "swearing": "Poster Pouvoir Pas Contenir Langue Explicite." }, "messages": { - "coming_soon": "Messages N'est Pas Prêt Maintenant. Revenir Bientôt!" + "coming_soon": "Les messages ne sont pas encore disponibles. Revenez bientôt!" }, "setup": { - "welcome": "Bienvenue à Juxtaposition!", + "welcome": "Bienvenue sur Juxtaposition!", "welcome_text": "Juxt Est un Communauté de Jeux ça Relier Gens de Tout le Monde Utiliser Personnage Mii. Utiliser Juxt à Partager Ton Expérience de Jeux et Retrouver Gens de Tout le Monde.", "beta": "Bêta Avertissement", "beta_text": { @@ -87,9 +87,9 @@ "second": "Ceci Pouvoir et il se Peut Que Comprendre un Effacer total à le Conclusion ou Pendant le Période Bêta.", "third": "Le site, son Logiciel et Tout Content Trouvé dans il es Fourni il un \"tel quel\" et \"tel disponible\" base. Le Pretendo Network Pouvoir pas Donner du Garantie, si Formel ou Impliquer, Aussi à le Convenir ou Convivialité de le site, et son Logiciel ou si de son Contenu." }, - "info": "Qu'est que Juxtaposition?", + "info": "Qu'est-ce que Juxtaposition?", "info_text": "Juxt est un Utilisateur-Motivé Communauté où tu Pouvoir Interagir avec Gens\nPartout le Montrer. Tu Pouvoir écrire et Dessiner Poster dans Communauté de Jeux ou Envoyer Messages Directement à ton amis.", - "rules": "Règle de Juxt", + "rules": "Règles de Juxt", "rules_text": { "first": "Le suivant sommes quelques lignes directrices d'important pour fabrication de Juxt une expérience de sympa et plaisant pour tout le monde. Le Code de Conduite contenir informations détaillé, donc lire lui minutieusement merci.", "second": "Posters Peut être Regardé à Travers le Monde", @@ -102,25 +102,25 @@ "seventh": "N'oubliez pas, connaître quelqu'un dans Juxt n'est pas la même chose aussi connaître dans le vraie vie. Jamais partager ton adresse e-mail, adresse de maison, nom de travail ou ecole, ou autre informations de identifier personnellement avec n'importe qui sur Juxt, et Jamais partager l'autre n'importe quis informations, de plus, si quelqu'un tu rencontrer dans Juxt inviter tu rencontrer lui ou elle dans le vraie vie, ne accepter pas. Juxt est un communauté en ligne et devoir pas utiliser à vraie vie se retrouver.", "ninth": "Quelques gens venir à Juxt recherche pour \"tips et tricks\" pour jeux, mais autres vouloir faire découvrir secrets de jeux sur leur propre.Posters que révéler secrets de jeux ou intrigue es qui s'appelle \"spoilers.\" si tu es poster quelque chose sur un jeux que il se pourrait que être un spoiler, être sûr à cocher le boîte de spoiler avant de poster tu. Ce façon, gens qui ne vouloir pas à spoiled ne voir pas ton poster.", "eleventh": "Nos objectif est à garder sympa et plaisant dans Juxt. Dans l'événement ça quelqu'un Violer du Juxt Code de Conduite, nous aller agir approprié, allant jusqu'à et inclure bouchage le choquant utilisateur ou console.", - "twelfth": "Avez-vous que tu Jeux ces Jeux?", + "twelfth": "As-tu joué à ce jeu?", "thirteenth": "Si vous publier dans la communauté pour un jeu auquel tu as joué, tes publications aura une icône indiquant que vous l'avez joué." }, - "experience": "Expérience de jeu", + "experience": "Expérience de joueur", "experience_text": { "info": "S'il vous plait dites-nous comment décririez-vous votre niveau d'expérience avec les jeux. Tu peux changer ce paramètre plus tard.", - "beginner": "Débutant/Débutante", + "beginner": "Débutant", "intermediate": "Intermédiaire", - "expert": "Expert/Experte" + "expert": "Expert" }, "google": "Google Analytics", "ready": "Prêt à commencer à utiliser Juxt", "ready_text": "Consultez d’abord certaines communautés et voyez ce que les gens du tout le monde entier publient. Profitez de cette occasion pour vous familiariser avec Juxt. Vous ferez peut-être de nouvelles découvertes en cours de route !", - "done": "Amusez-vous dans Juxt !", + "done": "Amusez-vous dans Juxt!", "done_button": "Allons-y!", "guest": "Mode Invité", "guest_button": "Je Comprends", "guest_text": "Nous ne pouvons pas vérifier votre compte pour le moment, ce qui signifie probablement que vous êtes connecté avec un compte Nintendo Network. Vous pourrez toujours parcourir Juxt, mais vous ne pourrez pas accéder à Yeah! des publiez ou créez vos propres publications jusqu'à ce que vous vous connectiez avec un compte Pretendo Network. Pour plus d'informations, consultez le serveur Discord.", - "google_text": "Juxtaposition utilise Google Analytics pour suivre comment les utilisateurs utilisent notre service.Les données collectées incluent, sans toutefois s'y limiter, le temps de visite, les pages visitées et le temps passé sur le site ne vous sont en aucun cas associées et ne sont pas utilisées à des fins publicitaires par nous ou par Google." + "google_text": "Juxtaposition utilise Google Analytics afin de comprendre comment les utilisateurs utilisent notre service. Les données collectées incluent, sans toutefois s'y limiter, l'heure de visite, les pages visitées et le temps passé sur le site. Ces données ne sont en aucun cas associées à vous et ne seront pas utilisées à des fins publicitaires, ni par nous ni par Google." }, "language": "Français (CA)" } From 65ba74ebf1c3a05fb010db10a13d0671f480c14b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnau=20B=C3=A0rcia?= Date: Fri, 13 Dec 2024 23:47:47 +0000 Subject: [PATCH 152/189] locales(update): Updated Spanish locale --- apps/juxtaposition-ui/src/translations/es.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/es.json b/apps/juxtaposition-ui/src/translations/es.json index 29ec99e7..36d3246c 100644 --- a/apps/juxtaposition-ui/src/translations/es.json +++ b/apps/juxtaposition-ui/src/translations/es.json @@ -58,7 +58,7 @@ "profile_settings": "Preferencias del perfil", "show_country": "Mostrar el país en el perfil", "show_birthday": "Mostrar cumpleaños en el perfil", - "show_game": "Mostrar tu nivel de experiencia como jugador en el perfil", + "show_game": "Mostrar tu nivel como jugador en el perfil", "show_comment": "Mostrar comentario en el perfil", "profile_comment": "Comentario del perfil", "swearing": "Los comentarios no pueden tener lenguaje inapropiado." From 2151dedde646b95f6855df7db9e9051fca063a5b Mon Sep 17 00:00:00 2001 From: Christian Date: Mon, 23 Dec 2024 23:34:36 +0000 Subject: [PATCH 153/189] locales(update): Updated Italian locale --- apps/juxtaposition-ui/src/translations/it.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/it.json b/apps/juxtaposition-ui/src/translations/it.json index 412c050b..28b67284 100644 --- a/apps/juxtaposition-ui/src/translations/it.json +++ b/apps/juxtaposition-ui/src/translations/it.json @@ -29,7 +29,7 @@ "community": { "follow": "Segui comunità", "following": "Seguiti", - "followers": "Seguitori", + "followers": "Seguaci", "posts": "Post", "tags": "Etichette", "recent": "Post recenti", From 51f5ae083a6609527fb2d8be44735b48f4bd6a92 Mon Sep 17 00:00:00 2001 From: Bryan Mainardi Date: Mon, 23 Dec 2024 23:35:15 +0000 Subject: [PATCH 154/189] locales(update): Updated Italian locale --- apps/juxtaposition-ui/src/translations/it.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/it.json b/apps/juxtaposition-ui/src/translations/it.json index 28b67284..d3a94fb5 100644 --- a/apps/juxtaposition-ui/src/translations/it.json +++ b/apps/juxtaposition-ui/src/translations/it.json @@ -52,7 +52,7 @@ "unfriend": "Rimuovi amicizia", "no_friends": "Nessun amico", "no_following": "Non segui nessuno", - "no_followers": "Nessun follower" + "no_followers": "Nessun seguace" }, "user_settings": { "profile_settings": "Impostazioni del profilo", From 4076b0eef514658f276111cfbb276d853114c6ba Mon Sep 17 00:00:00 2001 From: Ellie Rosa Maiella Date: Mon, 23 Dec 2024 23:38:39 +0000 Subject: [PATCH 155/189] locales(update): Updated Italian locale --- apps/juxtaposition-ui/src/translations/it.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/it.json b/apps/juxtaposition-ui/src/translations/it.json index d3a94fb5..b12e4e5e 100644 --- a/apps/juxtaposition-ui/src/translations/it.json +++ b/apps/juxtaposition-ui/src/translations/it.json @@ -116,7 +116,7 @@ "google": "Google Analytics", "google_text": "Juxtaposition utilizza Google Analytics per tracciare il modo in cui gli utenti utilizzano il nostro servizio. I dati raccolti includono ma non si limitano a: momento della visita, pagine visitate e tempo passato sul sito. Questi dati non sono ricollegabili a te in alcun modo, e non sono utilizzati per finalità pubblicitarie da noi o Google.", "ready": "Pronto a iniziare a usare Juxt", - "ready_text": "Per primaa cosa dai un'occhiata a qualche community e scopri di cosa stanno parlando persone da tutto il mondo. Cogli questa opportunità per familiarizzarti con Juxt. Potresti fare nuove scoperte strada facendo!", + "ready_text": "Per prima cosa dai un'occhiata a qualche community e scopri di cosa stanno parlando persone da tutto il mondo. Cogli questa opportunità per familiarizzarti con Juxt. Potresti fare nuove scoperte strada facendo!", "done": "Divertiti in Juxt!", "done_button": "Andiamo!", "guest": "Modalità ospite", From aa2de3cff9ed0bd0586b8e416f535e5f41bcb23e Mon Sep 17 00:00:00 2001 From: Jason Carroll <21anicheallachain@lccgmail.com> Date: Fri, 27 Dec 2024 11:49:18 +0000 Subject: [PATCH 156/189] locales(update): Updated Irish locale --- .../juxtaposition-ui/src/translations/ga.json | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/ga.json b/apps/juxtaposition-ui/src/translations/ga.json index d3ddae02..e4e019c3 100644 --- a/apps/juxtaposition-ui/src/translations/ga.json +++ b/apps/juxtaposition-ui/src/translations/ga.json @@ -17,7 +17,7 @@ "no_posts": "Gan Postálacha" }, "all_communities": { - "announcements": "Fógraí", + "announcements": "Fógraí Pobail", "ann_string": "Cliceáil anseo chun na fograí is deanaí a fheceáil!", "text": "Gach Phobail", "popular_places": "Áiteanna bhfuil gnaoi an phobail air", @@ -63,10 +63,11 @@ "profile_settings": "Socruithe Proifíl" }, "activity_feed": { - "empty": "Tá sé follamh anseo. Trial ag leanúint duine éigin!" + "empty": "Tá sé follamh anseo. Trial chun duine éigin a leanúint!" }, "notifications": { - "none": "Gan fógraí." + "none": "Gan fógraí.", + "new_follower": "- lean siad tú!" }, "new_post": { "post_to": "Postáil chuig", @@ -75,7 +76,22 @@ "new_post_text": "Postáil Nua" }, "setup": { - "welcome": "Fáilte chuig Juxtaposition!" + "welcome": "Fáilte chuig Juxtaposition!", + "welcome_text": "Is pobail cluichíocht é Juxt a nascann daoine timpeall an domhain ag úsáid charactar Mii. Úsáid Juxt chun do taithí cluichíocht a roinnt agus bualadh le daoine timpeall an domhain.", + "beta": "Shéanadh Béite", + "beta_text": { + "first": "Tá tú chun an chead béite poiblí de Juxt a thrial amach. Cialaíonn sé seo go bhfuil rudaí fós neamhcinnte, agus is feidir le go leor athrú in ann tharlú ag aon am.", + "second": "Is féidir agus is féadfaidh go mbeidh scrios iomlán don bunachar sonraí ag deireadh nó i rith an tréimhse béite." + }, + "info": "Cad é Juxtaposition?", + "rules_text": { + "second": "Is Feidir le Postálacha a Fheiceáil Ar Fud an Domhain", + "sixth": "Ná Postáil Eolas Pearsanta atá Leatsa nó Le Duine Eile", + "fourth": "Beidh Go Deas le Daoine Eile", + "third": "Tá go leor phobail cluchíocht i Juxt ina bhfuil daoine ar fud an domhain in ann a smaointe a roinnt. Nuair a cruthaíonn tú postáil, cuimhnigh gur feidir le gach daoine in ann é a fheiceál. Le do thoil, chur tú féin in iúl i mbealach a féidir le gach daoine taitneamh a bhaint as. Úsáid chiall cóiteann, agus smaoineamh roimh a deannan tú postál. Is seirbhís é Juxt a bhfuil ar fháil ar an tIdírlíon freisin. Cuimhnigh gur feidir freisin le dhaoine nach úsáideann Juxt do postálacha a fhecáil. Chomh maith leis sin, feicfear aon trácht a dheannan tú ar postálacha do chairde ag ní hamháin do chairde, ach daoine timpeall an domhain freisin. Le do thoil, cuimhnigh ar seo.", + "fifth": "Chun Juxt a coinnigh mar áit spraoiúil le haghadih gach duine, cuirimis ceist ort a bheidh tuisceanach le húsáideoirí eile. Cabhair linn Juxt a coinnigh mar taithí taitneamhach agus ná postáil rud ar bith atá mí-oiriúnach nó maslach." + }, + "rules": "Rialacha Juxt" }, "language": "Gaeilge", "messages": { From 07e2d5f8490ab68264a06114c5f288d8d34ad712 Mon Sep 17 00:00:00 2001 From: GreatHornedOwl Date: Sat, 28 Dec 2024 15:22:33 +0000 Subject: [PATCH 157/189] locales(update): Updated Indonesian locale --- apps/juxtaposition-ui/src/translations/id.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/id.json b/apps/juxtaposition-ui/src/translations/id.json index d8523179..936deea7 100644 --- a/apps/juxtaposition-ui/src/translations/id.json +++ b/apps/juxtaposition-ui/src/translations/id.json @@ -42,7 +42,9 @@ "second": "Hal ini dapat dan mungkin mencakup penghapusan total basis data para akhir atau selama periode beta." }, "welcome": "Selamat datang ke Juxtaposition (Juxt)!", - "beta": "Pembertitahuan Beta" + "beta": "Pembertitahuan Beta", + "done_button": "Ayo!", + "guest_button": "Saya Mengerti" }, "community": { "follow": "Ikut Komunitas", From 66cabac9a2148790eec1303b39634c08edef6653 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnau=20B=C3=A0rcia?= Date: Sun, 5 Jan 2025 02:22:39 +0000 Subject: [PATCH 158/189] locales(update): Updated Spanish locale --- apps/juxtaposition-ui/src/translations/es.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/es.json b/apps/juxtaposition-ui/src/translations/es.json index 36d3246c..5b887b0a 100644 --- a/apps/juxtaposition-ui/src/translations/es.json +++ b/apps/juxtaposition-ui/src/translations/es.json @@ -47,7 +47,7 @@ "followers": "Seguidores", "follow_user": "Seguir", "following_user": "Sigue a", - "befriend": "Ser amigos", + "befriend": "Solicitud de amistad", "pending": "Pendiente", "unfriend": "Eliminar amigo", "no_friends": "Sin amigos", From 35ea59933d67992bb80e61f1b1660eb95592b12d Mon Sep 17 00:00:00 2001 From: Aedh Date: Wed, 8 Jan 2025 12:32:12 +0000 Subject: [PATCH 159/189] locales(update): Updated French locale --- apps/juxtaposition-ui/src/translations/fr.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/fr.json b/apps/juxtaposition-ui/src/translations/fr.json index ac8c6eac..b3d59193 100644 --- a/apps/juxtaposition-ui/src/translations/fr.json +++ b/apps/juxtaposition-ui/src/translations/fr.json @@ -7,7 +7,7 @@ "messages": "Messages", "notifications": "Notifications", "go_back": "Retour", - "back": "Précedent", + "back": "Précédent", "yeahs": "Ouais", "more": "Voir plus de publications", "no_posts": "Aucune publication", From 4b11016b3a640f7500c2ad705c89b4176dd25c12 Mon Sep 17 00:00:00 2001 From: A Dev Date: Wed, 8 Jan 2025 01:01:02 +0000 Subject: [PATCH 160/189] locales(update): Updated Korean locale --- .../juxtaposition-ui/src/translations/ko.json | 60 +++++++++---------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/ko.json b/apps/juxtaposition-ui/src/translations/ko.json index 7c9d1bc7..4d0363fa 100644 --- a/apps/juxtaposition-ui/src/translations/ko.json +++ b/apps/juxtaposition-ui/src/translations/ko.json @@ -21,21 +21,21 @@ "text": "모든 커뮤니티", "announcements": "공지", "ann_string": "여기를 클릭해서 최근 공지를 확인하세요!", - "popular_places": "유명한 커뮤니티", - "new_communities": "새로운 커뮤니티", + "popular_places": "인기 커뮤니티", + "new_communities": "새 커뮤니티", "show_all": "모두 보기", "search": "커뮤니티 검색..." }, "community": { - "follow": "커뮤니티 팔로우", - "following": "팔로잉", + "follow": "커뮤니티 팔로우하기", + "following": "팔로우 중", "followers": "팔로워", "posts": "게시물", "tags": "태그", "recent": "최근 게시물", "popular": "인기 게시물", "verified": "인증된 게시물", - "new": "새로운 게시물" + "new": "새 게시물" }, "user_page": { "country": "국가", @@ -43,66 +43,66 @@ "game_experience": "게임 경험", "posts": "게시물", "friends": "친구", - "following": "팔로잉", + "following": "팔로우 중", "followers": "팔로워", "follow_user": "팔로우", "following_user": "팔로우 중", "befriend": "친구 추가하기", - "pending": "대기중", + "pending": "대기 중", "unfriend": "친구 제거하기", "no_friends": "친구 없음", - "no_following": "팔로우하는 사람 없음", + "no_following": "팔로우 중인 사람 없음", "no_followers": "팔로워 없음" }, "user_settings": { "profile_settings": "프로필 설정", - "show_country": "프로필에 국가 포시", + "show_country": "프로필에 국가 표시", "show_birthday": "프로필에 생년월일 표시", - "show_game": "프로필에 게임 경혐 표시", + "show_game": "프로필에 게임 경험 표시", "show_comment": "프로필에 메시지 표시", "profile_comment": "프로필 메시지", - "swearing": "프로필 메시지는 노골적인 단어를 포함할 수 없습니다." + "swearing": "프로필 메시지는 비속어를 포함할 수 없습니다." }, "activity_feed": { - "empty": "아무것도 없네요. 누군가를 팔로우해 보세요!" + "empty": "아무도 없네요. 누군가를 팔로우 해 보세요!" }, "notifications": { - "none": "알림은 없어요.", - "new_follower": "가 당신을 팔로우했습니다!" + "none": "알림 없음.", + "new_follower": "(이)가 당신을 팔로우했어요!" }, "new_post": { "new_post_text": "새 게시물", "post_to": "여기로 게시하기", - "text_hint": "여기를 눌러서 게시물을 만드세요.", - "swearing": "게시물에는 노골적인 단어를 포함할 수 없습니다." + "text_hint": "여기를 눌러 새 게시물을 작성하세요.", + "swearing": "게시물에는 비속어를 사용 할 수 없습니다." }, "messages": { "coming_soon": "응 아직 개발 안됨 ㅅㄱ 나중에 다시 와 보세요!" }, "setup": { "welcome": "Juxtaposition에 오신 것을 환영합니다!", - "welcome_text": "Juxt는 Mii 캐릭터를 사용하여 전 세계의 사람들을 잇는 게이밍 커뮤니티입니다. Juxt를 사용해서 게임 경험을 나누고, 전 세계 사람들과 만나세요.", + "welcome_text": "Juxt는 Mii 캐릭터를 사용하여 전 세계의 사람들을 잇는 게이밍 커뮤니티입니다. Juxt를 사용해서 게임 경험을 나누고, 전 세계의 사람들과 소통하세요.", "beta": "베타 테스트 주의", "beta_text": { "first": "당신은 Juxt의 첫 공개 베타에 참가한다는 것을 잊지 마세요. 아직 버그들이 많을 것이며, 언제든지 모든 게 확 바뀔 수 있습니다.", - "second": "베타 기간 중 및 종료 후, 온 데이터베이스가 삭제될 수 있습니다.", - "third": "이 웹사이트 및 그 소프트웨어, 그 외 모든 컨텐츠는 “있는 그대로” 및 “사용 가능한 상태로” 제공됩니다. Pretendo Network는 어떠한 웹사이트, 소프트웨어 또는 콘텐츠의 적합성 및 유용성에 대해 어떠한 명시적·묵시적 보증도 하지 않습니다." + "second": "베타 기간 중 혹은 종료 후에는 전체 데이터베이스가 삭제 될 수도 있습니다.", + "third": "이 웹 사이트 및 그 소프트웨어, 그 외 모든 컨텐츠는 “있는 그대로” 및 “사용 가능한 상태로” 제공됩니다. Pretendo Network는 어떠한 웹사이트, 소프트웨어 또는 콘텐츠의 적합성 및 유용성에 대해 어떠한 명시적·묵시적 보증도 하지 않습니다." }, "info": "Juxtaposition가 무엇이죠?", - "info_text": "유저들이 직접 운영하는 Juxt는 당신이 전 세계의 사람들과 상호 작용할 수 있는\n 게임 커뮤니티입니다. 게임 커뮤니티 내에서 게시물을 작성하거나, 친구에게 직접 메시지를 보낼 수 있습니다.", - "rules": "Juxt 규칙", + "info_text": "유저들이 직접 운영하는 Juxt는 당신이 전 세계의 사람들과 상호 작용할 수 있는\n 게임 커뮤니티입니다. 게임 커뮤니티 내에서 게시물을 작성하거나, 혹은 친구에게 직접 메시지를 보낼 수도 있습니다.", + "rules": "Juxt의 규칙", "rules_text": { - "first": "이하 내용은 Juxt를 모두가 재미있고 편안한 커뮤니티로 만들 수 있기에 앞서, 중요한 내용들입니다. Juxt 행동 강령에는 각 항목에 대해 보다 자세한 내용이 적혀 있으므로, 참고하며 조심히 읽어 주시기 바랍니다.", + "first": "이하 내용은 Juxt를 모두가 재미있고 편안한 커뮤니티로 만들기 위한 중요한 내용들입니다. Juxt의 규칙에는 각 항목에 대해 보다 자세한 내용이 적혀 있으므로, 참고하며 조심히 읽어 주시기 바랍니다.", "second": "게시물은 전 세계에서 볼 수 있습니다", - "third": "Juxt는 전 세계 사람들이 생각을 나눌 수 있는 게임 커뮤니티가 아주 많이 있습니다. 커뮤니티에 게시물을 작성할 시, 모두가 볼 수 있다는 것을 잊지 마시고, 모두가 즐길 수 있는 방식으로 표현해 주시기 바랍니다. 상식적인 게시물들을 작성해 주시기 바라며, 게시 전에 반드시 다시 한번 더 고려해 주시기 바랍니다. Juxt는 인터넷에서도 액세스가 가능하므로, Juxt를 사용하지 않는 사람들도 당신의 게시물를 볼 수 있다는 사실을 기억해 주시기 바랍니다. 추가적으로, 당신이 친구의 게시물에 단 댓글도 친구 뿐만 아니라, 전 세계의 분들도 열람할 수 있습니다. 어떻게 해서든 꼭 기억해주시길 바랍니다.", - "fourth": "타인에게 잘 하자", - "fifth": "Juxt를 모두가 다 같이 즐거운 곳으로 만들기 위해서, 다른 사용자들에게 사려 깊게 행동해 주시는 것을 부탁드립니다. 부적절하거나, 공격적인 내용은 게시를 하지 말아 주세요.", - "sixth": "개인정보를 올리지 말자. 내 개인정보여도’", + "third": "Juxt는 전 세계 사람들이 생각을 나눌 수 있는 게임 커뮤니티가 아주 많이 존재합니다. 커뮤니티에 게시물을 작성할 시, 모두가 볼 수 있다는 것을 잊지 마시고, 모두가 즐길 수 있는 방식으로 표현해 주시기 바랍니다. 상식적인 게시물들을 작성해 주시기 바라며, 게시 전에 반드시 다시 한번 더 고려해 주시기 바랍니다. 또한 Juxt는 인터넷에서도 액세스가 가능하므로, Juxt를 사용하지 않는 사람들도 당신의 게시물을 볼 수 있다는 사실을 기억해 주시길 바랍니다. 그리고 또, 당신이 친구의 게시물에 단 댓글도 친구 뿐만 아니라, 전 세계의 모든 사람들이 다 볼 수 있습니다. 어떻게 해서든 꼭 기억해주시길 바랍니다.", + "fourth": "다른 사람을 잘 대해주세요", + "fifth": "Juxt를 모두가 다 같이 즐거울 수 있는 곳으로 만들기 위해서, 다른 사용자들에게 사려 깊게 행동해 주시는 것을 부탁드립니다. 부적절하거나, 공격적인 내용은 게시를 하지 말아 주세요.", + "sixth": "아무리 자신의 개인정보라도 게시하지 마세요", "seventh": "명심해 주세요, Juxt에서 누군가를 아는 것은 실제 생활에서 누군가를 아는 것이랑 전혀 다릅니다. 절대로 메일 주소, 집 주소, 회사 및 학교명, 타 개인 정보를 Juxt의 누구와도 공유하지 마시고, 타인의 정보도 보내지 마시기 바랍니다. 추가적으로, 만약 Juxt에서 만난 누군가가 실제 생활에서 만나자고 했다면, 승탁하지 마세요. Juxt는 온라인 커뮤니티이며, 실제 생활에서의 미팅을 만드는 용도로 쓰이지 말아야 합니다.", - "eighth": "스포는 게시하지 말자", + "eighth": "스포일러는 게시하지 말아주세요", "ninth": "몇몇 사람들은 게임 내 팁 등을 찾으러 Juxt에 오지만, 다른 사람들은 게임의 비밀을 직접 찾고 싶을 겁니다. 게임 내 비밀이나 스토리를 밝히는 게시물을 \"스포일러\"라고 불립니다. 만약 게임과 관련된, 스포가 될 만한 정보를 게시하려고 하고 있다면, 게시물을 게시하기 전에 스포일러 박스를 체크하는 것을 잊지 마세요. 이렇게 하면, 스포당하고 싶지 않은 사람들은 당신의 게시물을 보지 않을 겁니다.", - "tenth": "행동 강령 위반", - "eleventh": "저희의 목표는 Juxt가 모두가 재미있고 즐길 수 있는 커뮤니티임을 유지하는 것입니다. 만약 누군가가 Juxt 행동 강령을 위반했다면, 저희가 적절하다고 판단한 조치를 취할 것입니다. 잘못하면 그 유저나 콘솔을 차단할 수도 있죠.", + "tenth": "규칙 위반", + "eleventh": "저희의 목표는 Juxt가 모두가 재미있고 즐길 수 있는 커뮤니티임을 유지하는 것입니다. 만약 누군가가 Juxt의 규칙을 위반했다면, 저희가 적절하다고 판단한 조치를 취할 것입니다. 잘못하면 그 유저나 콘솔을 차단할 수도 있죠.", "twelfth": "그 게임 해봤어?", "thirteenth": "만약 당신이 해본 게임의 커뮤니티에 게시물을 작성하면, 작성한 게시물에 이 게임을 플레이 했다는 아이콘이 뜰 것입니다." }, @@ -120,7 +120,7 @@ "done": "Juxt에서 좋은 시간을 보내시기 바랍니다!", "done_button": "가자!", "guest": "게스트 모드", - "guest_text": "어라? 계정을 확인할 수 없네요. 닌텐도 네트워크로 로그인을 하신 걸 수도 있어요. Juxt를 둘러보실 수는 있지만, '당근이지!'를 게시물에 달거나 게시물을 만드는 것은 Pretendo 네트워크로 로그인하면 Juxt의 모든 기능을 사용하실 수 있어요. 더 많은 정보는 디스코드 서버를 확인해주세요.", + "guest_text": "어라? 계정을 확인할 수 없네요. 닌텐도 네트워크로 로그인을 하신 걸 수도 있어요. Juxt를 둘러보실 수는 있지만, '당근이지!'를 게시물에 달거나 게시물을 만드는 것은 안되지만, Pretendo 네트워크로 로그인하면 Juxt의 모든 기능을 사용하실 수 있어요. 더 많은 정보는 디스코드 서버를 확인해주세요.", "guest_button": "알겠어요" } } From 1a730bff713a88ea8480eb6b4e66e3ef5d01eb4e Mon Sep 17 00:00:00 2001 From: Ellie Rosa Maiella Date: Sat, 18 Jan 2025 11:31:08 +0000 Subject: [PATCH 161/189] locales(update): Updated Italian locale --- apps/juxtaposition-ui/src/translations/it.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/it.json b/apps/juxtaposition-ui/src/translations/it.json index b12e4e5e..c95ca699 100644 --- a/apps/juxtaposition-ui/src/translations/it.json +++ b/apps/juxtaposition-ui/src/translations/it.json @@ -80,7 +80,7 @@ "coming_soon": "La funzionalità di messaggistica non è ancora pronta. Ricontrolla presto!" }, "setup": { - "welcome": "Benvenuto su Juxtaposition!", + "welcome": "Benvenuto/a su Juxtaposition!", "welcome_text": "Juxt è una community di gioco che connette persone da tutto il mondo attraverso personaggi Mii. Usa Juxt per condividere le tue esperienze di gioco e incontrare persone da tutto il mondo.", "beta": "Disclaimer beta", "beta_text": { From ff58ec829ba56c9ff8dfa21703f4185c799f0ce8 Mon Sep 17 00:00:00 2001 From: Atto Date: Tue, 21 Jan 2025 10:31:18 +0000 Subject: [PATCH 162/189] locales(update): Updated Swedish locale --- apps/juxtaposition-ui/src/translations/sv.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/sv.json b/apps/juxtaposition-ui/src/translations/sv.json index a595e796..b11835c9 100644 --- a/apps/juxtaposition-ui/src/translations/sv.json +++ b/apps/juxtaposition-ui/src/translations/sv.json @@ -57,15 +57,15 @@ "close": "Stäng", "save": "Spara", "no_posts": "Inga Inlägg", - "yeahs": "Jan", + "yeahs": "Ja:n", "private": "Privat", "more": "Ladda Mer Inlägg" }, "all_communities": { - "text": "Alla Samhällen", + "text": "Alla Gemenskap", "announcements": "Uttalanden", - "new_communities": "Nya Samhällen", - "search": "Sök samhällen...", + "new_communities": "Nya gemenskap", + "search": "Sök gemenskap...", "show_all": "Visa Allt", "popular_places": "Populära Ställen", "ann_string": "Klicka här för att visa de nyligen skapade uttalandena!" @@ -82,7 +82,7 @@ "community": { "following": "Följer", "tags": "Taggar", - "follow": "Följ Samhälle", + "follow": "Följ gemenskap", "posts": "Inlägg", "followers": "Följare", "verified": "Verifierade Inlägg", From e72b790668f72166b27f8958c54d8ef154bdfdf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vuka=C5=A1in=20=C4=8Ce=C4=8Den?= Date: Wed, 22 Jan 2025 16:41:51 +0000 Subject: [PATCH 163/189] locales(update): Updated Serbian locale --- apps/juxtaposition-ui/src/translations/sr.json | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/sr.json b/apps/juxtaposition-ui/src/translations/sr.json index f9eab702..1ee56d30 100644 --- a/apps/juxtaposition-ui/src/translations/sr.json +++ b/apps/juxtaposition-ui/src/translations/sr.json @@ -70,7 +70,19 @@ }, "experience_text": { "beginner": "Početnik", - "intermediate": "Srednji" - } + "intermediate": "Srednji", + "expert": "Ekspert", + "info": "Molimo vas da opišete vaš nivo iskustva sa igricama. Ovo podešavanje se može promeniti kasnije." + }, + "beta_text": { + "second": "Ovo može podrazumevati brisanje cele baze podataka po završetku ili za vreme probnog perioda." + }, + "experience": "Iskustvo sa Igricama", + "google": "Google Analitika", + "google_text": "Juxtaposition koristi Google Analitiku kako bi pratilo kako korisnici koriste naš servis. Prikupljene informacije uključuju ali nisu ograničene na vreme posete, posećene strane i vreme provedeno na sajtu. Ovi podatci nisu lično asocirani i neće biti korišćene u svrhe reklama od strane nas ili Google-a.", + "ready": "Spremni da Koristite Juxt", + "done": "Uživajte u Juxt-u!", + "done_button": "Krenimo!", + "ready_text": "Prvo proverite zajednice i vidite o čemu ljudi objavljuju oko celog sveta. Iskoristite ovu priliku da se upoznate sa Juxt-om. Možda ćete napraviti zanimljiva otkrića!" } } From a7c1a5e88d1be021c513bab1824299fa44dc08d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E0=AE=A4=E0=AE=AE=E0=AE=BF=E0=AE=B4=E0=AF=8D=E0=AE=A8?= =?UTF-8?q?=E0=AF=87=E0=AE=B0=E0=AE=AE=E0=AF=8D?= Date: Mon, 27 Jan 2025 16:54:13 +0100 Subject: [PATCH 164/189] locales(add): Added Tamil locale --- apps/juxtaposition-ui/src/translations/ta.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/juxtaposition-ui/src/translations/ta.json diff --git a/apps/juxtaposition-ui/src/translations/ta.json b/apps/juxtaposition-ui/src/translations/ta.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/apps/juxtaposition-ui/src/translations/ta.json @@ -0,0 +1 @@ +{} From 444926f1c983101366ccdf59747893ec029a0741 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E0=AE=A4=E0=AE=AE=E0=AE=BF=E0=AE=B4=E0=AF=8D=E0=AE=A8?= =?UTF-8?q?=E0=AF=87=E0=AE=B0=E0=AE=AE=E0=AF=8D?= Date: Mon, 27 Jan 2025 16:25:51 +0000 Subject: [PATCH 165/189] locales(update): Updated Tamil locale --- .../juxtaposition-ui/src/translations/ta.json | 127 +++++++++++++++++- 1 file changed, 126 insertions(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/ta.json b/apps/juxtaposition-ui/src/translations/ta.json index 0967ef42..731522f3 100644 --- a/apps/juxtaposition-ui/src/translations/ta.json +++ b/apps/juxtaposition-ui/src/translations/ta.json @@ -1 +1,126 @@ -{} +{ + "setup": { + "info": "சுருக்கம் என்றால் என்ன?", + "rules": "Juxts விதிகள்", + "guest_button": "எனக்குப் புரிகிறது", + "welcome": "சுருக்கத்திற்கு வருக!", + "welcome_text": "MIIXT என்பது ஒரு கேமிங் சமூகம், இது உலகெங்கிலும் உள்ள மக்களை MII எழுத்துக்களைப் பயன்படுத்தி இணைக்கிறது. உங்கள் கேமிங் அனுபவங்களைப் பகிர்ந்து கொள்ளவும், உலகெங்கிலும் உள்ளவர்களைச் சந்திக்கவும் சாக்ச்டைப் பயன்படுத்தவும்.", + "beta": "பீட்டா மறுப்பு", + "beta_text": { + "second": "இது முடிவில் அல்லது பீட்டா காலகட்டத்தில் தரவுத்தளத்தின் மொத்த துடைப்பைக் கொண்டிருக்கலாம்.", + "third": "வலைத்தளம், அதன் மென்பொருள் மற்றும் அதில் காணப்படும் அனைத்து உள்ளடக்கங்களும் “இருப்பது” மற்றும் “கிடைக்கக்கூடிய” அடிப்படையில் வழங்கப்படுகின்றன. வலைத்தளத்தின், அதன் மென்பொருள் அல்லது அதன் எந்தவொரு உள்ளடக்கத்தின் பொருந்தக்கூடிய தன்மை அல்லது பயன்பாட்டினைப் பொறுத்தவரை, எக்ச்பிரச் அல்லது மறைமுகமாக இருந்தாலும் ப்ரெடெண்டோ பிணையம் எந்த உத்தரவாதங்களையும் கொடுக்கவில்லை.", + "first": "நீங்கள் முதல் பொது பீட்டாவை முயற்சிக்க உள்ளீர்கள். இதன் பொருள் நிறைய காற்றில் உள்ளது, மேலும் எந்த நேரத்திலும் நிறைய மாறலாம்." + }, + "rules_text": { + "first": "அனைவருக்கும் வேடிக்கையான மற்றும் சுவையான அனுபவமாக மாற்றுவதற்கான சில முக்கியமான வழிகாட்டுதல்கள் பின்வருமாறு. நடத்தை நெறிமுறையில் விரிவான தகவல்கள் உள்ளன, எனவே தயவுசெய்து அதைக் கவனமாகப் படியுங்கள்.", + "second": "இடுகைகளை உலகம் முழுவதும் காணலாம்", + "third": "உலகெங்கிலும் உள்ள மக்கள் தங்கள் எண்ணங்களைப் பகிர்ந்து கொள்ளக்கூடிய பல கேமிங் சமூகங்கள் உள்ளன. நீங்கள் ஒரு சமூகத்தில் இடுகையிடும்போது, எல்லோரும் அதைப் பார்க்க முடியும் என்பதை நினைவில் கொள்ளுங்கள், எனவே எல்லோரும் அனுபவிக்கக்கூடிய வகையில் உங்களை வெளிப்படுத்துங்கள். பொது அறிவைப் பயன்படுத்துங்கள், நீங்கள் இடுகையிடுவதற்கு முன் சிந்தியுங்கள். JUXT என்பது இணையத்திலிருந்து அணுகக்கூடிய ஒரு சேவையாகும், எனவே உங்கள் இடுகைகளைப் பயன்படுத்தாதவர்களும் பார்க்கக்கூடும் என்பதை நினைவில் கொள்ளுங்கள். கூடுதலாக, உங்கள் நண்பர்களின் இடுகைகளில் நீங்கள் செய்யும் எந்தவொரு கருத்துகளும் உங்கள் நண்பர்களால் மட்டுமல்ல, உலகெங்கிலும் உள்ளவர்களால் பார்க்கப்படும். இதை மனதில் கொள்ளுங்கள்.", + "fourth": "ஒருவருக்கொருவர் நன்றாக இருங்கள்", + "fifth": "அனைவருக்கும் ஒரு வேடிக்கையான இடத்தை வைத்திருக்க, நீங்கள் மற்ற பயனர்களிடம் அக்கறை காட்டுமாறு கேட்டுக்கொள்கிறோம். பொருத்தமற்ற அல்லது தாக்குதல் எதையும் இடுகையிடாமல் ஒரு சுவையான அனுபவத்தை வைத்திருக்க எங்களுக்கு உதவுங்கள்.", + "eighth": "ச்பாய்லர்களை இடுகையிட வேண்டாம்", + "tenth": "நடத்தை விதிமுறை மீறல்கள்", + "twelfth": "நீங்கள் அந்த விளையாட்டை விளையாடியிருக்கிறீர்களா?", + "sixth": "தனிப்பட்ட தகவல்களை இடுகையிட வேண்டாம் - உங்கள் அல்லது பிறர் உடையது", + "eleventh": "அனைவருக்கும் வேடிக்கையாகவும் சுவாரச்யமாகவும் இருப்பதே எங்கள் குறிக்கோள். யாரோ ஒருவர் நடத்தை விதிமுறைகளை மீறும்போது, புண்படுத்தும் பயனர் அல்லது கன்சோலைத் தடுப்பது உட்பட, நாங்கள் தகுந்த நடவடிக்கை எடுப்போம்.", + "seventh": "நினைவில் கொள்ளுங்கள், ஒருவரைத் தெரிந்துகொள்வது நிச வாழ்க்கையில் அவர்களை அறிந்து கொள்வதற்கு சமமானதல்ல. உங்கள் மின்னஞ்சல் முகவரி, வீட்டு முகவரி, வேலை அல்லது பள்ளி பெயர் அல்லது பிற தனிப்பட்ட முறையில் அடையாளம் காணும் பிற தகவல்களை ஒருபோதும் பகிர வேண்டாம், வேறு யாருடைய தகவலையும் பகிர வேண்டாம். கூடுதலாக, நீங்கள் சந்திக்கும் ஒருவர் உண்மையான உலகில் அவரை அல்லது அவளைச் சந்திக்க உங்களை அழைத்தால், ஏற்றுக்கொள்ள வேண்டாம். JUXT என்பது ஒரு நிகழ்நிலை சமூகம் மற்றும் நிச உலக சந்திப்புகளை ஏற்பாடு செய்யப் பயன்படுத்தக் கூடாது.", + "ninth": "சிலர் விளையாட்டுகளுக்கான உதவிக்குறிப்புகள் மற்றும் தந்திரங்களைத் தேடி வருகிறார்கள், ஆனால் மற்றவர்கள் ஒரு விளையாட்டின் ரகசியங்களைச் சொந்தமாகக் கண்டுபிடிக்க விரும்புகிறார்கள். ஒரு விளையாட்டின் ரகசியங்களை அல்லது அதன் கதையை வெளிப்படுத்தும் இடுகைகள் \"ச்பாய்லர்கள்\" என்று அழைக்கப்படுகின்றன. ச்பாய்லராக இருக்கும் ஒரு விளையாட்டைப் பற்றி நீங்கள் ஏதாவது இடுகையிடுகிறீர்கள் என்றால், உங்கள் இடுகையை அனுப்புவதற்கு முன்பு ச்பாய்லர்கள் பெட்டியைச் சரிபார்க்கவும். இந்த வழியில், கெட்டுப்போக விரும்பாதவர்கள் உங்கள் இடுகையைப் பார்க்கமாட்டார்கள்.", + "thirteenth": "நீங்கள் விளையாடிய ஒரு விளையாட்டுக்காகச் சமூகத்தில் இடுகையிடுகிறீர்கள் என்றால், உங்கள் இடுகைகளில் நீங்கள் அதை விளையாடியதைக் குறிக்கும் படவுரு இருக்கும்." + }, + "experience": "விளையாட்டு பட்டறிவு", + "experience_text": { + "info": "விளையாட்டுகளுடனான உங்கள் அனுபவத்தை நீங்கள் எவ்வாறு விவரிப்பீர்கள் என்பதை எங்களுக்குத் தெரிவிக்கவும். இந்த அமைப்பை நீங்கள் பின்னர் மாற்றலாம்.", + "intermediate": "இடைநிலை", + "expert": "வல்லுநர்", + "beginner": "தொடக்கம்" + }, + "google": "கூகிள் பகுப்பாய்வியல்", + "google_text": "பயனர்கள் எங்கள் சேவையை எவ்வாறு பயன்படுத்துகிறார்கள் என்பதைக் கண்டறிய Google Analytics ஐப் பயன்படுத்துகிறது. சேகரிக்கப்பட்ட தரவுகளில் வருகை நேரம், பார்வையிட்ட பக்கங்கள் மற்றும் தளத்தில் செலவழித்த நேரம் ஆகியவை அடங்கும். இந்தத் தரவு உங்களுடன் எந்த வகையிலும் இணைக்கப்படவில்லை, மேலும் இது அமெரிக்கா அல்லது கூகிள் விளம்பரங்களுக்குப் பயன்படுத்தப்படவில்லை.", + "ready": "JUXT ஐப் பயன்படுத்தத் தயாராக உள்ளது", + "ready_text": "முதலில் சில சமூகங்களைப் பார்த்து, உலகம் முழுவதிலுமிருந்து மக்கள் எதைப் பற்றி இடுகையிடுகிறார்கள் என்பதைப் பாருங்கள். இந்த வாய்ப்பை நீங்களே பழக்கப்படுத்திக்கொள்ள இந்த வாய்ப்பைப் பயன்படுத்துங்கள். நீங்கள் சில புதிய கண்டுபிடிப்புகளைச் செய்யலாம்!", + "done": "வேடிக்கையாக இருங்கள்!", + "done_button": "போகலாம்!", + "guest": "விருந்தினர் பயன்முறை", + "info_text": "JUXT ஒரு பயனர் உந்துதல் கேமிங் சமூகமாகும், அங்கு நீங்கள் மக்களுடன் தொடர்பு கொள்ளலாம்\n உலகம் முழுவதும். நீங்கள் விளையாட்டு சமூகங்களில் இடுகைகளை எழுதலாம் அல்லது வரையலாம் அல்லது உங்கள் நண்பர்களுக்கு நேரடியாகச் செய்திகளை அனுப்பலாம்.", + "guest_text": "இந்த நேரத்தில் உங்கள் கணக்கை எங்களால் சரிபார்க்க முடியாது, அதாவது நீங்கள் தற்போது ஒரு நிண்டெண்டோ பிணையம் கணக்கில் உள்நுழைகிறீர்கள். நீங்கள் இன்னும் சாக்ச்ட்டை உலாவ முடியும், ஆனால் நீங்கள் ஆம் என்று முடியாது! ப்ரெடெண்டோ பிணையம் கணக்கில் உள்நுழையும் வரை இடுகைகள் அல்லது உங்கள் சொந்த இடுகைகளை உருவாக்கவும். மேலும் தகவலுக்கு டிச்கார்ட் சேவையகத்தைச் சரிபார்க்கவும்." + }, + "global": { + "user_page": "பயனர் பக்கம்", + "activity_feed": "செயல்பாட்டு ஊட்டம்", + "communities": "சமூகங்கள்", + "messages": "செய்திகள்", + "notifications": "அறிவிப்புகள்", + "back": "பின்", + "yeahs": "ஆம்", + "go_back": "திரும்பிச் செல்", + "more": "மேலும் இடுகைகளை ஏற்றவும்", + "no_posts": "பதிவுகள் இல்லை", + "private": "தனிப்பட்ட", + "close": "மூடு", + "save": "சேமி", + "exit": "வெளியேறு", + "next": "அடுத்தது" + }, + "all_communities": { + "text": "அனைத்து சமூகங்களும்", + "announcements": "அறிவிப்புகள்", + "ann_string": "அண்மைக் கால அறிவிப்புகளைக் காண இங்கே சொடுக்கு செய்க!", + "new_communities": "புதிய சமூகங்கள்", + "show_all": "அனைத்தையும் காட்டு", + "popular_places": "பெயர்பெற்ற இடங்கள்", + "search": "சமூகங்களைத் தேடு..." + }, + "community": { + "follow": "சமூகத்தைப் பின்பற்றுங்கள்", + "followers": "பின்தொடர்பவர்கள்", + "posts": "இடுகைகள்", + "tags": "குறிச்சொற்கள்", + "recent": "அண்மைக் கால இடுகைகள்", + "following": "பின்தொடர்கிறது", + "verified": "சரிபார்க்கப்பட்ட பதிவுகள்", + "new": "புதிய இடுகை", + "popular": "பெயர்பெற்ற இடுகைகள்" + }, + "user_page": { + "country": "நாடு", + "birthday": "பிறந்த நாள்", + "game_experience": "விளையாட்டு பட்டறிவு", + "posts": "இடுகைகள்", + "friends": "நண்பர்கள்", + "followers": "பின்தொடர்பவர்கள்", + "follow_user": "பின்தொடர்", + "befriend": "நட்பு", + "pending": "நிலுவையில் உள்ளது", + "no_friends": "நண்பர்கள் இல்லை", + "following": "பின்தொடர்கிறது", + "following_user": "பின்தொடர்கிறது", + "no_following": "யாரையும் பின்பற்றவில்லை", + "no_followers": "பின்தொடர்பவர்கள் இல்லை", + "unfriend": "நட்புவிலக்கம்" + }, + "user_settings": { + "show_country": "தன்விவரக்குறிப்பில் நாட்டைக் காட்டு", + "show_birthday": "தன்விவரக்குறிப்பில் பிறந்தநாளைக் காட்டு", + "show_game": "தன்விவரக்குறிப்பில் விளையாட்டு அனுபவத்தைக் காட்டு", + "profile_comment": "தன்விவரக்குறிப்பு கருத்து", + "show_comment": "தன்விவரக்குறிப்பில் கருத்தைக் காட்டு", + "swearing": "தன்விவரக்குறிப்புக் கருத்தில் வெளிப்படையான மொழியைக் கொண்டிருக்க முடியாது.", + "profile_settings": "தன்விவரக்குறிப்பு அமைப்புகள்" + }, + "activity_feed": { + "empty": "இது இங்கே காலியாக உள்ளது. யாரையாவது பின்தொடர முயற்சிக்கவும்!" + }, + "notifications": { + "none": "அறிவிப்புகள் இல்லை.", + "new_follower": "உங்களைப் பின்தொடர்ந்தார்!" + }, + "new_post": { + "new_post_text": "புதிய இடுகை", + "text_hint": "ஒரு இடுகையை உருவாக்க இங்கே தட்டவும்.", + "swearing": "இடுகையில் வெளிப்படையான மொழியைக் கொண்டிருக்க முடியாது.", + "post_to": "இடுகை இதற்கு" + }, + "messages": { + "coming_soon": "செய்திகள் இன்னும் தயாராக இல்லை. விரைவில் சரிபார்க்கவும்!" + }, + "language": "தமிழ்" +} From 3003fce1b394917434da69c29b7908601f776c65 Mon Sep 17 00:00:00 2001 From: Evan Lie Date: Thu, 30 Jan 2025 01:41:48 +0000 Subject: [PATCH 166/189] locales(update): Updated Indonesian locale --- .../juxtaposition-ui/src/translations/id.json | 47 ++++++++++++++++--- 1 file changed, 40 insertions(+), 7 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/id.json b/apps/juxtaposition-ui/src/translations/id.json index 936deea7..155b01ca 100644 --- a/apps/juxtaposition-ui/src/translations/id.json +++ b/apps/juxtaposition-ui/src/translations/id.json @@ -3,7 +3,7 @@ "user_page": "Halaman Pengguna", "communities": "Komunitas", "activity_feed": "Halaman Aktivitas", - "messages": "Pesan", + "messages": "Pesan-pesan", "notifications": "Notifikasi", "go_back": "Kembali", "back": "Kembali", @@ -39,19 +39,52 @@ "welcome_text": "Juxt adalah komunitas game yang menghubungan orang-orang dari seluruh dunia menggunakan karakter Mii. Gunakan Juxt untuk berbagi pengalaman bermain game anda dan bertemu orang-orang dari seluruh dunia.", "beta_text": { "first": "Anda akan mencoba versi beta publik pertama Juxt. Artinya, masih banyak hal yang belum terealisasi, dan banyak hal yang bisa berubah kapan saja.", - "second": "Hal ini dapat dan mungkin mencakup penghapusan total basis data para akhir atau selama periode beta." + "second": "Hal ini dapat dan mungkin mencakup penghapusan total basis data para akhir atau selama periode beta.", + "third": "Situs web, perangkat lunaknya, dan semua konten yang terdapat di dalamnya disediakan atas dasar \"apa adanya\" dan \"sebagaimana tersedia\". Pretendo Network tidak memberikan jaminan apa pun, baik tersurat maupun tersirat, mengenai kesesuaian atau kegunaan situs web, perangkat lunaknya, atau konten apa pun di dalamnya." }, "welcome": "Selamat datang ke Juxtaposition (Juxt)!", "beta": "Pembertitahuan Beta", "done_button": "Ayo!", - "guest_button": "Saya Mengerti" + "guest_button": "Saya Mengerti", + "experience": "Pengalaman Permainan", + "rules_text": { + "first": "Berikut ini adalah beberapa aturan penting untuk menjadikan Juxt sebagai pengalaman yang menyenangkan dan mengasyikkan bagi semua orang. Kode Etik Juxt memuat informasi terperinci, jadi harap baca dengan saksama.", + "third": "Juxt berisi banyak komunitas game tempat orang-orang dari seluruh dunia dapat berbagi pemikiran mereka. Saat anda memposting di suatu komunitas, ingatlah bahwa semua orang dapat melihatnya, jadi harap ekspresikan diri anda dengan cara yang dapat dinikmati semua orang. Gunakan akal sehat, dan pikirkan sebelum anda memposting. Juxt adalah layanan yang juga dapat diakses dari Internet, jadi perlu diingat bahwa orang yang tidak menggunakan Juxt juga dapat melihat postingan Anda. Selain itu, komentar apa pun yang anda buat pada postingan teman-teman anda tidak hanya akan dilihat oleh teman-teman anda, tetapi juga oleh orang-orang di seluruh dunia. Harap diingat hal ini.", + "sixth": "Jangan Memposting Informasi Pribadi—Informasi Anda atau Informasi Orang Lain", + "eighth": "Jangan Postingan Spoiler", + "eleventh": "Tujuan kami adalah menjaga Juxt tetap menyenangkan dan menghibur bagi semua orang. Jika ada yang melanggar Kode Etik Juxt, kami akan mengambil tindakan yang sesuai, termasuk memblokir pengguna atau konsol yang melanggar.", + "thirteenth": "Jika Anda mengepos di komunitas tentang permainan yang pernah Anda mainkan, pos Anda akan memiliki ikon yang menunjukkan bahwa Anda telah memainkannya.", + "fourth": "Bersikap Baik Terhadap Satu Sama Lain", + "seventh": "Ingat, mengenal seseorang di Juxt tidak sama dengan mengenalnya di dunia nyata. Jangan pernah membagikan alamat email, alamat rumah, nama kantor atau sekolah, atau informasi pengenal pribadi lainnya dengan siapa pun di Juxt, dan jangan pernah membagikan informasi orang lain juga. Selain itu, jika seseorang yang anda temui di Juxt mengundang Anda untuk bertemu dengannya di dunia nyata, jangan terima. Juxt adalah komunitas daring dan tidak boleh digunakan untuk mengatur pertemuan di dunia nyata.", + "second": "Postingan Dapat Dilihat di Seluruh Dunia", + "fifth": "Agar Juxt tetap menjadi tempat yang menyenangkan bagi semua orang, kami meminta anda untuk bersikap baik kepada pengguna lain. Bantu kami agar Juxt tetap menjadi pengalaman yang menyenangkan dengan tidak mengunggah sesuatu yang tidak pantas atau menyinggung.", + "tenth": "Pelanggaran Kode Etik", + "ninth": "Beberapa orang datang ke Juxt untuk mencari tips dan trik permainan, tetapi yang lain ingin menemukan sendiri rahasia permainan. Postingan yang mengungkap rahasia permainan atau ceritanya disebut \"spoiler.\" Jika anda memposting sesuatu tentang permainan yang mungkin merupakan spoiler, pastikan untuk mencentang kotak \"Spoiler\" sebelum mengirim postingan anda. Dengan cara ini, orang yang tidak ingin mengetahui spoiler tidak akan melihat postingan anda.", + "twelfth": "Pernahkah Anda Memainkan Game Itu?" + }, + "rules": "Aturan Juxt", + "experience_text": { + "info": "Harap beri tahu kami bagaimana Anda menggambarkan tingkat pengalaman Anda dengan gim. Anda dapat mengubah pengaturan ini nanti.", + "intermediate": "Intermediat", + "expert": "Pakar", + "beginner": "Pemula" + }, + "ready_text": "Pertama, kunjungi beberapa komunitas dan lihat apa yang diposting orang-orang dari seluruh dunia. Manfaatkan kesempatan ini untuk mengenal Juxt lebih jauh. Anda mungkin akan menemukan beberapa hal baru di sepanjang perjalanan!", + "done": "Bersenang-senanglah di Juxt!", + "google": "Google Analytics", + "ready": "Siap untuk Mulai Menggunakan Juxt", + "guest": "Mode Tamu", + "info_text": "Juxt adalah komunitas game yang digerakkan oleh pengguna tempat anda dapat berinteraksi dengan orang-orang\n di seluruh dunia. Anda dapat menulis atau menggambar postingan di komunitas game atau mengirim pesan langsung ke teman-teman anda.", + "guest_text": "Kami tidak dapat memverifikasi akun anda saat ini, yang kemungkinan berarti Anda saat ini masuk dengan akun Nintendo Network. Anda masih dapat menjelajahi Juxt, tetapi anda tidak akan dapat memposting Ya! atau membuat postingan sendiri hingga anda masuk dengan akun Pretendo Network. Untuk informasi lebih lanjut, lihat di server Discord.", + "google_text": "Juxt menggunakan Google Analytics untuk melacak bagaimana pengguna menggunakan layanan kami. Data yang dikumpulkan termasuk tetapi tidak terbatas pada waktu kunjungan, halaman yang dikunjungi, dan waktu yang dihabiskan di situs. Data ini tidak dikaitkan dengan Anda dengan cara apa pun, dan tidak digunakan untuk iklan oleh kami atau Google.", + "info": "Apa itu Juxtaposition?" }, "community": { "follow": "Ikut Komunitas", "following": "Mengikuti", "followers": "Pengikutas", "posts": "Postingan", - "tags": "Tags", + "tags": "Label", "recent": "Postingan Terkini", "popular": "Postingan Populer", "verified": "Postingan Diverifikasi", @@ -62,7 +95,7 @@ "birthday": "Ulang Tahun", "game_experience": "Pengalaman Permainan", "posts": "Postingan", - "friends": "Teman", + "friends": "Teman-Teman", "following": "Mengikuti", "followers": "Pengikutas", "follow_user": "Mengikut", @@ -72,7 +105,7 @@ "unfriend": "Hapus Teman", "no_friends": "Tidak ada Teman", "no_following": "Tidak Mengikuti Orang", - "no_followers": "Tidak ada Pengikutas" + "no_followers": "Tidak Ada Pengikutas" }, "activity_feed": { "empty": "Tidak ada apa-apa di sini. Coba mengikut orang!" @@ -88,6 +121,6 @@ "swearing": "Postingan tidak boleh mengandung bahasa eksplisit." }, "messages": { - "coming_soon": "Pessan belum siap sekarang. Segara periksa kembali!" + "coming_soon": "Pesan-Pesan belum siap sekarang. Segara periksa kembali!" } } From 1652879af909a040ff808c9f4d7dd35cfb9cf7b6 Mon Sep 17 00:00:00 2001 From: Svyatoslav Date: Sat, 1 Feb 2025 22:02:54 +0000 Subject: [PATCH 167/189] locales(update): Updated Ukrainian locale --- apps/juxtaposition-ui/src/translations/uk.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/uk.json b/apps/juxtaposition-ui/src/translations/uk.json index 3be972ad..f2635a6f 100644 --- a/apps/juxtaposition-ui/src/translations/uk.json +++ b/apps/juxtaposition-ui/src/translations/uk.json @@ -12,7 +12,7 @@ "activity_feed": "Стрічка Активності", "notifications": "Сповіщення", "go_back": "Повернутися", - "yeahs": "Погодження", + "yeahs": "Так", "next": "Наступне", "exit": "Вихід" }, @@ -27,9 +27,9 @@ }, "community": { "follow": "Підписатися на спільноту", - "following": "Підписан", - "tags": "Теги", - "followers": "Підписчики", + "following": "Підписані", + "tags": "Теґи", + "followers": "Підписники", "popular": "Популярні Пости", "new": "Новий пост", "verified": "Перевірені Пости", @@ -40,16 +40,16 @@ "birthday": "День народження", "game_experience": "Ігровий Досвід", "follow_user": "Підписатися", - "following_user": "Підписан", + "following_user": "Підписані", "country": "Країна", "unfriend": "Вилучити з друзів", "posts": "Пости", "friends": "Друзі", - "following": "Підписан", + "following": "Підписані", "befriend": "Дружити", "pending": "В очікуванні", "no_friends": "Немає Друзів", - "no_following": "Ні На Кого Не Підписаний", + "no_following": "Ні на кого не Підписаний", "no_followers": "Немає Підписників", "followers": "Підписчики" }, @@ -100,7 +100,7 @@ "language": "Українська", "user_settings": { "show_country": "Показати Країну в Профілі", - "show_game": "Показувати Ігровий Опит в Профілі", + "show_game": "Показувати Ігровий Досвід в Профілі", "show_comment": "Показувати Коментарі до Профілю", "swearing": "Коментарі профілю не можуть містити нецензурну лексику.", "profile_settings": "Налаштування Профілю", From f282e0594271d611a420d852a9acb3319342805d Mon Sep 17 00:00:00 2001 From: Evan Lie Date: Thu, 20 Feb 2025 00:04:42 +0100 Subject: [PATCH 168/189] locales(add): Added English (en@uwu) locale --- apps/juxtaposition-ui/src/translations/en@uwu.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/juxtaposition-ui/src/translations/en@uwu.json diff --git a/apps/juxtaposition-ui/src/translations/en@uwu.json b/apps/juxtaposition-ui/src/translations/en@uwu.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/apps/juxtaposition-ui/src/translations/en@uwu.json @@ -0,0 +1 @@ +{} From 791e7017b73326d1e7c8e332ea44a6db1c68bde8 Mon Sep 17 00:00:00 2001 From: Evan Lie Date: Thu, 20 Feb 2025 15:51:24 +0000 Subject: [PATCH 169/189] locales(update): Updated English (en@uwu) locale --- .../src/translations/en@uwu.json | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/en@uwu.json b/apps/juxtaposition-ui/src/translations/en@uwu.json index 0967ef42..319edbda 100644 --- a/apps/juxtaposition-ui/src/translations/en@uwu.json +++ b/apps/juxtaposition-ui/src/translations/en@uwu.json @@ -1 +1,32 @@ -{} +{ + "all_communities": { + "ann_string": "kik mii 4 nws fwom da big cheese!", + "popular_places": "so many kittehs in klans", + "new_communities": "new kitteh klans!!", + "text": "all kitteh klans", + "show_all": "show da secrets", + "search": "find kitteh klans…", + "announcements": "da big cheese nws!!" + }, + "community": { + "follow": "join kitteh klan" + }, + "global": { + "communities": "kitteh klans", + "messages": "kitteh texts", + "activity_feed": "kitteh parti", + "go_back": "go bak", + "back": "bak", + "yeahs": "kitteh'd", + "more": "mor kittehs plz", + "private": "no kitteh alowd", + "save": "sav", + "exit": "kthxbai!!", + "close": "kitteh retret", + "next": "nex", + "user_page": "kitteh pege", + "notifications": "PINGS", + "no_posts": "no kittehs, sad :(" + }, + "language": "lolcat" +} From e9ec5e7397afa7ce080cc465dbb7a177281f43db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnau=20B=C3=A0rcia?= Date: Sat, 29 Mar 2025 02:01:43 +0100 Subject: [PATCH 170/189] locales(update): Updated French locale --- apps/juxtaposition-ui/src/translations/fr.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/fr.json b/apps/juxtaposition-ui/src/translations/fr.json index b3d59193..4926ea95 100644 --- a/apps/juxtaposition-ui/src/translations/fr.json +++ b/apps/juxtaposition-ui/src/translations/fr.json @@ -1,10 +1,10 @@ { "language": "Français", "global": { - "user_page": "Profil", - "activity_feed": "Fil d'actualité", + "user_page": "Page de l'utilisateur", + "activity_feed": "Suivi des activités", "communities": "Communautés", - "messages": "Messages", + "messages": "Messages privés", "notifications": "Notifications", "go_back": "Retour", "back": "Précédent", From d94be6e8e551a061422a26ff3e6055002dcea7b7 Mon Sep 17 00:00:00 2001 From: ssantos Date: Thu, 10 Apr 2025 17:45:18 +0200 Subject: [PATCH 171/189] locales(add): Added Portuguese (Portugal) locale --- apps/juxtaposition-ui/src/translations/pt_PT.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/juxtaposition-ui/src/translations/pt_PT.json diff --git a/apps/juxtaposition-ui/src/translations/pt_PT.json b/apps/juxtaposition-ui/src/translations/pt_PT.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/apps/juxtaposition-ui/src/translations/pt_PT.json @@ -0,0 +1 @@ +{} From 823e0988547b3ac307fefbbea39480e7e4ff9ae6 Mon Sep 17 00:00:00 2001 From: ssantos Date: Thu, 10 Apr 2025 17:45:56 +0200 Subject: [PATCH 172/189] locales(update): Updated Portuguese (Portugal) locale --- .../src/translations/pt_PT.json | 127 +++++++++++++++++- 1 file changed, 126 insertions(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/pt_PT.json b/apps/juxtaposition-ui/src/translations/pt_PT.json index 0967ef42..5e93b429 100644 --- a/apps/juxtaposition-ui/src/translations/pt_PT.json +++ b/apps/juxtaposition-ui/src/translations/pt_PT.json @@ -1 +1,126 @@ -{} +{ + "language": "Português", + "global": { + "user_page": "Perfil do Utilizador", + "activity_feed": "Atividade", + "communities": "Comunidades", + "messages": "Mensagens", + "notifications": "Notificações", + "go_back": "Voltar", + "back": "Anterior", + "yeahs": "Fixes", + "more": "Carregar mais publicações", + "no_posts": "Sem publicações", + "private": "Privado", + "close": "Fechar", + "save": "Guardar", + "exit": "Sair", + "next": "Seguinte" + }, + "all_communities": { + "text": "Todas as comunidades", + "announcements": "Anúncios", + "ann_string": "Clica aqui para veres os anúncios recentes!", + "popular_places": "Lugares Populares", + "new_communities": "Novas Comunidades", + "show_all": "Mostrar todas", + "search": "Procurar comunidades..." + }, + "community": { + "recent": "Publicações Recentes", + "follow": "Seguir Comunidade", + "following": "A seguir", + "followers": "Seguidores", + "posts": "Publicações", + "tags": "Tags", + "popular": "Publicações Populares", + "verified": "Publicações Verificadas", + "new": "Nova Publicação" + }, + "user_page": { + "country": "País", + "birthday": "Aniversário", + "game_experience": "Experiência de Jogo", + "posts": "Publicações", + "followers": "Seguidores", + "follow_user": "Seguir", + "following_user": "Seguidores", + "friends": "Amigos", + "following": "A seguir", + "befriend": "Tornar-se Amigo", + "pending": "Pendente", + "unfriend": "Remover Amizade", + "no_friends": "Sem Amigos", + "no_following": "Não segue ninguém", + "no_followers": "Sem seguidores" + }, + "notifications": { + "none": "Sem notificações.", + "new_follower": "seguiu-te!" + }, + "setup": { + "rules_text": { + "fifth": "De forma a mantermos Juxt um lugar divertido para todos, pedimos-te que penses nas outras pessoas. Ajuda-nos a manter Juxt uma boa experiência ao não fazer publicações impróprias ou ofensivas.", + "sixth": "Não partilhes informações pessoais", + "third": "Juxt contém várias comunidades de jogadores onde pessoas de todo o mundo podem partilhar as suas ideias. Quando publicas numa comunidade, lembra-te que todos podem ver as tuas publicações, por isto expressa-te de uma maneira que possa ser divertida para todos. Usa o senso comum e pensa antes de publicar. Juxt é um serviço que também está acessível pela Internet, por isto pessoas que não usam Juxt também podem ver as tuas publicações. Adicionalmente, quaisquer comentários que faças em publicações de amigos são visíveis não só por estes, mas também por pessoas de todo o mundo. Tem isto em consideração.", + "first": "Estas são algumas regras que permitem que Juxt seja uma experiência divertida para todos. O código de conduta Juxt contém informação detalhada, por isso lê-o com atenção.", + "second": "Publicações podem ser vistas em todo o mundo", + "fourth": "Sê simpático com os outros", + "tenth": "Violações do código de conduta", + "seventh": "Lembra-te, conhecer alguém em Juxt não é o mesmo que conhecer alguém na vida real. Nunca partilhes com ninguém em Juxt o teu endereço de e-mail, morada, trabalho, nome da escola ou qualquer outra informação que te possa identificar nem partilhes informação de outras pessoas. Adicionalmente, se alguém que conheceres em Juxt te convidar para que se conheçam no mundo real, não aceites. Juxt é uma comunidade online e não deve ser usada para marcar encontros presenciais.", + "eighth": "Não publiques Spoilers", + "ninth": "Algumas pessoas vêm a Juxt à procura de dicas e truques para jogos, mas outras preferem descobrir os jogos por si mesmas. Publicações que revelam segredos de um jogo ou a sua história são chaamdas de \"spoilers.\" Se vais publicar algo sobre um jogo que pode ser um spoiler, marca a respetiva caixa antes de enviares a tua publicação. Desta forma, pessoas que não querem ver spoilers não verão a tua publicação.", + "eleventh": "O nosso objetivo é fazer de Juxt uma comunidade divertida para todos. No caso de alguém violar o Código de Conduta de Juxt, iremos tomar as medidas necessárias que poderão incluir banir o utilizador ou a consola.", + "twelfth": "Já jogaste este jogo?", + "thirteenth": "Se publicares numa comunidade de um jogo que já jogaste, as tuas publicações irão incluir um ícone que indica que já o jogaste." + }, + "welcome": "Bem-vindo a Juxtaposition!", + "welcome_text": "Juxt é uma comunidade de jogadores que liga pessoas de todo o mundo utilizando personagens Mii. Usa Juxt para partilhar as tuas experiências de jogo e conhecer novas pessoas de todo o mundo.", + "beta": "Nota sobre Beta", + "beta_text": { + "first": "Estás prestes a experimentar a primeira versão beta pública de Juxt. Isto significa que ainda há muito a fazer e que muitas coisas ainda poderão mudar a qualquer momento.", + "second": "No final do período beta, os dados registados na plataforma poderão vir a ser apagados.", + "third": "Este website, o seu software e todos os conteúdos nele conteúdos são disponibilizados “tal como estão” e “quando disponíveis”. A Pretendo Network não oferece quaisquer garantias, quer expressas quer implícitas, a respeito da integridade ou disponibilidade do website, do seu software ou dos seus conteúdos." + }, + "info": "O que é Juxtaposition?", + "info_text": "Juxt é uma comunidade de utilizadores que liga pessoas\n de todo o mundo. Podes escrever ou desenhar publicações nas comunidades dos jogos ou enviar mensagens diretamente aos teus amigos.", + "rules": "Regras de Juxt", + "google_text": "Juxtaposition usa Google Analytics de forma a recolher informações de como os utilizadores usam o serviço. Os dados recolhidos incluem, mas não estão limitados a, hora da visita, páginas visitadas e tempo passado no site. Estes dados não estão associados a ti de maneira nenhuma e não são usados para anúncios por nós nem pela Google.", + "experience": "Experiência de jogo", + "experience_text": { + "info": "Fala-nos um pouco da tua experiência com jogos. Podes alterar estas definições mais tarde.", + "beginner": "Iniciante", + "intermediate": "Intermédio", + "expert": "Avançado" + }, + "google": "Google Analytics", + "ready": "Pronto para usar Juxt", + "ready_text": "Começa por explorar algumas comunidades e ver o que as pessoas de todo o mundo estão a publicar. Aproveita esta oportunidade para te familiarizares com Juxt. Pode ser que descubras algo novo pelo caminho!", + "done": "Diverte-te com Juxt!", + "done_button": "Vamos a isso!", + "guest": "Modo de convidado", + "guest_text": "Não nos foi possível verificar a tua conta de momento, o que provavelmente significa que tens sessão iniciada com uma conta Nintendo Network. Podes explorar Juxt, mas não te será possível marcar publicações com Fixe! ou fazer publicações até que inicies sessão com uma conta Pretendo Network. Para mais informações visita o nosso servidor Discord.", + "guest_button": "Compreendo" + }, + "user_settings": { + "profile_settings": "Preferências de Perfil", + "show_country": "Mostrar país no perfil", + "show_birthday": "Mostrar data de aniversário no perfil", + "show_game": "Mostrar experiência de jogo no perfil", + "show_comment": "Mostrar comentário no perfil", + "profile_comment": "Comentário do Perfil", + "swearing": "O comentário do perfil não pode ter linguagem obscena." + }, + "activity_feed": { + "empty": "Isto está muito vazio. Começa a seguir alguém!" + }, + "new_post": { + "new_post_text": "Nova publicação", + "post_to": "Publicar em", + "text_hint": "Toca aqui para criar uma publicação.", + "swearing": "A publicação não pode ter linguagem obscena." + }, + "messages": { + "coming_soon": "A funcionalidade de mensagens ainda não está disponível. Volta em breve!" + } +} From 800ec6563848f4c8ac1565f166793b1232c5cdca Mon Sep 17 00:00:00 2001 From: sam lamberton Date: Wed, 16 Apr 2025 20:16:13 +0200 Subject: [PATCH 173/189] locales(update): Updated English (en@uwu) locale --- .../src/translations/en@uwu.json | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/en@uwu.json b/apps/juxtaposition-ui/src/translations/en@uwu.json index 319edbda..6b892f97 100644 --- a/apps/juxtaposition-ui/src/translations/en@uwu.json +++ b/apps/juxtaposition-ui/src/translations/en@uwu.json @@ -9,7 +9,13 @@ "announcements": "da big cheese nws!!" }, "community": { - "follow": "join kitteh klan" + "follow": "join kitteh klan", + "recent": "wecent p-posts", + "following": "Fowwowing", + "followers": "Fowwowers", + "popular": "Popuwaw P-posts", + "verified": "Vewwifiwed P-posts", + "new": "Nyew P-Post" }, "global": { "communities": "kitteh klans", @@ -28,5 +34,21 @@ "notifications": "PINGS", "no_posts": "no kittehs, sad :(" }, - "language": "lolcat" + "language": "lolcat", + "user_page": { + "no_friends": "Nyo Fwiends", + "friends": "Fwends", + "posts": "P-posts", + "country": "Countwy", + "birthday": "Biwthday", + "game_experience": "G-G-Game Expewience", + "followers": "Fowwowers", + "following": "Fowwowing", + "follow_user": "Fowwow", + "following_user": "Fowwowing", + "befriend": "Befwiend", + "pending": "Pwending", + "unfriend": "Unfwiend", + "no_following": "Nyot Fowwowing Anyonye" + } } From 17f46735fc81398a5d52fc82ee3933f8270baea5 Mon Sep 17 00:00:00 2001 From: Dimitri A Date: Wed, 23 Apr 2025 05:22:33 +0200 Subject: [PATCH 174/189] locales(update): Updated French (Canada) locale --- apps/juxtaposition-ui/src/translations/fr_CA.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/fr_CA.json b/apps/juxtaposition-ui/src/translations/fr_CA.json index af8b192c..9af69923 100644 --- a/apps/juxtaposition-ui/src/translations/fr_CA.json +++ b/apps/juxtaposition-ui/src/translations/fr_CA.json @@ -1,7 +1,7 @@ { "global": { - "user_page": "Page de l'utilisateur", - "activity_feed": "Flux d'activité", + "user_page": "Profil", + "activity_feed": "Fil d'activité", "communities": "Communautés", "messages": "Messages", "notifications": "Notifications", From 0c4020c781f633ba719b90ce231b4b3371dca247 Mon Sep 17 00:00:00 2001 From: Antoine Rapin Date: Mon, 28 Apr 2025 00:00:03 +0200 Subject: [PATCH 175/189] locales(update): Updated French (Canada) locale --- .../src/translations/fr_CA.json | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/fr_CA.json b/apps/juxtaposition-ui/src/translations/fr_CA.json index 9af69923..2dc65ec5 100644 --- a/apps/juxtaposition-ui/src/translations/fr_CA.json +++ b/apps/juxtaposition-ui/src/translations/fr_CA.json @@ -60,10 +60,10 @@ "show_game": "Afficher mon expérience de joueur sur le profil", "show_comment": "Rendre visible le commentaire de mon profil", "profile_comment": "Commentaire du profil", - "swearing": "Commentaire de Profil Pouvoir Pas Contenir Langue Explicite." + "swearing": "Le commentaire du profil ne peut pas contenir de vocabulaire explicite." }, "activity_feed": { - "empty": "Son Vide Ici. Essayer Suivants Quelqu'un!" + "empty": "C'est vide ici. Essaie de suivre quelqu'un!" }, "notifications": { "none": "Aucune notification.", @@ -73,32 +73,32 @@ "new_post_text": "Nouvelle publication", "post_to": "Poster à", "text_hint": "Entrez ici le texte que vous allez publier.", - "swearing": "Poster Pouvoir Pas Contenir Langue Explicite." + "swearing": "La publication ne peut pas contenir du vocabulaire explicite." }, "messages": { "coming_soon": "Les messages ne sont pas encore disponibles. Revenez bientôt!" }, "setup": { "welcome": "Bienvenue sur Juxtaposition!", - "welcome_text": "Juxt Est un Communauté de Jeux ça Relier Gens de Tout le Monde Utiliser Personnage Mii. Utiliser Juxt à Partager Ton Expérience de Jeux et Retrouver Gens de Tout le Monde.", - "beta": "Bêta Avertissement", + "welcome_text": "Juxt est une communauté de jeu qui rassemble du monde de partout à travers le monde en utilisant des personnages Mii. Utilisez Juxt pour partager votre expérience de jeu et rencontrer du monde à l'international.", + "beta": "Avertissement de version bêta", "beta_text": { - "first": "Tu es Tester la Premier public Bêta de Juxt. Ceci Signifier ça Beucoup est Encore au air, et ça Beucoup Pouvoir Changer à de Temps.", - "second": "Ceci Pouvoir et il se Peut Que Comprendre un Effacer total à le Conclusion ou Pendant le Période Bêta.", - "third": "Le site, son Logiciel et Tout Content Trouvé dans il es Fourni il un \"tel quel\" et \"tel disponible\" base. Le Pretendo Network Pouvoir pas Donner du Garantie, si Formel ou Impliquer, Aussi à le Convenir ou Convivialité de le site, et son Logiciel ou si de son Contenu." + "first": "Vous êtes sur le point d'essayer la première version bêta publique de Juxt. Ça veut dire que plusieurs choses sont encore en cours de développement et que tout peut changer à tout moment.", + "second": "Cela peut engendrer une suppression totale de la base de données pendant ou à la fin de la période bêta.", + "third": "Le site web, son logiciel et tout le contenu présent sont fournis comme tel et selon leur disponibilité. Le Pretendo Network ne fait aucune garantie, implicite ou explicite, quant à la pertinence ou au fonctionnement du site web, de son logiciel ou de son contenu." }, "info": "Qu'est-ce que Juxtaposition?", - "info_text": "Juxt est un Utilisateur-Motivé Communauté où tu Pouvoir Interagir avec Gens\nPartout le Montrer. Tu Pouvoir écrire et Dessiner Poster dans Communauté de Jeux ou Envoyer Messages Directement à ton amis.", + "info_text": "Juxt est une communauté de jeu axée sur les utilisateurs où vous pouvez intéragir avec du monde de partout à travers le monde.\nVous pouvez écrire ou dessiner des publications dans des communautés de jeu ou envoyer des messages directement à vos amis.", "rules": "Règles de Juxt", "rules_text": { - "first": "Le suivant sommes quelques lignes directrices d'important pour fabrication de Juxt une expérience de sympa et plaisant pour tout le monde. Le Code de Conduite contenir informations détaillé, donc lire lui minutieusement merci.", - "second": "Posters Peut être Regardé à Travers le Monde", - "fourth": "Sois Gentil à Un Autre", - "fifth": "Afin de garder Juxt un endroit gentil pour tout le monde, nous demander que tu être prévenant à autre utilisateurs. Aider nous garder Juxt un expérience plaisant par poster pas n'importe quoi inapproprié ou offensant.", - "sixth": "Poster pas informations personnel—Votres ou Autres", + "first": "Les directives suivantes sont importantes pour faire de Juxt une expérience amusante et agréable pour tous. Le code de conduite de Juxt contient des informations détaillées, donc veuillez les lire attentivement.", + "second": "Vos publications peuvent être vues partout à travers le monde", + "fourth": "Soyez gentils avec les autres", + "fifth": "Afin que Juxt reste un endroit agréable pour tous, nous vous demandons d'être soucieux des autres utilisateurs. Aidez-nous à faire de Juxt une expérience agréable en ne publiant rien d'inapproprié ou d'offensif.", + "sixth": "Ne publiez pas d'informations personnelles — Qu'elles soit les vôtres ou celles des autres", "eighth": "Ne Poster pas spoilers", "tenth": "Violation du Code de Conduite", - "third": "Juxt contenir beaucoup communautés de jeux où gens de à travers le monde pouvoir partager leur idées. Quand tu poster dans le communauté, se souvenir de tout le monde pouvoir vois-le, exprimer donc vous dans les manière que tout le monde pouvoir apprécier. Utiliser bon sens, et penser avant de poster. Juxt est une service que est accessible dans l'internet, donc ne pas perdre de vue gens qui utiliser pas Juxt il se peut que voir ton posters. De plus, tous commentaire tu créer dans ton amis posters aller être voir seulement pas ton amis mais par gens de à travers le monde, aussi. s'il vous plaît ne pas oublier.", + "third": "Juxt héberge une panoplie de communautés de jeu dans lesquelles des personnes de partout sur la planète peuvent partager leurs idées. Lorsque vous publiez dans une communauté, souvenez-vous que tout le monde peut le voir, donc veuillez vous exprimer de façon convenable pour tout le monde. Prenez le temps de réfléchir et d'utiliser votre bon sens avant de publier quelque chose. Juxt est un service qui est aussi accessible en ligne, donc rappelez-vous que des personnes n'utilisant pas Juxt peuvent également voir vos publications. De plus, les commentaires que vous faites sur les publications de vos amis ne vont non seulement être vus par vos amis, mais également par des personnes du monde entier. Veuillez garder cela à l'esprit.", "seventh": "N'oubliez pas, connaître quelqu'un dans Juxt n'est pas la même chose aussi connaître dans le vraie vie. Jamais partager ton adresse e-mail, adresse de maison, nom de travail ou ecole, ou autre informations de identifier personnellement avec n'importe qui sur Juxt, et Jamais partager l'autre n'importe quis informations, de plus, si quelqu'un tu rencontrer dans Juxt inviter tu rencontrer lui ou elle dans le vraie vie, ne accepter pas. Juxt est un communauté en ligne et devoir pas utiliser à vraie vie se retrouver.", "ninth": "Quelques gens venir à Juxt recherche pour \"tips et tricks\" pour jeux, mais autres vouloir faire découvrir secrets de jeux sur leur propre.Posters que révéler secrets de jeux ou intrigue es qui s'appelle \"spoilers.\" si tu es poster quelque chose sur un jeux que il se pourrait que être un spoiler, être sûr à cocher le boîte de spoiler avant de poster tu. Ce façon, gens qui ne vouloir pas à spoiled ne voir pas ton poster.", "eleventh": "Nos objectif est à garder sympa et plaisant dans Juxt. Dans l'événement ça quelqu'un Violer du Juxt Code de Conduite, nous aller agir approprié, allant jusqu'à et inclure bouchage le choquant utilisateur ou console.", From 02d6d6d7ebf7a8923e74e3c082791cbfca4a84bf Mon Sep 17 00:00:00 2001 From: Antoine Rapin Date: Mon, 28 Apr 2025 00:59:40 +0200 Subject: [PATCH 176/189] locales(update): Updated French (Canada) locale --- .../juxtaposition-ui/src/translations/fr_CA.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/fr_CA.json b/apps/juxtaposition-ui/src/translations/fr_CA.json index 2dc65ec5..ccc348b6 100644 --- a/apps/juxtaposition-ui/src/translations/fr_CA.json +++ b/apps/juxtaposition-ui/src/translations/fr_CA.json @@ -5,8 +5,8 @@ "communities": "Communautés", "messages": "Messages", "notifications": "Notifications", - "go_back": "Retour", - "back": "Revenir", + "go_back": "Revenir", + "back": "Précédent", "yeahs": "Ouais", "more": "Charger plus de publications", "no_posts": "Aucune publication", @@ -84,7 +84,7 @@ "beta": "Avertissement de version bêta", "beta_text": { "first": "Vous êtes sur le point d'essayer la première version bêta publique de Juxt. Ça veut dire que plusieurs choses sont encore en cours de développement et que tout peut changer à tout moment.", - "second": "Cela peut engendrer une suppression totale de la base de données pendant ou à la fin de la période bêta.", + "second": "Cela peut engendrer une suppression totale de la base de données pendant la période bêta ou à sa fin.", "third": "Le site web, son logiciel et tout le contenu présent sont fournis comme tel et selon leur disponibilité. Le Pretendo Network ne fait aucune garantie, implicite ou explicite, quant à la pertinence ou au fonctionnement du site web, de son logiciel ou de son contenu." }, "info": "Qu'est-ce que Juxtaposition?", @@ -96,12 +96,12 @@ "fourth": "Soyez gentils avec les autres", "fifth": "Afin que Juxt reste un endroit agréable pour tous, nous vous demandons d'être soucieux des autres utilisateurs. Aidez-nous à faire de Juxt une expérience agréable en ne publiant rien d'inapproprié ou d'offensif.", "sixth": "Ne publiez pas d'informations personnelles — Qu'elles soit les vôtres ou celles des autres", - "eighth": "Ne Poster pas spoilers", + "eighth": "Ne publiez pas de spoilers", "tenth": "Violation du Code de Conduite", "third": "Juxt héberge une panoplie de communautés de jeu dans lesquelles des personnes de partout sur la planète peuvent partager leurs idées. Lorsque vous publiez dans une communauté, souvenez-vous que tout le monde peut le voir, donc veuillez vous exprimer de façon convenable pour tout le monde. Prenez le temps de réfléchir et d'utiliser votre bon sens avant de publier quelque chose. Juxt est un service qui est aussi accessible en ligne, donc rappelez-vous que des personnes n'utilisant pas Juxt peuvent également voir vos publications. De plus, les commentaires que vous faites sur les publications de vos amis ne vont non seulement être vus par vos amis, mais également par des personnes du monde entier. Veuillez garder cela à l'esprit.", - "seventh": "N'oubliez pas, connaître quelqu'un dans Juxt n'est pas la même chose aussi connaître dans le vraie vie. Jamais partager ton adresse e-mail, adresse de maison, nom de travail ou ecole, ou autre informations de identifier personnellement avec n'importe qui sur Juxt, et Jamais partager l'autre n'importe quis informations, de plus, si quelqu'un tu rencontrer dans Juxt inviter tu rencontrer lui ou elle dans le vraie vie, ne accepter pas. Juxt est un communauté en ligne et devoir pas utiliser à vraie vie se retrouver.", - "ninth": "Quelques gens venir à Juxt recherche pour \"tips et tricks\" pour jeux, mais autres vouloir faire découvrir secrets de jeux sur leur propre.Posters que révéler secrets de jeux ou intrigue es qui s'appelle \"spoilers.\" si tu es poster quelque chose sur un jeux que il se pourrait que être un spoiler, être sûr à cocher le boîte de spoiler avant de poster tu. Ce façon, gens qui ne vouloir pas à spoiled ne voir pas ton poster.", - "eleventh": "Nos objectif est à garder sympa et plaisant dans Juxt. Dans l'événement ça quelqu'un Violer du Juxt Code de Conduite, nous aller agir approprié, allant jusqu'à et inclure bouchage le choquant utilisateur ou console.", + "seventh": "Souvenez-vous que connaître quelqu'un sur Juxt n'est pas la même chose que de le connaître dans la vie réelle. Ne partagez jamais votre adresse courriel, où vous habitez, le nom de votre endroit de travail ou d'étude, ou toute autre information d'identification à qui que ce soit sur Juxt, et ne partagez jamais les informations des autres. De plus, si quelqu'un que vous rencontrez sur Juxt vous invite à les rencontrer en personne, n'acceptez pas son invitation. Juxt est une communauté virtuelle et ne devrait pas être utilisé pour planifier des rencontres dans le monde réel.", + "ninth": "Certains viennent sur Juxt afin de trouver des conseils et des astuces pour des jeux, mais d'autres veulent découvrir les secrets d'un jeu par eux-même. Les publications qui révèlent les secrets d'un jeu ou de son histoire sont appelés \"spoilers\". Si vous publiez quelque chose à propos d'un jeu qui pourrait être un spoiler, assurez-vous de cocher la case Spoilers avant de publier votre publication. Ainsi, le monde ne voulant pas être spoilé ne verra pas votre publication.", + "eleventh": "Notre objectif est de faire en sorte que Juxt soit amusant et agréable pour tout le monde. Au cas où quelqu'un enfreint le code de conduite de Juxt, nous allons prendre les mesures appropriées, pouvant aller jusqu'au blocage de l'utilisateur fautif ou de sa console.", "twelfth": "As-tu joué à ce jeu?", "thirteenth": "Si vous publier dans la communauté pour un jeu auquel tu as joué, tes publications aura une icône indiquant que vous l'avez joué." }, @@ -122,5 +122,5 @@ "guest_text": "Nous ne pouvons pas vérifier votre compte pour le moment, ce qui signifie probablement que vous êtes connecté avec un compte Nintendo Network. Vous pourrez toujours parcourir Juxt, mais vous ne pourrez pas accéder à Yeah! des publiez ou créez vos propres publications jusqu'à ce que vous vous connectiez avec un compte Pretendo Network. Pour plus d'informations, consultez le serveur Discord.", "google_text": "Juxtaposition utilise Google Analytics afin de comprendre comment les utilisateurs utilisent notre service. Les données collectées incluent, sans toutefois s'y limiter, l'heure de visite, les pages visitées et le temps passé sur le site. Ces données ne sont en aucun cas associées à vous et ne seront pas utilisées à des fins publicitaires, ni par nous ni par Google." }, - "language": "Français (CA)" + "language": "Français (Canada)" } From 287187bfa585b091d8b9fb7e861ad53bb307007c Mon Sep 17 00:00:00 2001 From: Mael Parada Fernandez Date: Thu, 1 May 2025 16:00:58 +0200 Subject: [PATCH 177/189] locales(update): Updated Galician locale --- .../juxtaposition-ui/src/translations/gl.json | 80 ++++++++++++++++++- 1 file changed, 78 insertions(+), 2 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/gl.json b/apps/juxtaposition-ui/src/translations/gl.json index 0ae3384a..c364c748 100644 --- a/apps/juxtaposition-ui/src/translations/gl.json +++ b/apps/juxtaposition-ui/src/translations/gl.json @@ -44,7 +44,83 @@ "following": "Seguindo", "followers": "Seguidores", "follow_user": "Segue", - "birthday": "Aniversario" + "birthday": "Aniversario", + "following_user": "Seguindo", + "befriend": "Engadir como amigo", + "pending": "Pendente", + "unfriend": "Borrar como amigo", + "no_friends": "Sen amigos", + "no_following": "Non Seguindo A Ninguén", + "no_followers": "Sen Seguidores" }, - "language": "Galego" + "language": "Galego", + "setup": { + "rules_text": { + "eleventh": "A nosa meta é facer que Juxt siga sendo divertido e disfrutáble para tod@s. No momento no que alguén viole o Código de Conducta de Juxt, tomaremos a acción apropiada, incluíndo bloquear o usuario ofensor ou consola.", + "twelfth": "Xogaches a Ise Xogo?", + "seventh": "Recorde que coñecer a alguén en Juxt non é o mesmo que coñecelo na vida real. Nunca compartas a túa direccion de e-mail, a dirección da túa casa, nome do traballo ou nome do colexio/instituto/universidade, ou outra información identificante con ninguén en Juxt, e nunca compartas a información de outras persoas tampouco. Adicionalmente, si alguén que coñeces en Juxt invítache a coñecerlle na vida real, non aceptes. Juxt é unha comunidade online e non debería ser usada para facer quedadas na vida real.", + "third": "Juxt contén moitas comunidades de xogadores onde a xente de todo o mundo pode compartir os seus pensamentos. Cando publica nunha comunidade, recorde que todo o mundo pode velo, así que por favor exprésese nunha maneira na que todos poidan disfrutar. Utilize o sentido común, e pense antes de publicar. Juxt é un serivizo que tamén é accesible desde o Internet, así que teña en mente que a xente que non usa Juxt pode que vexa as súas publicacións. Adicionalmente, calquer comentario que faga nas publicacións dos seus amigos van ser vistos por xente en todo o mundo tamén. Por favor, teña esto en mente.", + "first": "As seguintes son algunhas regras para facer Juxt un lugar divertido e disfrutáble para tod@s. O código de conducta de Juxt contén información detallada, así que por favor, léeo con atención.", + "thirteenth": "Se estás publicando algo na comunidade dun xogo que xogaches as túas publicacións terán unha ícona indicando que o xogaches.", + "second": "As Publicacións Poden Ser Vistas En Todo o Mundo", + "fourth": "Ser Agradables", + "fifth": "Para facer Juxt un lugar divertido para todo o mundo, pedímoslle que sexas amable aos outros usuarios. Axúdanos a facer que Juxt siga sendo un lugar disfrutáble non publicando nada inapropiado ou ofensivo.", + "sixth": "Non Publiques Información Persoal, Xa sexa túa ou de outros", + "eighth": "Non Subas Spoilers", + "tenth": "Violacións do Código de Conducta", + "ninth": "Algunhas persoas veñen a Juxt buscando pistas e trucos para xogos, pero outros queren descubrir os segredos dun xogo eles sós. As publicacións que revelen segredos dun xogo ou da súa historia chámanse \"spoilers\". Se vai a subir algo sobre un xogo que pode que sexa un spoiler, asegúrese de marcar a casilla de Spoilers antes de envíar a súa publicación. De esta maneira, a xente que non quere que lle fagan spoiler non verá a súa publicación." + }, + "google": "Analíticas de Google", + "done": "Pásao ben en Juxt!", + "done_button": "Vamos alá!", + "experience_text": { + "info": "Por favor cóntanos como describiría o seu nivel de experiencia de xogos. Podes cambiar iste axuste máis tarde.", + "beginner": "Principiante", + "expert": "Experto", + "intermediate": "Intermedio" + }, + "experience": "Experiencia de Xogo", + "ready_text": "Primeiro mira algunhas comunidades e mira sobre o que a xente de todo o mundo está publicando. Utilice esta oportunidade para familiarizarse con Juxt. Pode que fagas algún novo descubrimento polo camiño!", + "guest": "Modo Invitado", + "beta_text": { + "third": "A páxina web, o seu software e todo o contenido nela ofrécese \"tal cal\" e \"segundo a súa dispoñibilidade\". Pretendo Network non da ningunha garantía, xa sea expresado ou implicado, sobre a idoneidade ou usabilidade do sitio web, o seu software ou calquera do seu contido.", + "first": "Estás a punto de probar a primeira beta pública de Juxt. Esto significa que hai moitas cousas sen rematar, e moitas cousas poden cambiar en calquera momento.", + "second": "Esto pode e quizáis inclúa una eliminación da base de datos no final ou durante a fase beta." + }, + "ready": "Preparado Para Comezar a Usar Juxt", + "welcome": "Benvido a Juxtaposition!", + "beta": "Aviso De Versión Beta", + "info": "Que é Juxtaposition?", + "info_text": "Juxt é unha comunidade de xogadores manexada polos usuarios onde podes interactuar con xente\narredor do mundo. Podes escribir ou debuxar publicacións en comunidades de xogos ou enviar mensaxes directamente aos teus amigos (aínda non dispoñíbel).", + "rules": "Regras de Juxt", + "guest_text": "Non podemos verificar a súa conta en este momento, o que probablemente significa que vostede está iniciando a sesión con unha conta de Nintendo Network account. Vas a ser capaz de mirar Juxt, pero non poderá \"Yeah!\" publicacións e non facer as súas propias publicacións hasta que inicie a sesión con unha conta de Pretendo Network. Para máis información revise o servidor de Discord.", + "guest_button": "Entendóo", + "welcome_text": "Juxtaposition é unha comunidade de xogadores que conecta xente de todo o mundo usando persoaxes Mii. Usa Juxtaposition para compartir as túas experiencias xogando e coñece a xente de todo o mundo.", + "google_text": "Juxtaposition utiliza Google Analytics para ver como os usuarios utilizan o noso servicio. Os datos recollidos inclúen máis non limitan ao tempo de visita, páxinas visitadas e tempo pasado no sito. Estos datos non están unidos a vostede en ningunha maneira, e non está usada para anuncios nosos ou de Google." + }, + "new_post": { + "text_hint": "Toca aiquí para facer unha publicación.", + "new_post_text": "Nova Publicación", + "post_to": "Publicar a", + "swearing": "A publicación non pode ter linguaxe explícito." + }, + "user_settings": { + "show_comment": "Amosar Comentarios no Perfil", + "profile_settings": "Axustes Do Perfil", + "show_country": "Amosar País no Perfil", + "show_birthday": "Amosar Aniversario no Perfil", + "show_game": "Amosar Experiencia En Xogos no Perfil", + "profile_comment": "Comentario do Perfil", + "swearing": "O comentario do perfil non pode ter linguaxe explícito." + }, + "activity_feed": { + "empty": "Está baleiro aiquí. Proba a seguir a alguén!" + }, + "notifications": { + "none": "Sen notificacións.", + "new_follower": "seguíuche!" + }, + "messages": { + "coming_soon": "Está función non está preparada. Volve a mirar pronto!" + } } From 04a802e1041aa216d4d08ff21daf2b8a981a8660 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnau=20B=C3=A0rcia?= Date: Mon, 5 May 2025 22:42:23 +0200 Subject: [PATCH 178/189] locales(update): Updated Spanish locale --- apps/juxtaposition-ui/src/translations/es.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/es.json b/apps/juxtaposition-ui/src/translations/es.json index 5b887b0a..c1e275f1 100644 --- a/apps/juxtaposition-ui/src/translations/es.json +++ b/apps/juxtaposition-ui/src/translations/es.json @@ -31,10 +31,10 @@ "following": "Siguiendo", "followers": "Seguidores", "posts": "Publicaciones", - "tags": "Etiquetas", - "recent": "Publicaciones recientes", - "popular": "Publicaciones populares", - "verified": "Publicaciones verificados", + "tags": "Distintivos de uso", + "recent": "Mensajes recientes", + "popular": "Mensajes populares", + "verified": "Mensajes verificados", "new": "Nueva publicación" }, "user_page": { From 05772cb0f5a72c0817061e0067d8551ed1ae6b13 Mon Sep 17 00:00:00 2001 From: Dimitri A Date: Sun, 18 May 2025 23:09:35 +0200 Subject: [PATCH 179/189] locales(update): Updated French (Canada) locale --- apps/juxtaposition-ui/src/translations/fr_CA.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/fr_CA.json b/apps/juxtaposition-ui/src/translations/fr_CA.json index ccc348b6..ee901b6c 100644 --- a/apps/juxtaposition-ui/src/translations/fr_CA.json +++ b/apps/juxtaposition-ui/src/translations/fr_CA.json @@ -23,7 +23,7 @@ "show_all": "Tout afficher", "search": "Rechercher des communautés...", "text": "Toutes les communautés", - "ann_string": "Cliquez ici pour voir les annonces récentes!" + "ann_string": "Cliquez ici pour voir les dernières annonces!" }, "community": { "follow": "Suivre la communauté", @@ -34,7 +34,7 @@ "recent": "Publi. récentes", "popular": "Publi. populaires", "verified": "Publi. vérifiées", - "new": "Nouvelle publication" + "new": "Publier" }, "user_page": { "country": "Pays", From ca9e99c4af6ef56956ec200a91bd3f4b9ef3a9d7 Mon Sep 17 00:00:00 2001 From: Am Date: Tue, 10 Jun 2025 14:33:59 +0200 Subject: [PATCH 180/189] locales(update): Updated Japanese locale --- apps/juxtaposition-ui/src/translations/ja.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/ja.json b/apps/juxtaposition-ui/src/translations/ja.json index 9cc03aba..812f647e 100644 --- a/apps/juxtaposition-ui/src/translations/ja.json +++ b/apps/juxtaposition-ui/src/translations/ja.json @@ -19,7 +19,7 @@ }, "all_communities": { "text": "すべてのコミュニティ", - "announcements": "おしらせ", + "announcements": "お知らせ", "ann_string": "最新のお知らせはこちら!", "popular_places": "人気のコミュニティ", "new_communities": "新しいコミュニティ", From 5d23f193383d41f0fe03a87ecae3f318c7b3a25b Mon Sep 17 00:00:00 2001 From: Anonymous Date: Mon, 30 Jun 2025 10:45:10 +0200 Subject: [PATCH 181/189] locales(update): Updated Kazakh locale --- .../juxtaposition-ui/src/translations/kk.json | 75 ++++++++++++++++++- 1 file changed, 71 insertions(+), 4 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/kk.json b/apps/juxtaposition-ui/src/translations/kk.json index 62ef6be6..0a50a266 100644 --- a/apps/juxtaposition-ui/src/translations/kk.json +++ b/apps/juxtaposition-ui/src/translations/kk.json @@ -42,18 +42,85 @@ "birthday": "Туған күн", "game_experience": "Ойын тәжірибесі", "friends": "Достар", - "posts": "Жазбалар" + "posts": "Жазбалар", + "follow_user": "", + "no_following": "", + "befriend": "", + "following_user": "", + "pending": "", + "followers": "", + "unfriend": "", + "no_followers": "", + "no_friends": "", + "following": "" }, "setup": { "experience_text": { "info": "Ойындар бойынша тәжірибе деңгейіңізді қалай сипаттайтыныңызды айтыңыз. Бұл параметрді кейінірек өзгертуге болады.", - "intermediate": "Орташа" + "intermediate": "Орташа", + "expert": "", + "beginner": "" }, "google": "Google Analytics", "rules_text": { - "eighth": "Спойлер жазбаңыз" + "eighth": "Спойлер жазбаңыз", + "eleventh": "", + "tenth": "", + "third": "", + "thirteenth": "", + "fifth": "", + "ninth": "", + "fourth": "", + "second": "", + "sixth": "", + "first": "", + "seventh": "", + "twelfth": "" }, "ready": "Juxt пайдалануды бастауға дайын", - "guest_button": "Мен түссіндім" + "guest_button": "Мен түссіндім", + "beta_text": { + "third": "", + "second": "", + "first": "" + }, + "done_button": "", + "guest": "", + "guest_text": "", + "experience": "", + "rules": "", + "welcome_text": "", + "google_text": "", + "info": "", + "info_text": "", + "ready_text": "", + "done": "", + "beta": "", + "welcome": "" + }, + "notifications": { + "none": "", + "new_follower": "" + }, + "new_post": { + "swearing": "", + "text_hint": "", + "new_post_text": "", + "post_to": "" + }, + "user_settings": { + "show_game": "", + "show_comment": "", + "show_birthday": "", + "profile_settings": "", + "profile_comment": "", + "swearing": "", + "show_country": "" + }, + "activity_feed": { + "empty": "" + }, + "messages": { + "coming_soon": "" } } From 5f6ab5127c113b5b881c5e1ad2ea991e1202b666 Mon Sep 17 00:00:00 2001 From: Anonymous Date: Mon, 30 Jun 2025 10:45:20 +0200 Subject: [PATCH 182/189] locales(update): Updated Serbian locale --- .../juxtaposition-ui/src/translations/sr.json | 52 ++++++++++++++++--- 1 file changed, 45 insertions(+), 7 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/sr.json b/apps/juxtaposition-ui/src/translations/sr.json index 1ee56d30..2fb87008 100644 --- a/apps/juxtaposition-ui/src/translations/sr.json +++ b/apps/juxtaposition-ui/src/translations/sr.json @@ -11,7 +11,10 @@ "next": "Sledeće", "go_back": "Vrati se", "close": "Zatvori", - "more": "Učitaj još objava" + "more": "Učitaj još objava", + "yeahs": "", + "activity_feed": "", + "user_page": "" }, "language": "Srpski", "community": { @@ -33,7 +36,14 @@ "friends": "Prijatelji", "follow_user": "Zaprati", "followers": "Pratioci", - "pending": "U toku" + "pending": "U toku", + "game_experience": "", + "no_following": "", + "befriend": "", + "unfriend": "", + "no_followers": "", + "no_friends": "", + "following": "" }, "all_communities": { "new_communities": "Nove zajednice", @@ -51,12 +61,17 @@ "user_settings": { "profile_settings": "Podešavanja profila", "show_country": "Prikaži zemlju na profilu", - "show_birthday": "Prikaži rođendan na profilu" + "show_birthday": "Prikaži rođendan na profilu", + "show_game": "", + "show_comment": "", + "profile_comment": "", + "swearing": "" }, "new_post": { "new_post_text": "Nova objava", "post_to": "Objavi na", - "text_hint": "Dodirni ovde da napraviš objavu." + "text_hint": "Dodirni ovde da napraviš objavu.", + "swearing": "" }, "activity_feed": { "empty": "Ovde je prazno. Pokušaj da pratiš nekoga!" @@ -66,7 +81,19 @@ }, "setup": { "rules_text": { - "eighth": "Ne objavljuj spojlere" + "eighth": "Ne objavljuj spojlere", + "eleventh": "", + "tenth": "", + "third": "", + "thirteenth": "", + "fifth": "", + "ninth": "", + "fourth": "", + "second": "", + "sixth": "", + "first": "", + "seventh": "", + "twelfth": "" }, "experience_text": { "beginner": "Početnik", @@ -75,7 +102,9 @@ "info": "Molimo vas da opišete vaš nivo iskustva sa igricama. Ovo podešavanje se može promeniti kasnije." }, "beta_text": { - "second": "Ovo može podrazumevati brisanje cele baze podataka po završetku ili za vreme probnog perioda." + "second": "Ovo može podrazumevati brisanje cele baze podataka po završetku ili za vreme probnog perioda.", + "third": "", + "first": "" }, "experience": "Iskustvo sa Igricama", "google": "Google Analitika", @@ -83,6 +112,15 @@ "ready": "Spremni da Koristite Juxt", "done": "Uživajte u Juxt-u!", "done_button": "Krenimo!", - "ready_text": "Prvo proverite zajednice i vidite o čemu ljudi objavljuju oko celog sveta. Iskoristite ovu priliku da se upoznate sa Juxt-om. Možda ćete napraviti zanimljiva otkrića!" + "ready_text": "Prvo proverite zajednice i vidite o čemu ljudi objavljuju oko celog sveta. Iskoristite ovu priliku da se upoznate sa Juxt-om. Možda ćete napraviti zanimljiva otkrića!", + "guest_button": "", + "guest": "", + "guest_text": "", + "rules": "", + "welcome_text": "", + "info": "", + "info_text": "", + "beta": "", + "welcome": "" } } From cbbf6b0927b9976da1cf6f8d92a7d24dceff09d2 Mon Sep 17 00:00:00 2001 From: Anonymous Date: Mon, 30 Jun 2025 10:45:09 +0200 Subject: [PATCH 183/189] locales(update): Updated Belarusian locale --- .../juxtaposition-ui/src/translations/be.json | 70 +++++++++++++++++-- 1 file changed, 66 insertions(+), 4 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/be.json b/apps/juxtaposition-ui/src/translations/be.json index 0f28522f..4af60478 100644 --- a/apps/juxtaposition-ui/src/translations/be.json +++ b/apps/juxtaposition-ui/src/translations/be.json @@ -47,18 +47,80 @@ "follow_user": "Сачыць", "following_user": "Далей", "befriend": "Сябраваць", - "pending": "Дапытлівы" + "pending": "Дапытлівы", + "no_following": "", + "unfriend": "", + "no_followers": "", + "no_friends": "" }, "language": "Беларуская", "setup": { "experience_text": { "beginner": "Пачатковец", - "expert": "Эксперт" + "expert": "Эксперт", + "info": "", + "intermediate": "" }, "rules_text": { "tenth": "Парушэнні Кодэкса паводзін", - "thirteenth": "Калі вы размяшчаеце паведамленні ў суполцы аб гульні, у якую вы гулялі, вашы паведамленні будуць мець значок, які паказвае, што вы ў яе гулялі." + "thirteenth": "Калі вы размяшчаеце паведамленні ў суполцы аб гульні, у якую вы гулялі, вашы паведамленні будуць мець значок, які паказвае, што вы ў яе гулялі.", + "eleventh": "", + "third": "", + "fifth": "", + "ninth": "", + "fourth": "", + "second": "", + "sixth": "", + "first": "", + "eighth": "", + "seventh": "", + "twelfth": "" }, - "experience": "Вопыт гульні" + "experience": "Вопыт гульні", + "beta_text": { + "third": "", + "second": "", + "first": "" + }, + "guest_button": "", + "done_button": "", + "guest": "", + "ready": "", + "guest_text": "", + "google": "", + "rules": "", + "welcome_text": "", + "google_text": "", + "info": "", + "info_text": "", + "ready_text": "", + "done": "", + "beta": "", + "welcome": "" + }, + "notifications": { + "none": "", + "new_follower": "" + }, + "new_post": { + "swearing": "", + "text_hint": "", + "new_post_text": "", + "post_to": "" + }, + "user_settings": { + "show_game": "", + "show_comment": "", + "show_birthday": "", + "profile_settings": "", + "profile_comment": "", + "swearing": "", + "show_country": "" + }, + "activity_feed": { + "empty": "" + }, + "messages": { + "coming_soon": "" } } From 60863e5f5ee6de1e8b95fac126f0baada48b0b84 Mon Sep 17 00:00:00 2001 From: Anonymous Date: Mon, 30 Jun 2025 10:45:31 +0200 Subject: [PATCH 184/189] locales(update): Updated Welsh locale --- .../juxtaposition-ui/src/translations/cy.json | 36 +++++++++++++++++-- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/cy.json b/apps/juxtaposition-ui/src/translations/cy.json index 3490c2ef..030b8dd8 100644 --- a/apps/juxtaposition-ui/src/translations/cy.json +++ b/apps/juxtaposition-ui/src/translations/cy.json @@ -60,7 +60,8 @@ "show_country": "Ddangos Gwlad Ar Profil", "show_birthday": "Ddangos Penblwydd Ar Profil", "profile_comment": "Sylwadau profil", - "swearing": "Ni all gynnwys iaith eglur ar sylwadau profil." + "swearing": "Ni all gynnwys iaith eglur ar sylwadau profil.", + "show_game": "" }, "new_post": { "new_post_text": "Llwyth newydd", @@ -72,7 +73,17 @@ "rules_text": { "second": "Pobol dros y byd yn gallu spio ar eich llwythau", "eighth": "Ddim Llwythio Sbeilwyr", - "twelfth": "Ydach chi wedi chwarae gem yna?" + "twelfth": "Ydach chi wedi chwarae gem yna?", + "eleventh": "", + "tenth": "", + "third": "", + "thirteenth": "", + "fifth": "", + "ninth": "", + "fourth": "", + "sixth": "", + "first": "", + "seventh": "" }, "ready": "Barod I i ddechrau defnyddio juxt", "done": "Cael Hwyl Yn Juxt!", @@ -81,7 +92,26 @@ "guest_button": "Dwi'n Deall", "welcome": "Croeso I Jusxtaposition!", "rules": "Rheol Juxt", - "info": "Beth ydy juxtaposition?" + "info": "Beth ydy juxtaposition?", + "beta_text": { + "third": "", + "second": "", + "first": "" + }, + "experience_text": { + "expert": "", + "info": "", + "intermediate": "", + "beginner": "" + }, + "guest_text": "", + "experience": "", + "google": "", + "welcome_text": "", + "google_text": "", + "info_text": "", + "ready_text": "", + "beta": "" }, "activity_feed": { "empty": "Maen wag yma. Ceishwch dilyn rhywun!" From ad854e71ef2e1871f9296cb7af547c92908f06b5 Mon Sep 17 00:00:00 2001 From: Anonymous Date: Mon, 30 Jun 2025 10:45:33 +0200 Subject: [PATCH 185/189] locales(update): Updated Slovak locale --- apps/juxtaposition-ui/src/translations/sk.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/juxtaposition-ui/src/translations/sk.json b/apps/juxtaposition-ui/src/translations/sk.json index cd75332b..c88ddbc0 100644 --- a/apps/juxtaposition-ui/src/translations/sk.json +++ b/apps/juxtaposition-ui/src/translations/sk.json @@ -14,7 +14,8 @@ "activity_feed": "Informačný kanál aktivity", "go_back": "Choď späť", "back": "Späť", - "more": "Načítať ďalšie príspevky" + "more": "Načítať ďalšie príspevky", + "yeahs": "" }, "community": { "following": "Odoberané", From ad548f601cfa5e8ae16ce153ca47007ca404b865 Mon Sep 17 00:00:00 2001 From: Anonymous Date: Mon, 30 Jun 2025 10:45:33 +0200 Subject: [PATCH 186/189] locales(update): Updated Danish locale --- apps/juxtaposition-ui/src/translations/da.json | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/da.json b/apps/juxtaposition-ui/src/translations/da.json index fd12e448..edc32974 100644 --- a/apps/juxtaposition-ui/src/translations/da.json +++ b/apps/juxtaposition-ui/src/translations/da.json @@ -22,7 +22,13 @@ "fourth": "Vær sød or rare ved hinanden", "second": "Oplæg Kan Ses Verdenen Over", "eighth": "Del ikke Spoilere", - "tenth": "Retningslinjer Overtrædelser" + "tenth": "Retningslinjer Overtrædelser", + "eleventh": "", + "third": "", + "thirteenth": "", + "fifth": "", + "ninth": "", + "seventh": "" }, "beta": "Beta Ansvarsfralæggelse", "done_button": "Lad os komme i gang!", @@ -36,7 +42,12 @@ }, "ready_text": "Først og fremmest check ud nogle af fællesskaberne for at se hvad folk rund om verdenen snakker om. Brug det øjeblik til at gøre dig mere bekendt med Juxt. Måske opstår der endda nogle nye opdagelser på vejen!", "done": "Mor dig i Juxt!", - "info_text": "Juxt er et brugerdrevet spilfællesskab, hvor du kan kommunikere med folk\nfra hele verdenen. Du kan skrive eller tegne oplag i spilfælleskaber eller sende beskeder direkte til dine venner." + "info_text": "Juxt er et brugerdrevet spilfællesskab, hvor du kan kommunikere med folk\nfra hele verdenen. Du kan skrive eller tegne oplag i spilfælleskaber eller sende beskeder direkte til dine venner.", + "guest": "", + "ready": "", + "guest_text": "", + "google": "", + "google_text": "" }, "user_page": { "followers": "Følgere", From 74a56bab1451d6422d1b9098c9fb9d8abc181355 Mon Sep 17 00:00:00 2001 From: Anonymous Date: Mon, 30 Jun 2025 10:45:07 +0200 Subject: [PATCH 187/189] locales(update): Updated Hebrew locale --- .../juxtaposition-ui/src/translations/he.json | 78 ++++++++++++++++++- 1 file changed, 75 insertions(+), 3 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/he.json b/apps/juxtaposition-ui/src/translations/he.json index 337e4072..9ac9ca67 100644 --- a/apps/juxtaposition-ui/src/translations/he.json +++ b/apps/juxtaposition-ui/src/translations/he.json @@ -32,7 +32,9 @@ "posts": "פוסטים", "recent": "פוסטים אחרונים", "popular": "פוסטים פופולריים", - "verified": "פוסטים מאומתים" + "verified": "פוסטים מאומתים", + "tags": "", + "followers": "" }, "user_page": { "birthday": "יוֹם הוּלֶדֶת", @@ -45,10 +47,80 @@ "pending": "תָלוּי וְעוֹמֵד", "no_friends": "אין חברים", "no_following": "לא עוקב אחרי אף אחד", - "no_followers": "אין עוקבים" + "no_followers": "אין עוקבים", + "befriend": "", + "followers": "", + "unfriend": "", + "country": "" }, "user_settings": { "profile_settings": "הגדרות פרופיל", - "show_birthday": "הצג יום הולדת בפרופיל" + "show_birthday": "הצג יום הולדת בפרופיל", + "show_game": "", + "show_comment": "", + "profile_comment": "", + "swearing": "", + "show_country": "" + }, + "setup": { + "rules_text": { + "eleventh": "", + "tenth": "", + "third": "", + "thirteenth": "", + "fifth": "", + "ninth": "", + "fourth": "", + "second": "", + "sixth": "", + "first": "", + "eighth": "", + "seventh": "", + "twelfth": "" + }, + "beta_text": { + "third": "", + "second": "", + "first": "" + }, + "experience_text": { + "expert": "", + "info": "", + "intermediate": "", + "beginner": "" + }, + "guest_button": "", + "done_button": "", + "guest": "", + "ready": "", + "guest_text": "", + "experience": "", + "google": "", + "rules": "", + "welcome_text": "", + "google_text": "", + "info": "", + "info_text": "", + "ready_text": "", + "done": "", + "beta": "", + "welcome": "" + }, + "notifications": { + "none": "", + "new_follower": "" + }, + "new_post": { + "swearing": "", + "text_hint": "", + "new_post_text": "", + "post_to": "" + }, + "language": "", + "activity_feed": { + "empty": "" + }, + "messages": { + "coming_soon": "" } } From 5466c41d76d3a9f16475d3c340d3ffaa8196f404 Mon Sep 17 00:00:00 2001 From: Anonymous Date: Mon, 30 Jun 2025 10:45:08 +0200 Subject: [PATCH 188/189] locales(update): Updated Irish locale --- .../juxtaposition-ui/src/translations/ga.json | 32 +++++++++++++++++-- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/ga.json b/apps/juxtaposition-ui/src/translations/ga.json index e4e019c3..13555ae4 100644 --- a/apps/juxtaposition-ui/src/translations/ga.json +++ b/apps/juxtaposition-ui/src/translations/ga.json @@ -81,7 +81,8 @@ "beta": "Shéanadh Béite", "beta_text": { "first": "Tá tú chun an chead béite poiblí de Juxt a thrial amach. Cialaíonn sé seo go bhfuil rudaí fós neamhcinnte, agus is feidir le go leor athrú in ann tharlú ag aon am.", - "second": "Is féidir agus is féadfaidh go mbeidh scrios iomlán don bunachar sonraí ag deireadh nó i rith an tréimhse béite." + "second": "Is féidir agus is féadfaidh go mbeidh scrios iomlán don bunachar sonraí ag deireadh nó i rith an tréimhse béite.", + "third": "" }, "info": "Cad é Juxtaposition?", "rules_text": { @@ -89,9 +90,34 @@ "sixth": "Ná Postáil Eolas Pearsanta atá Leatsa nó Le Duine Eile", "fourth": "Beidh Go Deas le Daoine Eile", "third": "Tá go leor phobail cluchíocht i Juxt ina bhfuil daoine ar fud an domhain in ann a smaointe a roinnt. Nuair a cruthaíonn tú postáil, cuimhnigh gur feidir le gach daoine in ann é a fheiceál. Le do thoil, chur tú féin in iúl i mbealach a féidir le gach daoine taitneamh a bhaint as. Úsáid chiall cóiteann, agus smaoineamh roimh a deannan tú postál. Is seirbhís é Juxt a bhfuil ar fháil ar an tIdírlíon freisin. Cuimhnigh gur feidir freisin le dhaoine nach úsáideann Juxt do postálacha a fhecáil. Chomh maith leis sin, feicfear aon trácht a dheannan tú ar postálacha do chairde ag ní hamháin do chairde, ach daoine timpeall an domhain freisin. Le do thoil, cuimhnigh ar seo.", - "fifth": "Chun Juxt a coinnigh mar áit spraoiúil le haghadih gach duine, cuirimis ceist ort a bheidh tuisceanach le húsáideoirí eile. Cabhair linn Juxt a coinnigh mar taithí taitneamhach agus ná postáil rud ar bith atá mí-oiriúnach nó maslach." + "fifth": "Chun Juxt a coinnigh mar áit spraoiúil le haghadih gach duine, cuirimis ceist ort a bheidh tuisceanach le húsáideoirí eile. Cabhair linn Juxt a coinnigh mar taithí taitneamhach agus ná postáil rud ar bith atá mí-oiriúnach nó maslach.", + "eleventh": "", + "tenth": "", + "thirteenth": "", + "ninth": "", + "first": "", + "eighth": "", + "seventh": "", + "twelfth": "" }, - "rules": "Rialacha Juxt" + "rules": "Rialacha Juxt", + "experience_text": { + "expert": "", + "info": "", + "intermediate": "", + "beginner": "" + }, + "guest_button": "", + "done_button": "", + "guest": "", + "ready": "", + "guest_text": "", + "experience": "", + "google": "", + "google_text": "", + "info_text": "", + "ready_text": "", + "done": "" }, "language": "Gaeilge", "messages": { From a474416772471b6ce52b8cc0ddea11795ac815d6 Mon Sep 17 00:00:00 2001 From: Anonymous Date: Mon, 30 Jun 2025 10:45:20 +0200 Subject: [PATCH 189/189] locales(update): Updated English (en@uwu) locale --- .../src/translations/en@uwu.json | 76 ++++++++++++++++++- 1 file changed, 74 insertions(+), 2 deletions(-) diff --git a/apps/juxtaposition-ui/src/translations/en@uwu.json b/apps/juxtaposition-ui/src/translations/en@uwu.json index 6b892f97..6c31694b 100644 --- a/apps/juxtaposition-ui/src/translations/en@uwu.json +++ b/apps/juxtaposition-ui/src/translations/en@uwu.json @@ -15,7 +15,9 @@ "followers": "Fowwowers", "popular": "Popuwaw P-posts", "verified": "Vewwifiwed P-posts", - "new": "Nyew P-Post" + "new": "Nyew P-Post", + "posts": "", + "tags": "" }, "global": { "communities": "kitteh klans", @@ -49,6 +51,76 @@ "befriend": "Befwiend", "pending": "Pwending", "unfriend": "Unfwiend", - "no_following": "Nyot Fowwowing Anyonye" + "no_following": "Nyot Fowwowing Anyonye", + "no_followers": "" + }, + "setup": { + "rules_text": { + "eleventh": "", + "tenth": "", + "third": "", + "thirteenth": "", + "fifth": "", + "ninth": "", + "fourth": "", + "second": "", + "sixth": "", + "first": "", + "eighth": "", + "seventh": "", + "twelfth": "" + }, + "beta_text": { + "third": "", + "second": "", + "first": "" + }, + "experience_text": { + "expert": "", + "info": "", + "intermediate": "", + "beginner": "" + }, + "guest_button": "", + "done_button": "", + "guest": "", + "ready": "", + "guest_text": "", + "experience": "", + "google": "", + "rules": "", + "welcome_text": "", + "google_text": "", + "info": "", + "info_text": "", + "ready_text": "", + "done": "", + "beta": "", + "welcome": "" + }, + "notifications": { + "none": "", + "new_follower": "" + }, + "new_post": { + "swearing": "", + "text_hint": "", + "new_post_text": "", + "post_to": "" + }, + "user_settings": { + "show_game": "", + "show_comment": "", + "show_birthday": "", + "profile_settings": "", + "profile_comment": "", + "swearing": "", + "show_country": "" + }, + "activity_feed": { + "empty": "" + }, + "messages": { + "coming_soon": "" } }