Merge branch 'develop' into swn

This commit is contained in:
tamaina 2021-10-19 15:48:10 +09:00
commit 20649f5ae1
93 changed files with 1347 additions and 746 deletions

View file

@ -29,5 +29,5 @@ jobs:
with: with:
context: . context: .
push: true push: true
tags: develop tags: misskey/misskey:develop
labels: develop labels: develop

View file

@ -16,16 +16,16 @@ jobs:
services: services:
postgres: postgres:
image: postgres:10-alpine image: postgres:12.2-alpine
ports: ports:
- 5432:5432 - 54312:5432
env: env:
POSTGRES_DB: test-misskey POSTGRES_DB: test-misskey
POSTGRES_HOST_AUTH_METHOD: trust POSTGRES_HOST_AUTH_METHOD: trust
redis: redis:
image: redis:alpine image: redis:4.0-alpine
ports: ports:
- 6379:6379 - 56312:6379
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
@ -40,7 +40,7 @@ jobs:
- name: Check yarn.lock - name: Check yarn.lock
run: git diff --exit-code yarn.lock run: git diff --exit-code yarn.lock
- name: Copy Configure - name: Copy Configure
run: cp .circleci/misskey/*.yml .config run: cp test/test.yml .config
- name: Build - name: Build
run: yarn build run: yarn build
- name: Test - name: Test

View file

@ -12,6 +12,19 @@
## 12.x.x (unreleased) ## 12.x.x (unreleased)
### Improvements
- クライアント: 自分のリアクション一覧を見れるように
- 設定により、リアクション一覧を全員に公開することも可能
- クライアント: ユーザー検索の精度を強化
- クライアント: 新しいライトテーマを追加
- API: ユーザーのリアクション一覧を取得する users/reactions を追加
- API: users/search および users/search-by-username-and-host を強化
### Bugfixes
- クライアント: テーマの管理が行えない問題を修正
## 12.92.0 (2021/10/16)
### Improvements ### Improvements
- アカウント登録にメールアドレスの設定を必須にするオプション - アカウント登録にメールアドレスの設定を必須にするオプション
- クライアント: 全体的なUIのブラッシュアップ - クライアント: 全体的なUIのブラッシュアップ
@ -23,6 +36,7 @@
- クライアント: 新しいダークテーマを追加 - クライアント: 新しいダークテーマを追加
- クライアント: テーマコンパイラに hue と saturate 関数を追加 - クライアント: テーマコンパイラに hue と saturate 関数を追加
- ActivityPub: HTML -> MFMの変換を強化 - ActivityPub: HTML -> MFMの変換を強化
- API: グループから抜ける users/groups/leave エンドポイントを実装
- API: i/notifications に unreadOnly オプションを追加 - API: i/notifications に unreadOnly オプションを追加
- API: ap系のエンドポイントをログイン必須化+レートリミット追加 - API: ap系のエンドポイントをログイン必須化+レートリミット追加
- MFM: Add tag syntaxes of bold <b></b> and strikethrough <s></s> - MFM: Add tag syntaxes of bold <b></b> and strikethrough <s></s>

View file

@ -9,9 +9,9 @@ It will also allow the reader to use the translation tool of their preference if
## Issues ## Issues
Before creating an issue, please check the following: Before creating an issue, please check the following:
- To avoid duplication, please search for similar issues before creating a new issue. - To avoid duplication, please search for similar issues before creating a new issue.
- Do not use Issues as a question. - Do not use Issues to ask questions or troubleshooting.
- Issues should only be used to feature requests, suggestions, and report problems. - Issues should only be used to feature requests, suggestions, and bug tracking.
- Please ask questions in the [Misskey Forum](https://forum.misskey.io/) or [Discord](https://discord.gg/Wp8gVStHW3). - Please ask questions or troubleshooting in the [Misskey Forum](https://forum.misskey.io/) or [Discord](https://discord.gg/Wp8gVStHW3).
## Before implementation ## Before implementation
When you want to add a feature or fix a bug, **first have the design and policy reviewed in an Issue** (if it is not there, please make one). Without this step, there is a high possibility that the PR will not be merged even if it is implemented. When you want to add a feature or fix a bug, **first have the design and policy reviewed in an Issue** (if it is not there, please make one). Without this step, there is a high possibility that the PR will not be merged even if it is implemented.
@ -57,6 +57,17 @@ If your language is not listed in Crowdin, please open an issue.
- Test codes are located in [`/test`](/test). - Test codes are located in [`/test`](/test).
### Run test ### Run test
Create a config file.
```
cp test/test.yml .config/
```
Prepare DB/Redis for testing.
```
docker-compose -f test/docker-compose.yml up
```
Alternatively, prepare an empty (data can be erased) DB and edit `.config/test.yml`.
Run all test.
``` ```
npm run test npm run test
``` ```

View file

@ -6,6 +6,7 @@ search: "البحث"
notifications: "الإشعارات" notifications: "الإشعارات"
username: "اسم المستخدم" username: "اسم المستخدم"
password: "الكلمة السرية" password: "الكلمة السرية"
forgotPassword: "نسيتَ كلمة السر"
fetchingAsApObject: "جارٍ جلبه مِن الفديفرس…" fetchingAsApObject: "جارٍ جلبه مِن الفديفرس…"
ok: " حسناً" ok: " حسناً"
gotIt: "فهِمت" gotIt: "فهِمت"

View file

@ -81,6 +81,8 @@ somethingHappened: "Ein Fehler ist aufgetreten"
retry: "Wiederholen" retry: "Wiederholen"
pageLoadError: "Laden der Seite fehlgeschlagen." pageLoadError: "Laden der Seite fehlgeschlagen."
pageLoadErrorDescription: "Dieser Fehler wird meist durch Netzwerkfehler oder den Browser-Cache verursacht. Bitte leere den Cache oder versuche es nach einiger Zeit erneut." pageLoadErrorDescription: "Dieser Fehler wird meist durch Netzwerkfehler oder den Browser-Cache verursacht. Bitte leere den Cache oder versuche es nach einiger Zeit erneut."
serverIsDead: "Dieser Server antwortet nicht. Bitte warte einen Moment und versuche es dann erneut."
youShouldUpgradeClient: "Bitte aktualisiere diese Seite, um eine neuere Version deines Clients zu verwenden."
enterListName: "Name der Liste eingeben" enterListName: "Name der Liste eingeben"
privacy: "Privatsphäre" privacy: "Privatsphäre"
makeFollowManuallyApprove: "Follow-Anfragen benötigen Bestätigung" makeFollowManuallyApprove: "Follow-Anfragen benötigen Bestätigung"
@ -545,7 +547,7 @@ invisibleNote: "Private Notiz"
enableInfiniteScroll: "Automatisch mehr Notizen laden" enableInfiniteScroll: "Automatisch mehr Notizen laden"
visibility: "Sichtbarkeit" visibility: "Sichtbarkeit"
poll: "Umfrage" poll: "Umfrage"
useCw: "Inhalt verbergen" useCw: "Inhaltswarnung verwenden"
enablePlayer: "Video-Player öffnen" enablePlayer: "Video-Player öffnen"
disablePlayer: "Video-Player schließen" disablePlayer: "Video-Player schließen"
expandTweet: "Tweet ausklappen" expandTweet: "Tweet ausklappen"
@ -764,6 +766,7 @@ middle: "Mittel"
low: "Niedrig" low: "Niedrig"
emailNotConfiguredWarning: "Keine Email-Adresse hinterlegt" emailNotConfiguredWarning: "Keine Email-Adresse hinterlegt"
ratio: "Verhältnis" ratio: "Verhältnis"
previewNoteText: "Vorschau anzeigen"
customCss: "Benutzerdefiniertes CSS" customCss: "Benutzerdefiniertes CSS"
customCssWarn: "Verwende diese Einstellung nur, wenn du weißt, was sie tut. Ungültige Eingaben können dazu führen, dass der Client nicht mehr normal funktioniert." customCssWarn: "Verwende diese Einstellung nur, wenn du weißt, was sie tut. Ungültige Eingaben können dazu führen, dass der Client nicht mehr normal funktioniert."
global: "Global" global: "Global"
@ -782,11 +785,22 @@ translatedFrom: "Aus {x} übersetzt"
accountDeletionInProgress: "Löschung des Benutzerkontos momentan in Bearbeitung" accountDeletionInProgress: "Löschung des Benutzerkontos momentan in Bearbeitung"
usernameInfo: "Ein Name, durch den dein Benutzerkonto auf diesem Server identifiziert werden kann. Du kannst das Alphabet (a~z, A~Z), Ziffern (0~9) oder Unterstriche (_) verwenden. Benutzernamen können später nicht geändert werden." usernameInfo: "Ein Name, durch den dein Benutzerkonto auf diesem Server identifiziert werden kann. Du kannst das Alphabet (a~z, A~Z), Ziffern (0~9) oder Unterstriche (_) verwenden. Benutzernamen können später nicht geändert werden."
aiChanMode: "Ai Modus" aiChanMode: "Ai Modus"
keepCw: "Inhaltswarnung beibehalten" keepCw: "Inhaltswarnungen beibehalten"
pubSub: "Pub/Sub Benutzerkonten" pubSub: "Pub/Sub Benutzerkonten"
lastCommunication: "Letzte Kommunikation" lastCommunication: "Letzte Kommunikation"
resolved: "Gelöst" resolved: "Gelöst"
unresolved: "Ungelöst" unresolved: "Ungelöst"
itsOn: "Eingeschaltet"
itsOff: "Ausgeschaltet"
emailRequiredForSignup: "Angaben einer Email-Adresse als benötigt markieren"
unread: "Ungelesen"
filter: "Filter"
controllPanel: "Systemsteuerung"
manageAccounts: "Benutzerkonten verwalten"
_signup:
almostThere: "Fast geschafft"
emailAddressInfo: "Bitte gib deine Email-Adresse ein."
emailSent: "An deine Email-Adresse ({email}) wurde soeben eine Bestätigungsmail geschickt. Bitte klicke auf den enthaltenen Link, um die Erstellung deines Benutzerkontos abzuschließen."
_accountDelete: _accountDelete:
accountDelete: "Benutzerkonto löschen" accountDelete: "Benutzerkonto löschen"
mayTakeTime: "Da die Löschung eines Benutzerkontos ein aufwendiger Prozess ist, kann dessen Dauer davon abhängen, wie viel Inhalt in diesem erstellt wurde oder wie viele Dateien hochgeladen wurden." mayTakeTime: "Da die Löschung eines Benutzerkontos ein aufwendiger Prozess ist, kann dessen Dauer davon abhängen, wie viel Inhalt in diesem erstellt wurde oder wie viele Dateien hochgeladen wurden."
@ -901,6 +915,8 @@ _mfm:
fontDescription: "Setzt die Schriftart des Inhaltes fest." fontDescription: "Setzt die Schriftart des Inhaltes fest."
rainbow: "Regenbogen" rainbow: "Regenbogen"
rainbowDescription: "Lässt den Inhalt in Regenbogenfarben erscheinen." rainbowDescription: "Lässt den Inhalt in Regenbogenfarben erscheinen."
sparkle: "Glitzer"
sparkleDescription: "Verleiht Inhalt einen glitzernden Partikeleffekt."
_reversi: _reversi:
reversi: "Reversi" reversi: "Reversi"
gameSettings: "Spieleinstellungen" gameSettings: "Spieleinstellungen"
@ -1024,9 +1040,9 @@ _theme:
infoFg: "Text von Informationen" infoFg: "Text von Informationen"
infoWarnBg: "Hintergrund von Warnungen" infoWarnBg: "Hintergrund von Warnungen"
infoWarnFg: "Text von Warnungen" infoWarnFg: "Text von Warnungen"
cwBg: "Hintergrund von verborgenen Inhalten" cwBg: "Hintergrund des Inhaltswarnungsknopfs"
cwFg: "Text von verborgenen Inhalten" cwFg: "Text des Inhaltswarnungsknopfs"
cwHoverBg: "Hintergrund von verborgenen Inhalten (Mouseover)" cwHoverBg: "Hintergrund des Inhaltswarnungsknopfs (Mouseover)"
toastBg: "Hintergrund von Benachrichtigungen" toastBg: "Hintergrund von Benachrichtigungen"
toastFg: "Text von Benachrichtigungen" toastFg: "Text von Benachrichtigungen"
buttonBg: "Hintergrund von Schaltflächen" buttonBg: "Hintergrund von Schaltflächen"
@ -1173,7 +1189,7 @@ _widgets:
aiscript: "AiScript-Konsole" aiscript: "AiScript-Konsole"
aichan: "Ai" aichan: "Ai"
_cw: _cw:
hide: "Verbergen" hide: "Inhalt verbergen"
show: "Inhalt anzeigen" show: "Inhalt anzeigen"
chars: "{count} Zeichen" chars: "{count} Zeichen"
files: "{count} Datei(en)" files: "{count} Datei(en)"

View file

@ -1,7 +1,7 @@
--- ---
_lang_: "English" _lang_: "English"
headlineMisskey: "A network connected by notes" headlineMisskey: "A network connected by notes"
introMisskey: "Welcome! Misskey is an open source, decentralized microblogging service.\nCreate \"notes\" to share what your thoughts with everyone around you. 📡\nWith \"reactions\", you can also quickly express your feelings about everyone's notes. 👍\nLet's explore a new world! 🚀" introMisskey: "Welcome! Misskey is an open source, decentralized microblogging service.\nCreate \"notes\" to share your thoughts with everyone around you. 📡\nWith \"reactions\", you can also quickly express your feelings about everyone's notes. 👍\nLet's explore a new world! 🚀"
monthAndDay: "{month}/{day}" monthAndDay: "{month}/{day}"
search: "Search" search: "Search"
notifications: "Notifications" notifications: "Notifications"
@ -81,6 +81,8 @@ somethingHappened: "An error occurred"
retry: "Retry" retry: "Retry"
pageLoadError: "Failed to load page." pageLoadError: "Failed to load page."
pageLoadErrorDescription: "This is normally caused by network errors or the browser's cache. Try clearing the cache and then try again after waiting a little while." pageLoadErrorDescription: "This is normally caused by network errors or the browser's cache. Try clearing the cache and then try again after waiting a little while."
serverIsDead: "This server is not responding. Please wait for a while and try again."
youShouldUpgradeClient: "To view this page, please refresh to update your client."
enterListName: "Enter a list name" enterListName: "Enter a list name"
privacy: "Privacy" privacy: "Privacy"
makeFollowManuallyApprove: "Follow requests require approval" makeFollowManuallyApprove: "Follow requests require approval"
@ -764,6 +766,7 @@ middle: "Medium"
low: "Low" low: "Low"
emailNotConfiguredWarning: "Email address not set." emailNotConfiguredWarning: "Email address not set."
ratio: "Ratio" ratio: "Ratio"
previewNoteText: "Show preview"
customCss: "Custom CSS" customCss: "Custom CSS"
customCssWarn: "This setting should only be used if you know what it does. Entering improper values may cause the client to stop functioning normally." customCssWarn: "This setting should only be used if you know what it does. Entering improper values may cause the client to stop functioning normally."
global: "Global" global: "Global"
@ -782,11 +785,22 @@ translatedFrom: "Translated from {x}"
accountDeletionInProgress: "Account deletion is currently in progress" accountDeletionInProgress: "Account deletion is currently in progress"
usernameInfo: "A name that identifies your account from others on this server. You can use the alphabet (a~z, A~Z), digits (0~9) or underscores (_). Usernames cannot be changed later." usernameInfo: "A name that identifies your account from others on this server. You can use the alphabet (a~z, A~Z), digits (0~9) or underscores (_). Usernames cannot be changed later."
aiChanMode: "Ai Mode" aiChanMode: "Ai Mode"
keepCw: "Keep Content Warning" keepCw: "Keep Content Warnings"
pubSub: "Pub/Sub Accounts" pubSub: "Pub/Sub Accounts"
lastCommunication: "Last communication" lastCommunication: "Last communication"
resolved: "Resolved" resolved: "Resolved"
unresolved: "Unresolved" unresolved: "Unresolved"
itsOn: "Enabled"
itsOff: "Disabled"
emailRequiredForSignup: "Require email address for sign-up"
unread: "Unread"
filter: "Filter"
controllPanel: "Control Panel"
manageAccounts: "Manage Accounts"
_signup:
almostThere: "Almost there"
emailAddressInfo: "Please enter your email address."
emailSent: "A confirmation email has been sent to your email address ({email}). Please click the included link to complete account creation."
_accountDelete: _accountDelete:
accountDelete: "Delete Account" accountDelete: "Delete Account"
mayTakeTime: "As account deletion is a resource-heavy process, it may take some time to complete depending on how much content you have created and how many files you have uploaded." mayTakeTime: "As account deletion is a resource-heavy process, it may take some time to complete depending on how much content you have created and how many files you have uploaded."

View file

@ -1,8 +1,8 @@
--- ---
_lang_: "Esperanto" _lang_: "Esperanto"
headlineMisskey: "Jen la reto konektita de notoj" headlineMisskey: "Jen la reto konektata de notoj"
introMisskey: "Bonvenon! Misskey estas malfermitkoda malcentraliza mikrobloga servo.\nKreu \"noto\"n por diskonigu tion kio nun okazas, aŭ por parolu pri vi. 📡\nUzu la funkcion \"reago\" por esprimu rapide vian senton pri ies noto. 👍\nBonvole esploru novan mondon. 🚀" introMisskey: "Bonvenon! Misskey estas malfermitkoda malcentraliza etbloga servo.\nKreu \"noto\"n por paroli vian penson al iuj ĉirkaŭ vi. 📡\nLa funkcion \"reago\" ebligas esprimi rapide vian senton pri ies noto en Fediverso. 👍\nBonvole esploru novan mondon. 🚀"
monthAndDay: "{day}a/{month}" monthAndDay: "La {day}-a de la {month}-a monato"
search: "Serĉi" search: "Serĉi"
notifications: "Sciigoj" notifications: "Sciigoj"
username: "Uzantnomo" username: "Uzantnomo"
@ -33,18 +33,18 @@ save: "Konservi"
users: "Uzantoj" users: "Uzantoj"
addUser: "Aldoni uzanton" addUser: "Aldoni uzanton"
favorite: "Preferi" favorite: "Preferi"
favorites: "Preferataĵoj" favorites: "Preferaĵoj"
unfavorite: "Malpreferi" unfavorite: "Malpreferi"
favorited: "Aldonita al preferataĵoj" favorited: "Aldonita al via listo de preferaĵoj."
alreadyFavorited: "Ankoraŭ aldonita al via listo de preferaĵoj." alreadyFavorited: "Ĝi jam estis aldonita al via listo de preferaĵoj."
cantFavorite: "Ne aldonita al preferataĵoj" cantFavorite: "Ne aldonita al via listo de preferaĵoj."
pin: "Alpingli al la profilo" pin: "Alpingli"
unpin: "Depingli" unpin: "Depingli"
copyContent: "Kopii enhavon" copyContent: "Kopii enhavon"
copyLink: "Kopii ligilon" copyLink: "Kopii ligilon"
delete: "Forviŝi" delete: "Forviŝi"
deleteAndEdit: "Forviŝi kaj redakti" deleteAndEdit: "Redakti foriginte"
deleteAndEditConfirm: "Ĉu vi certas, ke vi volas forigi kaj redakti la noton? Kun tio foriĝos reagoj, plusendaĵoj, kaj respondoj ĉiuj de ĝi." deleteAndEditConfirm: "Ĉu vi certas, ke vi volas forigi kaj redakti la noton? Tio forviŝos reagojn, notojn plusendintajn, kaj respondojn ĉiujn de ĝi."
addToList: "Aldoni al listo" addToList: "Aldoni al listo"
sendMessage: "Sendi mesaĝon" sendMessage: "Sendi mesaĝon"
copyUsername: "Kopii uzantnomon" copyUsername: "Kopii uzantnomon"
@ -57,17 +57,17 @@ receiveFollowRequest: "Peto de sekvado estas ricevita"
followRequestAccepted: "La peto de sekvado akceptita" followRequestAccepted: "La peto de sekvado akceptita"
mention: "Mencioj" mention: "Mencioj"
mentions: "Al vi" mentions: "Al vi"
directNotes: "Notoj rektaj" directNotes: "Rekte senditaj"
importAndExport: "Importi/eksporti" importAndExport: "Importi/eksporti"
import: "Importi" import: "Importi"
export: "Eksporti" export: "Eksporti"
files: "Dosieroj" files: "Dosieroj"
download: "Elŝuti" download: "Elŝuti"
driveFileDeleteConfirm: "Ĉu vi certas, ke vi volas forviŝi la dosieron \"{name}\"? Pro tio forviŝiĝos ankaŭ la notoj kiuj enhavas ĝin." driveFileDeleteConfirm: "Ĉu vi certas, ke vi volas forviŝi la dosieron \"{name}\"? Pro tio forviŝiĝos ankaŭ la notoj kiuj enhavas ĝin."
unfollowConfirm: "Ĉu vi certas, ke vi volas ne plu sekvi {name}'(o)n?" unfollowConfirm: "Ĉu vi certas, ke vi volas ĉesi sekvi {name}'(o)n?"
lists: "Listoj" lists: "Listoj"
noLists: "Neniu listo" noLists: "Neniu listo"
note: "Notoj" note: "Sendi"
notes: "Notoj" notes: "Notoj"
following: "Sekvatoj" following: "Sekvatoj"
followers: "Sekvantoj" followers: "Sekvantoj"
@ -92,13 +92,13 @@ cantRenote: "Oni ne povas plusendi la noton."
cantReRenote: "Plusendado ne estas plusendebla." cantReRenote: "Plusendado ne estas plusendebla."
quote: "Citi" quote: "Citi"
pinnedNote: "Alpinglita noto" pinnedNote: "Alpinglita noto"
pinned: "Alpingli al la profilo" pinned: "Alpingli"
you: "Vi" you: "Vi"
clickToShow: "Klaku por malkaŝu" clickToShow: "Klaku por malkaŝu"
sensitive: "Enhavo ne estas deca por laborejo (NSFW)" sensitive: "Enhavo ne estas deca por laborejo (NSFW)"
add: "Aldoni" add: "Aldoni"
reaction: "Reagoj" reaction: "Reagoj"
rememberNoteVisibility: "Rememoru la videblecon de la noto laste sendita" rememberNoteVisibility: "Rememoru videblecon de la noto laste sendita "
attachCancel: "Deigi aldonaĵon" attachCancel: "Deigi aldonaĵon"
markAsSensitive: "Troviĝi NSFW" markAsSensitive: "Troviĝi NSFW"
unmarkAsSensitive: "Ne troviĝi NSFW" unmarkAsSensitive: "Ne troviĝi NSFW"
@ -137,7 +137,7 @@ removeWallpaper: "Forviŝi ekranfonon. "
searchWith: "Serĉi: {q}" searchWith: "Serĉi: {q}"
youHaveNoLists: "Vi ne havas listojn." youHaveNoLists: "Vi ne havas listojn."
followConfirm: "Ĉu vi certas ke vi volas sekvi {name}'(o)n?" followConfirm: "Ĉu vi certas ke vi volas sekvi {name}'(o)n?"
host: "Gastiganto" host: "Gastigo"
selectUser: "Elekti uzanton" selectUser: "Elekti uzanton"
recipient: "Ricevonto" recipient: "Ricevonto"
annotation: "Komentarioj" annotation: "Komentarioj"
@ -254,7 +254,7 @@ unwatch: "Malobservi"
accept: "Permesi" accept: "Permesi"
normal: "Normala" normal: "Normala"
instanceName: "Nomo de la nodo" instanceName: "Nomo de la nodo"
instanceDescription: "Mempriskribo de la nodo " instanceDescription: "Priskribo de la nodo "
maintainerName: "Nomo de la administranto" maintainerName: "Nomo de la administranto"
maintainerEmail: "Retpoŝto de la administranto" maintainerEmail: "Retpoŝto de la administranto"
tosUrl: "URL de kondiĉoj de uzado" tosUrl: "URL de kondiĉoj de uzado"
@ -323,6 +323,7 @@ newPasswordIs: "La nova pasvorto estas {password}."
share: "Diskonigi" share: "Diskonigi"
notFound: "Ne trovita" notFound: "Ne trovita"
cacheClear: "Malplenigi staplon" cacheClear: "Malplenigi staplon"
markAsReadAllNotifications: "Marki ĉiujn sciigojn kiel legito"
help: "Manlibro de uzado" help: "Manlibro de uzado"
inputMessageHere: "Entajpu masaĝo tie ĉi" inputMessageHere: "Entajpu masaĝo tie ĉi"
close: "Fermi" close: "Fermi"
@ -344,10 +345,10 @@ quoteAttached: "Kun citaĵo"
quoteQuestion: "Ĉu vi aldonas citaĵon?" quoteQuestion: "Ĉu vi aldonas citaĵon?"
noMessagesYet: "Ankoraŭ neniu mesaĝo" noMessagesYet: "Ankoraŭ neniu mesaĝo"
newMessageExists: "Vi ricevis novan mesaĝon." newMessageExists: "Vi ricevis novan mesaĝon."
onlyOneFileCanBeAttached: "Vi povas aldoni nur unu dosieron po unu mesaĝo." onlyOneFileCanBeAttached: "Oni povas aldoni nur unu dosieron po mesaĝo."
signinRequired: "Bonvolu ensaluti" signinRequired: "Bonvolu ensaluti"
invitations: "Inviti" invitations: "Inviti"
invitationCode: "Kodo de invito" invitationCode: "Invita kodo"
unavailable: "Ne disponebla" unavailable: "Ne disponebla"
passwordMatched: "Konforma" passwordMatched: "Konforma"
passwordNotMatched: "Nekonforma" passwordNotMatched: "Nekonforma"
@ -417,7 +418,7 @@ enablePlayer: "Vidi videon"
disablePlayer: "Fermi videon" disablePlayer: "Fermi videon"
expandTweet: "Disvolvi pepon" expandTweet: "Disvolvi pepon"
themeEditor: "Redaktilo de koloraroj" themeEditor: "Redaktilo de koloraroj"
description: "Priskribe" description: "Priskribo"
describeFile: "Priskribi la bildon" describeFile: "Priskribi la bildon"
enterFileDescription: "Priskribu" enterFileDescription: "Priskribu"
author: "Aŭtoro" author: "Aŭtoro"
@ -433,7 +434,7 @@ emailServer: "Retpoŝta servilo"
email: "Retpoŝto" email: "Retpoŝto"
emailAddress: "Retpoŝta adreso" emailAddress: "Retpoŝta adreso"
smtpConfig: "Agordoj de SMTP servilo" smtpConfig: "Agordoj de SMTP servilo"
smtpHost: "Gastiganto" smtpHost: "Gastigo"
smtpPort: "Pordo" smtpPort: "Pordo"
smtpUser: "Uzantnomo" smtpUser: "Uzantnomo"
smtpPass: "Pasvorto" smtpPass: "Pasvorto"
@ -481,7 +482,7 @@ notSet: "Ne elektita"
emailVerified: "Via retpoŝto estis kontrolita." emailVerified: "Via retpoŝto estis kontrolita."
noteFavoritesCount: "La nombro de notoj preferataj" noteFavoritesCount: "La nombro de notoj preferataj"
pageLikesCount: "La nombro de paĝoj kiun la uzanto preferas" pageLikesCount: "La nombro de paĝoj kiun la uzanto preferas"
pageLikedCount: "La nombro de uzantoj kiuj preferas la paĝon" pageLikedCount: "La nombro de uzantoj, kiuj preferas paĝon de ĉi tiu uzanto"
contact: "Kontakto" contact: "Kontakto"
makeExplorable: "Videbligi konton sur la paĝo \"Esplori\"" makeExplorable: "Videbligi konton sur la paĝo \"Esplori\""
duplicate: "Duobligi" duplicate: "Duobligi"
@ -509,7 +510,7 @@ inUse: "Uzata"
editCode: "Redakti kodon" editCode: "Redakti kodon"
emailNotification: "Sciigoj per retpoŝto" emailNotification: "Sciigoj per retpoŝto"
inChannelSearch: "Serĉi en kanalo" inChannelSearch: "Serĉi en kanalo"
useReactionPickerForContextMenu: "Oni malfermas reago-elektilon per dekstro-kliki" useReactionPickerForContextMenu: "Malfermi reago-elektilon per dekstro-klaki"
typingUsers: "{users} nun entajpas…" typingUsers: "{users} nun entajpas…"
clear: "Vakigi" clear: "Vakigi"
goBack: "Reiri antaŭ" goBack: "Reiri antaŭ"
@ -540,6 +541,7 @@ troubleshooting: "Problemsolvi"
learnMore: "Lernu pli" learnMore: "Lernu pli"
translate: "Traduki" translate: "Traduki"
translatedFrom: "Tradukita el {x}" translatedFrom: "Tradukita el {x}"
controllPanel: "Ŝaltpodio"
_docs: _docs:
continueReading: "Legi plu" continueReading: "Legi plu"
features: "Funkcioj" features: "Funkcioj"
@ -614,8 +616,8 @@ _wordMute:
mutedNotes: "Silentigitaj notoj" mutedNotes: "Silentigitaj notoj"
_theme: _theme:
manage: "Administri kolorarojn" manage: "Administri kolorarojn"
code: "Kodo de koloraro" code: "Kolorara kodo"
description: "Priskribe" description: "Priskribo"
color: "Koloro" color: "Koloro"
darken: "Malbrileco" darken: "Malbrileco"
lighten: "Brileco" lighten: "Brileco"
@ -667,8 +669,8 @@ _permissions:
"write:blocks": "Redakti vian liston de blokitoj" "write:blocks": "Redakti vian liston de blokitoj"
"read:drive": "Legi vian diskon" "read:drive": "Legi vian diskon"
"write:drive": "Ĉia operacio por skribi, forviŝi, aŭ alimaniere ŝanĝi la informon de dosiero en via disko de Misskey" "write:drive": "Ĉia operacio por skribi, forviŝi, aŭ alimaniere ŝanĝi la informon de dosiero en via disko de Misskey"
"read:favorites": "Vidi vian liston de preferataĵoj" "read:favorites": "Vidi vian liston de preferaĵoj"
"write:favorites": "Redakti vian liston de preferataĵoj." "write:favorites": "Redakti vian liston de preferaĵoj"
"read:following": "Vidi la infomaciojn pri tio, kion vi sekvas" "read:following": "Vidi la infomaciojn pri tio, kion vi sekvas"
"write:following": "Sekvi aŭ malsekvi alian uzanton" "write:following": "Sekvi aŭ malsekvi alian uzanton"
"read:messaging": "Vidi vian retbabiladon" "read:messaging": "Vidi vian retbabiladon"
@ -715,23 +717,24 @@ _poll:
vote: "Baloti" vote: "Baloti"
closed: "Oni jam balotis ĝin" closed: "Oni jam balotis ĝin"
_visibility: _visibility:
public: "Publika"
publicDescription: "Via noto estos videbla de ĉiuj uzantoj" publicDescription: "Via noto estos videbla de ĉiuj uzantoj"
home: "Hejma" home: "Hejma"
homeDescription: "Dissendi nur sur hejma templinio" homeDescription: "Dissendi nur sur hejma templinio"
followers: "Sekvantoj" followers: "Nur al sekvantoj"
followersDescription: "Nur al sekvantoj al mi" followersDescription: "Publiki nur al viaj sekvantoj"
specified: "Rekta" specified: "Rekte"
specifiedDescription: "Publikigi nur al specifaj uzantoj" specifiedDescription: "Montri nur al specifaj uzantoj"
localOnly: "Nur loka" localOnly: "Nur loka"
localOnlyDescription: "Ne montri al transaj uzantoj" localOnlyDescription: "Ne montri al transaj uzantoj"
_postForm: _postForm:
replyPlaceholder: "Respondi tiun noton…" replyPlaceholder: "Respondi la noton…"
quotePlaceholder: "Citi tiun noton…" quotePlaceholder: "Citi la noton…"
channelPlaceholder: "Mencii en kanalo…" channelPlaceholder: "Mencii en kanalo…"
_profile: _profile:
name: "Nomo" name: "Nomo"
username: "Uzantnomo" username: "Uzantnomo"
description: "Pri mi" description: "Sinprezento"
metadata: "Kromaj informoj" metadata: "Kromaj informoj"
metadataEdit: "Redakti kromaj informoj" metadataEdit: "Redakti kromaj informoj"
changeAvatar: "Ŝanĝi profilbildon" changeAvatar: "Ŝanĝi profilbildon"
@ -746,7 +749,7 @@ _charts:
federationInstancesTotal: "La totala nombro de nodoj kunfederantaj" federationInstancesTotal: "La totala nombro de nodoj kunfederantaj"
usersTotal: "La totala nombro de la uzantoj" usersTotal: "La totala nombro de la uzantoj"
activeUsers: "La nombro de la uzantoj aktivaj" activeUsers: "La nombro de la uzantoj aktivaj"
notesTotal: "La totala nombro de la notoj" notesTotal: "La totala nombro de notoj"
filesTotal: "La totala nombro de la dosieroj" filesTotal: "La totala nombro de la dosieroj"
_timelines: _timelines:
home: "Hejma" home: "Hejma"
@ -859,16 +862,21 @@ _pages:
argVariables: "Eniga junto" argVariables: "Eniga junto"
_notification: _notification:
fileUploaded: "La dosiero sukcese alŝutiĝis." fileUploaded: "La dosiero sukcese alŝutiĝis."
youGotMention: "{name} mencis"
youGotReply: "{name} respondis"
youGotQuote: "{name} citis"
youRenoted: "{name} plusendis" youRenoted: "{name} plusendis"
youGotPoll: "{name} balotis" youGotPoll: "{name} balotis"
youGotMessagingMessageFromUser: "{name} sentis mesaĝon al vi." youGotMessagingMessageFromUser: "{name} sentis mesaĝon al vi."
youGotMessagingMessageFromGroup: "Retbabilan mesaĝon oni sendis al la grupo {name}" youGotMessagingMessageFromGroup: "Retbabilan mesaĝon oni sendis al la grupo {name}"
youWereFollowed: "eksekvis vin" youWereFollowed: "eksekvis vin"
youReceivedFollowRequest: "Vi ricevis peton de sekvado" youReceivedFollowRequest: "Vi ricevis peton de sekvado"
yourFollowRequestAccepted: "Via peto por sekvado estis akceptita." yourFollowRequestAccepted: "Via peto de sekvado estis akceptita."
_types: _types:
follow: "Sekvatoj" all: "Ĉio"
follow: "Nova sekvatoj"
mention: "Mencioj" mention: "Mencioj"
reply: "Respondoj"
renote: "Notoj plusenditaj" renote: "Notoj plusenditaj"
quote: "Citi" quote: "Citi"
reaction: "Reagoj" reaction: "Reagoj"
@ -882,4 +890,4 @@ _deck:
antenna: "Antenoj" antenna: "Antenoj"
list: "Listoj" list: "Listoj"
mentions: "Al vi" mentions: "Al vi"
direct: "Notoj rektaj" direct: "Rekte"

View file

@ -7,6 +7,7 @@ search: "Buscar"
notifications: "Notificaciones" notifications: "Notificaciones"
username: "Nombre de usuario" username: "Nombre de usuario"
password: "Contraseña" password: "Contraseña"
forgotPassword: "Olvidé mi Contraseña"
fetchingAsApObject: "Buscando en el fediverso" fetchingAsApObject: "Buscando en el fediverso"
ok: "OK" ok: "OK"
gotIt: "Entendido" gotIt: "Entendido"
@ -279,6 +280,7 @@ emptyDrive: "El drive está vacío"
emptyFolder: "La carpeta está vacía" emptyFolder: "La carpeta está vacía"
unableToDelete: "No se puede borrar" unableToDelete: "No se puede borrar"
inputNewFileName: "Ingrese un nuevo nombre de archivo" inputNewFileName: "Ingrese un nuevo nombre de archivo"
inputNewDescription: "Ingrese nueva descripción"
inputNewFolderName: "Ingrese un nuevo nombre de la carpeta" inputNewFolderName: "Ingrese un nuevo nombre de la carpeta"
circularReferenceFolder: "La carpeta de destino es una sub-carpeta de la carpeta que quieres mover." circularReferenceFolder: "La carpeta de destino es una sub-carpeta de la carpeta que quieres mover."
hasChildFilesOrFolders: "No se puede borrar esta carpeta. No está vacía." hasChildFilesOrFolders: "No se puede borrar esta carpeta. No está vacía."
@ -310,6 +312,8 @@ monthX: "Mes {month}"
yearX: "Año {year}" yearX: "Año {year}"
pages: "Páginas" pages: "Páginas"
integration: "Integración" integration: "Integración"
connectService: "Conectar"
disconnectService: "Desconectar"
enableLocalTimeline: "Habilitar linea de tiempo local" enableLocalTimeline: "Habilitar linea de tiempo local"
enableGlobalTimeline: "Habilitar linea de tiempo global" enableGlobalTimeline: "Habilitar linea de tiempo global"
disablingTimelinesInfo: "Aunque se desactiven estas lineas de tiempo, por conveniencia el administrador y los moderadores pueden seguir usándolos" disablingTimelinesInfo: "Aunque se desactiven estas lineas de tiempo, por conveniencia el administrador y los moderadores pueden seguir usándolos"
@ -323,6 +327,7 @@ driveCapacityPerRemoteAccount: "Capacidad del drive por usuario remoto"
inMb: "En megabytes" inMb: "En megabytes"
iconUrl: "URL de la imagen del avatar" iconUrl: "URL de la imagen del avatar"
bannerUrl: "URL de la imagen del banner" bannerUrl: "URL de la imagen del banner"
backgroundImageUrl: "URL de la imagen de fondo"
basicInfo: "Información básica" basicInfo: "Información básica"
pinnedUsers: "Usuarios fijados" pinnedUsers: "Usuarios fijados"
pinnedUsersDescription: "Describir los usuarios que quiere fijar en la página \"Descubrir\" separados por una linea nueva" pinnedUsersDescription: "Describir los usuarios que quiere fijar en la página \"Descubrir\" separados por una linea nueva"
@ -524,6 +529,9 @@ removeAllFollowing: "Retener todos los siguientes"
removeAllFollowingDescription: "Cancelar todos los siguientes del servidor {host}. Ejecutar en caso de que esta instancia haya dejado de existir" removeAllFollowingDescription: "Cancelar todos los siguientes del servidor {host}. Ejecutar en caso de que esta instancia haya dejado de existir"
userSuspended: "Este usuario ha sido suspendido." userSuspended: "Este usuario ha sido suspendido."
userSilenced: "Este usuario ha sido silenciado." userSilenced: "Este usuario ha sido silenciado."
yourAccountSuspendedTitle: "Esta cuenta ha sido suspendida"
yourAccountSuspendedDescription: "Esta cuenta ha sido suspendida debido a violaciones de los términos de servicio del servidor y otras razones. Para más información, póngase en contacto con el administrador. Por favor, no cree una nueva cuenta."
menu: "Menú"
divider: "Divisor" divider: "Divisor"
addItem: "Agregar elemento" addItem: "Agregar elemento"
rooms: "Cuartos" rooms: "Cuartos"
@ -543,6 +551,8 @@ disablePlayer: "Cerrar reproductor"
expandTweet: "Expandir tweet" expandTweet: "Expandir tweet"
themeEditor: "Editor de temas" themeEditor: "Editor de temas"
description: "Descripción" description: "Descripción"
describeFile: "Añade una descripción"
enterFileDescription: "Introducir un título"
author: "Autor" author: "Autor"
leaveConfirm: "Hay modificaciones sin guardar. ¿Desea descartarlas?" leaveConfirm: "Hay modificaciones sin guardar. ¿Desea descartarlas?"
manage: "Administrar" manage: "Administrar"
@ -645,29 +655,90 @@ driveFilesCount: "Cantidad de archivos en el drive"
driveUsage: "Uso del drive" driveUsage: "Uso del drive"
noCrawle: "Rechazar indexación del crawler" noCrawle: "Rechazar indexación del crawler"
noCrawleDescription: "Pedir a los motores de búsqueda que no indexen tu perfil, notas, páginas, etc." noCrawleDescription: "Pedir a los motores de búsqueda que no indexen tu perfil, notas, páginas, etc."
lockedAccountInfo: "A menos que configures la visibilidad de tus notas como \"Sólo seguidores\", tus notas serán visibles para cualquiera, incluso si requieres que los seguidores sean aprobados manualmente."
alwaysMarkSensitive: "Marcar los medios de comunicación como contenido sensible por defecto" alwaysMarkSensitive: "Marcar los medios de comunicación como contenido sensible por defecto"
loadRawImages: "Cargar las imágenes originales en lugar de mostrar las miniaturas"
disableShowingAnimatedImages: "No reproducir imágenes animadas"
verificationEmailSent: "Se le ha enviado un correo electrónico de confirmación. Por favor, acceda al enlace proporcionado en el correo electrónico para completar la configuración." verificationEmailSent: "Se le ha enviado un correo electrónico de confirmación. Por favor, acceda al enlace proporcionado en el correo electrónico para completar la configuración."
notSet: "Sin especificar" notSet: "Sin especificar"
emailVerified: "Su dirección de correo electrónico ha sido verificada." emailVerified: "Su dirección de correo electrónico ha sido verificada."
noteFavoritesCount: "Número de notas favoritas" noteFavoritesCount: "Número de notas favoritas"
pageLikesCount: "Número de favoritos en la página" pageLikesCount: "Número de favoritos en la página"
pageLikedCount: "Número de favoritos de su página" pageLikedCount: "Número de favoritos de su página"
reversiCount: "Numero de partidas Reversi"
contact: "Contacto" contact: "Contacto"
useSystemFont: "Utilizar la tipografía por defecto del sistema"
clips: "Clip" clips: "Clip"
experimentalFeatures: "Características experimentales"
developer: "Desarrolladores"
makeExplorable: "Hacer visible la cuenta en \"Explorar\""
makeExplorableDescription: "Si desactiva esta opción, su cuenta no aparecerá en la sección \"Explorar\"."
showGapBetweenNotesInTimeline: "Mostrar un intervalo entre notas en la línea de tiempo"
duplicate: "Duplicar"
left: "Izquierda"
center: "Centrar"
wide: "Ancho"
narrow: "Estrecho"
reloadToApplySetting: "Esta configuración sólo se aplicará después de recargar la página. ¿Recargar ahora?"
showTitlebar: "Mostrar la barra de título"
clearCache: "Limpiar caché" clearCache: "Limpiar caché"
onlineUsersCount: "{n} usuarios en línea"
nUsers: "{n} Usuarios"
nNotes: "{n} Notas"
sendErrorReports: "Envíar informe de errores"
sendErrorReportsDescription: "Si habilita esta opción, ayudará a mejorar la calidad de Misskey compartiendo información detallada sobre los errores cuando se produzca un problema.\nEsto incluye información como la versión de su sistema operativo, el tipo de navegador que utiliza, su historial de actividad, etc."
myTheme: "Mi Tema"
backgroundColor: "Fondo" backgroundColor: "Fondo"
accentColor: "Acento" accentColor: "Acento"
textColor: "Texto" textColor: "Texto"
saveAs: "Guardar como…"
advanced: "Avanzado"
value: "Valores" value: "Valores"
createdAt: "Fecha de creación"
updatedAt: "Actualizado"
saveConfirm: "¿Guardar cambios?"
deleteConfirm: "¿Desea eliminarlo?"
invalidValue: "Este no es un valor válido."
registry: "Registro"
closeAccount: "Cerrar cuenta"
currentVersion: "Versión actual"
latestVersion: "Última versión"
youAreRunningUpToDateClient: "Está utilizando la versión más reciente de su cliente."
newVersionOfClientAvailable: "Hay una versión más nueva de su cliente disponible."
usageAmount: "Uso"
capacity: "Capacidad"
inUse: "Usado"
editCode: "Editar código"
goBack: "Deseleccionar" goBack: "Deseleccionar"
info: "Información" info: "Información"
user: "Usuarios" user: "Usuarios"
administration: "Administrar" administration: "Administrar"
expiration: "Termina el" expiration: "Termina el"
middle: "Mediano" middle: "Mediano"
customCssWarn: "Este ajuste sólo debe utilizarse si se sabe lo que hace. Introducir valores inadecuados puede hacer que el cliente deje de funcionar con normalidad."
global: "Global" global: "Global"
squareAvatars: "Mostrar iconos cuadrados"
sent: "Enviar" sent: "Enviar"
received: "Recibido"
searchResult: "Resultados de búsqueda"
hashtags: "Hashtag" hashtags: "Hashtag"
troubleshooting: "Solución de problemas"
useBlurEffect: "Utilizar efecto de desenfoque en la interfaz de usuario"
learnMore: "Ver más"
misskeyUpdated: "¡Misskey ha sido actualizado!"
whatIsNew: "Mostrar cambios"
translate: "Traducir"
translatedFrom: "Traducido de {x}"
accountDeletionInProgress: "La eliminación de la cuenta está en curso"
usernameInfo: "Un nombre que identifique su cuenta de otras en este servidor. Puede utilizar el alfabeto (a~z, A~Z), dígitos (0~9) o guiones bajos (_). Los nombres de usuario no se pueden cambiar posteriormente."
aiChanMode: "Modo Ai"
keepCw: "Mantener la advertencia de contenido"
pubSub: "Cuentas Pub/Sub"
lastCommunication: "Última comunicación"
resolved: "Resuelto"
unresolved: "Sin resolver"
_accountDelete:
accountDelete: "Eliminar Cuenta"
_docs: _docs:
admin: "Administrar" admin: "Administrar"
_ad: _ad:

View file

@ -81,6 +81,8 @@ somethingHappened: "Une erreur est survenue"
retry: "Réessayer" retry: "Réessayer"
pageLoadError: "Le chargement de la page a échoué" pageLoadError: "Le chargement de la page a échoué"
pageLoadErrorDescription: "Cela est généralement causé par le cache du navigateur ou par un problème réseau. Veuillez vider votre cache ou attendre un peu et réessayer." pageLoadErrorDescription: "Cela est généralement causé par le cache du navigateur ou par un problème réseau. Veuillez vider votre cache ou attendre un peu et réessayer."
serverIsDead: "Le serveur ne répond pas. Patientez quelques instants puis essayez à nouveau."
youShouldUpgradeClient: "Si la page ne s'affiche pas correctement, rechargez-la pour mettre votre client à jour."
enterListName: "Nom de la liste" enterListName: "Nom de la liste"
privacy: "Confidentialité" privacy: "Confidentialité"
makeFollowManuallyApprove: "Accepter manuellement les demandes dabonnement" makeFollowManuallyApprove: "Accepter manuellement les demandes dabonnement"
@ -136,7 +138,7 @@ settingGuide: "Configuration proposée"
cacheRemoteFiles: "Mise en cache des fichiers distants" cacheRemoteFiles: "Mise en cache des fichiers distants"
cacheRemoteFilesDescription: "Lorsque cette option est désactivée, les fichiers distants sont chargés directement depuis linstance distante. La désactiver diminuera certes lutilisation de lespace de stockage local mais augmentera le trafic réseau puisque les miniatures ne seront plus générées." cacheRemoteFilesDescription: "Lorsque cette option est désactivée, les fichiers distants sont chargés directement depuis linstance distante. La désactiver diminuera certes lutilisation de lespace de stockage local mais augmentera le trafic réseau puisque les miniatures ne seront plus générées."
flagAsBot: "Ce compte est un robot" flagAsBot: "Ce compte est un robot"
flagAsBotDescription: "Si ce compte est géré de manière automatisée , définissez cette option. Si elle est activée, elle agira comme un marqueur pour les autres développeurs afin d'éviter des chaînes d'interaction sans fin avec d'autres robots et d'ajuster les systèmes internes de Misskey pour traiter ce compte comme un robot." flagAsBotDescription: "Si ce compte est géré de manière automatisée, choisissez cette option. Si elle est activée, elle agira comme un marqueur pour les autres développeurs afin d'éviter des chaînes d'interaction sans fin avec d'autres robots et d'ajuster les systèmes internes de Misskey pour traiter ce compte comme un robot."
flagAsCat: "Ce compte est un chat" flagAsCat: "Ce compte est un chat"
flagAsCatDescription: "Activer l'option \" Je suis un chat \" pour ce compte." flagAsCatDescription: "Activer l'option \" Je suis un chat \" pour ce compte."
autoAcceptFollowed: "Accepter automatiquement les demandes dabonnement venant dutilisateur·rice·s que vous suivez" autoAcceptFollowed: "Accepter automatiquement les demandes dabonnement venant dutilisateur·rice·s que vous suivez"
@ -377,7 +379,7 @@ aboutMisskey: "À propos de Misskey"
administrator: "Administrateur" administrator: "Administrateur"
token: "Jeton" token: "Jeton"
twoStepAuthentication: "Authentification à deux facteurs" twoStepAuthentication: "Authentification à deux facteurs"
moderator: "Modérateurs" moderator: "Modérateur·rice·s"
nUsersMentioned: "{n} utilisateur·rice·s mentionné·e·s" nUsersMentioned: "{n} utilisateur·rice·s mentionné·e·s"
securityKey: "Clé de sécurité" securityKey: "Clé de sécurité"
securityKeyName: "Nom de la clé" securityKeyName: "Nom de la clé"
@ -495,7 +497,7 @@ objectStorageSetPublicRead: "Régler sur « public » lors de l'envoi"
serverLogs: "Journal du serveur" serverLogs: "Journal du serveur"
deleteAll: "Supprimer tout" deleteAll: "Supprimer tout"
showFixedPostForm: "Afficher le formulaire de publication en haut du fil d'actualité" showFixedPostForm: "Afficher le formulaire de publication en haut du fil d'actualité"
newNoteRecived: "Vous avez reçu une nouvelle note" newNoteRecived: "Voir les nouvelles notes"
sounds: "Sons" sounds: "Sons"
listen: "Écouter" listen: "Écouter"
none: "Rien" none: "Rien"
@ -530,6 +532,7 @@ removeAllFollowingDescription: "Se désabonner de tous les comptes de {host}. Ve
userSuspended: "Cet·te utilisateur·rice a été suspendu·e." userSuspended: "Cet·te utilisateur·rice a été suspendu·e."
userSilenced: "Cette utilisateur·trice a été mis·e en sourdine." userSilenced: "Cette utilisateur·trice a été mis·e en sourdine."
yourAccountSuspendedTitle: "Ce compte est suspendu" yourAccountSuspendedTitle: "Ce compte est suspendu"
yourAccountSuspendedDescription: "Ce compte est suspendu car vous avez enfreint les conditions d'utilisation de l'instance, ou pour un motif similaire. Si vous souhaitez connaître en détail les raisons de cette suspension, renseignez-vous auprès de l'administrateur·rice de votre instance. Merci de ne pas créer de nouveau compte."
menu: "Menu" menu: "Menu"
divider: "Séparateur" divider: "Séparateur"
addItem: "Ajouter un élément" addItem: "Ajouter un élément"
@ -786,6 +789,15 @@ pubSub: "Comptes Pub/Sub"
lastCommunication: "Dernière communication" lastCommunication: "Dernière communication"
resolved: "Résolu" resolved: "Résolu"
unresolved: "En attente" unresolved: "En attente"
emailRequiredForSignup: "Une adresse e-mail est nécessaire pour créer un compte"
unread: "Non lu"
filter: "Filtre"
controllPanel: "Panneau de contrôle"
manageAccounts: "Gérer les comptes"
_signup:
almostThere: "Bientôt fini"
emailAddressInfo: "Insérez votre adresse e-mail."
emailSent: "Un courriel de confirmation vient d'être envoyé à l'adresse que vous avez renseignée ({email}). Cliquez sur le lien contenu dans le message pour terminer la création de votre compte."
_accountDelete: _accountDelete:
accountDelete: "Supprimer le compte" accountDelete: "Supprimer le compte"
mayTakeTime: "La suppression de compte nécessitant beaucoup de ressources, l'exécution du processus peut prendre du temps, en fonction de la quantité de contenus que vous avez créés et du nombre de fichiers que vous avez téléversés." mayTakeTime: "La suppression de compte nécessitant beaucoup de ressources, l'exécution du processus peut prendre du temps, en fonction de la quantité de contenus que vous avez créés et du nombre de fichiers que vous avez téléversés."
@ -900,6 +912,8 @@ _mfm:
fontDescription: "Il est possible de choisir la police." fontDescription: "Il est possible de choisir la police."
rainbow: "Arc-en-ciel" rainbow: "Arc-en-ciel"
rainbowDescription: "Permet d'afficher le contenu en couleurs arc-en-ciel." rainbowDescription: "Permet d'afficher le contenu en couleurs arc-en-ciel."
sparkle: "Paillettes"
sparkleDescription: "Ajoute un effet scintillant au contenu."
_reversi: _reversi:
reversi: "Reversi" reversi: "Reversi"
gameSettings: "Réglages de la partie" gameSettings: "Réglages de la partie"
@ -1243,7 +1257,7 @@ _charts:
federationInstancesTotal: "Nombre total d'instances fédérées" federationInstancesTotal: "Nombre total d'instances fédérées"
usersIncDec: "Variation du nombre d'utilisateur·rice·s" usersIncDec: "Variation du nombre d'utilisateur·rice·s"
usersTotal: "Nombre des utilisateur·rice·s au total" usersTotal: "Nombre des utilisateur·rice·s au total"
activeUsers: "Utilisateur·rice·s actif·ve·s" activeUsers: "Nombre d'utilisateurices actif·ve·s"
notesIncDec: "Variation du nombre des notes" notesIncDec: "Variation du nombre des notes"
localNotesIncDec: "Variation du nombre de notes locales" localNotesIncDec: "Variation du nombre de notes locales"
remoteNotesIncDec: "Variation du nombre de notes distantes" remoteNotesIncDec: "Variation du nombre de notes distantes"

View file

@ -780,6 +780,7 @@ translatedFrom: "Terjemahkan dari {x}"
accountDeletionInProgress: "Penghapusan akun sedang dalam proses" accountDeletionInProgress: "Penghapusan akun sedang dalam proses"
usernameInfo: "Nama yang mengidentifikasikan akun kamu dari yang lain pada server ini. Kamu dapat menggunakan alfabet (a~z, A~Z), digit (0~9) atau garis bawah (_). Username tidak dapat diubah setelahnya." usernameInfo: "Nama yang mengidentifikasikan akun kamu dari yang lain pada server ini. Kamu dapat menggunakan alfabet (a~z, A~Z), digit (0~9) atau garis bawah (_). Username tidak dapat diubah setelahnya."
keepCw: "Biarkan Peringatan Konten" keepCw: "Biarkan Peringatan Konten"
controllPanel: "Panel kontrol"
_accountDelete: _accountDelete:
accountDelete: "Hapus akun" accountDelete: "Hapus akun"
mayTakeTime: "Karena penghapusan akun merupakan proses yang berat dan intensif, kemungkinan dapat membutuhkan waktu untuk menyelesaikan tergantung daripada berapa banyak konten yang kamu buat dan berapa banyak berkas yang telah kamu unggah." mayTakeTime: "Karena penghapusan akun merupakan proses yang berat dan intensif, kemungkinan dapat membutuhkan waktu untuk menyelesaikan tergantung daripada berapa banyak konten yang kamu buat dan berapa banyak berkas yang telah kamu unggah."

View file

@ -482,7 +482,7 @@ objectStorageSetPublicRead: "Imposta \"visibilità pubblica\" al momento di cari
serverLogs: "Log del server" serverLogs: "Log del server"
deleteAll: "Cancella cronologia" deleteAll: "Cancella cronologia"
showFixedPostForm: "Visualizzare la finestra di pubblicazione in cima alla timeline" showFixedPostForm: "Visualizzare la finestra di pubblicazione in cima alla timeline"
newNoteRecived: "Nuova nota ricevuta" newNoteRecived: "Vedi le nuove note"
sounds: "Impostazioni suoni" sounds: "Impostazioni suoni"
listen: "Ascolta" listen: "Ascolta"
none: "Niente" none: "Niente"

View file

@ -797,6 +797,8 @@ unread: "未読"
filter: "フィルタ" filter: "フィルタ"
controllPanel: "コントロールパネル" controllPanel: "コントロールパネル"
manageAccounts: "アカウントを管理" manageAccounts: "アカウントを管理"
makeReactionsPublic: "リアクション一覧を公開する"
makeReactionsPublicDescription: "あなたがしたリアクション一覧を誰でも見れるようにします。"
_signup: _signup:
almostThere: "ほとんど完了です" almostThere: "ほとんど完了です"

View file

@ -787,6 +787,7 @@ pubSub: "Pub/Sub 계정"
lastCommunication: "마지막 통신" lastCommunication: "마지막 통신"
resolved: "해결됨" resolved: "해결됨"
unresolved: "해결되지 않음" unresolved: "해결되지 않음"
controllPanel: "제어판"
_accountDelete: _accountDelete:
accountDelete: "계정 삭제" accountDelete: "계정 삭제"
mayTakeTime: "계정 삭제는 서버에 부하를 가하기 때문에, 작성한 콘텐츠나 업로드한 파일의 수가 많으면 완료까지 시간이 걸릴 수 있습니다." mayTakeTime: "계정 삭제는 서버에 부하를 가하기 때문에, 작성한 콘텐츠나 업로드한 파일의 수가 많으면 완료까지 시간이 걸릴 수 있습니다."
@ -901,6 +902,8 @@ _mfm:
fontDescription: "내용의 글꼴을 지정할 수 있습니다." fontDescription: "내용의 글꼴을 지정할 수 있습니다."
rainbow: "무지개" rainbow: "무지개"
rainbowDescription: "내용을 무지개로 표시합니다." rainbowDescription: "내용을 무지개로 표시합니다."
sparkle: "반짝반짝"
sparkleDescription: "반짝이는 파티클 효과를 추가합니다."
_reversi: _reversi:
reversi: "리버시" reversi: "리버시"
gameSettings: "대국 설정" gameSettings: "대국 설정"

View file

@ -81,6 +81,8 @@ somethingHappened: "Что-то пошло не так"
retry: "Повторить попытку" retry: "Повторить попытку"
pageLoadError: "Не удалось загрузить страницу" pageLoadError: "Не удалось загрузить страницу"
pageLoadErrorDescription: "Обычно это случается из-за сбоев в сети или кэша браузера. Попробуйте очистить кэш, или подождать пару минут, а потом попытаться загрузить страницу снова." pageLoadErrorDescription: "Обычно это случается из-за сбоев в сети или кэша браузера. Попробуйте очистить кэш, или подождать пару минут, а потом попытаться загрузить страницу снова."
serverIsDead: "Ответа от сервера нет. Пожалуйста, подождите немного и повторите попытку."
youShouldUpgradeClient: "Чтобы просмотреть эту страницу, пожалуйста, обновите ее."
enterListName: "Название списка" enterListName: "Название списка"
privacy: "Конфиденциальность" privacy: "Конфиденциальность"
makeFollowManuallyApprove: "Принимать подписчиков вручную" makeFollowManuallyApprove: "Принимать подписчиков вручную"
@ -529,6 +531,8 @@ removeAllFollowing: "Удалить всех подписчиков"
removeAllFollowingDescription: "Отменить все подписки с домена {host}? Пожалуйста, применяйте это действие, если инстанс больше не существует." removeAllFollowingDescription: "Отменить все подписки с домена {host}? Пожалуйста, применяйте это действие, если инстанс больше не существует."
userSuspended: "Эта учётная запись заморожена" userSuspended: "Эта учётная запись заморожена"
userSilenced: "Этот пользователь был заглушен" userSilenced: "Этот пользователь был заглушен"
yourAccountSuspendedTitle: "Эта учетная запись заблокирована"
yourAccountSuspendedDescription: "Эта учетная запись была заблокирована из-за нарушения условий предоставления услуг сервера. Свяжитесь с администратором, если вы хотите узнать более подробную причину. Пожалуйста, не создавайте новую учетную запись."
menu: "Меню" menu: "Меню"
divider: "Линия-разделитель" divider: "Линия-разделитель"
addItem: "Добавить элемент" addItem: "Добавить элемент"
@ -775,6 +779,13 @@ useBlurEffect: "Размытие в интерфейсе"
learnMore: "Подробнее" learnMore: "Подробнее"
misskeyUpdated: "Misskey обновился!" misskeyUpdated: "Misskey обновился!"
whatIsNew: "Что новенького?" whatIsNew: "Что новенького?"
translate: "Перевод"
accountDeletionInProgress: "В настоящее время выполняется удаление учетной записи"
usernameInfo: "Имя, которое отличает вашу учетную запись от других на этом сервере. Вы можете использовать алфавит (a~z, A~Z), цифры (0~9) или символы подчеркивания (_). Имена пользователей не могут быть изменены позже."
aiChanMode: "ИИ режим"
keepCw: "Сохраняйте Предупреждения о содержимом"
controllPanel: "Панель управления"
manageAccounts: "Управление аккаунтом"
_docs: _docs:
continueReading: "Читать подробнее" continueReading: "Читать подробнее"
features: "Возможности" features: "Возможности"

View file

@ -81,6 +81,8 @@ somethingHappened: "出现了一些问题!"
retry: "重试" retry: "重试"
pageLoadError: "页面加载失败。" pageLoadError: "页面加载失败。"
pageLoadErrorDescription: "这通常是由于网络或浏览器缓存的原因。请清除缓存或等待片刻后重试。" pageLoadErrorDescription: "这通常是由于网络或浏览器缓存的原因。请清除缓存或等待片刻后重试。"
serverIsDead: "服务器没有响应。 请稍等片刻,然后重试。"
youShouldUpgradeClient: "请重新加载并使用新版本的客户端查看此页面。"
enterListName: "输入列表名称" enterListName: "输入列表名称"
privacy: "隐私" privacy: "隐私"
makeFollowManuallyApprove: "关注者的关注请求需要批准" makeFollowManuallyApprove: "关注者的关注请求需要批准"
@ -764,6 +766,7 @@ middle: "中"
low: "低" low: "低"
emailNotConfiguredWarning: "电子邮件地址未设置。" emailNotConfiguredWarning: "电子邮件地址未设置。"
ratio: "比率" ratio: "比率"
previewNoteText: "预览文本"
customCss: "自定义 CSS" customCss: "自定义 CSS"
customCssWarn: "这些设置必须有相关的基础知识,不当的配置可能导致客户端无法正常使用!" customCssWarn: "这些设置必须有相关的基础知识,不当的配置可能导致客户端无法正常使用!"
global: "全局" global: "全局"
@ -787,6 +790,17 @@ pubSub: "Pub/Sub账户"
lastCommunication: "最近通信" lastCommunication: "最近通信"
resolved: "已解决" resolved: "已解决"
unresolved: "未解决" unresolved: "未解决"
itsOn: "已开启"
itsOff: "已关闭"
emailRequiredForSignup: "注册账户需要电子邮件地址"
unread: "未读"
filter: "筛选"
controllPanel: "控制面板"
manageAccounts: "管理账户"
_signup:
almostThere: "即将完成"
emailAddressInfo: "请输入您所使用的电子邮件地址"
emailSent: "已将确认邮件发送至您输入的电子邮件地址 ({email})。请访问电子邮件中的链接以完成帐户创建。"
_accountDelete: _accountDelete:
accountDelete: "删除帐户" accountDelete: "删除帐户"
mayTakeTime: "删除账号是一个性能损耗较大的处理,如果账号持有的内容数量和上传的文件数量较多的话,完成需要花费一段时间。" mayTakeTime: "删除账号是一个性能损耗较大的处理,如果账号持有的内容数量和上传的文件数量较多的话,完成需要花费一段时间。"
@ -901,6 +915,8 @@ _mfm:
fontDescription: "可以设置内容所使用的字体。" fontDescription: "可以设置内容所使用的字体。"
rainbow: "彩虹" rainbow: "彩虹"
rainbowDescription: "用彩虹色来显示内容。" rainbowDescription: "用彩虹色来显示内容。"
sparkle: "闪光"
sparkleDescription: "添加发光粒子效果。"
_reversi: _reversi:
reversi: "黑白棋" reversi: "黑白棋"
gameSettings: "对局设置" gameSettings: "对局设置"

View file

@ -0,0 +1,14 @@
import {MigrationInterface, QueryRunner} from "typeorm";
export class userPublicReactions1634486652000 implements MigrationInterface {
name = 'userPublicReactions1634486652000'
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "user_profile" ADD "publicReactions" boolean NOT NULL DEFAULT false`);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "publicReactions"`);
}
}

View file

@ -1,7 +1,7 @@
{ {
"name": "misskey", "name": "misskey",
"author": "syuilo <syuilotan@yahoo.co.jp>", "author": "syuilo <syuilotan@yahoo.co.jp>",
"version": "12.91.0", "version": "12.92.0",
"codename": "indigo", "codename": "indigo",
"repository": { "repository": {
"type": "git", "type": "git",
@ -103,8 +103,8 @@
"@types/webpack-stream": "3.2.12", "@types/webpack-stream": "3.2.12",
"@types/websocket": "1.0.4", "@types/websocket": "1.0.4",
"@types/ws": "8.2.0", "@types/ws": "8.2.0",
"@typescript-eslint/parser": "4.33.0", "@typescript-eslint/parser": "5.0.0",
"@vue/compiler-sfc": "3.2.19", "@vue/compiler-sfc": "3.2.20",
"abort-controller": "3.0.0", "abort-controller": "3.0.0",
"apexcharts": "3.28.3", "apexcharts": "3.28.3",
"autobind-decorator": "2.4.0", "autobind-decorator": "2.4.0",
@ -114,8 +114,8 @@
"bcryptjs": "2.4.3", "bcryptjs": "2.4.3",
"blurhash": "1.1.4", "blurhash": "1.1.4",
"broadcast-channel": "4.2.0", "broadcast-channel": "4.2.0",
"bull": "3.29.2", "bull": "3.29.3",
"cacheable-lookup": "6.0.2", "cacheable-lookup": "6.0.3",
"cafy": "15.2.1", "cafy": "15.2.1",
"cbor": "8.0.2", "cbor": "8.0.2",
"chalk": "4.1.2", "chalk": "4.1.2",
@ -125,11 +125,11 @@
"concurrently": "6.3.0", "concurrently": "6.3.0",
"content-disposition": "0.5.3", "content-disposition": "0.5.3",
"crc-32": "1.2.0", "crc-32": "1.2.0",
"css-loader": "6.3.0", "css-loader": "6.4.0",
"cssnano": "5.0.8", "cssnano": "5.0.8",
"dateformat": "4.5.1", "dateformat": "4.5.1",
"escape-regexp": "0.0.1", "escape-regexp": "0.0.1",
"eslint": "7.32.0", "eslint": "8.0.1",
"eslint-plugin-vue": "7.19.1", "eslint-plugin-vue": "7.19.1",
"eventemitter3": "4.0.7", "eventemitter3": "4.0.7",
"feed": "4.2.2", "feed": "4.2.2",
@ -176,15 +176,15 @@
"multer": "1.4.3", "multer": "1.4.3",
"nested-property": "4.0.0", "nested-property": "4.0.0",
"node-fetch": "2.6.1", "node-fetch": "2.6.1",
"nodemailer": "6.6.5", "nodemailer": "6.7.0",
"os-utils": "0.0.14", "os-utils": "0.0.14",
"parse5": "6.0.1", "parse5": "6.0.1",
"pg": "8.7.1", "pg": "8.7.1",
"portscanner": "2.2.0", "portscanner": "2.2.0",
"postcss": "8.3.9", "postcss": "8.3.9",
"postcss-loader": "6.1.1", "postcss-loader": "6.2.0",
"prismjs": "1.25.0", "prismjs": "1.25.0",
"private-ip": "2.2.1", "private-ip": "2.3.0",
"probe-image-size": "7.2.1", "probe-image-size": "7.2.1",
"promise-limit": "2.7.0", "promise-limit": "2.7.0",
"pug": "3.0.2", "pug": "3.0.2",
@ -203,8 +203,8 @@
"rimraf": "3.0.2", "rimraf": "3.0.2",
"rndstr": "1.0.0", "rndstr": "1.0.0",
"s-age": "1.1.2", "s-age": "1.1.2",
"sass": "1.42.1", "sass": "1.43.2",
"sass-loader": "12.1.0", "sass-loader": "12.2.0",
"seedrandom": "3.0.5", "seedrandom": "3.0.5",
"sharp": "0.29.1", "sharp": "0.29.1",
"speakeasy": "2.0.0", "speakeasy": "2.0.0",
@ -213,7 +213,7 @@
"style-loader": "3.3.0", "style-loader": "3.3.0",
"summaly": "2.4.1", "summaly": "2.4.1",
"syslog-pro": "1.0.0", "syslog-pro": "1.0.0",
"systeminformation": "5.9.4", "systeminformation": "5.9.7",
"syuilo-password-strength": "0.0.1", "syuilo-password-strength": "0.0.1",
"textarea-caret": "3.1.0", "textarea-caret": "3.1.0",
"three": "0.117.1", "three": "0.117.1",
@ -221,19 +221,19 @@
"tinycolor2": "1.4.2", "tinycolor2": "1.4.2",
"tmp": "0.2.1", "tmp": "0.2.1",
"ts-loader": "9.2.6", "ts-loader": "9.2.6",
"ts-node": "10.2.1", "ts-node": "10.3.0",
"tsc-alias": "1.3.10", "tsc-alias": "1.3.10",
"tsconfig-paths": "3.11.0", "tsconfig-paths": "3.11.0",
"tslint": "6.1.3", "tslint": "6.1.3",
"tslint-sonarts": "1.9.0", "tslint-sonarts": "1.9.0",
"twemoji-parser": "13.1.0", "twemoji-parser": "13.1.0",
"typeorm": "0.2.38", "typeorm": "0.2.38",
"typescript": "4.4.3", "typescript": "4.4.4",
"ulid": "2.3.0", "ulid": "2.3.0",
"uuid": "8.3.2", "uuid": "8.3.2",
"v-debounce": "0.1.2", "v-debounce": "0.1.2",
"vanilla-tilt": "1.7.2", "vanilla-tilt": "1.7.2",
"vue": "3.2.19", "vue": "3.2.20",
"vue-loader": "16.7.0", "vue-loader": "16.7.0",
"vue-prism-editor": "2.0.0-alpha.2", "vue-prism-editor": "2.0.0-alpha.2",
"vue-router": "4.0.5", "vue-router": "4.0.5",
@ -241,7 +241,7 @@
"vue-svg-loader": "0.17.0-beta.2", "vue-svg-loader": "0.17.0-beta.2",
"vuedraggable": "4.0.1", "vuedraggable": "4.0.1",
"web-push": "3.4.5", "web-push": "3.4.5",
"webpack": "5.58.0", "webpack": "5.58.2",
"webpack-cli": "4.9.0", "webpack-cli": "4.9.0",
"websocket": "1.0.34", "websocket": "1.0.34",
"ws": "8.2.3", "ws": "8.2.3",

View file

@ -22,7 +22,6 @@ export default defineComponent({
} }
}, },
render() { render() {
const label = this.$slots.desc();
let options = this.$slots.default(); let options = this.$slots.default();
// Fragment // Fragment
@ -31,7 +30,6 @@ export default defineComponent({
return h('div', { return h('div', {
class: 'novjtcto' class: 'novjtcto'
}, [ }, [
h('div', { class: 'label' }, label),
...options.map(option => h(MkRadio, { ...options.map(option => h(MkRadio, {
key: option.key, key: option.key,
value: option.props.value, value: option.props.value,
@ -45,16 +43,6 @@ export default defineComponent({
<style lang="scss"> <style lang="scss">
.novjtcto { .novjtcto {
> .label {
font-size: 0.85em;
padding: 0 0 8px 12px;
user-select: none;
&:empty {
display: none;
}
}
&:first-child { &:first-child {
margin-top: 0; margin-top: 0;
} }

View file

@ -33,10 +33,16 @@ export default defineComponent({
onMounted(() => { onMounted(() => {
ro = new ResizeObserver((entries) => { ro = new ResizeObserver((entries) => {
/* iOS
adjust({ adjust({
width: entries[0].borderBoxSize[0].inlineSize, width: entries[0].borderBoxSize[0].inlineSize,
height: entries[0].borderBoxSize[0].blockSize, height: entries[0].borderBoxSize[0].blockSize,
}); });
*/
adjust({
width: root.value.offsetWidth,
height: root.value.offsetHeight,
});
}); });
ro.observe(root.value); ro.observe(root.value);

View file

@ -10,7 +10,7 @@
</span> </span>
<button class="_button" @click="$refs.modal.close()"><i class="fas fa-times"></i></button> <button class="_button" @click="$refs.modal.close()"><i class="fas fa-times"></i></button>
</div> </div>
<div class="body _flat_"> <div class="body _fitSide_">
<keep-alive> <keep-alive>
<component :is="component" v-bind="props" :ref="changePage"/> <component :is="component" v-bind="props" :ref="changePage"/>
</keep-alive> </keep-alive>

View file

@ -16,7 +16,7 @@
<template #headerLeft> <template #headerLeft>
<button v-if="history.length > 0" class="_button" @click="back()" v-tooltip="$ts.goBack"><i class="fas fa-arrow-left"></i></button> <button v-if="history.length > 0" class="_button" @click="back()" v-tooltip="$ts.goBack"><i class="fas fa-arrow-left"></i></button>
</template> </template>
<div class="yrolvcoq _flat_"> <div class="yrolvcoq _fitSide_">
<component :is="component" v-bind="props" :ref="changePage"/> <component :is="component" v-bind="props" :ref="changePage"/>
</div> </div>
</XWindow> </XWindow>

View file

@ -35,8 +35,8 @@ export default defineComponent({
> button { > button {
flex: 1; flex: 1;
padding: 15px 12px 12px 12px; padding: 10px 8px;
border-bottom: solid 3px transparent; border-radius: var(--radius);
&:disabled { &:disabled {
opacity: 1 !important; opacity: 1 !important;
@ -45,11 +45,16 @@ export default defineComponent({
&.active { &.active {
color: var(--accent); color: var(--accent);
border-bottom-color: var(--accent); background: var(--accentedBg);
} }
&:not(.active):hover { &:not(.active):hover {
color: var(--fgHighlighted); color: var(--fgHighlighted);
background: var(--panelHighlight);
}
&:not(:first-child) {
margin-left: 8px;
} }
> .icon { > .icon {
@ -61,7 +66,7 @@ export default defineComponent({
font-size: 80%; font-size: 80%;
> button { > button {
padding: 11px 8px 8px 8px; padding: 11px 8px;
} }
} }
} }

View file

@ -154,7 +154,7 @@ export default defineComponent({
} }
} }
._flat_ .ssazuxis { ._fitSide_ .ssazuxis {
> header { > header {
padding: 0 16px; padding: 0 16px;
} }

View file

@ -43,7 +43,7 @@ export default defineComponent({
} }
} }
._flat_ .fpezltsf { ._fitSide_ .fpezltsf {
border-radius: 0; border-radius: 0;
} }
</style> </style>

View file

@ -382,7 +382,7 @@ export default defineComponent({
<style lang="scss" scoped> <style lang="scss" scoped>
.window-enter-active, .window-leave-active { .window-enter-active, .window-leave-active {
transition: opacity 0.3s, transform 0.3s !important; transition: opacity 0.2s, transform 0.2s !important;
} }
.window-enter-from, .window-leave-to { .window-enter-from, .window-leave-to {
pointer-events: none; pointer-events: none;

View file

@ -65,13 +65,18 @@
</div> </div>
<div v-else-if="tab === 'search'"> <div v-else-if="tab === 'search'">
<div class="_isolated"> <div class="_isolated">
<MkInput v-model="query" :debounce="true" type="search"> <MkInput v-model="searchQuery" :debounce="true" type="search">
<template #prefix><i class="fas fa-search"></i></template> <template #prefix><i class="fas fa-search"></i></template>
<template #label>{{ $ts.searchUser }}</template> <template #label>{{ $ts.searchUser }}</template>
</MkInput> </MkInput>
<MkRadios v-model="searchOrigin">
<option value="local">{{ $ts.local }}</option>
<option value="remote">{{ $ts.remote }}</option>
<option value="both">{{ $ts.both }}</option>
</MkRadios>
</div> </div>
<XUserList v-if="query" class="_gap" :pagination="searchPagination" ref="search"/> <XUserList v-if="searchQuery" class="_gap" :pagination="searchPagination" ref="search"/>
</div> </div>
</div> </div>
</MkSpacer> </MkSpacer>
@ -83,6 +88,7 @@ import { computed, defineComponent } from 'vue';
import XUserList from '@client/components/user-list.vue'; import XUserList from '@client/components/user-list.vue';
import MkFolder from '@client/components/ui/folder.vue'; import MkFolder from '@client/components/ui/folder.vue';
import MkInput from '@client/components/form/input.vue'; import MkInput from '@client/components/form/input.vue';
import MkRadios from '@client/components/form/radios.vue';
import number from '@client/filters/number'; import number from '@client/filters/number';
import * as os from '@client/os'; import * as os from '@client/os';
import * as symbols from '@client/symbols'; import * as symbols from '@client/symbols';
@ -92,6 +98,7 @@ export default defineComponent({
XUserList, XUserList,
MkFolder, MkFolder,
MkInput, MkInput,
MkRadios,
}, },
props: { props: {
@ -158,14 +165,16 @@ export default defineComponent({
searchPagination: { searchPagination: {
endpoint: 'users/search', endpoint: 'users/search',
limit: 10, limit: 10,
params: computed(() => (this.query && this.query !== '') ? { params: computed(() => (this.searchQuery && this.searchQuery !== '') ? {
query: this.query query: this.searchQuery,
origin: this.searchOrigin,
} : null) } : null)
}, },
tagsLocal: [], tagsLocal: [],
tagsRemote: [], tagsRemote: [],
stats: null, stats: null,
query: null, searchQuery: null,
searchOrigin: 'combined',
num: number, num: number,
}; };
}, },

View file

@ -302,7 +302,7 @@ export default defineComponent({
> .text { > .text {
&, ::v-deep(*) { &, ::v-deep(*) {
color: #fff !important; color: var(--fgOnAccent) !important;
} }
} }
} }

View file

@ -2,6 +2,7 @@
<div> <div>
<MkHeader :info="header"/> <MkHeader :info="header"/>
<MkSpacer>
<!-- TODO: MkHeaderに統合 --> <!-- TODO: MkHeaderに統合 -->
<MkTab v-model="tab" v-if="$i"> <MkTab v-model="tab" v-if="$i">
<option value="featured"><i class="fas fa-fire-alt"></i> {{ $ts._pages.featured }}</option> <option value="featured"><i class="fas fa-fire-alt"></i> {{ $ts._pages.featured }}</option>
@ -29,6 +30,7 @@
</MkPagination> </MkPagination>
</div> </div>
</div> </div>
</MkSpacer>
</div> </div>
</template> </template>

View file

@ -5,6 +5,10 @@
<FormSwitch v-model="autoAcceptFollowed" :disabled="!isLocked" @update:modelValue="save()">{{ $ts.autoAcceptFollowed }}</FormSwitch> <FormSwitch v-model="autoAcceptFollowed" :disabled="!isLocked" @update:modelValue="save()">{{ $ts.autoAcceptFollowed }}</FormSwitch>
<template #caption>{{ $ts.lockedAccountInfo }}</template> <template #caption>{{ $ts.lockedAccountInfo }}</template>
</FormGroup> </FormGroup>
<FormSwitch v-model="publicReactions" @update:modelValue="save()">
{{ $ts.makeReactionsPublic }}
<template #desc>{{ $ts.makeReactionsPublicDescription }}</template>
</FormSwitch>
<FormSwitch v-model="hideOnlineStatus" @update:modelValue="save()"> <FormSwitch v-model="hideOnlineStatus" @update:modelValue="save()">
{{ $ts.hideOnlineStatus }} {{ $ts.hideOnlineStatus }}
<template #desc>{{ $ts.hideOnlineStatusDescription }}</template> <template #desc>{{ $ts.hideOnlineStatusDescription }}</template>
@ -64,6 +68,7 @@ export default defineComponent({
noCrawle: false, noCrawle: false,
isExplorable: false, isExplorable: false,
hideOnlineStatus: false, hideOnlineStatus: false,
publicReactions: false,
} }
}, },
@ -80,6 +85,7 @@ export default defineComponent({
this.noCrawle = this.$i.noCrawle; this.noCrawle = this.$i.noCrawle;
this.isExplorable = this.$i.isExplorable; this.isExplorable = this.$i.isExplorable;
this.hideOnlineStatus = this.$i.hideOnlineStatus; this.hideOnlineStatus = this.$i.hideOnlineStatus;
this.publicReactions = this.$i.publicReactions;
}, },
mounted() { mounted() {
@ -94,6 +100,7 @@ export default defineComponent({
noCrawle: !!this.noCrawle, noCrawle: !!this.noCrawle,
isExplorable: !!this.isExplorable, isExplorable: !!this.isExplorable,
hideOnlineStatus: !!this.hideOnlineStatus, hideOnlineStatus: !!this.hideOnlineStatus,
publicReactions: !!this.publicReactions,
}); });
} }
} }

View file

@ -10,13 +10,13 @@
</optgroup> </optgroup>
</FormSelect> </FormSelect>
<template v-if="selectedTheme"> <template v-if="selectedTheme">
<FormInput readonly :value="selectedTheme.author"> <FormInput readonly :modelValue="selectedTheme.author">
<span>{{ $ts.author }}</span> <span>{{ $ts.author }}</span>
</FormInput> </FormInput>
<FormTextarea readonly :value="selectedTheme.desc" v-if="selectedTheme.desc"> <FormTextarea readonly :modelValue="selectedTheme.desc" v-if="selectedTheme.desc">
<span>{{ $ts._theme.description }}</span> <span>{{ $ts._theme.description }}</span>
</FormTextarea> </FormTextarea>
<FormTextarea readonly tall :value="selectedThemeCode"> <FormTextarea readonly tall :modelValue="selectedThemeCode">
<span>{{ $ts._theme.code }}</span> <span>{{ $ts._theme.code }}</span>
<template #desc><button @click="copyThemeCode()" class="_textButton">{{ $ts.copy }}</button></template> <template #desc><button @click="copyThemeCode()" class="_textButton">{{ $ts.copy }}</button></template>
</FormTextarea> </FormTextarea>
@ -28,12 +28,12 @@
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import * as JSON5 from 'json5'; import * as JSON5 from 'json5';
import FormTextarea from '@client/components/form/textarea.vue'; import FormTextarea from '@client/components/debobigego/textarea.vue';
import FormSelect from '@client/components/form/select.vue'; import FormSelect from '@client/components/debobigego/select.vue';
import FormRadios from '@client/components/form/radios.vue'; import FormRadios from '@client/components/debobigego/radios.vue';
import FormBase from '@client/components/debobigego/base.vue'; import FormBase from '@client/components/debobigego/base.vue';
import FormGroup from '@client/components/debobigego/group.vue'; import FormGroup from '@client/components/debobigego/group.vue';
import FormInput from '@client/components/form/input.vue'; import FormInput from '@client/components/debobigego/input.vue';
import FormButton from '@client/components/debobigego/button.vue'; import FormButton from '@client/components/debobigego/button.vue';
import { Theme, builtinThemes } from '@client/scripts/theme'; import { Theme, builtinThemes } from '@client/scripts/theme';
import copyToClipboard from '@client/scripts/copy-to-clipboard'; import copyToClipboard from '@client/scripts/copy-to-clipboard';

View file

@ -12,7 +12,6 @@
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import MkPagination from '@client/components/ui/pagination.vue'; import MkPagination from '@client/components/ui/pagination.vue';
import { userPage, acct } from '@client/filters/user';
export default defineComponent({ export default defineComponent({
components: { components: {
@ -43,12 +42,6 @@ export default defineComponent({
this.$refs.list.reload(); this.$refs.list.reload();
} }
}, },
methods: {
userPage,
acct
}
}); });
</script> </script>

View file

@ -12,7 +12,6 @@
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import MkUserInfo from '@client/components/user-info.vue'; import MkUserInfo from '@client/components/user-info.vue';
import MkPagination from '@client/components/ui/pagination.vue'; import MkPagination from '@client/components/ui/pagination.vue';
import { userPage, acct } from '@client/filters/user';
export default defineComponent({ export default defineComponent({
components: { components: {
@ -51,12 +50,6 @@ export default defineComponent({
user() { user() {
this.$refs.list.reload(); this.$refs.list.reload();
} }
},
methods: {
userPage,
acct
} }
}); });
</script> </script>

View file

@ -12,7 +12,6 @@
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import MkGalleryPostPreview from '@client/components/gallery-post-preview.vue'; import MkGalleryPostPreview from '@client/components/gallery-post-preview.vue';
import MkPagination from '@client/components/ui/pagination.vue'; import MkPagination from '@client/components/ui/pagination.vue';
import { userPage, acct } from '@client/filters/user';
export default defineComponent({ export default defineComponent({
components: { components: {
@ -43,12 +42,6 @@ export default defineComponent({
user() { user() {
this.$refs.list.reload(); this.$refs.list.reload();
} }
},
methods: {
userPage,
acct
} }
}); });
</script> </script>

View file

@ -1,6 +1,6 @@
<template> <template>
<div class="yrzkoczt" v-sticky-container> <div class="yrzkoczt" v-sticky-container>
<MkTab v-model="with_" class="_gap tab"> <MkTab v-model="with_" class="tab">
<option :value="null">{{ $ts.notes }}</option> <option :value="null">{{ $ts.notes }}</option>
<option value="replies">{{ $ts.notesAndReplies }}</option> <option value="replies">{{ $ts.notesAndReplies }}</option>
<option value="files">{{ $ts.withFiles }}</option> <option value="files">{{ $ts.withFiles }}</option>
@ -60,7 +60,16 @@ export default defineComponent({
<style lang="scss" scoped> <style lang="scss" scoped>
.yrzkoczt { .yrzkoczt {
> .tab { > .tab {
margin: calc(var(--margin) / 2) 0;
padding: calc(var(--margin) / 2) 0;
background: var(--bg); background: var(--bg);
} }
} }
._fitSide_ .yrzkoczt {
> .tab {
padding-left: var(--margin);
padding-right: var(--margin);
}
}
</style> </style>

View file

@ -181,6 +181,7 @@
</template> </template>
<XFollowList v-else-if="page === 'following'" type="following" :user="user" class="_content _gap"/> <XFollowList v-else-if="page === 'following'" type="following" :user="user" class="_content _gap"/>
<XFollowList v-else-if="page === 'followers'" type="followers" :user="user" class="_content _gap"/> <XFollowList v-else-if="page === 'followers'" type="followers" :user="user" class="_content _gap"/>
<XReactions v-else-if="page === 'reactions'" :user="user" class="_gap"/>
<XClips v-else-if="page === 'clips'" :user="user" class="_gap"/> <XClips v-else-if="page === 'clips'" :user="user" class="_gap"/>
<XPages v-else-if="page === 'pages'" :user="user" class="_gap"/> <XPages v-else-if="page === 'pages'" :user="user" class="_gap"/>
<XGallery v-else-if="page === 'gallery'" :user="user" class="_gap"/> <XGallery v-else-if="page === 'gallery'" :user="user" class="_gap"/>
@ -223,6 +224,7 @@ export default defineComponent({
MkTab, MkTab,
MkInfo, MkInfo,
XFollowList: defineAsyncComponent(() => import('./follow-list.vue')), XFollowList: defineAsyncComponent(() => import('./follow-list.vue')),
XReactions: defineAsyncComponent(() => import('./reactions.vue')),
XClips: defineAsyncComponent(() => import('./clips.vue')), XClips: defineAsyncComponent(() => import('./clips.vue')),
XPages: defineAsyncComponent(() => import('./pages.vue')), XPages: defineAsyncComponent(() => import('./pages.vue')),
XGallery: defineAsyncComponent(() => import('./gallery.vue')), XGallery: defineAsyncComponent(() => import('./gallery.vue')),
@ -268,7 +270,12 @@ export default defineComponent({
title: this.$ts.overview, title: this.$ts.overview,
icon: 'fas fa-home', icon: 'fas fa-home',
onClick: () => { this.$router.push('/@' + getAcct(this.user)); }, onClick: () => { this.$router.push('/@' + getAcct(this.user)); },
}, { }, ...(this.$i && (this.$i.id === this.user.id)) || this.user.publicReactions ? [{
active: this.page === 'reactions',
title: this.$ts.reaction,
icon: 'fas fa-laugh',
onClick: () => { this.$router.push('/@' + getAcct(this.user) + '/reactions'); },
}] : [], {
active: this.page === 'clips', active: this.page === 'clips',
title: this.$ts.clips, title: this.$ts.clips,
icon: 'fas fa-paperclip', icon: 'fas fa-paperclip',
@ -827,7 +834,7 @@ export default defineComponent({
} }
} }
._flat_ .ftskorzw.narrow { ._fitSide_ .ftskorzw.narrow {
> .profile { > .profile {
> .warn { > .warn {
margin: 0; margin: 0;

View file

@ -10,7 +10,6 @@
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import MkPagePreview from '@client/components/page-preview.vue'; import MkPagePreview from '@client/components/page-preview.vue';
import MkPagination from '@client/components/ui/pagination.vue'; import MkPagination from '@client/components/ui/pagination.vue';
import { userPage, acct } from '@client/filters/user';
export default defineComponent({ export default defineComponent({
components: { components: {
@ -41,12 +40,6 @@ export default defineComponent({
user() { user() {
this.$refs.list.reload(); this.$refs.list.reload();
} }
},
methods: {
userPage,
acct
} }
}); });
</script> </script>

View file

@ -0,0 +1,81 @@
<template>
<div>
<MkPagination :pagination="pagination" #default="{items}" ref="list">
<div v-for="item in items" :key="item.id" :to="`/clips/${item.id}`" class="item _panel _gap afdcfbfb">
<div class="header">
<MkAvatar class="avatar" :user="user"/>
<MkReactionIcon class="reaction" :reaction="item.type" :custom-emojis="item.note.emojis" :no-style="true"/>
<MkTime :time="item.createdAt" class="createdAt"/>
</div>
<MkNote :note="item.note" @update:note="updated(note, $event)" :key="item.id"/>
</div>
</MkPagination>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import MkPagination from '@client/components/ui/pagination.vue';
import MkNote from '@client/components/note.vue';
import MkReactionIcon from '@client/components/reaction-icon.vue';
export default defineComponent({
components: {
MkPagination,
MkNote,
MkReactionIcon,
},
props: {
user: {
type: Object,
required: true
},
},
data() {
return {
pagination: {
endpoint: 'users/reactions',
limit: 20,
params: {
userId: this.user.id,
}
},
};
},
watch: {
user() {
this.$refs.list.reload();
}
},
});
</script>
<style lang="scss" scoped>
.afdcfbfb {
> .header {
display: flex;
align-items: center;
padding: 8px 16px;
margin-bottom: 8px;
border-bottom: solid 2px var(--divider);
> .avatar {
width: 24px;
height: 24px;
margin-right: 8px;
}
> .reaction {
width: 32px;
height: 32px;
}
> .createdAt {
margin-left: auto;
}
}
}
</style>

View file

@ -20,6 +20,7 @@ export const builtinThemes = [
require('@client/themes/l-apricot.json5'), require('@client/themes/l-apricot.json5'),
require('@client/themes/l-rainy.json5'), require('@client/themes/l-rainy.json5'),
require('@client/themes/l-vivid.json5'), require('@client/themes/l-vivid.json5'),
require('@client/themes/l-sushi.json5'),
require('@client/themes/d-dark.json5'), require('@client/themes/d-dark.json5'),
require('@client/themes/d-persimmon.json5'), require('@client/themes/d-persimmon.json5'),

View file

@ -380,7 +380,7 @@ hr {
} }
} }
._flat_ { ._fitSide_ {
--root-margin: 0px; --root-margin: 0px;
--baseContentWidth: 100%; --baseContentWidth: 100%;
--panelBorder: none; --panelBorder: none;

View file

@ -0,0 +1,18 @@
{
id: '213273e5-7d20-d5f0-6e36-1b6a4f67115c',
name: 'Mi Sushi Light',
author: 'syuilo',
base: 'light',
props: {
accent: '#e36749',
bg: '#f0eee9',
fg: '#5f5f5f',
renote: '@accent',
link: '@accent',
mention: '@accent',
hashtag: '#229e82',
},
}

View file

@ -3,7 +3,7 @@
<header class="header" @contextmenu.prevent.stop="onContextmenu"> <header class="header" @contextmenu.prevent.stop="onContextmenu">
<MkHeader class="title" :info="pageInfo" :center="false"/> <MkHeader class="title" :info="pageInfo" :center="false"/>
</header> </header>
<component :is="component" v-bind="props" :ref="changePage" class="body _flat_"/> <component :is="component" v-bind="props" :ref="changePage" class="body _fitSide_"/>
</div> </div>
</template> </template>

View file

@ -7,7 +7,7 @@
</template> </template>
</template> </template>
<router-view v-slot="{ Component }" class="_flat_"> <router-view v-slot="{ Component }" class="_fitSide_">
<transition> <transition>
<keep-alive :include="['timeline']"> <keep-alive :include="['timeline']">
<component :is="Component" :ref="changePage" @contextmenu.stop="onContextmenu"/> <component :is="Component" :ref="changePage" @contextmenu.stop="onContextmenu"/>

View file

@ -29,7 +29,7 @@
<MkAvatar :user="$i" class="avatar"/><MkAcct class="acct" :user="$i"/> <MkAvatar :user="$i" class="avatar"/><MkAcct class="acct" :user="$i"/>
</button> </button>
<div class="post" @click="post"> <div class="post" @click="post">
<MkButton class="button" primary full rounded> <MkButton class="button" gradate full rounded>
<i class="fas fa-pencil-alt fa-fw"></i> <i class="fas fa-pencil-alt fa-fw"></i>
</MkButton> </MkButton>
</div> </div>

View file

@ -13,7 +13,7 @@
</template> </template>
<main class="main" @contextmenu.stop="onContextmenu" :style="{ background: pageInfo?.bg }"> <main class="main" @contextmenu.stop="onContextmenu" :style="{ background: pageInfo?.bg }">
<div class="content" :class="{ _flat_: !fullView }"> <div class="content" :class="{ _fitSide_: !fullView }">
<router-view v-slot="{ Component }"> <router-view v-slot="{ Component }">
<transition :name="$store.state.animation ? 'page' : ''" mode="out-in" @enter="onTransition"> <transition :name="$store.state.animation ? 'page' : ''" mode="out-in" @enter="onTransition">
<keep-alive :include="['timeline']"> <keep-alive :include="['timeline']">

View file

@ -3,7 +3,7 @@
<template #header><i class="fas fa-bell"></i>{{ $ts.notifications }}</template> <template #header><i class="fas fa-bell"></i>{{ $ts.notifications }}</template>
<template #func><button @click="configure()" class="_button"><i class="fas fa-cog"></i></button></template> <template #func><button @click="configure()" class="_button"><i class="fas fa-cog"></i></button></template>
<div class="_flat_"> <div class="_fitSide_">
<XNotifications :include-types="props.includingTypes"/> <XNotifications :include-types="props.includingTypes"/>
</div> </div>
</MkContainer> </MkContainer>

View file

@ -3,5 +3,5 @@ AiScript is a scripting language for Misskey.
<div class="info"> AiScript is open source and hosted in a separate repository from Misskey. </a></div> <div class="info"> AiScript is open source and hosted in a separate repository from Misskey. </a></div>
## 使い方 ## Usage
AiScript documentation such as syntax and built-in functions can be found [here](https://github.com/syuilo/aiscript/tree/master/docs). AiScript documentation such as syntax and built-in functions can be found [here](https://github.com/syuilo/aiscript/tree/master/docs).

View file

@ -4,7 +4,7 @@ MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス
APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。 APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。
## アクセストークンの取得 ## Obtain an access token
基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。 基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。
* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む * 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む
@ -20,7 +20,7 @@ APIを使い始めるには、まずアクセストークンを取得する必
#### Step 1 #### Step 1
UUIDを生成する。以後これをセッションIDと呼びます。 Generate UUID.以後これをセッションIDと呼びます。
> このセッションIDは毎回生成し、使いまわさないようにしてください。 > このセッションIDは毎回生成し、使いまわさないようにしてください。
@ -30,14 +30,14 @@ UUIDを生成する。以後これをセッションIDと呼びます。
> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` > 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f`
表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます: 表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます:
* `name` ... アプリケーション名 * `name` ... App name
* > 例: `MissDeck` * > 例: `MissDeck`
* `icon` ... アプリケーションのアイコン画像URL * `icon` ... App icon URL
* > 例: `https://missdeck.example.com/icon.png` * > 例: `https://missdeck.example.com/icon.png`
* `callback` ... 認証が終わった後にリダイレクトするURL * `callback` ... 認証が終わった後にリダイレクトするURL
* > 例: `https://missdeck.example.com/callback` * > 例: `https://missdeck.example.com/callback`
* リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます * リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます
* `permission` ... アプリケーションが要求する権限 * `permission` ... App permissions
* > 例: `write:notes,write:following,read:drive` * > 例: `write:notes,write:following,read:drive`
* 要求する権限を`,`で区切って列挙します * 要求する権限を`,`で区切って列挙します
* どのような権限があるかは[APIリファレンス](/api-doc)で確認できます * どのような権限があるかは[APIリファレンス](/api-doc)で確認できます
@ -46,13 +46,13 @@ UUIDを生成する。以後これをセッションIDと呼びます。
ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。 ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。
レスポンスに含まれるプロパティ: レスポンスに含まれるプロパティ:
* `token` ... ユーザーのアクセストークン * `token` ... User access token
* `user` ... ユーザーの情報 * `user` ... User info
[「APIの使い方」へ進む](#APIの使い方) [「APIの使い方」へ進む](#APIの使い方)
## APIの使い方 ## API usage
**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。 **APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。There is no REST support.** アクセストークンは、`i`というパラメータ名でリクエストに含めます。
* [APIリファレンス](/api-doc) * [API Reference](/api-doc)
* [ストリーミングAPI](./stream) * [Streaming API](./stream)

View file

@ -1,20 +1,20 @@
# プラグインの作成 # New Plugin
Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。 Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。
## Metadata ## Metadata
プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。 プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。
### name ### name
プラグイン名 Plugin name
### author ### author
プラグイン作者 Plugin author
### version ### version
プラグインバージョン。数値を指定してください。 プラグインバージョン。A number must be specified.
### description ### description
プラグインの説明 Plugin description
### permissions ### permissions
プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。 プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。
@ -34,7 +34,7 @@ Misskey Webクライアントのプラグイン機能を使うと、クライア
#### default #### default
設定のデフォルト値 設定のデフォルト値
## APIリファレンス ## API Reference
AiScript標準で組み込まれているAPIは掲載しません。 AiScript標準で組み込まれているAPIは掲載しません。
### Mk:dialog(title text type) ### Mk:dialog(title text type)

View file

@ -1,4 +1,4 @@
# Botの作成 # Create a bot
[Misskey API](./api)を利用してBotの開発が可能です。 また、いくつかのBot実装が公開されているため、ぜひ参考にしてください。 [Misskey API](./api)を利用してBotの開発が可能です。 また、いくつかのBot実装が公開されているため、ぜひ参考にしてください。
- [syuilo/ai](https://github.com/syuilo/ai) ... Node.js上で動く、TypeScript製Bot実装 - [syuilo/ai](https://github.com/syuilo/ai) ... Node.js上で動く、TypeScript製Bot実装

View file

@ -1,4 +1,4 @@
# ストリーミングAPI # Streaming API
ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。 ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。

View file

@ -73,7 +73,7 @@ A feature allowing users to organize the files they have uploaded to Misskey.For
## Notes ## Notes
Content which may include text, images, surveys and others that has been posted to Misskey.For details, see [here.](../features/note) Content which may include text, images, surveys and others that has been posted to Misskey.For details, see [here.](../features/note)
## Misskist ## Misskeyist
Users of Misskey. Users of Misskey.
## Moderator ## Moderator

View file

@ -34,7 +34,7 @@ A blinking light indicates unread content.In cases where this light won't go awa
Followers-only notes cannot be renoted. Followers-only notes cannot be renoted.
## Specific parts of the UI are not being displayed ## Specific parts of the UI are not being displayed
Problems like these can arise if you are using an Adblocker.Please turn these off on Misskey. Problems like these can arise if you are using an Adblocker. For an optimized experience on Misskey, please turn it off.
## Some parts of the UI are untranslated ## Some parts of the UI are untranslated
In most cases, this is simply a matter of the translation not having been done yet instead of being a bug.Please wait until the translation of this area has been completed. You can alternatively also [participate in translation](./misskey) yourself. In most cases, this is simply a matter of the translation not having been done yet instead of being a bug.Please wait until the translation of this area has been completed. You can alternatively also [participate in translation](./misskey) yourself.

View file

@ -1,4 +1,4 @@
# よくある質問 # Oftaj demandoj
ここでは、サーバー管理者向けのよくある質問を掲載しています。 ここでは、サーバー管理者向けのよくある質問を掲載しています。
## デフォルトテーマを設定したい ## デフォルトテーマを設定したい

View file

@ -1,4 +1,4 @@
# プラグインの作成 # Krei kromaĵo
Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。 Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。
## Metadatumoj ## Metadatumoj

View file

@ -1,4 +1,4 @@
# ストリーミングAPI # API de Flui
ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。 ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。

View file

@ -1,4 +1,4 @@
# Preferataĵoj # Preferaĵoj
[ノート](./node)をお気に入りとして登録できる機能です。 お気に入り登録したノートは、[お気に入りページ](./my/favorites)で一覧することができます。 お気に入りに登録したことは相手に通知されず、お気に入りは自分しか見ることができません。 [ノート](./node)をお気に入りとして登録できる機能です。 お気に入り登録したノートは、[お気に入りページ](./my/favorites)で一覧することができます。 お気に入りに登録したことは相手に通知されず、お気に入りは自分しか見ることができません。
ノートをお気に入り登録するには、ノートメニューの「お気に入り」を押します。お気に入り解除するには、ノートメニューの「お気に入り解除」を押します。 ノートをお気に入り登録するには、ノートメニューの「お気に入り」を押します。お気に入り解除するには、ノートメニューの「お気に入り解除」を押します。

View file

@ -4,21 +4,21 @@
これらのショートカットは基本的にどこでも使えます。 これらのショートカットは基本的にどこでも使えます。
<table> <table>
<thead> <thead>
<tr><th>Fulmoklavoj</th><th>効果</th><th>由来</th></tr> <tr><th>Fulmoklavoj</th><th>Rezultato</th><th>Deveno (angla)</th></tr>
</thead> </thead>
<tbody> <tbody>
<tr><td><kbd class="key">P</kbd>, <kbd class="key">N</kbd></td><td>Skribi novan noton</td><td><b>P</b>ost, <b>N</b>ew, <b>N</b>ote</td></tr> <tr><td><kbd class="key">P</kbd>, <kbd class="key">N</kbd></td><td>Skribi novan noton</td><td><b>P</b>ost, <b>N</b>ew, <b>N</b>ote</td></tr>
<tr><td><kbd class="key">T</kbd></td><td>タイムラインの最も新しい投稿にフォーカス</td><td><b>T</b>imeline, <b>T</b>op</td></tr> <tr><td><kbd class="key">T</kbd></td><td>タイムラインの最も新しい投稿にフォーカス</td><td><b>T</b>imeline, <b>T</b>op</td></tr>
<tr><td><kbd class="group"><kbd class="key">Shift</kbd> + <kbd class="key">N</kbd></kbd></td><td>Malfermi sekcio de sciigoj</td><td><b>N</b>otifications</td></tr> <tr><td><kbd class="group"><kbd class="key">Shift</kbd> + <kbd class="key">N</kbd></kbd></td><td>Malfermi sekcio de sciigoj</td><td><b>N</b>otifications</td></tr>
<tr><td><kbd class="key">S</kbd></td><td>Serĉi</td><td><b>S</b>earch</td></tr> <tr><td><kbd class="key">S</kbd></td><td>Serĉi</td><td><b>S</b>earch</td></tr>
<tr><td><kbd class="key">H</kbd>, <kbd class="key">?</kbd></td><td>ヘルプを表示</td><td><b>H</b>elp</td></tr> <tr><td><kbd class="key">H</kbd>, <kbd class="key">?</kbd></td><td>Montru helpon</td><td><b>H</b>elp</td></tr>
</tbody> </tbody>
</table> </table>
## 投稿にフォーカスされた状態 ## 投稿にフォーカスされた状態
<table> <table>
<thead> <thead>
<tr><th>Fulmoklavoj</th><th>効果</th><th>Deveno (angla)</th></tr> <tr><th>Fulmoklavoj</th><th>Rezultato</th><th>Deveno (angla)</th></tr>
</thead> </thead>
<tbody> <tbody>
<tr><td><kbd class="key"></kbd>, <kbd class="key">K</kbd>, <kbd class="group"><kbd class="key">Shift</kbd> + <kbd class="key">Tab</kbd></kbd></td><td>上の投稿にフォーカスを移動</td><td>-</td></tr> <tr><td><kbd class="key"></kbd>, <kbd class="key">K</kbd>, <kbd class="group"><kbd class="key">Shift</kbd> + <kbd class="key">Tab</kbd></kbd></td><td>上の投稿にフォーカスを移動</td><td>-</td></tr>
@ -28,7 +28,7 @@
<tr><td><kbd class="group"><kbd class="key">Ctrl</kbd> + <kbd class="key">Q</kbd></kbd></td><td>Tuj plusendos (sen la fasado)</td><td>-</td></tr> <tr><td><kbd class="group"><kbd class="key">Ctrl</kbd> + <kbd class="key">Q</kbd></kbd></td><td>Tuj plusendos (sen la fasado)</td><td>-</td></tr>
<tr><td><kbd class="key">E</kbd>, <kbd class="key">A</kbd>, <kbd class="key">+</kbd></td><td>リアクションフォームを開く</td><td><b>E</b>mote, re<b>A</b>ction</td></tr> <tr><td><kbd class="key">E</kbd>, <kbd class="key">A</kbd>, <kbd class="key">+</kbd></td><td>リアクションフォームを開く</td><td><b>E</b>mote, re<b>A</b>ction</td></tr>
<tr><td><kbd class="key">0</kbd>-<kbd class="key">9</kbd></td><td>数字に対応したリアクションをする(対応については後述)</td><td>-</td></tr> <tr><td><kbd class="key">0</kbd>-<kbd class="key">9</kbd></td><td>数字に対応したリアクションをする(対応については後述)</td><td>-</td></tr>
<tr><td><kbd class="key">F</kbd>, <kbd class="key">B</kbd></td><td>Aldoni vian liston de preferaĵoj</td><td><b>F</b>avorite, <b>B</b>ookmark</td></tr> <tr><td><kbd class="key">F</kbd>, <kbd class="key">B</kbd></td><td>Aldoni al vian liston de preferaĵoj</td><td><b>F</b>avorite, <b>B</b>ookmark</td></tr>
<tr><td><kbd class="key">Del</kbd>, <kbd class="group"><kbd class="key">Ctrl</kbd> + <kbd class="key">D</kbd></kbd></td><td>Forviŝi la noton</td><td><b>D</b>elete</tr> <tr><td><kbd class="key">Del</kbd>, <kbd class="group"><kbd class="key">Ctrl</kbd> + <kbd class="key">D</kbd></kbd></td><td>Forviŝi la noton</td><td><b>D</b>elete</tr>
<tr><td><kbd class="key">M</kbd>, <kbd class="key">O</kbd></td><td>Malfelmi poŝtaĵan menuon</td><td><b>M</b>ore, <b>O</b>ther</td></tr> <tr><td><kbd class="key">M</kbd>, <kbd class="key">O</kbd></td><td>Malfelmi poŝtaĵan menuon</td><td><b>M</b>ore, <b>O</b>ther</td></tr>
<tr><td><kbd class="key">S</kbd></td><td>CWで隠された部分を表示 or 隠す</td><td><b>S</b>how, <b>S</b>ee</td></tr> <tr><td><kbd class="key">S</kbd></td><td>CWで隠された部分を表示 or 隠す</td><td><b>S</b>how, <b>S</b>ee</td></tr>
@ -48,11 +48,11 @@
</tbody> </tbody>
</table> </table>
## リアクションフォーム ## Elektilo de reago
デフォルトで「👍」にフォーカスが当たっている状態です。 デフォルトで「👍」にフォーカスが当たっている状態です。
<table> <table>
<thead> <thead>
<tr><th>Fulmoklavoj</th><th>効果</th><th>Deveno (angla)</th></tr> <tr><th>Fulmoklavoj</th><th>Rezultato</th><th>Deveno (angla)</th></tr>
</thead> </thead>
<tbody> <tbody>
<tr><td><kbd class="key"></kbd>, <kbd class="key">K</kbd></td><td>上のリアクションにフォーカスを移動</td><td>-</td></tr> <tr><td><kbd class="key"></kbd>, <kbd class="key">K</kbd></td><td>上のリアクションにフォーカスを移動</td><td>-</td></tr>

View file

@ -2,10 +2,10 @@
MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます。 MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます。
## MFMが使用可能な場所の例 ## MFMが使用可能な場所の例
- ノート本文 - Teksto de notoj
- CW注釈 - CW注釈
- Nomo de uzanto - La nomo de uzantoj
- Profilo de uzanto - La sinprezento de profiloj
## Informoj por programistoj ## Informoj por programistoj
MFMのパーサー実装はライブラリとして公開されており、簡単にクライアントにMFMを組み込むことが可能です。 MFMのパーサー実装はライブラリとして公開されており、簡単にクライアントにMFMを組み込むことが可能です。

View file

@ -1,5 +1,5 @@
# Notoj # Notoj
ートは、Misskeyに投稿される、文章、ファイル、アンケートなどを含むコンテンツで、Misskeyの中心的概念です。また、そのートを作成する行為自体もートと呼ばれます。 Notoj estas centraj konceptoj en Misskey kaj enhavoj kiuj konsistas el teksto, bildoj, dosieroj, balotujo k.t.p.Ankaŭ krei notojn estas nomata "noto" same kiel ili
ノートが作成されると、[タイムライン](./timeline)に追加され、自分の[フォロワー](./follow)やサーバーのユーザーが見れるようになります。 ノートが作成されると、[タイムライン](./timeline)に追加され、自分の[フォロワー](./follow)やサーバーのユーザーが見れるようになります。
@ -7,14 +7,14 @@
ノートを[お気に入り](./favorite)登録することで、後で簡単に見返すことができます。 ノートを[お気に入り](./favorite)登録することで、後で簡単に見返すことができます。
## ノートを作成する ## Skribi notojn
ノートを作成するには、画面上にある鉛筆マークのボタンを押して、作成フォームを開きます。作成フォームに内容を入力し、「ノート」ボタンを押すことでノートが作成されます。 ノートには、画像、動画など任意のファイルや、[アンケート](./poll)を添付することができます。また、本文中には[MFM](./mfm)が使用でき、[メンション](./mention)や[ハッシュタグ](./hashtag)を含めることもできます。 他にも、CWや公開範囲といった設定も行えます(詳細は後述)。 ノートを作成するには、画面上にある鉛筆マークのボタンを押して、作成フォームを開きます。作成フォームに内容を入力し、「ノート」ボタンを押すことでノートが作成されます。 ノートには、画像、動画など任意のファイルや、[アンケート](./poll)を添付することができます。また、本文中には[MFM](./mfm)が使用でき、[メンション](./mention)や[ハッシュタグ](./hashtag)を含めることもできます。 他にも、CWや公開範囲といった設定も行えます(詳細は後述)。
<div class="info"> コンピューターのクリップボードに画像データがある状態で、フォーム内のテキストボックスにペーストするとその画像を添付することができます。</div> <div class="info"> コンピューターのクリップボードに画像データがある状態で、フォーム内のテキストボックスにペーストするとその画像を添付することができます。</div>
<div class="info"> テキストボックス内で<kbd class="key">Ctrl + Enter</kbd>を押すことでも投稿できます。</div> <div class="info"> テキストボックス内で<kbd class="key">Ctrl + Enter</kbd>を押すことでも投稿できます。</div>
## Plusendi la noton ## Plusendi noton
既にあるートを引用、もしくはそのートを新しいートとして共有する行為、またそれによって作成されたートをRenoteと呼びます。 自分がフォローしているユーザーの、気に入ったノートを自分のフォロワーに共有したい場合や、過去の自分のノートを再度共有したい場合に使います。 同じートに対して無制限にRenoteを行うことができますが、あまり連続して使用すると迷惑になる場合もあるので、注意しましょう。 既にあるートを引用、もしくはそのートを新しいートとして共有する行為、またそれによって作成されたートをRenoteと呼びます。 自分がフォローしているユーザーの、気に入ったノートを自分のフォロワーに共有したい場合や、過去の自分のノートを再度共有したい場合に使います。 同じートに対して無制限にRenoteを行うことができますが、あまり連続して使用すると迷惑になる場合もあるので、注意しましょう。
<div class="warn">⚠️ 公開範囲がフォロワーやダイレクトのートはRenoteできません</div> <div class="warn">⚠️ Se oni sendas notojn nur al sekvantoj aŭ rekte, iliaj ne estas plusendeblaj.</div>
Renoteを削除するには、Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 Renoteを削除するには、Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。
@ -31,10 +31,10 @@ Contents Warningの略で、ートの内容を、閲覧者の操作なしに
### Hejma ### Hejma
全ての人に対してノートが公開されますが、フォロワー以外のローカルタイムライン、ソーシャルタイムライン、グローバルタイムラインにはノートは流れません。 全ての人に対してノートが公開されますが、フォロワー以外のローカルタイムライン、ソーシャルタイムライン、グローバルタイムラインにはノートは流れません。
### Sekvantoj ### Nur al sekvantoj
自分のフォロワーに対してのみノートを公開します。フォロワーの全てのタイムラインに流れます。 Viaj notoj estos senditaj nur al viaj sekvantoj.La noto aperos sur ĉiuj templinioj de viaj sekvantoj.
### Rekta ### Rekte
指定したユーザーに対してのみノートを公開します。指定したユーザーの全てのタイムラインに流れます。 指定したユーザーに対してのみノートを公開します。指定したユーザーの全てのタイムラインに流れます。
### 「ローカルのみ」オプション ### 「ローカルのみ」オプション
@ -42,13 +42,13 @@ Contents Warningの略で、ートの内容を、閲覧者の操作なしに
### 公開範囲の比較 ### 公開範囲の比較
<table> <table>
<tr><th></th><th>Publika</th><th>Hejma</th><th>Sekvantoj</th><th>Rekta</th></tr> <tr><th></th><th>Publika</th><th>Hejma</th><th>Nur al sekvantoj</th><th>Rekte</th></tr>
<tr><th>フォロワーのLTL/STL/GTL</th><td></td><td></td><td></td><td></td></tr> <tr><th>フォロワーのLTL/STL/GTL</th><td></td><td></td><td></td><td></td></tr>
<tr><th>非フォロワーのLTL/STL/GTL</th><td></td><td></td><td></td><td></td></tr> <tr><th>非フォロワーのLTL/STL/GTL</th><td></td><td></td><td></td><td></td></tr>
</table> </table>
## Alpingli al la profilo ## Alpingli sur profilo
ノートをピン留めすると、ユーザーページに常にそのノートを表示しておくことができます。 ノートのメニューを開き、「ピン留め」を選択してピン留めできます。 複数のノートをピン留めできます。 ノートをピン留めすると、ユーザーページに常にそのノートを表示しておくことができます。 ノートのメニューを開き、「ピン留め」を選択してピン留めできます。 複数のノートをピン留めできます。
## Observi ## Observi
Vi povas ricevi sciigojn pri reagoj, respondoj, ktp al noto, kiuj ne apartenas al vi. Por observu, malfermu respektivan menuon de noto, kaj elektu la "Observi" el ĝi. Vi povas ricevi tiuj sciigoj pri reagoj, respondoj, k.t.p al noto kiuj ne apartenas al vi estas ankaŭ ricevebla. Por komenci tion elektu la "Observi" el la menuon kuntekstan de la notoj respektivaj.

View file

@ -1,4 +1,4 @@
# よくある質問 # Oftaj demandoj
ここでは利用上のよくある質問について掲載しています。 Misskeyのプロジェクト自体についてのよくある質問は[こちら](./misskey)に掲載されています。 ここでは利用上のよくある質問について掲載しています。 Misskeyのプロジェクト自体についてのよくある質問は[こちら](./misskey)に掲載されています。
## iOS/Androidのアプリはありますか ## iOS/Androidのアプリはありますか

View file

@ -1,4 +1,4 @@
# 用語集 # Glosaro
Misskeyに関する用語集です。 Misskeyに関する用語集です。
## ActivityPub ## ActivityPub
@ -49,7 +49,7 @@ Ai estas oficiala maskoto de Misskey.
## Nodo ## Nodo
todo todo
## Personecigitaj emoĵioj ## Emoĵioj personecigitaj
サーバーで用意された絵文字。カスタム絵文字ではない通常の絵文字は「Unicode絵文字」と区別して呼ばれる。 サーバーで用意された絵文字。カスタム絵文字ではない通常の絵文字は「Unicode絵文字」と区別して呼ばれる。
## Ŝaltpodio ## Ŝaltpodio
@ -68,10 +68,10 @@ todo
アカウントが使用不可に設定されている状態。 アカウントが使用不可に設定されている状態。
## Disko ## Disko
Misskeyにアップロードしたファイルを管理する機能。詳細は[こちら。](../features/drive) Funkcio ebligas al uzantoj administri dosierojn kiujn ili alŝutis al Misskey.Rigardu por sciu pli tie[.](../features/drive)
## Notoj ## Notoj
Misskeyに投稿される、文章、ファイル、アンケートなどを含めることができるコンテンツ。Rigardu por sciu pli tie[.](../features/note) Enpoŝtigaĵoj en Misskey kiuj konsistas el teksto, dosiero, balotujo, ktp.Rigardu por sciu pli tie[.](../features/note)
## Miskiisto ## Miskiisto
Uzuloj de Misskey. Uzuloj de Misskey.
@ -82,7 +82,7 @@ Uzuloj de Misskey.
## Transa, Surloka ## Transa, Surloka
他サーバーのことを指します。リモートユーザーといったように接頭辞としても使われます。ローカルの逆です。 他サーバーのことを指します。リモートユーザーといったように接頭辞としても使われます。ローカルの逆です。
## Kunfederado ## Federado
サーバー上で作成された情報が他のサーバーに伝わること。 サーバー上で作成された情報が他のサーバーに伝わること。
## Loka ## Loka

View file

@ -43,7 +43,7 @@ Misskeyはビジネスではなく、利用は無料であるため、収益は
## クレジット ## クレジット
Misskeyの開発者や、Misskeyに寄付をしてくださった方の一覧は[こちら](/about-misskey)で見ることができます。 Misskeyの開発者や、Misskeyに寄付をしてくださった方の一覧は[こちら](/about-misskey)で見ることができます。
## よくある質問 ## Oftaj demandoj
### プロジェクトは何を目指していますか? ### プロジェクトは何を目指していますか?
強いて言うと、漠然的になりますが広く使われる汎用的なプラットフォームになることを目指しています。 Misskeyは他のプロジェクトとは違い、何らかの思想(例えば、反中央集権)やビジョンに基づいて開発が行われているわけではなく、その点ではフラットです。 それが逆に、特定の方向性に縛られないフレキシブルさを生み出すことに繋がっていると感じています。 強いて言うと、漠然的になりますが広く使われる汎用的なプラットフォームになることを目指しています。 Misskeyは他のプロジェクトとは違い、何らかの思想(例えば、反中央集権)やビジョンに基づいて開発が行われているわけではなく、その点ではフラットです。 それが逆に、特定の方向性に縛られないフレキシブルさを生み出すことに繋がっていると感じています。
<!-- TODO: ここにロードマップへのリンク --> <!-- TODO: ここにロードマップへのリンク -->

View file

@ -1,4 +1,4 @@
# トラブルシューティング # Solución de problemas
<div class="info"> <a href="./faq">よくある質問</a>も合わせてお役立てください。</div> <div class="info"> <a href="./faq">よくある質問</a>も合わせてお役立てください。</div>
問題が発生したときは、まずこちらをご確認ください。 該当する項目が無い、もしくは手順を試しても効果がない場合は、サーバーの管理者に連絡するか[不具合を報告](./report-issue)してください。 問題が発生したときは、まずこちらをご確認ください。 該当する項目が無い、もしくは手順を試しても効果がない場合は、サーバーの管理者に連絡するか[不具合を報告](./report-issue)してください。

View file

@ -1,6 +1,6 @@
# Liste des applications tierces # Liste des applications tierces
## クライアント ## Client
todo todo
## 連携サービス ## Services connexes
todo todo

View file

@ -1,65 +1,65 @@
# 用語集 # Glossaire
Misskeyに関する用語集です。 Glossaire des termes utilisés dans Misskey.
## ActivityPub ## ActivityPub
(読み: あくてぃびてぃぱぶ) 分散型を実現するために用いられるプロトコル(仕様)。このプロトコルに則ってサーバー同士通信を行うことで、連合が行われ、Fediverseを形成しています。 Nom du protocole (procédé technique) utilisé par Misskey pour pouvoir fonctionner comme service décentralisé. Ce protocole permet à tous les serveurs l'ayant adopté de communiquer entre eux et de former une sorte de fédération que l'on appelle « Fédiverse ».
## AiScript ## AiScript
(読み: あいすくりぷと) Misskey上で使用できるプログラミング言語です。詳細は[こちら。](../advanced/aiscript) Langage de programmation qui peut être utilisé sur Misskey. [Voir ici pour plus d'informations.](../advanced/aiscript)
## API ## API
(読み: えーぴーあい) Misskeyのサーバーが公開している、プログラムからMisskeyを扱うためのインターフェース。詳細は[こちら。](../advanced/api) (読み: えーぴーあい) Misskeyのサーバーが公開している、プログラムからMisskeyを扱うためのインターフェース。[Voir ici pour plus d'informations. ](../advanced/api)
## Bot ## Bot
(読み: ぼっと) プログラムによって動作しているアカウント。 Anglicisme désignant un compte géré par un programme informatique (vous le trouverez parfois aussi sous le terme de « robot »).
## CW ## CW
(読み: こんてんつわーにんぐ) Contents Warningの略。ートの内容を、操作なしには表示しないようにできる機能。主に長大な内容を隠すためや、ネタバレ防止などに使われます。 Abréviation de « Content Warning » (qui signifie littéralement « alerte de contenu »). Fonctionnalité permettant d'assujettir l'affichage du contenu d'une note à une intervention de l'utilisateur·rice par le biais d'un bouton de masquage automatique. Principalement employée pour cacher le contenu des notes très longues, ou pour éviter de dévoiler publiquement des spoils potentiels, etc.
## Fediverse ## Fédiverse
(読み: ふぇでぃばーす) Misskeyを含む様々な分散型ソフトウェアのサーバーで構成されたネットワーク。 Nom du réseau social fédéré qui rassemble une multitude d'instances appartenant à différents services et dont fait partie Misskey.
## GTL ## FG
グローバルタイムライン(Global TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) Abréviation de « Fil global ». Pour en savoir plus sur les différents fils, [voir ici.](../features/timeline)
## HTL ## FP
ホームタイムライン(Home TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) Abréviation de « Fil principal ». Pour en savoir plus sur les différents fils, [voir ici.](../features/timeline)
## LTL ## FL
ローカルタイムライン(Local TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) Abréviation de « Fil local ». Pour en savoir plus sur les différents fils, [voir ici.](../features/timeline)
## MFM ## MFM
(読み: えむえふえむ) Misskey Flavored Markdownの略で、Misskey上で使用できるマークアップ言語です。詳細は[こちら。](../features/mfm) Abréviation de « Misskey Flavored Markdown », un langage Markdown qui peut être utilisé sur Misskey. [Voir ici pour plus d'informations.](../features/mfm)
## NSFW ## NSFW
(読み: のっとせーふふぉーわーく) Not Safe For Workの略。画像を「閲覧注意」扱いにし、操作なしには表示しないようにすることができる機能。 Abréviation de « Not Safe For Work » (qui signifie littéralement « pas sûr pour le travail »). Fonctionnalité permettant d'avertir que le contenu d'une note n'est pas approprié sur le lieu de travail et d'en assujettir l'affichage à une intervention de l'utilisateur·rice par le biais d'un bouton de masquage automatique.
## Renoter ## Renoter
(読み: りのーと) 既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノート。詳細は[こちら。](../features/note) Il s'agit du fait de citer une note existante ou de partager une note existante dans une nouvelle note. La note créée par l'un de ces deux biais est alors appelée une « Renote ». [Voir ici pour plus d'informations.](../features/note)
## STL ## FS
ソーシャルタイムライン(Social TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) Abréviation de « Fil social ». Pour en savoir plus sur les différents fils, [voir ici.](../features/timeline)
## ## Ai
(読み: あい) Misskeyの看板娘(公式キャラクター)です。 Nom de la mascotte officielle de Misskey. (Le mot japonais, à prononcer « a-i », signifie littéralement « indigo »).
## アクティブユーザー ## Utilisateurices actif·ve·s
インスタンスにアカウントを作っているユーザーのうち、現在も実際にサービスを利用しているユーザーのこと。 Désigne les utilisateur·rice·s, parmi tou·te·s celleux inscrit·e·s sur l'instance, qui utilisent effectivement leur compte au moment présent.
## Instance ## Instance
todo todo
## Émojis personnalisés ## Émojis personnalisés
サーバーで用意された絵文字。カスタム絵文字ではない通常の絵文字は「Unicode絵文字」と区別して呼ばれる。 Désigne les émojis mis à disposition par votre instance. Par opposition, les émojis disponibles par défaut (donc pas « personnalisés ») sont appelés « émojis unicode ».
## コントロールパネル ## Panneau de contrôle
インスタンスの設定画面のこと。 Écran de contrôle des paramètres d'instance.
## Serveurs ## Serveurs
todo todo
## Mettre en sourdine ## Mettre en sourdine
ノートをパブリックな公開範囲で投稿できなくされている状態。モデレーターの判断でユーザーごとに設定されます。詳細は[こちら。](../features/silence) ノートをパブリックな公開範囲で投稿できなくされている状態。モデレーターの判断でユーザーごとに設定されます。[Voir ici pour plus d'informations. ](../features/silence)
## File dattente ## File dattente
アクティビティ配送などを順番に行うためのシステム。 アクティビティ配送などを順番に行うためのシステム。
@ -68,15 +68,15 @@ todo
アカウントが使用不可に設定されている状態。 アカウントが使用不可に設定されている状態。
## Drive ## Drive
Misskeyにアップロードしたファイルを管理する機能。詳細は[こちら。](../features/drive) Fonctionnalité vous permettant de gérer les fichiers que vous avez téléversés sur Misskey. [Voir ici pour plus d'informations. ](../features/drive)
## Notes ## Notes
Misskeyに投稿される、文章、ファイル、アンケートなどを含めることができるコンテンツ。詳細は[こちら。](../features/note) Nom des publications sur Misskey. Leur contenu peut être du texte, mais aussi des fichiers, des enquêtes, etc. [Voir ici pour plus d'informations.](../features/note)
## ミスキスト ## Misskeynaute
Misskeyを使う人のこと。 Désigne les utilisateur·rice·s de Misskey.
## Modérateurs ## Modérateur·rice·s
スパムの凍結およびサイレンスや不適切な投稿の削除など、コミュニティ運営に関する権限を持つユーザー。 スパムの凍結およびサイレンスや不適切な投稿の削除など、コミュニティ運営に関する権限を持つユーザー。
## Distant ## Distant

View file

@ -21,20 +21,20 @@ Essayez les solutions proposées ci-dessous :
- activer l'option « Réduire les animations dans l'interface » dans les paramètres du client - activer l'option « Réduire les animations dans l'interface » dans les paramètres du client
- désactiver l'option « Utiliser un effet de flou pour les modals » dans les paramètres du client - désactiver l'option « Utiliser un effet de flou pour les modals » dans les paramètres du client
- activer l'accélération matérielle dans les paramètres de votre navigateur - activer l'accélération matérielle dans les paramètres de votre navigateur
- お使いのデバイスのスペックを上げる - effectuer les mises à jour de votre appareil.
## UIの一部の表示がおかしい(背景が透明になっている等) ## Certaines parties de l'interface ne s'affichent pas correctement (arrière-plan transparent, etc.)
アップデートによりUIの改修が行われたときに、テーマのキャッシュシステムの影響でそのような表示になることがあります。 クライアントの設定の「キャッシュをクリア」すると直ります。 Cela peut être lié au système de mise en cache du thème lorsqu'une mise à jour visant à améliorer l'interface a eu lieu. Pour résoudre le problème, sélectionnez la touche « Vider le cache » dans les paramètres du client.
<div class="warn">⚠️ 「クライアントの」キャッシュクリアです。「ブラウザの」キャッシュクリアは行わないでください。</div> <div class="warn">⚠️ Attention de bien vider le cache du -client-... et pas celui du -navigateur- !</div>
## 通知やアンテナ等の点滅が消えない ## Les pastilles de notification clignotantes ne disparaissent pas
点滅は、未読のコンテンツがあることを示しています。通常点滅が消えない場合は、コンテンツを遡ると未読なコンテンツが残っています。 すべて既読にしたと思われるのに、それでもなお点滅が続く場合(おそらく不具合と思われます)は設定から強制的にすべて既読扱いにすることができます。 Une pastille clignotante indique la présence de nouveau contenu que vous n'avez pas encore lu. Lorsque cette pastille ne disparaît pas, c'est généralement parce que du contenu laissé non lu a été repoussé par la réception de nouveau contenu. S'il s'avère que vous avez déjà lu le contenu dans sa totalité mais que la pastille continue tout de même de clignoter, il s'agit alors vraisemblablement d'un bug et vous pouvez forcer Misskey à tout marquer comme lu depuis vos paramètres généraux.
## La fonction « Renoter » ne fonctionne pas ## La fonction « Renoter » ne fonctionne pas
Les notes dont l'audience est limitée aux « Abonné·e·s uniquement » ne peuvent pas être renotées. Les notes dont l'audience est limitée aux « Abonné·e·s uniquement » ne peuvent pas être renotées.
## Des éléments spécifiques de l'interface ne s'affichent pas ## Des éléments spécifiques de l'interface ne s'affichent pas
広告ブロッカーを使用しているとそのような不具合が発生することがあります。Misskeyではオフにしてご利用ください。 Ce type de dysfonctionnement survient lorsque vous utilisez des bloqueurs de publicité. Désactivez-les pour profiter d'une expérience optimale sur Misskey.
## Certaines parties de l'interface ne sont pas traduites ## Certaines parties de l'interface ne sont pas traduites
La plupart du temps, cela n'est pas un bug mais simplement un problème de traduction qui n'a pas encore été faite. Merci de patienter jusqu'à ce que la traduction de la portion en question soit achevée. Vous pouvez également [aider à traduire](./misskey) Misskey. La plupart du temps, cela n'est pas un bug mais simplement un problème de traduction qui n'a pas encore été faite. Merci de patienter jusqu'à ce que la traduction de la portion en question soit achevée. Vous pouvez également [aider à traduire](./misskey) Misskey.

View file

@ -50,7 +50,7 @@ MisskeyのストリーミングAPIにはチャンネルという概念があり
} }
``` ```
ここで、 其中:
* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。 * `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。
* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。 * `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。
* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。 * `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。
@ -74,7 +74,7 @@ MisskeyのストリーミングAPIにはチャンネルという概念があり
} }
``` ```
ここで、 其中:
* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。 * `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。
* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。 * `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。
* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。 * `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。
@ -96,7 +96,7 @@ MisskeyのストリーミングAPIにはチャンネルという概念があり
} }
``` ```
ここで、 其中:
* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。 * `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。
* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。 * `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。
* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。 * `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。
@ -113,7 +113,7 @@ MisskeyのストリーミングAPIにはチャンネルという概念があり
} }
``` ```
ここで、 其中:
* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。 * `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。
## ストリームを経由してAPIリクエストする ## ストリームを経由してAPIリクエストする
@ -134,7 +134,7 @@ MisskeyのストリーミングAPIにはチャンネルという概念があり
} }
``` ```
ここで、 其中:
* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 * `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。
* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 * `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。
* `data`には、エンドポイントのパラメータを含めます。 * `data`には、エンドポイントのパラメータを含めます。
@ -154,7 +154,7 @@ APIへリクエストすると、レスポンスがストリームから次の
} }
``` ```
ここで、 其中:
* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 * `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。
* `body`には、レスポンスが含まれています。 * `body`には、レスポンスが含まれています。
@ -181,7 +181,7 @@ Misskeyは投稿のキャプチャと呼ばれる仕組みを提供していま
} }
``` ```
ここで、 其中:
* `id`にキャプチャしたい投稿の`id`を設定します。 * `id`にキャプチャしたい投稿の`id`を設定します。
このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。
@ -202,7 +202,7 @@ Misskeyは投稿のキャプチャと呼ばれる仕組みを提供していま
} }
``` ```
ここで、 其中:
* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。 * `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。
* `body`内の`type`に、イベントの種類が設定されます。 * `body`内の`type`に、イベントの種類が設定されます。
* `body`内の`body`に、イベントの詳細が設定されます。 * `body`内の`body`に、イベントの詳細が設定されます。
@ -285,7 +285,7 @@ Misskeyは投稿のキャプチャと呼ばれる仕組みを提供していま
} }
``` ```
ここで、 其中:
* `id`にキャプチャを解除したい投稿の`id`を設定します。 * `id`にキャプチャを解除したい投稿の`id`を設定します。
このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。

View file

@ -1,2 +1,2 @@
# 关注 # 关注
ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします 当您关注一名用户时,您可以在您的时间线上看到该用户的发帖。但是不包含该用户对其他用户的回复。 要关注一名用户,请点击该用户页面上的“关注”按钮。如果需要取消关注,请再次点击该按钮

View file

@ -1,12 +1,12 @@
# MFM # MFM
MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます MFM是Misskey Flavored Markdown的缩写是一种专用的标记语言可以用在Misskey的任何地方。 MFM中可用的语法可以在[MFM代码速查表](/mfm-cheat-sheet)中找到
## MFMが使用可能な場所の ## 使用 MFM 的位置示
- ノート本 - 帖子正
- CW注释 - CW注释
- ユーザーの名前 - 用户姓名
- ユーザーの自己紹介 - 用户自我介绍
## 開発者向け情報 ## 面向开发者的信息
MFMのパーサー実装はライブラリとして公開されており、簡単にクライアントにMFMを組み込むことが可能です MFM 的解析器实现作为库发布,可以轻松地将 MFM 嵌入到客户端中
- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptパーサー実装 - [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScript的解析器实现

View file

@ -2,7 +2,7 @@ import * as fs from 'fs';
import * as stream from 'stream'; import * as stream from 'stream';
import * as util from 'util'; import * as util from 'util';
import got, * as Got from 'got'; import got, * as Got from 'got';
import { httpAgent, httpsAgent } from './fetch'; import { httpAgent, httpsAgent, StatusError } from './fetch';
import config from '@/config/index'; import config from '@/config/index';
import * as chalk from 'chalk'; import * as chalk from 'chalk';
import Logger from '@/services/logger'; import Logger from '@/services/logger';
@ -37,6 +37,7 @@ export async function downloadUrl(url: string, path: string) {
http: httpAgent, http: httpAgent,
https: httpsAgent, https: httpsAgent,
}, },
http2: false, // default
retry: 0, retry: 0,
}).on('response', (res: Got.Response) => { }).on('response', (res: Got.Response) => {
if ((process.env.NODE_ENV === 'production' || process.env.NODE_ENV === 'test') && !config.proxy && res.ip) { if ((process.env.NODE_ENV === 'production' || process.env.NODE_ENV === 'test') && !config.proxy && res.ip) {
@ -59,17 +60,17 @@ export async function downloadUrl(url: string, path: string) {
logger.warn(`maxSize exceeded (${progress.transferred} > ${maxSize}) on downloadProgress`); logger.warn(`maxSize exceeded (${progress.transferred} > ${maxSize}) on downloadProgress`);
req.destroy(); req.destroy();
} }
}).on('error', (e: any) => {
if (e.name === 'HTTPError') {
const statusCode = e.response?.statusCode;
const statusMessage = e.response?.statusMessage;
e.name = `StatusError`;
e.statusCode = statusCode;
e.message = `${statusCode} ${statusMessage}`;
}
}); });
try {
await pipeline(req, fs.createWriteStream(path)); await pipeline(req, fs.createWriteStream(path));
} catch (e) {
if (e instanceof Got.HTTPError) {
throw new StatusError(`${e.response.statusCode} ${e.response.statusMessage}`, e.response.statusCode, e.response.statusMessage);
} else {
throw e;
}
}
logger.succ(`Download finished: ${chalk.cyan(url)}`); logger.succ(`Download finished: ${chalk.cyan(url)}`);
} }

View file

@ -1,51 +1,62 @@
import * as http from 'http'; import * as http from 'http';
import * as https from 'https'; import * as https from 'https';
import CacheableLookup from 'cacheable-lookup'; import CacheableLookup from 'cacheable-lookup';
import fetch, { HeadersInit } from 'node-fetch'; import fetch from 'node-fetch';
import { HttpProxyAgent, HttpsProxyAgent } from 'hpagent'; import { HttpProxyAgent, HttpsProxyAgent } from 'hpagent';
import config from '@/config/index'; import config from '@/config/index';
import { URL } from 'url'; import { URL } from 'url';
export async function getJson(url: string, accept = 'application/json, */*', timeout = 10000, headers?: HeadersInit) { export async function getJson(url: string, accept = 'application/json, */*', timeout = 10000, headers?: Record<string, string>) {
const res = await fetch(url, { const res = await getResponse({
url,
method: 'GET',
headers: Object.assign({ headers: Object.assign({
'User-Agent': config.userAgent, 'User-Agent': config.userAgent,
Accept: accept Accept: accept
}, headers || {}), }, headers || {}),
timeout, timeout
agent: getAgentByUrl,
}); });
if (!res.ok) {
throw {
name: `StatusError`,
statusCode: res.status,
message: `${res.status} ${res.statusText}`,
};
}
return await res.json(); return await res.json();
} }
export async function getHtml(url: string, accept = 'text/html, */*', timeout = 10000, headers?: HeadersInit) { export async function getHtml(url: string, accept = 'text/html, */*', timeout = 10000, headers?: Record<string, string>) {
const res = await fetch(url, { const res = await getResponse({
url,
method: 'GET',
headers: Object.assign({ headers: Object.assign({
'User-Agent': config.userAgent, 'User-Agent': config.userAgent,
Accept: accept Accept: accept
}, headers || {}), }, headers || {}),
timeout
});
return await res.text();
}
export async function getResponse(args: { url: string, method: string, body?: string, headers: Record<string, string>, timeout?: number, size?: number }) {
const timeout = args?.timeout || 10 * 1000;
const controller = new AbortController();
setTimeout(() => {
controller.abort();
}, timeout * 6);
const res = await fetch(args.url, {
method: args.method,
headers: args.headers,
body: args.body,
timeout, timeout,
size: args?.size || 10 * 1024 * 1024,
agent: getAgentByUrl, agent: getAgentByUrl,
signal: controller.signal,
}); });
if (!res.ok) { if (!res.ok) {
throw { throw new StatusError(`${res.status} ${res.statusText}`, res.status, res.statusText);
name: `StatusError`,
statusCode: res.status,
message: `${res.status} ${res.statusText}`,
};
} }
return await res.text(); return res;
} }
const cache = new CacheableLookup({ const cache = new CacheableLookup({
@ -114,3 +125,17 @@ export function getAgentByUrl(url: URL, bypassProxy = false) {
return url.protocol == 'http:' ? httpAgent : httpsAgent; return url.protocol == 'http:' ? httpAgent : httpsAgent;
} }
} }
export class StatusError extends Error {
public statusCode: number;
public statusMessage?: string;
public isClientError: boolean;
constructor(message: string, statusCode: number, statusMessage?: string) {
super(message);
this.name = 'StatusError';
this.statusCode = statusCode;
this.statusMessage = statusMessage;
this.isClientError = typeof this.statusCode === 'number' && this.statusCode >= 400 && this.statusCode < 500;
}
}

View file

@ -75,6 +75,11 @@ export class UserProfile {
}) })
public emailNotificationTypes: string[]; public emailNotificationTypes: string[];
@Column('boolean', {
default: false,
})
public publicReactions: boolean;
@Column('varchar', { @Column('varchar', {
length: 128, nullable: true, length: 128, nullable: true,
}) })

View file

@ -1,6 +1,6 @@
import { EntityRepository, Repository } from 'typeorm'; import { EntityRepository, Repository } from 'typeorm';
import { NoteReaction } from '@/models/entities/note-reaction'; import { NoteReaction } from '@/models/entities/note-reaction';
import { Users } from '../index'; import { Notes, Users } from '../index';
import { Packed } from '@/misc/schema'; import { Packed } from '@/misc/schema';
import { convertLegacyReaction } from '@/misc/reaction-lib'; import { convertLegacyReaction } from '@/misc/reaction-lib';
import { User } from '@/models/entities/user'; import { User } from '@/models/entities/user';
@ -9,8 +9,15 @@ import { User } from '@/models/entities/user';
export class NoteReactionRepository extends Repository<NoteReaction> { export class NoteReactionRepository extends Repository<NoteReaction> {
public async pack( public async pack(
src: NoteReaction['id'] | NoteReaction, src: NoteReaction['id'] | NoteReaction,
me?: { id: User['id'] } | null | undefined me?: { id: User['id'] } | null | undefined,
options?: {
withNote: boolean;
},
): Promise<Packed<'NoteReaction'>> { ): Promise<Packed<'NoteReaction'>> {
const opts = Object.assign({
withNote: false,
}, options);
const reaction = typeof src === 'object' ? src : await this.findOneOrFail(src); const reaction = typeof src === 'object' ? src : await this.findOneOrFail(src);
return { return {
@ -18,6 +25,9 @@ export class NoteReactionRepository extends Repository<NoteReaction> {
createdAt: reaction.createdAt.toISOString(), createdAt: reaction.createdAt.toISOString(),
user: await Users.pack(reaction.userId, me), user: await Users.pack(reaction.userId, me),
type: convertLegacyReaction(reaction.reaction), type: convertLegacyReaction(reaction.reaction),
...(opts.withNote ? {
note: await Notes.pack(reaction.noteId, me),
} : {})
}; };
} }
} }

View file

@ -231,6 +231,7 @@ export class UserRepository extends Repository<User> {
}), }),
pinnedPageId: profile!.pinnedPageId, pinnedPageId: profile!.pinnedPageId,
pinnedPage: profile!.pinnedPageId ? Pages.pack(profile!.pinnedPageId, me) : null, pinnedPage: profile!.pinnedPageId ? Pages.pack(profile!.pinnedPageId, me) : null,
publicReactions: profile!.publicReactions,
twoFactorEnabled: profile!.twoFactorEnabled, twoFactorEnabled: profile!.twoFactorEnabled,
usePasswordLessLogin: profile!.usePasswordLessLogin, usePasswordLessLogin: profile!.usePasswordLessLogin,
securityKeys: profile!.twoFactorEnabled securityKeys: profile!.twoFactorEnabled

View file

@ -11,6 +11,7 @@ import { toPuny } from '@/misc/convert-host';
import { Cache } from '@/misc/cache'; import { Cache } from '@/misc/cache';
import { Instance } from '@/models/entities/instance'; import { Instance } from '@/models/entities/instance';
import { DeliverJobData } from '../types'; import { DeliverJobData } from '../types';
import { StatusError } from '@/misc/fetch';
const logger = new Logger('deliver'); const logger = new Logger('deliver');
@ -68,16 +69,16 @@ export default async (job: Bull.Job<DeliverJobData>) => {
registerOrFetchInstanceDoc(host).then(i => { registerOrFetchInstanceDoc(host).then(i => {
Instances.update(i.id, { Instances.update(i.id, {
latestRequestSentAt: new Date(), latestRequestSentAt: new Date(),
latestStatus: res != null && res.hasOwnProperty('statusCode') ? res.statusCode : null, latestStatus: res instanceof StatusError ? res.statusCode : null,
isNotResponding: true isNotResponding: true
}); });
instanceChart.requestSent(i.host, false); instanceChart.requestSent(i.host, false);
}); });
if (res != null && res.hasOwnProperty('statusCode')) { if (res instanceof StatusError) {
// 4xx // 4xx
if (res.statusCode >= 400 && res.statusCode < 500) { if (res.isClientError) {
// HTTPステータスコード4xxはクライアントエラーであり、それはつまり // HTTPステータスコード4xxはクライアントエラーであり、それはつまり
// 何回再送しても成功することはないということなのでエラーにはしないでおく // 何回再送しても成功することはないということなのでエラーにはしないでおく
return `${res.statusCode} ${res.statusMessage}`; return `${res.statusCode} ${res.statusMessage}`;

View file

@ -14,6 +14,7 @@ import { InboxJobData } from '../types';
import DbResolver from '@/remote/activitypub/db-resolver'; import DbResolver from '@/remote/activitypub/db-resolver';
import { resolvePerson } from '@/remote/activitypub/models/person'; import { resolvePerson } from '@/remote/activitypub/models/person';
import { LdSignature } from '@/remote/activitypub/misc/ld-signature'; import { LdSignature } from '@/remote/activitypub/misc/ld-signature';
import { StatusError } from '@/misc/fetch';
const logger = new Logger('inbox'); const logger = new Logger('inbox');
@ -53,7 +54,7 @@ export default async (job: Bull.Job<InboxJobData>): Promise<string> => {
authUser = await dbResolver.getAuthUserFromApId(getApId(activity.actor)); authUser = await dbResolver.getAuthUserFromApId(getApId(activity.actor));
} catch (e) { } catch (e) {
// 対象が4xxならスキップ // 対象が4xxならスキップ
if (e.statusCode >= 400 && e.statusCode < 500) { if (e instanceof StatusError && e.isClientError) {
return `skip: Ignored deleted actors on both ends ${activity.actor} - ${e.statusCode}`; return `skip: Ignored deleted actors on both ends ${activity.actor} - ${e.statusCode}`;
} }
throw `Error in actor ${activity.actor} - ${e.statusCode || e}`; throw `Error in actor ${activity.actor} - ${e.statusCode || e}`;

View file

@ -0,0 +1,104 @@
import * as crypto from 'crypto';
import { URL } from 'url';
type Request = {
url: string;
method: string;
headers: Record<string, string>;
};
type PrivateKey = {
privateKeyPem: string;
keyId: string;
};
export function createSignedPost(args: { key: PrivateKey, url: string, body: string, additionalHeaders: Record<string, string> }) {
const u = new URL(args.url);
const digestHeader = `SHA-256=${crypto.createHash('sha256').update(args.body).digest('base64')}`;
const request: Request = {
url: u.href,
method: 'POST',
headers: objectAssignWithLcKey({
'Date': new Date().toUTCString(),
'Host': u.hostname,
'Content-Type': 'application/activity+json',
'Digest': digestHeader,
}, args.additionalHeaders),
};
const result = signToRequest(request, args.key, ['(request-target)', 'date', 'host', 'digest']);
return {
request,
signingString: result.signingString,
signature: result.signature,
signatureHeader: result.signatureHeader,
};
}
export function createSignedGet(args: { key: PrivateKey, url: string, additionalHeaders: Record<string, string> }) {
const u = new URL(args.url);
const request: Request = {
url: u.href,
method: 'GET',
headers: objectAssignWithLcKey({
'Accept': 'application/activity+json, application/ld+json',
'Date': new Date().toUTCString(),
'Host': new URL(args.url).hostname,
}, args.additionalHeaders),
};
const result = signToRequest(request, args.key, ['(request-target)', 'date', 'host', 'accept']);
return {
request,
signingString: result.signingString,
signature: result.signature,
signatureHeader: result.signatureHeader,
};
}
function signToRequest(request: Request, key: PrivateKey, includeHeaders: string[]) {
const signingString = genSigningString(request, includeHeaders);
const signature = crypto.sign('sha256', Buffer.from(signingString), key.privateKeyPem).toString('base64');
const signatureHeader = `keyId="${key.keyId}",algorithm="rsa-sha256",headers="${includeHeaders.join(' ')}",signature="${signature}"`;
request.headers = objectAssignWithLcKey(request.headers, {
Signature: signatureHeader
});
return {
request,
signingString,
signature,
signatureHeader,
};
}
function genSigningString(request: Request, includeHeaders: string[]) {
request.headers = lcObjectKey(request.headers);
const results: string[] = [];
for (const key of includeHeaders.map(x => x.toLowerCase())) {
if (key === '(request-target)') {
results.push(`(request-target): ${request.method.toLowerCase()} ${new URL(request.url).pathname}`);
} else {
results.push(`${key}: ${request.headers[key]}`);
}
}
return results.join('\n');
}
function lcObjectKey(src: Record<string, string>) {
const dst: Record<string, string> = {};
for (const key of Object.keys(src).filter(x => x != '__proto__' && typeof src[x] === 'string')) dst[key.toLowerCase()] = src[key];
return dst;
}
function objectAssignWithLcKey(a: Record<string, string>, b: Record<string, string>) {
return Object.assign(lcObjectKey(a), lcObjectKey(b));
}

View file

@ -8,6 +8,7 @@ import { extractDbHost } from '@/misc/convert-host';
import { fetchMeta } from '@/misc/fetch-meta'; import { fetchMeta } from '@/misc/fetch-meta';
import { getApLock } from '@/misc/app-lock'; import { getApLock } from '@/misc/app-lock';
import { parseAudience } from '../../audience'; import { parseAudience } from '../../audience';
import { StatusError } from '@/misc/fetch';
const logger = apLogger; const logger = apLogger;
@ -41,7 +42,7 @@ export default async function(resolver: Resolver, actor: IRemoteUser, activity:
renote = await resolveNote(targetUri); renote = await resolveNote(targetUri);
} catch (e) { } catch (e) {
// 対象が4xxならスキップ // 対象が4xxならスキップ
if (e.statusCode >= 400 && e.statusCode < 500) { if (e instanceof StatusError && e.isClientError) {
logger.warn(`Ignored announce target ${targetUri} - ${e.statusCode}`); logger.warn(`Ignored announce target ${targetUri} - ${e.statusCode}`);
return; return;
} }

View file

@ -4,6 +4,7 @@ import { createNote, fetchNote } from '../../models/note';
import { getApId, IObject, ICreate } from '../../type'; import { getApId, IObject, ICreate } from '../../type';
import { getApLock } from '@/misc/app-lock'; import { getApLock } from '@/misc/app-lock';
import { extractDbHost } from '@/misc/convert-host'; import { extractDbHost } from '@/misc/convert-host';
import { StatusError } from '@/misc/fetch';
/** /**
* 稿 * 稿
@ -32,7 +33,7 @@ export default async function(resolver: Resolver, actor: IRemoteUser, note: IObj
await createNote(note, resolver, silent); await createNote(note, resolver, silent);
return 'ok'; return 'ok';
} catch (e) { } catch (e) {
if (e.statusCode >= 400 && e.statusCode < 500) { if (e instanceof StatusError && e.isClientError) {
return `skip ${e.statusCode}`; return `skip ${e.statusCode}`;
} else { } else {
throw e; throw e;

View file

@ -26,6 +26,7 @@ import { createMessage } from '@/services/messages/create';
import { parseAudience } from '../audience'; import { parseAudience } from '../audience';
import { extractApMentions } from './mention'; import { extractApMentions } from './mention';
import DbResolver from '../db-resolver'; import DbResolver from '../db-resolver';
import { StatusError } from '@/misc/fetch';
const logger = apLogger; const logger = apLogger;
@ -177,7 +178,7 @@ export async function createNote(value: string | IObject, resolver?: Resolver, s
} }
} catch (e) { } catch (e) {
return { return {
status: e.statusCode >= 400 && e.statusCode < 500 ? 'permerror' : 'temperror' status: (e instanceof StatusError && e.isClientError) ? 'permerror' : 'temperror'
}; };
} }
}; };

View file

@ -1,66 +1,31 @@
import * as http from 'http';
import * as https from 'https';
import { sign } from 'http-signature';
import * as crypto from 'crypto';
import config from '@/config/index'; import config from '@/config/index';
import { User } from '@/models/entities/user';
import { getAgentByUrl } from '@/misc/fetch';
import { URL } from 'url';
import got from 'got';
import * as Got from 'got';
import { getUserKeypair } from '@/misc/keypair-store'; import { getUserKeypair } from '@/misc/keypair-store';
import { User } from '@/models/entities/user';
import { getResponse } from '../../misc/fetch';
import { createSignedPost, createSignedGet } from './ap-request';
export default async (user: { id: User['id'] }, url: string, object: any) => { export default async (user: { id: User['id'] }, url: string, object: any) => {
const timeout = 10 * 1000; const body = JSON.stringify(object);
const { protocol, hostname, port, pathname, search } = new URL(url);
const data = JSON.stringify(object);
const sha256 = crypto.createHash('sha256');
sha256.update(data);
const hash = sha256.digest('base64');
const keypair = await getUserKeypair(user.id); const keypair = await getUserKeypair(user.id);
await new Promise<void>((resolve, reject) => { const req = createSignedPost({
const req = https.request({ key: {
agent: getAgentByUrl(new URL(`https://example.net`)), privateKeyPem: keypair.privateKey,
protocol, keyId: `${config.url}/users/${user.id}#main-key`
hostname, },
port, url,
method: 'POST', body,
path: pathname + search, additionalHeaders: {
timeout,
headers: {
'User-Agent': config.userAgent, 'User-Agent': config.userAgent,
'Content-Type': 'application/activity+json',
'Digest': `SHA-256=${hash}`
}
}, res => {
if (res.statusCode! >= 400) {
reject(res);
} else {
resolve();
} }
}); });
sign(req, { await getResponse({
authorizationHeaderName: 'Signature', url,
key: keypair.privateKey, method: req.request.method,
keyId: `${config.url}/users/${user.id}#main-key`, headers: req.request.headers,
headers: ['(request-target)', 'date', 'host', 'digest'] body,
});
req.on('timeout', () => req.abort());
req.on('error', e => {
if (req.aborted) reject('timeout');
reject(e);
});
req.end(data);
}); });
}; };
@ -70,87 +35,24 @@ export default async (user: { id: User['id'] }, url: string, object: any) => {
* @param url URL to fetch * @param url URL to fetch
*/ */
export async function signedGet(url: string, user: { id: User['id'] }) { export async function signedGet(url: string, user: { id: User['id'] }) {
const timeout = 10 * 1000;
const keypair = await getUserKeypair(user.id); const keypair = await getUserKeypair(user.id);
const req = got.get<any>(url, { const req = createSignedGet({
headers: { key: {
'Accept': 'application/activity+json, application/ld+json', privateKeyPem: keypair.privateKey,
keyId: `${config.url}/users/${user.id}#main-key`
},
url,
additionalHeaders: {
'User-Agent': config.userAgent, 'User-Agent': config.userAgent,
}, }
responseType: 'json',
timeout,
hooks: {
beforeRequest: [
options => {
options.request = (url: URL, opt: http.RequestOptions, callback?: (response: any) => void) => {
// Select custom agent by URL
opt.agent = getAgentByUrl(url, false);
// Wrap original https?.request
const requestFunc = url.protocol === 'http:' ? http.request : https.request;
const clientRequest = requestFunc(url, opt, callback) as http.ClientRequest;
// HTTP-Signature
sign(clientRequest, {
authorizationHeaderName: 'Signature',
key: keypair.privateKey,
keyId: `${config.url}/users/${user.id}#main-key`,
headers: ['(request-target)', 'host', 'date', 'accept']
}); });
return clientRequest; const res = await getResponse({
}; url,
}, method: req.request.method,
], headers: req.request.headers
},
retry: 0,
}); });
const res = await receiveResponce(req, 10 * 1024 * 1024); return await res.json();
return res.body;
}
/**
* Receive response (with size limit)
* @param req Request
* @param maxSize size limit
*/
export async function receiveResponce<T>(req: Got.CancelableRequest<Got.Response<T>>, maxSize: number) {
// 応答ヘッダでサイズチェック
req.on('response', (res: Got.Response) => {
const contentLength = res.headers['content-length'];
if (contentLength != null) {
const size = Number(contentLength);
if (size > maxSize) {
req.cancel();
}
}
});
// 受信中のデータでサイズチェック
req.on('downloadProgress', (progress: Got.Progress) => {
if (progress.transferred > maxSize) {
req.cancel();
}
});
// 応答取得 with ステータスコードエラーの整形
const res = await req.catch(e => {
if (e.name === 'HTTPError') {
const statusCode = (e as Got.HTTPError).response.statusCode;
const statusMessage = (e as Got.HTTPError).response.statusMessage;
throw {
name: `StatusError`,
statusCode,
message: `${statusCode} ${statusMessage}`,
};
} else {
throw e;
}
});
return res;
} }

View file

@ -68,6 +68,10 @@ export const meta = {
validator: $.optional.bool, validator: $.optional.bool,
}, },
publicReactions: {
validator: $.optional.bool,
},
carefulBot: { carefulBot: {
validator: $.optional.bool, validator: $.optional.bool,
}, },
@ -180,6 +184,7 @@ export default define(meta, async (ps, _user, token) => {
if (typeof ps.isLocked === 'boolean') updates.isLocked = ps.isLocked; if (typeof ps.isLocked === 'boolean') updates.isLocked = ps.isLocked;
if (typeof ps.isExplorable === 'boolean') updates.isExplorable = ps.isExplorable; if (typeof ps.isExplorable === 'boolean') updates.isExplorable = ps.isExplorable;
if (typeof ps.hideOnlineStatus === 'boolean') updates.hideOnlineStatus = ps.hideOnlineStatus; if (typeof ps.hideOnlineStatus === 'boolean') updates.hideOnlineStatus = ps.hideOnlineStatus;
if (typeof ps.publicReactions === 'boolean') profileUpdates.publicReactions = ps.publicReactions;
if (typeof ps.isBot === 'boolean') updates.isBot = ps.isBot; if (typeof ps.isBot === 'boolean') updates.isBot = ps.isBot;
if (typeof ps.carefulBot === 'boolean') profileUpdates.carefulBot = ps.carefulBot; if (typeof ps.carefulBot === 'boolean') profileUpdates.carefulBot = ps.carefulBot;
if (typeof ps.autoAcceptFollowed === 'boolean') profileUpdates.autoAcceptFollowed = ps.autoAcceptFollowed; if (typeof ps.autoAcceptFollowed === 'boolean') profileUpdates.autoAcceptFollowed = ps.autoAcceptFollowed;

View file

@ -0,0 +1,50 @@
import $ from 'cafy';
import { ID } from '@/misc/cafy-id';
import define from '../../../define';
import { ApiError } from '../../../error';
import { UserGroups, UserGroupJoinings } from '@/models/index';
export const meta = {
tags: ['groups', 'users'],
requireCredential: true as const,
kind: 'write:user-groups',
params: {
groupId: {
validator: $.type(ID),
},
},
errors: {
noSuchGroup: {
message: 'No such group.',
code: 'NO_SUCH_GROUP',
id: '62780270-1f67-5dc0-daca-3eb510612e31'
},
youAreOwner: {
message: 'Your are the owner.',
code: 'YOU_ARE_OWNER',
id: 'b6d6e0c2-ef8a-9bb8-653d-79f4a3107c69'
},
}
};
export default define(meta, async (ps, me) => {
// Fetch the group
const userGroup = await UserGroups.findOne({
id: ps.groupId,
});
if (userGroup == null) {
throw new ApiError(meta.errors.noSuchGroup);
}
if (me.id === userGroup.userId) {
throw new ApiError(meta.errors.youAreOwner);
}
await UserGroupJoinings.delete({ userGroupId: userGroup.id, userId: me.id });
});

View file

@ -0,0 +1,79 @@
import $ from 'cafy';
import { ID } from '@/misc/cafy-id';
import define from '../../define';
import { NoteReactions, UserProfiles } from '@/models/index';
import { makePaginationQuery } from '../../common/make-pagination-query';
import { generateVisibilityQuery } from '../../common/generate-visibility-query';
import { ApiError } from '../../error';
export const meta = {
tags: ['users', 'reactions'],
requireCredential: false as const,
params: {
userId: {
validator: $.type(ID),
},
limit: {
validator: $.optional.num.range(1, 100),
default: 10,
},
sinceId: {
validator: $.optional.type(ID),
},
untilId: {
validator: $.optional.type(ID),
},
sinceDate: {
validator: $.optional.num,
},
untilDate: {
validator: $.optional.num,
},
},
res: {
type: 'array' as const,
optional: false as const, nullable: false as const,
items: {
type: 'object' as const,
optional: false as const, nullable: false as const,
ref: 'NoteReaction',
}
},
errors: {
reactionsNotPublic: {
message: 'Reactions of the user is not public.',
code: 'REACTIONS_NOT_PUBLIC',
id: '673a7dd2-6924-1093-e0c0-e68456ceae5c'
},
}
};
export default define(meta, async (ps, me) => {
const profile = await UserProfiles.findOneOrFail(ps.userId);
if (me == null || (me.id !== ps.userId && !profile.publicReactions)) {
throw new ApiError(meta.errors.reactionsNotPublic);
}
const query = makePaginationQuery(NoteReactions.createQueryBuilder('reaction'),
ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate)
.andWhere(`reaction.userId = :userId`, { userId: ps.userId })
.leftJoinAndSelect('reaction.note', 'note');
generateVisibilityQuery(query, me);
const reactions = await query
.take(ps.limit!)
.getMany();
return await Promise.all(reactions.map(reaction => NoteReactions.pack(reaction, me, { withNote: true })));
});

View file

@ -1,6 +1,8 @@
import $ from 'cafy'; import $ from 'cafy';
import define from '../../define'; import define from '../../define';
import { Users } from '@/models/index'; import { Users } from '@/models/index';
import { Brackets } from 'typeorm';
import { USER_ACTIVE_THRESHOLD } from '@/const';
export const meta = { export const meta = {
tags: ['users'], tags: ['users'],
@ -44,13 +46,15 @@ export const meta = {
}; };
export default define(meta, async (ps, me) => { export default define(meta, async (ps, me) => {
const activeThreshold = new Date(Date.now() - (1000 * 60 * 60 * 24 * 30)); // 30日
if (ps.host) { if (ps.host) {
const q = Users.createQueryBuilder('user') const q = Users.createQueryBuilder('user')
.where('user.isSuspended = FALSE') .where('user.isSuspended = FALSE')
.andWhere('user.host LIKE :host', { host: ps.host.toLowerCase() + '%' }); .andWhere('user.host LIKE :host', { host: ps.host.toLowerCase() + '%' });
if (ps.username) { if (ps.username) {
q.andWhere('user.usernameLower like :username', { username: ps.username.toLowerCase() + '%' }); q.andWhere('user.usernameLower LIKE :username', { username: ps.username.toLowerCase() + '%' });
} }
q.andWhere('user.updatedAt IS NOT NULL'); q.andWhere('user.updatedAt IS NOT NULL');
@ -63,9 +67,12 @@ export default define(meta, async (ps, me) => {
let users = await Users.createQueryBuilder('user') let users = await Users.createQueryBuilder('user')
.where('user.host IS NULL') .where('user.host IS NULL')
.andWhere('user.isSuspended = FALSE') .andWhere('user.isSuspended = FALSE')
.andWhere('user.usernameLower like :username', { username: ps.username.toLowerCase() + '%' }) .andWhere('user.usernameLower LIKE :username', { username: ps.username.toLowerCase() + '%' })
.andWhere('user.updatedAt IS NOT NULL') .andWhere(new Brackets(qb => { qb
.orderBy('user.updatedAt', 'DESC') .where('user.updatedAt IS NULL')
.orWhere('user.updatedAt > :activeThreshold', { activeThreshold: activeThreshold });
}))
.orderBy('user.updatedAt', 'DESC', 'NULLS LAST')
.take(ps.limit!) .take(ps.limit!)
.skip(ps.offset) .skip(ps.offset)
.getMany(); .getMany();
@ -74,7 +81,7 @@ export default define(meta, async (ps, me) => {
const otherUsers = await Users.createQueryBuilder('user') const otherUsers = await Users.createQueryBuilder('user')
.where('user.host IS NOT NULL') .where('user.host IS NOT NULL')
.andWhere('user.isSuspended = FALSE') .andWhere('user.isSuspended = FALSE')
.andWhere('user.usernameLower like :username', { username: ps.username.toLowerCase() + '%' }) .andWhere('user.usernameLower LIKE :username', { username: ps.username.toLowerCase() + '%' })
.andWhere('user.updatedAt IS NOT NULL') .andWhere('user.updatedAt IS NOT NULL')
.orderBy('user.updatedAt', 'DESC') .orderBy('user.updatedAt', 'DESC')
.take(ps.limit! - users.length) .take(ps.limit! - users.length)

View file

@ -2,6 +2,7 @@ import $ from 'cafy';
import define from '../../define'; import define from '../../define';
import { UserProfiles, Users } from '@/models/index'; import { UserProfiles, Users } from '@/models/index';
import { User } from '@/models/entities/user'; import { User } from '@/models/entities/user';
import { Brackets } from 'typeorm';
export const meta = { export const meta = {
tags: ['users'], tags: ['users'],
@ -23,9 +24,9 @@ export const meta = {
default: 10, default: 10,
}, },
localOnly: { origin: {
validator: $.optional.bool, validator: $.optional.str.or(['local', 'remote', 'combined']),
default: false, default: 'combined',
}, },
detail: { detail: {
@ -46,63 +47,79 @@ export const meta = {
}; };
export default define(meta, async (ps, me) => { export default define(meta, async (ps, me) => {
const activeThreshold = new Date(Date.now() - (1000 * 60 * 60 * 24 * 30)); // 30日
const isUsername = ps.query.startsWith('@'); const isUsername = ps.query.startsWith('@');
let users: User[] = []; let users: User[] = [];
if (isUsername) { if (isUsername) {
users = await Users.createQueryBuilder('user') const usernameQuery = Users.createQueryBuilder('user')
.where('user.host IS NULL') .where('user.usernameLower LIKE :username', { username: ps.query.replace('@', '').toLowerCase() + '%' })
.andWhere('user.isSuspended = FALSE') .andWhere(new Brackets(qb => { qb
.andWhere('user.usernameLower like :username', { username: ps.query.replace('@', '').toLowerCase() + '%' }) .where('user.updatedAt IS NULL')
.andWhere('user.updatedAt IS NOT NULL') .orWhere('user.updatedAt > :activeThreshold', { activeThreshold: activeThreshold });
.orderBy('user.updatedAt', 'DESC') }))
.andWhere('user.isSuspended = FALSE');
if (ps.origin === 'local') {
usernameQuery.andWhere('user.host IS NULL');
} else if (ps.origin === 'remote') {
usernameQuery.andWhere('user.host IS NOT NULL');
}
users = await usernameQuery
.orderBy('user.updatedAt', 'DESC', 'NULLS LAST')
.take(ps.limit!)
.skip(ps.offset)
.getMany();
} else {
const nameQuery = Users.createQueryBuilder('user')
.where('user.name ILIKE :query', { query: '%' + ps.query + '%' })
.andWhere(new Brackets(qb => { qb
.where('user.updatedAt IS NULL')
.orWhere('user.updatedAt > :activeThreshold', { activeThreshold: activeThreshold });
}))
.andWhere('user.isSuspended = FALSE');
if (ps.origin === 'local') {
nameQuery.andWhere('user.host IS NULL');
} else if (ps.origin === 'remote') {
nameQuery.andWhere('user.host IS NOT NULL');
}
users = await nameQuery
.orderBy('user.updatedAt', 'DESC', 'NULLS LAST')
.take(ps.limit!) .take(ps.limit!)
.skip(ps.offset) .skip(ps.offset)
.getMany(); .getMany();
if (users.length < ps.limit! && !ps.localOnly) { if (users.length < ps.limit!) {
const otherUsers = await Users.createQueryBuilder('user')
.where('user.host IS NOT NULL')
.andWhere('user.isSuspended = FALSE')
.andWhere('user.usernameLower like :username', { username: ps.query.replace('@', '').toLowerCase() + '%' })
.andWhere('user.updatedAt IS NOT NULL')
.orderBy('user.updatedAt', 'DESC')
.take(ps.limit! - users.length)
.getMany();
users = users.concat(otherUsers);
}
} else {
const profQuery = UserProfiles.createQueryBuilder('prof') const profQuery = UserProfiles.createQueryBuilder('prof')
.select('prof.userId') .select('prof.userId')
.where('prof.userHost IS NULL') .where('prof.description ILIKE :query', { query: '%' + ps.query + '%' });
.andWhere('prof.description ilike :query', { query: '%' + ps.query + '%' });
users = await Users.createQueryBuilder('user') if (ps.origin === 'local') {
profQuery.andWhere('prof.userHost IS NULL');
} else if (ps.origin === 'remote') {
profQuery.andWhere('prof.userHost IS NOT NULL');
}
const query = Users.createQueryBuilder('user')
.where(`user.id IN (${ profQuery.getQuery() })`) .where(`user.id IN (${ profQuery.getQuery() })`)
.setParameters(profQuery.getParameters()) .andWhere(new Brackets(qb => { qb
.andWhere('user.updatedAt IS NOT NULL') .where('user.updatedAt IS NULL')
.orderBy('user.updatedAt', 'DESC') .orWhere('user.updatedAt > :activeThreshold', { activeThreshold: activeThreshold });
}))
.andWhere('user.isSuspended = FALSE')
.setParameters(profQuery.getParameters());
users = users.concat(await query
.orderBy('user.updatedAt', 'DESC', 'NULLS LAST')
.take(ps.limit!) .take(ps.limit!)
.skip(ps.offset) .skip(ps.offset)
.getMany(); .getMany()
);
if (users.length < ps.limit! && !ps.localOnly) {
const profQuery2 = UserProfiles.createQueryBuilder('prof')
.select('prof.userId')
.where('prof.userHost IS NOT NULL')
.andWhere('prof.description ilike :query', { query: '%' + ps.query + '%' });
const otherUsers = await Users.createQueryBuilder('user')
.where(`user.id IN (${ profQuery2.getQuery() })`)
.setParameters(profQuery2.getParameters())
.andWhere('user.updatedAt IS NOT NULL')
.orderBy('user.updatedAt', 'DESC')
.take(ps.limit! - users.length)
.getMany();
users = users.concat(otherUsers);
} }
} }

View file

@ -13,6 +13,7 @@ import { downloadUrl } from '@/misc/download-url';
import { detectType } from '@/misc/get-file-info'; import { detectType } from '@/misc/get-file-info';
import { convertToJpeg, convertToPngOrJpeg } from '@/services/drive/image-processor'; import { convertToJpeg, convertToPngOrJpeg } from '@/services/drive/image-processor';
import { GenerateVideoThumbnail } from '@/services/drive/generate-video-thumbnail'; import { GenerateVideoThumbnail } from '@/services/drive/generate-video-thumbnail';
import { StatusError } from '@/misc/fetch';
//const _filename = fileURLToPath(import.meta.url); //const _filename = fileURLToPath(import.meta.url);
const _filename = __filename; const _filename = __filename;
@ -83,9 +84,9 @@ export default async function(ctx: Koa.Context) {
ctx.set('Content-Type', image.type); ctx.set('Content-Type', image.type);
ctx.set('Cache-Control', 'max-age=31536000, immutable'); ctx.set('Cache-Control', 'max-age=31536000, immutable');
} catch (e) { } catch (e) {
serverLogger.error(e.statusCode); serverLogger.error(`${e}`);
if (typeof e.statusCode === 'number' && e.statusCode >= 400 && e.statusCode < 500) { if (e instanceof StatusError && e.isClientError) {
ctx.status = e.statusCode; ctx.status = e.statusCode;
ctx.set('Cache-Control', 'max-age=86400'); ctx.set('Cache-Control', 'max-age=86400');
} else { } else {

View file

@ -5,6 +5,7 @@ import { IImage, convertToPng, convertToJpeg } from '@/services/drive/image-proc
import { createTemp } from '@/misc/create-temp'; import { createTemp } from '@/misc/create-temp';
import { downloadUrl } from '@/misc/download-url'; import { downloadUrl } from '@/misc/download-url';
import { detectType } from '@/misc/get-file-info'; import { detectType } from '@/misc/get-file-info';
import { StatusError } from '@/misc/fetch';
export async function proxyMedia(ctx: Koa.Context) { export async function proxyMedia(ctx: Koa.Context) {
const url = 'url' in ctx.query ? ctx.query.url : 'https://' + ctx.params.url; const url = 'url' in ctx.query ? ctx.query.url : 'https://' + ctx.params.url;
@ -37,9 +38,9 @@ export async function proxyMedia(ctx: Koa.Context) {
ctx.set('Cache-Control', 'max-age=31536000, immutable'); ctx.set('Cache-Control', 'max-age=31536000, immutable');
ctx.body = image.data; ctx.body = image.data;
} catch (e) { } catch (e) {
serverLogger.error(e); serverLogger.error(`${e}`);
if (typeof e.statusCode === 'number' && e.statusCode >= 400 && e.statusCode < 500) { if (e instanceof StatusError && e.isClientError) {
ctx.status = e.statusCode; ctx.status = e.statusCode;
} else { } else {
ctx.status = 500; ctx.status = 500;

55
test/ap-request.ts Normal file
View file

@ -0,0 +1,55 @@
import * as assert from 'assert';
import { genRsaKeyPair } from '../src/misc/gen-key-pair';
import { createSignedPost, createSignedGet } from '../src/remote/activitypub/ap-request';
const httpSignature = require('http-signature');
export const buildParsedSignature = (signingString: string, signature: string, algorithm: string) => {
return {
scheme: 'Signature',
params: {
keyId: 'KeyID', // dummy, not used for verify
algorithm: algorithm,
headers: [ '(request-target)', 'date', 'host', 'digest' ], // dummy, not used for verify
signature: signature,
},
signingString: signingString,
algorithm: algorithm?.toUpperCase(),
keyId: 'KeyID', // dummy, not used for verify
};
};
describe('ap-request', () => {
it('createSignedPost with verify', async () => {
const keypair = await genRsaKeyPair();
const key = { keyId: 'x', 'privateKeyPem': keypair.privateKey };
const url = 'https://example.com/inbox';
const activity = { a: 1 };
const body = JSON.stringify(activity);
const headers = {
'User-Agent': 'UA'
};
const req = createSignedPost({ key, url, body, additionalHeaders: headers });
const parsed = buildParsedSignature(req.signingString, req.signature, 'rsa-sha256');
const result = httpSignature.verifySignature(parsed, keypair.publicKey);
assert.deepStrictEqual(result, true);
});
it('createSignedGet with verify', async () => {
const keypair = await genRsaKeyPair();
const key = { keyId: 'x', 'privateKeyPem': keypair.privateKey };
const url = 'https://example.com/outbox';
const headers = {
'User-Agent': 'UA'
};
const req = createSignedGet({ key, url, additionalHeaders: headers });
const parsed = buildParsedSignature(req.signingString, req.signature, 'rsa-sha256');
const result = httpSignature.verifySignature(parsed, keypair.publicKey);
assert.deepStrictEqual(result, true);
});
});

15
test/docker-compose.yml Normal file
View file

@ -0,0 +1,15 @@
version: "3"
services:
redistest:
image: redis:4.0-alpine
ports:
- "127.0.0.1:56312:6379"
dbtest:
image: postgres:12.2-alpine
ports:
- "127.0.0.1:54312:5432"
environment:
POSTGRES_DB: "test-misskey"
POSTGRES_HOST_AUTH_METHOD: trust

12
test/test.yml Normal file
View file

@ -0,0 +1,12 @@
url: 'http://misskey.local'
port: 61812
db:
host: localhost
port: 54312
db: test-misskey
user: postgres
pass: ''
redis:
host: localhost
port: 56312
id: aid

475
yarn.lock
View file

@ -2,13 +2,6 @@
# yarn lockfile v1 # yarn lockfile v1
"@babel/code-frame@7.12.11":
version "7.12.11"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f"
integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==
dependencies:
"@babel/highlight" "^7.10.4"
"@babel/code-frame@^7.0.0": "@babel/code-frame@^7.0.0":
version "7.12.13" version "7.12.13"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.13.tgz#dcfc826beef65e75c50e21d3837d7d95798dd658" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.13.tgz#dcfc826beef65e75c50e21d3837d7d95798dd658"
@ -21,7 +14,7 @@
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed"
integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw== integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==
"@babel/highlight@^7.10.4", "@babel/highlight@^7.12.13": "@babel/highlight@^7.12.13":
version "7.12.13" version "7.12.13"
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.12.13.tgz#8ab538393e00370b26271b01fa08f7f27f2e795c" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.12.13.tgz#8ab538393e00370b26271b01fa08f7f27f2e795c"
integrity sha512-kocDQvIbgMKlWxXe9fof3TQ+gkIPOUSEYhJjqUjvKMez3krV7vbzYCDq39Oj11UAVK7JqPVGQPlgE85dPNlQww== integrity sha512-kocDQvIbgMKlWxXe9fof3TQ+gkIPOUSEYhJjqUjvKMez3krV7vbzYCDq39Oj11UAVK7JqPVGQPlgE85dPNlQww==
@ -61,10 +54,10 @@
resolved "https://registry.yarnpkg.com/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz#33bf4b7b39c178821606f669bbc447a6a629786b" resolved "https://registry.yarnpkg.com/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz#33bf4b7b39c178821606f669bbc447a6a629786b"
integrity sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg== integrity sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==
"@cspotcode/source-map-support@0.6.1": "@cspotcode/source-map-support@0.7.0":
version "0.6.1" version "0.7.0"
resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.6.1.tgz#118511f316e2e87ee4294761868e254d3da47960" resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz#4789840aa859e46d2f3173727ab707c66bf344f5"
integrity sha512-DX3Z+T5dt1ockmPdobJS/FAsQPW4V4SrWEhD2iYQT2Cb2tQsiMnYxrcUH9By/Z3B+v0S5LMBkQtV/XOBbpLEOg== integrity sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==
dependencies: dependencies:
"@cspotcode/source-map-consumer" "0.8.0" "@cspotcode/source-map-consumer" "0.8.0"
@ -131,14 +124,14 @@
pump "^3.0.0" pump "^3.0.0"
secure-json-parse "^2.1.0" secure-json-parse "^2.1.0"
"@eslint/eslintrc@^0.4.3": "@eslint/eslintrc@^1.0.3":
version "0.4.3" version "1.0.3"
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c" resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.0.3.tgz#41f08c597025605f672251dcc4e8be66b5ed7366"
integrity sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw== integrity sha512-DHI1wDPoKCBPoLZA3qDR91+3te/wDSc1YhKg3jR8NxKKRJq2hwHwcWv31cSwSYvIBrmbENoYMWcenW8uproQqg==
dependencies: dependencies:
ajv "^6.12.4" ajv "^6.12.4"
debug "^4.1.1" debug "^4.3.2"
espree "^7.3.0" espree "^9.0.0"
globals "^13.9.0" globals "^13.9.0"
ignore "^4.0.6" ignore "^4.0.6"
import-fresh "^3.2.1" import-fresh "^3.2.1"
@ -158,10 +151,10 @@
dependencies: dependencies:
"@hapi/hoek" "^9.0.0" "@hapi/hoek" "^9.0.0"
"@humanwhocodes/config-array@^0.5.0": "@humanwhocodes/config-array@^0.6.0":
version "0.5.0" version "0.6.0"
resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.5.0.tgz#1407967d4c6eecd7388f83acf1eaf4d0c6e58ef9" resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.6.0.tgz#b5621fdb3b32309d2d16575456cbc277fa8f021a"
integrity sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg== integrity sha512-JQlEKbcgEUjBFhLIF4iqM7u/9lwgHRBcpHrmUNCALK0Q3amXN6lxdoXLnF0sm11E9VqTmBALR87IlUg1bZ8A9A==
dependencies: dependencies:
"@humanwhocodes/object-schema" "^1.2.0" "@humanwhocodes/object-schema" "^1.2.0"
debug "^4.1.1" debug "^4.1.1"
@ -1189,144 +1182,144 @@
resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.8.2.tgz#808c9fa7e4517274ed555fa158f2de4b4f468e71" resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.8.2.tgz#808c9fa7e4517274ed555fa158f2de4b4f468e71"
integrity sha512-HrCIVMLjE1MOozVoD86622S7aunluLb2PJdPfb3nYiEtohm8mIB/vyv0Fd37AdeMFrTUQXEunw78YloMA3Qilg== integrity sha512-HrCIVMLjE1MOozVoD86622S7aunluLb2PJdPfb3nYiEtohm8mIB/vyv0Fd37AdeMFrTUQXEunw78YloMA3Qilg==
"@typescript-eslint/parser@4.33.0": "@typescript-eslint/parser@5.0.0":
version "4.33.0" version "5.0.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.33.0.tgz#dfe797570d9694e560528d18eecad86c8c744899" resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.0.0.tgz#50d1be2e0def82d73e863cceba74aeeac9973592"
integrity sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA== integrity sha512-B6D5rmmQ14I1fdzs71eL3DAuvnPHTY/t7rQABrL9BLnx/H51Un8ox1xqYAchs0/V2trcoyxB1lMJLlrwrJCDgw==
dependencies: dependencies:
"@typescript-eslint/scope-manager" "4.33.0" "@typescript-eslint/scope-manager" "5.0.0"
"@typescript-eslint/types" "4.33.0" "@typescript-eslint/types" "5.0.0"
"@typescript-eslint/typescript-estree" "4.33.0" "@typescript-eslint/typescript-estree" "5.0.0"
debug "^4.3.1" debug "^4.3.1"
"@typescript-eslint/scope-manager@4.33.0": "@typescript-eslint/scope-manager@5.0.0":
version "4.33.0" version "5.0.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz#d38e49280d983e8772e29121cf8c6e9221f280a3" resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.0.0.tgz#aea0fb0e2480c1169a02e89d9005ac3f2835713f"
integrity sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ== integrity sha512-5RFjdA/ain/MDUHYXdF173btOKncIrLuBmA9s6FJhzDrRAyVSA+70BHg0/MW6TE+UiKVyRtX91XpVS0gVNwVDQ==
dependencies: dependencies:
"@typescript-eslint/types" "4.33.0" "@typescript-eslint/types" "5.0.0"
"@typescript-eslint/visitor-keys" "4.33.0" "@typescript-eslint/visitor-keys" "5.0.0"
"@typescript-eslint/types@4.33.0": "@typescript-eslint/types@5.0.0":
version "4.33.0" version "5.0.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.33.0.tgz#a1e59036a3b53ae8430ceebf2a919dc7f9af6d72" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.0.0.tgz#25d93f6d269b2d25fdc51a0407eb81ccba60eb0f"
integrity sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ== integrity sha512-dU/pKBUpehdEqYuvkojmlv0FtHuZnLXFBn16zsDmlFF3LXkOpkAQ2vrKc3BidIIve9EMH2zfTlxqw9XM0fFN5w==
"@typescript-eslint/typescript-estree@4.33.0": "@typescript-eslint/typescript-estree@5.0.0":
version "4.33.0" version "5.0.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz#0dfb51c2908f68c5c08d82aefeaf166a17c24609" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.0.0.tgz#bc20f413c6e572c7309dbe5fa3be027984952af3"
integrity sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA== integrity sha512-V/6w+PPQMhinWKSn+fCiX5jwvd1vRBm7AX7SJQXEGQtwtBvjMPjaU3YTQ1ik2UF1u96X7tsB96HMnulG3eLi9Q==
dependencies: dependencies:
"@typescript-eslint/types" "4.33.0" "@typescript-eslint/types" "5.0.0"
"@typescript-eslint/visitor-keys" "4.33.0" "@typescript-eslint/visitor-keys" "5.0.0"
debug "^4.3.1" debug "^4.3.1"
globby "^11.0.3" globby "^11.0.3"
is-glob "^4.0.1" is-glob "^4.0.1"
semver "^7.3.5" semver "^7.3.5"
tsutils "^3.21.0" tsutils "^3.21.0"
"@typescript-eslint/visitor-keys@4.33.0": "@typescript-eslint/visitor-keys@5.0.0":
version "4.33.0" version "5.0.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz#2a22f77a41604289b7a186586e9ec48ca92ef1dd" resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.0.0.tgz#b789f7cd105e59bee5c0983a353942a5a48f56df"
integrity sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg== integrity sha512-yRyd2++o/IrJdyHuYMxyFyBhU762MRHQ/bAGQeTnN3pGikfh+nEmM61XTqaDH1XDp53afZ+waXrk0ZvenoZ6xw==
dependencies: dependencies:
"@typescript-eslint/types" "4.33.0" "@typescript-eslint/types" "5.0.0"
eslint-visitor-keys "^2.0.0" eslint-visitor-keys "^3.0.0"
"@ungap/promise-all-settled@1.1.2": "@ungap/promise-all-settled@1.1.2":
version "1.1.2" version "1.1.2"
resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44"
integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==
"@vue/compiler-core@3.2.19": "@vue/compiler-core@3.2.20":
version "3.2.19" version "3.2.20"
resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.2.19.tgz#b537dd377ce51fdb64e9b30ebfbff7cd70a64cb9" resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.2.20.tgz#af5a3c5237818835b0d0be837eb5885a8d21c160"
integrity sha512-8dOPX0YOtaXol0Zf2cfLQ4NU/yHYl2H7DCKsLEZ7gdvPK6ZSEwGLJ7IdghhY2YEshEpC5RB9QKdC5I07z8Dtjg== integrity sha512-vcEXlKXoPwBXFP5aUTHN9GTZaDfwCofa9Yu9bbW2C5O/QSa9Esdt7OG4+0RRd3EHEMxUvEdj4RZrd/KpQeiJbA==
dependencies: dependencies:
"@babel/parser" "^7.15.0" "@babel/parser" "^7.15.0"
"@vue/shared" "3.2.19" "@vue/shared" "3.2.20"
estree-walker "^2.0.2" estree-walker "^2.0.2"
source-map "^0.6.1" source-map "^0.6.1"
"@vue/compiler-dom@3.2.19": "@vue/compiler-dom@3.2.20":
version "3.2.19" version "3.2.20"
resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.2.19.tgz#0607bc90de6af55fde73b09b3c4d0bf8cb597ed8" resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.2.20.tgz#8e0ef354449c0faf41519b00bfc2045eae01dcb5"
integrity sha512-WzQoE8rfkFjPtIioc7SSgTsnz9g2oG61DU8KHnzPrRS7fW/lji6H2uCYJfp4Z6kZE8GjnHc1Ljwl3/gxDes0cw== integrity sha512-QnI77ec/JtV7R0YBbcVayYTDCRcI9OCbxiUQK6izVyqQO0658n0zQuoNwe+bYgtqnvGAIqTR3FShTd5y4oOjdg==
dependencies: dependencies:
"@vue/compiler-core" "3.2.19" "@vue/compiler-core" "3.2.20"
"@vue/shared" "3.2.19" "@vue/shared" "3.2.20"
"@vue/compiler-sfc@3.2.19": "@vue/compiler-sfc@3.2.20":
version "3.2.19" version "3.2.20"
resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.2.19.tgz#d412195a98ebd49b84602f171719294a1d9549be" resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.2.20.tgz#2d7668e76f066c566dd7c09c15c9acce4e876e0a"
integrity sha512-pLlbgkO1UHTO02MSpa/sFOXUwIDxSMiKZ1ozE5n71CY4DM+YmI+G3gT/ZHZ46WBId7f3VTF/D8pGwMygcQbrQA== integrity sha512-03aZo+6tQKiFLfunHKSPZvdK4Jsn/ftRCyaro8AQIWkuxJbvSosbKK6HTTn+D2c3nPScG155akJoxKENw7rftQ==
dependencies: dependencies:
"@babel/parser" "^7.15.0" "@babel/parser" "^7.15.0"
"@vue/compiler-core" "3.2.19" "@vue/compiler-core" "3.2.20"
"@vue/compiler-dom" "3.2.19" "@vue/compiler-dom" "3.2.20"
"@vue/compiler-ssr" "3.2.19" "@vue/compiler-ssr" "3.2.20"
"@vue/ref-transform" "3.2.19" "@vue/ref-transform" "3.2.20"
"@vue/shared" "3.2.19" "@vue/shared" "3.2.20"
estree-walker "^2.0.2" estree-walker "^2.0.2"
magic-string "^0.25.7" magic-string "^0.25.7"
postcss "^8.1.10" postcss "^8.1.10"
source-map "^0.6.1" source-map "^0.6.1"
"@vue/compiler-ssr@3.2.19": "@vue/compiler-ssr@3.2.20":
version "3.2.19" version "3.2.20"
resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.2.19.tgz#3e91ecf70f8f961c5f63eacd2139bcdab9a7a07c" resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.2.20.tgz#9cceb6261d9932cb5568202610c1c28f86c5e521"
integrity sha512-oLon0Cn3O7WEYzzmzZavGoqXH+199LT+smdjBT3Uf3UX4HwDNuBFCmvL0TsqV9SQnIgKvBRbQ7lhbpnd4lqM3w== integrity sha512-rzzVVYivm+EjbfiGQvNeyiYZWzr6Hkej97RZLZvcumacQlnKv9176Xo9rRyeWwFbBlxmtNdrVMslRXtipMXk2w==
dependencies: dependencies:
"@vue/compiler-dom" "3.2.19" "@vue/compiler-dom" "3.2.20"
"@vue/shared" "3.2.19" "@vue/shared" "3.2.20"
"@vue/reactivity@3.2.19": "@vue/reactivity@3.2.20":
version "3.2.19" version "3.2.20"
resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.2.19.tgz#fc6e0f0106f295226835cfed5ff5f84d927bea65" resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.2.20.tgz#81fe1c368e7f20bc0ec1dec1045bbee253582de8"
integrity sha512-FtachoYs2SnyrWup5UikP54xDX6ZJ1s5VgHcJp4rkGoutU3Ry61jhs+nCX7J64zjX992Mh9gGUC0LqTs8q9vCA== integrity sha512-nSmoLojUTk+H8HNTAkrUduB4+yIUBK2HPihJo2uXVSH4Spry6oqN6lFzE5zpLK+F27Sja+UqR9R1+/kIOsHV5w==
dependencies: dependencies:
"@vue/shared" "3.2.19" "@vue/shared" "3.2.20"
"@vue/ref-transform@3.2.19": "@vue/ref-transform@3.2.20":
version "3.2.19" version "3.2.20"
resolved "https://registry.yarnpkg.com/@vue/ref-transform/-/ref-transform-3.2.19.tgz#cf0f986486bb26838fbd09749e927bab19745600" resolved "https://registry.yarnpkg.com/@vue/ref-transform/-/ref-transform-3.2.20.tgz#2a59ec90caf8e5c7336776a0900bff0a8b81c090"
integrity sha512-03wwUnoIAeKti5IGGx6Vk/HEBJ+zUcm5wrUM3+PQsGf7IYnXTbeIfHHpx4HeSeWhnLAjqZjADQwW8uA4rBmVbg== integrity sha512-Y42d3PGlYZ1lXcF3dbd3+qU/C/a3wYEZ949fyOI5ptzkjDWlkfU6vn74fmOjsLjEcjs10BXK2qO99FqQIK2r1Q==
dependencies: dependencies:
"@babel/parser" "^7.15.0" "@babel/parser" "^7.15.0"
"@vue/compiler-core" "3.2.19" "@vue/compiler-core" "3.2.20"
"@vue/shared" "3.2.19" "@vue/shared" "3.2.20"
estree-walker "^2.0.2" estree-walker "^2.0.2"
magic-string "^0.25.7" magic-string "^0.25.7"
"@vue/runtime-core@3.2.19": "@vue/runtime-core@3.2.20":
version "3.2.19" version "3.2.20"
resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.2.19.tgz#807715b7f4728abb84fa4a8efdbe37d8ddb4c6d3" resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.2.20.tgz#8f63e956a3f88fb772541443c45a7701211012cb"
integrity sha512-qArZSWKxWsgKfxk9BelZ32nY0MZ31CAW2kUUyVJyxh4cTfHaXGbjiQB5JgsvKc49ROMNffv9t3/qjasQqAH+RQ== integrity sha512-d1xfUGhZPfiZzAN7SatStD4vRtT8deJSXib2+Cz3x0brjMWKxe32asQc154FF1E2fFgMCHtnfd4A90bQEzV4GQ==
dependencies: dependencies:
"@vue/reactivity" "3.2.19" "@vue/reactivity" "3.2.20"
"@vue/shared" "3.2.19" "@vue/shared" "3.2.20"
"@vue/runtime-dom@3.2.19": "@vue/runtime-dom@3.2.20":
version "3.2.19" version "3.2.20"
resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.2.19.tgz#7e8bf645754703e360fa132e4be9113edf2377bb" resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.2.20.tgz#8aa56ae6c30f9cd4a71ca0e9ec3c4bdc67148d15"
integrity sha512-hIRboxXwafeHhbZEkZYNV0MiJXPNf4fP0X6hM2TJb0vssz8BKhD9cF92BkRgZztTQevecbhk0gu4uAPJ3dxL9A== integrity sha512-4TCvZMLhESWCFHFYgqN4QmMA/onnINAlUovhopjlS8ST27G1A8Z0tyxPzLoXLa+b5JrOpbMPheEMPvdKExTJig==
dependencies: dependencies:
"@vue/runtime-core" "3.2.19" "@vue/runtime-core" "3.2.20"
"@vue/shared" "3.2.19" "@vue/shared" "3.2.20"
csstype "^2.6.8" csstype "^2.6.8"
"@vue/server-renderer@3.2.19": "@vue/server-renderer@3.2.20":
version "3.2.19" version "3.2.20"
resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.2.19.tgz#870bcec9f7cdaee0c2187a169b6e636ab4362fb1" resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.2.20.tgz#705e07ae9425132b2b6227d308a51a13f4d4ec81"
integrity sha512-A9FNT7fgQJXItwdzWREntAgWKVtKYuXHBKGev/H4+ByTu8vB7gQXGcim01QxaJshdNg4dYuH2tEBZXCNCNx+/w== integrity sha512-viIbZGep9XabnrRcaxWIi00cOh1x21QYm2upIL5W0zqzTJ54VdTzpI+zi1osNp+VfRQDTHpV2U7H3Kn4ljYJvg==
dependencies: dependencies:
"@vue/compiler-ssr" "3.2.19" "@vue/compiler-ssr" "3.2.20"
"@vue/shared" "3.2.19" "@vue/shared" "3.2.20"
"@vue/shared@3.2.19": "@vue/shared@3.2.20":
version "3.2.19" version "3.2.20"
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.2.19.tgz#111ec3da18337d86274446984c49925b1b2b2dd7" resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.2.20.tgz#53746961f731a8ea666e3316271e944238dc31db"
integrity sha512-Knqhx7WieLdVgwCAZgTVrDCXZ50uItuecLh9JdLC8O+a5ayaSyIQYveUK3hCRNC7ws5zalHmZwfdLMGaS8r4Ew== integrity sha512-FbpX+hD5BvXCQerEYO7jtAGHlhAkhTQ4KIV73kmLWNlawWhTiVuQxizgVb0BOkX5oG9cIRZ42EG++d/k/Efp0w==
"@webassemblyjs/ast@1.11.0": "@webassemblyjs/ast@1.11.0":
version "1.11.0" version "1.11.0"
@ -1655,7 +1648,7 @@ acorn-walk@^8.1.1:
resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.1.1.tgz#3ddab7f84e4a7e2313f6c414c5b7dac85f4e3ebc" resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.1.1.tgz#3ddab7f84e4a7e2313f6c414c5b7dac85f4e3ebc"
integrity sha512-FbJdceMlPHEAWJOILDk1fXD8lnTlEIWFkqtfk+MvmL5q/qlHfN7GEHcsFZWt/Tea9jRNPWUZG4G976nqAAmU9w== integrity sha512-FbJdceMlPHEAWJOILDk1fXD8lnTlEIWFkqtfk+MvmL5q/qlHfN7GEHcsFZWt/Tea9jRNPWUZG4G976nqAAmU9w==
acorn@^7.1.1, acorn@^7.4.0: acorn@^7.1.1:
version "7.4.1" version "7.4.1"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa"
integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==
@ -1675,6 +1668,11 @@ acorn@^8.4.1:
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.4.1.tgz#56c36251fc7cabc7096adc18f05afe814321a28c" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.4.1.tgz#56c36251fc7cabc7096adc18f05afe814321a28c"
integrity sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA== integrity sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==
acorn@^8.5.0:
version "8.5.0"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.5.0.tgz#4512ccb99b3698c752591e9bb4472e38ad43cee2"
integrity sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==
agent-base@6: agent-base@6:
version "6.0.2" version "6.0.2"
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77"
@ -1714,16 +1712,6 @@ ajv@^6.10.0, ajv@^6.12.4, ajv@^6.12.5, ajv@^6.5.5:
json-schema-traverse "^0.4.1" json-schema-traverse "^0.4.1"
uri-js "^4.2.2" uri-js "^4.2.2"
ajv@^8.0.1:
version "8.5.0"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.5.0.tgz#695528274bcb5afc865446aa275484049a18ae4b"
integrity sha512-Y2l399Tt1AguU3BPRP9Fn4eN+Or+StUGWCUpbnFyXSo8NZ9S4uj+AG2pjs5apK+ZMOwYOz1+a+VKvKH7CudXgQ==
dependencies:
fast-deep-equal "^3.1.1"
json-schema-traverse "^1.0.0"
require-from-string "^2.0.2"
uri-js "^4.2.2"
alphanum-sort@^1.0.1, alphanum-sort@^1.0.2: alphanum-sort@^1.0.1, alphanum-sort@^1.0.2:
version "1.0.2" version "1.0.2"
resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3"
@ -2422,10 +2410,10 @@ builtin-modules@^1.1.1:
resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f"
integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8= integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=
bull@3.29.2: bull@3.29.3:
version "3.29.2" version "3.29.3"
resolved "https://registry.yarnpkg.com/bull/-/bull-3.29.2.tgz#30051fd14c7214b1e90c212585674f77fd982650" resolved "https://registry.yarnpkg.com/bull/-/bull-3.29.3.tgz#5b0059b172685b0d6f011d56214e1898ff3a7a0b"
integrity sha512-zWHyza/ElwVvJUqIEDJdUhGKd1V9EHjituUL7sJAmJoxS9Z7QMhYcMOWcgbUlWPgtiKN1g9ZlOtFAoq7C4/SQw== integrity sha512-MOqV1dKLy1YQgP9m3lFolyMxaU+1+o4afzYYf0H4wNM+x/S0I1QPQfkgGlLiH00EyFrvSmeubeCYFP47rTfpjg==
dependencies: dependencies:
cron-parser "^2.13.0" cron-parser "^2.13.0"
debuglog "^1.0.0" debuglog "^1.0.0"
@ -2497,10 +2485,10 @@ cache-content-type@^1.0.0:
mime-types "^2.1.18" mime-types "^2.1.18"
ylru "^1.2.0" ylru "^1.2.0"
cacheable-lookup@6.0.2: cacheable-lookup@6.0.3:
version "6.0.2" version "6.0.3"
resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-6.0.2.tgz#8df03d6239c91bb9f6394700d7ba4a100abbad67" resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-6.0.3.tgz#61d6171f6818fab230666b11f7cf3f5a48df7818"
integrity sha512-9RJkUl1k/A1dFhaRfrEUdISvvou0WKx8LboMO0j1BpsqgAuolwZgwaEtn0dmFMk5HQxpFtHF1bHCnIQMywUpvw== integrity sha512-xdwIK7MEC8NpRIt0dx2PL7pTRKaSmDb+zirzuM+cJTRWDfwfVu4XyASkODIU4XbjsyFHKo/tDOPSs64Z3yfFWg==
cacheable-lookup@^5.0.3: cacheable-lookup@^5.0.3:
version "5.0.3" version "5.0.3"
@ -3325,10 +3313,10 @@ css-declaration-sorter@^6.0.3:
dependencies: dependencies:
timsort "^0.3.0" timsort "^0.3.0"
css-loader@6.3.0: css-loader@6.4.0:
version "6.3.0" version "6.4.0"
resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.3.0.tgz#334d3500ff0a0c14cfbd4b0670088dbb5b5c1530" resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.4.0.tgz#01c57ea776024e18ca193428dcad3ff6b42a0130"
integrity sha512-9NGvHOR+L6ps13Ilw/b216++Q8q+5RpJcVufCdW9S/9iCzs4KBDNa8qnA/n3FK/sSfWmH35PAIK/cfPi7LOSUg== integrity sha512-Dlt6qfsxI/w1vU0r8qDd4BtMPxWqJeY5qQU7SmmZfvbpe6Xl18McO4GhyaMLns24Y2VNPiZwJPQ8JSbg4qvQLw==
dependencies: dependencies:
icss-utils "^5.1.0" icss-utils "^5.1.0"
postcss "^8.2.15" postcss "^8.2.15"
@ -4280,6 +4268,14 @@ eslint-scope@5.1.1, eslint-scope@^5.1.1:
esrecurse "^4.3.0" esrecurse "^4.3.0"
estraverse "^4.1.1" estraverse "^4.1.1"
eslint-scope@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-6.0.0.tgz#9cf45b13c5ac8f3d4c50f46a5121f61b3e318978"
integrity sha512-uRDL9MWmQCkaFus8RF5K9/L/2fn+80yoW3jkD53l4shjCh26fCtvJGasxjUqP5OT87SYTxCVA3BwTUzuELx9kA==
dependencies:
esrecurse "^4.3.0"
estraverse "^5.2.0"
eslint-utils@^2.1.0: eslint-utils@^2.1.0:
version "2.1.0" version "2.1.0"
resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27"
@ -4287,7 +4283,14 @@ eslint-utils@^2.1.0:
dependencies: dependencies:
eslint-visitor-keys "^1.1.0" eslint-visitor-keys "^1.1.0"
eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: eslint-utils@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672"
integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==
dependencies:
eslint-visitor-keys "^2.0.0"
eslint-visitor-keys@^1.1.0:
version "1.3.0" version "1.3.0"
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e"
integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==
@ -4297,37 +4300,41 @@ eslint-visitor-keys@^2.0.0:
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz#21fdc8fbcd9c795cc0321f0563702095751511a8" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz#21fdc8fbcd9c795cc0321f0563702095751511a8"
integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ== integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==
eslint@7.32.0: eslint-visitor-keys@^3.0.0:
version "7.32.0" version "3.0.0"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.32.0.tgz#c6d328a14be3fb08c8d1d21e12c02fdb7a2a812d" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.0.0.tgz#e32e99c6cdc2eb063f204eda5db67bfe58bb4186"
integrity sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA== integrity sha512-mJOZa35trBTb3IyRmo8xmKBZlxf+N7OnUl4+ZhJHs/r+0770Wh/LEACE2pqMGMe27G/4y8P2bYGk4J70IC5k1Q==
eslint@8.0.1:
version "8.0.1"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.0.1.tgz#3610e7fe4a05c2154669515ca60835a76a19f700"
integrity sha512-LsgcwZgQ72vZ+SMp4K6pAnk2yFDWL7Ti4pJaRvsZ0Hsw2h8ZjUIW38a9AFn2cZXdBMlScMFYYgsSp4ttFI/0bA==
dependencies: dependencies:
"@babel/code-frame" "7.12.11" "@eslint/eslintrc" "^1.0.3"
"@eslint/eslintrc" "^0.4.3" "@humanwhocodes/config-array" "^0.6.0"
"@humanwhocodes/config-array" "^0.5.0"
ajv "^6.10.0" ajv "^6.10.0"
chalk "^4.0.0" chalk "^4.0.0"
cross-spawn "^7.0.2" cross-spawn "^7.0.2"
debug "^4.0.1" debug "^4.3.2"
doctrine "^3.0.0" doctrine "^3.0.0"
enquirer "^2.3.5" enquirer "^2.3.5"
escape-string-regexp "^4.0.0" escape-string-regexp "^4.0.0"
eslint-scope "^5.1.1" eslint-scope "^6.0.0"
eslint-utils "^2.1.0" eslint-utils "^3.0.0"
eslint-visitor-keys "^2.0.0" eslint-visitor-keys "^3.0.0"
espree "^7.3.1" espree "^9.0.0"
esquery "^1.4.0" esquery "^1.4.0"
esutils "^2.0.2" esutils "^2.0.2"
fast-deep-equal "^3.1.3" fast-deep-equal "^3.1.3"
file-entry-cache "^6.0.1" file-entry-cache "^6.0.1"
functional-red-black-tree "^1.0.1" functional-red-black-tree "^1.0.1"
glob-parent "^5.1.2" glob-parent "^6.0.1"
globals "^13.6.0" globals "^13.6.0"
ignore "^4.0.6" ignore "^4.0.6"
import-fresh "^3.0.0" import-fresh "^3.0.0"
imurmurhash "^0.1.4" imurmurhash "^0.1.4"
is-glob "^4.0.0" is-glob "^4.0.0"
js-yaml "^3.13.1" js-yaml "^4.1.0"
json-stable-stringify-without-jsonify "^1.0.1" json-stable-stringify-without-jsonify "^1.0.1"
levn "^0.4.1" levn "^0.4.1"
lodash.merge "^4.6.2" lodash.merge "^4.6.2"
@ -4335,11 +4342,10 @@ eslint@7.32.0:
natural-compare "^1.4.0" natural-compare "^1.4.0"
optionator "^0.9.1" optionator "^0.9.1"
progress "^2.0.0" progress "^2.0.0"
regexpp "^3.1.0" regexpp "^3.2.0"
semver "^7.2.1" semver "^7.2.1"
strip-ansi "^6.0.0" strip-ansi "^6.0.0"
strip-json-comments "^3.1.0" strip-json-comments "^3.1.0"
table "^6.0.9"
text-table "^0.2.0" text-table "^0.2.0"
v8-compile-cache "^2.0.3" v8-compile-cache "^2.0.3"
@ -4357,14 +4363,14 @@ espree@^6.2.1:
acorn-jsx "^5.2.0" acorn-jsx "^5.2.0"
eslint-visitor-keys "^1.1.0" eslint-visitor-keys "^1.1.0"
espree@^7.3.0, espree@^7.3.1: espree@^9.0.0:
version "7.3.1" version "9.0.0"
resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6" resolved "https://registry.yarnpkg.com/espree/-/espree-9.0.0.tgz#e90a2965698228502e771c7a58489b1a9d107090"
integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g== integrity sha512-r5EQJcYZ2oaGbeR0jR0fFVijGOcwai07/690YRXLINuhmVeRY4UKSAsQPe/0BNuDgwP7Ophoc1PRsr2E3tkbdQ==
dependencies: dependencies:
acorn "^7.4.0" acorn "^8.5.0"
acorn-jsx "^5.3.1" acorn-jsx "^5.3.1"
eslint-visitor-keys "^1.3.0" eslint-visitor-keys "^3.0.0"
esprima@^2.6.0: esprima@^2.6.0:
version "2.7.3" version "2.7.3"
@ -5043,12 +5049,12 @@ glob-parent@^5.1.0, glob-parent@~5.1.0:
dependencies: dependencies:
is-glob "^4.0.1" is-glob "^4.0.1"
glob-parent@^5.1.2: glob-parent@^6.0.1:
version "5.1.2" version "6.0.2"
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3"
integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==
dependencies: dependencies:
is-glob "^4.0.1" is-glob "^4.0.3"
glob-stream@^6.1.0: glob-stream@^6.1.0:
version "6.1.0" version "6.1.0"
@ -5763,7 +5769,7 @@ ip-cidr@3.0.4:
ip-address "^7.1.0" ip-address "^7.1.0"
jsbn "^1.1.0" jsbn "^1.1.0"
ip-regex@^4.3.0: ip-regex@^4.0.0, ip-regex@^4.3.0:
version "4.3.0" version "4.3.0"
resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-4.3.0.tgz#687275ab0f57fa76978ff8f4dddc8a23d5990db5" resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-4.3.0.tgz#687275ab0f57fa76978ff8f4dddc8a23d5990db5"
integrity sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q== integrity sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==
@ -5773,6 +5779,11 @@ ip@^1.1.5:
resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a"
integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=
ipaddr.js@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.0.1.tgz#eca256a7a877e917aeb368b0a7497ddf42ef81c0"
integrity sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng==
is-absolute-url@^2.0.0: is-absolute-url@^2.0.0:
version "2.1.0" version "2.1.0"
resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6" resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6"
@ -5951,6 +5962,13 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1:
dependencies: dependencies:
is-extglob "^2.1.1" is-extglob "^2.1.1"
is-glob@^4.0.3:
version "4.0.3"
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
dependencies:
is-extglob "^2.1.1"
is-installed-globally@~0.4.0: is-installed-globally@~0.4.0:
version "0.4.0" version "0.4.0"
resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.4.0.tgz#9a0fd407949c30f86eb6959ef1b7994ed0b7b520" resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.4.0.tgz#9a0fd407949c30f86eb6959ef1b7994ed0b7b520"
@ -5959,6 +5977,13 @@ is-installed-globally@~0.4.0:
global-dirs "^3.0.0" global-dirs "^3.0.0"
is-path-inside "^3.0.2" is-path-inside "^3.0.2"
is-ip@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/is-ip/-/is-ip-3.1.0.tgz#2ae5ddfafaf05cb8008a62093cf29734f657c5d8"
integrity sha512-35vd5necO7IitFPjd/YBeqwWnyDWbuLH9ZXQdMfDA8TEo7pv5X8yfrvVO3xbJbLUlERCMvf6X0hTUamQxCYJ9Q==
dependencies:
ip-regex "^4.0.0"
is-lambda@^1.0.1: is-lambda@^1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5" resolved "https://registry.yarnpkg.com/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5"
@ -6241,7 +6266,7 @@ js-yaml@4.0.0:
dependencies: dependencies:
argparse "^2.0.1" argparse "^2.0.1"
js-yaml@4.1.0, js-yaml@^4.0.0: js-yaml@4.1.0, js-yaml@^4.0.0, js-yaml@^4.1.0:
version "4.1.0" version "4.1.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602"
integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==
@ -6838,11 +6863,6 @@ lodash.bind@^4.1.4:
resolved "https://registry.yarnpkg.com/lodash.bind/-/lodash.bind-4.2.1.tgz#7ae3017e939622ac31b7d7d7dcb1b34db1690d35" resolved "https://registry.yarnpkg.com/lodash.bind/-/lodash.bind-4.2.1.tgz#7ae3017e939622ac31b7d7d7dcb1b34db1690d35"
integrity sha1-euMBfpOWIqwxt9fX3LGzTbFpDTU= integrity sha1-euMBfpOWIqwxt9fX3LGzTbFpDTU=
lodash.clonedeep@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef"
integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=
lodash.defaults@^4.0.1, lodash.defaults@^4.2.0: lodash.defaults@^4.0.1, lodash.defaults@^4.2.0:
version "4.2.0" version "4.2.0"
resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c"
@ -6923,11 +6943,6 @@ lodash.sortby@^4.7.0:
resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"
integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=
lodash.truncate@^4.4.2:
version "4.4.2"
resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193"
integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=
lodash.uniq@^4.5.0: lodash.uniq@^4.5.0:
version "4.5.0" version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
@ -7560,10 +7575,10 @@ node-releases@^1.1.70, node-releases@^1.1.71:
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.71.tgz#cb1334b179896b1c89ecfdd4b725fb7bbdfc7dbb" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.71.tgz#cb1334b179896b1c89ecfdd4b725fb7bbdfc7dbb"
integrity sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg== integrity sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg==
nodemailer@6.6.5: nodemailer@6.7.0:
version "6.6.5" version "6.7.0"
resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.6.5.tgz#f9f6953cee5cfe82cbea152eeddacf7a0442049a" resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.7.0.tgz#86614722c4e0c33d1b5b02aecb90d6d629932b0d"
integrity sha512-C/v856DBijUzHcHIgGpQoTrfsH3suKIRAGliIzCstatM2cAa+MYX3LuyCrABiO/cdJTxgBBHXxV1ztiqUwst5A== integrity sha512-AtiTVUFHLiiDnMQ43zi0YgkzHOEWUkhDgPlBXrsDzJiJvB29Alo4OKxHQ0ugF3gRqRQIneCLtZU3yiUo7pItZw==
nofilter@^2.0.3: nofilter@^2.0.3:
version "2.0.3" version "2.0.3"
@ -8398,10 +8413,10 @@ postcss-filter-plugins@^2.0.0:
dependencies: dependencies:
postcss "^5.0.4" postcss "^5.0.4"
postcss-loader@6.1.1: postcss-loader@6.2.0:
version "6.1.1" version "6.2.0"
resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-6.1.1.tgz#58dd0a3accd9bc87cc52eff75244db578d11301a" resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-6.2.0.tgz#714370a3f567141cf4cadcdf9575f5234d186bc5"
integrity sha512-lBmJMvRh1D40dqpWKr9Rpygwxn8M74U9uaCSeYGNKLGInbk9mXBt1ultHf2dH9Ghk6Ue4UXlXWwGMH9QdUJ5ug== integrity sha512-H9hv447QjQJVDbHj3OUdciyAXY3v5+UDduzEytAlZCVHCpNAAg/mCSwhYYqZr9BiGYhmYspU8QXxZwiHTLn3yA==
dependencies: dependencies:
cosmiconfig "^7.0.0" cosmiconfig "^7.0.0"
klona "^2.0.4" klona "^2.0.4"
@ -8911,12 +8926,14 @@ prismjs@1.25.0:
resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.25.0.tgz#6f822df1bdad965734b310b315a23315cf999756" resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.25.0.tgz#6f822df1bdad965734b310b315a23315cf999756"
integrity sha512-WCjJHl1KEWbnkQom1+SzftbtXMKQoezOCYs5rECqMN+jP+apI7ftoflyqigqzopSO3hMhTEb0mFClA8lkolgEg== integrity sha512-WCjJHl1KEWbnkQom1+SzftbtXMKQoezOCYs5rECqMN+jP+apI7ftoflyqigqzopSO3hMhTEb0mFClA8lkolgEg==
private-ip@2.2.1: private-ip@2.3.0:
version "2.2.1" version "2.3.0"
resolved "https://registry.yarnpkg.com/private-ip/-/private-ip-2.2.1.tgz#4fe167d04e12eca5c67cdcbd3224e86b38c79253" resolved "https://registry.yarnpkg.com/private-ip/-/private-ip-2.3.0.tgz#aa07bf623c60ea75ee5d140814f492648c001717"
integrity sha512-jN1WT/br/VNW9xEcwHr6DjtOKxQ5qOIqmh7o+co2TWgq56pZJw99iO3UT1tWdfgsQiyK9FqG4ji3ykwpjFqITA== integrity sha512-3lTFzg+Z1Q2VNQChw8AW2c5LM7getyUJ67SqeWtvnkUO4gihjbf5oIEK4+jAQ4v1sCqOVV7r+GzKrgowW/W3tw==
dependencies: dependencies:
ip-regex "^4.3.0" ip-regex "^4.3.0"
ipaddr.js "^2.0.1"
is-ip "^3.1.0"
netmask "^2.0.2" netmask "^2.0.2"
probe-image-size@7.2.1: probe-image-size@7.2.1:
@ -9411,10 +9428,10 @@ regex-not@^1.0.0, regex-not@^1.0.2:
extend-shallow "^3.0.2" extend-shallow "^3.0.2"
safe-regex "^1.1.0" safe-regex "^1.1.0"
regexpp@^3.1.0: regexpp@^3.2.0:
version "3.1.0" version "3.2.0"
resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2"
integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q== integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==
remove-bom-buffer@^3.0.0: remove-bom-buffer@^3.0.0:
version "3.0.0" version "3.0.0"
@ -9739,18 +9756,18 @@ safe-regex@^1.1.0:
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
sass-loader@12.1.0: sass-loader@12.2.0:
version "12.1.0" version "12.2.0"
resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-12.1.0.tgz#b73324622231009da6fba61ab76013256380d201" resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-12.2.0.tgz#b370010fb0ababae2ef9c6c89e05d6c6debc6042"
integrity sha512-FVJZ9kxVRYNZTIe2xhw93n3xJNYZADr+q69/s98l9nTCrWASo+DR2Ot0s5xTKQDDEosUkatsGeHxcH4QBp5bSg== integrity sha512-qducnp5vSV+8A8MZxuH6zV0MUg4MOVISScl2wDTCAn/2WJX+9Auxh92O/rnkdR2bvi5QxZBafnzkzRrWGZvm7w==
dependencies: dependencies:
klona "^2.0.4" klona "^2.0.4"
neo-async "^2.6.2" neo-async "^2.6.2"
sass@1.42.1: sass@1.43.2:
version "1.42.1" version "1.43.2"
resolved "https://registry.yarnpkg.com/sass/-/sass-1.42.1.tgz#5ab17bebc1cb1881ad2e0c9a932c66ad64e441e2" resolved "https://registry.yarnpkg.com/sass/-/sass-1.43.2.tgz#c02501520c624ad6622529a8b3724eb08da82d65"
integrity sha512-/zvGoN8B7dspKc5mC6HlaygyCBRvnyzzgD5khiaCfglWztY99cYoiTUksVx11NlnemrcfH5CEaCpsUKoW0cQqg== integrity sha512-DncYhjl3wBaPMMJR0kIUaH3sF536rVrOcqqVGmTZHQRRzj7LQlyGV7Mb8aCKFyILMr5VsPHwRYtyKpnKYlmQSQ==
dependencies: dependencies:
chokidar ">=3.0.0 <4.0.0" chokidar ">=3.0.0 <4.0.0"
@ -10620,28 +10637,16 @@ syslog-pro@1.0.0:
dependencies: dependencies:
moment "^2.22.2" moment "^2.22.2"
systeminformation@5.9.4: systeminformation@5.9.7:
version "5.9.4" version "5.9.7"
resolved "https://registry.yarnpkg.com/systeminformation/-/systeminformation-5.9.4.tgz#1f0e29e0aa376dec8f69cc517eeefc5cdcda411a" resolved "https://registry.yarnpkg.com/systeminformation/-/systeminformation-5.9.7.tgz#8a5041d3aa1518e962b17740e20a3c75ff390e6d"
integrity sha512-FOsiTn0CyJZoj9kIhla11ndsMzbbwwuriul81wpqIBt9IpbxHZ6P/oZCphIFgJrwqjTnme0Qp1HDzIkUD9Xr/g== integrity sha512-Vcmc8HaWPMFM4DoasuKN2lpvIwS2AqaoPuEGZc4HCT6tlRJH+IQ5GhA2BrUgjpBDJjFMj2Bti6qLOzP3T1arCw==
syuilo-password-strength@0.0.1: syuilo-password-strength@0.0.1:
version "0.0.1" version "0.0.1"
resolved "https://registry.yarnpkg.com/syuilo-password-strength/-/syuilo-password-strength-0.0.1.tgz#08f71a8f0ecb77db649f3d9a6424510d9d945f52" resolved "https://registry.yarnpkg.com/syuilo-password-strength/-/syuilo-password-strength-0.0.1.tgz#08f71a8f0ecb77db649f3d9a6424510d9d945f52"
integrity sha1-CPcajw7Ld9tknz2aZCRRDZ2UX1I= integrity sha1-CPcajw7Ld9tknz2aZCRRDZ2UX1I=
table@^6.0.9:
version "6.7.1"
resolved "https://registry.yarnpkg.com/table/-/table-6.7.1.tgz#ee05592b7143831a8c94f3cee6aae4c1ccef33e2"
integrity sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==
dependencies:
ajv "^8.0.1"
lodash.clonedeep "^4.5.0"
lodash.truncate "^4.4.2"
slice-ansi "^4.0.0"
string-width "^4.2.0"
strip-ansi "^6.0.0"
tapable@^2.1.1, tapable@^2.2.0: tapable@^2.1.1, tapable@^2.2.0:
version "2.2.0" version "2.2.0"
resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.0.tgz#5c373d281d9c672848213d0e037d1c4165ab426b" resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.0.tgz#5c373d281d9c672848213d0e037d1c4165ab426b"
@ -10972,12 +10977,12 @@ ts-loader@9.2.6:
micromatch "^4.0.0" micromatch "^4.0.0"
semver "^7.3.4" semver "^7.3.4"
ts-node@10.2.1: ts-node@10.3.0:
version "10.2.1" version "10.3.0"
resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.2.1.tgz#4cc93bea0a7aba2179497e65bb08ddfc198b3ab5" resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.3.0.tgz#a797f2ed3ff50c9a5d814ce400437cb0c1c048b4"
integrity sha512-hCnyOyuGmD5wHleOQX6NIjJtYVIO8bPP8F2acWkB4W06wdlkgyvJtubO/I9NkI88hCFECbsEgoLc0VNkYmcSfw== integrity sha512-RYIy3i8IgpFH45AX4fQHExrT8BxDeKTdC83QFJkNzkvt8uFB6QJ8XMyhynYiKMLxt9a7yuXaDBZNOYS3XjDcYw==
dependencies: dependencies:
"@cspotcode/source-map-support" "0.6.1" "@cspotcode/source-map-support" "0.7.0"
"@tsconfig/node10" "^1.0.7" "@tsconfig/node10" "^1.0.7"
"@tsconfig/node12" "^1.0.7" "@tsconfig/node12" "^1.0.7"
"@tsconfig/node14" "^1.0.0" "@tsconfig/node14" "^1.0.0"
@ -11187,10 +11192,10 @@ typeorm@0.2.38:
yargs "^17.0.1" yargs "^17.0.1"
zen-observable-ts "^1.0.0" zen-observable-ts "^1.0.0"
typescript@4.4.3: typescript@4.4.4:
version "4.4.3" version "4.4.4"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.4.3.tgz#bdc5407caa2b109efd4f82fe130656f977a29324" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.4.4.tgz#2cd01a1a1f160704d3101fd5a58ff0f9fcb8030c"
integrity sha512-4xfscpisVgqqDfPaJo5vkd+Qd/ItkoagnHpufr+i2QCHBsNYp+G7UAoyFl8aPtx879u38wPV65rZ8qbGZijalA== integrity sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==
uc.micro@^1.0.1, uc.micro@^1.0.5: uc.micro@^1.0.1, uc.micro@^1.0.5:
version "1.0.6" version "1.0.6"
@ -11558,16 +11563,16 @@ vue-svg-loader@0.17.0-beta.2:
semver "^7.3.2" semver "^7.3.2"
svgo "^1.3.2" svgo "^1.3.2"
vue@3.2.19: vue@3.2.20:
version "3.2.19" version "3.2.20"
resolved "https://registry.yarnpkg.com/vue/-/vue-3.2.19.tgz#da2c80a6a0271c7097fee9e31692adfd9d569c8f" resolved "https://registry.yarnpkg.com/vue/-/vue-3.2.20.tgz#940f8aa8bf3e3be78243ca582bad41fcd45ae3e6"
integrity sha512-6KAMdIfAtlK+qohTIUE4urwAv4A3YRuo8uAbByApUmiB0CziGAAPs6qVugN6oHPia8YIafHB/37K0O6KZ7sGmA== integrity sha512-81JjEP4OGk9oO8+CU0h2nFPGgJBm9mNa3kdCX2k6FuRdrWrC+CNe+tOnuIeTg8EWwQuI+wwdra5Q7vSzp7p4Iw==
dependencies: dependencies:
"@vue/compiler-dom" "3.2.19" "@vue/compiler-dom" "3.2.20"
"@vue/compiler-sfc" "3.2.19" "@vue/compiler-sfc" "3.2.20"
"@vue/runtime-dom" "3.2.19" "@vue/runtime-dom" "3.2.20"
"@vue/server-renderer" "3.2.19" "@vue/server-renderer" "3.2.20"
"@vue/shared" "3.2.19" "@vue/shared" "3.2.20"
vuedraggable@4.0.1: vuedraggable@4.0.1:
version "4.0.1" version "4.0.1"
@ -11679,10 +11684,10 @@ webpack-sources@^3.2.0:
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.0.tgz#b16973bcf844ebcdb3afde32eda1c04d0b90f89d" resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.0.tgz#b16973bcf844ebcdb3afde32eda1c04d0b90f89d"
integrity sha512-fahN08Et7P9trej8xz/Z7eRu8ltyiygEo/hnRi9KqBUs80KeDcnf96ZJo++ewWd84fEf3xSX9bp4ZS9hbw0OBw== integrity sha512-fahN08Et7P9trej8xz/Z7eRu8ltyiygEo/hnRi9KqBUs80KeDcnf96ZJo++ewWd84fEf3xSX9bp4ZS9hbw0OBw==
webpack@5.58.0: webpack@5.58.2:
version "5.58.0" version "5.58.2"
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.58.0.tgz#9ec621cf8534f23c25e779e7c35dfde1211d5ccb" resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.58.2.tgz#6b4af12fc9bd5cbedc00dc0a2fc2b9592db16b44"
integrity sha512-xc2k5MLbR1iah24Z5xUm1nBh1PZXEdUnrX6YkTSOScq/VWbl5JCLREXJzGYqEAUbIO8tZI+Dzv82lGtnuUnVCQ== integrity sha512-3S6e9Vo1W2ijk4F4PPWRIu6D/uGgqaPmqw+av3W3jLDujuNkdxX5h5c+RQ6GkjVR+WwIPOfgY8av+j5j4tMqJw==
dependencies: dependencies:
"@types/eslint-scope" "^3.7.0" "@types/eslint-scope" "^3.7.0"
"@types/estree" "^0.0.50" "@types/estree" "^0.0.50"