Merge remote-tracking branch 'misskey-original/develop' into develop
# Conflicts: # packages/backend/src/core/activitypub/models/ApPersonService.ts
This commit is contained in:
commit
e4fe534dc6
|
@ -1157,6 +1157,12 @@ edited: "Editat"
|
|||
notificationRecieveConfig: "Paràmetres de notificacions"
|
||||
mutualFollow: "Seguidor mutu"
|
||||
fileAttachedOnly: "Només notes amb adjunts"
|
||||
showRepliesToOthersInTimeline: "Mostrar les respostes a altres a la línia de temps"
|
||||
hideRepliesToOthersInTimeline: "Amagar les respostes a altres a la línia de temps"
|
||||
showRepliesToOthersInTimelineAll: "Mostrar les respostes a altres a usuaris que segueixes a la línia de temps"
|
||||
hideRepliesToOthersInTimelineAll: "Ocultar les teves respostes a tots els usuaris que segueixes a la línia de temps"
|
||||
confirmShowRepliesAll: "Aquesta opció no té marxa enrere. Vols mostrar les teves respostes a tots els que segueixes a la teva línia de temps?"
|
||||
confirmHideRepliesAll: "Aquesta opció no té marxa enrere. Vols ocultar les teves respostes a tots els usuaris que segueixes a la línia de temps?"
|
||||
externalServices: "Serveis externs"
|
||||
impressum: "Impressum"
|
||||
impressumUrl: "Adreça URL impressum"
|
||||
|
@ -1187,7 +1193,25 @@ seasonalScreenEffect: "Efectes de pantalla segons les estacions"
|
|||
decorate: "Decorar"
|
||||
addMfmFunction: "Afegeix funcions MFM"
|
||||
enableQuickAddMfmFunction: "Activar accés ràpid per afegir funcions MFM"
|
||||
bubbleGame: "Bubble Game"
|
||||
sfx: "Efectes de so"
|
||||
soundWillBePlayed: "Es reproduiran efectes de so"
|
||||
showReplay: "Veure reproducció"
|
||||
replay: "Reproduir"
|
||||
replaying: "Reproduint"
|
||||
ranking: "Classificació"
|
||||
lastNDays: "Últims {n} dies"
|
||||
backToTitle: "Torna al títol"
|
||||
hemisphere: "Geolocalització"
|
||||
withSensitive: "Incloure notes amb fitxers sensibles"
|
||||
userSaysSomethingSensitive: "La publicació de {name} conte material sensible"
|
||||
enableHorizontalSwipe: "Lliscar per canviar de pestanya"
|
||||
_bubbleGame:
|
||||
howToPlay: "Com es juga"
|
||||
_howToPlay:
|
||||
section1: "Ajusta la posició i deixa caure l'objecte dintre la caixa."
|
||||
section2: "Quan dos objectes del mateix tipus es toquen, canviaran en un objecte diferent i guanyares punts."
|
||||
section3: "El joc s'acabarà quan els objectes sobresurtin de la caixa. Intenta aconseguir la puntuació més gran possible fusionant objectes mentre impedeixes que sobresurtin de la caixa!"
|
||||
_announcement:
|
||||
forExistingUsers: "Anunci per usuaris registrats"
|
||||
forExistingUsersDescription: "Aquest avís només es mostrarà als usuaris existents fins al moment de la publicació. Si no també es mostrarà als usuaris que es registrin després de la publicació."
|
||||
|
@ -1209,8 +1233,32 @@ _initialAccountSetting:
|
|||
privacySetting: "Configuració de seguretat"
|
||||
theseSettingsCanEditLater: "Aquests ajustos es poden canviar més tard."
|
||||
youCanEditMoreSettingsInSettingsPageLater: "A més d'això, es poden fer diferents configuracions a través de la pàgina de configuració. Assegureu-vos de comprovar-ho més tard."
|
||||
followUsers: "Prova de seguir usuaris que t'interessin per construir la teva línia de temps."
|
||||
pushNotificationDescription: "Activant les notificacions emergents et permetrà rebre notificacions de {name} directament al teu dispositiu."
|
||||
initialAccountSettingCompleted: "Configuració del perfil completada!"
|
||||
haveFun: "Disfruta {name}!"
|
||||
youCanContinueTutorial: "Pots continuar amb un tutorial per aprendre a Fer servir {name} (MissKey) o tu pots estalviar i començar a fer-lo servir ja."
|
||||
startTutorial: "Començar el tutorial"
|
||||
skipAreYouSure: "Et vols saltar la configuració del perfil?"
|
||||
laterAreYouSure: "Vols continuar la configuració del perfil més tard?"
|
||||
_initialTutorial:
|
||||
launchTutorial: "Començar tutorial"
|
||||
title: "Tutorial"
|
||||
wellDone: "Ben fet!"
|
||||
skipAreYouSure: "Sortir del tutorial?"
|
||||
_landing:
|
||||
title: "Benvingut al tutorial"
|
||||
description: "Aquí aprendràs el bàsic per poder fer servir Misskey i les seves característiques."
|
||||
_note:
|
||||
title: "Què és una Nota?"
|
||||
description: "Les publicacions a Misskey es diuen 'Notes'. Les Notes s'ordenen cronològicament a la línia de temps i s'actualitzen de forma automàtica."
|
||||
reply: "Fes clic en aquest botó per contestar a un missatge. També és possible contestar a una contestació, continuant la conversació en forma de fil."
|
||||
renote: "Pots compartir una Nota a la teva pròpia línia de temps. Inclús pots citar-les amb els teus comentaris."
|
||||
reaction: "Pots afegir reaccions a les Notes. Entrarem més en detall a la pròxima pàgina."
|
||||
menu: "Pots veure els detalls de les Notes, copiar enllaços i fer diferents accions."
|
||||
_reaction:
|
||||
title: "Què són les Reaccions?"
|
||||
description: "Es poden reaccionar a les Notes amb diferents emoticones. Les reaccions et permeten expressar matisos que hi són més enllà d'un simple m'agrada."
|
||||
letsTryReacting: "Es poden afegir reaccions fent clic al botó '+'. Prova reaccionant a aquesta nota!"
|
||||
reactToContinue: "Afegeix una reacció per continuar."
|
||||
reactNotification: "Rebràs notificacions en temps real quan un usuari reaccioni a les teves notes."
|
||||
|
@ -1272,9 +1320,75 @@ _serverSettings:
|
|||
shortName: "Nom curt"
|
||||
shortNameDescription: "Una abreviatura del nom de la instància que es poguí mostrar en cas que el nom oficial sigui massa llarg"
|
||||
fanoutTimelineDescription: "Quan es troba activat millora bastant el rendiment quan es recuperen les línies de temps i redueix la carrega de la base de dades. Com a contrapunt, l'ús de memòria de Redis es veurà incrementada. Considera d'estabilitat aquesta opció en cas de tenir un servidor amb poca memòria o si tens problemes de inestabilitat."
|
||||
fanoutTimelineDbFallback: "Carregar de la base de dades"
|
||||
fanoutTimelineDbFallbackDescription: "Quan s'activa, la línia de temps fa servir la base de dades per consultes adicionals si la línia de temps no es troba a la memòria cau. Si és desactiva la càrrega del servidor és veure reduïda, però també és reduirà el nombre de línies de temps que és poden obtenir."
|
||||
_accountMigration:
|
||||
moveFrom: "Migrar un altre compte a aquest"
|
||||
moveFromSub: "Crear un àlies per un altre compte"
|
||||
moveFromLabel: "Compte original #{n}"
|
||||
moveFromDescription: "Has de crear un àlies del compte que vols migrar en aquest compte.\nFes servir aquest format per posar el compte que vols migrar: @nomusuari@servidor.exemple.com\nPer esborrar l'àlies deixa el camp en blanc (no és recomanable de fer)"
|
||||
moveTo: "Migrar aquest compte a un altre"
|
||||
moveToLabel: "Compte al qual es vol migrar:"
|
||||
moveCannotBeUndone: "Les migracions dels comptes no es poden desfer."
|
||||
moveAccountDescription: "Això migrarà la teva compte a un altre diferent.\n ・Els seguidors d'aquest compte és passaran al compte nou de forma automàtica\n ・Es deixaran de seguir a tots els usuaris que es segueixen actualment en aquest compte\n ・No es poden crear notes noves, etc. en aquest compte\n\nSi bé la migració de seguidors es automàtica, has de preparar alguns pasos manualment per migrar la llista d'usuaris que segueixes. Per fer això has d'exportar els seguidors que després importaraes al compte nou mitjançant el menú de configuració. El mateix procediment s'ha de seguir per less teves llistes i els teus usuaris silenciats i bloquejats.\n\n(Aquesta explicació s'aplica a Misskey v13.12.0 i posteriors. Altres aplicacions, com Mastodon, poden funcionar diferent.)"
|
||||
moveAccountHowTo: "Per fer la migració, primer has de crear un àlies per aquest compte al compte al qual vols migrar.\nDesprés de crear l'àlies, introdueix el compte al qual vols migrar amb el format següent: @nomusuari@servidor.exemple.com"
|
||||
startMigration: "Migrar"
|
||||
migrationConfirm: "Vols migrar aquest compte a {account}? Una vegada comenci la migració no es podrà parar O fer marxa enrere i no podràs tornar a fer servir aquest compte mai més."
|
||||
movedAndCannotBeUndone: "Aquest compte ha migrat.\nLes migracions no es poden desfer."
|
||||
postMigrationNote: "Aquest compte deixarà de seguir tots els comptes que segueix 24 hores després de germinar la migració.\nEl nombre de seguidors i seguits passarà a ser de zero. Per evitar que els teus seguidors no puguin veure les publicacions marcades com a només seguidors continuaren seguint aquest compte."
|
||||
movedTo: "Nou compte:"
|
||||
_achievements:
|
||||
earnedAt: "Desbloquejat el"
|
||||
_types:
|
||||
_notes1:
|
||||
title: "Aquí, configurant el meu msky"
|
||||
description: "Publica la teva primera Nota"
|
||||
flavor: "Passa-t'ho bé fent servir Miskey!"
|
||||
_notes10:
|
||||
title: "Algunes notes"
|
||||
description: "Publica 10 notes"
|
||||
_notes100:
|
||||
title: "Un piló de notes"
|
||||
description: "Publica 100 notes"
|
||||
_notes500:
|
||||
title: "Cobert de notes"
|
||||
description: "Publica 500 notes"
|
||||
_notes1000:
|
||||
title: "Un piló de notes"
|
||||
description: "1 000 notes publicades"
|
||||
_notes5000:
|
||||
title: "Desbordament de notes"
|
||||
description: "5 000 notes publicades"
|
||||
_notes10000:
|
||||
title: "Supernota"
|
||||
description: "10 000 notes publicades"
|
||||
_notes20000:
|
||||
title: "Necessito... Més... Notes!"
|
||||
description: "20 000 notes publicades"
|
||||
_notes30000:
|
||||
title: "Notes notes notes!"
|
||||
description: "30 000 notes publicades"
|
||||
_notes40000:
|
||||
title: "Fàbrica de notes"
|
||||
description: "40 000 notes publicades"
|
||||
_notes50000:
|
||||
title: "Planeta de notes"
|
||||
description: "50 000 notes publicades"
|
||||
_notes60000:
|
||||
title: "Quàsar de notes"
|
||||
description: "60 000 notes publicades"
|
||||
_notes70000:
|
||||
title: "Forat negre de notes"
|
||||
description: "70 000 notes publicades"
|
||||
_notes80000:
|
||||
title: "Galàxia de notes"
|
||||
description: "80 000 notes publicades"
|
||||
_notes90000:
|
||||
title: "Univers de notes"
|
||||
description: "90 000 notes publicades"
|
||||
_notes100000:
|
||||
title: "ALL YOUR NOTE ARE BELONG TO US"
|
||||
description: "100 000 notes publicades"
|
||||
flavor: "Segur que tens moltes coses a dir?"
|
||||
_login3:
|
||||
title: "Principiant I"
|
||||
|
@ -1347,13 +1461,90 @@ _achievements:
|
|||
description: "És la primera vegada que et segueixo"
|
||||
_following10:
|
||||
title: "Segueix-me... Segueix-me..."
|
||||
description: "Seguir 10 usuaris"
|
||||
_following50:
|
||||
title: "Molts amics"
|
||||
description: "Seguir 50 comptes"
|
||||
_following100:
|
||||
title: "100 amics"
|
||||
description: "Segueixes 100 comptes"
|
||||
_following300:
|
||||
title: "Sobrecàrrega d'amics"
|
||||
description: "Segueixes 300 comptes"
|
||||
_followers1:
|
||||
title: "Primer seguidor"
|
||||
description: "1 seguidor guanyat"
|
||||
_followers10:
|
||||
title: "Segueix-me!"
|
||||
description: "10 seguidors guanyats"
|
||||
_followers50:
|
||||
title: "Venen en manada"
|
||||
description: "50 seguidors guanyats"
|
||||
_followers100:
|
||||
title: "Popular"
|
||||
description: "100 seguidors guanyats"
|
||||
_followers300:
|
||||
title: "Si us plau, d'un en un!"
|
||||
description: "300 seguidors guanyats"
|
||||
_followers500:
|
||||
title: "Torre de ràdio"
|
||||
description: "500 seguidors guanyats"
|
||||
_followers1000:
|
||||
title: "Influenciador"
|
||||
description: "1 000 seguidors guanyats"
|
||||
_collectAchievements30:
|
||||
title: "Col·leccionista d'èxits "
|
||||
description: "Desbloqueja 30 assoliments"
|
||||
_viewAchievements3min:
|
||||
title: "M'agraden els èxits "
|
||||
description: "Mira la teva llista d'assoliments durant més de 3 minuts"
|
||||
_iLoveMisskey:
|
||||
title: "Estimo Misskey"
|
||||
description: "Publica \"I ❤ #Misskey\""
|
||||
flavor: "L'equip de desenvolupament de Misskey agraeix el vostre suport!"
|
||||
_foundTreasure:
|
||||
title: "A la Recerca del Tresor"
|
||||
description: "Has trobat el tresor amagat"
|
||||
_client30min:
|
||||
title: "Parem una estona"
|
||||
description: "Mantingues obert Misskey per 30 minuts"
|
||||
_client60min:
|
||||
title: "A totes amb Misskey"
|
||||
description: "Mantingues Misskey obert per 60 minuts"
|
||||
_noteDeletedWithin1min:
|
||||
title: "No et preocupis"
|
||||
description: "Esborra una nota al minut de publicar-la"
|
||||
_postedAtLateNight:
|
||||
title: "Nocturn"
|
||||
description: "Publica una nota a altes hores de la nit "
|
||||
flavor: "És hora d'anar a dormir."
|
||||
_open3windows:
|
||||
title: "Multi finestres"
|
||||
description: "I va obrir més de tres finestres"
|
||||
_driveFolderCircularReference:
|
||||
title: "Consulteu la secció de bucle"
|
||||
_role:
|
||||
permission: "Permisos de rol"
|
||||
descriptionOfPermission: "Els <b>Moderadors</b> poden fer operacions bàsiques de moderació.\nEls <b>Administradors</b> poden canviar tots els ajustos del servidor."
|
||||
assignTarget: "Assignar "
|
||||
descriptionOfAssignTarget: "<b>Manual</b> per canviar manualment qui és part d'aquest rol i qui no.\n<b>Condicional</b> per afegir o eliminar de manera automàtica els usuaris d'aquest rol basat en una determinada condició."
|
||||
manual: "Manual"
|
||||
manualRoles: "Rols manuals"
|
||||
conditional: "Condicional"
|
||||
conditionalRoles: "Rols condicionals"
|
||||
condition: "Condició"
|
||||
isConditionalRole: "Aquest és un rol condicional"
|
||||
isPublic: "Rol públic"
|
||||
descriptionOfIsPublic: "Aquest rol es mostrarà al perfil dels usuaris al que se'ls assigni."
|
||||
options: "Opcions"
|
||||
policies: "Polítiques"
|
||||
baseRole: "Plantilla de rols"
|
||||
useBaseValue: "Fer servir els valors de la plantilla de rols"
|
||||
chooseRoleToAssign: "Selecciona els rols a assignar"
|
||||
iconUrl: "URL de la icona "
|
||||
asBadge: "Mostrar com a insígnia "
|
||||
descriptionOfAsBadge: "La icona d'aquest rol es mostrarà al costat dels noms d'usuaris que tinguin assignats aquest rol."
|
||||
isExplorable: "Fer el rol explorable"
|
||||
priority: "Prioritat"
|
||||
_priority:
|
||||
low: "Baixa"
|
||||
|
|
|
@ -102,7 +102,7 @@ defaultNoteVisibility: "Privacy predefinita delle note"
|
|||
follow: "Segui"
|
||||
followRequest: "Richiesta di follow"
|
||||
followRequests: "Richieste di follow"
|
||||
unfollow: "Interrompi following"
|
||||
unfollow: "Smetti di seguire"
|
||||
followRequestPending: "Richiesta in approvazione"
|
||||
enterEmoji: "Inserisci emoji"
|
||||
renote: "Rinota"
|
||||
|
@ -380,9 +380,11 @@ hcaptcha: "hCaptcha"
|
|||
enableHcaptcha: "Abilita hCaptcha"
|
||||
hcaptchaSiteKey: "Chiave del sito"
|
||||
hcaptchaSecretKey: "Chiave segreta"
|
||||
mcaptcha: "mCaptcha"
|
||||
enableMcaptcha: "Abilita hCaptcha"
|
||||
mcaptchaSiteKey: "Chiave del sito"
|
||||
mcaptchaSecretKey: "Chiave segreta"
|
||||
mcaptchaInstanceUrl: "URL della istanza mCaptcha"
|
||||
recaptcha: "reCAPTCHA"
|
||||
enableRecaptcha: "Abilita reCAPTCHA"
|
||||
recaptchaSiteKey: "Chiave del sito"
|
||||
|
@ -630,6 +632,7 @@ medium: "Medio"
|
|||
small: "Piccolo"
|
||||
generateAccessToken: "Genera token di accesso"
|
||||
permission: "Autorizzazioni "
|
||||
adminPermission: "Privilegi amministrativi"
|
||||
enableAll: "Abilita tutto"
|
||||
disableAll: "Disabilita tutto"
|
||||
tokenRequested: "Autorizza accesso al profilo"
|
||||
|
@ -673,6 +676,7 @@ useGlobalSettingDesc: "Quando attiva, verranno utilizzate le impostazioni notifi
|
|||
other: "Ulteriori"
|
||||
regenerateLoginToken: "Genera di nuovo un token di connessione"
|
||||
regenerateLoginTokenDescription: "Genera un nuovo token di autenticazione. Solitamente questa operazione non è necessaria: quando si genera un nuovo token, tutti i dispositivi vanno disconnessi."
|
||||
theKeywordWhenSearchingForCustomEmoji: "Questa sarà la parola chiave durante la ricerca di emoji personalizzate"
|
||||
setMultipleBySeparatingWithSpace: "È possibile creare multiple voci separate da spazi."
|
||||
fileIdOrUrl: "ID o URL del file"
|
||||
behavior: "Comportamento"
|
||||
|
@ -869,7 +873,7 @@ pubSub: "Publish/Subscribe del profilo"
|
|||
lastCommunication: "La comunicazione più recente"
|
||||
resolved: "Risolto"
|
||||
unresolved: "Non risolto"
|
||||
breakFollow: "Interrompi follow"
|
||||
breakFollow: "Impedire di seguirmi"
|
||||
breakFollowConfirm: "Vuoi davvero che questo profilo smetta di seguirti?"
|
||||
itsOn: "Abilitato"
|
||||
itsOff: "Disabilitato"
|
||||
|
@ -885,6 +889,8 @@ makeReactionsPublicDescription: "La lista delle reazioni che avete fatto è a di
|
|||
classic: "Classico"
|
||||
muteThread: "Silenzia conversazione"
|
||||
unmuteThread: "Riattiva la conversazione"
|
||||
followingVisibility: "Visibilità dei profili seguiti"
|
||||
followersVisibility: "Visibilità dei profili che ti seguono"
|
||||
continueThread: "Altre conversazioni"
|
||||
deleteAccountConfirm: "Così verrà eliminato il profilo. Vuoi procedere?"
|
||||
incorrectPassword: "La password è errata."
|
||||
|
@ -1053,6 +1059,8 @@ limitWidthOfReaction: "Limita la larghezza delle reazioni e ridimensionale"
|
|||
noteIdOrUrl: "ID della Nota o URL"
|
||||
video: "Video"
|
||||
videos: "Video"
|
||||
audio: "Audio"
|
||||
audioFiles: "Audio"
|
||||
dataSaver: "Risparmia dati"
|
||||
accountMigration: "Migrazione del profilo"
|
||||
accountMoved: "Questo profilo ha migrato altrove:"
|
||||
|
@ -1183,7 +1191,27 @@ remainingN: "Rimangono: {n}"
|
|||
overwriteContentConfirm: "Vuoi davvero sostituire l'attuale contenuto?"
|
||||
seasonalScreenEffect: "Schermate in base alla stagione"
|
||||
decorate: "Decora"
|
||||
addMfmFunction: "Aggiungi decorazioni"
|
||||
enableQuickAddMfmFunction: "Attiva il selettore di funzioni MFM"
|
||||
bubbleGame: "Bubble Game"
|
||||
sfx: "Effetti sonori"
|
||||
soundWillBePlayed: "Verrà riprodotto il suono"
|
||||
showReplay: "Vedi i replay"
|
||||
replay: "Replay"
|
||||
replaying: "Replay in corso"
|
||||
ranking: "Classifica"
|
||||
lastNDays: "Ultimi {n} giorni"
|
||||
backToTitle: "Torna al titolo"
|
||||
hemisphere: "Geolocalizzazione"
|
||||
withSensitive: "Mostra le Note con allegati espliciti"
|
||||
userSaysSomethingSensitive: "Note da {name} con allegati espliciti"
|
||||
enableHorizontalSwipe: "Trascina per invertire i tab"
|
||||
_bubbleGame:
|
||||
howToPlay: "Come giocare"
|
||||
_howToPlay:
|
||||
section1: "Regola la posizione e rilascia l'oggetto nella casella."
|
||||
section2: "Ottieni un punteggio, quando due oggetti dello stesso tipo si toccano e si trasformano in un oggetto diverso."
|
||||
section3: "Se gli oggetti traboccano dalla scatola, il gioco finisce. Cerca di ottenere un punteggio elevato fondendo gli oggetti, evitando che escano dalla scatola!"
|
||||
_announcement:
|
||||
forExistingUsers: "Solo ai profili attuali"
|
||||
forExistingUsersDescription: "L'annuncio sarà visibile solo ai profili esistenti in questo momento. Se disabilitato, sarà visibile anche ai profili che verranno creati dopo la pubblicazione di questo annuncio."
|
||||
|
@ -1554,6 +1582,13 @@ _achievements:
|
|||
_tutorialCompleted:
|
||||
title: "Attestato di partecipazione al corso per principianti di Misskey"
|
||||
description: "Ha completato il tutorial"
|
||||
_bubbleGameExplodingHead:
|
||||
title: "🤯"
|
||||
description: "Estrai l'oggetto più grande dal Bubble Game"
|
||||
_bubbleGameDoubleExplodingHead:
|
||||
title: "Doppio 🤯"
|
||||
description: "Due oggetti più grossi contemporaneamente nel Bubble Game"
|
||||
flavor: "Ha le dimensioni di una bento-box 🤯 🤯"
|
||||
_role:
|
||||
new: "Nuovo ruolo"
|
||||
edit: "Modifica ruolo"
|
||||
|
@ -1644,6 +1679,7 @@ _emailUnavailable:
|
|||
disposable: "Indirizzo email non utilizzabile"
|
||||
mx: "Server email non corretto"
|
||||
smtp: "Il server email non risponde"
|
||||
banned: "Non puoi registrarti con questo indirizzo email"
|
||||
_ffVisibility:
|
||||
public: "Pubblica"
|
||||
followers: "Mostra solo ai follower"
|
||||
|
@ -1935,6 +1971,26 @@ _permissions:
|
|||
"write:flash": "Modifica Play"
|
||||
"read:flash-likes": "Visualizza lista di Play piaciuti"
|
||||
"write:flash-likes": "Modifica lista di Play piaciuti"
|
||||
"read:admin:abuse-user-reports": "Mostra i report dai profili utente"
|
||||
"write:admin:delete-account": "Elimina l'account utente"
|
||||
"write:admin:delete-all-files-of-a-user": "Elimina i file dell'account utente"
|
||||
"read:admin:index-stats": "Visualizza informazioni sugli indici del database"
|
||||
"read:admin:table-stats": "Visualizza informazioni sulle tabelle del database"
|
||||
"read:admin:user-ips": "Visualizza indirizzi IP degli account"
|
||||
"read:admin:meta": "Visualizza i metadati dell'istanza"
|
||||
"write:admin:reset-password": "Ripristina la password dell'account utente"
|
||||
"write:admin:resolve-abuse-user-report": "Risolvere le segnalazioni dagli account utente"
|
||||
"write:admin:send-email": "Spedire email"
|
||||
"read:admin:server-info": "Vedere le informazioni sul server"
|
||||
"read:admin:show-moderation-log": "Vedere lo storico di moderazione"
|
||||
"read:admin:show-user": "Vedere le informazioni private degli account utente"
|
||||
"read:admin:show-users": "Vedere le informazioni private degli account utente"
|
||||
"write:admin:suspend-user": "Sospendere i profili"
|
||||
"write:admin:unset-user-avatar": "Rimuovere la foto profilo dai profili"
|
||||
"write:admin:unset-user-banner": "Rimuovere l'immagine testata dai profili"
|
||||
"write:admin:unsuspend-user": "Togliere la sospensione ai profili"
|
||||
"write:admin:meta": "Modificare i metadati dell'istanza"
|
||||
"write:admin:user-note": "Scrivere annotazioni di moderazione"
|
||||
_auth:
|
||||
shareAccessTitle: "Permessi dell'applicazione"
|
||||
shareAccess: "Vuoi autorizzare {name} ad accedere al tuo profilo?"
|
||||
|
|
|
@ -40,7 +40,7 @@ favorites: "질겨찾기"
|
|||
unfavorite: "질겨찾기서 어ᇝ애기"
|
||||
favorited: "질겨찾기에 담앗십니다."
|
||||
alreadyFavorited: "벌시로 질겨찾기에 담기 잇십니다."
|
||||
cantFavorite: "질겨찾기에 몬 담았십니다."
|
||||
cantFavorite: "질겨찾기에 몬 담앗십니다."
|
||||
pin: "프로필에 붙이기"
|
||||
unpin: "프로필서 띠기"
|
||||
copyContent: "내용 복사하기"
|
||||
|
@ -124,6 +124,7 @@ reactions: "반엉"
|
|||
reactionSettingDescription2: "꺼시서 두고, 누질라서 뭉캐고, ‘+’럴 누질라서 옇십니다."
|
||||
rememberNoteVisibility: "공개 범위럴 기억하기"
|
||||
attachCancel: "붙임 빼기"
|
||||
deleteFile: "파일 뭉캐기"
|
||||
markAsSensitive: "수ᇚ힘 설정"
|
||||
unmarkAsSensitive: "수ᇚ힘 무루기"
|
||||
enterFileName: "파일 이럼 서기"
|
||||
|
@ -463,6 +464,8 @@ onlyOneFileCanBeAttached: "메시지엔 파일 하나까제밖에 몬 넣십니
|
|||
invitations: "초대하기"
|
||||
invitationCode: "초대장"
|
||||
checking: "학인하고 잇십니다"
|
||||
tooShort: "억수로 짜립니다"
|
||||
tooLong: "억수로 집니다"
|
||||
passwordMatched: "맞십니다"
|
||||
passwordNotMatched: "안 맞십니다"
|
||||
signinFailed: "로그인 몬 했십니다. 고 이름이랑 비밀번호 제대로 썼는가 확인해 주이소."
|
||||
|
@ -571,7 +574,11 @@ userSilenced: "요 게정은... 수ᇚ혀 있십니다."
|
|||
relays: "릴레이"
|
||||
addRelay: "릴레이 옇기"
|
||||
addedRelays: "옇은 릴레이"
|
||||
deletedNote: "뭉캔 걸"
|
||||
enableInfiniteScroll: "알아서 더 보기"
|
||||
useCw: "내용 수ᇚ후기"
|
||||
description: "설멩"
|
||||
describeFile: "캡션 옇기"
|
||||
author: "맨던 사람"
|
||||
manage: "간리"
|
||||
emailServer: "전자우펜 서버"
|
||||
|
@ -600,6 +607,7 @@ renotesCount: "리노트한 수"
|
|||
renotedCount: "리노트덴 수"
|
||||
followingCount: "팔로우 수"
|
||||
followersCount: "팔로워 수"
|
||||
noteFavoritesCount: "질겨찾기한 노트 수"
|
||||
clips: "클립 맨걸기"
|
||||
clearCache: "캐시 비우기"
|
||||
unlikeConfirm: "좋네예럴 무룹니꺼?"
|
||||
|
@ -608,6 +616,7 @@ user: "사용자"
|
|||
administration: "간리"
|
||||
on: "킴"
|
||||
off: "껌"
|
||||
hide: "수ᇚ후기"
|
||||
clickToFinishEmailVerification: "[{ok}]럴 누질라서 전자우펜 정멩얼 껕내이소."
|
||||
searchByGoogle: "찾기"
|
||||
tenMinutes: "십 분"
|
||||
|
@ -626,9 +635,11 @@ role: "옉할"
|
|||
noRole: "옉할이 없십니다"
|
||||
thisPostMayBeAnnoyingCancel: "아이예"
|
||||
likeOnly: "좋네예마"
|
||||
myClips: "내 클립"
|
||||
icon: "아바타"
|
||||
replies: "답하기"
|
||||
renotes: "리노트"
|
||||
attach: "옇기"
|
||||
_initialAccountSetting:
|
||||
startTutorial: "길라잡이 하기"
|
||||
_initialTutorial:
|
||||
|
@ -641,9 +652,52 @@ _initialTutorial:
|
|||
title: "길라잡이가 껕낫십니다!🎉"
|
||||
_achievements:
|
||||
_types:
|
||||
_notes1:
|
||||
description: "첫 노트럴 섯어예"
|
||||
_notes10:
|
||||
description: "노트럴 10번 섰어예"
|
||||
_notes100:
|
||||
description: "노트럴 100번 섰어예"
|
||||
_notes500:
|
||||
description: "노트럴 500번 섰어예"
|
||||
_notes1000:
|
||||
description: "노트럴 1,000번 섰어예"
|
||||
_notes5000:
|
||||
description: "노트럴 5,000번 섰어예"
|
||||
_notes10000:
|
||||
description: "노트럴 10,000번 섰어예"
|
||||
_notes20000:
|
||||
description: "노트럴 20,000번 섰어예"
|
||||
_notes30000:
|
||||
description: "노트럴 30,000번 섰어예"
|
||||
_notes40000:
|
||||
description: "노트럴 40,000번 섰어예"
|
||||
_notes50000:
|
||||
description: "노트럴 50,000번 섰어예"
|
||||
_notes60000:
|
||||
description: "노트럴 60,000번 섰어예"
|
||||
_notes70000:
|
||||
description: "노트럴 70,000번 섰어예"
|
||||
_notes80000:
|
||||
description: "노트럴 80,000번 섰어예"
|
||||
_notes90000:
|
||||
description: "노트럴 90,000번 섰어예"
|
||||
_notes100000:
|
||||
description: "노트럴 100,000번 섰어예"
|
||||
_noteClipped1:
|
||||
description: "첫 노트럴 클립햇어예"
|
||||
_noteFavorited1:
|
||||
description: "첫 노트럴 질겨찾기에 담앗어예"
|
||||
_myNoteFavorited1:
|
||||
description: "다런 사람이 내 노트럴 질겨찾기에 담앗십니다"
|
||||
_iLoveMisskey:
|
||||
description: "“I ❤ #Misskey”럴 섰어예"
|
||||
_postedAt0min0sec:
|
||||
description: "0분 0초에 노트를 섰어예"
|
||||
_tutorialCompleted:
|
||||
description: "길라잡이럴 껕냇십니다"
|
||||
_gallery:
|
||||
my: "내 걸"
|
||||
liked: "좋네예한 걸"
|
||||
like: "좋네예!"
|
||||
unlike: "좋네예 무루기"
|
||||
|
@ -654,7 +708,12 @@ _serverDisconnectedBehavior:
|
|||
reload: "알아서 새로곤침"
|
||||
_channel:
|
||||
removeBanner: "배너 뭉캐기"
|
||||
usersCount: "{n}명 참여"
|
||||
notesCount: "노트 {n}개"
|
||||
_menuDisplay:
|
||||
hide: "수ᇚ후기"
|
||||
_theme:
|
||||
description: "설멩"
|
||||
keys:
|
||||
mention: "멘션"
|
||||
_sfx:
|
||||
|
@ -663,6 +722,9 @@ _sfx:
|
|||
_2fa:
|
||||
step3Title: "학인 기호럴 서기"
|
||||
renewTOTPCancel: "뎃어예"
|
||||
_permissions:
|
||||
"read:favorites": "질겨찾기 보기"
|
||||
"write:favorites": "질겨찾기 곤치기"
|
||||
_widgets:
|
||||
profile: "프로필"
|
||||
instanceInfo: "서버 정보"
|
||||
|
@ -674,7 +736,10 @@ _widgets:
|
|||
_userList:
|
||||
chooseList: "리스트 개리기"
|
||||
_cw:
|
||||
hide: "수ᇚ후기"
|
||||
show: "더 볼래예"
|
||||
chars: "걸자 {count}개"
|
||||
files: "파일 {count}개"
|
||||
_visibility:
|
||||
home: "덜머리"
|
||||
followers: "팔로워"
|
||||
|
@ -682,6 +747,7 @@ _profile:
|
|||
name: "이럼"
|
||||
username: "사용자 이럼"
|
||||
_exportOrImport:
|
||||
favoritedNotes: "질겨찾기한 노트"
|
||||
clips: "클립 맨걸기"
|
||||
followingList: "팔로잉"
|
||||
muteList: "수ᇚ후기"
|
||||
|
@ -692,16 +758,20 @@ _charts:
|
|||
_timelines:
|
||||
home: "덜머리"
|
||||
_play:
|
||||
my: "내 플레이"
|
||||
script: "스크립트"
|
||||
summary: "설멩"
|
||||
_pages:
|
||||
like: "좋네예"
|
||||
unlike: "좋네예 무루기"
|
||||
my: "내 페이지"
|
||||
blocks:
|
||||
image: "이미지"
|
||||
_note:
|
||||
id: "노트 아이디"
|
||||
_notification:
|
||||
youWereFollowed: "새 팔로워가 잇십니다"
|
||||
newNote: "새 걸"
|
||||
_types:
|
||||
follow: "팔로잉"
|
||||
mention: "멘션"
|
||||
|
|
|
@ -279,7 +279,7 @@ uploadFromUrl: "URL 업로드"
|
|||
uploadFromUrlDescription: "업로드하려는 파일의 URL"
|
||||
uploadFromUrlRequested: "업로드를 요청했습니다"
|
||||
uploadFromUrlMayTakeTime: "업로드가 완료될 때까지 시간이 소요될 수 있습니다."
|
||||
explore: "발견하기"
|
||||
explore: "둘러보기"
|
||||
messageRead: "읽음"
|
||||
noMoreHistory: "이것보다 과거의 기록이 없습니다"
|
||||
startMessaging: "대화 시작하기"
|
||||
|
@ -1022,7 +1022,7 @@ internalServerError: "내부 서버 오류"
|
|||
internalServerErrorDescription: "내부 서버에서 예기치 않은 오류가 발생했습니다."
|
||||
copyErrorInfo: "오류 정보 복사"
|
||||
joinThisServer: "이 서버에 가입"
|
||||
exploreOtherServers: "다른 서버 둘러보기"
|
||||
exploreOtherServers: "다른 서버 찾기"
|
||||
letsLookAtTimeline: "타임라인 구경하기"
|
||||
disableFederationConfirm: "정말로 연합을 끄시겠습니까?"
|
||||
disableFederationConfirmWarn: "연합을 끄더라도 게시물이 비공개로 전환되는 것은 아닙니다. 대부분의 경우 연합을 비활성화할 필요가 없습니다."
|
||||
|
@ -1797,7 +1797,7 @@ _instanceMute:
|
|||
title: "지정한 서버의 노트를 숨깁니다."
|
||||
heading: "뮤트할 서버"
|
||||
_theme:
|
||||
explore: "테마 찾아보기"
|
||||
explore: "테마 둘러보기"
|
||||
install: "테마 설치"
|
||||
manage: "테마 관리"
|
||||
code: "테마 코드"
|
||||
|
@ -2022,7 +2022,7 @@ _permissions:
|
|||
"write:report-abuse": "위반 내용 신고하기"
|
||||
_auth:
|
||||
shareAccessTitle: "어플리케이션의 접근 허가"
|
||||
shareAccess: "\"{name}\" 이 계정에 접근하는 것을 허용하시겠습니까?"
|
||||
shareAccess: "‘{name}’에서 계정에 접근하는 것을 허용하시겠습니까?"
|
||||
shareAccessAsk: "이 애플리케이션이 계정에 접근하는 것을 허용하시겠습니까?"
|
||||
permission: "{name}에서 다음 권한을 요청하였습니다"
|
||||
permissionAsk: "이 앱은 다음의 권한을 요청합니다"
|
||||
|
|
|
@ -40,6 +40,8 @@ export class EmailService {
|
|||
public async sendEmail(to: string, subject: string, html: string, text: string) {
|
||||
const meta = await this.metaService.fetch(true);
|
||||
|
||||
if (!meta.enableEmail) return;
|
||||
|
||||
const iconUrl = `${this.config.url}/static-assets/mi-white.png`;
|
||||
const emailSettingUrl = `${this.config.url}/settings/email`;
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*/
|
||||
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { IsNull } from 'typeorm';
|
||||
import { IsNull, Not } from 'typeorm';
|
||||
import type { MiLocalUser } from '@/models/User.js';
|
||||
import type { UsersRepository } from '@/models/_.js';
|
||||
import { MemorySingleCache } from '@/misc/cache.js';
|
||||
|
@ -27,6 +27,14 @@ export class InstanceActorService {
|
|||
this.cache = new MemorySingleCache<MiLocalUser>(Infinity);
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public async realLocalUsersPresent(): Promise<boolean> {
|
||||
return await this.usersRepository.existsBy({
|
||||
host: IsNull(),
|
||||
username: Not(ACTOR_USERNAME),
|
||||
});
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public async getInstanceActor(): Promise<MiLocalUser> {
|
||||
const cached = this.cache.get();
|
||||
|
|
|
@ -16,6 +16,7 @@ import { MiUserKeypair } from '@/models/UserKeypair.js';
|
|||
import { MiUsedUsername } from '@/models/UsedUsername.js';
|
||||
import generateUserToken from '@/misc/generate-native-user-token.js';
|
||||
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
||||
import { InstanceActorService } from '@/core/InstanceActorService.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import UsersChart from '@/core/chart/charts/users.js';
|
||||
import { UtilityService } from '@/core/UtilityService.js';
|
||||
|
@ -37,6 +38,7 @@ export class SignupService {
|
|||
private userEntityService: UserEntityService,
|
||||
private idService: IdService,
|
||||
private metaService: MetaService,
|
||||
private instanceActorService: InstanceActorService,
|
||||
private usersChart: UsersChart,
|
||||
) {
|
||||
}
|
||||
|
@ -81,7 +83,7 @@ export class SignupService {
|
|||
throw new Error('USED_USERNAME');
|
||||
}
|
||||
|
||||
const isTheFirstUser = (await this.usersRepository.countBy({ host: IsNull() })) === 0;
|
||||
const isTheFirstUser = !await this.instanceActorService.realLocalUsersPresent();
|
||||
|
||||
if (!opts.ignorePreservedUsernames && !isTheFirstUser) {
|
||||
const instance = await this.metaService.fetch(true);
|
||||
|
|
|
@ -232,20 +232,36 @@ export class ApPersonService implements OnModuleInit {
|
|||
return null;
|
||||
}
|
||||
|
||||
private async resolveAvatarAndBanner(user: MiRemoteUser, host: string | null, icon: any, image: any): Promise<Pick<MiRemoteUser, 'avatarId' | 'bannerId' | 'avatarUrl' | 'bannerUrl' | 'avatarBlurhash' | 'bannerBlurhash'>> {
|
||||
private async resolveAvatarAndBanner(user: MiRemoteUser, host: string | null, icon: any, image: any): Promise<Partial<Pick<MiRemoteUser, 'avatarId' | 'bannerId' | 'avatarUrl' | 'bannerUrl' | 'avatarBlurhash' | 'bannerBlurhash'>>> {
|
||||
if (user == null) throw new Error('failed to create user: user is null');
|
||||
|
||||
const [avatar, banner] = await Promise.all([icon, image].map(img => {
|
||||
if (img == null) return null;
|
||||
if (user == null) throw new Error('failed to create user: user is null');
|
||||
// if we have an explicitly missing image, return an
|
||||
// explicitly-null set of values
|
||||
if ((img == null) || (typeof img === 'object' && img.url == null)) {
|
||||
return { id: null, url: null, blurhash: null };
|
||||
}
|
||||
return this.apImageService.resolveImage(user, img).catch(() => null);
|
||||
}));
|
||||
|
||||
const returnData: any = {
|
||||
avatarId: avatar?.id ?? null,
|
||||
bannerId: banner?.id ?? null,
|
||||
avatarUrl: avatar ? this.driveFileEntityService.getPublicUrl(avatar, 'avatar') : null,
|
||||
bannerUrl: banner ? this.driveFileEntityService.getPublicUrl(banner) : null,
|
||||
avatarBlurhash: avatar?.blurhash ?? null,
|
||||
bannerBlurhash: banner?.blurhash ?? null,
|
||||
/*
|
||||
we don't want to return nulls on errors! if the database fields
|
||||
are already null, nothing changes; if the database has old
|
||||
values, we should keep those. The exception is if the remote has
|
||||
actually removed the images: in that case, the block above
|
||||
returns the special {id:null}&c value, and we return those
|
||||
*/
|
||||
return {
|
||||
...( avatar ? {
|
||||
avatarId: avatar.id,
|
||||
avatarUrl: avatar.url ? this.driveFileEntityService.getPublicUrl(avatar, 'avatar') : null,
|
||||
avatarBlurhash: avatar.blurhash,
|
||||
} : {}),
|
||||
...( banner ? {
|
||||
bannerId: banner.id,
|
||||
bannerUrl: banner.url ? this.driveFileEntityService.getPublicUrl(banner) : null,
|
||||
bannerBlurhash: banner.blurhash,
|
||||
} : {}),
|
||||
};
|
||||
|
||||
if (host) {
|
||||
|
|
|
@ -9,6 +9,7 @@ import { Endpoint } from '@/server/api/endpoint-base.js';
|
|||
import type { UsersRepository } from '@/models/_.js';
|
||||
import { SignupService } from '@/core/SignupService.js';
|
||||
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
||||
import { InstanceActorService } from '@/core/InstanceActorService.js';
|
||||
import { localUsernameSchema, passwordSchema } from '@/models/User.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import { Packed } from '@/misc/json-schema.js';
|
||||
|
@ -46,13 +47,12 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
|
||||
private userEntityService: UserEntityService,
|
||||
private signupService: SignupService,
|
||||
private instanceActorService: InstanceActorService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, _me, token) => {
|
||||
const me = _me ? await this.usersRepository.findOneByOrFail({ id: _me.id }) : null;
|
||||
const noUsers = (await this.usersRepository.countBy({
|
||||
host: IsNull(),
|
||||
})) === 0;
|
||||
if ((!noUsers && !me?.isRoot) || token !== null) throw new Error('access denied');
|
||||
const realUsers = await this.instanceActorService.realLocalUsersPresent();
|
||||
if ((realUsers && !me?.isRoot) || token !== null) throw new Error('access denied');
|
||||
|
||||
const { account, secret } = await this.signupService.signup({
|
||||
username: ps.username,
|
||||
|
|
|
@ -6,11 +6,12 @@
|
|||
import { IsNull, LessThanOrEqual, MoreThan, Brackets } from 'typeorm';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import JSON5 from 'json5';
|
||||
import type { AdsRepository, UsersRepository } from '@/models/_.js';
|
||||
import type { AdsRepository } from '@/models/_.js';
|
||||
import { MAX_NOTE_TEXT_LENGTH } from '@/const.js';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
||||
import { MetaService } from '@/core/MetaService.js';
|
||||
import { InstanceActorService } from '@/core/InstanceActorService.js';
|
||||
import type { Config } from '@/config.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import { DEFAULT_POLICIES } from '@/core/RoleService.js';
|
||||
|
@ -326,14 +327,12 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
@Inject(DI.config)
|
||||
private config: Config,
|
||||
|
||||
@Inject(DI.usersRepository)
|
||||
private usersRepository: UsersRepository,
|
||||
|
||||
@Inject(DI.adsRepository)
|
||||
private adsRepository: AdsRepository,
|
||||
|
||||
private userEntityService: UserEntityService,
|
||||
private metaService: MetaService,
|
||||
private instanceActorService: InstanceActorService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
const instance = await this.metaService.fetch(true);
|
||||
|
@ -412,9 +411,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
...(ps.detail ? {
|
||||
cacheRemoteFiles: instance.cacheRemoteFiles,
|
||||
cacheRemoteSensitiveFiles: instance.cacheRemoteSensitiveFiles,
|
||||
requireSetup: (await this.usersRepository.countBy({
|
||||
host: IsNull(),
|
||||
})) === 0,
|
||||
requireSetup: !await this.instanceActorService.realLocalUsersPresent(),
|
||||
} : {}),
|
||||
};
|
||||
|
||||
|
|
|
@ -214,6 +214,12 @@ const patronsWithIcon = [{
|
|||
}, {
|
||||
name: 'taichan',
|
||||
icon: 'https://assets.misskey-hub.net/patrons/f981ab0159fb4e2c998e05f7263e1cd9.png',
|
||||
}, {
|
||||
name: '猫吉よりお',
|
||||
icon: 'https://assets.misskey-hub.net/patrons/a11518b3b34b4536a4bdd7178ba76a7b.png',
|
||||
}, {
|
||||
name: '有栖かずみ',
|
||||
icon: 'https://assets.misskey-hub.net/patrons/9240e8e0ba294a8884143e99ac7ed6a0.png',
|
||||
}];
|
||||
|
||||
const patrons = [
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* version: 2024.2.0-beta.8
|
||||
* generatedAt: 2024-01-31T01:46:47.964Z
|
||||
* generatedAt: 2024-02-04T11:51:13.598Z
|
||||
*/
|
||||
|
||||
import type { SwitchCaseResponseType } from '../api.js';
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* version: 2024.2.0-beta.8
|
||||
* generatedAt: 2024-01-31T01:46:47.962Z
|
||||
* generatedAt: 2024-02-04T11:51:13.595Z
|
||||
*/
|
||||
|
||||
import type {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* version: 2024.2.0-beta.8
|
||||
* generatedAt: 2024-01-31T01:46:47.961Z
|
||||
* generatedAt: 2024-02-04T11:51:13.593Z
|
||||
*/
|
||||
|
||||
import { operations } from './types.js';
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* version: 2024.2.0-beta.8
|
||||
* generatedAt: 2024-01-31T01:46:47.959Z
|
||||
* generatedAt: 2024-02-04T11:51:13.592Z
|
||||
*/
|
||||
|
||||
import { components } from './types.js';
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
/*
|
||||
* version: 2024.2.0-beta.8
|
||||
* generatedAt: 2024-01-31T01:46:47.878Z
|
||||
* generatedAt: 2024-02-04T11:51:13.473Z
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue