diff --git a/.github/ISSUE_TEMPLATE/01_bug-report.md b/.github/ISSUE_TEMPLATE/01_bug-report.md index 019f8c739ddf2d4e04a70c1fcccf677c514733c4..8734fc0c3645f3ec8bb64e8561fcf803f430483c 100644 --- a/.github/ISSUE_TEMPLATE/01_bug-report.md +++ b/.github/ISSUE_TEMPLATE/01_bug-report.md @@ -16,11 +16,11 @@ First, in order to avoid duplicate Issues, please search to see if the problem y <!-- Tell us what the bug is --> -## 🙂 Expected Behavior +## 🥰 Expected Behavior <!--- Tell us what should happen --> -## â˜¹ï¸ Actual Behavior +## 🤬 Actual Behavior <!--- Tell us what happens instead of the expected behavior --> @@ -33,3 +33,7 @@ First, in order to avoid duplicate Issues, please search to see if the problem y ## 📌 Environment <!-- Tell us where on the platform it happens --> + +Misskey version: +Your OS: +Your browser: diff --git a/CHANGELOG.md b/CHANGELOG.md index 65f5e01947ca278581693fa6fd5ce6828b15f89d..b60a85cf1ec54ddcb823fe846fb1ee69928c4a5e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,11 +2,46 @@ ## 12.x.x (unreleased) ### Improvements +- ### Bugfixes +- +You should also include the user name that made the change. --> +## 12.104.0 (2022/02/09) + +### Note +ã“ã®ãƒªãƒªãƒ¼ã‚¹ã¯ãƒžã‚¤ã‚°ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã®è¦æ¨¡ãŒå¤§ãã„ãŸã‚ã€ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ã«ã‚ˆã£ã¦ã¯ãƒžã‚¤ã‚°ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã«æ™‚é–“ãŒã‹ã‹ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚ +マイグレーションãŒçµ‚ã‚らãªã„å ´åˆã¯ã€ãƒãƒ£ãƒ¼ãƒˆã®æƒ…å ±ã¯ãƒªã‚»ãƒƒãƒˆã•ã‚Œã¦ã—ã¾ã„ã¾ã™ãŒ`__chart__`ã§å§‹ã¾ã‚‹ãƒ†ãƒ¼ãƒ–ルã®**レコード**ã‚’å…¨ã¦å‰Šé™¤(テーブル自体ã¯æ¶ˆã•ãªã„ã§ãã ã•ã„)ã—ã¦ã‹ã‚‰å†åº¦è©¦ã™æ–¹æ³•ã‚‚ã‚ã‚Šã¾ã™ã€‚ + +### Improvements +- ãƒãƒ£ãƒ¼ãƒˆã‚¨ãƒ³ã‚¸ãƒ³ã®å¼·åŒ– @syuilo + - テーブルサイズã®å‰Šæ¸› + - notes/instance/perUserNotesãƒãƒ£ãƒ¼ãƒˆã«æ·»ä»˜ãƒ•ã‚¡ã‚¤ãƒ«ä»˜ãノートã®æ•°ã‚’è¿½åŠ + - activeUsersãƒãƒ£ãƒ¼ãƒˆã«æ–°ã—ã„é …ç›®ã‚’è¿½åŠ + - federationãƒãƒ£ãƒ¼ãƒˆã«æ–°ã—ã„é …ç›®ã‚’è¿½åŠ + - apRequestãƒãƒ£ãƒ¼ãƒˆã‚’è¿½åŠ + - networkãƒãƒ£ãƒ¼ãƒˆå»ƒæ¢ +- クライアント: è‡ªã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹æƒ…å ±ãƒšãƒ¼ã‚¸ã§ãƒãƒ£ãƒ¼ãƒˆã‚’見れるよã†ã« @syuilo +- クライアント: デãƒã‚¤ã‚¹ã®ç¨®é¡žã‚’手動指定ã§ãるよã†ã« @syuilo +- クライアント: UIã®ã‚¢ã‚¤ã‚³ãƒ³ã‚’æ›´æ–° @syuilo +- クライアント: UIã®ã‚¢ã‚¤ã‚³ãƒ³ã‚’セルフホスティングã™ã‚‹ã‚ˆã†ã« @syuilo +- NodeInfo ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼æ•°ã¨æŠ•ç¨¿æ•°ã®å†…容を見直㙠@xianonn + +### Bugfixes +- Client: タイムライン種別を切り替ãˆã‚‹ã¨ã€Œæ–°ã—ã„ノートãŒã‚ã‚Šã¾ã™ã€ã®è¡¨ç¤ºãŒæ®‹ç•™ã—ã¦ã—ã¾ã†ã®ã‚’ä¿®æ£ @tamaina +- Client: UIã®ã‚µã‚¤ã‚ºãŒãŠã‹ã—ããªã‚‹å•é¡Œã®ä¿®æ£ @tamaina +- Client: Setting instance information of notes to always show breaks the timeline @Johann150 +- Client: 環境ã«ä¾ã£ã¦ã¯è¿”ä¿¡ã™ã‚‹éš›ã®ã‚«ãƒ¼ã‚½ãƒ«ä½ç½®ãŒæ£ã—ããªã„å•é¡Œã‚’ä¿®æ£ @syuilo +- Client: コントãƒãƒ¼ãƒ«ãƒ‘ãƒãƒ«ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã€ãƒ•ã‚¡ã‚¤ãƒ«ã«ã¦ã€ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ã®è¡¨ç¤ºç¯„囲切り替ãˆãŒæ©Ÿèƒ½ã—ãªã„å•é¡Œã‚’ä¿®æ£ @syuilo +- Client: アップデートãŠçŸ¥ã‚‰ã›ãƒ€ã‚¤ã‚¢ãƒã‚°ãŒå‡ºãªã„ã®ã‚’ä¿®æ£ @syuilo +- Client: Follows/Followers Visibility changes won't be saved unless clicking on an other checkbox @Johann150 +- API: Fix API cast @mei23 +- add instance favicon where it's missing @solfisher +- ãƒãƒ£ãƒ¼ãƒˆã®å®šæœŸresyncãŒå‹•ä½œã—ã¦ã„ãªã„å•é¡Œã‚’ä¿®æ£ @syuilo + ## 12.103.1 (2022/02/02) ### Bugfixes diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 662fa709b5251606e0dba6e42ad21e1537b5ca81..6e0f500be5d316e09cc083a56a11126b8486eb9d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -16,6 +16,9 @@ Before creating an issue, please check the following: ## 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. +At this point, you also need to clarify the goals of the PR you will create, and make sure that the other members of the team are aware of them. +PRs that do not have a clear set of do's and don'ts tend to be bloated and difficult to review. + Also, when you start implementation, assign yourself to the Issue (if you cannot do it yourself, ask another member to assign you). By expressing your intention to work the Issue, you can prevent conflicts in the work. ## Well-known branches @@ -39,6 +42,23 @@ Thank you for your PR! Before creating a PR, please check the following: Thanks for your cooperation 🤗 +## Reviewers guide +Be willing to comment on the good points and not just the things you want fixed 💯 + +### Review perspective +- Scope + - Are the goals of the PR clear? + - Is the granularity of the PR appropriate? +- Security + - Does merging this PR create a vulnerability? +- Performance + - Will merging this PR cause unexpected performance degradation? + - Is there a more efficient way? +- Testing + - Does the test ensure the expected behavior? + - Are there any omissions or gaps? + - Does it check for anomalies? + ## Localization (l10n) Misskey uses [Crowdin](https://crowdin.com/project/misskey) for localization management. You can improve our translations with your Crowdin account. diff --git a/gulpfile.js b/gulpfile.js index 3bc0b23beef6122bb7c1566bd7d6d2c2e270a3f8..b7aa4e328e1cbdf4e8169e057642d88f24e3b385 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -19,6 +19,10 @@ gulp.task('copy:client:fonts', () => gulp.src('./packages/client/node_modules/three/examples/fonts/**/*').pipe(gulp.dest('./built/_client_dist_/fonts/')) ); +gulp.task('copy:client:fontawesome', () => + gulp.src('./packages/client/node_modules/@fortawesome/fontawesome-free/**/*').pipe(gulp.dest('./built/_client_dist_/fontawesome/')) +); + gulp.task('copy:client:locales', cb => { fs.mkdirSync('./built/_client_dist_/locales', { recursive: true }); @@ -50,7 +54,7 @@ gulp.task('build:backend:style', () => { }); gulp.task('build', gulp.parallel( - 'copy:client:locales', 'copy:backend:views', 'build:backend:script', 'build:backend:style', 'copy:client:fonts' + 'copy:client:locales', 'copy:backend:views', 'build:backend:script', 'build:backend:style', 'copy:client:fonts', 'copy:client:fontawesome' )); gulp.task('default', gulp.task('build')); diff --git a/locales/ar-SA.yml b/locales/ar-SA.yml index 5a053cdee918910035bd99558ad41868bba84a26..914a16bb2fafdffd3cfb2745a8250cd95099fbe1 100644 --- a/locales/ar-SA.yml +++ b/locales/ar-SA.yml @@ -1110,6 +1110,8 @@ _exportOrImport: blockingList: "المستخدمون المØجوبون" userLists: "القوائم" _charts: + federation: "الÙديرالية" + apRequest: "الطلبات" usersIncDec: "اختلا٠عدد المستخدمين" usersTotal: "مجموع عدد المستخدمين والمستخدمات" activeUsers: "المستخدمون النشطون" diff --git a/locales/bn-BD.yml b/locales/bn-BD.yml index 02f18cd1e95be6ad5fa5d8b5ce1c684c16674843..fa18a8b3d0d69cf79b3463d129a2c0104dc62560 100644 --- a/locales/bn-BD.yml +++ b/locales/bn-BD.yml @@ -141,6 +141,8 @@ flagAsBot: "বট হিসাবে চিহà§à¦¨à¦¿à¦¤ করà§à¦¨" flagAsBotDescription: "à¦à¦‡ অà§à¦¯à¦¾à¦•à¦¾à¦‰à¦¨à§à¦Ÿà¦Ÿà¦¿ যদি à¦à¦•à¦Ÿà¦¿ পà§à¦°à§‹à¦—à§à¦°à¦¾à¦® দà§à¦¬à¦¾à¦°à¦¾ পরিচালিত হয়, তাহলে à¦à¦‡ অপশনটি চালৠকরà§à¦¨à¥¤ ইনà§à¦Ÿà¦¾à¦°à¦…à§à¦¯à¦¾à¦•à¦¶à¦¾à¦¨ চেইনিং রোধ করতে, মিসà§à¦•à¦¿à¦° সিসà§à¦Ÿà§‡à¦® পরিচালনাকে বট-বানà§à¦§à¦¬ করতে à¦à¦¬à¦‚ অনà§à¦¯à¦¾à¦¨à§à¦¯ ডেà¦à§‡à¦²à¦ªà¦¾à¦°à¦¦à§‡à¦° সাহাযà§à¦¯ করতে আপনার বট ঠà¦à¦‡ অপশনটি চালৠকরà§à¦¨à§·" flagAsCat: "বিড়াল হিসাবে চিহà§à¦¨à¦¿à¦¤ করà§à¦¨" flagAsCatDescription: "অà§à¦¯à¦¾à¦•à¦¾à¦‰à¦¨à§à¦Ÿà¦Ÿà¦¿à¦•à§‡ বিড়াল হিসাবে চিহà§à¦¨à¦¿à¦¤ করার জনà§à¦¯ অপশনটি চালৠকরà§à¦¨à¥¤" +flagShowTimelineReplies: "টাইমলাইনে নোটগà§à¦²à¦¿à¦° রিপà§à¦²à¦¾à¦‡ দেখান" +flagShowTimelineRepliesDescription: "চালৠকরলে, টাইমলাইন বà§à¦¯à¦¬à¦¹à¦¾à¦°à¦•à¦¾à¦°à§€à¦° নোট ছাড়াও বà§à¦¯à¦¬à¦¹à¦¾à¦°à¦•à¦¾à¦°à§€à¦° অনà§à¦¯à¦¾à¦¨à§à¦¯ নোটের জবাবগà§à¦²à§‹ দেখায়।" autoAcceptFollowed: "আপনি যেসব অà§à¦¯à¦¾à¦•à¦¾à¦‰à¦¨à§à¦Ÿ অনà§à¦¸à¦°à¦£ করেন, সà§à¦¬à§Ÿà¦‚কà§à¦°à¦¿à§Ÿà¦à¦¾à¦¬à§‡ তাদের অনà§à¦¸à¦°à¦£à§‡à¦° অনà§à¦°à¦§ সà§à¦¬à§€à¦•à¦¾à¦° করà§à¦¨" addAccount: "অà§à¦¯à¦¾à¦•à¦¾à¦‰à¦¨à§à¦Ÿ যোগ করà§à¦¨" loginFailed: "পà§à¦°à¦¬à§‡à¦¶ করা যায়নি" @@ -297,8 +299,8 @@ disconnectedFromServer: "সারà§à¦à¦¾à¦° থেকে সংযোগ ব reload: "আবার লোড করà§à¦¨" doNothing: "কিছৠকরবেন না" reloadConfirm: "আপনি কি রিলোড করতে চান?" -watch: "দেখà§à¦¨" -unwatch: "দেখা বনà§à¦§ করà§à¦¨ " +watch: "বিজà§à¦žà¦ªà§à¦¤à¦¿ পান" +unwatch: "বিজà§à¦žà¦ªà§à¦¤à¦¿ পাওয়া বনà§à¦§ করà§à¦¨ " accept: "অনà§à¦®à§‹à¦¦à¦¨" reject: "পà§à¦°à¦¤à§à¦¯à¦¾à¦–à§à¦¯à¦¾à¦¨" normal: "সà§à¦¬à¦¾à¦à¦¾à¦¬à¦¿à¦•" @@ -345,6 +347,8 @@ hcaptchaSecretKey: "সিকà§à¦°à§‡à¦Ÿ কী" recaptcha: "reCAPTCHA" enableRecaptcha: "reCAPTCHA চালৠকরà§à¦¨" recaptchaSiteKey: "সাইট কী" +recaptchaSecretKey: "সিকà§à¦°à§‡à¦Ÿ কী" +avoidMultiCaptchaConfirm: "à¦à¦•à¦¾à¦§à¦¿à¦• Captcha বà§à¦¯à¦¬à¦¹à¦¾à¦° করলে তারা পরসà§à¦ªà¦°à§‡à¦° কাজে বাধা দিতে পারে। আপনি কি অনà§à¦¯à¦¾à¦¨à§à¦¯ Captcha নিষà§à¦•à§à¦°à¦¿à¦¯à¦¼ করতে চান? আপনি 'বাতিল' কà§à¦²à¦¿à¦• করার মাধà§à¦¯à¦®à§‡ à¦à¦•à¦¾à¦§à¦¿à¦• Captcha চালৠরাখতে পারেন।" antennas: "অà§à¦¯à¦¾à¦¨à§à¦Ÿà§‡à¦¨à¦¾" manageAntennas: "অà§à¦¯à¦¾à¦¨à§à¦Ÿà§‡à¦¨à¦¾ বà§à¦¯à¦¬à¦¸à§à¦¥à¦¾à¦ªà¦¨à¦¾" name: "নাম" @@ -396,8 +400,56 @@ uploadFolder: "আপলোডের জনà§à¦¯ ডিফলà§à¦Ÿ ফোল cacheClear: "কà§à¦¯à¦¾à¦¶ পরিষà§à¦•à¦¾à¦° করà§à¦¨" markAsReadAllNotifications: "সমসà§à¦¤ বিজà§à¦žà¦ªà§à¦¤à¦¿à¦—à§à¦²à¦¿ পঠিত হিসাবে চিহà§à¦¨à¦¿à¦¤ করà§à¦¨" markAsReadAllUnreadNotes: "সমসà§à¦¤ নোটগà§à¦²à¦¿ পঠিত হিসাবে চিহà§à¦¨à¦¿à¦¤ করà§à¦¨" +markAsReadAllTalkMessages: "সমসà§à¦¤ মেসেজ পঠিত হিসাবে চিহà§à¦¨à¦¿à¦¤ করà§à¦¨" +help: "সহায়তা" +inputMessageHere: "à¦à¦–ানে মেসেজ লিখà§à¦¨" +close: "বনà§à¦§" +group: "গà§à¦°à§à¦ª" +groups: "গà§à¦°à§à¦ªà¦¸à¦®à§‚হ" +createGroup: "গà§à¦°à§à¦ª তৈরী করà§à¦¨" +ownedGroups: "আপনার গà§à¦°à§à¦ªà¦—à§à¦²à¦¿" +joinedGroups: "যেসব গà§à¦°à§à¦ªà§‡ আপনি আছেন" invites: "আমনà§à¦¤à§à¦°à¦£" +groupName: "গà§à¦°à§à¦ªà§‡à¦° নাম" +members: "সদসà§à¦¯à¦¬à§ƒà¦¨à§à¦¦" +transfer: "হসà§à¦¤à¦¾à¦¨à§à¦¤à¦°" +messagingWithUser: "পà§à¦°à¦¾à¦‡à¦à§‡à¦Ÿ চà§à¦¯à¦¾à¦Ÿ" +messagingWithGroup: "গà§à¦°à§à¦ª চà§à¦¯à¦¾à¦Ÿ" +title: "শিরোনাম" +text: "পাঠà§à¦¯" +enable: "সকà§à¦°à¦¿à§Ÿ" +next: "পরবরà§à¦¤à§€" +retype: "পà§à¦¨à¦ƒ পà§à¦°à¦¬à§‡à¦¶" +noteOf: "{user} à¦à¦° নোট" +inviteToGroup: "গà§à¦°à§à¦ªà§‡ আমনà§à¦¤à§à¦°à¦£ জানান" +maxNoteTextLength: "নোট à¦à¦° সরà§à¦¬à§‹à¦šà§à¦š দৈরà§à¦˜à§à¦¯" +quoteAttached: "উদà§à¦§à§ƒà¦¤" +quoteQuestion: "উদà§à¦§à§ƒà¦¤à¦¿ হিসাবে সংযà§à¦•à§à¦¤ করবেন?" +noMessagesYet: "কোন মেসেজ নেই" +newMessageExists: "নতà§à¦¨ মেসেজ পেয়েছেন" +onlyOneFileCanBeAttached: "আপনি মেসেজের সাথে সরà§à¦¬à§‹à¦šà§à¦š à¦à¦•à¦Ÿà¦¿ ফাইল যà§à¦•à§à¦¤ করতে পারবেন" +signinRequired: "দয়া করে লগ ইন করà§à¦¨" invitations: "আমনà§à¦¤à§à¦°à¦£" +invitationCode: "ইনà¦à¦¾à¦‡à¦Ÿ কোড" +checking: "পরীকà§à¦·à¦¾ করা হচà§à¦›à§‡..." +available: "উপলবà§à¦§" +unavailable: "অনà§à¦ªà¦²à¦¬à§à¦§" +usernameInvalidFormat: "আপনি কেবলমাতà§à¦° a-z, A-Z, 0-9, _ বà§à¦¯à¦¬à¦¹à¦¾à¦° করতে পারেন" +tooShort: "খà§à¦¬ ছোট" +tooLong: "খà§à¦¬ বড়" +weakPassword: "দà§à¦°à§à¦¬à¦² পাসওয়ারà§à¦¡" +normalPassword: "সাধারণ পাসওয়ারà§à¦¡" +strongPassword: "শকà§à¦¤à¦¿à¦¶à¦¾à¦²à§€ পাসওয়ারà§à¦¡" +passwordMatched: "মিলেছে" +passwordNotMatched: "মিলেনি" +signinWith: "{x} à¦à¦° সাহাযà§à¦¯à§‡ সাইন ইন করà§à¦¨" +signinFailed: "লগ ইন করা যায়নি। আপনার বà§à¦¯à¦¬à¦¹à¦¾à¦°à¦•à¦¾à¦°à§€à¦° নাম à¦à¦¬à¦‚ পাসওয়ারà§à¦¡ চেক করà§à¦¨." +tapSecurityKey: "সিকিউরিটি কী সà§à¦ªà¦°à§à¦¶ করà§à¦¨" +or: "অথবা" +language: "à¦à¦¾à¦·à¦¾" +uiLanguage: "UI à¦à¦° à¦à¦¾à¦·à¦¾" +groupInvited: "আপনি à¦à¦•à¦Ÿà¦¿ গà§à¦°à§à¦ªà§‡ আমনà§à¦¤à§à¦°à¦¿à¦¤ হয়েছেন" +aboutX: "{x} সমà§à¦ªà¦°à§à¦•à§‡" useOsNativeEmojis: "অপারেটিং সিসà§à¦Ÿà§‡à¦®à§‡à¦° নেটিঠইমোজি বà§à¦¯à¦¬à¦¹à¦¾à¦° করà§à¦¨" disableDrawer: "ডà§à¦°à¦¯à¦¼à¦¾à¦° মেনৠপà§à¦°à¦¦à¦°à§à¦¶à¦¨ করবেন না" youHaveNoGroups: "আপনার কোন গà§à¦°à§à¦ª নেই " @@ -428,37 +480,704 @@ promotion: "পà§à¦°à¦®à§‹à¦¶à¦¨" promote: "পà§à¦°à¦šà¦¾à¦° করà§à¦¨" numberOfDays: "দিনের সংখà§à¦¯à¦¾" hideThisNote: "নোটটি লà§à¦•à¦¾à¦¨" +showFeaturedNotesInTimeline: "টাইমলাইনে সà§à¦ªà¦¾à¦°à¦¿à¦¶à¦•à§ƒà¦¤ নোটগà§à¦²à¦¿ দেখান" +objectStorage: "অবজেকà§à¦Ÿ সà§à¦Ÿà§‹à¦°à§‡à¦œ" +useObjectStorage: "অবজেকà§à¦Ÿ সà§à¦Ÿà§‹à¦°à§‡à¦œ বà§à¦¯à¦¾à¦¬à¦¹à¦¾à¦° করà§à¦¨" +objectStorageBaseUrl: "Base URL" +objectStorageBaseUrlDesc: "রেফারেনà§à¦¸ হিসাবে বà§à¦¯à¦¬à¦¹à§ƒà¦¤ URL। আপনি à¦à¦•à¦Ÿà¦¿ CDN বা পà§à¦°à¦•à§à¦¸à¦¿ বà§à¦¯à¦¬à¦¹à¦¾à¦° করলে URL, S3: 'https://<bucket>.s3.amazonaws.com', GCS: 'https://storage.googleapis.com/<bucket>'।" +objectStorageBucket: "Bucket" +objectStorageBucketDesc: "বà§à¦¯à¦¬à¦¹à¦¾à¦° করা পরিষেবার bucket à¦à¦° নাম লিখà§à¦¨à¥¤ " +objectStoragePrefix: "Prefix" +objectStoragePrefixDesc: "ফাইলসমূহ à¦à¦‡ prefix যà§à¦•à§à¦¤ ফোলà§à¦¡à¦¾à¦°à§‡à¦° অধীনে সংরকà§à¦·à¦£ করা হবে।" +objectStorageEndpoint: "à¦à¦¨à§à¦¡à¦ªà§Ÿà§‡à¦¨à§à¦Ÿ" +objectStorageEndpointDesc: "S3 à¦à¦° জনà§à¦¯ ফাà¦à¦•à¦¾ রাখà§à¦¨, অনà§à¦¯à¦¥à¦¾à¦¯à¦¼ পà§à¦°à¦¤à¦¿à¦Ÿà¦¿ পরিষেবার à¦à¦¨à§à¦¡à¦ªà§Ÿà§‡à¦¨à§à¦Ÿ নিরà§à¦¦à¦¿à¦·à§à¦Ÿ করà§à¦¨à¥¤ '<host>'বা'<host>: <port>' হিসেবে লিখà§à¦¨à¥¤" +objectStorageRegion: "Region" +objectStorageRegionDesc: "'xx-east-1'-à¦à¦° মতো à¦à¦•à¦Ÿà¦¿ region নিরà§à¦¦à¦¿à¦·à§à¦Ÿ করà§à¦¨à¥¤ যদি আপনার পরিষেবাতে region à¦à¦° ধারণা না থাকে, তাহলে à¦à¦Ÿà¦¿ খালি বা 'us-east-1' হওয়া উচিত।" +objectStorageUseSSL: "SSL বà§à¦¯à¦¾à¦¬à¦¹à¦¾à¦° করà§à¦¨" +objectStorageUseSSLDesc: "API কানেকশনগà§à¦²à¦¿à¦° জনà§à¦¯ যদি https বà§à¦¯à¦¾à¦¬à¦¹à¦¾à¦° না করেন, তাহলে à¦à¦‡ অপশনটি বনà§à¦§ করà§à¦¨" +objectStorageUseProxy: "Proxy বà§à¦¯à¦¾à¦¬à¦¹à¦¾à¦° করà§à¦¨" +objectStorageUseProxyDesc: "আপনি API সংযোগের জনà§à¦¯ proxy বà§à¦¯à¦¬à¦¹à¦¾à¦° না করলে, à¦à¦Ÿà¦¿ বনà§à¦§ করà§à¦¨à¥¤" +objectStorageSetPublicRead: "আপলোডের উপর ''public-read' সেট করà§à¦¨" +serverLogs: "সারà§à¦à¦¾à¦° লগ" +deleteAll: "সব মà§à¦›à§à¦¨" +showFixedPostForm: "টাইমলাইনের শীরà§à¦·à§‡ পোসà§à¦Ÿ করার ফরà§à¦®à¦Ÿà¦¿ দেখান" +newNoteRecived: "নতà§à¦¨ নোট আছে" +sounds: "শবà§à¦¦" +listen: "শà§à¦¨à§à¦¨" +none: "কিছà§à¦‡ না" +showInPage: "পেজে দেখান" +popout: "পপ-আউট" +volume: "আওয়াজের মাতà§à¦°à¦¾" +masterVolume: "মাসà§à¦Ÿà¦¾à¦° আওয়াজের মাতà§à¦°à¦¾" +details: "আরও জানà§à¦¨" +chooseEmoji: "ইমোজি নিরà§à¦¬à¦¾à¦šà¦¨ করà§à¦¨" +unableToProcess: "কাজটি সমà§à¦ªà¦¨à§à¦¨ করা যায়নি" +recentUsed: "সমà§à¦ªà§à¦°à¦¤à¦¿ বà§à¦¯à¦¬à¦¹à§ƒà¦¤" +install: "ইনà§à¦¸à¦Ÿà¦²" +uninstall: "আনইনà§à¦¸à¦Ÿà¦²" +installedApps: "ইনà§à¦¸à¦Ÿà¦² করা অà§à¦¯à¦¾à¦ªà¦¸à¦®à§‚হ" +nothing: "à¦à¦–ানে কিছà§à¦‡ নাই" +installedDate: "ইনà§à¦¸à¦Ÿà¦² করার তারিখ" +lastUsedDate: "সরà§à¦¬à¦¶à§‡à¦· বà§à¦¯à¦¾à¦¬à¦¹à§ƒà¦¤" +state: "অবসà§à¦¥à¦¾" +sort: "সাজান" +ascendingOrder: "ঊরà§à¦§à§à¦¬à¦•à§à¦°à¦®à§‡" +descendingOrder: "নিমà§à¦¨à¦•à§à¦°à¦®à§‡" +scratchpad: "সà§à¦•à§à¦°à§à¦¯à¦¾à¦šà¦ªà§à¦¯à¦¾à¦¡" +scratchpadDescription: "সà§à¦•à§à¦°à§à¦¯à¦¾à¦šà¦ªà§à¦¯à¦¾à¦¡ AiScript-à¦à¦° জনà§à¦¯ à¦à¦•à¦Ÿà¦¿ পরীকà§à¦·à¦¾à¦®à§‚লক পরিবেশ পà§à¦°à¦¦à¦¾à¦¨ করে। আপনি মিসà§à¦•à¦¿à¦° সাথে ইনà§à¦Ÿà¦¾à¦°à¦…à§à¦¯à¦¾à¦•à§à¦Ÿ করে à¦à¦®à¦¨ কোড লিখতে, চালাতে à¦à¦¬à¦‚ তার ফলাফল দেখতে পারেন।" +output: "আউটপà§à¦Ÿ" +script: "সà§à¦•à§à¦°à¦¿à¦ªà§à¦Ÿ" +disablePagesScript: "পেজগà§à¦²à§‹à¦¤à§‡ AiScript অকà§à¦·à¦® করà§à¦¨" +updateRemoteUser: "রিমোট বà§à¦¯à¦¬à¦¹à¦¾à¦°à¦•à¦¾à¦°à§€à¦° তথà§à¦¯ আপডেট করà§à¦¨" +deleteAllFiles: "সকল ফাইল ডিলিট করà§à¦¨" +deleteAllFilesConfirm: "সকল ফাইল ডিলিট করতে চান?" +removeAllFollowing: "সকল অনà§à¦¸à¦°à¦£ বাতিল করà§à¦¨" +removeAllFollowingDescription: "{host} à¦à¦° সকল বà§à¦¯à¦¾à¦¬à¦¹à¦¾à¦°à¦•à¦¾à¦°à§€à¦•à§‡ আর ফলোও করবেন না । যদি ইনà§à¦¸à¦¤à§à¦¯à¦¾à¦¨à§à¦¸à¦Ÿà¦¿à¦° কোন সমসà§à¦¯à¦¾ (যেমনঃ ইনà§à¦¸à¦¤à§à¦¯à¦¾à¦¨à§à¦¸à¦Ÿà¦¿ আর নেই) হয়ে থাকে তবে à¦à¦Ÿà¦¿ বà§à¦¯à¦¾à¦¬à¦¹à¦¾à¦° করà§à¦¨ । " +userSuspended: "à¦à¦‡ বà§à¦¯à¦¾à¦¬à¦¹à¦¾à¦°à¦•à¦¾à¦°à¦¿à¦° অà§à¦¯à¦¾à¦•à¦¾à¦‰à¦¨à§à¦Ÿ সà§à¦¥à¦—িত করা হয়েছে" +userSilenced: "à¦à¦‡ বà§à¦¯à¦¾à¦¬à¦¹à¦¾à¦°à¦•à¦¾à¦°à¦¿à¦•à§‡ মিউট করা হয়েছে" +yourAccountSuspendedTitle: "à¦à¦‡ অà§à¦¯à¦¾à¦•à¦¾à¦‰à¦¨à§à¦Ÿà¦Ÿà¦¿ সà§à¦¥à¦—িত করা হয়েছে" +yourAccountSuspendedDescription: "সারà§à¦à¦¾à¦°à§‡à¦° বà§à¦¯à¦¬à¦¹à¦¾à¦°à§‡à¦° শরà§à¦¤à¦¾à¦¬à¦²à§€ লঙà§à¦˜à¦¨à§‡à¦° মতো কারণে à¦à¦‡ অà§à¦¯à¦¾à¦•à¦¾à¦‰à¦¨à§à¦Ÿà¦Ÿà¦¿ সà§à¦¥à¦—িত করা হয়েছে৷ বিসà§à¦¤à¦¾à¦°à¦¿à¦¤ জানার জনà§à¦¯ পà§à¦°à¦¶à¦¾à¦¸à¦•à§‡à¦° সাথে যোগাযোগ করà§à¦¨ । à¦à¦•à¦Ÿà¦¿ নতà§à¦¨ অà§à¦¯à¦¾à¦•à¦¾à¦‰à¦¨à§à¦Ÿ তৈরি করবেন না দয়া করে ।" +menu: "মেনà§" +divider: "খনà§à¦¡à¦•" +addItem: "আইটেম যোগ করà§à¦¨" +relays: "রিলেগà§à¦²à¦¿" +addRelay: "রিলে যোগ করà§à¦¨" +inboxUrl: "inbox à¦à¦° URL" +addedRelays: "যোগকৃত রিলেগà§à¦²à¦¿" +serviceworkerInfo: "পà§à¦¶ বিজà§à¦žà¦ªà§à¦¤à¦¿à¦° জনà§à¦¯ চালৠকরা লাগবে।" +deletedNote: "ডিলিট করা নোট" +invisibleNote: "অদৃশà§à¦¯ নোট" +enableInfiniteScroll: "ইনফিনিট সà§à¦•à§à¦°à¦² চালৠকরà§à¦¨" +visibility: "দৃশà§à¦¯à¦®à¦¾à¦¨à¦¤à¦¾" +poll: "জরিপ" +useCw: "কনà§à¦Ÿà§‡à¦¨à§à¦Ÿ লà§à¦•à¦¾à¦¨" +enablePlayer: "à¦à¦¿à¦¡à¦¿à¦“ পà§à¦²à§‡à§Ÿà¦¾à¦° খà§à¦²à§à¦¨" +disablePlayer: "à¦à¦¿à¦¡à¦¿à¦“ পà§à¦²à§‡à§Ÿà¦¾à¦° বনà§à¦§ করà§à¦¨" +expandTweet: "টà§à¦‡à¦Ÿ বিসà§à¦¤à¦¾à¦°à¦¿à¦¤ করà§à¦¨" +themeEditor: "থিম সমà§à¦ªà¦¾à¦¦à¦•" +description: "বরà§à¦£à¦¨à¦¾" +describeFile: "কà§à¦¯à¦¾à¦ªà¦¶à¦¨ যোগ করà§à¦¨" +enterFileDescription: "কà§à¦¯à¦¾à¦ªà¦¶à¦¨ যোগ করà§à¦¨" +author: "লেখক" +leaveConfirm: "কিছৠপরিবরà§à¦¤à¦¨ সেঠকরা হয়নি। আপনি কি চলে যেতে চান?" +manage: "পরিচালনা" +plugins: "পà§à¦²à¦¾à¦—ইনসমূহ" +deck: "ডেক" +undeck: "ডেকমà§à¦•à§à¦¤ করà§à¦¨" +useBlurEffectForModal: "মোডালের জনà§à¦¯ বà§à¦²à¦¾à¦° ইফেকà§à¦Ÿ বà§à¦¯à¦¬à¦¹à¦¾à¦° করà§à¦¨" +useFullReactionPicker: "সমà§à¦ªà§‚রà§à¦£ বৈশিষà§à¦Ÿà§à¦¯à¦¯à§à¦•à§à¦¤ রিঅà§à¦¯à¦¾à¦•à¦¶à¦¨ পিকার বà§à¦¯à¦¬à¦¹à¦¾à¦° করà§à¦¨" +width: "পà§à¦°à¦¸à§à¦¥" +height: "উচà§à¦šà¦¤à¦¾" +large: "বড়" +medium: "মাà¦à¦¾à¦°à¦¿" +small: "ছোট" +generateAccessToken: "অà§à¦¯à¦¾à¦•à§à¦¸à§‡à¦¸ টোকেন তৈরি করà§à¦¨" +permission: "অনà§à¦®à¦¤à¦¿" +enableAll: "সবগà§à¦²à¦¿ সকà§à¦°à¦¿à§Ÿ করà§à¦¨" +disableAll: "সবগà§à¦²à¦¿ নিষà§à¦•à§à¦°à¦¿à§Ÿ করà§à¦¨" +tokenRequested: "অà§à¦¯à¦¾à¦•à¦¾à¦‰à¦¨à§à¦Ÿà§‡ অà§à¦¯à¦¾à¦•à§à¦¸à§‡à¦¸ পà§à¦°à¦¦à¦¾à¦¨ করবেন" +pluginTokenRequestedDescription: "à¦à¦‡ পà§à¦²à¦¾à¦—ইনটি à¦à¦–ানে দেওয়া অনà§à¦®à§à¦¤à¦¿à¦¸à¦®à§‚হ বà§à¦¯à¦¾à¦¬à¦¹à¦¾à¦° করবে" +notificationType: "বিজà§à¦žà¦ªà§à¦¤à¦¿à¦° ধরন" +edit: "সমà§à¦ªà¦¾à¦¦à¦¨à¦¾" +useStarForReactionFallback: "রিঅà§à¦¯à¦¾à¦•à¦¶à¦¨à§‡à¦° ইমোজি না জানলে ★ বà§à¦¯à¦¬à¦¹à¦¾à¦° করà§à¦¨" +emailServer: "ইমেইল সারà§à¦à¦¾à¦°" +enableEmail: "ইমেইল বিতরণ চালৠকরà§à¦¨" +emailConfigInfo: "আপনার ইমেল ঠিকানা নিশà§à¦šà¦¿à¦¤ করতে à¦à¦¬à¦‚ আপনার পাসওয়ারà§à¦¡ পà§à¦¨à¦°à¦¾à¦¯à¦¼ সেট করতে বà§à¦¯à¦¬à¦¹à§ƒà¦¤ হয়" +email: "ইমেইল" +emailAddress: "ইমেইল ঠিকানা" +smtpConfig: "SMTP সারà§à¦à¦¾à¦° কনফিগারেশন" smtpHost: "হোসà§à¦Ÿ" +smtpPort: "পোরà§à¦Ÿ" smtpUser: "বà§à¦¯à¦¬à¦¹à¦¾à¦°à¦•à¦¾à¦°à§€à¦° নাম" smtpPass: "পাসওয়ারà§à¦¡" +emptyToDisableSmtpAuth: "আপনি বà§à¦¯à¦¬à¦¹à¦¾à¦°à¦•à¦¾à¦°à§€à¦° নাম à¦à¦¬à¦‚ পাসওয়ারà§à¦¡ ফাà¦à¦•à¦¾ রেখে SMTP পà§à¦°à¦®à¦¾à¦£à§€à¦•à¦°à¦£ নিষà§à¦•à§à¦°à¦¿à¦¯à¦¼ করতে পারেন।" +smtpSecure: "SMTP সংযোগের জনà§à¦¯ SSL/TLS বà§à¦¯à¦¬à¦¹à¦¾à¦° করà§à¦¨" +smtpSecureInfo: "STARTTLS বà§à¦¯à¦¬à¦¹à¦¾à¦° করার সময় à¦à¦Ÿà¦¿ বনà§à¦§ করà§à¦¨à¥¤" +testEmail: "ইমেল বিতরণ পরীকà§à¦·à¦¾ করà§à¦¨" +wordMute: "বিশেষ কোন শবà§à¦¦à¦•à§‡ মিউট করà§à¦¨" +instanceMute: "মিউট করা ইনà§à¦¸à¦¤à§à¦¯à¦¾à¦¨à§à¦¸à¦—à§à¦²à¦¿" +userSaysSomething: "{name} কিছৠবলেছে" +makeActive: "সকà§à¦°à¦¿à¦¯à¦¼ করা" +display: "পà§à¦°à¦¦à¦°à§à¦¶à¦¨" +copy: "অনà§à¦²à¦¿à¦ªà¦¿" +metrics: "মেটà§à¦°à¦¿à¦•à§à¦¸" +overview: "সারাংশ" +logs: "লগ" +delayed: "দেরি করà§à¦¨" +database: "ডেটাবেজ" +channel: "চà§à¦¯à¦¾à¦¨à§‡à¦²à¦—à§à¦²à¦¿" +create: "তৈরি করà§à¦¨" +notificationSetting: "বিজà§à¦žà¦ªà§à¦¤à¦¿à¦° সেটিংস" +notificationSettingDesc: "কি ধরনের বিজà§à¦žà¦ªà§à¦¤à¦¿ পাবেন তা নিরà§à¦§à¦¾à¦°à¦£ করà§à¦¨" +useGlobalSetting: "গà§à¦²à§‹à¦¬à¦¾à¦² সেটিংস বà§à¦¯à¦¾à¦¬à¦¹à¦¾à¦° করà§à¦¨" +useGlobalSettingDesc: "চালৠকরলে, আপনার অà§à¦¯à¦¾à¦•à¦¾à¦‰à¦¨à§à¦Ÿà§‡à¦° বিজà§à¦žà¦ªà§à¦¤à¦¿ সেটিংস বà§à¦¯à¦¬à¦¹à¦¾à¦° করা হবে। বনà§à¦§ করলে, à¦à¦Ÿà¦¿ পৃথকà¦à¦¾à¦¬à§‡ সেট করা যেতে পারে।" +other: "অনà§à¦¯à¦¾à¦¨à§à¦¯" +regenerateLoginToken: "লগইন টোকেন আবার বানান" +regenerateLoginTokenDescription: "লগ ইন করার জনà§à¦¯ বà§à¦¯à¦¬à¦¹à§ƒà¦¤ অà¦à§à¦¯à¦¨à§à¦¤à¦°à§€à¦£ টোকেন পà§à¦¨à¦°à¦¾à¦¯à¦¼ তৈরি করে। সাধারণত আপনার à¦à¦Ÿà¦¿ করার দরকার নেই। à¦à¦Ÿà¦¿ করলে, আপনি সমসà§à¦¤ ডিà¦à¦¾à¦‡à¦¸à§‡ লগ আউট হয়ে যাবেন৷" +setMultipleBySeparatingWithSpace: "আপনি à¦à¦•à¦Ÿà¦¿ সà§à¦ªà§‡à¦¸ দিয়ে আলাদা করে à¦à¦•à¦¾à¦§à¦¿à¦• à¦à¦¨à§à¦Ÿà§à¦°à¦¿ দিতে পারেন।" +fileIdOrUrl: "ফাইল ID অথবা URL" +behavior: "আচরণ" +sample: "উদাহরণ" +abuseReports: "অà¦à¦¿à¦¯à§‹à¦—" +reportAbuse: "অà¦à¦¿à¦¯à§‹à¦—" +reportAbuseOf: "{name} ঠঅà¦à¦¿à¦¯à§‹à¦— করà§à¦¨" +fillAbuseReportDescription: "রিপোরà§à¦Ÿà§‡à¦° কারণ বরà§à¦£à¦¨à¦¾ করà§à¦¨. à¦à¦•à¦Ÿà¦¿ বিশেষ নোট à¦à¦° জনà§à¦¯ রিপোরà§à¦Ÿà¦Ÿà¦¿ হয়ে থাকে তবে তার URL টি অনà§à¦¤à¦°à§à¦à§à¦•à§à¦¤ করà§à¦¨à¥¤ " +abuseReported: "আপনার অà¦à¦¿à¦¯à§‹à¦—টি দাখিল করা হয়েছে। আপনাকে ধনà§à¦¯à¦¬à¦¾à¦¦à¥¤" +reporter: "অà¦à¦¿à¦¯à§‹à¦—কারী" +reporteeOrigin: "অà¦à¦¿à¦¯à§‹à¦—টির উৎস" +reporterOrigin: "অà¦à¦¿à¦¯à§‹à¦—কারীর উৎস" +forwardReport: "রিমোট ইনà§à¦¸à¦¤à§à¦¯à¦¾à¦¨à§à¦¸à§‡ অà¦à¦¿à¦¯à§‹à¦—টি পাঠান" +forwardReportIsAnonymous: "আপনার তথà§à¦¯ রিমোট ইনà§à¦¸à¦¤à§à¦¯à¦¾à¦¨à§à¦¸à§‡ পাঠানো হবে না à¦à¦¬à¦‚ à¦à¦•à¦Ÿà¦¿ বেনামী সিসà§à¦Ÿà§‡à¦® অà§à¦¯à¦¾à¦•à¦¾à¦‰à¦¨à§à¦Ÿ হিসাবে পà§à¦°à¦¦à¦°à§à¦¶à¦¿à¦¤ হবে।" +send: "পাঠান" +abuseMarkAsResolved: "অà¦à¦¿à¦¯à§‹à¦—টিকে সমাধাকৃত হিসাবে চিহà§à¦¨à¦¿à¦¤ করà§à¦¨" +openInNewTab: "নতà§à¦¨ টà§à¦¯à¦¾à¦¬à§‡ খà§à¦²à§à¦¨" +openInSideView: "সাইড à¦à¦¿à¦‰à¦¤à§‡ খà§à¦²à§à¦¨" +defaultNavigationBehaviour: "ডিফলà§à¦Ÿ নেà¦à¦¿à¦—েশন" +editTheseSettingsMayBreakAccount: "à¦à¦¸à¦¬ সেটিংস সমà§à¦ªà¦¾à¦¦à¦¨à¦¾ করলে আপনার অà§à¦¯à¦¾à¦•à¦¾à¦‰à¦¨à§à¦Ÿà§‡à¦° কà§à¦·à¦¤à¦¿ হতে পারে। " +instanceTicker: "ইনà§à¦¸à¦¤à§à¦¯à¦¾à¦¨à§à¦¸à§‡ নোটের তথà§à¦¯" +waitingFor: "{x} à¦à¦° জনà§à¦¯ অপেকà§à¦·à¦¾ করা হচà§à¦›à§‡" +random: "রâ€à§à¦¯à¦¾à¦¨à§à¦¡à¦®" +system: "সিসà§à¦Ÿà§‡à¦®" +switchUi: "UI পরিবরà§à¦¤à¦¨ করà§à¦¨" +desktop: "ডেসà§à¦•à¦Ÿà¦ª" +clip: "কà§à¦²à¦¿à¦ª" +createNew: "নতà§à¦¨" +optional: "পà§à¦°à¦¯à¦¼à§‹à¦œà¦¨à§€à§Ÿ নয়" +createNewClip: "নতà§à¦¨ কà§à¦²à¦¿à¦ª তৈরি করà§à¦¨" +public: "সরà§à¦¬à¦œà¦¨à§€à¦¨" +i18nInfo: "Misskey সà§à¦¬à§‡à¦šà§à¦›à¦¾à¦¸à§‡à¦¬à¦•à¦¦à§‡à¦° দà§à¦¬à¦¾à¦°à¦¾ বিà¦à¦¿à¦¨à§à¦¨ à¦à¦¾à¦·à¦¾à¦¯à¦¼ অনà§à¦¬à¦¾à¦¦ করা হচà§à¦›à§‡à¥¤ আপনি {link} ঠগিয়ে অনà§à¦¬à¦¾à¦¦à§‡ সহযোগিতা করতে পারেন।" +manageAccessTokens: "অà§à¦¯à¦¾à¦•à§à¦¸à§‡à¦¸ টোকেন পরিচালনা করà§à¦¨" +accountInfo: "অà§à¦¯à¦¾à¦•à¦¾à¦‰à¦¨à§à¦Ÿà§‡à¦° তথà§à¦¯" +notesCount: "নোটের সংখà§à¦¯à¦¾" +repliesCount: "জবাবের সংখà§à¦¯à¦¾" +renotesCount: "রিনোটের সংখà§à¦¯à¦¾" +repliedCount: "জবাব গà§à¦°à¦¹à¦¨ করা হয়েছে" +renotedCount: "রিনোট পেয়েছেন" +followingCount: "যাদেরকে অনà§à¦¸à¦°à¦£ করেন, তাদের সংখà§à¦¯à¦¾" +followersCount: "অনà§à¦¸à¦°à¦£à¦•à¦¾à¦°à§€à¦¦à§‡à¦° সংখà§à¦¯à¦¾" +sentReactionsCount: "রিঅà§à¦¯à¦¾à¦•à¦¶à¦¨ পাঠানো হয়েছে" +receivedReactionsCount: "রিঅà§à¦¯à¦¾à¦•à¦¶à¦¨ পেয়েছেন" +pollVotesCount: "পোল à¦à§‹à¦Ÿ দিয়েছেন" +pollVotedCount: "পোল à¦à§‹à¦Ÿ পেয়েছেন" +yes: "হà§à¦¯à¦¾à¦" +no: "না" +driveFilesCount: "ডà§à¦°à¦¾à¦‡à¦à§‡ ফাইল à¦à¦° সংখà§à¦¯à¦¾" +driveUsage: "ডà§à¦°à¦¾à¦‡à¦ à¦à¦° বà§à¦¯à¦¾à¦¬à¦¹à¦¾à¦°" +noCrawle: "কà§à¦°à¦²à¦¾à¦° ইনà§à¦¡à§‡à¦•à§à¦¸à¦¿à¦‚ বনà§à¦§ করà§à¦¨" +noCrawleDescription: "সারà§à¦š ইঞà§à¦œà¦¿à¦¨à¦—à§à¦²à¦¿à¦•à§‡ আপনার পà§à¦°à§‹à¦«à¦¾à¦‡à¦², নোট, পেজ ইতà§à¦¯à¦¾à¦¦à¦¿ ইনডেকà§à¦¸ করতে নিষেধ করà§à¦¨à¥¤ " +lockedAccountInfo: "à¦à¦®à¦¨à¦•à¦¿ আপনি আপনার অনà§à¦¸à¦°à¦£à¦•à¦¾à¦°à§€à¦¦à§‡à¦° বেছে বেছে অনà§à¦®à§‹à¦¦à¦¨ করলেও, যে কেউ আপনার নোটগà§à¦²à¦¿ দেখতে পাবে, যতকà§à¦·à¦£ না আপনি আপনার নোটগà§à¦²à¦¿à¦•à§‡ \"অনà§à¦¸à¦¾à¦°à§€à¦¦à§‡à¦° জনà§à¦¯\" হিসাবে সেট না করেন৷" +alwaysMarkSensitive: "সরà§à¦¬à¦¦à¦¾ সà§à¦ªà¦°à§à¦¶à¦•à¦¾à¦¤à¦° হিসাবে চিহà§à¦¨à¦¿à¦¤ করà§à¦¨" +loadRawImages: "সংযà§à¦•à§à¦¤ ছবির থামà§à¦¬à¦¨à§‡à¦‡à¦²à¦Ÿà¦¿ দেখানর পরিবরà§à¦¤à§‡ আসল ছবি দেখান" +disableShowingAnimatedImages: "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦Ÿà§‡à¦¡ চিতà§à¦° দেখানো বনà§à¦§ করà§à¦¨" +verificationEmailSent: "নিশà§à¦šà¦¿à¦¤à¦•à¦°à¦£ ইমেল পাঠানো হয়েছে। সেটআপ সমà§à¦ªà§‚রà§à¦£ করতে ইমেল à¦à¦° লিঙà§à¦• অনà§à¦¸à¦°à¦£ করà§à¦¨à¥¤" +notSet: "সেট করা হয়নি" +emailVerified: "ইমেইল নিশà§à¦šà¦¿à¦¤ করা হয়েছে" +noteFavoritesCount: "পছনà§à¦¦ করা নোটের সংখà§à¦¯à¦¾" +pageLikesCount: "পেজ লাইক করেছেন" +pageLikedCount: "পেজ লাইক পেয়েছেন" +contact: "পরিচিতি সমূহ" +useSystemFont: "সিসà§à¦Ÿà§‡à¦® ফনà§à¦Ÿ বà§à¦¯à¦¾à¦¬à¦¹à¦¾à¦° করà§à¦¨" +clips: "কà§à¦²à¦¿à¦ªà¦—à§à¦²à¦¿ " +experimentalFeatures: "পরীকà§à¦·à¦¾à¦®à§‚লক বৈশিষà§à¦Ÿà§à¦¯à¦—à§à¦²à¦¿" +developer: "ডেà¦à§‡à¦²à¦ªà¦¾à¦°" +makeExplorable: "অà§à¦¯à¦¾à¦•à¦¾à¦‰à¦¨à§à¦Ÿ \"ঘà§à¦°à§‡ দেখà§à¦¨\" পৃষà§à¦ ায় দেখান" +makeExplorableDescription: "আপনি à¦à¦Ÿà¦¿ বনà§à¦§ করলে, আপনার অà§à¦¯à¦¾à¦•à¦¾à¦‰à¦¨à§à¦Ÿ \"ঘà§à¦°à§‡ দেখà§à¦¨\" পৃষà§à¦ ায় পà§à¦°à¦¦à¦°à§à¦¶à¦¿à¦¤ হবে না।" +showGapBetweenNotesInTimeline: "টাইমলাইন à¦à¦¬à¦‚ নোটের মাà¦à§‡ ফাকা জায়গা রাখà§à¦¨" +duplicate: "পà§à¦°à¦¤à¦¿à¦°à§‚প" +left: "বাম" +center: "মাà¦à¦–ান" +wide: "চওড়া" +narrow: "সংকীরà§à¦£" +reloadToApplySetting: "পৃষà§à¦ াটি রিলোড করার পর সেটিংসটি পà§à¦°à¦¯à¦¼à§‹à¦— করা হবে। আপনি কি à¦à¦–ন রিলোড করতে চান?" +needReloadToApply: "পৃষà§à¦ াটি রিলোড করার পর সেটিংসটি পà§à¦°à¦¯à¦¼à§‹à¦— করা হবে।" +showTitlebar: "টাইটেল বার দেখান" clearCache: "কà§à¦¯à¦¾à¦¶ পরিষà§à¦•à¦¾à¦° করà§à¦¨" +onlineUsersCount: "{n} জন বà§à¦¯à¦¾à¦¬à¦¹à¦¾à¦°à¦•à¦¾à¦°à§€ অনলাইন" +nUsers: "{n} জন বà§à¦¯à¦¾à¦¬à¦¹à¦¾à¦°à¦•à¦¾à¦°à§€" +nNotes: "{n} টি নোট" +sendErrorReports: "কà§à¦°à§à¦Ÿà¦¿ পà§à¦°à¦¤à¦¿à¦¬à§‡à¦¦à¦¨ পাঠান" +sendErrorReportsDescription: "চালৠথাকলে, বিসà§à¦¤à¦¾à¦°à¦¿à¦¤ তà§à¦°à§à¦Ÿà¦¿à¦° তথà§à¦¯ Misskey-à¦à¦° সাথে শেয়ার করা হয়। যা সফà§à¦Ÿà¦“য়à§à¦¯à¦¾à¦°à¦Ÿà¦¿à¦° গà§à¦£à¦®à¦¾à¦¨ উনà§à¦¨à¦¤ করতে সাহাযà§à¦¯ করে। তà§à¦°à§à¦Ÿà¦¿à¦° তথà§à¦¯à§‡à¦° মধà§à¦¯à§‡ রয়েছে OS সংসà§à¦•à¦°à¦£, বà§à¦°à¦¾à¦‰à¦œà¦¾à¦°à§‡à¦° ধরন, করà§à¦®à§‡à¦° ইতিহাস ইতà§à¦¯à¦¾à¦¦à¦¿à¥¤" +myTheme: "আমার থিম" +backgroundColor: "পটà¦à§‚মির রং" +accentColor: "à¦à¦•à§à¦¸à§‡à¦¨à§à¦Ÿà§‡à¦° রং" +textColor: "লেখার রং" +saveAs: "à¦à¦‡à¦°à§‚পে সংরকà§à¦·à¦£ করà§à¦¨" +advanced: "উনà§à¦¨à¦¤" +value: "মান" +createdAt: "তৈরি হয়েছে" +updatedAt: "শেষ হালনাগাদ হয়েছে" +saveConfirm: "পরিবরà§à¦¤à¦¨à¦—à§à¦²à¦¿ সংরকà§à¦·à¦£ করতে চান?" +deleteConfirm: "আসলেই মà§à¦›à§‡ ফেলতে চান?" +invalidValue: "অগà§à¦°à¦¹à¦£à¦¯à§‹à¦—à§à¦¯ মান" +registry: "রেজিসà§à¦Ÿà§à¦°à¦¿" +closeAccount: "অà§à¦¯à¦¾à¦•à¦¾à¦‰à¦¨à§à¦Ÿ বনà§à¦§ করà§à¦¨" +currentVersion: "বরà§à¦¤à¦®à¦¾à¦¨ সংসà§à¦•à¦°à¦£" +latestVersion: "সরà§à¦¬à¦¶à§‡à¦· সংসà§à¦•à¦°à¦£" +youAreRunningUpToDateClient: "আপনি সবচেয়ে নতà§à¦¨ কà§à¦²à¦¾à§Ÿà§‡à¦¨à§à¦Ÿ বà§à¦¯à¦¾à¦¬à¦¹à¦¾à¦° করছেন" +newVersionOfClientAvailable: "আপনার কà§à¦²à¦¾à§Ÿà§‡à¦¨à§à¦Ÿà§‡à¦° à¦à¦•à¦Ÿà¦¿ নতà§à¦¨ à¦à¦¾à¦°à§à¦¸à¦¨ চলে à¦à¦¸à§‡à¦›à§‡" +usageAmount: "বà§à¦¯à¦¾à¦¬à¦¹à¦¾à¦°" +capacity: "ধারণকà§à¦·à¦®à¦¤à¦¾" +inUse: "বà§à¦¯à¦¬à¦¹à§ƒà¦¤" +editCode: "কোড সমà§à¦ªà¦¾à¦¦à¦¨à¦¾ করà§à¦¨" +apply: "পà§à¦°à¦¯à¦¼à§‹à¦— করà§à¦¨" +receiveAnnouncementFromInstance: "à¦à¦‡ ইনà§à¦¸à¦Ÿà§à¦¯à¦¾à¦¨à§à¦¸ থেকে বিজà§à¦žà¦ªà§à¦¤à¦¿ পান" +emailNotification: "ইমেইল বিজà§à¦žà¦ªà§à¦¤à¦¿" +publish: "পà§à¦°à¦•à¦¾à¦¶" +inChannelSearch: "চà§à¦¯à¦¾à¦¨à§‡à¦²à§‡ খà§à¦à¦œà§à¦¨" +useReactionPickerForContextMenu: "রাইট কà§à¦²à¦¿à¦•à§‡à¦° মাধà§à¦¯à¦®à§‡ রিঅà§à¦¯à¦¾à¦•à¦¶à¦¨ পিকার খà§à¦²à§à¦¨" +typingUsers: "{users} লেখছে" +jumpToSpecifiedDate: "à¦à¦•à¦Ÿà¦¿ নিরà§à¦¦à¦¿à¦·à§à¦Ÿ তারিখে যান" +showingPastTimeline: "অতীতের টাইমলাইন দেখানো হচà§à¦›à§‡" +clear: "পরিষà§à¦•à¦¾à¦°" +markAllAsRead: "সব পঠিত হিসেবে চিহà§à¦¨à¦¿à¦¤ করà§à¦¨" +goBack: "পিছনে" +unlikeConfirm: "আসলেই লাইক সরিয়ে নিবেন?" +fullView: "ফà§à¦² à¦à¦¿à¦‰" +quitFullView: "ফà§à¦² à¦à¦¿à¦‰ বনà§à¦§ করà§à¦¨" +addDescription: "বরà§à¦£à¦¨à¦¾ যোগ করà§à¦¨" +userPagePinTip: "আপনি পà§à¦°à¦¤à¦¿à¦Ÿà¦¿ নোটের জনà§à¦¯ মেনৠথেকে \"পà§à¦°à§‹à¦«à¦¾à¦‡à¦²à§‡ পিন করà§à¦¨\" নিরà§à¦¬à¦¾à¦šà¦¨ করে আপনার নোটগà§à¦²à¦¿ à¦à¦–ানে পà§à¦°à¦¦à¦°à§à¦¶à¦¨ করতে পারেন।" +notSpecifiedMentionWarning: "পà§à¦°à¦¾à¦ªà¦• ছাড়াও à¦à¦‡ নোটে অনà§à¦¯ বà§à¦¯à¦¾à¦¬à¦¹à¦¾à¦°à¦•à¦¾à¦°à§€à¦¦à§‡à¦° উলà§à¦²à§‡à¦–à§à¦¯ করা হয়েছে" info: "আপনার সমà§à¦ªà¦°à§à¦•à§‡" +userInfo: "বà§à¦¯à¦¬à¦¹à¦¾à¦°à¦•à¦¾à¦°à§€à¦° তথà§à¦¯" +unknown: "অজানা" +onlineStatus: "অনলাইন সà§à¦Ÿà§à¦¯à¦¾à¦Ÿà¦¾à¦¸" +hideOnlineStatus: "অনলাইন সà§à¦Ÿà§à¦¯à¦¾à¦Ÿà¦¾à¦¸ লà§à¦•à¦¾à¦¨" +hideOnlineStatusDescription: "অনলাইন সà§à¦Ÿà§à¦¯à¦¾à¦Ÿà¦¾à¦¸ লà§à¦•à¦¿à¦¯à¦¼à§‡ রাখলে সারà§à¦šà§‡à¦° মতো কিছৠফাংশনের সà§à¦¬à¦¿à¦§à¦¾ কমে যায়।" +online: "অনলাইন" +active: "অà§à¦¯à¦¾à¦•à¦Ÿà¦¿à¦" +offline: "অফলাইন" +notRecommended: "সà§à¦ªà¦¾à¦°à¦¿à¦¶ করা হয় না" +botProtection: "বট পà§à¦°à§‹à¦Ÿà§‡à¦•à¦¶à¦¨" +instanceBlocking: "বà§à¦²à¦• করা ইনà§à¦¸à¦Ÿà§à¦¯à¦¾à¦¨à§à¦¸à¦—à§à¦²à¦¿" +selectAccount: "অà§à¦¯à¦¾à¦•à¦¾à¦‰à¦¨à§à¦Ÿ নিরà§à¦¬à¦¾à¦šà¦¨" +switchAccount: "অà§à¦¯à¦¾à¦•à¦¾à¦‰à¦¨à§à¦Ÿ পালà§à¦Ÿà¦¾à¦¨" +enabled: "চালà§" +disabled: "বনà§à¦§" +quickAction: "কà§à¦‡à¦• অà§à¦¯à¦¾à¦•à¦¶à¦¨" user: "বà§à¦¯à¦¬à¦¹à¦¾à¦°à¦•à¦¾à¦°à§€à¦—ণ" +administration: "পরিচালনা" +accounts: "অà§à¦¯à¦¾à¦•à¦¾à¦‰à¦¨à§à¦Ÿà¦—à§à¦²à¦¿" +switch: "পালà§à¦Ÿà¦¾à¦¨" +noMaintainerInformationWarning: "পà§à¦°à¦¶à¦¾à¦¸à¦•à§‡à¦° তথà§à¦¯ সেট করা হয়নি।" +noBotProtectionWarning: "বট পà§à¦°à§‹à¦Ÿà§‡à¦•à¦¶à¦¨ সেট করা হয়নি।" +configure: "কনফিগার করà§à¦¨" +postToGallery: "গà§à¦¯à¦¾à¦²à¦¾à¦°à§€ পোসà§à¦Ÿ তৈরি করà§à¦¨" +gallery: "গà§à¦¯à¦¾à¦²à¦¾à¦°à§€" +recentPosts: "নতà§à¦¨ পোসà§à¦Ÿ" +popularPosts: "জনপà§à¦°à¦¿à§Ÿ পোসà§à¦Ÿ" +shareWithNote: "নোটের মাধà§à¦¯à¦®à§‡ শেয়ার করà§à¦¨" +ads: "বিজà§à¦žà¦¾à¦ªà¦¨" +expiration: "নিরà§à¦¦à¦¿à¦·à§à¦Ÿ সময়সীমা" +memo: "মেমো" +priority: "অগà§à¦°à¦¾à¦§à¦¿à¦•à¦¾à¦°" +high: "উচà§à¦š" +middle: "মাà¦à¦¾à¦°à¦¿" +low: "নিমà§à¦¨" +emailNotConfiguredWarning: "ইমেইল অà§à¦¯à¦¾à¦¡à§à¦°à§‡à¦¸ সেট করা হয়নি।" +ratio: "অনà§à¦ªà¦¾à¦¤" +previewNoteText: "পà§à¦°à¦¿à¦à¦¿à¦‰ দেখান" +customCss: "কাসà§à¦Ÿà¦® CSS" +customCssWarn: "à¦à¦‡ বà§à¦¯à¦¾à¦ªà¦¾à¦°à§‡ অà¦à¦¿à¦œà§à¦žà¦¤à¦¾ না থাকলে à¦à¦‡ সেটিংটি বà§à¦¯à¦¾à¦¬à¦¹à¦¾à¦° করবেন না। অনà§à¦ªà¦¯à§à¦•à§à¦¤ সেটিংস কà§à¦²à¦¾à¦¯à¦¼à§‡à¦¨à§à¦Ÿà¦•à§‡ সà§à¦¬à¦¾à¦à¦¾à¦¬à¦¿à¦•à¦à¦¾à¦¬à§‡ বà§à¦¯à¦¬à¦¹à¦¾à¦° করতে বাধা দিতে পারে।" +global: "গà§à¦²à§‹à¦¬à¦¾à¦²" +squareAvatars: "চারকোনা পà§à¦°à§‹à¦«à¦¾à¦‡à¦² পিকচার দেখান " +sent: "পাঠান" +received: "পà§à¦°à¦¾à¦ªà§à¦¤" +searchResult: "অনà§à¦¸à¦¨à§à¦§à¦¾à¦¨à§‡à¦° ফলাফল" +hashtags: "হà§à¦¯à¦¾à¦¶à¦Ÿà§à¦¯à¦¾à¦—" +troubleshooting: "টà§à¦°à¦¾à¦¬à¦²à¦¶à§à¦Ÿà¦¿à¦‚" +useBlurEffect: "UI তে বà§à¦²à¦¾à¦° ইফেকà§à¦Ÿ বà§à¦¯à¦¾à¦¬à¦¹à¦¾à¦° করà§à¦¨" +learnMore: "আরও জানà§à¦¨" +misskeyUpdated: "Misskey আপডেট করা হয়েছেï¼" +whatIsNew: "পরিবরà§à¦¤à¦¨à¦—à§à¦²à¦¿ দেখান" +translate: "অনà§à¦¬à¦¾à¦¦" +translatedFrom: "{x} হতে অনà§à¦¬à¦¾à¦¦ করা" +accountDeletionInProgress: "অà§à¦¯à¦¾à¦•à¦¾à¦‰à¦¨à§à¦Ÿ মà§à¦›à§‡ ফেলা হচà§à¦›à§‡" +usernameInfo: "à¦à¦•à¦Ÿà¦¿ নাম যা সারà§à¦à¦¾à¦°à§‡ আপনার অà§à¦¯à¦¾à¦•à¦¾à¦‰à¦¨à§à¦Ÿà¦Ÿà¦¿à¦•à§‡ অননà§à¦¯à¦à¦¾à¦¬à§‡ সনাকà§à¦¤ করে। আপনি বরà§à¦£à¦®à¦¾à¦²à¦¾ (a ~ z, A ~ Z), সংখà§à¦¯à¦¾ (0 ~ 9), à¦à¦¬à¦‚ আনà§à¦¡à¦¾à¦°à¦¸à§à¦•à§‹à¦° (_) বà§à¦¯à¦¬à¦¹à¦¾à¦° করতে পারেন। বà§à¦¯à¦¬à¦¹à¦¾à¦°à¦•à¦¾à¦°à§€à¦° নাম পরে পরিবরà§à¦¤à¦¨ করা যাবে না।" +aiChanMode: "Ai মোড" +keepCw: "CW রাখà§à¦¨" +pubSub: "Pub/Sub অà§à¦¯à¦¾à¦•à¦¾à¦‰à¦¨à§à¦Ÿà¦—à§à¦²à§‹" +lastCommunication: "শেষ যোগাযোগ" +resolved: "সমাধান হয়েছে" +unresolved: "সমাধান হয়নি" +breakFollow: "অনà§à¦¸à¦°à¦£ করা বনà§à¦§" +itsOn: "চালà§" +itsOff: "বনà§à¦§" +emailRequiredForSignup: "অà§à¦¯à¦¾à¦•à¦¾à¦‰à¦¨à§à¦Ÿ তৈরির জনà§à¦¯ ইমেইল à¦à¦° দরকার পড়বে" +unread: "অপঠিত" +filter: "ফিলà§à¦Ÿà¦¾à¦°" controlPanel: "নিয়নà§à¦¤à§à¦°à¦¨ কেনà§à¦¦à§à¦°" +manageAccounts: "অà§à¦¯à¦¾à¦•à¦¾à¦‰à¦¨à§à¦Ÿà¦—à§à¦²à¦¿ পরিচালনা করà§à¦¨" +makeReactionsPublic: "রিঅà§à¦¯à¦¾à¦•à¦¶à¦¨à§‡à¦° ইতিহাস উনà§à¦®à§à¦•à§à¦¤ করà§à¦¨" +makeReactionsPublicDescription: "আপনার পূরà§à¦¬à¦¬à¦°à§à¦¤à§€ রিঅà§à¦¯à¦¾à¦•à¦¶à¦¨à¦—à§à¦²à¦¿à¦° তালিকা যে কারও কাছে দৃশà§à¦¯à¦®à¦¾à¦¨ হবে।" +classic: "কà§à¦²à¦¾à¦¸à¦¿à¦•" +muteThread: "থà§à¦°à§‡à¦¡ মিউট করà§à¦¨" +unmuteThread: "থà§à¦°à§‡à¦¡ আনমিউট করà§à¦¨" +ffVisibility: "অনà§à¦¸à¦°à¦£/অনà§à¦¸à¦°à¦£à¦•à¦¾à¦°à§€à¦¦à§‡à¦° দৃশà§à¦¯à¦®à¦¾à¦¨à§à¦¯à¦¤à¦¾" +ffVisibilityDescription: "আপনি কাকে অনà§à¦¸à¦°à¦£ করেন à¦à¦¬à¦‚ কে আপনাকে অনà§à¦¸à¦°à¦£ করে, সেটা কারা দেখতে পাবে তা নিরà§à¦§à¦¾à¦°à¦£ করে।" +continueThread: "আরো থà§à¦°à§‡à¦¡ দেখà§à¦¨" +deleteAccountConfirm: "আপনার অà§à¦¯à¦¾à¦•à¦¾à¦‰à¦¨à§à¦Ÿ মà§à¦›à§‡ ফেলা হবে। ঠিক আছে?" +incorrectPassword: "আপনার দেওয়া পাসওয়ারà§à¦¡à¦Ÿà¦¿ à¦à§à¦²à¥¤" +voteConfirm: "\"{choice}\" ঠà¦à§‹à¦Ÿ দিতে চান?" +hide: "লà§à¦•à¦¾à¦¨" +leaveGroup: "গà§à¦°à§à¦ª ছেড়ে চলে যান" +leaveGroupConfirm: "\"{name}\" গà§à¦°à§à¦ª ছেড়ে চলে যেতে চান?" +useDrawerReactionPickerForMobile: "মোবাইলে রিঅà§à¦¯à¦¾à¦•à¦¶à¦¨ পিকারকে ডà§à¦°à¦¯à¦¼à¦¾à¦°à§‡ পà§à¦°à¦¦à¦°à§à¦¶à¦¨ করà§à¦¨" +welcomeBackWithName: "আবার সà§à¦¬à¦¾à¦—তম, {name}" +clickToFinishEmailVerification: " [{ok}] কà§à¦²à¦¿à¦• করার মাধà§à¦¯à¦®à§‡ আপনার ইমেল ঠিকানা নিশà§à¦šà¦¿à¦¤ করà§à¦¨à¥¤" +_emailUnavailable: + used: "à¦à¦‡ ইমেইল ঠিকানাটি ইতোমধà§à¦¯à§‡ বà§à¦¯à¦¬à¦¹à§ƒà¦¤ হয়েছে" + format: "à¦à¦‡ ইমেল ঠিকানাটি সঠিকà¦à¦¾à¦¬à§‡ লিখা হয়নি" + disposable: "অসà§à¦¥à¦¾à§Ÿà§€ ইমেইল ঠিকানা বà§à¦¯à¦¾à¦¬à¦¹à¦¾à¦° করা যাবে না" + mx: "ইমেইল ​​সারà§à¦à¦¾à¦°à¦Ÿà¦¿ ঠিক নাই" + smtp: "ইমেইল সারà§à¦à¦¾à¦°à¦Ÿà¦¿ সাড়া দিচà§à¦›à§‡ না" +_ffVisibility: + public: "পà§à¦°à¦•à¦¾à¦¶" + followers: "শà§à¦§à§à¦®à¦¾à¦¤à§à¦° অনà§à¦¸à¦°à¦£à¦•à¦¾à¦°à§€à¦¦à§‡à¦° কাছে দৃশà§à¦¯à¦®à¦¾à¦¨" + private: "বà§à¦¯à¦¾à¦•à§à¦¤à¦¿à¦—ত" +_signup: + almostThere: "পà§à¦°à¦¾à¦¯à¦¼ শেষ" + emailAddressInfo: "আপনি যে ইমেল ঠিকানাটি বà§à¦¯à¦¬à¦¹à¦¾à¦° করবেন সেটি লিখà§à¦¨à¥¤ আপনার ইমেইল ঠিকানা পà§à¦°à¦•à¦¾à¦¶ করা হবে না।" + emailSent: "আপনার দেওয়া ইমেল ঠিকানায় ({email}) à¦à¦•à¦Ÿà¦¿ নিশà§à¦šà¦¿à¦¤à¦•à¦°à¦£ ইমেল পাঠানো হয়েছে। অà§à¦¯à¦¾à¦•à¦¾à¦‰à¦¨à§à¦Ÿ তৈরি সমà§à¦ªà§‚রà§à¦£ করতে ইমেলের লিঙà§à¦•à¦Ÿà¦¿ অà§à¦¯à¦¾à¦•à§à¦¸à§‡à¦¸ করà§à¦¨à¥¤" +_accountDelete: + accountDelete: "অà§à¦¯à¦¾à¦•à¦¾à¦‰à¦¨à§à¦Ÿ মà§à¦›à§‡ ফেলà§à¦¨" + mayTakeTime: "à¦à¦•à¦Ÿà¦¿ অà§à¦¯à¦¾à¦•à¦¾à¦‰à¦¨à§à¦Ÿ মà§à¦›à§‡ ফেলা à¦à¦•à¦Ÿà¦¿ দীরà§à¦˜ পà§à¦°à¦•à§à¦°à¦¿à¦¯à¦¼à¦¾ à¦à¦¬à¦‚ আপনি যদি পà§à¦°à¦šà§à¦° পরিমাণে সামগà§à¦°à§€ তৈরি করে থাকেন বা ফাইল আপলোড করেন তবে à¦à¦Ÿà¦¿ সমà§à¦ªà§‚রà§à¦£ হতে দীরà§à¦˜ সময় নিতে পারে।" + sendEmail: "অà§à¦¯à¦¾à¦•à¦¾à¦‰à¦¨à§à¦Ÿ মà§à¦›à§‡ ফেলা সমà§à¦ªà§‚রà§à¦£ হলে, নিবনà§à¦§à¦¿à¦¤ ইমেল ঠিকানায় à¦à¦•à¦Ÿà¦¿ বিজà§à¦žà¦ªà§à¦¤à¦¿ পাঠানো হবে।" + requestAccountDelete: "অà§à¦¯à¦¾à¦•à¦¾à¦‰à¦¨à§à¦Ÿ মà§à¦›à§‡ ফেলার অনà§à¦°à§‹à¦§ করà§à¦¨" + started: "মà§à¦›à§‡ ফেলার পà§à¦°à¦•à§à¦°à¦¿à¦¯à¦¼à¦¾ শà§à¦°à§ হয়েছে।" + inProgress: "মà§à¦›à§‡ ফেলার কাজ চলছে" +_ad: + back: "পিছনে" + reduceFrequencyOfThisAd: "à¦à¦‡ বিজà§à¦žà¦¾à¦ªà¦¨à¦Ÿà¦¿ কম দেখান" +_forgotPassword: + enterEmail: "আপনি আপনার অà§à¦¯à¦¾à¦•à¦¾à¦‰à¦¨à§à¦Ÿà§‡à¦° জনà§à¦¯ নিবনà§à¦§à¦¿à¦¤ ইমেল ঠিকানা লিখà§à¦¨. সেই ঠিকানায় à¦à¦•à¦Ÿà¦¿ পাসওয়ারà§à¦¡ রিসেট লিঙà§à¦• পাঠানো হবে।" + ifNoEmail: "আপনি যদি নিবনà§à¦§à¦¨à§‡à¦° সময় ই-মেইল ঠিকানা না দিয়ে থাকেন, তাহলে অনà§à¦—à§à¦°à¦¹ করে পà§à¦°à¦¶à¦¾à¦¸à¦•à§‡à¦° সাথে যোগাযোগ করà§à¦¨à¥¤" + contactAdmin: "à¦à¦‡ ইনà§à¦¸à¦Ÿà§à¦¯à¦¾à¦¨à§à¦¸à¦Ÿà¦¿ ইমেইল বà§à¦¯à¦¾à¦¬à¦¹à¦¾à¦° করে না, তাই আপনার পাসওয়ারà§à¦¡ পà§à¦¨à¦°à¦¾à¦¯à¦¼ সেট করতে পà§à¦°à¦¶à¦¾à¦¸à¦•à§‡à¦° সাথে যোগাযোগ করà§à¦¨à§·" +_gallery: + my: "আমার গà§à¦¯à¦¾à¦²à¦¾à¦°à§€" + liked: "পছনà§à¦¦ করা পোসà§à¦Ÿ" + like: "পছনà§à¦¦ করা" + unlike: "পছনà§à¦¦ সরান" _email: _follow: title: "আপনাকে অনà§à¦¸à¦°à¦£ করছে" + _receiveFollowRequest: + title: "অনà§à¦¸à¦°à¦£ করার অনà§à¦°à§‹à¦§ পেয়েছেন" +_plugin: + install: "পà§à¦²à¦¾à¦—ইন ইনà§à¦¸à¦Ÿà¦² করà§à¦¨" + installWarn: "অবিশà§à¦¬à¦¸à§à¦¤ পà§à¦²à¦¾à¦—ইন ইনসà§à¦Ÿà¦² করবেন না।" + manage: "পà§à¦²à¦¾à¦—ইন মà§à¦¯à¦¾à¦¨à§‡à¦œ করà§à¦¨" +_registry: + scope: "সà§à¦•à§‹à¦ª" + key: "কী" + keys: "কী - সমূহ" + domain: "ডোমেন" + createKey: "কী বানান" +_aboutMisskey: + about: "Misskey, à¦à¦•à¦Ÿà¦¿ ওপেন সোরà§à¦¸ সফà§à¦Ÿà¦“য়à§à¦¯à¦¾à¦° যা 2014 সাল থেকে syuilo তৈরি করছেন।" + contributors: "পà§à¦°à¦§à¦¾à¦¨ কনà§à¦Ÿà§à¦°à¦¿à¦¬à¦¿à¦‰à¦Ÿà¦¾à¦°à¦—ণ" + allContributors: "সকল কনà§à¦Ÿà§à¦°à¦¿à¦¬à¦¿à¦‰à¦Ÿà¦¾à¦°à¦—ণ" + source: "সোরà§à¦¸ কোড" + translation: "Misskey অনà§à¦¬à¦¾à¦¦ করà§à¦¨" + donate: "Misskey তে দান করà§à¦¨" + morePatrons: "আরও অনেকে আমাদের সাহাযà§à¦¯ করছেন। তাদের সবাইকে ধনà§à¦¯à¦¬à¦¾à¦¦ 🥰" + patrons: "সমরà§à¦¥à¦¨à¦•à¦¾à¦°à§€" +_nsfw: + respect: "সà§à¦ªà¦°à§à¦¶à¦•à¦¾à¦¤à¦° মিডিয়া লà§à¦•à¦¾à¦¨" + ignore: "সà§à¦ªà¦°à§à¦¶à¦•à¦¾à¦¤à¦° মিডিয়া লà§à¦•à¦¾à¦¬à§‡à¦¨ না" + force: "সকল মিডিয়া লà§à¦•à¦¾à¦¨" _mfm: + cheatSheet: "MFM চিটশিট" + intro: "MFM à¦à¦•à¦Ÿà¦¿ মারà§à¦•à¦†à¦ª à¦à¦¾à¦·à¦¾ যা Misskey-à¦à¦° মধà§à¦¯à§‡ বিà¦à¦¿à¦¨à§à¦¨ জায়গায় বà§à¦¯à¦¬à¦¹à¦¾à¦° করা যেতে পারে। à¦à¦–ানে আপনি MFM-à¦à¦° সিনটà§à¦¯à¦¾à¦•à§à¦¸à¦—à§à¦²à¦¿à¦° à¦à¦•à¦Ÿà¦¿ তালিকা দেখতে পারবেন।" + dummy: "মিসকি ফেডিà¦à¦¾à¦°à§à¦¸à§‡à¦° বিশà§à¦¬à¦•à§‡ পà§à¦°à¦¸à¦¾à¦°à¦¿à¦¤ করে" mention: "উলà§à¦²à§‡à¦–" + mentionDescription: "@ চিহà§à¦¨ + বà§à¦¯à¦¬à¦¹à¦¾à¦°à¦•à¦¾à¦°à§€à¦° নাম à¦à¦•à¦Ÿà¦¿ নিরà§à¦¦à¦¿à¦·à§à¦Ÿ বà§à¦¯à¦¬à¦¹à¦¾à¦°à¦•à¦¾à¦°à§€à¦•à§‡ নিরà§à¦¦à§‡à¦¶ করতে বà§à¦¯à¦¬à¦¹à¦¾à¦° করা যায়।" + hashtag: "হà§à¦¯à¦¾à¦¶à¦Ÿà§à¦¯à¦¾à¦—" + hashtagDescription: "আপনি à¦à¦•à¦Ÿà¦¿ # চিহà§à¦¨ + টà§à¦¯à¦¾à¦— সহ à¦à¦•à¦Ÿà¦¿ হà§à¦¯à¦¾à¦¶à¦Ÿà§à¦¯à¦¾à¦— নিরà§à¦¦à§‡à¦¶ করতে পারেন।" + url: "URL" + urlDescription: "URL দেখানো সমà§à¦à¦¬à¥¤" + link: "লিংক" + linkDescription: "আপনি পাঠà§à¦¯à§‡à¦° à¦à¦•à¦Ÿà¦¿ নিরà§à¦¦à¦¿à¦·à§à¦Ÿ অংশকে URL হিসাবে দেখাতে পারেন৷" + bold: "গাà§" + boldDescription: "অকà§à¦·à¦°à¦—à§à¦²à¦¿à¦•à§‡ মোটাকরে পà§à¦°à¦¦à¦°à§à¦¶à¦¨ করা হবে।" + small: "ছোট" + smallDescription: "লেখা ছোট à¦à¦¬à¦‚ পাতলা করে দেখানো হবে।" + center: "সেনà§à¦Ÿà¦¾à¦°" + centerDescription: "লেখা মাঠবরাবর দেখানো হবে" + inlineCode: "কোড (ইনলাইন)" + inlineCodeDescription: " পà§à¦°à§‹à¦—à§à¦°à¦¾à¦®à§‡à¦° কোডের জনà§à¦¯ ইনলাইন সিনটà§à¦¯à¦¾à¦•à§à¦¸ হাইলাইটিং করা হবে" + blockCode: "কোড (বà§à¦²à¦•)" + blockCodeDescription: "মালà§à¦Ÿà¦¿-লাইন পà§à¦°à§‹à¦—à§à¦°à¦¾à¦®à§‡à¦° কোডের জনà§à¦¯ সিনটà§à¦¯à¦¾à¦•à§à¦¸ হাইলাইট করে।" + inlineMath: "গাণিতিক সূতà§à¦° (ইনলাইন)" + inlineMathDescription: "গাণিতিক সূতà§à¦° পà§à¦°à¦¦à¦°à§à¦¶à¦¨ করà§à¦¨ (KaTeX) ইনলাইন।" + blockMath: "গাণিতিক সূতà§à¦° (বà§à¦²à¦•)" + blockMathDescription: "à¦à¦•à¦Ÿà¦¿ বà§à¦²à¦•à§‡ à¦à¦•à¦¾à¦§à¦¿à¦• লাইনের গাণিতিক সূতà§à¦° পà§à¦°à¦¦à¦°à§à¦¶à¦¨ করà§à¦¨ (KaTeX)।" quote: "উদà§à¦§à§ƒà¦¤à¦¿" + quoteDescription: "বিষয়বসà§à¦¤à§à¦•à§‡ à¦à¦•à¦Ÿà¦¿ উদà§à¦§à§ƒà¦¤à¦¿ হিসাবে দেখানো হবে।" emoji: "সà§à¦¬à¦¨à¦¿à¦°à§à¦§à¦¾à¦°à¦¿à¦¤ ইমোজিগà§à¦²à¦¿" + emojiDescription: "আপনি à¦à¦•à¦Ÿà¦¿ কাসà§à¦Ÿà¦® ইমোজির নাম কোলনে আবদà§à¦§ করে কাসà§à¦Ÿà¦® ইমোজিটি দেখাতে পারেন৷" search: "খà§à¦à¦œà§à¦¨" + searchDescription: "পূরà§à¦¬-টাইপ করা পাঠà§à¦¯ সহ à¦à¦•à¦Ÿà¦¿ অনà§à¦¸à¦¨à§à¦§à¦¾à¦¨ বাকà§à¦¸ পà§à¦°à¦¦à¦°à§à¦¶à¦¨ করে।" + flip: "উলà§à¦Ÿà¦¾à¦¨" + flipDescription: "বিষয়বসà§à¦¤à§ উপরে/নীচে বা বাম/ডানে উলà§à¦Ÿà¦¾à¦¨à¥¤" + jelly: "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨ (জেলি)" + jellyDescription: "জেলির মত অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨ দেখায়।" + tada: "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨ (টাডা)" + tadaDescription: "\"টাডা!\" à¦à¦° মত অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨ দেখায়।" + jump: "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨ (লাফ)" + jumpDescription: "বিষয়বসà§à¦¤à§à¦¤à§‡ লাফ মারার মত অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨ দেখায়।" + bounce: "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨ (তিড়িং বিড়িং)" + bounceDescription: "তিড়িং বিড়িং করার মত অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨ দেখায়।" + shake: "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨ (à¦à¦¾à¦à¦•à¦¿)" + shakeDescription: "à¦à¦¾à¦à¦•à¦¿à¦° মত অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨ দেখায়।" + twitch: "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨ (মোচড়ানো)" + twitchDescription: "মোচড়ানোর মত অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨ দেখায়।" + spin: "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨ (ঘà§à¦°à¦¾)" + spinDescription: "ঘà§à¦°à¦¾à¦° মত অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨ দেখায়।" + x2: "বড়" + x2Description: "বিষয়বসà§à¦¤à§ বড় করে দেখায়।" + x3: "অনেক বড়" + x3Description: "বিষয়বসà§à¦¤à§ আরও বড় করে দেখায়।" + x4: "অসà§à¦¬à¦¾à¦à¦¾à¦¬à¦¿à¦• বড়" + x4Description: "বিষয়বসà§à¦¤à§à¦•à§‡ আগের থেকেও আরও বড় করে দেখায়।" + blur: "বà§à¦²à¦¾à¦°" + blurDescription: "বিষয়বসà§à¦¤à§à¦•à§‡ বà§à¦²à¦¾à¦° করতে পারেন। আপনি à¦à¦° উপর মাউস কারà§à¦¸à¦¾à¦° রাখলে, à¦à¦Ÿà¦¿ পরিষà§à¦•à¦¾à¦°à¦à¦¾à¦¬à§‡ দেখতে পাবেন।" + font: "ফনà§à¦Ÿ" + fontDescription: "বিষয়বসà§à¦¤à§à¦•à§‡ কোন ফনà§à¦Ÿà§‡ দেখানো হবে তা নিরà§à¦§à¦¾à¦°à¦£ করে।" + rainbow: "রেইনবো" + rainbowDescription: "বিষয়বসà§à¦¤à§à¦•à§‡ রংধনà§à¦° রং গà§à¦²à¦¿à¦¤à§‡ পà§à¦°à¦¦à¦°à§à¦¶à¦¨ করে।" + sparkle: "চিক চিক" + sparkleDescription: "বিষয়বসà§à¦¤à§à¦•à§‡ à¦à¦•à¦Ÿà¦¿ চিকচিকে কণা পà§à¦°à¦à¦¾à¦¬ দেয়।" + rotate: "ঘà§à¦°à¦¾à¦¨" + rotateDescription: "বিষয়বসà§à¦¤à§à¦•à§‡ à¦à¦•à¦Ÿà¦¿ নিরà§à¦¦à¦¿à¦·à§à¦Ÿ কোনে ঘà§à¦°à¦¾à§Ÿà¥¤" +_instanceTicker: + none: "দেখাবেন না" + remote: "রিমোট বà§à¦¯à¦¾à¦¬à¦¹à¦¾à¦°à¦•à¦¾à¦°à§€à¦¦à§‡à¦° জনà§à¦¯ দেখান" + always: "সরà§à¦¬à¦¦à¦¾ দেখান" +_serverDisconnectedBehavior: + reload: "সà§à¦¬à§Ÿà¦‚কà§à¦°à¦¿à§Ÿà¦à¦¾à¦¬à§‡ রিলোড" + dialog: "সতরà§à¦•à¦¤à¦¾ ডায়ালগ দেখান" + quiet: "অগচরী সতরà§à¦•à¦¤à¦¾ দেখান" +_channel: + create: "চà§à¦¯à¦¾à¦¨à§‡à¦² বানান" + edit: "চà§à¦¯à¦¾à¦¨à§‡à¦² সমà§à¦ªà¦¾à¦¦à¦¨à¦¾ করà§à¦¨" + setBanner: "বà§à¦¯à¦¾à¦¨à¦¾à¦° সেট করà§à¦¨" + removeBanner: "বà§à¦¯à¦¾à¦¨à¦¾à¦° সরান" + featured: "বরà§à¦¤à¦®à¦¾à¦¨à§‡ জনপà§à¦°à¦¿à§Ÿ" + owned: "নিজের" + following: "অনà§à¦¸à¦°à¦£ করা হচà§à¦›à§‡" + usersCount: "{n} জন অংশগà§à¦°à¦¹à¦£à¦•à¦¾à¦°à§€" + notesCount: "{n} টি নোট" +_menuDisplay: + sideFull: "পাশে" + sideIcon: "পাশে (আইকন)" + top: "শীরà§à¦·à§‡" + hide: "লà§à¦•à¦¾à¦¨" +_wordMute: + muteWords: "নিঃশবà§à¦¦ করা শবà§à¦¦à¦—à§à¦²à¦¿" + muteWordsDescription: "সà§à¦ªà§‡à¦¸ দিয়ে আলাদা করলে AND শরà§à¦¤ তৈরি হবে à¦à¦¬à¦‚ আলাদা লাইনে লিখলে OR শরà§à¦¤ তৈরি হবে।" + muteWordsDescription2: "রেগà§à¦²à¦¾à¦° à¦à¦•à§à¦¸à¦ªà§à¦°à§‡à¦¶à¦¨ বà§à¦¯à¦¬à¦¹à¦¾à¦° করতে সà§à¦²à§à¦¯à¦¾à¦¶ দিয়ে কীওয়ারà§à¦¡à¦•à§‡ ঘিরে রাখà§à¦¨à¥¤" + softDescription: "টাইমলাইন থেকে নিরà§à¦¦à¦¿à¦·à§à¦Ÿ শরà§à¦¤à¦¾à¦¨à§à¦¯à¦¾à§Ÿà§€ নোট লà§à¦•à¦¿à¦¯à¦¼à§‡ রাখে।" + hardDescription: "নিরà§à¦¦à¦¿à¦·à§à¦Ÿ শরà§à¦¤à¦¾à¦¨à§à¦¯à¦¾à§Ÿà§€ নোটগà§à¦²à¦¿à¦•à§‡ টাইমলাইন থেকে বাদ দেয়। আপনি শরà§à¦¤ পরিবরà§à¦¤à¦¨ করলেও যে নোটগà§à¦²à¦¿ যোগ করা হয়নি সেগà§à¦²à¦¿ বাদ দেওয়া হবে।" + soft: "নমনীয়" + hard: "কঠোর" + mutedNotes: "মিউট করা নোটগà§à¦²à¦¿" +_instanceMute: + instanceMuteDescription: "কনফিগার করা ইনà§à¦¸à¦Ÿà§à¦¯à¦¾à¦¨à§à¦¸à§‡à¦° সব নোট à¦à¦¬à¦‚ রিনোট মিউট করà§à¦¨, মিউট করা ইনà§à¦¸à¦Ÿà§à¦¯à¦¾à¦¨à§à¦¸à§‡à¦° বà§à¦¯à¦¬à¦¹à¦¾à¦°à¦•à¦¾à¦°à§€à¦¦à§‡à¦° উতà§à¦¤à¦° সহ।" + instanceMuteDescription2: "পà§à¦°à¦¤à¦¿à¦Ÿà¦¿à¦•à§‡ আলাদা লাইনে লিখà§à¦¨" + title: "কনফিগার করা ইনà§à¦¸à¦Ÿà§à¦¯à¦¾à¦¨à§à¦¸à§‡à¦° নোটগà§à¦²à¦¿à¦•à§‡ লà§à¦•à¦¿à¦¯à¦¼à§‡ রাখে।" + heading: "মিউট করা ইনà§à¦¸à¦¤à§à¦¯à¦¾à¦¨à§à¦¸à§‡à¦° তালিকা" _theme: + explore: "থিমগà§à¦²à¦¿ ঘà§à¦°à§‡ দেখà§à¦¨" + install: "থিম ইনসà§à¦Ÿà¦² করà§à¦¨" + manage: "থিম বà§à¦¯à¦¾à¦¬à¦¸à§à¦¥à¦¾à¦ªà¦¨à¦¾" + code: "থিম কোড" + description: "বরà§à¦£à¦¨à¦¾" + installed: "{name} ইনà§à¦¸à¦Ÿà¦² করা হয়েছে" + installedThemes: "ইনà§à¦¸à¦Ÿà¦² করা থিমসমূহ" + builtinThemes: "বিলà§à¦Ÿ-ইন থিমসমূহ" + alreadyInstalled: "à¦à¦‡ থিমটি ইতিমধà§à¦¯à§‡ ইনà§à¦¸à¦Ÿà¦² করা হয়েছে" + invalid: "থিমটির ফরমà§à¦¯à¦¾à¦Ÿ সঠিক নয়" + make: "থিম বানান" + base: "বেস" + addConstant: "ধà§à¦°à§à¦¬à¦• যোগ করà§à¦¨" + constant: "ধà§à¦°à§à¦¬à¦•" + defaultValue: "ডিফলà§à¦Ÿ মান" + color: "রং" + refProp: "পà§à¦°à§‹à¦ªà¦¾à¦°à§à¦Ÿà¦¿ রেফারেনà§à¦¸ করà§à¦¨" + refConst: "ধà§à¦°à§à¦¬à¦• রেফারেনà§à¦¸ করà§à¦¨" + key: "কী" + func: "ফাংশন" + funcKind: "ফাংশনের ধরন" + argument: "আরà§à¦—à§à¦®à§‡à¦¨à§à¦Ÿ" + basedProp: "রেফারেনà§à¦¸ করা পà§à¦°à§‹à¦ªà¦¾à¦°à§à¦Ÿà¦¿" + alpha: "অসà§à¦¬à¦šà§à¦›à¦¤à¦¾" + darken: "অনà§à¦§à¦•à¦¾à¦° করà§à¦¨" + lighten: "উজà§à¦œà§à¦¬à¦² করà§à¦¨" + inputConstantName: "ধà§à¦°à§à¦¬à¦•à¦Ÿà¦¿à¦° নাম লিখà§à¦¨" + importInfo: "আপনি à¦à¦–ানে থিম কোড পেসà§à¦Ÿ করতে পারেন à¦à¦¬à¦‚ সেটিকে à¦à¦¡à¦¿à¦Ÿà¦°à§‡ ইমà§à¦ªà§‹à¦°à§à¦Ÿ করতে পারেন" + deleteConstantConfirm: "আপনি কি ধà§à¦°à§à¦¬à¦• {const} মà§à¦›à§‡ ফেলতে চান?" keys: + accent: "অà§à¦¯à¦¾à¦•à¦¸à§‡à¦¨à§à¦Ÿ" + bg: "পটà¦à§‚মি" + fg: "লেখা" + focus: "ফোকাস" + indicator: "ইনডিকেটর" + panel: "পà§à¦¯à¦¾à¦¨à§‡à¦²" + shadow: "ছায়া" + header: "হেডার" + navBg: "সাইডবারের পটà¦à§‚মি" + navFg: "সাইডবারের পাঠà§à¦¯" + navHoverFg: "সাইডবারের পাঠà§à¦¯ (হà¦à¦¾à¦°)" + navActive: "সাইডবারের পাঠà§à¦¯ (অà§à¦¯à¦¾à¦•à¦Ÿà¦¿à¦)" + navIndicator: "সাইডবারের ইনডিকেটর" + link: "লিংক" + hashtag: "হà§à¦¯à¦¾à¦¶à¦Ÿà§à¦¯à¦¾à¦—" mention: "উলà§à¦²à§‡à¦–" + mentionMe: "আপনাকে উলà§à¦²à§‡à¦–à§à¦¯ করা" renote: "রিনোট" + modalBg: "মোডালের পটà¦à§‚মি" + divider: "খনà§à¦¡à¦•" + scrollbarHandle: "সà§à¦•à§à¦°à¦²à¦¬à¦¾à¦° হà§à¦¯à¦¾à¦¨à§à¦¡à§‡à¦²" + scrollbarHandleHover: "সà§à¦•à§à¦°à¦²à¦¬à¦¾à¦° হà§à¦¯à¦¾à¦¨à§à¦¡à§‡à¦² (হà¦à¦¾à¦°)" + dateLabelFg: "তারিখ লেবেলের পাঠà§à¦¯" + infoBg: "তথà§à¦¯à§‡à¦° পটà¦à§‚মি" + infoFg: "তথà§à¦¯à§‡à¦° পাঠà§à¦¯" + infoWarnBg: "ওয়ারà§à¦¨à¦¿à¦‚ à¦à¦° পটà¦à§‚মি" + infoWarnFg: "ওয়ারà§à¦¨à¦¿à¦‚ à¦à¦° পাঠà§à¦¯" + cwBg: "CW বাটনের পটà¦à§‚মি" + cwFg: "CW বাটনের পাঠà§à¦¯" + cwHoverBg: "CW বাটনের পটà¦à§‚মি (হà¦à¦¾à¦°)" + toastBg: "বিজà§à¦žà¦ªà§à¦¤à¦¿à¦° পটà¦à§‚মি" + toastFg: "বিজà§à¦žà¦ªà§à¦¤à¦¿à¦° পাঠà§à¦¯" + buttonBg: "বাটনের পটà¦à§‚মি" + buttonHoverBg: "বাটনের পটà¦à§‚মি (হà¦à¦¾à¦°)" + inputBorder: "ইনপà§à¦Ÿ ফিলà§à¦¡à§‡à¦° বরà§à¦¡à¦¾à¦°" + listItemHoverBg: "লিসà§à¦Ÿ আইটেমের পটà¦à§‚মি (হোà¦à¦¾à¦°)" + driveFolderBg: "ডà§à¦°à¦¾à¦‡à¦ ফোলà§à¦¡à¦¾à¦°à§‡à¦° পটà¦à§‚মি" + wallpaperOverlay: "ওয়ালপেপার ওà¦à¦¾à¦°à¦²à§‡" + badge: "বà§à¦¯à¦¾à¦œ" + messageBg: "চà§à¦¯à¦¾à¦Ÿà§‡à¦° পটà¦à§‚মি" + accentDarken: "অà§à¦¯à¦¾à¦•à¦¸à§‡à¦¨à§à¦Ÿ (গাà§)" + accentLighten: "অà§à¦¯à¦¾à¦•à¦¸à§‡à¦¨à§à¦Ÿ (হালà§à¦•à¦¾)" + fgHighlighted: "হাইলাইট করা পাঠà§à¦¯" _sfx: note: "নোটগà§à¦²à¦¿" + noteMy: "নোট (আপনার)" notification: "বিজà§à¦žà¦ªà§à¦¤à¦¿" chat: "চà§à¦¯à¦¾à¦Ÿ" + chatBg: "চà§à¦¯à¦¾à¦Ÿ (বà§à¦¯à¦¾à¦•à¦—à§à¦°à¦¾à¦‰à¦¨à§à¦¡)" + antenna: "অà§à¦¯à¦¾à¦¨à§à¦Ÿà§‡à¦¨à¦¾à¦—à§à¦²à¦¿" + channel: "চà§à¦¯à¦¾à¦¨à§‡à¦²à§‡à¦° বিজà§à¦žà¦ªà§à¦¤à¦¿" +_ago: + unknown: "অজানা" + future: "à¦à¦¬à¦¿à¦·à§à¦¯à§Ž" + justNow: "à¦à¦‡à¦®à¦¾à¦¤à§à¦°" + secondsAgo: "{n} সেকেনà§à¦¡ আগে" + minutesAgo: "{n} মিনিট আগে" + hoursAgo: "{n} ঘণà§à¦Ÿà¦¾ আগে" + daysAgo: "{n} দিন আগে" + weeksAgo: "{n} সপà§à¦¤à¦¾à¦¹ আগে" + monthsAgo: "{n} মাস আগে" + yearsAgo: "{n} বছর আগে" +_time: + second: "সেকেনà§à¦¡" + minute: "মিনিট" + hour: "ঘণà§à¦Ÿà¦¾" + day: "দিন" +_tutorial: + title: "Misskey কিà¦à¦¾à¦¬à§‡ বà§à¦¯à¦¾à¦¬à¦¹à¦¾à¦° করবেন" + step1_1: "সà§à¦¬à¦¾à¦—তম!" + step1_2: "à¦à¦‡ সà§à¦•à§à¦°à§€à¦¨à¦Ÿà¦¿à¦•à§‡ \"টাইমলাইন\" বলা হয় à¦à¦¬à¦‚ কালানà§à¦•à§à¦°à¦®à¦¿à¦• কà§à¦°à¦®à§‡ আপনার à¦à¦¬à¦‚ আপনি যাদের \"অনà§à¦¸à¦°à¦£ করেন\" তাদের \"নোটগà§à¦²à¦¿\" দেখায়৷" + step1_3: "আপনি আপনার টাইমলাইনে কিছৠদেখতে পাবেন না কারণ আপনি à¦à¦–নও কোনো নোট পোসà§à¦Ÿ করেননি à¦à¦¬à¦‚ আপনি কাউকে অনà§à¦¸à¦°à¦£ করছেন না৷" + step2_1: "নোট তৈরি করার আগে বা কাউকে অনà§à¦¸à¦°à¦£ করার আগে পà§à¦°à¦¥à¦®à§‡ আপনার পà§à¦°à§‹à¦«à¦¾à¦‡à¦²à¦Ÿà¦¿ সমà§à¦ªà§‚রà§à¦£ করà§à¦¨à¥¤" + step2_2: "আপনি কে তা জানা অনেক লোকের জনà§à¦¯ আপনার নোটগà§à¦²à¦¿ দেখা à¦à¦¬à¦‚ অনà§à¦¸à¦°à¦£ করাকে সহজ করে তোলে৷" + step3_1: "আপনি কি সফলà¦à¦¾à¦¬à§‡ আপনার পà§à¦°à§‹à¦«à¦¾à¦‡à¦² সেট আপ করেছেন?" + step3_2: "à¦à¦–ন, কিছৠনোট পোসà§à¦Ÿ করার চেষà§à¦Ÿà¦¾ করà§à¦¨à¥¤ পোসà§à¦Ÿ ফরà§à¦® খà§à¦²à¦¤à§‡ পেনà§à¦¸à¦¿à¦² চিহà§à¦¨à¦¯à§à¦•à§à¦¤ বাটনে কà§à¦²à¦¿à¦• করà§à¦¨à¥¤" + step3_3: "বিষয়বসà§à¦¤à§ লেখার পরে, আপনি ফরà§à¦®à§‡à¦° উপরের ডানদিকের বাটনে কà§à¦²à¦¿à¦• করে পোসà§à¦Ÿ করতে পারেন।" + step3_4: "পোসà§à¦Ÿ করার মত কিছৠমনে পরছে না? \"আমি মিসকি সেট আপ করছি\" বললে কেমন হয়?" + step4_1: "পোসà§à¦Ÿ করেছেন?" + step4_2: "সাবাশ! à¦à¦–ন আপনার নোট টাইমলাইনে দেখা যাবে।" + step5_1: "à¦à¦–ন অনà§à¦¯à¦¦à§‡à¦°à¦•à§‡ অনà§à¦¸à¦°à¦£ করে আপনার টাইমলাইনকে পà§à¦°à¦¾à¦£à¦¬à¦¨à§à¦¤ করে তà§à¦²à§à¦¨à¥¤" + step5_2: "আপনি {featured}-ঠজনপà§à¦°à¦¿à¦¯à¦¼ নোটগà§à¦²à¦¿ দেখতে পারেন, যাতে আপনি যে বà§à¦¯à¦•à§à¦¤à¦¿à¦•à§‡ পছনà§à¦¦ করেন তাকে বেছে নিতে à¦à¦¬à¦‚ অনà§à¦¸à¦°à¦£ করতে পারেন, অথবা {explore}-ঠজনপà§à¦°à¦¿à¦¯à¦¼ বà§à¦¯à¦¬à¦¹à¦¾à¦°à¦•à¦¾à¦°à§€à¦¦à§‡à¦° দেখতে পারেন৷" + step5_3: "à¦à¦•à¦œà¦¨ বà§à¦¯à¦¬à¦¹à¦¾à¦°à¦•à¦¾à¦°à§€à¦•à§‡ অনà§à¦¸à¦°à¦£ করতে, বà§à¦¯à¦¬à¦¹à¦¾à¦°à¦•à¦¾à¦°à§€à¦° আইকনে কà§à¦²à¦¿à¦• করà§à¦¨ à¦à¦¬à¦‚ বà§à¦¯à¦¬à¦¹à¦¾à¦°à¦•à¦¾à¦°à§€à¦° পৃষà§à¦ াতে \"অনà§à¦¸à¦°à¦£ করà§à¦¨\" বাটনে কà§à¦²à¦¿à¦• করà§à¦¨à¥¤" + step5_4: "যদি বà§à¦¯à¦¬à¦¹à¦¾à¦°à¦•à¦¾à¦°à§€à¦° নামের পাশে à¦à¦•à¦Ÿà¦¿ লক আইকন থাকে তাহলে আপনার অনà§à¦¸à¦°à¦£à§‡à¦° অনà§à¦°à§‹à¦§ গà§à¦°à¦¹à¦£ করার জনà§à¦¯ তারা কিছৠসময় নিতে পারে।" + step6_1: "সবকিছৠঠিক থাকলে আপনি টাইমলাইনে অনà§à¦¯ বà§à¦¯à¦¬à¦¹à¦¾à¦°à¦•à¦¾à¦°à§€à¦¦à§‡à¦° নোট দেখতে পাবেন।" + step6_2: "আপনি সহজেই আপনার পà§à¦°à¦¤à¦¿à¦•à§à¦°à¦¿à¦¯à¦¼à¦¾ জানাতে অনà§à¦¯ বà§à¦¯à¦•à§à¦¤à¦¿à¦° নোটে \"রিঅà§à¦¯à¦¾à¦•à¦¶à¦¨\" যোগ করতে পারেন।" + step6_3: "à¦à¦•à¦Ÿà¦¿ রিঅà§à¦¯à¦¾à¦•à¦¶à¦¨ যোগ করতে, নোটে \"+\" চিহà§à¦¨à§‡ কà§à¦²à¦¿à¦• করà§à¦¨ à¦à¦¬à¦‚ আপনার পছনà§à¦¦à§‡à¦° রিঅà§à¦¯à¦¾à¦•à¦¶à¦¨ নিরà§à¦¬à¦¾à¦šà¦¨ করà§à¦¨à¥¤" + step7_1: "অà¦à¦¿à¦¨à¦¨à§à¦¦à¦¨! আপনি à¦à¦–ন Misskey-র পà§à¦°à¦¾à¦¥à¦®à¦¿à¦• টিউটোরিয়ালটি শেষ করেছেন।" + step7_2: "আপনি যদি Misskey সমà§à¦ªà¦°à§à¦•à§‡ আরও জানতে চান, তাহলে {help} ঠদেখà§à¦¨à¥¤" + step7_3: "à¦à¦–ন Misskey উপà¦à§‹à¦— করà§à¦¨ 🚀" +_2fa: + alreadyRegistered: "আপনি ইতিমধà§à¦¯à§‡ à¦à¦•à¦Ÿà¦¿ 2-ফà§à¦¯à¦¾à¦•à§à¦Ÿà¦° অথেনটিকেশন ডিà¦à¦¾à¦‡à¦¸ নিবনà§à¦§à¦¨ করেছেন৷" + registerDevice: "নতà§à¦¨ ডিà¦à¦¾à¦‡à¦¸ নিবনà§à¦§à¦¨ করà§à¦¨" + registerKey: "সিকিউরিটি কী নিবনà§à¦§à¦¨ করà§à¦¨" + step1: "পà§à¦°à¦¥à¦®à§‡, আপনার ডিà¦à¦¾à¦‡à¦¸à§‡ {a} বা {b} à¦à¦° মতো à¦à¦•à¦Ÿà¦¿ অথেনটিকেশন অà§à¦¯à¦¾à¦ª ইনসà§à¦Ÿà¦² করà§à¦¨à§·" +_permissions: + "read:pages": "আপনার পেজগà§à¦²à¦¿ দেখà§à¦¨" + "write:pages": "পেজগà§à¦²à¦¿ সমà§à¦ªà¦¾à¦¦à¦¨à¦¾ বা ডিলিট করà§à¦¨" +_auth: + pleaseGoBack: "দয়া করে অà§à¦¯à¦¾à¦ªà§à¦²à¦¿à¦•à§‡à¦¶à¦¨à§‡ ফিরে যান" + callback: "অà§à¦¯à¦¾à¦ªà§à¦²à¦¿à¦•à§‡à¦¶à¦¨à§‡ ফিরে যাচà§à¦›à¦¿" + denied: "পà§à¦°à¦¬à§‡à¦¶ নিষেধ" +_antennaSources: + all: "সকল নোট" + homeTimeline: "আপনি অনà§à¦¸à¦°à¦£ করছেন, à¦à¦®à¦¨ বà§à¦¯à¦¬à¦¹à¦¾à¦°à¦•à¦¾à¦°à§€à¦¦à§‡à¦° নোট" + users: "à¦à¦• বা à¦à¦•à¦¾à¦§à¦¿à¦• নিরà§à¦¦à¦¿à¦·à§à¦Ÿ বà§à¦¯à¦¬à¦¹à¦¾à¦°à¦•à¦¾à¦°à§€à¦° নোট" + userList: "নিরà§à¦¦à¦¿à¦·à§à¦Ÿ তালিকায় নাম থাকা বà§à¦¯à¦¬à¦¹à¦¾à¦°à¦•à¦¾à¦°à§€à¦¦à§‡à¦° নোট" + userGroup: "নিরà§à¦¦à¦¿à¦·à§à¦Ÿ গà§à¦°à§à¦ªà§‡ থাকা বà§à¦¯à¦¬à¦¹à¦¾à¦°à¦•à¦¾à¦°à§€à¦¦à§‡à¦° নোট" +_weekday: + sunday: "রবিবার" + monday: "সোমবার" + tuesday: "মঙà§à¦—লবার" + wednesday: "বà§à¦§à¦¬à¦¾à¦°" + thursday: "বৃহসà§à¦ªà¦¤à¦¿à¦¬à¦¾à¦°" + friday: "শà§à¦•à§à¦°à¦¬à¦¾à¦°" + saturday: "শনিবার" _widgets: + memo: "সà§à¦Ÿà¦¿à¦•à¦¿ নোট" notifications: "বিজà§à¦žà¦ªà§à¦¤à¦¿" timeline: "টাইমলাইন" + calendar: "কà§à¦¯à¦¾à¦²à§‡à¦¨à§à¦¡à¦¾à¦°" + trends: "বরà§à¦¤à¦®à¦¾à¦¨à§‡ জনপà§à¦°à¦¿à§Ÿ" + clock: "ঘড়ি" + rss: "RSS রিডার" activity: "কারà§à¦¯à¦•à¦²à¦¾à¦ª" + photos: "ফটোগà§à¦²à¦¿" + digitalClock: "ডিজিটাল ঘড়ি" federation: "ফেডিà¦à¦¾à¦°à§à¦¸" + postForm: "নোট লিখà§à¦¨" + slideshow: "সà§à¦²à¦¾à¦‡à¦¡à¦¶à§‹" + button: "বাটন" + onlineUsers: "অনলাইনে থাকা বà§à¦¯à¦¬à¦¹à¦¾à¦°à¦•à¦¾à¦°à§€à¦—ণ" jobQueue: "জব কিউ" + serverMetric: "সারà§à¦à¦¾à¦° মেটà§à¦°à¦¿à¦•à§à¦¸" + aiscript: "AiScript কনসোল" + aichan: "আই চান" _cw: + hide: "লà§à¦•à¦¾à¦¨" show: "আরও দেখà§à¦¨" + chars: "{count} টি অকà§à¦·à¦°" + files: "{count} টি ফাইল" +_poll: + noOnlyOneChoice: "সরà§à¦¬à¦¨à¦¿à¦®à§à¦¨ 2 টি অপশন বেছে নিতে হবে" + choiceN: "বিকলà§à¦ªà¦—à§à¦²à¦¿ {n}" + noMore: "আপনি আর কোন বিকলà§à¦ª যোগ করতে পারবেন না" + canMultipleVote: "à¦à¦•à¦¾à¦§à¦¿à¦• বিকলà§à¦ª বাছাই করা যাবে" + expiration: "পোলের সময়সীমা" + infinite: "অনিরà§à¦¦à¦¿à¦·à§à¦Ÿ" + at: "শেষ হবে" + after: "শেষ হবে" + deadlineDate: "শেষ হওয়ার তারিখ" + deadlineTime: "ঘণà§à¦Ÿà¦¾" + duration: "বà§à¦¯à¦¾à¦ªà§à¦¤à¦¿à¦•à¦¾à¦²" + votesCount: "{n} টি à¦à§‹à¦Ÿ" + totalVotes: "সরà§à¦¬à¦®à§‹à¦Ÿ {n} টি à¦à§‹à¦Ÿ" + vote: "à¦à§‹à¦Ÿ দিন" + showResult: "রেজালà§à¦Ÿ দেখান" + voted: "à¦à§‹à¦Ÿ দিয়েছেন" + closed: "শেষ হয়ে গেছে" + remainingDays: "আর {d} দিন {h} ঘণà§à¦Ÿà¦¾ বাকি আছে" + remainingHours: "আর {h} ঘণà§à¦Ÿà¦¾ {m} মিনিট বাকি আছে" _visibility: home: "মূল পাতা" followers: "অনà§à¦¸à¦°à¦£à¦•à¦¾à¦°à§€" @@ -466,13 +1185,17 @@ _profile: name: "নাম" username: "বà§à¦¯à¦¬à¦¹à¦¾à¦°à¦•à¦¾à¦°à§€à¦° নাম" _exportOrImport: + allNotes: "সকল নোট" followingList: "অনà§à¦¸à¦°à¦£ করা হচà§à¦›à§‡" muteList: "মিউট" blockingList: "বà§à¦²à¦•" userLists: "লিসà§à¦Ÿ" +_charts: + federation: "ফেডিà¦à¦¾à¦°à§à¦¸" _timelines: home: "মূল পাতা" _pages: + viewPage: "আপনার পেজগà§à¦²à¦¿ দেখà§à¦¨" blocks: image: "ছবি" script: @@ -483,6 +1206,12 @@ _pages: arg1: "লিসà§à¦Ÿ" _randomPick: arg1: "লিসà§à¦Ÿ" + _dailyRandom: + arg1: "সমà§à¦à¦¾à¦¬à§à¦¯à¦¤à¦¾" + dailyRannum: "রâ€à§à¦¯à¦¾à¦¨à§à¦¡à¦® সংখà§à¦¯à¦¾ (পà§à¦°à¦¤à¦¿à¦Ÿà¦¿ বà§à¦¯à¦¬à¦¹à¦¾à¦°à¦•à¦¾à¦°à§€à¦° জনà§à¦¯ পà§à¦°à¦¤à¦¿à¦¦à¦¿à¦¨ পরিবরà§à¦¤à§€à¦¤ হয়)" + _dailyRannum: + arg1: "নà§à¦¯à§‚নতম মান" + arg2: "সরà§à¦¬à§‹à¦šà§à¦š মান" _dailyRandomPick: arg1: "লিসà§à¦Ÿ" _seedRandomPick: @@ -491,20 +1220,83 @@ _pages: arg1: "লিসà§à¦Ÿ" _listLen: arg1: "লিসà§à¦Ÿ" + _numberToString: + arg1: "সংখà§à¦¯à¦¾" + splitStrByLine: "পাঠà§à¦¯à¦•à§‡ লাইনে বিà¦à¦•à§à¦¤ করà§à¦¨" + _splitStrByLine: + arg1: "লেখা" + ref: "চলক" + aiScriptVar: "AiScript চলক" + fn: "ফাংশন" + _fn: + slots: "সà§à¦²à¦Ÿà¦—à§à¦²à¦¿" + slots-info: "পà§à¦°à¦¤à¦¿à¦Ÿà¦¿ সà§à¦²à¦Ÿà¦•à§‡ আলাদা লাইনে লিখà§à¦¨" + arg1: "আউটপà§à¦Ÿ" + for: "for-লà§à¦ª" + _for: + arg1: "কতবার চলবে" + arg2: "অà§à¦¯à¦¾à¦•à¦¶à¦¨" + typeError: "সà§à¦²à¦Ÿ {slot}, {expect} ধরনের মান গà§à¦°à¦¹à¦£ করে, কিনà§à¦¤à§ {actual} ধরনের মান দেওয়া হয়েছে!" + thereIsEmptySlot: "সà§à¦²à¦Ÿ {slot} খালিï¼" types: + string: "লেখা" + number: "সংখà§à¦¯à¦¾" + boolean: "ফà§à¦²à§à¦¯à¦¾à¦—" array: "লিসà§à¦Ÿ" + stringArray: "লেখার লিসà§à¦Ÿ" + emptySlot: "খালি সà§à¦²à¦Ÿ" + enviromentVariables: "à¦à¦¨à¦à¦¾à¦‡à¦°à¦¨à¦®à§‡à¦¨à§à¦Ÿ à¦à§à¦¯à¦¾à¦°à¦¿à§Ÿà§‡à¦¬à¦²" + pageVariables: "পেজের চলক" + argVariables: "ইনপà§à¦Ÿà§‡à¦° জায়গা" +_relayStatus: + requesting: "অপেকà§à¦·à¦®à¦¾à¦¨" + accepted: "অনà§à¦®à§‹à¦¦à¦¿à¦¤" + rejected: "পà§à¦°à¦¤à§à¦¯à¦¾à¦–িত" _notification: + fileUploaded: "ফাইল সফলà¦à¦¾à¦¬à§‡ আপলোড করা হয়েছে" + youGotMention: "{name} আপনাকে উলà§à¦²à§‡à¦–à§à¦¯ করেছে" + youGotReply: "{name} আপনাকে জবাব দিয়েছে" + youGotQuote: "{name} আপনাকে উদà§à¦§à§ƒà¦¤ করেছে" + youRenoted: "{name} à¦à¦° Renote" + youGotPoll: "{name} আপনার পোলে à¦à§‹à¦Ÿ দিয়েছে" + youGotMessagingMessageFromUser: "{name} আপনাকে মেসেজ করেছে" + youGotMessagingMessageFromGroup: "{name} গà§à¦°à§à¦ªà§‡ à¦à¦•à¦Ÿà¦¿ নতà§à¦¨ মেসেজ আছে" youWereFollowed: "আপনাকে অনà§à¦¸à¦°à¦£ করছে" + youReceivedFollowRequest: "অনà§à¦¸à¦°à¦£ করার জনà§à¦¯ অনà§à¦°à§‹à¦§ পাওয়া গেছে" + yourFollowRequestAccepted: "আপনার অনà§à¦¸à¦°à¦£ করার অনà§à¦°à§‹à¦§ গৃহীত হয়েছে" + youWereInvitedToGroup: "আপনি à¦à¦•à¦Ÿà¦¿ গà§à¦°à§à¦ªà§‡ আমনà§à¦¤à§à¦°à¦¿à¦¤ হয়েছেন" _types: + all: "সকল" follow: "অনà§à¦¸à¦°à¦£ করা হচà§à¦›à§‡" mention: "উলà§à¦²à§‡à¦–" + reply: "উতà§à¦¤à¦° দিন" renote: "রিনোট" quote: "উদà§à¦§à§ƒà¦¤à¦¿" reaction: "পà§à¦°à¦¤à¦¿à¦•à§à¦°à¦¿à¦¯à¦¼à¦¾" + pollVote: "পোলে à¦à§‹à¦Ÿ আছে" + receiveFollowRequest: "পà§à¦°à¦¾à¦ªà§à¦¤ অনà§à¦¸à¦°à¦£à§‡à¦° অনà§à¦°à§‹à¦§à¦¸à¦®à§‚হ" + followRequestAccepted: "গৃহীত অনà§à¦¸à¦°à¦£à§‡à¦° অনà§à¦°à§‹à¦§à¦¸à¦®à§‚হ" + groupInvited: "গà§à¦°à§à¦ªà§‡à¦° আমনà§à¦¤à§à¦°à¦¨à¦¸à¦®à§‚হ" + app: "লিঙà§à¦• করা অà§à¦¯à¦¾à¦ª থেকে বিজà§à¦žà¦ªà§à¦¤à¦¿" _deck: + alwaysShowMainColumn: "সরà§à¦¬à¦¦à¦¾ মেইন কলাম দেখান" + columnAlign: "কলাম সাজান" + columnMargin: "কলামের মধà§à¦¯à¦¬à¦°à§à¦¤à§€ মারà§à¦œà¦¿à¦¨" + columnHeaderHeight: "কলামের হেডারের উচà§à¦šà¦¤à¦¾" + addColumn: "কলাম যà§à¦•à§à¦¤ করà§à¦¨" + swapLeft: "বামে সরান" + swapRight: "ডানে সরান" + swapUp: "উপরে উঠান" + swapDown: "নিচে নামান" + stackLeft: "বাম কলামে সাজান" + popRight: "ডানদিকে রাখà§à¦¨" + profile: "পà§à¦°à§‹à¦«à¦¾à¦‡à¦²" _columns: + main: "পà§à¦°à¦§à¦¾à¦¨" + widgets: "উইজেটগà§à¦²à¦¿" notifications: "বিজà§à¦žà¦ªà§à¦¤à¦¿" tl: "টাইমলাইন" antenna: "অà§à¦¯à¦¾à¦¨à§à¦Ÿà§‡à¦¨à¦¾" list: "লিসà§à¦Ÿ" mentions: "উলà§à¦²à§‡à¦–সমূহ" + direct: "ডাইরেকà§à¦Ÿ নোটগà§à¦²à¦¿" diff --git a/locales/de-DE.yml b/locales/de-DE.yml index 05360e1703f7f547cd04808721950b3bf0e7d90b..cec230e10d7fa44ef2341647f61418eb2db3c128 100644 --- a/locales/de-DE.yml +++ b/locales/de-DE.yml @@ -141,6 +141,8 @@ flagAsBot: "Als Bot markieren" flagAsBotDescription: "Aktiviere diese Option, falls dieses Benutzerkonto durch ein Programm gesteuert wird. Falls aktiviert, agiert es als Flag für andere Entwickler zur Verhinderung von endlosen Kettenreaktionen mit anderen Bots und lässt Misskeys interne Systeme dieses Benutzerkonto als Bot behandeln." flagAsCat: "Als Katze markieren" flagAsCatDescription: "Aktiviere diese Option, um dieses Benutzerkonto als Katze zu markieren." +flagShowTimelineReplies: "Antworten in der Chronik anzeigen" +flagShowTimelineRepliesDescription: "Ist diese Option aktiviert, so werden Antworten von Benutzern auf die Notizen anderer Benuzter in der Chronik an angezeigt." autoAcceptFollowed: "Follow-Anfragen von Benutzern, denen du folgst, automatisch akzeptieren" addAccount: "Benutzerkonto hinzufügen" loginFailed: "Anmeldung fehlgeschlagen" @@ -822,6 +824,10 @@ leaveGroupConfirm: "Möchtest du \"{name}\" wirklich verlassen?" useDrawerReactionPickerForMobile: "Auf mobilen Geräten ausfahrbare Reaktionsauswahl anzeigen" welcomeBackWithName: "Willkommen zurück, {name}" clickToFinishEmailVerification: "Drücke bitte auf [{ok}], um die Email-Bestätigung abzuschließen." +overridedDeviceKind: "Gerätetyp" +smartphone: "Smartphone" +tablet: "Tablet" +auto: "Automatisch" _emailUnavailable: used: "Diese Email-Adresse wird bereits verwendet" format: "Das Format dieser Email-Adresse ist ungültig" @@ -1258,8 +1264,8 @@ _exportOrImport: excludeMutingUsers: "Stummgeschaltete Benutzer aussortieren" excludeInactiveUsers: "Inaktive Benutzer aussortieren" _charts: - federationInstancesIncDec: "Unterschied in der Anzahl von förderierenden Instanzen" - federationInstancesTotal: "Anzahl aller föderierenden Instanzen" + federation: "Föderation" + apRequest: "Anfragen" usersIncDec: "Unterschied in der Anzahl von Benutzern" usersTotal: "Anzahl aller Benutzer" activeUsers: "Aktive Benutzer" diff --git a/locales/en-US.yml b/locales/en-US.yml index 9a2b0bf5c59681988d4288105f5f56b665ccd0e2..43ecf98206c6bbe839fec8840187e1d7df6b868f 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -141,6 +141,8 @@ flagAsBot: "Mark this account as a bot" flagAsBotDescription: "Enable this option if this account is controlled by a program. If enabled, it will act as a flag for other developers to prevent endless interaction chains with other bots and adjust Misskey's internal systems to treat this account as a bot." flagAsCat: "Mark this account as a cat" flagAsCatDescription: "Enable this option to mark this account as a cat." +flagShowTimelineReplies: "Show replies in timeline" +flagShowTimelineRepliesDescription: "Shows replies of users to notes of other users in the timeline if turned on." autoAcceptFollowed: "Automatically approve follow requests from users you're following" addAccount: "Add account" loginFailed: "Failed to sign in" @@ -822,6 +824,10 @@ leaveGroupConfirm: "Are you sure you want to leave \"{name}\"?" useDrawerReactionPickerForMobile: "Display reaction picker as drawer on mobile" welcomeBackWithName: "Welcome back, {name}" clickToFinishEmailVerification: "Please click [{ok}] to complete email verification." +overridedDeviceKind: "Device type" +smartphone: "Smartphone" +tablet: "Tablet" +auto: "Auto" _emailUnavailable: used: "This email address is already being used" format: "The format of this email address is invalid" @@ -1258,8 +1264,8 @@ _exportOrImport: excludeMutingUsers: "Exclude muted users" excludeInactiveUsers: "Exclude inactive users" _charts: - federationInstancesIncDec: "Difference in # of federating instances" - federationInstancesTotal: "Total # of federating instances" + federation: "Federation" + apRequest: "Requests" usersIncDec: "Difference in # of users" usersTotal: "Total # of users" activeUsers: "Active users" diff --git a/locales/eo-UY.yml b/locales/eo-UY.yml index 0689834a1e293b74a3c32559e73eeac88573756e..286a0d857f6241bf489c853d72a120be1e4e5db5 100644 --- a/locales/eo-UY.yml +++ b/locales/eo-UY.yml @@ -65,6 +65,8 @@ files: "Dosieroj" download: "ElÅuti" driveFileDeleteConfirm: "Ĉu vi certas, ke vi volas forviÅi la dosieron \"{name}\"? Tio ankaÅ forviÅos la notojn kiuj citas Äin." unfollowConfirm: "Ĉu vi certas, ke vi volas ĉesi sekvi {name}?" +exportRequested: "Vi petis elporton. Äœi povas bezoni longan tempon. Elportaĵo estos aldonita al disko post elportado." +importRequested: "Vi petis enportadon. Äœi povas bezoni longan tempon. " lists: "Listoj" noLists: "Neniu listo" note: "Noti" @@ -77,7 +79,10 @@ manageLists: "Bonteni liston" error: "Eraro" somethingHappened: "Problemo okazis" retry: "Provi denove" +pageLoadError: "FuÅiÄis enlegi paÄon." +pageLoadErrorDescription: "Ordinare tio okazas pro la retkondiĉo aÅ la staplo de retumilo.\nPurigu la staplon, aÅ refaru poste. " serverIsDead: "La servilo ne respondas. Vole atendu iom kaj penu denove." +youShouldUpgradeClient: "Por montri ĉi paÄon, bonvolu enlegi refoje kaj uzi klienton novversian." enterListName: "Entajpu nomon de la listo" privacy: "Privateco" makeFollowManuallyApprove: "Eksekvi vin devas peti al vi" @@ -132,6 +137,7 @@ settingGuide: "Agordaj rekomendoj" cacheRemoteFiles: "Stapli forajn dosierojn" flagAsBot: "Marki kiel esti uzanto de roboto" flagAsCat: "Marki kiel esti kato" +flagShowTimelineReplies: "Montri respondon de notoj en templinio." autoAcceptFollowed: "AÅtomate akcepti la peton de sekvado far uzantoj kiujn vi sekvas" addAccount: "Aldoni konton" loginFailed: "Saluto malsukcesis" @@ -178,6 +184,7 @@ noUsers: "Neniu uzanto" editProfile: "Redakti profilon" noteDeleteConfirm: "Ĉu vi certas ke vi volas forviÅi la noton?" pinLimitExceeded: "Vi ne povas alpingli pli" +intro: "Instalado de Misskey finiÄis! Kreu administran konton." done: "Fini" processing: "Prilaborado…" preview: "AntaÅmontro" @@ -326,6 +333,7 @@ antennaExcludeKeywords: "Krom ĉefterminoj" notifyAntenna: "Oni sciigos novajn notojn" withFileAntenna: "Nur kun aldonaĵo" enableServiceworker: "Aktivigi ServiceWorker" +caseSensitive: "Distingi usklecon" withReplies: "Inkluzive respondoj" connectedTo: "Sekva konto estas konektita" notesAndReplies: "Kun respondoj" @@ -363,6 +371,7 @@ notFound: "Ne trovita" uploadFolder: "Dosierujo implicita por alÅuto" cacheClear: "Malplenigi staplon" markAsReadAllNotifications: "Marki ĉiujn sciigojn kiel legita" +markAsReadAllUnreadNotes: "Marki ĉiujn afiÅojn kiel legita" markAsReadAllTalkMessages: "Marki ĉiujn retbabiladojn kiel legita" help: "Manlibro de uzado" inputMessageHere: "Entajpu mesaÄon tie" @@ -385,6 +394,7 @@ next: "Sekve" retype: "Retajpu" noteOf: "Noto de {user}" inviteToGroup: "Inviti al grupo" +maxNoteTextLength: "Limnombro de leteroj en noto" quoteAttached: "Kun citaĵo" quoteQuestion: "Ĉu vi volas aldoni citaĵon?" noMessagesYet: "AnkoraÅ neniu mesaÄo" @@ -393,6 +403,7 @@ onlyOneFileCanBeAttached: "Oni povas aldoni nur unu dosieron po mesaÄo." signinRequired: "Bonvolu saluti" invitations: "Inviti" invitationCode: "Kodo de invito" +checking: "kontrolante..." available: "Disposabla" unavailable: "Ne disponebla" usernameInvalidFormat: "La uzantnomo povas enhavi minusklajn kaj majusklajn literojn, numerojn, nur kaj '_'." @@ -404,6 +415,7 @@ strongPassword: "Forta pasvorto" passwordMatched: "Konforma" passwordNotMatched: "Nekonforma" signinWith: "Saluti kun {x}" +signinFailed: "FuÅiÄis ensaluti. Bonvolu kontroli uzantnomon kaj pasvorton." or: "AÅ" language: "Lingvo" uiLanguage: "Lingvo de fasado" @@ -430,6 +442,7 @@ total: "Entute" appearance: "Eksteraĵo" clientSettings: "Agordoj de kliento" accountSettings: "Agordoj de konto" +promote: "Reklamata" numberOfDays: "Nombro de tagoj" hideThisNote: "KaÅi la noton" showFeaturedNotesInTimeline: "Montri en via templinio notojn de la tendenco" @@ -465,11 +478,13 @@ scratchpad: "Malneta redaktilo" output: "Elmeto" script: "Skripto" disablePagesScript: "Malebligi AiScript en la paÄoj" +updateRemoteUser: "Aktualigi informon de foraj uzantoj" deleteAllFiles: "ForviÅi ĉiujn dosierojn" deleteAllFilesConfirm: "Ĉu vi certas, ke vi volas forviÅi ĉiujn dosierojn?" removeAllFollowing: "Ĉesi sekvi ĉiujn sekvatojn" userSuspended: "La uzanto estas flostigita." userSilenced: "La uzanto estas mutigita." +yourAccountSuspendedTitle: "La konto estas frostigita." menu: "Menuo" addItem: "Aldoni novaĵon" deletedNote: "ForviÅita noto" @@ -499,6 +514,7 @@ generateAccessToken: "Generi aÅtentikigan pecon" permission: "Permesoj" enableAll: "Ebligi ĉiujn" disableAll: "Malebligi ĉiujn" +tokenRequested: "Alirpermeso al konto" notificationType: "Tipo de sciigoj" edit: "Redakti" emailServer: "RetpoÅta servilo" @@ -530,6 +546,7 @@ regenerateLoginToken: "Regeneri la aÅtentikigan pecon" fileIdOrUrl: "Dosiera identigilo aÅ URL" behavior: "Konduto" sample: "Ekzemplo" +reporter: "Informanto" send: "Sendi" openInNewTab: "Malfermi en nova langeto" editTheseSettingsMayBreakAccount: "Redakti tiujn agordojn povas damaÄi vian konton." @@ -553,6 +570,7 @@ followingCount: "La nombro de sekvatoj" followersCount: "La nombro de sekvantoj" sentReactionsCount: "La nombro de la reagoj senditaj" receivedReactionsCount: "La nombro de la reagoj ricevitaj" +pollVotesCount: "Nombro de voĉdonado" yes: "Jes" no: "Ne" driveFilesCount: "La nombro de la dosieroj sur la disko" @@ -587,6 +605,7 @@ createdAt: "Kreita je" updatedAt: "Laste Äisdatigita" saveConfirm: "Ĉu vi konservas la ÅanÄon?" deleteConfirm: "Ĉu certas forviÅi?" +invalidValue: "Nevalida valoro" closeAccount: "Forigi konton" currentVersion: "La aktuala versio" latestVersion: "La plej nova versio" @@ -608,14 +627,18 @@ userInfo: "Informoj de uzanto" unknown: "Nekonata" online: "Surkonektita" offline: "Forkonektita" +notRecommended: "Evitindaj" instanceBlocking: "Bloki specifajn nodojn" selectAccount: "Elekti konton" user: "Uzantoj" administration: "Bontenado" accounts: "Kontoj" +configure: "Agordi" recentPosts: "Novaj afiÅoj" +popularPosts: "Populara noto" shareWithNote: "Kundividi en noto" ads: "Reklamaĵo" +expiration: "Limtempo" memo: "Memorigilo" high: "Alta" middle: "Meza" @@ -629,12 +652,18 @@ searchResult: "Serĉorezultoj" hashtags: "Kradvorto" troubleshooting: "Problemsolvi" learnMore: "Lernu pli" +misskeyUpdated: "Misskey ÄisdatiÄis!" +whatIsNew: "Montri novaĵojn" translate: "Traduki" translatedFrom: "Tradukita el {x}" +accountDeletionInProgress: "La konto estas forviÅanta." +resolved: "Solvita" +unresolved: "Nesolvita" breakFollow: "Ĉesigi la sekvadon al vi" itsOn: "Åœaltita" emailRequiredForSignup: "Registri konton devas konformi retpoÅtadreson" unread: "Nelegita" +filter: "Filtrilo" controlPanel: "Åœaltpodio" manageAccounts: "Bonteni la kontojn" classic: "Klasika" @@ -644,6 +673,7 @@ ffVisibility: "Videbleco de viaj sekvatoj/sekvantoj" ffVisibilityDescription: "Oni permesas agordi tiuln kiuj povas vidi la homojn kiujn vi sekvas, kaj la homojn kiuj sekvas vin." continueThread: "Pli vidi la mesaÄaron" incorrectPassword: "Nevalida pasvorto" +voteConfirm: "Ĉu vi voĉdonas {choice}n?" leaveGroup: "EliÄi el la grupo" leaveGroupConfirm: "Ĉu vi certas ke vi volas eliÄi el la grupo {name}?" welcomeBackWithName: "Bonrevenon, {name}!" @@ -661,11 +691,14 @@ _signup: emailAddressInfo: "Entajpu vian retpoÅton" _accountDelete: accountDelete: "Forigi konton" + requestAccountDelete: "Peti forviÅi konton" + started: "ForviÅado komenciÄis." _ad: back: "Nuligi" _forgotPassword: enterEmail: "Entajpu la retpoÅton kiun vi registrigis al via konto. Ligilo por restarigi pasvorton estos sendita al la retadreso." _gallery: + my: "Mia afiÅo" liked: "Åœatitaj notoj" like: "Åœati" _email: @@ -687,6 +720,7 @@ _aboutMisskey: allContributors: "Ĉiuj kontribuantoj" source: "Fontkodo" translation: "Traduki Misskey" + donate: "Mondonaci al Misskey" patrons: "Mecenatoj" _mfm: dummy: "Misskey evoluigas la mondon de Fediverso" @@ -724,6 +758,7 @@ _channel: owned: "Bontenitaj de vi" following: "Sekvado" usersCount: "{n} partoprenantoj" + notesCount: "{n} notoj" _menuDisplay: sideFull: "Flanko" sideIcon: "Flanko (bildsimbolo)" @@ -735,9 +770,15 @@ _wordMute: hard: "Per la servilo" mutedNotes: "Silentigitaj notoj" _theme: + explore: "Serĉi koloraron" + install: "Instali koloraron" manage: "Bonteni kolorarojn" code: "Kolorara kodo" description: "Priskribo" + installedThemes: "Instalita koloraro" + make: "Krei koloraron" + addConstant: "Aldoni konstanton" + constant: "Konstanto" defaultValue: "Implicitaĵa valoro" color: "Koloro" func: "Funkcio" @@ -745,12 +786,14 @@ _theme: lighten: "Brileco" keys: bg: "Fono" + shadow: "Ombro" navBg: "Fono de flanka stango" link: "Ligilo" hashtag: "Kradvorto" mention: "Mencioj" mentionMe: "Mencio al vi" renote: "Plusendita" + infoBg: "Fono de informo" buttonBg: "Fono de butono" driveFolderBg: "Fono de dosierujo de la disko" messageBg: "Fono de la retbabilejo" @@ -823,6 +866,7 @@ _widgets: timeline: "Templinio" clock: "HorloÄo" activity: "Aktiveco" + photos: "Fotoj" federation: "Federaĵo" slideshow: "Bildoprezento" button: "Butono" @@ -830,10 +874,12 @@ _widgets: aichan: "Ai" _cw: show: "Vidi pli" + chars: "{count} literoj" files: "{count} dosiero(j)" _poll: choiceN: "Balotilo {n}" noMore: "Oni ne povas aldoni pli." + expiration: "Limtempo" infinite: "Neniam" deadlineTime: "hor" votesCount: "{n} balotiloj" @@ -876,7 +922,7 @@ _exportOrImport: blockingList: "Blokitoj" userLists: "Listoj" _charts: - federationInstancesTotal: "La totala nombro de nodoj federantaj" + federation: "Federaĵo" usersTotal: "La totala nombro de la uzantoj" activeUsers: "La nombro de la uzantoj aktivaj" notesTotal: "La totala nombro de notoj" @@ -965,6 +1011,45 @@ _pages: _join: arg1: "Listoj" arg2: "apartigilo" + _add: + arg1: "A" + arg2: "B" + _subtract: + arg1: "A" + arg2: "B" + _multiply: + arg1: "A" + arg2: "B" + _divide: + arg1: "A" + arg2: "B" + _mod: + arg1: "A" + arg2: "B" + _eq: + arg1: "A" + arg2: "B" + _notEq: + arg1: "A" + arg2: "B" + _and: + arg1: "A" + arg2: "B" + _or: + arg1: "A" + arg2: "B" + _lt: + arg1: "A" + arg2: "B" + _gt: + arg1: "A" + arg2: "B" + _ltEq: + arg1: "A" + arg2: "B" + _gtEq: + arg1: "A" + arg2: "B" random: "Hazardo" _randomPick: arg1: "Listoj" diff --git a/locales/es-ES.yml b/locales/es-ES.yml index a9339acf7b232a1f693785722ac4bb7371c2a02a..1e85e7d8c42047943e4a201d988e54dd2f923aa7 100644 --- a/locales/es-ES.yml +++ b/locales/es-ES.yml @@ -1091,8 +1091,8 @@ _exportOrImport: blockingList: "Bloqueados" userLists: "Listas" _charts: - federationInstancesIncDec: "Variación de instancias federando" - federationInstancesTotal: "Total de instancias federando" + federation: "Federación" + apRequest: "Pedidos" usersIncDec: "Variación de usuarios" usersTotal: "Total de usuarios" activeUsers: "Cantidad de usuarios activos" diff --git a/locales/fr-FR.yml b/locales/fr-FR.yml index 62f85bef8de501e1189f94d22b5899390dec4b1b..1deda414ce7861ef73672752b88eeb75cccb904b 100644 --- a/locales/fr-FR.yml +++ b/locales/fr-FR.yml @@ -141,6 +141,7 @@ flagAsBot: "Ce compte est 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" flagAsCatDescription: "Activer l'option \" Je suis un chat \" pour ce compte." +flagShowTimelineReplies: "Afficher les réponses dans le fil" autoAcceptFollowed: "Accepter automatiquement les demandes d’abonnement venant d’utilisateur·rice·s que vous suivez" addAccount: "Ajouter un compte" loginFailed: "Échec de la connexion" @@ -811,6 +812,7 @@ ffVisibilityDescription: "Permet de configurer qui peut voir les personnes que t continueThread: "Afficher la suite du fil" deleteAccountConfirm: "Votre compte sera supprimé. Êtes vous certain ?" incorrectPassword: "Le mot de passe est incorrect." +voteConfirm: "Confirmez-vous votre vote pour « {choice} » ?" hide: "Masquer" leaveGroup: "Quitter le groupe" leaveGroupConfirm: "Êtes vous sûr de vouloir quitter \"{name}\" ?" @@ -972,6 +974,8 @@ _wordMute: hard: "Strict" mutedNotes: "Notes filtrées" _instanceMute: + instanceMuteDescription2: "Séparer avec de nouvelles lignes" + title: "Masque les notes venant des instances listées." heading: "Instances à mettre en sourdine" _theme: explore: "Explorer les thèmes" @@ -1247,8 +1251,8 @@ _exportOrImport: excludeMutingUsers: "Exclure les utilisateur·rice·s mis en sourdine" excludeInactiveUsers: "Exclure les utilisateur·rice·s inactifs" _charts: - federationInstancesIncDec: "Variation du nombre d'instances fédérées" - federationInstancesTotal: "Nombre total d'instances fédérées" + federation: "Fédération" + apRequest: "Requêtes" usersIncDec: "Variation du nombre d'utilisateur·rice·s" usersTotal: "Nombre des utilisateur·rice·s au total" activeUsers: "Nombre d'utilisateurices actif·ve·s" diff --git a/locales/id-ID.yml b/locales/id-ID.yml index a1d52f6ef1b5e547c3dc1777e1eb68c8d0522eb4..be766e72c53bac9cd8dc692f3baea1759cd20e5b 100644 --- a/locales/id-ID.yml +++ b/locales/id-ID.yml @@ -106,6 +106,7 @@ clickToShow: "Klik untuk melihat" sensitive: "Konten sensitif" add: "Tambahkan" reaction: "Reaksi" +reactionSetting: "Reaksi untuk dimunculkan di bilah reaksi" reactionSettingDescription2: "Geser untuk memindah urutkan, klik untuk menghapus, tekan \"+\" untuk menambahkan" rememberNoteVisibility: "Ingat pengaturan visibilitas catatan" attachCancel: "Hapus lampiran" @@ -140,6 +141,8 @@ flagAsBot: "Atur akun ini sebagai Bot" flagAsBotDescription: "Jika akun ini dikendalikan oleh program, tetapkanlah opsi ini. Jika diaktifkan, ini akan berfungsi sebagai tanda bagi pengembang lain untuk mencegah interaksi berantai dengan bot lain dan menyesuaikan sistem internal Misskey untuk memperlakukan akun ini sebagai bot." flagAsCat: "Atur akun ini sebagai kucing" flagAsCatDescription: "Nyalakan tanda ini untuk menandai akun ini sebagai kucing." +flagShowTimelineReplies: "Tampilkan balasan di linimasa" +flagShowTimelineRepliesDescription: "Menampilkan balasan pengguna dari note pengguna lain di linimasa apabila dinyalakan." autoAcceptFollowed: "Setujui otomatis permintaan mengikuti dari pengguna yang kamu ikuti" addAccount: "Tambahkan akun" loginFailed: "Gagal untuk masuk" @@ -234,6 +237,8 @@ resetAreYouSure: "Yakin mau atur ulang?" saved: "Telah disimpan" messaging: "Pesan" upload: "Unggah" +keepOriginalUploading: "Simpan gambar asli" +keepOriginalUploadingDescription: "Simpan gambar yang diunggah sebagaimana gambar aslinya. Bila dimatikan, versi tampilan web akan dihasilkan pada saat diunggah." fromDrive: "Dari Drive" fromUrl: "Dari URL" uploadFromUrl: "Unggah dari URL" @@ -446,6 +451,7 @@ uiLanguage: "Bahasa antarmuka pengguna" groupInvited: "Telah diundang ke grup" aboutX: "Tentang {x}" useOsNativeEmojis: "Gunakan Emoji bawaan sistem operasi" +disableDrawer: "Jangan gunakan menu bergaya laci" youHaveNoGroups: "Kamu tidak memiliki grup" joinOrCreateGroup: "Bergabunglah dengan grup atau kamu dapat membuat grupmu sendiri." noHistory: "Tidak ada riwayat" @@ -589,6 +595,7 @@ smtpSecure: "Gunakan SSL/TLS implisit untuk koneksi SMTP" smtpSecureInfo: "Matikan ini ketika menggunakan STARTTLS" testEmail: "Tes pengiriman surel" wordMute: "Bisukan kata" +instanceMute: "Bisuka instansi" userSaysSomething: "{name} mengatakan sesuatu" makeActive: "Aktifkan" display: "Tampilkan" @@ -616,8 +623,11 @@ reportAbuse: "Laporkan" reportAbuseOf: "Laporkan {name}" fillAbuseReportDescription: "Mohon isi rincian laporan. Jika laporan ini mengenai catatan yang spesifik, mohon lampirkan serta URL catatan tersebut." abuseReported: "Laporan kamu telah dikirimkan. Terima kasih." +reporter: "Pelapor" reporteeOrigin: "Yang dilaporkan" reporterOrigin: "Pelapor" +forwardReport: "Teruskan laporan ke instansi luar" +forwardReportIsAnonymous: "Untuk melindungi privasi akun kamu, akun anonim dari sistem akan digunakan sebagai pelapor pada instansi luar." send: "Kirim" abuseMarkAsResolved: "Tandai laporan sebagai selesai" openInNewTab: "Buka di tab baru" @@ -679,6 +689,7 @@ center: "Tengah" wide: "Lebar" narrow: "Sempit" reloadToApplySetting: "Pengaturan ini akan diterapkan saat memuat halaman kembali. Apakah kamu ingin memuat halaman kembali sekarang?" +needReloadToApply: "Pengaturan ini hanya akan diterapkan setelah memuat ulang halaman." showTitlebar: "Tampilkan bilah judul" clearCache: "Hapus tembolok" onlineUsersCount: "{n} orang sedang daring" @@ -739,6 +750,7 @@ notRecommended: "Tidak disarankan" botProtection: "Perlindungan Bot" instanceBlocking: "Instansi yang diblokir" selectAccount: "Pilih akun" +switchAccount: "Ganti akun" enabled: "Aktif" disabled: "Nonaktif" quickAction: "Aksi cepat" @@ -787,6 +799,7 @@ pubSub: "Akun Pub/Sub" lastCommunication: "Komunikasi terakhir" resolved: "Selesai" unresolved: "Belum selesai" +breakFollow: "Batalkan mengikuti" itsOn: "Aktif" itsOff: "Nonaktif" emailRequiredForSignup: "Membutuhkan alamat surel untuk mendaftar" @@ -806,6 +819,15 @@ deleteAccountConfirm: "Akun akan dihapus. Apakah kamu yakin?" incorrectPassword: "Kata sandi salah." voteConfirm: "Konfirmasi suara kamu untuk ({choice})?" hide: "Sembunyikan" +leaveGroup: "Keluar grup" +leaveGroupConfirm: "Apakah kamu yakin untuk keluar dari \"{name}\"?" +useDrawerReactionPickerForMobile: "Tampilkan bilah reaksi sebagai laci di ponsel" +welcomeBackWithName: "Selamat datang kembali, {name}." +clickToFinishEmailVerification: "Mohon klik [{ok}] untuk menyelesaikan verifikasi email." +overridedDeviceKind: "Tipe perangkat" +smartphone: "Ponsel" +tablet: "Tablet" +auto: "Otomatis" _emailUnavailable: used: "Alamat surel ini telah digunakan" format: "Format tidak valid." @@ -963,6 +985,11 @@ _wordMute: soft: "Lembut" hard: "Keras" mutedNotes: "Catatan yang dibisukan" +_instanceMute: + instanceMuteDescription: "Pengaturan ini akan membisukan note/renote apa saja dari instansi yang terdaftar, termasuk pengguna yang membalas pengguna lain dalam instansi yang dibisukan." + instanceMuteDescription2: "Pisah dengan baris baru" + title: "Sembunyikan note dari instansi terdaftar." + heading: "Daftar instansi yang akan dibisukan" _theme: explore: "Jelajahi tema" install: "Pasang tema" @@ -1234,9 +1261,11 @@ _exportOrImport: muteList: "Bisukan" blockingList: "Blokir" userLists: "Daftar" + excludeMutingUsers: "Kecualikan pengguna yang dibisukan" + excludeInactiveUsers: "Kecualikan pengguna tidak aktif" _charts: - federationInstancesIncDec: "Perbedaan jumlah # instansi yang memfederasi" - federationInstancesTotal: "Jumlah # instansi yang memfederasi" + federation: "Federasi" + apRequest: "Permintaan" usersIncDec: "Perbedaan dalam # pengguna" usersTotal: "Jumlah # pengguna" activeUsers: "Pengguna aktif" diff --git a/locales/it-IT.yml b/locales/it-IT.yml index d13e53625fcdc60fb4196d14e58f2de092e746b1..c4ec4232a53c236f4fb461b08f991016fcaeeab3 100644 --- a/locales/it-IT.yml +++ b/locales/it-IT.yml @@ -1177,8 +1177,8 @@ _exportOrImport: blockingList: "Account bloccati" userLists: "Liste" _charts: - federationInstancesIncDec: "Variazione del numero di istanze federate" - federationInstancesTotal: "Numero totale di istanze federate" + federation: "Federazione" + apRequest: "Richieste" usersIncDec: "Variazione del numero di utenti" usersTotal: "Numero totale di utenti" activeUsers: "Numero di utenti attivi" diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 8fd41e533b30f6a49cfb848af3dea026117800a8..ac8d4951a8796a8edf955960bb1ba334ad1394a5 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -141,6 +141,8 @@ flagAsBot: "Botã¨ã—ã¦è¨å®š" flagAsBotDescription: "ã“ã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆãŒãƒ—ãƒã‚°ãƒ©ãƒ ã«ã‚ˆã£ã¦é‹ç”¨ã•ã‚Œã‚‹å ´åˆã¯ã€ã“ã®ãƒ•ãƒ©ã‚°ã‚’オンã«ã—ã¾ã™ã€‚オンã«ã™ã‚‹ã¨ã€åå¿œã®é€£éŽ–を防ããŸã‚ã®ãƒ•ãƒ©ã‚°ã¨ã—ã¦ä»–ã®é–‹ç™ºè€…ã«å½¹ç«‹ã£ãŸã‚Šã€Misskeyã®ã‚·ã‚¹ãƒ†ãƒ 上ã§ã®æ‰±ã„ãŒBotã«åˆã£ãŸã‚‚ã®ã«ãªã‚Šã¾ã™ã€‚" flagAsCat: "Catã¨ã—ã¦è¨å®š" flagAsCatDescription: "ã“ã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆãŒçŒ«ã§ã‚ã‚‹ã“ã¨ã‚’示ã™å ´åˆã¯ã€ã“ã®ãƒ•ãƒ©ã‚°ã‚’オンã«ã—ã¾ã™ã€‚" +flagShowTimelineReplies: "タイムラインã«ãƒŽãƒ¼ãƒˆã¸ã®è¿”信を表示ã™ã‚‹" +flagShowTimelineRepliesDescription: "オンã«ã™ã‚‹ã¨ã€ã‚¿ã‚¤ãƒ ラインã«ãƒ¦ãƒ¼ã‚¶ãƒ¼ã®ãƒŽãƒ¼ãƒˆä»¥å¤–ã«ã‚‚ãã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã®ä»–ã®ãƒŽãƒ¼ãƒˆã¸ã®è¿”信を表示ã—ã¾ã™ã€‚" autoAcceptFollowed: "フォãƒãƒ¼ä¸ãƒ¦ãƒ¼ã‚¶ãƒ¼ã‹ã‚‰ã®ãƒ•ã‚©ãƒãƒªã‚¯ã‚’自動承èª" addAccount: "ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã‚’è¿½åŠ " loginFailed: "ãƒã‚°ã‚¤ãƒ³ã«å¤±æ•—ã—ã¾ã—ãŸ" @@ -822,6 +824,10 @@ leaveGroupConfirm: "「{name}ã€ã‹ã‚‰æŠœã‘ã¾ã™ã‹ï¼Ÿ" useDrawerReactionPickerForMobile: "モãƒã‚¤ãƒ«ãƒ‡ãƒã‚¤ã‚¹ã®ã¨ãドãƒãƒ¯ãƒ¼ã§è¡¨ç¤º" welcomeBackWithName: "ãŠã‹ãˆã‚Šãªã•ã„ã€{name}ã•ã‚“" clickToFinishEmailVerification: "[{ok}]を押ã—ã¦ã€ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ã®ç¢ºèªã‚’完了ã—ã¦ãã ã•ã„。" +overridedDeviceKind: "デãƒã‚¤ã‚¹ã‚¿ã‚¤ãƒ—" +smartphone: "スマートフォン" +tablet: "タブレット" +auto: "自動" _emailUnavailable: used: "æ—¢ã«ä½¿ç”¨ã•ã‚Œã¦ã„ã¾ã™" @@ -1296,8 +1302,8 @@ _exportOrImport: excludeInactiveUsers: "使ã‚ã‚Œã¦ã„ãªã„アカウントを除外" _charts: - federationInstancesIncDec: "連åˆã®å¢—減" - federationInstancesTotal: "連åˆã®åˆè¨ˆ" + federation: "連åˆ" + apRequest: "リクエスト" usersIncDec: "ユーザーã®å¢—減" usersTotal: "ユーザーã®åˆè¨ˆ" activeUsers: "アクティブユーザー数" diff --git a/locales/ja-KS.yml b/locales/ja-KS.yml index 45ab9684d26b26ea2d54ffbb2d1e8239075dcb71..b5b4e72576125e6fde2e42b2d7ddd72c6de03c6a 100644 --- a/locales/ja-KS.yml +++ b/locales/ja-KS.yml @@ -81,6 +81,8 @@ somethingHappened: "ãªã‚“ã‹ã‚¢ã‚«ãƒ³ã“ã¨ãŒèµ·ã“ã£ãŸã§" retry: "ã‚‚ã£ãºã‚“やる?" pageLoadError: "ページã®èªã¿è¾¼ã¿ã«å¤±æ•—ã—ã¦ã—ã‚‚ã†ãŸã§â€¦" pageLoadErrorDescription: "ã“ã‚Œã¯æ™®é€šã€ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã‹ãƒ–ラウザã‚ャッシュãŒåŽŸå› ã‚„ã‹ã‚‰ã。ã‚ャッシュをクリアã™ã‚‹ã‹ã€ã‚‚ã†ã¡ã£ã¨ã ã‘å¾…ã£ã¦ãã‚Œã¸ã‚“ã‹ï¼Ÿ" +serverIsDead: "The server is not responding. Please wait for a while before trying again." +youShouldUpgradeClient: "To display this page, please reload and use a new version client. " enterListName: "リストåを入れã¦ã‚„" privacy: "プライãƒã‚·ãƒ¼" makeFollowManuallyApprove: "自分ãŒèªã‚ãŸäººã ã‘ãŒã“ã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã‚’フォãƒãƒ¼ã§ãるよã†ã«ã™ã‚‹" @@ -104,6 +106,7 @@ clickToShow: "押ã—ãŸã‚‰è¦‹ãˆã‚‹ã§" sensitive: "ã¡ã‚‡ã£ã¨ã‚¢ã‚«ãƒ³ã‚„ã¤ã‚„ã§" add: "増やã™" reaction: "リアクション" +reactionSetting: "Reaction that will be displayed in Picker. " reactionSettingDescription2: "ドラッグã§ä¸¦ã³æ›¿ãˆã€ã‚¯ãƒªãƒƒã‚¯ã§å‰Šé™¤ã€ï¼‹ã‚’押ã—ã¦è¿½åŠ ã‚„ã§ã€‚" rememberNoteVisibility: "公開範囲覚ãˆã¨ã„ã¦" attachCancel: "ã®ã£ã‘ã‚‹ã®ã‚„ã‚ã‚‹" @@ -138,6 +141,8 @@ flagAsBot: "Botã‚„ã§" flagAsBotDescription: "ã‚‚ã—ã“ã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆãŒãƒ—ãƒã‚°ãƒ©ãƒ ã«ã‚ˆã£ã¦é‹ç”¨ã•ã‚Œã‚‹ã‚“ã‚„ã£ãŸã‚‰ã€ã“ã®ãƒ•ãƒ©ã‚°ã‚’オンã«ã—ã¦ãŸã®ã‚€ã§ã€‚オンã«ã™ã‚‹ã¨ã€åå¿œã®é€£éŽ–を防ããŸã‚ã®ãƒ•ãƒ©ã‚°ã¨ã—ã¦ä»–ã®é–‹ç™ºè€…ã«å½¹ç«‹ã£ãŸã‚Šã€Misskeyã®ã‚·ã‚¹ãƒ†ãƒ 上ã§ã®æ‰±ã„ãŒBotã«åˆã£ãŸã‚‚ã‚“ã«ãªã‚‹ã‚“ã‚„ã§ã€‚" flagAsCat: "Catã‚„ã§" flagAsCatDescription: "ワレã€çŒ«ã¡ã‚ƒã‚“ãªã‚‰ã“ã®ãƒ•ãƒ©ã‚°ã‚’ã¤ã‘ã¦ã¿ï¼Ÿ" +flagShowTimelineReplies: "It will display the reply to the note in the timeline. " +flagShowTimelineRepliesDescription: "It will display the reply to notes other than the user notes in the timeline when you turn it on. " autoAcceptFollowed: "フォãƒãƒ¼ã—ã¨ã‚‹ãƒ¦ãƒ¼ã‚¶ãƒ¼ã‹ã‚‰ã®ãƒ•ã‚©ãƒãƒ¼ãƒªã‚¯ã‚¨ã‚¹ãƒˆã‚’å‹æ‰‹ã«è¨±å¯ã—ã¨ã" addAccount: "ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã‚’è¿½åŠ " loginFailed: "ãƒã‚°ã‚¤ãƒ³ã«å¤±æ•—ã—ã¦ã—ã‚‚ã†ãŸâ€¦" @@ -232,6 +237,8 @@ resetAreYouSure: "リセットã—ã¦ãˆãˆã‚“?" saved: "ä¿å˜ã—ãŸã§ï¼" messaging: "ãƒãƒ£ãƒƒãƒˆ" upload: "アップãƒãƒ¼ãƒ‰" +keepOriginalUploading: "Retain the original image. " +keepOriginalUploadingDescription: "When uploading the clip, the original version will be retained. Turning it of then uploading will produce images for public use. " fromDrive: "ドライブã‹ã‚‰" fromUrl: "URLã‹ã‚‰" uploadFromUrl: "URLアップãƒãƒ¼ãƒ‰" @@ -884,6 +891,8 @@ _exportOrImport: blockingList: "ブãƒãƒƒã‚¯" userLists: "リスト" _charts: + federation: "連åˆ" + apRequest: "リクエスト" usersTotal: "ユーザーã®åˆè¨ˆ" activeUsers: "アクティブユーザー数" notesIncDec: "ノートã®å¢—減" diff --git a/locales/ko-KR.yml b/locales/ko-KR.yml index 38a328862f50da706ae0cb75efe1f3511d87dd38..116e397ff558887cf167630b1be59b64c295e532 100644 --- a/locales/ko-KR.yml +++ b/locales/ko-KR.yml @@ -141,6 +141,8 @@ flagAsBot: "나는 봇입니다" flagAsBotDescription: "ì´ ê³„ì •ì„ ìžë™í™”ëœ ìˆ˜ë‹¨ìœ¼ë¡œ ìš´ìš©í• ê²½ìš°ì— í™œì„±í™”í•´ 주세요. ì´ í”Œëž˜ê·¸ë¥¼ 활성화하면, 다른 ë´‡ì´ ì´ë¥¼ ì°¸ê³ í•˜ì—¬ ë´‡ ë¼ë¦¬ì˜ 무한 연쇄 ë°˜ì‘ì„ íšŒí”¼í•˜ê±°ë‚˜, ì´ ê³„ì •ì˜ ì‹œìŠ¤í…œ ìƒì—ì„œì˜ ì·¨ê¸‰ì´ Bot ìš´ì˜ì— 최ì í™”ë˜ëŠ” ë“±ì˜ ë³€í™”ê°€ ìƒê¹ë‹ˆë‹¤." flagAsCat: "나는 ê³ ì–‘ì´ë‹¤ëƒ¥" flagAsCatDescription: "ì´ ê³„ì •ì´ ê³ ì–‘ì´ë¼ë©´ 활성화 해주세요." +flagShowTimelineReplies: "타임ë¼ì¸ì— ë…¸íŠ¸ì˜ ë‹µê¸€ì„ í‘œì‹œí•˜ê¸°" +flagShowTimelineRepliesDescription: "ì´ ì„¤ì •ì„ í™œì„±í™”í•˜ë©´ 타임ë¼ì¸ì— 다른 ìœ ì € ê°„ì˜ ë‹µê¸€ì„ í‘œì‹œí•©ë‹ˆë‹¤." autoAcceptFollowed: "팔로우 ì¤‘ì¸ ìœ ì €ë¡œë¶€í„°ì˜ íŒ”ë¡œìš° ìš”ì²ì„ ìžë™ 수ë½" addAccount: "ê³„ì • 추가" loginFailed: "로그ì¸ì— 실패했습니다" @@ -822,6 +824,10 @@ leaveGroupConfirm: "\"{name}\"ì—ì„œ 나갈까요?" useDrawerReactionPickerForMobile: "모바ì¼ì—ì„œ 드로어 메뉴로 표시" welcomeBackWithName: "환ì˜í•©ë‹ˆë‹¤, {name}님" clickToFinishEmailVerification: "[{ok}]를 눌러 ì´ë©”ì¼ ì¸ì¦ì„ 완료하세요." +overridedDeviceKind: "장치 ìœ í˜•" +smartphone: "스마트í°" +tablet: "태블릿" +auto: "ìžë™" _emailUnavailable: used: "ì´ ë©”ì¼ ì£¼ì†ŒëŠ” 사용중입니다" format: "형ì‹ì´ 올바르지 않습니다" @@ -1258,8 +1264,8 @@ _exportOrImport: excludeMutingUsers: "뮤트한 ìœ ì € ì œì™¸í•˜ê¸°" excludeInactiveUsers: "휴면 ì¤‘ì¸ ê³„ì • ì œì™¸í•˜ê¸°" _charts: - federationInstancesIncDec: "ì—°í•© ì¸ìŠ¤í„´ìŠ¤ 수 ì¦ê°" - federationInstancesTotal: "ì—°í•© ì¸ìŠ¤í„´ìŠ¤ 수 합계" + federation: "ì—°í•©" + apRequest: "ìš”ì²" usersIncDec: "ìœ ì € 수 ì¦ê°" usersTotal: "ìœ ì € 수 합계" activeUsers: "활성 ìœ ì € 수" diff --git a/locales/nl-NL.yml b/locales/nl-NL.yml index 386357f2d39ec823b7d07249626db86f9bb8c3f4..38f9a88af8e0241f42e0a870d73fe3f504590ad1 100644 --- a/locales/nl-NL.yml +++ b/locales/nl-NL.yml @@ -291,6 +291,8 @@ _exportOrImport: userLists: "Lijsten" excludeMutingUsers: "Negeer gedempte gebruikers" excludeInactiveUsers: "Negeer inactieve gebruikers" +_charts: + federation: "Federatie" _timelines: home: "Startpagina" _pages: diff --git a/locales/pl-PL.yml b/locales/pl-PL.yml index 27772663bcee03d138726334cd884efc80b294a9..0b57a3a46fa19e10e897287ba8218c7ba44a0c85 100644 --- a/locales/pl-PL.yml +++ b/locales/pl-PL.yml @@ -1084,7 +1084,8 @@ _exportOrImport: blockingList: "Zablokuj" userLists: "Listy" _charts: - federationInstancesTotal: "ÅÄ…cznie sfederowanych instancji" + federation: "Federacja" + apRequest: "Żądania" usersTotal: "ÅÄ…cznie # użytkowników" activeUsers: "Aktywni użytkownicy" _instanceCharts: diff --git a/locales/ru-RU.yml b/locales/ru-RU.yml index 7de9f8ff950b007cd24db2393f52f0d47929a9f7..b29d2173c80cbeecb9fadfd35ebc2dfbc9b3c5d1 100644 --- a/locales/ru-RU.yml +++ b/locales/ru-RU.yml @@ -235,6 +235,7 @@ resetAreYouSure: "Ðа Ñамом деле ÑброÑить?" saved: "Сохранено" messaging: "СообщениÑ" upload: "Загрузить" +keepOriginalUploading: "Сохранить иÑходное изображение" fromDrive: "С «диÑка»" fromUrl: "По ÑÑылке" uploadFromUrl: "Загрузить по ÑÑылке" @@ -743,6 +744,7 @@ notRecommended: "Ðе рекомендуетÑÑ" botProtection: "Ботозащита" instanceBlocking: "Блокировка инÑтанÑов" selectAccount: "Выберите учётную запиÑÑŒ" +switchAccount: "Сменить учётную запиÑÑŒ" enabled: "Вкл." disabled: "Откл." quickAction: "БыÑтрое дейÑтвие" @@ -1249,8 +1251,8 @@ _exportOrImport: excludeMutingUsers: "За иÑключением заглушенных пользователей" excludeInactiveUsers: "Без неактивных учётных запиÑей" _charts: - federationInstancesIncDec: "Изменение внешних ÑвÑзей" - federationInstancesTotal: "КоличеÑтво внешних ÑвÑзей" + federation: "ФедерациÑ" + apRequest: "ЗапроÑÑ‹" usersIncDec: "Изменение чиÑла пользователей" usersTotal: "КоличеÑтво пользователей" activeUsers: "Ðктивные пользователи" diff --git a/locales/sk-SK.yml b/locales/sk-SK.yml new file mode 100644 index 0000000000000000000000000000000000000000..7ee4f5be7933ad93993d7d60f850dcc7c2e90688 --- /dev/null +++ b/locales/sk-SK.yml @@ -0,0 +1,1636 @@ +--- +_lang_: "SlovenÄina" +headlineMisskey: "SieÅ¥ prepojená poznámkami" +introMisskey: "Vitajte! Misskey je otvorená a decentralizovaná mikroblogovacia služba.\n\"Poznámkami\" môžete zdieľaÅ¥ svoje myÅ¡lienky so vÅ¡etkými okolo. 📡\nPomocou \"reakciÃ\" môžete rýchlo vyjadri svoje pocity o každého poznámkach. ðŸ‘\nPoÄte objavovaÅ¥ svet! 🚀" +monthAndDay: "{day}. {month}." +search: "HľadaÅ¥" +notifications: "Oznámenia" +username: "Meno použÃvateľa" +password: "Heslo" +forgotPassword: "Zabudnuté heslo" +fetchingAsApObject: "NaÄÃtam údaje z Fediverzu" +ok: "OK" +gotIt: "Rozumiem!" +cancel: "ZruÅ¡iÅ¥" +enterUsername: "Zadajte meno použÃvateľa" +renotedBy: "{user} preposlal/a" +noNotes: "Žiadne poznámky" +noNotifications: "Žiadne oznámenia" +instance: "InÅ¡tancia" +settings: "Nastavenia" +basicSettings: "VÅ¡eobecné nastavenia" +otherSettings: "RozÅ¡Ãrené nastavenia" +openInWindow: "OtvoriÅ¥ v novom okne" +profile: "Profil" +timeline: "ÄŒasová os" +noAccountDescription: "Tento použÃvateľ zatiaľ nenapÃsal o sebe." +login: "PrihlásiÅ¥ sa" +loggingIn: "Prebieha prihlasovanie" +logout: "OdhlásiÅ¥" +signup: "RegistrovaÅ¥" +uploading: "Nahrávanie..." +save: "UložiÅ¥" +users: "PoužÃvatelia" +addUser: "PridaÅ¥ použÃvateľa" +favorite: "PáÄi sa mi" +favorites: "Obľúbené" +unfavorite: "NepáÄi sa mi" +favorited: "Pridané do obľúbených" +alreadyFavorited: "Už je medzi obľúbenými" +cantFavorite: "Nepodarilo sa pridaÅ¥ medzi obľúbené." +pin: "Pripnúť" +unpin: "Odopnúť" +copyContent: "KopÃrovaÅ¥ obsah" +copyLink: "KopÃrovaÅ¥ odkaz" +delete: "OdstrániÅ¥" +deleteAndEdit: "OdstrániÅ¥ a upraviÅ¥" +deleteAndEditConfirm: "Naozaj chcete odstrániÅ¥ túto poznámku a upraviÅ¥ ju? StratÃte tým vÅ¡etky reakcie a odpovede na ňu." +addToList: "PridaÅ¥ do zoznamu" +sendMessage: "OdoslaÅ¥ správu" +copyUsername: "KopÃrovaÅ¥ meno použÃvateľa" +searchUser: "HľadaÅ¥ použÃvateľov" +reply: "OdpovedaÅ¥" +loadMore: "ZobraziÅ¥ viac" +showMore: "ZobraziÅ¥ viac" +youGotNewFollower: "Máte nového sledujúceho" +receiveFollowRequest: "ŽiadosÅ¥ o sledovanie prijatá" +followRequestAccepted: "ŽiadosÅ¥ o sledovanie akceptovaná" +mention: "Zmienka" +mentions: "Zmienky" +directNotes: "Priame poznámky" +importAndExport: "Import a export" +import: "ImportovaÅ¥" +export: "ExportovaÅ¥" +files: "Súbor/y" +download: "StiahnuÅ¥" +driveFileDeleteConfirm: "Naozaj chcete odstrániÅ¥ súbor \"{name}\"? Poznámky s týmto súborom sa odstránia tiež." +unfollowConfirm: "Naozaj už nechcete sledovaÅ¥ {name}?" +exportRequested: "Vyžiadali ste export. Môže to chvÃľu trvaÅ¥. Po skonÄenà pribudne na vaÅ¡om disku." +importRequested: "Požiadali ste o export. Môže to chvÃľu trvaÅ¥." +lists: "Zoznamy" +noLists: "Nemáte žiadne zoznamy" +note: "Poznámka" +notes: "Poznámky" +following: "Sledujete" +followers: "Sledujúci" +followsYou: "Sledujú vás" +createList: "VytvoriÅ¥ zoznam" +manageLists: "SpravovaÅ¥ zoznamy" +error: "Chyba" +somethingHappened: "Ups. NieÄo sa nepodarilo." +retry: "OpakovaÅ¥" +pageLoadError: "Nepodarilo sa naÄÃtaÅ¥ stránku" +pageLoadErrorDescription: "Toto môže byÅ¥ spôsobené problémami so sieÅ¥ou alebo cachou prehliadaÄa. Skúste vyÄistiÅ¥ cache a potom skúsiÅ¥ znova po chvÃli." +serverIsDead: "Tento server nereaguje. ProsÃm chvÃľu poÄkajte a skúste znova." +youShouldUpgradeClient: "Na pozretie tejto stránky prosÃm obnovte svojho klienta." +enterListName: "Zadajte názov zoznamu" +privacy: "Súkromie" +makeFollowManuallyApprove: "Žiadosti o sledovanie treba schváliÅ¥" +defaultNoteVisibility: "Predvolená viditeľnosÅ¥" +follow: "SledovaÅ¥" +followRequest: "PožiadaÅ¥ o sledovanie" +followRequests: "Žiadosti o sledovanie" +unfollow: "NesledovaÅ¥" +followRequestPending: "ŽiadosÅ¥ o sledovanie Äaká" +enterEmoji: "Zadajte emoji" +renote: "PreposlaÅ¥" +unrenote: "VrátiÅ¥ preposlanie" +renoted: "Preposlané." +cantRenote: "Tento prÃspevok sa nedá preposlaÅ¥." +cantReRenote: "OdpoveÄ nemôže byÅ¥ odstránená." +quote: "CitovaÅ¥" +pinnedNote: "Pripnuté poznámky" +pinned: "Pripnúť" +you: "Vy" +clickToShow: "KliknutÃm zobrazÃte" +sensitive: "NSFW" +add: "PridaÅ¥" +reaction: "Reakcie" +reactionSetting: "Reakcie zobrazené vo výbere reakciÃ" +reactionSettingDescription2: "ŤahanÃm preusporiadate, kliknutÃm odstránite, StlaÄenÃm \"+\" pridáte" +rememberNoteVisibility: "ZapamätaÅ¥ nastavenia viditeľnosti poznámky" +attachCancel: "OdstrániÅ¥ prÃlohu" +markAsSensitive: "OznaÄiÅ¥ ako NSFW" +unmarkAsSensitive: "OdznaÄiÅ¥ NSFW" +enterFileName: "Zadajte názov súboru" +mute: "Vypnúť zvuk" +unmute: "Zapnúť zvuk" +block: "ZablokovaÅ¥" +unblock: "OdblokovaÅ¥" +suspend: "ZmraziÅ¥" +unsuspend: "OdmraziÅ¥" +blockConfirm: "Naozaj chcete zablokovaÅ¥ tento úÄet?" +unblockConfirm: "Naozaj chcete odblokovaÅ¥ tento úÄet?" +suspendConfirm: "Naozaj chcete zmraziÅ¥ tento úÄet?" +unsuspendConfirm: "Naozaj chcete odmraziÅ¥ tento úÄet?" +selectList: "Vyberte zoznam" +selectAntenna: "Vyberte anténu" +selectWidget: "Vyberte widget" +editWidgets: "UpraviÅ¥ widget" +editWidgetsExit: "Hotovo" +customEmojis: "Vlastné emoji" +emoji: "Emoji" +emojis: "Emoji" +emojiName: "Názov emoji" +emojiUrl: "URL obrázku" +addEmoji: "PridaÅ¥ emoji" +settingGuide: "OdporúÄané nastavenia" +cacheRemoteFiles: "Cachovanie vzdialených súborov" +cacheRemoteFilesDescription: "Zakázanie tohoto nastavenia spôsobÃ, že vzdialené súbory budú odkazované priamo, namiesto ukladania do cache. UÅ¡etrà sa tak miesto na serveri, ale zvýši sa dátový tok, pretože sa negenerujú miniatúry." +flagAsBot: "Tento úÄet je bot" +flagAsBotDescription: "Ak je tento úÄet ovládaný programom, zaÅ¡krtnite túto voľbu. Ostatnà uvidia, že je to bot a zabráni nekoneÄným interakciám s ÄalÅ¡Ãmi botmi a upravà interné systémy Misskey, aby ho považoval za bota." +flagAsCat: "Tento úÄet je maÄka" +flagAsCatDescription: "Zvoľte túto voľbu, aby bol tento úÄet oznaÄený ako maÄka." +flagShowTimelineReplies: "ZobraziÅ¥ odpovede na poznámky v Äasovej osi" +flagShowTimelineRepliesDescription: "KeÄ je zapnuté, na Äasovej osi sa zobrazia odpovede k poznámkam použÃvateľov okrem samotných poznámok." +autoAcceptFollowed: "Automaticky prijaÅ¥ sledovanie od úÄtov, ktoré sledujete" +addAccount: "PridaÅ¥ úÄet" +loginFailed: "Prihlásenie sa nepodarilo." +showOnRemote: "ZobraziÅ¥ na vzdialenom serveri" +general: "VÅ¡eobecné" +wallpaper: "Tapeta" +setWallpaper: "NastaviÅ¥ tapetu" +removeWallpaper: "OdstrániÅ¥ tapetu" +searchWith: "HľadaÅ¥: {q}" +youHaveNoLists: "Nemáte žiadne zoznamy" +followConfirm: "Naozaj chcete sledovaÅ¥ {name}?" +proxyAccount: "Proxy úÄet" +proxyAccountDescription: "Proxy úÄet je úÄet, ktorý za urÄitých podmienok sleduje použÃvateľov na diaľku vaÅ¡Ãm menom. NaprÃklad keÄ použÃvateľ zaradà vzdialeného použÃvateľa do zoznamu, pokiaľ nikto nesleduje použÃvateľa na zozname, aktivita nebude doruÄená na server, takže namiesto toho bude použÃvateľa sledova proxy úÄet." +host: "Host" +selectUser: "Vyberte použÃvateľa" +recipient: "PrijÃmateľ" +annotation: "Komentáre" +federation: "Federácia" +instances: "InÅ¡tancia" +registeredAt: "Registrácia" +latestRequestSentAt: "Posledná odoslaná požiadavka" +latestRequestReceivedAt: "Posledná prijatá požiadavka" +latestStatus: "Posledný status" +storageUsage: "Využité úložisko" +charts: "Grafy" +perHour: "za hodinu" +perDay: "za deň" +stopActivityDelivery: "ZastaviÅ¥ posielanie aktivÃt" +blockThisInstance: "BlokovaÅ¥ tento server" +operations: "Operácie" +software: "Softvér" +version: "Verzia" +metadata: "Metadáta" +withNFiles: "{n} súbor(ov)" +monitor: "Monitor" +jobQueue: "Fronta úloh" +cpuAndMemory: "CPU a pamäť" +network: "SieÅ¥" +disk: "Disk" +instanceInfo: "Informácie o serveri" +statistics: "Å tatistiky" +clearQueue: "VyÄistiÅ¥ frontu" +clearQueueConfirmTitle: "Naozaj chcete zruÅ¡iÅ¥ vÅ¡etky úlohy vo fronte?" +clearQueueConfirmText: "VÅ¡etky nedoruÄené poznámky Äakajúce vo fronte nebudú federované. ZvyÄajne táto operácia nie je potrebná." +clearCachedFiles: "VyprázdniÅ¥ cache" +clearCachedFilesConfirm: "Naozaj chcete odstrániÅ¥ vÅ¡etky nacachované vzdialené súbory?" +blockedInstances: "Blokované servery" +blockedInstancesDescription: "Zoznam blokovaných serverov na riadkoch. Blokované servery nebudú môcÅ¥ komunikovaÅ¥ s týmto serverom." +muteAndBlock: "UmlÄania a blokácie" +mutedUsers: "UmlÄanà použÃvatelia" +blockedUsers: "Blokovanà použÃvatelia" +noUsers: "Žiadni použÃvatelia" +editProfile: "UpraviÅ¥ profil" +noteDeleteConfirm: "Naozaj chcete odstrániÅ¥ túto poznámku?" +pinLimitExceeded: "ÄŽalÅ¡ie poznámky už nemôžete pripnúť." +intro: "InÅ¡talácia Misskey je dokonÄená! ProsÃm vytvorte administrátora." +done: "Hotovo" +processing: "Pracujem..." +preview: "Náhľad" +default: "Predvolené" +noCustomEmojis: "Žiadne emoji" +noJobs: "Žiadne úlohy" +federating: "Federácia" +blocked: "Blokované" +suspended: "Zmrazené" +all: "VÅ¡etko" +subscribing: "Odoberanie" +publishing: "Zverejňovanie" +notResponding: "Neodpovedá" +instanceFollowing: "Sledujem na serveri" +instanceFollowers: "Sledujúci zo servera" +instanceUsers: "PoužÃvatelia servera" +changePassword: "ZmeniÅ¥ heslo" +security: "ZabezpeÄenie" +retypedNotMatch: "Zadané vstupy nesúhlasia" +currentPassword: "Aktuálne heslo" +newPassword: "Nové heslo" +newPasswordRetype: "Nové heslo (znovu)" +attachFile: "PriložiÅ¥ súbor" +more: "Viac!" +featured: "Obľúbené poznámky" +usernameOrUserId: "Meno použÃvateľa alebo ID použÃvateľa" +noSuchUser: "PoužÃvateľ sa nenaÅ¡iel" +lookup: "VyhľadaÅ¥" +announcements: "Oznamy" +imageUrl: "URL obrázku" +remove: "OdstrániÅ¥" +removed: "Odstránené" +removeAreYouSure: "Naozaj chcete odstrániÅ¥ \"{x}\"?" +deleteAreYouSure: "Naozaj chcete odstrániÅ¥ \"{x}\"?" +resetAreYouSure: "Naozaj resetovaÅ¥?" +saved: "Uložené" +messaging: "Chat" +upload: "NahraÅ¥ súbor" +keepOriginalUploading: "ZachovaÅ¥ pôvodný obrázok" +keepOriginalUploadingDescription: "Uložà pôvodný obrázok ako je. Ak je vypnuté, verzia pre web sa vygeneruje pri nahratÃ." +fromDrive: "Z disku" +fromUrl: "Z URL" +uploadFromUrl: "NahraÅ¥ z URL adresy" +uploadFromUrlDescription: "URL adresa nahrávaného súboru" +uploadFromUrlRequested: "Upload vyžiadaný" +uploadFromUrlMayTakeTime: "Nahrávanie môže nejaký Äas trvaÅ¥." +explore: "ObjavovaÅ¥" +messageRead: "PreÄÃtané" +noMoreHistory: "To je vÅ¡etko" +startMessaging: "ZaÄaÅ¥ chat" +nUsersRead: "preÄÃtané {n} použÃvateľmi" +agreeTo: "SúhlasÃm s {0}" +tos: "Podmienky použÃvania" +start: "ZaÄaÅ¥" +home: "Domov" +remoteUserCaution: "Tieto informácie nemusia byÅ¥ aktuálne, keÄže použÃvateľ je na vzdialenom serveri." +activity: "Aktivita" +images: "Obrázky" +birthday: "Dátum narodenia" +yearsOld: "{age} rokov" +registeredDate: "Dátum registrácie" +location: "Lokalita" +theme: "Téma" +themeForLightMode: "Téma pri svetlom režime" +themeForDarkMode: "Téma pri tmavom režime" +light: "Svetlá" +dark: "Tmavá" +lightThemes: "Svetlá téma" +darkThemes: "Tmavá téma" +syncDeviceDarkMode: "SynchronizovaÅ¥ tmavú tému s nastavenà vášho systému" +drive: "Disk" +fileName: "Názov súboru" +selectFile: "Vyberte súbor" +selectFiles: "Vyberte súbory" +selectFolder: "Vyberte prieÄinok" +selectFolders: "Vyberte prieÄinky" +renameFile: "PremenovaÅ¥ súbor" +folderName: "Názov prieÄinka" +createFolder: "VytvoriÅ¥ prieÄinok" +renameFolder: "PremenovaÅ¥ prieÄinok" +deleteFolder: "OdstrániÅ¥ prieÄinok" +addFile: "PridaÅ¥ súbor" +emptyDrive: "Váš disk je prázdny" +emptyFolder: "Tento prieÄinok je prázdny" +unableToDelete: "Nedá sa odstrániÅ¥" +inputNewFileName: "Zadajte nový názov" +inputNewDescription: "Zadajte nový popis" +inputNewFolderName: "Zadajte nový názov prieÄinka" +circularReferenceFolder: "Cieľový prieÄinok je podprieÄinkom prieÄinka, ktorý chcete presunúť." +hasChildFilesOrFolders: "Nemôžete odstrániÅ¥ prieÄinok sú súbormi." +copyUrl: "KopÃrovaÅ¥ URL" +rename: "PremenovaÅ¥" +avatar: "Avatar" +banner: "BAnner" +nsfw: "NSFW" +whenServerDisconnected: "KeÄ sa stratà spojenie so serverom" +disconnectedFromServer: "Spojenie so serverom bolo preruÅ¡ené" +reload: "ObnoviÅ¥" +doNothing: "IgnorovaÅ¥" +reloadConfirm: "Chcete obnoviÅ¥ Äasovú os?" +watch: "SledovaÅ¥" +unwatch: "NesledovaÅ¥" +accept: "SúhlasÃm" +reject: "NesúhlasÃm" +normal: "Normálne" +instanceName: "Názov servera" +instanceDescription: "Popis servera" +maintainerName: "Správca" +maintainerEmail: "E-mailová adresa správcu" +tosUrl: "URL zmluvných podmienok" +thisYear: "Rok" +thisMonth: "Mesiac" +today: "Dnes" +dayX: "{day}" +monthX: "{month}" +yearX: "{year}" +pages: "Stránky" +integration: "Integrácia" +connectService: "PripojiÅ¥" +disconnectService: "OdpojiÅ¥" +enableLocalTimeline: "PovoliÅ¥ lokálnu Äasovú os" +enableGlobalTimeline: "PovoliÅ¥ globálnu Äasovú os" +disablingTimelinesInfo: "Administrátori a moderátori majú vždy prÃstup ku vÅ¡etkým Äasovým osiam, aj keÄ sú vypnuté." +registration: "Registrácia" +enableRegistration: "PovoliÅ¥ registráciu nových použÃvateľov" +invite: "PozvaÅ¥" +proxyRemoteFiles: "Proxy vzdialených súborov" +proxyRemoteFilesDescription: "Ak je zapnuté, vzdialené súbory, ktoré nie sú uložené lokálne alebo boli odstránené kvôli obmedzeniam úložiska, budú vyžiadané cez proxy, vrátane generovani miniatúr. Neovplyvnà to úložisko na serveri." +driveCapacityPerLocalAccount: "Kapacita disku pre použÃvateľa" +driveCapacityPerRemoteAccount: "Kapacita disku pre vzdialeného použÃvateľa" +inMb: "V megabajtoch" +iconUrl: "Favicon URL" +bannerUrl: "URL obrázku bannera" +backgroundImageUrl: "URL obrázku pozadia" +basicInfo: "Základné informácie" +pinnedUsers: "Pripnutà použÃvatelia" +pinnedUsersDescription: "Zoznam mien použÃvateľov oddelených riadkami, ktorý budú pripnutà v záložke \"ObjavovaÅ¥\"." +pinnedPages: "Pripnuté stránky" +pinnedPagesDescription: "Na každý riadok zadajte cesty stránok, ktoré chcete pripnúť na vrch stránky tohoto servera." +pinnedClipId: "ID pripnutého klipu" +pinnedNotes: "Pripnuté poznámky" +hcaptcha: "hCaptcha" +enableHcaptcha: "Zapnúť hCaptchu" +hcaptchaSiteKey: "Site key" +hcaptchaSecretKey: "Secret key" +recaptcha: "reCAPTCHA" +enableRecaptcha: "Zapnúť ReCAPTCHA" +recaptchaSiteKey: "Site key" +recaptchaSecretKey: "Secret key" +avoidMultiCaptchaConfirm: "Použitie viacerých Captcha systémov môže sposobiÅ¥ problémy. Chcete radÅ¡ej vypnúť ostatné Captcha systémy? Môžete ich povoliÅ¥ viaceré stlaÄenà ZruÅ¡iÅ¥." +antennas: "Antény" +manageAntennas: "SpravovaÅ¥ antény" +name: "Názov" +antennaSource: "Zdroj antény" +antennaKeywords: "PoÄúvané kľúÄové slová" +antennaExcludeKeywords: "VylúÄené kľúÄové slová" +antennaKeywordsDescription: "Oddeľte medzerami pre podmienku AND alebo novými riadkami pre podmienku OR." +notifyAntenna: "UpozorniÅ¥ na nové poznámky" +withFileAntenna: "Len poznámky so súbormi" +enableServiceworker: "PovoliÅ¥ Service Worker" +antennaUsersDescription: "Zoznam použÃvateľov jeden na riadok" +caseSensitive: "RozliÅ¡uje malé a veľké pÃsmená" +withReplies: "Vrátane odpovedÃ" +connectedTo: "Nasledujúce úÄty sú pripojené" +notesAndReplies: "Poznámky a odpovede" +withFiles: "Vrátane súborov" +silence: "Ticho" +silenceConfirm: "Naozaj chcete utÃÅ¡iÅ¥ tohoto použÃvateľa?" +unsilence: "VrátiÅ¥ utÃÅ¡enie" +unsilenceConfirm: "Naozaj chcete vrátiÅ¥ utÃÅ¡enie tohoto použÃvateľa?" +popularUsers: "Populárni použÃvatelia" +recentlyUpdatedUsers: "PoužÃvatelia s najnovÅ¡ou aktivitou" +recentlyRegisteredUsers: "NajnovÅ¡Ã použÃvatelia" +recentlyDiscoveredUsers: "Naposledy objavenà použÃvatelia" +exploreUsersCount: "Existuje {count} použÃvateľov" +exploreFediverse: "ObjavovaÅ¥ Fediverzum" +popularTags: "Populárne znaÄky" +userList: "Zoznamy" +about: "Informácie" +aboutMisskey: "O Misskey" +administrator: "Administrátor" +token: "Token" +twoStepAuthentication: "Dvojfaktorová autentifikácia" +moderator: "Moderátor" +nUsersMentioned: "{n} použÃvateľov spomenulo" +securityKey: "BezpeÄnostný kľúÄ" +securityKeyName: "Názov kľúÄa" +registerSecurityKey: "RegistrovaÅ¥ bezpeÄnostný kľúÄ" +lastUsed: "Naposledy použité" +unregister: "OdregistrovaÅ¥" +passwordLessLogin: "NastaviÅ¥ bezheslové prihlásenie" +resetPassword: "ResetovaÅ¥ heslo" +newPasswordIs: "Nové heslo je \"{password}\"" +reduceUiAnimation: "Menej UI animáciÃ" +share: "ZdieľaÅ¥" +notFound: "Nenájdené" +notFoundDescription: "NenaÅ¡la sa žiadna stránka na zadanej URL." +uploadFolder: "Predvolený prieÄinok pre nahrávanie" +cacheClear: "VyÄistiÅ¥ cache" +markAsReadAllNotifications: "OznaÄiÅ¥ vÅ¡etky oznámenia ako preÄÃtané" +markAsReadAllUnreadNotes: "OznaÄiÅ¥ vÅ¡etky poznámky ako preÄÃtané" +markAsReadAllTalkMessages: "OznaÄiÅ¥ vÅ¡etky správy ako preÄÃtané" +help: "Pomoc" +inputMessageHere: "Sem napÃÅ¡te správu" +close: "ZavrieÅ¥" +group: "Skupina" +groups: "Skupiny" +createGroup: "VytvoriÅ¥ skupinu" +ownedGroups: "Vlastnené skupiny" +joinedGroups: "ÄŒlenstvo v skupinách" +invites: "PozvaÅ¥" +groupName: "Názov skupiny" +members: "ÄŒlenovia" +transfer: "Presun" +messagingWithUser: "Súkromný chat" +messagingWithGroup: "Skupinový chat" +title: "Nadpis" +text: "Text" +enable: "PovoliÅ¥" +next: "ÄŽalÅ¡Ã" +retype: "Zadajte znovu" +noteOf: "Poznámky použÃvateľa {user}" +inviteToGroup: "PozvaÅ¥ do skupiny" +maxNoteTextLength: "Maximálny poÄet znakov poznámky" +quoteAttached: "Citované" +quoteQuestion: "PripojiÅ¥ ako citát?" +noMessagesYet: "Zatiaľ žiadne správy" +newMessageExists: "Máte novú správu" +onlyOneFileCanBeAttached: "Ku správe môžete priložiÅ¥ len jeden súbor" +signinRequired: "Prihláste sa, prosÃm!" +invitations: "PozvaÅ¥" +invitationCode: "Kód pozvánky" +checking: "Overujem..." +available: "Dostupné" +unavailable: "Nedostupné" +usernameInvalidFormat: "Povolené sú pÃsmená, ÄÃsla a _." +tooShort: "PrÃliÅ¡ krátke" +tooLong: "PrÃliÅ¡ dlhé" +weakPassword: "Slabé heslo" +normalPassword: "Dobré heslo" +strongPassword: "Silné heslo" +passwordMatched: "Heslá sú rovnaké" +passwordNotMatched: "Heslá nie sú rovnaké" +signinWith: "PrihlásiÅ¥ sa použitÃm {x}" +signinFailed: "Nedá sa prihlásiÅ¥. Skontrolujte prosÃm meno použÃvateľa a heslo." +tapSecurityKey: "Ťuknite na bezpeÄnostný kľúÄ" +or: "Alebo" +language: "Jazyk" +uiLanguage: "Jazyk použÃvateľského prostredia" +groupInvited: "PozvaÅ¥ do skupiny" +aboutX: "O {x}" +useOsNativeEmojis: "PoužÃvaÅ¥ natÃvne emoji z OS" +disableDrawer: "NepoužÃvaÅ¥ Å¡uflÃkové menu" +youHaveNoGroups: "Nemáte žiadne skupiny" +joinOrCreateGroup: "Požiadajte o pozvanie do existujúcej skupiny alebo vytvorte novú." +noHistory: "Žiadna história" +signinHistory: "História prihlásenÃ" +disableAnimatedMfm: "Vypnúť MFM s animáciou" +doing: "Pracujem..." +category: "Kategórie" +tags: "ZnaÄky" +docSource: "Zdroj tohoto dokumentu" +createAccount: "VytvoriÅ¥ úÄet" +existingAccount: "Existujúci úÄet" +regenerate: "PregenerovaÅ¥" +fontSize: "VeľkosÅ¥ pÃsma" +noFollowRequests: "Nemáte nijaké Äakajúce žiadosti o sledovanie" +openImageInNewTab: "OtvoriÅ¥ obrázok v novom tabe" +dashboard: "Prehľad" +local: "Lokálne" +remote: "Vzdialené" +total: "Celkom" +weekOverWeekChanges: "Medzitýždňové zmeny" +dayOverDayChanges: "Medzidenné zmeny" +appearance: "Vzhľad" +clientSettings: "Nastavenia klienta" +accountSettings: "Nastavenia úÄtu" +promotion: "Propagácia" +promote: "PropagovaÅ¥" +numberOfDays: "PoÄet dnÃ" +hideThisNote: "SkryÅ¥ túto poznámku" +showFeaturedNotesInTimeline: "ZobraziÅ¥ významné poznámky v Äasovej osi" +objectStorage: "Objektové úložisko" +useObjectStorage: "PoužiÅ¥ objektové úložisko" +objectStorageBaseUrl: "Základná URL" +objectStorageBaseUrlDesc: "URL použitá ako referencia. Zadajte URL svojho CDN alebo Proxy ak niektoré použÃvate. S3: 'https://<bucket>.s3.amazonaws.com', GCS: 'https://storage.googleapis.com/<bucket>' atÄ." +objectStorageBucket: "Bucket" +objectStorageBucketDesc: "ProsÃm zadajte názov bucketu od svojho poskytovateľa." +objectStoragePrefix: "Prefix" +objectStoragePrefixDesc: "Súbory budú ukladané do prieÄinkov pod týmto prefixom." +objectStorageEndpoint: "Endpoint" +objectStorageEndpointDesc: "Nechajte prázdne ak použÃvate AWS S3, inak zadajte endpoint ako \"<host>\" alebo \"<host>:<port>\". Záležà to od služby, ktorú použÃvate." +objectStorageRegion: "Región" +objectStorageRegionDesc: "Zadajte región ako 'xx-east-1'. Ak vaÅ¡a služba nerozliÅ¡uje regióny, nechajte prázdne alebo zadajte 'us-east-1'." +objectStorageUseSSL: "PoužiÅ¥ SSL" +objectStorageUseSSLDesc: "Vypnite to ak nechcete použiÅ¥ HTTPS na API spojenia." +objectStorageUseProxy: "PripájaÅ¥ cez Proxy" +objectStorageUseProxyDesc: "Vypnite ak nechcete, aby spojenia na API iÅ¡li cez Proxy" +objectStorageSetPublicRead: "Pri nahratà nastaviÅ¥ \"public-read\"" +serverLogs: "Logy servera" +deleteAll: "OdstrániÅ¥ vÅ¡etko" +showFixedPostForm: "ZobraziÅ¥ formulár na nové prÃspevky nad Äasovou osou" +newNoteRecived: "Sú nové poznámky" +sounds: "Zvuky" +listen: "PoÄúvaÅ¥" +none: "Žiadne" +showInPage: "ZobraziÅ¥ v stránke" +popout: "Pop-out" +volume: "HlasitosÅ¥" +masterVolume: "Celková hlasitosÅ¥" +details: "Detaily" +chooseEmoji: "VybraÅ¥ emoji" +unableToProcess: "Operáciu sa nepodarilo dokonÄiÅ¥." +recentUsed: "Neposledy použité" +install: "NainÅ¡talovaÅ¥" +uninstall: "OdinÅ¡talovaÅ¥" +installedApps: "Autorizované aplikácie" +nothing: "NiÄ tu nie je" +installedDate: "Dátum autorizácie" +lastUsedDate: "Naposledy použité" +state: "Status" +sort: "ZoradiÅ¥" +ascendingOrder: "Vzostupne" +descendingOrder: "Zostupne" +scratchpad: "ZápisnÃk" +scratchpadDescription: "ZápisnÃk poskytuje prostredia pre experimenty s AiScriptom. Môžete pÃsaÅ¥, spúšťaÅ¥ a skúšaÅ¥ vysledky pri interakcii s Misskey." +output: "Výstup" +script: "Skript" +disablePagesScript: "Vypnúť AiScript na stránkach" +updateRemoteUser: "AktualizovaÅ¥ informácie o vzdialenom úÄte" +deleteAllFiles: "OdstrániÅ¥ vÅ¡etky súbory" +deleteAllFilesConfirm: "Naozaj chcete odstrániÅ¥ vÅ¡etky súbory" +removeAllFollowing: "ZruÅ¡iÅ¥ sledovani vÅ¡etkých použÃvateľov" +removeAllFollowingDescription: "Týmto zruÅ¡Ãte sledovanie vÅ¡etkých použÃvateľov z {host}. Spustite to prosÃm, keÄ server naprÃklad už neexistuje." +userSuspended: "Tento použÃvateľ je zmrazený." +userSilenced: "Tento použÃvateľ je umlÄaný." +yourAccountSuspendedTitle: "Tento úÄet je zmrazený" +yourAccountSuspendedDescription: "Tento úÄet bol zmrazený, lebo poruÅ¡oval zmluvné podmienky. Kontaktujte administrátora ak chcete viac podrobnostÃ. ProsÃm nevytvárajte nový úÄet." +menu: "Menu" +divider: "OddeľovaÄ" +addItem: "PridaÅ¥ položku" +relays: "Prenos" +addRelay: "PridaÅ¥ prenos" +inboxUrl: "Inbox URL" +addedRelays: "Pridané prenosy" +serviceworkerInfo: "Musà byÅ¥ zapnuté pre push notifikácie." +deletedNote: "Odstránené prÃspevky" +invisibleNote: "Skryté prÃspevky" +enableInfiniteScroll: "Zapnúť nekoneÄné skrolovanie" +visibility: "ViditeľnosÅ¥" +poll: "Hlasovanie" +useCw: "SkryÅ¥ obsah" +enablePlayer: "OtvoriÅ¥ video prehrávaÄ" +disablePlayer: "ZavrieÅ¥ video prehrávaÄ" +expandTweet: "RozÅ¡ÃriÅ¥ tweet" +themeEditor: "Editor tém" +description: "Popis" +describeFile: "PridaÅ¥ nadpis" +enterFileDescription: "Zadajte nadpis" +author: "Autor" +leaveConfirm: "Máte neuložené zmeny. Chcete ich zahodiÅ¥?" +manage: "Administrácia" +plugins: "Pluginy" +deck: "Deck" +useBlurEffectForModal: "PoužiÅ¥ efekt rozmazania na okná" +useFullReactionPicker: "PoužiÅ¥ plnú veľkosÅ¥ výberu reakciÃ" +width: "Å Ãrka" +height: "Výška" +large: "Veľké" +medium: "Stredné" +small: "Malé" +generateAccessToken: "VygenerovaÅ¥ prÃstupový token" +permission: "Oprávnenia" +enableAll: "PovoliÅ¥ vÅ¡etko" +disableAll: "Vypnúť vÅ¡etko" +tokenRequested: "PovoliÅ¥ prÃstup k úÄtu" +pluginTokenRequestedDescription: "Tento plugin bude môcÅ¥ použÃvaÅ¥ oprávnenia nastavené tu." +notificationType: "Typ oznámenia" +edit: "UpraviÅ¥" +useStarForReactionFallback: "PoužiÅ¥ ★ keÄ emoji reakcie nie je známe" +emailServer: "Email server" +enableEmail: "Zapnúť email" +emailConfigInfo: "PoužÃva sa na overenie emaily pri registrácii alebo pri zabudnutà hesla" +email: "Email" +emailAddress: "Emailová adresa" +smtpConfig: "Nastavenia SMTP servera" +smtpHost: "Host" +smtpPort: "Port" +smtpUser: "Meno použÃvateľa" +smtpPass: "Heslo" +emptyToDisableSmtpAuth: "VynechanÃm mena hesla vypnete SMTP verifikáciu" +smtpSecure: "PoužiÅ¥ implicitné SSL/TLS pre SMTP spojenia" +smtpSecureInfo: "Toto vypnite keÄ použÃvate STARTTLS" +testEmail: "DoruÄenie testovacieho emailu" +wordMute: "StÃÅ¡enie slova" +instanceMute: "StÃÅ¡ené servery" +userSaysSomething: "{name} nieÄo povedal/a" +makeActive: "AktivovaÅ¥" +display: "ZobraziÅ¥" +copy: "KopÃrovaÅ¥" +metrics: "Metriky" +overview: "Prehľad" +logs: "Logy" +delayed: "Oneskorené" +database: "Databáza" +channel: "Kanály" +create: "VytvoriÅ¥" +notificationSetting: "Nastavenia oznámenÃ" +notificationSettingDesc: "Vyberte typ oznámenà na zobrazenie" +useGlobalSetting: "PoužiÅ¥ globálne nastavenie" +useGlobalSettingDesc: "Ak je zapnuté, použijú sa oznámenia vášho úÄtu. Ak je vypnuté, použijú sa jednotlivé nastavenia." +other: "OstatnÃ" +regenerateLoginToken: "PregenerovaÅ¥ prihlasovacà token" +regenerateLoginTokenDescription: "Pregeneruje token interne použÃvaný poÄas prihlásenia. Normálne toto netreba robiÅ¥. Ak sa pregeneruje, vÅ¡etky zariadenia sa odhlásia." +setMultipleBySeparatingWithSpace: "Viaceré položky oddeľte medzerami." +fileIdOrUrl: "ID alebo URL súboru" +behavior: "Správanie" +sample: "Ukážka" +abuseReports: "Nahlásenia" +reportAbuse: "NahlásiÅ¥" +reportAbuseOf: "NahlásiÅ¥ {name}" +fillAbuseReportDescription: "ProsÃm vyplňte podrobnosti nahlásenia. Ak sa týka konkrétnej poznámky, prosÃm napÃÅ¡te jej URL." +abuseReported: "VaÅ¡e nahlásenie je odoslané. Veľmi pekne Äakujeme." +reporter: "Nahlásil" +reporteeOrigin: "Pôvod nahláseného" +reporterOrigin: "Pôvod nahlasovaÄa" +forwardReport: "PreposlaÅ¥ nahlásenie na server" +forwardReportIsAnonymous: "Namiesto vášho úÄtu bude zobrazený anonymný systémový úÄet na vzdialenom serveri ako autor nahlásenia." +send: "PoslaÅ¥" +abuseMarkAsResolved: "OznaÄiÅ¥ nahlásenia ako vyrieÅ¡ené" +openInNewTab: "OtvoriÅ¥ v novom tabe" +openInSideView: "OtvoriÅ¥ v boÄnom paneli" +defaultNavigationBehaviour: "Predvolené správanie navigácie" +editTheseSettingsMayBreakAccount: "Úpravou týchto nastavenà si môžete pokaziÅ¥ úÄet." +instanceTicker: "Informácie servera o poznámkach" +waitingFor: "ÄŒaká sa na {x}" +random: "Náhodné" +system: "Systém" +switchUi: "Prepnúť UI" +desktop: "Desktop" +clip: "Klip" +createNew: "VytvoriÅ¥ nový" +optional: "Voliteľné" +createNewClip: "VytvoriÅ¥ nový klip" +public: "Verejné" +i18nInfo: "Misskey je prekladaný do rôznych jazykov dobrovoľnÃkmi. PomôcÅ¥ môžete na {link}." +manageAccessTokens: "SpravovaÅ¥ prÃstupové tokeny" +accountInfo: "Informácie o úÄte" +notesCount: "PoÄet poznámok" +repliesCount: "PoÄet odoslaných odpovedÃ" +renotesCount: "PoÄet preposlaných poznámok" +repliedCount: "PoÄet odpovedà prijatých" +renotedCount: "PoÄet preposlanà prijatých" +followingCount: "PoÄet sledovaných úÄtov" +followersCount: "PoÄet sledujúcich" +sentReactionsCount: "PoÄet poslaných reakciÃ" +receivedReactionsCount: "PoÄet prijatých reakciÃ" +pollVotesCount: "PoÄet odoslaných hlasov" +pollVotedCount: "PoÄet prijatých hlasov" +yes: "Ãno" +no: "Nie" +driveFilesCount: "PoÄet súborov na disku" +driveUsage: "Využité miesto na disku" +noCrawle: "OdmietaÅ¥ indexovanie crawlerov" +noCrawleDescription: "PožiadaÅ¥ vyhľadávaÄe, aby neindexovali váš profil, poznámky, stránky, atÄ." +lockedAccountInfo: "Pokým nenastavÃte viditeľnosÅ¥ poznámok na \"Len pre sledujúcich\", vaÅ¡e prÃspevky bude vidieÅ¥ hocikto, aj keÄ vyžadujete manuálne potvrdenie sledovania." +alwaysMarkSensitive: "Predvolene oznaÄovaÅ¥ ako NSFW" +loadRawImages: "NaÄÃtaÅ¥ originálne obrázky namiesto miniatúr" +disableShowingAnimatedImages: "NeprehrávaÅ¥ animované obrázky" +verificationEmailSent: "Odoslali sme overovacà email. Overenie dokonÄÃte kliknutÃm na odkaz v emaili." +notSet: "Nenastavené" +emailVerified: "Email overený" +noteFavoritesCount: "PoÄet obľúbených poznámok" +pageLikesCount: "PoÄet obľúbených stránok" +pageLikedCount: "PoÄet prijatých \"páÄi sa mi\"" +contact: "Kontakt" +useSystemFont: "PoužiÅ¥ predvolené systémové pÃsmo" +clips: "Klip" +experimentalFeatures: "Experimentálne funkcie" +developer: "Vývojár" +makeExplorable: "SpraviÅ¥ úÄet viditeľný v \"ObjavovaÅ¥\"" +makeExplorableDescription: "Ak toto vypnete, váš úÄet sa nezobrazà v sekcii \"Objavovat\"." +showGapBetweenNotesInTimeline: "ZobraziÅ¥ medzeru medzi prÃspevkami Äasovej osi." +duplicate: "DuplikovaÅ¥" +left: "Naľavo" +center: "Stred" +wide: "Å iroko" +narrow: "Úzko" +reloadToApplySetting: "Toto nastavenia sa prejavà až po obnovenà stránky. ObnoviÅ¥ teraz?" +needReloadToApply: "Toto nastavenie sa prejavà až po obnovenà stránky." +showTitlebar: "ZobraziÅ¥ riadok s nadpisom" +clearCache: "VyprázdniÅ¥ cache" +onlineUsersCount: "{n} použÃvateľov je online" +nUsers: "{n} použÃvateľov" +nNotes: "{n} poznámok" +sendErrorReports: "PoslaÅ¥ nahlásenie chyby" +sendErrorReportsDescription: "KeÄ je zapnuté, v prÃpade problému sa odoÅ¡lú podrobné informácie o chybe do Misskey. Pomôžete tak zvýšiÅ¥ kvalitu Misskey.\nTieto informácie zahŕňajú verziu vášho OS, použitý prehliadaÄ, históriu aktivÃt, atÄ." +myTheme: "Moja téma" +backgroundColor: "Pozadie" +accentColor: "Akcent" +textColor: "Text" +saveAs: "UložiÅ¥ ako..." +advanced: "RozÅ¡Ãrené" +value: "Hodnoty" +createdAt: "Vytvorené" +updatedAt: "Upravené" +saveConfirm: "UložiÅ¥ zmeny?" +deleteConfirm: "Naozaj odstrániÅ¥?" +invalidValue: "Nesprávna hodnota." +registry: "Register" +closeAccount: "ZavrieÅ¥ úÄet" +currentVersion: "Aktuálna verzia" +latestVersion: "NajnovÅ¡ia verzia" +youAreRunningUpToDateClient: "PoužÃvate najnovÅ¡iu verziu vášho klienta." +newVersionOfClientAvailable: "Je dostupná novÅ¡ia verzia vášho klienta." +usageAmount: "Využitie" +capacity: "Kapacita" +inUse: "Použité" +editCode: "UpraviÅ¥ kód" +apply: "PoužiÅ¥" +receiveAnnouncementFromInstance: "PrijaÅ¥ notifikácie z tohoto servera" +emailNotification: "Emailové upozornenia" +publish: "ZverejniÅ¥" +inChannelSearch: "HľadaÅ¥ v kanáli" +useReactionPickerForContextMenu: "OtvoriÅ¥ výber reakcià na pravý klik" +typingUsers: "{users} pÃÅ¡e/u" +jumpToSpecifiedDate: "SkoÄiÅ¥ na konkrétny dátum" +showingPastTimeline: "Práve vidÃte starú Äasovú os" +clear: "VrátiÅ¥" +markAllAsRead: "OznaÄiÅ¥ vÅ¡etko ako preÄÃtané" +goBack: "Späť" +unlikeConfirm: "Naozaj odstrániÅ¥ váš like?" +fullView: "Plný pohľad" +quitFullView: "ZavrieÅ¥ plný pohľad" +addDescription: "PridaÅ¥ popis" +userPagePinTip: "Tu môžete zobraziÅ¥ poznámky zvolenÃm \"Pripnúť na profil\" z menu jednotlivých poznámok." +notSpecifiedMentionWarning: "Táto poznámka obsahuje spomenutých použÃvateľov, ktorà nie sú medzi adresátmi." +info: "Informácie" +userInfo: "Informácie o použÃvateľovi" +unknown: "Neznáme" +onlineStatus: "Online status" +hideOnlineStatus: "SkryÅ¥ online status" +hideOnlineStatusDescription: "Skrytie vášho online statusu znÞi pohodlnosÅ¥ niektorých funkcià ako naprÃklad vyhľadávanie." +online: "Online" +active: "AktÃvny" +offline: "Offline" +notRecommended: "NeodporúÄané" +botProtection: "Bot ochrana" +instanceBlocking: "Blokované servery" +selectAccount: "Vyberte úÄet" +switchAccount: "Prepnút úÄet" +enabled: "Zapnuté" +disabled: "Vypnuté" +quickAction: "Rýchle akcie" +user: "PoužÃvatelia" +administration: "Spravovanie" +accounts: "ÚÄty" +switch: "Prepnúť" +noMaintainerInformationWarning: "Informácie správcu nie sú nastavené." +noBotProtectionWarning: "Ochrana proti botom nie je nastavená." +configure: "KonfigurovaÅ¥" +postToGallery: "VytvoriÅ¥ nový prÃspevok v galérii" +gallery: "Galéria" +recentPosts: "NajnovÅ¡ie prÃspevky" +popularPosts: "Populárne prÃspevky" +shareWithNote: "ZdieľaÅ¥ s poznámkou" +ads: "Reklamy" +expiration: "UkonÄiÅ¥ hlasovanie" +memo: "Memo" +priority: "Priorita" +high: "Vysoká" +middle: "Stredné" +low: "Málo" +emailNotConfiguredWarning: "Nie je nastavená emailová adresa." +ratio: "Pomer" +previewNoteText: "ZobraziÅ¥ náhľad" +customCss: "Vlastné CSS" +customCssWarn: "Toto nastavenie by sa malo použÃvaÅ¥ iba ak viete Äo robÃte. Zadanie nesprávnych hodnôt môže spôsobiÅ¥ nenormálne správanie klienta." +global: "Globálne" +squareAvatars: "ZobrazovaÅ¥ Å¡tvorcové avatary" +sent: "PoslaÅ¥" +received: "Prijaté" +searchResult: "Výsledky hľadania" +hashtags: "Hashtagy" +troubleshooting: "RieÅ¡enie problémov" +useBlurEffect: "PoužÃvaÅ¥ efekty rozmazania v UI" +learnMore: "ZistiÅ¥ viac" +misskeyUpdated: "Misskey sa aktualizoval!" +whatIsNew: "ÄŒo je nové?" +translate: "PreložiÅ¥" +translatedFrom: "Preložené z {x}" +accountDeletionInProgress: "Odstraňovanie úÄtu prebieha" +usernameInfo: "Meno, ktoré odliÅ¡uje váš úÄet od ostatných na tomto serveri. Môžete použiÅ¥ abecedu (a~z, A~Z), ÄÃsla (0~9) alebo podtržnÃk (_). PoužÃvateľské mená sa nedajú neskôr zmeniÅ¥." +aiChanMode: "Ai režim" +keepCw: "NechaÅ¥ varovania obsahu" +pubSub: "Pub/Sub úÄty" +lastCommunication: "Posledná komunikácia" +resolved: "VyrieÅ¡ené" +unresolved: "NevyrieÅ¡ené" +breakFollow: "NesledovaÅ¥" +itsOn: "Zapnuté" +itsOff: "Vypnuté" +emailRequiredForSignup: "Registrácia vyžaduje emailovú adresu" +unread: "NepreÄÃtané" +filter: "Filter" +controlPanel: "Ovládacà panel" +manageAccounts: "Správa úÄtov" +makeReactionsPublic: "Reakcie sú verejné" +makeReactionsPublicDescription: "Toto spravà vÅ¡etky vaÅ¡e minulé reakcie viditeľné verejnosti." +classic: "Klasika" +muteThread: "ZtÃÅ¡iÅ¥ vlákno" +unmuteThread: "ZruÅ¡iÅ¥ stÃÅ¡enie vlákna" +ffVisibility: "ViditeľnosÅ¥ sledujúcich/sledovaných" +ffVisibilityDescription: "Umožňuje nastaviÅ¥ kto vidà koho sledujete a kto vás sleduje." +continueThread: "ZobraziÅ¥ pokraÄovanie vlákna" +deleteAccountConfirm: "Toto nezvrátiteľne vymaže váš úÄet. PokraÄovaÅ¥?" +incorrectPassword: "Nesprávne heslo." +voteConfirm: "Potvrdzujete svoj hlas za \"{choice}\"?" +hide: "SkryÅ¥" +leaveGroup: "OpustiÅ¥ skupiny" +leaveGroupConfirm: "Naozaj chcete opustiÅ¥ \"{name}\"?" +useDrawerReactionPickerForMobile: "ZobraziÅ¥ výber reakcià ako Å¡uflÃk na mobile" +welcomeBackWithName: "Vitajte späť, {name}" +clickToFinishEmailVerification: "KliknutÃm na [{ok}] dokonÄÃte overeniu emailu." +overridedDeviceKind: "Typ zariadenia" +smartphone: "Smartfón" +tablet: "Tablet" +auto: "Automaticky" +_emailUnavailable: + used: "Táto emailová adresa sa už použÃva" + format: "Formát emailovej adresy je nesprávny" + disposable: "Jednorázové emailové adresy sa nemôžu použÃvaÅ¥." + mx: "Tento emailový server nefunguje." + smtp: "Tento emailový server neodpovedá." +_ffVisibility: + public: "ZverejniÅ¥" + followers: "Len viditeľnà sledujúci" + private: "Súkromné" +_signup: + almostThere: "Skoro na konci" + emailAddressInfo: "ProsÃm zadajte svoju emailovú adresu!" + emailSent: "Na vaÅ¡u emailovú adresu ({email}) sme odoslali email. Vytvorenie úÄtu dokonÄÃte kliknutÃm na odkaz v emaili." +_accountDelete: + accountDelete: "OdstrániÅ¥ úÄet" + mayTakeTime: "KeÄže odstránenie úÄtu je nároÄný proces, môže to nejaký Äas trvaÅ¥. Záležà koľko obsahu ste vytvorili a koľko súborov ste nahrali." + sendEmail: "Po odstránenà úÄtu vám poÅ¡leme email na emailovú adresu zadanú pri registrácii tohoto úÄtu." + requestAccountDelete: "PožiadaÅ¥ o zmazanie úÄtu" + started: "Odstraňovanie zaÄalo." + inProgress: "Odstraňovanie prebieha" +_ad: + back: "Späť" + reduceFrequencyOfThisAd: "Túto reklamu zobrazovaÅ¥ menej" +_forgotPassword: + enterEmail: "Zadajte emailovú adresu, ktorú ste použili pri registrácii. PoÅ¡leme vám na ňu odkaz, cez ktorý si môžete obnoviÅ¥ heslo." + ifNoEmail: "Ak ste pri registrácii nepoužili email, prosÃm kontaktujte administrátora." + contactAdmin: "Tento server nepodporuje použÃvanie emailových adries, prosÃm kontaktuje administrátor, ktorý vám resetuje heslo." +_gallery: + my: "Moja galéria" + liked: "Obľúbené prÃspevky" + like: "PáÄi sa mi" + unlike: "NepáÄi sa mi" +_email: + _follow: + title: "Máte nového sledujúceho" + _receiveFollowRequest: + title: "Dostali ste žiadosÅ¥ o sledovanie" +_plugin: + install: "InÅ¡talova pluginy" + installWarn: "ProsÃm neinÅ¡talujte nedôveryhodné pluginy." + manage: "Spravovanie pluginov" +_registry: + scope: "OblasÅ¥" + key: "KľúÄ" + keys: "KľúÄe" + domain: "Doména" + createKey: "VytvoriÅ¥ kľúÄ" +_aboutMisskey: + about: "Misskey je open-source softvér, ktorý vyvÃja syuilo od 2014." + contributors: "Hlavnà prispievatelia" + allContributors: "VÅ¡etci prispievatelia" + source: "Zdrojový kód" + translation: "PreložiÅ¥ Misskey" + donate: "PodporiÅ¥ Misskey" + morePatrons: "Takisto oceňujeme podporu mnoých ÄalÅ¡Ãch, ktorà tu nie sú uvedenÃ. ÄŽakujeme! 🥰" + patrons: "Prispievatelia" +_nsfw: + respect: "SkryÅ¥ NSFW médiá" + ignore: "NeskrývaÅ¥ NSFW médiá" + force: "SkryÅ¥ vÅ¡etky médiá" +_mfm: + cheatSheet: "MFM Cheatsheet" + intro: "MFM je Misskey exkluzÃvny znaÄkovacà jazyk, ktorý sa dá použÃvaÅ¥ na viacerých miestach. Tu môžete vidieÅ¥ zoznam vÅ¡etkej dostupnej MFM syntaxe." + dummy: "Misskey rozÅ¡iruje svet Fediverza" + mention: "Zmienka" + mentionDescription: "PoužÃvateľa spomeniete použÃtÃm zavináÄa a mena použÃvateľa" + hashtag: "Hashtag" + hashtagDescription: "Môžete zadaÅ¥ hashtag použitÃm mriežky a textu" + url: "URL" + urlDescription: "URL sa dajú zobraziÅ¥." + link: "Odkaz" + linkDescription: "Jednotlivé Äasti texty sa dajú zobraziÅ¥ ako URL." + bold: "TuÄné" + boldDescription: "Zvýraznà pÃsmená tým, že budú tuÄnejÅ¡ie." + small: "Malé" + smallDescription: "Zobrazà obsah malý a tenký." + center: "VystrediÅ¥ prvky" + centerDescription: "Zobrazà obsah v strede" + inlineCode: "Kód (inline)" + inlineCodeDescription: "Zobrazà kód so zvýraznenÃm syntaxe." + blockCode: "Kód (blok)" + blockCodeDescription: "Zobrazà viacriadkový kód so zvýraznenÃm syntaxe v bloku." + inlineMath: "Vzorec (inline)" + inlineMathDescription: "Zobrazà matematický vzorec (KaTeX) v riadku." + blockMath: "Vzorec (blok)" + blockMathDescription: "Zobrazà viacriadkový matematický vzorec (KaTeX) v bloku" + quote: "CitovaÅ¥" + quoteDescription: "Zobrazà obsah ako citát." + emoji: "Vlastné emoji" + emojiDescription: "PridanÃm dvojbodiek pred a za názov vlastnej emoji, sa dá zobraziÅ¥ vlastná emoji." + search: "HľadaÅ¥" + searchDescription: "Zobrazà vyhľadávacie pole so zadaným textom." + flip: "PreklopiÅ¥" + flipDescription: "Preklopà obsah horizontálne alebo vertikálne" + jelly: "Animácia (želé)" + jellyDescription: "Obsah sa bude hýbaÅ¥ ako želé." + tada: "Animácia (tadá)" + tadaDescription: "Obsah sa bude hýbaÅ¥ ako Tada!" + jump: "Animácia (skok)" + jumpDescription: "Obsah skoÄÃ." + bounce: "Animácia (odraz)" + bounceDescription: "Obsah sa bude odrážaÅ¥." + shake: "Animácia (trasenie)" + shakeDescription: "Obsah sa bude triasÅ¥." + twitch: "Animácia (myknutie)" + twitchDescription: "Obsahu dá animáciu silného trasenia." + spin: "Animácia (rotácia)" + spinDescription: "Obsahu pridá otáÄajúcu animáciu." + x2: "Veľký" + x2Description: "Zobrazà obsah väÄÅ¡Ã." + x3: "Veľmi veľký" + x3Description: "Zobrazà obsah eÅ¡te väÄÅ¡Ã." + x4: "Neuveriteľne veľký" + x4Description: "Zobrazà obsah eÅ¡te viac veľký než veľmi veľký." + blur: "Rozmazanie" + blurDescription: "Týmto efektom môže byÅ¥ obsah rozmazaný. Zaostrà sa keÄ ned neho prÃde kurzor." + font: "PÃsmo" + fontDescription: "Nastavà pÃsmo, ktorým sa zobrazà text." + rainbow: "Dúha" + rainbowDescription: "Zobrazà obsah vo farbách dúhy." + sparkle: "Trblietky" + sparkleDescription: "Obsahu dodá trblietajúci efekt." + rotate: "OtáÄaÅ¥" + rotateDescription: "OtoÄà obsah o urÄitý uhol." +_instanceTicker: + none: "Nikdy nezobrazovaÅ¥" + remote: "ZobraziÅ¥ pre vzdialených použÃvateľov" + always: "ZobraziÅ¥ vždy" +_serverDisconnectedBehavior: + reload: "Automaticky obnoviÅ¥" + dialog: "ZobraziÅ¥ okno s varovanÃm" + quiet: "ZobraziÅ¥ neruÅ¡ivé varovanie" +_channel: + create: "VytvoriÅ¥ kanál" + edit: "UpraviÅ¥ kanál" + setBanner: "NastaviÅ¥ banner" + removeBanner: "OdstrániÅ¥ banner" + featured: "Trendy" + owned: "Vlastnené" + following: "Sledované" + usersCount: "{n} úÄastnÃkov" + notesCount: "{n} poznámok" +_menuDisplay: + sideFull: "Strana" + sideIcon: "Strana (Ikony)" + top: "Hore" + hide: "SkryÅ¥" +_wordMute: + muteWords: "UmlÄané slová" + muteWordsDescription: "Medzerami oddeľte pre podmienku AND a novými riadkami pre podmienku OR." + muteWordsDescription2: "Regulárne výrazy sa použijú keÄ použijete okolo lomÃtka." + softDescription: "Skryje poznámky z Äasovej osi, ktoré spĺňajú podmienky." + hardDescription: "Zabráni poznámky spĺňajúce množinu podmienok, aby boli pridané do Äasovej osi. NavyÅ¡e tieto poznámky nepribudnú v Äasovej osi ani keÄ sa podmienky zmenia." + soft: "Mäkké" + hard: "Tvrdé" + mutedNotes: "UmlÄané poznámky" +_instanceMute: + instanceMuteDescription: "Toto umlÄà vÅ¡etky poznámky/preposlania zo zoznamu serverov, vrátane tých, na ktoré použÃvatelia odpovedajú z umlÄaného servera." + instanceMuteDescription2: "Oddeľte novými riadkami" + title: "Skryje poznámky z uvedených serverov." + heading: "Zoznam umlÄaných inÅ¡tanciÃ" +_theme: + explore: "ObjavovaÅ¥ témy" + install: "NainÅ¡talovaÅ¥ tému" + manage: "SpravovaÅ¥ témy" + code: "Kód témy" + description: "Popis" + installed: "{name} je nainÅ¡talovaná" + installedThemes: "NainÅ¡talované témy" + builtinThemes: "Vstavané témy" + alreadyInstalled: "Táto téma je už nainÅ¡talovaná" + invalid: "Formát tejto témy je nesprávny" + make: "VytvoriÅ¥ tému" + base: "Základ" + addConstant: "PridaÅ¥ konÅ¡tantu" + constant: "KonÅ¡tanta" + defaultValue: "Predvolená hodnota" + color: "Farba" + refProp: "Odkaz na vlastnosÅ¥" + refConst: "Odkaz na konÅ¡tantu" + key: "KľúÄ" + func: "Funkcie" + funcKind: "Typ funkcie" + argument: "Argument" + basedProp: "Odkazovaná vlastnosÅ¥" + alpha: "PriehľadnosÅ¥" + darken: "StmaviÅ¥" + lighten: "ZosvetliÅ¥" + inputConstantName: "Zadajte názov tejto konÅ¡tanty" + importInfo: "Ak sem zadáte kód témy, môžete ju importovaÅ¥ do editora tém." + deleteConstantConfirm: "Naozaj chcete odstrániÅ¥ konÅ¡tantu {const}?" + keys: + accent: "Akcent" + bg: "Pozadie" + fg: "Text" + focus: "Fokus" + indicator: "Indikátor" + panel: "Panel" + shadow: "Tieň" + header: "HlaviÄka" + navBg: "Pozadie boÄného panela" + navFg: "Text boÄného panela" + navHoverFg: "Text boÄného panela (pod kurzorom)" + navActive: "Text boÄného panela (aktÃvny)" + navIndicator: "Indikátor boÄného panela" + link: "Odkaz" + hashtag: "Hashtag" + mention: "Zmienka" + mentionMe: "Zmienky (mňa)" + renote: "PreposlaÅ¥" + modalBg: "Pozadie modálu" + divider: "OddeľovaÄ" + scrollbarHandle: "RúÄka scrollbaru" + scrollbarHandleHover: "RúÄka scrollbaru (pod kurzorom)" + dateLabelFg: "Text dátového popisku" + infoBg: "Pozadie informáciÃ" + infoFg: "InformaÄný text" + infoWarnBg: "Pozadie varovania" + infoWarnFg: "Text varovania" + cwBg: "CW pozadie tlaÄidla" + cwFg: "CW text tlaÄidla" + cwHoverBg: "CW pozadie tlaÄidla (pod kurzorom)" + toastBg: "Pozadie upozornenia" + toastFg: "Text upozornenia" + buttonBg: "Pozadie tlaÄidla" + buttonHoverBg: "Pozadie tlaÄidla (pod kurzorom)" + inputBorder: "Okraj vstupného poľa" + listItemHoverBg: "Pozadie položky zoznamu (pod kurzorom)" + driveFolderBg: "Pozadie prieÄinu disku" + wallpaperOverlay: "Vrstvenie pozadia" + badge: "Odznak" + messageBg: "Pozadie chatu" + accentDarken: "Akcent (stmavené)" + accentLighten: "Akcent (zosvetlené)" + fgHighlighted: "Zvýraznený text" +_sfx: + note: "Poznámky" + noteMy: "Vlastná poznámka" + notification: "Oznámenia" + chat: "Chat" + chatBg: "Chat (pozadie)" + antenna: "Antény" + channel: "Upozornenia kanála" +_ago: + unknown: "Neznáme" + future: "BudúcnosÅ¥" + justNow: "Teraz" + secondsAgo: "pred {n} sekundami" + minutesAgo: "pred {n} minútami" + hoursAgo: "pred {n} hodinami" + daysAgo: "pred {n} dňami" + weeksAgo: "pred {n} týždňami" + monthsAgo: "pred {n} mesiacmi" + yearsAgo: "pred {n} rokmi" +_time: + second: "s" + minute: "min" + hour: "hod" + day: "dnÃ" +_tutorial: + title: "Ako použÃvaÅ¥ Misskey" + step1_1: "Vitajte!" + step1_2: "Táto stránka sa volá \"Äasová os\". Zobrazuje chronologicky zoradené \"poznámky\" od ľudÃ, ktorých sledujete." + step1_3: "VaÅ¡a Äasová os je teraz prázdna pretože ste nepridali žiadne poznámky ani nikoho zatiaľ nesledujete." + step2_1: "Podˇme dokonÄiÅ¥ nastavenia vášho profilu pred napÃsanÃm poznámky alebo sledovanÃm niekoho." + step2_2: "PoskytnutÃm informácià o vás uľahÄÃte ostatným, Äi chcú vidieÅ¥ alebo sledovaÅ¥ vaÅ¡e poznámky." + step3_1: "DokonÄili ste nastavovanie svojho profilu?" + step3_2: "PoÄme vyskúšaÅ¥ napÃsaÅ¥ poznámku. Môžete to spraviÅ¥ stlaÄenÃm ikony ceruzky na vrchu obrazovky." + step3_3: "Vyplňte polia a stlaÄte tlaÄÃtko vpravo hore." + step3_4: "Nemáte Äo povedaÅ¥? Skúste \"len si nastavujem môj msky\"!" + step4_1: "NapÃsali ste svoju prvú poznámku?" + step4_2: "Hurá! Teraz by vaÅ¡a prvá poznámka mala byÅ¥ na vaÅ¡ej Äasovej osi." + step5_1: "Teraz skúsme oživiÅ¥ Äasovú os sledovanÃm nejakých ľudÃ." + step5_2: "{featured} zobrazà populárne poznámku na tomto serveri. {explore} môžete objavovaÅ¥ populárnych použÃvateľov. Skúste tam nájsÅ¥ ľudÃ, ktorých by ste radi sledovali!" + step5_3: "Ak chcete sledovaÅ¥ ÄalÅ¡Ãch použÃvateľov, kliknite na ich ikonu a stlaÄte tlaÄidlo \"SledovaÅ¥\" na ich profile." + step5_4: "Ak má niektorý použÃvateľ ikonu zámku vedľa svojho mena, znamená to, že môže trvaÅ¥ urÄitý Äas, kým daný použÃvateľ schváli vaÅ¡u žiadosÅ¥ o sledovanie." + step6_1: "Teraz by ste mali vidieÅ¥ poznámky ÄalÅ¡Ãch použÃvateľov na svojej Äasovej osi." + step6_2: "Môžete daÅ¥ \"reakcie\" na poznámky ÄalÅ¡Ãch ľudà ako rýchlu odpoveÄ." + step6_3: "Reakciu pridáte kliknutÃm na \"+\" niekoho poznámke a vybratÃm emoji, ktorou chcete reagovaÅ¥." + step7_1: "Gralujeme! DokonÄili ste základného sprievodcu Misskey." + step7_2: "Ak sa chcete nauÄiÅ¥ viac o Misskey, skúste sekciu {help}." + step7_3: "A teraz, veľa Å¡Å¥astia, bavte sa s Misskey! 🚀" +_2fa: + alreadyRegistered: "Už ste zaregistrovali 2-faktorové autentifikaÄné zariadenie." + registerDevice: "RegistrovaÅ¥ nové zariadenie" + registerKey: "RegistrovaÅ¥ bezpeÄnostný kľúÄ" + step1: "Najprv si nainÅ¡talujte autentifikaÄnú aplikáciu (naprÃklad {a} alebo {b}) na svoje zariadenie." + step2: "Potom, naskenujte QR kód zobrazený na obrazovke." + step3: "Nastavenie dokonÄÃte zadanÃm tokenu z vaÅ¡ej aplikácie." + step4: "Od teraz, vÅ¡etky ÄalÅ¡ie prihlásenia budú vyžadovaÅ¥ prihlasovacà token." + securityKeyInfo: "Okrem odtlaÄku prsta alebo PIN autentifikácie si môžete nastaviÅ¥ autentifikáciu cez hardvérový bezpeÄnostný kÄ¾ÃºÄ podporujúci FIDO2 a tak eÅ¡te viac zabezpeÄiÅ¥ svoj úÄet." +_permissions: + "read:account": "VidieÅ¥ informácie o vaÅ¡om úÄte" + "write:account": "UpraviÅ¥ informácie o vaÅ¡om úÄte" + "read:blocks": "VidieÅ¥ zoznam blokovaných použÃvateľov" + "write:blocks": "UpraviÅ¥ zoznam blokovaných použÃvateľov" + "read:drive": "PrÃstup k súborom a prieÄinkom na disku" + "write:drive": "UpraviÅ¥ alebo odstrániÅ¥ súbory a prieÄinky na disku" + "read:favorites": "VidieÅ¥ váš zoznam obľúbených" + "write:favorites": "UpraviÅ¥ váš zoznam obľúbených" + "read:following": "VidieÅ¥ koho sledujete" + "write:following": "SledovaÅ¥ alebo nesledovaÅ¥ ÄalÅ¡ie úÄty" + "read:messaging": "VidieÅ¥ vaÅ¡e chaty" + "write:messaging": "PÃsaÅ¥ alebo odstraňovaÅ¥ správy v chate" + "read:mutes": "VidieÅ¥ váš zoznam stÃÅ¡ených použÃvateľov" + "write:mutes": "UpravovaÅ¥ zoznam stÃÅ¡ených použÃvateľov" + "write:notes": "PÃsaÅ¥ alebo odstrániÅ¥ poznámky" + "read:notifications": "VidieÅ¥ vaÅ¡e oznámenia" + "write:notifications": "PracovaÅ¥ s vaÅ¡imi notifikáciami" + "read:reactions": "VidieÅ¥ vaÅ¡e reakcie" + "write:reactions": "UpravovaÅ¥ vaÅ¡e reakcie" + "write:votes": "HlasovaÅ¥ v hlasovaniach" + "read:pages": "VidieÅ¥ vaÅ¡e stránky" + "write:pages": "UpraviÅ¥ alebo odstrániÅ¥ vaÅ¡e stránky" + "read:page-likes": "VidieÅ¥ vaÅ¡e páÄiky na stránkach" + "write:page-likes": "UpraviÅ¥ páÄiky na stránkach" + "read:user-groups": "VidieÅ¥ vaÅ¡e skupiny" + "write:user-groups": "UpraviÅ¥ alebo odstrániÅ¥ vaÅ¡e skupiny" + "read:channels": "ÄŒÃtaÅ¥ vaÅ¡e kanály" + "write:channels": "UpravovaÅ¥ vaÅ¡e kanály" + "read:gallery": "VidieÅ¥ vaÅ¡u galériu" + "write:gallery": "UpravovaÅ¥ vaÅ¡u galériu" + "read:gallery-likes": "VidieÅ¥ zoznam obľúbených prÃspevkov z galérie" + "write:gallery-likes": "UpraviÅ¥ zoznam obľúbených prÃspevov z galérie" +_auth: + shareAccess: "Prajete si povoliÅ¥ \"{name}\", aby mal prÃstup k tomuto úÄtu?" + shareAccessAsk: "Naozaj chcete povoliÅ¥ tejto aplikácii prÃstup k tomuto úÄtu?" + permissionAsk: "Táto aplikácia vyžaduje nasledujúce nastavenia" + pleaseGoBack: "ProsÃm prejdite späť na aplikáciu" + callback: "Vraciam sa späť na aplikáciu" + denied: "PrÃstup zamietnutý" +_antennaSources: + all: "VÅ¡etky poznámky" + homeTimeline: "Poznámky od sledovaného použÃvateľa" + users: "Poznámky od konkrétneho použÃvateľa" + userList: "Poznámky od použÃvateľov v zozname" + userGroup: "Poznámky od použÃvateľov z konkrétnej skupiny." +_weekday: + sunday: "Nedeľa" + monday: "Pondelok" + tuesday: "Utorok" + wednesday: "Streda" + thursday: "Å tvrtok" + friday: "Piatok" + saturday: "Sobota" +_widgets: + memo: "Prilepené poznámky" + notifications: "Oznámenia" + timeline: "ÄŒasová os" + calendar: "Kalendár" + trends: "Trendy" + clock: "Hodiny" + rss: "RSS ÄÃtaÄka" + activity: "Aktivita" + photos: "Fotky" + digitalClock: "Digitálne hodiny" + federation: "Federácia" + postForm: "NapÃsaÅ¥ poznámku" + slideshow: "Prezentácia" + button: "TlaÄidlo" + onlineUsers: "Online použÃvatelia" + jobQueue: "Fronta úloh" + serverMetric: "Metriky servera" + aiscript: "Konzola AiScript" + aichan: "Ai" +_cw: + hide: "SkryÅ¥" + show: "ZobraziÅ¥ viac" + chars: "{count} znakov" + files: "{count} súbor/ov" +_poll: + noOnlyOneChoice: "Treba aspoň dve voľby" + choiceN: "Voľba {n}" + noMore: "Nemôžete pridaÅ¥ viac volieb" + canMultipleVote: "PovoliÅ¥ hlasovaÅ¥ za viac volieb." + expiration: "UkonÄiÅ¥ hlasovanie" + infinite: "Nikdy" + at: "Konkrétny dátum..." + after: "UkonÄiÅ¥ po..." + deadlineDate: "Dátum ukonÄenia" + deadlineTime: "hod" + duration: "Trvanie" + votesCount: "{n} hlasov" + totalVotes: "{n} hlasov celkom" + vote: "HlasovaÅ¥" + showResult: "VidieÅ¥ výsledky hlasovania" + voted: "Zahlasované" + closed: "SkonÄilo" + remainingDays: "zostáva {d} dnà {h} hodÃn" + remainingHours: "zostáva {h} hodÃn {m} minút" + remainingMinutes: "zostáva {m} minút {s} sekúnd" + remainingSeconds: "zostáva {s} sekúnd" +_visibility: + public: "Verejné" + publicDescription: "VaÅ¡a poznámku bude viditeľná vÅ¡etkým použÃvateľom" + home: "Domov" + homeDescription: "PridaÅ¥ iba na domácu Äasovú os" + followers: "Sledujúci" + followersDescription: "Viditeľné iba tým, ktorà vás sledujú" + specified: "Priame" + specifiedDescription: "Viditeľné iba pre konkrétnych použÃvateľov" + localOnly: "Iba lokálne" + localOnlyDescription: "Vzdialený použÃvatelia nebudú vidieÅ¥" +_postForm: + replyPlaceholder: "OdpoveÄ na túto poznámku..." + quotePlaceholder: "Citovanie tejto poznámky..." + channelPlaceholder: "PoslaÅ¥ do kanála..." + _placeholders: + a: "ÄŒo máte v pláne?" + b: "ÄŒo sa deje?" + c: "O Äom rozmýšľaÅ¡?" + d: "ÄŒo chcete povedaÅ¥?" + e: "ZaÄnite pÃsaÅ¥..." + f: "ÄŒaká sa na pÃsanie..." +_profile: + name: "Názov" + username: "Meno použÃvateľa" + description: "Bio" + youCanIncludeHashtags: "Vo svojom bio môžete maÅ¥ aj hashtagy." + metadata: "DodatoÄné informácie" + metadataEdit: "UpraviÅ¥ dodatoÄné informácie" + metadataDescription: "Vo svojom profile môžete uviesÅ¥ až Å¡tyri dodatoÄné informaÄné polia." + metadataLabel: "Popisok" + metadataContent: "Obsah" + changeAvatar: "ZmeniÅ¥ avatara" + changeBanner: "ZmeniÅ¥ banner" +_exportOrImport: + allNotes: "VÅ¡etky poznámky" + followingList: "Sledujete" + muteList: "Vypnúť zvuk" + blockingList: "ZablokovaÅ¥" + userLists: "Zoznamy" + excludeMutingUsers: "VylúÄiÅ¥ stÃÅ¡ených použÃvateľov" + excludeInactiveUsers: "VylúÄiÅ¥ neaktÃvnych použÃvateľov" +_charts: + federation: "Federácia" + apRequest: "Žiadosti" + usersIncDec: "Rozdiel v poÄte použÃvateľov" + usersTotal: "Celkový poÄet použÃvateľov" + activeUsers: "AktÃvni použÃvatelia" + notesIncDec: "Rozdiel v poÄte poznámok" + localNotesIncDec: "Rozdiel v poÄte lokálnych poznámok" + remoteNotesIncDec: "Rozdiel v poÄte vzdialených poznámok" + notesTotal: "Celkový poÄet poznámok" + filesIncDec: "Rozdiel v poÄte súborov" + filesTotal: "Celkový poÄet súborov" + storageUsageIncDec: "Rozdiel využitého úložiska" + storageUsageTotal: "Celkové využité úložisko" +_instanceCharts: + requests: "Žiadosti" + users: "Rozdiel v poÄte použÃvateľov" + usersTotal: "Celkom spolu poÄet použÃvateľov" + notes: "Rozdiel v poÄte poznámok" + notesTotal: "Celkom spolu poÄet poznámok" + ff: "Rozdiel v poÄte sledovaných/sledujúcich" + ffTotal: "Celkom spolu poÄet sledovaných / sledujúcich" + cacheSize: "Rozdiel vo veľkosti cache" + cacheSizeTotal: "Celkom spolu veľkosÅ¥ cache" + files: "Rozdiel v poÄte súborov" + filesTotal: "Celkom spolu poÄet súborov" +_timelines: + home: "Domov" + local: "Lokálne" + social: "Sociálne" + global: "Globálne" +_pages: + newPage: "VytvoriÅ¥ novú stránku" + editPage: "UpraviÅ¥ túto stránku" + readPage: "Zobrazenie zdroja aktÃvne" + created: "Stránka úspeÅ¡ne vytvorená" + updated: "Stránka úspeÅ¡ne upravená" + deleted: "Stránka úspeÅ¡ne odstránená" + pageSetting: "Nastavenia stránky" + nameAlreadyExists: "Zadaná URL stránku už existuje" + invalidNameTitle: "Zadaná URL stránku je nesprávna" + invalidNameText: "Uistite sa, že nadpis stránky nie je prázdny" + editThisPage: "UpraviÅ¥ túto stránku" + viewSource: "UkázaÅ¥ zdroj" + viewPage: "UkázaÅ¥ vaÅ¡e stránky" + like: "PáÄi sa mi" + unlike: "NepáÄi sa mi" + my: "Moje stránky" + liked: "Obľúbené stránky" + featured: "VýznaÄné" + inspector: "InÅ¡pektor" + contents: "Obsah" + content: "Blok stránky" + variables: "Premenné" + title: "Nadpis" + url: "URL stránky" + summary: "Zhrnutie stránky" + alignCenter: "VystrediÅ¥ prvky" + hideTitleWhenPinned: "SkryÅ¥ nadpis stránky keÄ je pripnutá na profil" + font: "PÃsmo" + fontSerif: "Pätkové" + fontSansSerif: "Bezpätkové" + eyeCatchingImageSet: "NastaviÅ¥ miniatúru" + eyeCatchingImageRemove: "OdstrániÅ¥ miniatúru" + chooseBlock: "PridaÅ¥ blok" + selectType: "Vyberte typ" + enterVariableName: "Zadajte meno premennej" + variableNameIsAlreadyUsed: "Meno premennej s už použÃva" + contentBlocks: "Obsah" + inputBlocks: "Vstup" + specialBlocks: "Å peciálne" + blocks: + text: "Text" + textarea: "Textové pole" + section: "Sekcia" + image: "Obrázky" + button: "TlaÄidlo" + if: "Ak" + _if: + variable: "Premenné" + post: "NapÃsaÅ¥ poznámku" + _post: + text: "Obsah" + attachCanvasImage: "PrÃspevok s obrázkom na plátne" + canvasId: "ID plátna" + textInput: "Textový vstup" + _textInput: + name: "Meno premennej" + text: "Nadpis" + default: "Predvolená hodnota" + textareaInput: "Viacriadkový textový vstup" + _textareaInput: + name: "Meno premennej" + text: "Nadpis" + default: "Predvolená hodnota" + numberInput: "ÄŒÃselný vstup" + _numberInput: + name: "Meno premennej" + text: "Nadpis" + default: "Predvolená hodnota" + canvas: "Plátno" + _canvas: + id: "ID plátna" + width: "Å Ãrka" + height: "Výška" + note: "Vložená poznámka" + _note: + id: "ID poznámky" + idDescription: "Alebo môžete vložiÅ¥ URL poznámky sem" + detailed: "Podrobný pohľad" + switch: "Prepnúť" + _switch: + name: "Meno premennej" + text: "Nadpis" + default: "Predvolená hodnota" + counter: "PoÄÃtadlo" + _counter: + name: "Meno premennej" + text: "Nadpis" + inc: "PripoÄÃtaÅ¥" + _button: + text: "Nadpis" + colored: "Farebné" + action: "Operácia po stlaÄenà tlaÄidla" + _action: + dialog: "ZobraziÅ¥ dialóg" + _dialog: + content: "Obsah" + resetRandom: "ResetovaÅ¥ zdroj náhodnosti" + pushEvent: "PoslaÅ¥ udalosÅ¥" + _pushEvent: + event: "Názov udalosti" + message: "Zobrazená správa po aktivácii" + variable: "Odoslaná premenná" + no-variable: "Žiadne" + callAiScript: "SpustiÅ¥ AiScript" + _callAiScript: + functionName: "Názov funkcie" + radioButton: "MožnosÅ¥" + _radioButton: + name: "Meno premennej" + title: "Nadpis" + values: "Zoznam možnostà oddelené novými riadkami" + default: "Predvolená hodnota" + script: + categories: + flow: "Riadenie behu" + logical: "Logická operácia" + operation: "VýpoÄet" + comparison: "Porovnanie" + random: "Náhodné" + value: "Hodnoty" + fn: "Funkcie" + text: "Textové operácie" + convert: "Transformácie" + list: "Zoznamy" + blocks: + text: "Text" + multiLineText: "Text (viacriadkový)" + textList: "Zoznam textov" + _textList: + info: "Oddeľte každú položku novým riadkom" + strLen: "Dĺžka textu" + _strLen: + arg1: "Text" + strPick: "VybraÅ¥ znak" + _strPick: + arg1: "Text" + arg2: "PozÃcia znaku" + strReplace: "Náhradný text" + _strReplace: + arg1: "Text" + arg2: "Nahradený text" + arg3: "NahradiÅ¥ s" + strReverse: "OtoÄiÅ¥ text" + _strReverse: + arg1: "Text" + join: "SpojiÅ¥ texty" + _join: + arg1: "Zoznamy" + arg2: "OddeľovaÄ" + add: "PridaÅ¥" + _add: + arg1: "A" + arg2: "B" + subtract: "OdÄÃtaÅ¥" + _subtract: + arg1: "A" + arg2: "B" + multiply: "NásobiÅ¥" + _multiply: + arg1: "A" + arg2: "B" + divide: "DeliÅ¥" + _divide: + arg1: "A" + arg2: "B" + mod: "ZvyÅ¡ok po delenÃ" + _mod: + arg1: "A" + arg2: "B" + round: "ZaokrúhliÅ¥" + _round: + arg1: "ÄŒÃslo" + eq: "A a B sa rovnajú" + _eq: + arg1: "A" + arg2: "B" + notEq: "A a B sa nerovnajú" + _notEq: + arg1: "A" + arg2: "B" + and: "A a zároveň B" + _and: + arg1: "A" + arg2: "B" + or: "A alebo B" + _or: + arg1: "A" + arg2: "B" + lt: "< A je menÅ¡ie ako B" + _lt: + arg1: "A" + arg2: "B" + gt: "> A je väÄÅ¡ie ako B" + _gt: + arg1: "A" + arg2: "B" + ltEq: "<= A je menÅ¡ie alebo rovné B" + _ltEq: + arg1: "A" + arg2: "B" + gtEq: ">= A je väÄÅ¡ie alebo rovné B" + _gtEq: + arg1: "A" + arg2: "B" + if: "Vetva" + _if: + arg1: "Ak" + arg2: "Potom" + arg3: "Inak" + not: "Opak" + _not: + arg1: "Opak" + random: "Náhodné" + _random: + arg1: "PravdepodobnosÅ¥" + rannum: "Náhodné ÄÃslo" + _rannum: + arg1: "Minimálna hodnota" + arg2: "Maximálna hodnota" + randomPick: "Náhodný výber zo zoznamu" + _randomPick: + arg1: "Zoznam" + dailyRandom: "Náhodne (zmenà sa raz denne pre každého použÃvateľa)" + _dailyRandom: + arg1: "PravdepodobnosÅ¥" + dailyRannum: "Náhodné ÄÃslo (Menà sa denne pre každého použÃvateľa)" + _dailyRannum: + arg1: "Minimálna hodnota" + arg2: "Maximálna hodnota" + dailyRandomPick: "Náhodný výber zo zoznamu (Menà sa denne pre každého použÃvateľa)" + _dailyRandomPick: + arg1: "Zoznam" + seedRandom: "Náhodne (so seedom)" + _seedRandom: + arg1: "Seed" + arg2: "PravdepodobnosÅ¥" + seedRannum: "Náhodné ÄÃslo (so seedom)" + _seedRannum: + arg1: "Seed" + arg2: "Minimálna hodnota" + arg3: "Maximálna hodnota" + seedRandomPick: "Náhodný výber zo zoznamu (so seedom)" + _seedRandomPick: + arg1: "Seed" + arg2: "Zoznam" + DRPWPM: "Náhodný výber z váženého zoznamu (Menà sa denne pre každého použÃvateľa)" + _DRPWPM: + arg1: "Zoznam textov" + pick: "VybraÅ¥ zo zoznamu" + _pick: + arg1: "Zoznam" + arg2: "PozÃcia" + listLen: "ZÃskaÅ¥ dĺžku zoznamu" + _listLen: + arg1: "Zoznam" + number: "ÄŒÃslo" + stringToNumber: "Text na ÄÃslo" + _stringToNumber: + arg1: "Text" + numberToString: "ÄŒÃslo na text" + _numberToString: + arg1: "ÄŒÃslo" + splitStrByLine: "Rozdelà text po riadkoch" + _splitStrByLine: + arg1: "Text" + ref: "Premenné" + aiScriptVar: "AiScript premenná" + fn: "Funkcie" + _fn: + slots: "Sloty" + slots-info: "Oddeľte každý slot novým riadkom" + arg1: "Výstup" + for: "For cyklus" + _for: + arg1: "PoÄet opakovanÃ" + arg2: "Akcia" + typeError: "Slot {slot} akceptuje hodnoty typu \"{expect}\", ale dodaná hodnota je typu \"{actual}\"!" + thereIsEmptySlot: "Slot {slot} je prázdny!" + types: + string: "Text" + number: "ÄŒÃslo" + boolean: "Boolean" + array: "Zoznamy" + stringArray: "Zoznam textov" + emptySlot: "Prázdny slot" + enviromentVariables: "Premenné prostredia" + pageVariables: "Premenné stránky" + argVariables: "Vstupné sloty" +_relayStatus: + requesting: "ÄŒaká sa" + accepted: "Akceptované" + rejected: "Odmietnuté" +_notification: + fileUploaded: "Súbor sa úspeÅ¡ne nahral" + youGotMention: "{name} vás spomenul/a" + youGotReply: "{name} vám odpovedal/a" + youGotQuote: "{name} vás citoval/a" + youRenoted: "{name} preposlal/a vaÅ¡u poznámku" + youGotPoll: "{name} hlasoval/a" + youGotMessagingMessageFromUser: "{name} vám poslal/a správu" + youGotMessagingMessageFromGroup: "PriÅ¡la správa do skupiny {name}" + youWereFollowed: "Máte nového sledujúceho" + youReceivedFollowRequest: "Dostali ste žiadosÅ¥ o sledovanie" + yourFollowRequestAccepted: "VaÅ¡a žiadosÅ¥ o sledovanie bola prijatá" + youWereInvitedToGroup: "PozvaÅ¥ do skupiny" + _types: + all: "VÅ¡etky" + follow: "Sledujete" + mention: "Zmienka" + reply: "Odpovede" + renote: "PreposlaÅ¥" + quote: "CitovaÅ¥" + reaction: "Reakcie" + pollVote: "Hlasy v hlasovaniach" + receiveFollowRequest: "DoruÄené žiadosti o sledovanie" + followRequestAccepted: "Schválené žiadosti o sledovanie" + groupInvited: "Pozvánky do skupÃn" + app: "Oznámenia z prepojených aplikáciÃ" +_deck: + alwaysShowMainColumn: "Vždy zobraziÅ¥ v hlavnom stĺpci" + columnAlign: "ZarovnaÅ¥ stĺpce" + columnMargin: "Rozostup medzi stĺpcami" + columnHeaderHeight: "Výška hlaviÄky stĺpca" + addColumn: "PridaÅ¥ stĺpec" + swapLeft: "VymeniÅ¥ vľavo" + swapRight: "VymeniÅ¥ vpravo" + swapUp: "VymeniÅ¥ hore" + swapDown: "VymeniÅ¥ s nasledujúcim" + stackLeft: "PriložiÅ¥ do ľavého stĺpca" + popRight: "VybraÅ¥ napravo" + profile: "Profil" + _columns: + main: "Hlavný" + widgets: "Widgety" + notifications: "Oznámenia" + tl: "ÄŒasová os" + antenna: "Antény" + list: "Zoznam" + mentions: "Zmienky" + direct: "Priame poznámky" diff --git a/locales/uk-UA.yml b/locales/uk-UA.yml index 2dd605601143fc1cd3c7a6d927b0529822720fa8..588df8d3256eceef096833cb39e1e3f81562a5e2 100644 --- a/locales/uk-UA.yml +++ b/locales/uk-UA.yml @@ -1038,7 +1038,8 @@ _exportOrImport: blockingList: "Заблокувати" userLists: "СпиÑки" _charts: - federationInstancesTotal: "Загальна кількіÑÑ‚ÑŒ федеративних інÑтанÑів" + federation: "ФедіверÑ" + apRequest: "Запити" usersTotal: "Загальна кількіÑÑ‚ÑŒ кориÑтувачів" activeUsers: "Ðктивні кориÑтувачі" notesTotal: "Загальна кількіÑÑ‚ÑŒ нотаток" diff --git a/locales/zh-CN.yml b/locales/zh-CN.yml index c54e64214a652a1e48b20c0c7415216c2166c660..f4f1680caa112a544ab26823544082fd09f114a6 100644 --- a/locales/zh-CN.yml +++ b/locales/zh-CN.yml @@ -141,6 +141,8 @@ flagAsBot: "这是一个机器人账å·" flagAsBotDescription: "如果æ¤å¸æˆ·ç”±ç¨‹åºæŽ§åˆ¶ï¼Œè¯·å¯ç”¨æ¤é¡¹ã€‚å¯ç”¨åŽï¼Œæ¤æ ‡å¿—å¯ä»¥å¸®åŠ©å…¶ä»–å¼€å‘人员防æ¢æœºå™¨äººä¹‹é—´äº§ç”Ÿæ— é™äº’动的行为,并让Misskey的内部系统将æ¤å¸æˆ·è¯†åˆ«ä¸ºæœºå™¨äººã€‚" flagAsCat: "将这个账户设定为一åªçŒ«" flagAsCatDescription: "如果您想表明æ¤å¸æˆ·æ˜¯ä¸€åªçŒ«ï¼Œè¯·æ‰“å¼€æ¤æ ‡å¿—。" +flagShowTimelineReplies: "在时间线上显示帖å的回å¤" +flagShowTimelineRepliesDescription: "å¯ç”¨æ—¶ï¼Œæ—¶é—´çº¿é™¤äº†æ˜¾ç¤ºç”¨æˆ·çš„帖å外,还会显示其他用户对帖å的回å¤ã€‚" autoAcceptFollowed: "自动å…许关注" addAccount: "æ·»åŠ è´¦æˆ·" loginFailed: "登录失败" @@ -822,6 +824,10 @@ leaveGroupConfirm: "确定离开「{name}ã€ï¼Ÿ" useDrawerReactionPickerForMobile: "在移动设备上使用抽屉显示" welcomeBackWithName: "欢迎回æ¥ï¼Œ{name}" clickToFinishEmailVerification: "点击 [{ok}] 完æˆç”µå邮件地å€è®¤è¯ã€‚" +overridedDeviceKind: "设备类型" +smartphone: "智能手机" +tablet: "å¹³æ¿" +auto: "自动" _emailUnavailable: used: "å·²ç»è¢«ä½¿ç”¨è¿‡" format: "æ— æ•ˆçš„æ ¼å¼" @@ -1258,8 +1264,8 @@ _exportOrImport: excludeMutingUsers: "排除å±è”½ç”¨æˆ·" excludeInactiveUsers: "排除ä¸æ´»è·ƒç”¨æˆ·" _charts: - federationInstancesIncDec: "è”åˆï¼šå¢žåŠ /å‡å°‘" - federationInstancesTotal: "è”åˆæ€»æ•°" + federation: "è”åˆ" + apRequest: "请求" usersIncDec: "用户数é‡ï¼šå¢žåŠ /å‡å°‘" usersTotal: "用户总数" activeUsers: "活跃用户数" diff --git a/locales/zh-TW.yml b/locales/zh-TW.yml index 798398a6a9021a341ba4ee5f469ec69e6c432552..b10871ec1d9440eb45b67e97ebaea2ad37e6244b 100644 --- a/locales/zh-TW.yml +++ b/locales/zh-TW.yml @@ -1114,6 +1114,8 @@ _exportOrImport: blockingList: "å°éŽ–" userLists: "清單" _charts: + federation: "ç«™å°è¯é‚¦" + apRequest: "請求" usersIncDec: "使用者増減" usersTotal: "使用者åˆå…±" activeUsers: "æ´»èºä½¿ç”¨è€…" diff --git a/package.json b/package.json index 27fd81cd869f1e0267efe97dc18a878f85ddd326..46dac95db3b3c32193934a1dbd6162a522a840f3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "misskey", - "version": "12.103.1", + "version": "12.104.0", "codename": "indigo", "repository": { "type": "git", @@ -46,7 +46,7 @@ "@types/fluent-ffmpeg": "2.1.20", "@typescript-eslint/parser": "5.10.0", "cross-env": "7.0.3", - "cypress": "9.3.1", + "cypress": "9.4.1", "start-server-and-test": "1.14.0", "typescript": "4.5.5" } diff --git a/packages/backend/migration/1629833361000-AddShowTLReplies.js b/packages/backend/migration/1629833361000-AddShowTLReplies.js new file mode 100644 index 0000000000000000000000000000000000000000..bfd4ab7ff78259aed09685a128defd208fe85d26 --- /dev/null +++ b/packages/backend/migration/1629833361000-AddShowTLReplies.js @@ -0,0 +1,15 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class addShowTLReplies1629833361000 { + constructor() { + this.name = 'addShowTLReplies1629833361000'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "user" ADD "showTimelineReplies" boolean NOT NULL DEFAULT false`); + await queryRunner.query(`COMMENT ON COLUMN "user"."showTimelineReplies" IS 'Whether to show users replying to other users in the timeline.'`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "showTimelineReplies"`); + } +} +exports.addShowTLReplies1629833361000 = addShowTLReplies1629833361000; diff --git a/packages/backend/migration/1643963705770-chart-v4.js b/packages/backend/migration/1643963705770-chart-v4.js new file mode 100644 index 0000000000000000000000000000000000000000..91b0a747e65fbb294b273bc87abc2660f249ad00 --- /dev/null +++ b/packages/backend/migration/1643963705770-chart-v4.js @@ -0,0 +1,63 @@ +const { MigrationInterface, QueryRunner } = require("typeorm"); + +module.exports = class chartV41643963705770 { + name = 'chartV41643963705770' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "__chart__instance" DROP COLUMN "___drive_totalUsage"`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" DROP COLUMN "___drive_totalUsage"`); + await queryRunner.query(`ALTER TABLE "__chart__drive" DROP COLUMN "___local_totalCount"`); + await queryRunner.query(`ALTER TABLE "__chart__drive" DROP COLUMN "___local_totalSize"`); + await queryRunner.query(`ALTER TABLE "__chart__drive" DROP COLUMN "___remote_totalCount"`); + await queryRunner.query(`ALTER TABLE "__chart__drive" DROP COLUMN "___remote_totalSize"`); + await queryRunner.query(`ALTER TABLE "__chart_day__drive" DROP COLUMN "___local_totalCount"`); + await queryRunner.query(`ALTER TABLE "__chart_day__drive" DROP COLUMN "___local_totalSize"`); + await queryRunner.query(`ALTER TABLE "__chart_day__drive" DROP COLUMN "___remote_totalCount"`); + await queryRunner.query(`ALTER TABLE "__chart_day__drive" DROP COLUMN "___remote_totalSize"`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "___local_users"`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "___local_users" bigint NOT NULL DEFAULT 0`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "___remote_users"`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "___remote_users" bigint NOT NULL DEFAULT 0`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "___local_users"`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "___local_users" bigint NOT NULL DEFAULT 0`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "___remote_users"`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "___remote_users" bigint NOT NULL DEFAULT 0`); + await queryRunner.query(`ALTER TABLE "__chart__hashtag" DROP COLUMN "___local_users"`); + await queryRunner.query(`ALTER TABLE "__chart__hashtag" ADD "___local_users" bigint NOT NULL DEFAULT 0`); + await queryRunner.query(`ALTER TABLE "__chart__hashtag" DROP COLUMN "___remote_users"`); + await queryRunner.query(`ALTER TABLE "__chart__hashtag" ADD "___remote_users" bigint NOT NULL DEFAULT 0`); + await queryRunner.query(`ALTER TABLE "__chart_day__hashtag" DROP COLUMN "___local_users"`); + await queryRunner.query(`ALTER TABLE "__chart_day__hashtag" ADD "___local_users" bigint NOT NULL DEFAULT 0`); + await queryRunner.query(`ALTER TABLE "__chart_day__hashtag" DROP COLUMN "___remote_users"`); + await queryRunner.query(`ALTER TABLE "__chart_day__hashtag" ADD "___remote_users" bigint NOT NULL DEFAULT 0`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "__chart_day__hashtag" DROP COLUMN "___remote_users"`); + await queryRunner.query(`ALTER TABLE "__chart_day__hashtag" ADD "___remote_users" character varying array NOT NULL`); + await queryRunner.query(`ALTER TABLE "__chart_day__hashtag" DROP COLUMN "___local_users"`); + await queryRunner.query(`ALTER TABLE "__chart_day__hashtag" ADD "___local_users" character varying array NOT NULL`); + await queryRunner.query(`ALTER TABLE "__chart__hashtag" DROP COLUMN "___remote_users"`); + await queryRunner.query(`ALTER TABLE "__chart__hashtag" ADD "___remote_users" character varying array NOT NULL`); + await queryRunner.query(`ALTER TABLE "__chart__hashtag" DROP COLUMN "___local_users"`); + await queryRunner.query(`ALTER TABLE "__chart__hashtag" ADD "___local_users" character varying array NOT NULL`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "___remote_users"`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "___remote_users" character varying array NOT NULL`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "___local_users"`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "___local_users" character varying array NOT NULL`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "___remote_users"`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "___remote_users" character varying array NOT NULL`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "___local_users"`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "___local_users" character varying array NOT NULL`); + await queryRunner.query(`ALTER TABLE "__chart_day__drive" ADD "___remote_totalSize" bigint NOT NULL`); + await queryRunner.query(`ALTER TABLE "__chart_day__drive" ADD "___remote_totalCount" bigint NOT NULL`); + await queryRunner.query(`ALTER TABLE "__chart_day__drive" ADD "___local_totalSize" bigint NOT NULL`); + await queryRunner.query(`ALTER TABLE "__chart_day__drive" ADD "___local_totalCount" bigint NOT NULL`); + await queryRunner.query(`ALTER TABLE "__chart__drive" ADD "___remote_totalSize" bigint NOT NULL`); + await queryRunner.query(`ALTER TABLE "__chart__drive" ADD "___remote_totalCount" bigint NOT NULL`); + await queryRunner.query(`ALTER TABLE "__chart__drive" ADD "___local_totalSize" bigint NOT NULL`); + await queryRunner.query(`ALTER TABLE "__chart__drive" ADD "___local_totalCount" bigint NOT NULL`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ADD "___drive_totalUsage" bigint NOT NULL`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ADD "___drive_totalUsage" bigint NOT NULL`); + } +} diff --git a/packages/backend/migration/1643966656277-chart-v5.js b/packages/backend/migration/1643966656277-chart-v5.js new file mode 100644 index 0000000000000000000000000000000000000000..9ff05be63b18fbd19fc001139fd1fdc20e94a084 --- /dev/null +++ b/packages/backend/migration/1643966656277-chart-v5.js @@ -0,0 +1,27 @@ +const { MigrationInterface, QueryRunner } = require("typeorm"); + +module.exports = class chartV51643966656277 { + name = 'chartV51643966656277' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "unique_temp___local_users" character varying array NOT NULL DEFAULT '{}'`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "unique_temp___remote_users" character varying array NOT NULL DEFAULT '{}'`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "unique_temp___local_users" character varying array NOT NULL DEFAULT '{}'`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "unique_temp___remote_users" character varying array NOT NULL DEFAULT '{}'`); + await queryRunner.query(`ALTER TABLE "__chart__hashtag" ADD "unique_temp___local_users" character varying array NOT NULL DEFAULT '{}'`); + await queryRunner.query(`ALTER TABLE "__chart__hashtag" ADD "unique_temp___remote_users" character varying array NOT NULL DEFAULT '{}'`); + await queryRunner.query(`ALTER TABLE "__chart_day__hashtag" ADD "unique_temp___local_users" character varying array NOT NULL DEFAULT '{}'`); + await queryRunner.query(`ALTER TABLE "__chart_day__hashtag" ADD "unique_temp___remote_users" character varying array NOT NULL DEFAULT '{}'`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "__chart_day__hashtag" DROP COLUMN "unique_temp___remote_users"`); + await queryRunner.query(`ALTER TABLE "__chart_day__hashtag" DROP COLUMN "unique_temp___local_users"`); + await queryRunner.query(`ALTER TABLE "__chart__hashtag" DROP COLUMN "unique_temp___remote_users"`); + await queryRunner.query(`ALTER TABLE "__chart__hashtag" DROP COLUMN "unique_temp___local_users"`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "unique_temp___remote_users"`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "unique_temp___local_users"`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "unique_temp___remote_users"`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "unique_temp___local_users"`); + } +} diff --git a/packages/backend/migration/1643967331284-chart-v6.js b/packages/backend/migration/1643967331284-chart-v6.js new file mode 100644 index 0000000000000000000000000000000000000000..86feade9d16518fe81b9b0f0b1ad2d182e6cc764 --- /dev/null +++ b/packages/backend/migration/1643967331284-chart-v6.js @@ -0,0 +1,343 @@ +const { MigrationInterface, QueryRunner } = require("typeorm"); + +module.exports = class chartV61643967331284 { + name = 'chartV61643967331284' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "__chart__federation" ALTER COLUMN "___instance_total" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__federation" ALTER COLUMN "___instance_inc" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__federation" ALTER COLUMN "___instance_dec" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__federation" ALTER COLUMN "___instance_total" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__federation" ALTER COLUMN "___instance_inc" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__federation" ALTER COLUMN "___instance_dec" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___local_total" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___local_inc" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___local_dec" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___local_diffs_normal" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___local_diffs_reply" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___local_diffs_renote" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___remote_total" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___remote_inc" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___remote_dec" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___remote_diffs_normal" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___remote_diffs_reply" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___remote_diffs_renote" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___local_total" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___local_inc" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___local_dec" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___local_diffs_normal" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___local_diffs_reply" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___local_diffs_renote" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___remote_total" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___remote_inc" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___remote_dec" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___remote_diffs_normal" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___remote_diffs_reply" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___remote_diffs_renote" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__users" ALTER COLUMN "___local_total" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__users" ALTER COLUMN "___local_inc" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__users" ALTER COLUMN "___local_dec" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__users" ALTER COLUMN "___remote_total" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__users" ALTER COLUMN "___remote_inc" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__users" ALTER COLUMN "___remote_dec" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__users" ALTER COLUMN "___local_total" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__users" ALTER COLUMN "___local_inc" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__users" ALTER COLUMN "___local_dec" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__users" ALTER COLUMN "___remote_total" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__users" ALTER COLUMN "___remote_inc" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__users" ALTER COLUMN "___remote_dec" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__network" ALTER COLUMN "___incomingRequests" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__network" ALTER COLUMN "___outgoingRequests" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__network" ALTER COLUMN "___totalTime" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__network" ALTER COLUMN "___incomingBytes" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__network" ALTER COLUMN "___outgoingBytes" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__network" ALTER COLUMN "___incomingRequests" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__network" ALTER COLUMN "___outgoingRequests" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__network" ALTER COLUMN "___totalTime" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__network" ALTER COLUMN "___incomingBytes" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__network" ALTER COLUMN "___outgoingBytes" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___requests_failed" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___requests_succeeded" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___requests_received" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___notes_total" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___notes_inc" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___notes_dec" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___notes_diffs_normal" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___notes_diffs_reply" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___notes_diffs_renote" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___users_total" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___users_inc" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___users_dec" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___following_total" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___following_inc" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___following_dec" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___followers_total" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___followers_inc" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___followers_dec" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___drive_totalFiles" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___drive_incFiles" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___drive_decFiles" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___drive_incUsage" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___drive_decUsage" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___requests_failed" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___requests_succeeded" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___requests_received" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___notes_total" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___notes_inc" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___notes_dec" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___notes_diffs_normal" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___notes_diffs_reply" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___notes_diffs_renote" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___users_total" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___users_inc" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___users_dec" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___following_total" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___following_inc" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___following_dec" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___followers_total" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___followers_inc" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___followers_dec" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___drive_totalFiles" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___drive_incFiles" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___drive_decFiles" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___drive_incUsage" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___drive_decUsage" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "___total" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "___inc" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "___dec" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "___diffs_normal" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "___diffs_reply" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "___diffs_renote" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ALTER COLUMN "___total" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ALTER COLUMN "___inc" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ALTER COLUMN "___dec" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ALTER COLUMN "___diffs_normal" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ALTER COLUMN "___diffs_reply" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ALTER COLUMN "___diffs_renote" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___local_incCount" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___local_incSize" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___local_decCount" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___local_decSize" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___remote_incCount" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___remote_incSize" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___remote_decCount" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___remote_decSize" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___local_incCount" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___local_incSize" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___local_decCount" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___local_decSize" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___remote_incCount" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___remote_incSize" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___remote_decCount" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___remote_decSize" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_reaction" ALTER COLUMN "___local_count" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_reaction" ALTER COLUMN "___remote_count" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_reaction" ALTER COLUMN "___local_count" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_reaction" ALTER COLUMN "___remote_count" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___local_followings_total" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___local_followings_inc" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___local_followings_dec" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___local_followers_total" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___local_followers_inc" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___local_followers_dec" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___remote_followings_total" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___remote_followings_inc" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___remote_followings_dec" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___remote_followers_total" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___remote_followers_inc" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___remote_followers_dec" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___local_followings_total" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___local_followings_inc" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___local_followings_dec" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___local_followers_total" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___local_followers_inc" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___local_followers_dec" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___remote_followings_total" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___remote_followings_inc" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___remote_followings_dec" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___remote_followers_total" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___remote_followers_inc" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___remote_followers_dec" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "___totalCount" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "___totalSize" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "___incCount" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "___incSize" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "___decCount" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "___decSize" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_drive" ALTER COLUMN "___totalCount" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_drive" ALTER COLUMN "___totalSize" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_drive" ALTER COLUMN "___incCount" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_drive" ALTER COLUMN "___incSize" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_drive" ALTER COLUMN "___decCount" SET DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_drive" ALTER COLUMN "___decSize" SET DEFAULT '0'`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_drive" ALTER COLUMN "___decSize" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_drive" ALTER COLUMN "___decCount" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_drive" ALTER COLUMN "___incSize" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_drive" ALTER COLUMN "___incCount" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_drive" ALTER COLUMN "___totalSize" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_drive" ALTER COLUMN "___totalCount" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "___decSize" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "___decCount" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "___incSize" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "___incCount" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "___totalSize" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "___totalCount" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___remote_followers_dec" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___remote_followers_inc" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___remote_followers_total" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___remote_followings_dec" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___remote_followings_inc" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___remote_followings_total" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___local_followers_dec" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___local_followers_inc" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___local_followers_total" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___local_followings_dec" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___local_followings_inc" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___local_followings_total" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___remote_followers_dec" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___remote_followers_inc" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___remote_followers_total" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___remote_followings_dec" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___remote_followings_inc" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___remote_followings_total" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___local_followers_dec" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___local_followers_inc" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___local_followers_total" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___local_followings_dec" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___local_followings_inc" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___local_followings_total" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_reaction" ALTER COLUMN "___remote_count" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_reaction" ALTER COLUMN "___local_count" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_reaction" ALTER COLUMN "___remote_count" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_reaction" ALTER COLUMN "___local_count" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___remote_decSize" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___remote_decCount" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___remote_incSize" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___remote_incCount" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___local_decSize" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___local_decCount" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___local_incSize" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___local_incCount" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___remote_decSize" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___remote_decCount" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___remote_incSize" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___remote_incCount" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___local_decSize" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___local_decCount" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___local_incSize" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___local_incCount" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ALTER COLUMN "___diffs_renote" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ALTER COLUMN "___diffs_reply" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ALTER COLUMN "___diffs_normal" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ALTER COLUMN "___dec" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ALTER COLUMN "___inc" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ALTER COLUMN "___total" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "___diffs_renote" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "___diffs_reply" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "___diffs_normal" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "___dec" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "___inc" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "___total" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___drive_decUsage" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___drive_incUsage" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___drive_decFiles" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___drive_incFiles" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___drive_totalFiles" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___followers_dec" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___followers_inc" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___followers_total" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___following_dec" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___following_inc" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___following_total" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___users_dec" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___users_inc" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___users_total" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___notes_diffs_renote" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___notes_diffs_reply" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___notes_diffs_normal" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___notes_dec" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___notes_inc" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___notes_total" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___requests_received" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___requests_succeeded" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___requests_failed" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___drive_decUsage" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___drive_incUsage" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___drive_decFiles" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___drive_incFiles" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___drive_totalFiles" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___followers_dec" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___followers_inc" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___followers_total" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___following_dec" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___following_inc" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___following_total" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___users_dec" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___users_inc" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___users_total" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___notes_diffs_renote" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___notes_diffs_reply" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___notes_diffs_normal" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___notes_dec" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___notes_inc" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___notes_total" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___requests_received" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___requests_succeeded" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___requests_failed" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__network" ALTER COLUMN "___outgoingBytes" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__network" ALTER COLUMN "___incomingBytes" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__network" ALTER COLUMN "___totalTime" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__network" ALTER COLUMN "___outgoingRequests" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__network" ALTER COLUMN "___incomingRequests" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__network" ALTER COLUMN "___outgoingBytes" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__network" ALTER COLUMN "___incomingBytes" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__network" ALTER COLUMN "___totalTime" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__network" ALTER COLUMN "___outgoingRequests" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__network" ALTER COLUMN "___incomingRequests" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__users" ALTER COLUMN "___remote_dec" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__users" ALTER COLUMN "___remote_inc" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__users" ALTER COLUMN "___remote_total" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__users" ALTER COLUMN "___local_dec" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__users" ALTER COLUMN "___local_inc" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__users" ALTER COLUMN "___local_total" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__users" ALTER COLUMN "___remote_dec" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__users" ALTER COLUMN "___remote_inc" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__users" ALTER COLUMN "___remote_total" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__users" ALTER COLUMN "___local_dec" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__users" ALTER COLUMN "___local_inc" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__users" ALTER COLUMN "___local_total" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___remote_diffs_renote" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___remote_diffs_reply" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___remote_diffs_normal" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___remote_dec" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___remote_inc" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___remote_total" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___local_diffs_renote" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___local_diffs_reply" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___local_diffs_normal" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___local_dec" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___local_inc" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___local_total" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___remote_diffs_renote" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___remote_diffs_reply" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___remote_diffs_normal" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___remote_dec" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___remote_inc" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___remote_total" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___local_diffs_renote" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___local_diffs_reply" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___local_diffs_normal" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___local_dec" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___local_inc" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___local_total" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__federation" ALTER COLUMN "___instance_dec" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__federation" ALTER COLUMN "___instance_inc" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart_day__federation" ALTER COLUMN "___instance_total" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__federation" ALTER COLUMN "___instance_dec" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__federation" ALTER COLUMN "___instance_inc" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "__chart__federation" ALTER COLUMN "___instance_total" DROP DEFAULT`); + } +} diff --git a/packages/backend/migration/1644058404077-chart-v7.js b/packages/backend/migration/1644058404077-chart-v7.js new file mode 100644 index 0000000000000000000000000000000000000000..a462a7cd36239ca2610b75280e451b320d40b61c --- /dev/null +++ b/packages/backend/migration/1644058404077-chart-v7.js @@ -0,0 +1,511 @@ +const { MigrationInterface, QueryRunner } = require("typeorm"); + +module.exports = class chartV71644058404077 { + name = 'chartV71644058404077' + + async up(queryRunner) { + await queryRunner.query(`UPDATE "__chart__federation" SET "___instance_total"=2147483647 WHERE "___instance_total" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__federation" SET "___instance_inc"=32767 WHERE "___instance_inc" > 32767`); + await queryRunner.query(`UPDATE "__chart__federation" SET "___instance_dec"=32767 WHERE "___instance_dec" > 32767`); + await queryRunner.query(`UPDATE "__chart_day__federation" SET "___instance_total"=2147483647 WHERE "___instance_total" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__federation" SET "___instance_inc"=32767 WHERE "___instance_inc" > 32767`); + await queryRunner.query(`UPDATE "__chart_day__federation" SET "___instance_dec"=32767 WHERE "___instance_dec" > 32767`); + await queryRunner.query(`UPDATE "__chart__notes" SET "___local_total"=2147483647 WHERE "___local_total" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__notes" SET "___local_inc"=2147483647 WHERE "___local_inc" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__notes" SET "___local_dec"=2147483647 WHERE "___local_dec" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__notes" SET "___local_diffs_normal"=2147483647 WHERE "___local_diffs_normal" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__notes" SET "___local_diffs_reply"=2147483647 WHERE "___local_diffs_reply" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__notes" SET "___local_diffs_renote"=2147483647 WHERE "___local_diffs_renote" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__notes" SET "___remote_total"=2147483647 WHERE "___remote_total" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__notes" SET "___remote_inc"=2147483647 WHERE "___remote_inc" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__notes" SET "___remote_dec"=2147483647 WHERE "___remote_dec" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__notes" SET "___remote_diffs_normal"=2147483647 WHERE "___remote_diffs_normal" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__notes" SET "___remote_diffs_reply"=2147483647 WHERE "___remote_diffs_reply" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__notes" SET "___remote_diffs_renote"=2147483647 WHERE "___remote_diffs_renote" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__notes" SET "___local_total"=2147483647 WHERE "___local_total" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__notes" SET "___local_inc"=2147483647 WHERE "___local_inc" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__notes" SET "___local_dec"=2147483647 WHERE "___local_dec" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__notes" SET "___local_diffs_normal"=2147483647 WHERE "___local_diffs_normal" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__notes" SET "___local_diffs_reply"=2147483647 WHERE "___local_diffs_reply" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__notes" SET "___local_diffs_renote"=2147483647 WHERE "___local_diffs_renote" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__notes" SET "___remote_total"=2147483647 WHERE "___remote_total" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__notes" SET "___remote_inc"=2147483647 WHERE "___remote_inc" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__notes" SET "___remote_dec"=2147483647 WHERE "___remote_dec" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__notes" SET "___remote_diffs_normal"=2147483647 WHERE "___remote_diffs_normal" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__notes" SET "___remote_diffs_reply"=2147483647 WHERE "___remote_diffs_reply" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__notes" SET "___remote_diffs_renote"=2147483647 WHERE "___remote_diffs_renote" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__users" SET "___local_total"=2147483647 WHERE "___local_total" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__users" SET "___local_inc"=32767 WHERE "___local_inc" > 32767`); + await queryRunner.query(`UPDATE "__chart__users" SET "___local_dec"=32767 WHERE "___local_dec" > 32767`); + await queryRunner.query(`UPDATE "__chart__users" SET "___remote_total"=2147483647 WHERE "___remote_total" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__users" SET "___remote_inc"=32767 WHERE "___remote_inc" > 32767`); + await queryRunner.query(`UPDATE "__chart__users" SET "___remote_dec"=32767 WHERE "___remote_dec" > 32767`); + await queryRunner.query(`UPDATE "__chart_day__users" SET "___local_total"=2147483647 WHERE "___local_total" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__users" SET "___local_inc"=32767 WHERE "___local_inc" > 32767`); + await queryRunner.query(`UPDATE "__chart_day__users" SET "___local_dec"=32767 WHERE "___local_dec" > 32767`); + await queryRunner.query(`UPDATE "__chart_day__users" SET "___remote_total"=2147483647 WHERE "___remote_total" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__users" SET "___remote_inc"=32767 WHERE "___remote_inc" > 32767`); + await queryRunner.query(`UPDATE "__chart_day__users" SET "___remote_dec"=32767 WHERE "___remote_dec" > 32767`); + await queryRunner.query(`UPDATE "__chart__network" SET "___incomingRequests"=2147483647 WHERE "___incomingRequests" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__network" SET "___outgoingRequests"=2147483647 WHERE "___outgoingRequests" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__network" SET "___totalTime"=2147483647 WHERE "___totalTime" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__network" SET "___incomingBytes"=2147483647 WHERE "___incomingBytes" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__network" SET "___outgoingBytes"=2147483647 WHERE "___outgoingBytes" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__network" SET "___incomingRequests"=2147483647 WHERE "___incomingRequests" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__network" SET "___outgoingRequests"=2147483647 WHERE "___outgoingRequests" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__network" SET "___totalTime"=2147483647 WHERE "___totalTime" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__network" SET "___incomingBytes"=2147483647 WHERE "___incomingBytes" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__network" SET "___outgoingBytes"=2147483647 WHERE "___outgoingBytes" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__instance" SET "___requests_failed"=32767 WHERE "___requests_failed" > 32767`); + await queryRunner.query(`UPDATE "__chart__instance" SET "___requests_succeeded"=32767 WHERE "___requests_succeeded" > 32767`); + await queryRunner.query(`UPDATE "__chart__instance" SET "___requests_received"=32767 WHERE "___requests_received" > 32767`); + await queryRunner.query(`UPDATE "__chart__instance" SET "___notes_total"=2147483647 WHERE "___notes_total" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__instance" SET "___notes_inc"=2147483647 WHERE "___notes_inc" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__instance" SET "___notes_dec"=2147483647 WHERE "___notes_dec" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__instance" SET "___notes_diffs_normal"=2147483647 WHERE "___notes_diffs_normal" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__instance" SET "___notes_diffs_reply"=2147483647 WHERE "___notes_diffs_reply" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__instance" SET "___notes_diffs_renote"=2147483647 WHERE "___notes_diffs_renote" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__instance" SET "___users_total"=2147483647 WHERE "___users_total" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__instance" SET "___users_inc"=32767 WHERE "___users_inc" > 32767`); + await queryRunner.query(`UPDATE "__chart__instance" SET "___users_dec"=32767 WHERE "___users_dec" > 32767`); + await queryRunner.query(`UPDATE "__chart__instance" SET "___following_total"=2147483647 WHERE "___following_total" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__instance" SET "___following_inc"=32767 WHERE "___following_inc" > 32767`); + await queryRunner.query(`UPDATE "__chart__instance" SET "___following_dec"=32767 WHERE "___following_dec" > 32767`); + await queryRunner.query(`UPDATE "__chart__instance" SET "___followers_total"=2147483647 WHERE "___followers_total" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__instance" SET "___followers_inc"=32767 WHERE "___followers_inc" > 32767`); + await queryRunner.query(`UPDATE "__chart__instance" SET "___followers_dec"=32767 WHERE "___followers_dec" > 32767`); + await queryRunner.query(`UPDATE "__chart__instance" SET "___drive_totalFiles"=2147483647 WHERE "___drive_totalFiles" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__instance" SET "___drive_incFiles"=2147483647 WHERE "___drive_incFiles" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__instance" SET "___drive_decFiles"=2147483647 WHERE "___drive_decFiles" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__instance" SET "___drive_incUsage"=2147483647 WHERE "___drive_incUsage" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__instance" SET "___drive_decUsage"=2147483647 WHERE "___drive_decUsage" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__instance" SET "___requests_failed"=32767 WHERE "___requests_failed" > 32767`); + await queryRunner.query(`UPDATE "__chart_day__instance" SET "___requests_succeeded"=32767 WHERE "___requests_succeeded" > 32767`); + await queryRunner.query(`UPDATE "__chart_day__instance" SET "___requests_received"=32767 WHERE "___requests_received" > 32767`); + await queryRunner.query(`UPDATE "__chart_day__instance" SET "___notes_total"=2147483647 WHERE "___notes_total" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__instance" SET "___notes_inc"=2147483647 WHERE "___notes_inc" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__instance" SET "___notes_dec"=2147483647 WHERE "___notes_dec" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__instance" SET "___notes_diffs_normal"=2147483647 WHERE "___notes_diffs_normal" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__instance" SET "___notes_diffs_reply"=2147483647 WHERE "___notes_diffs_reply" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__instance" SET "___notes_diffs_renote"=2147483647 WHERE "___notes_diffs_renote" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__instance" SET "___users_total"=2147483647 WHERE "___users_total" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__instance" SET "___users_inc"=32767 WHERE "___users_inc" > 32767`); + await queryRunner.query(`UPDATE "__chart_day__instance" SET "___users_dec"=32767 WHERE "___users_dec" > 32767`); + await queryRunner.query(`UPDATE "__chart_day__instance" SET "___following_total"=2147483647 WHERE "___following_total" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__instance" SET "___following_inc"=32767 WHERE "___following_inc" > 32767`); + await queryRunner.query(`UPDATE "__chart_day__instance" SET "___following_dec"=32767 WHERE "___following_dec" > 32767`); + await queryRunner.query(`UPDATE "__chart_day__instance" SET "___followers_total"=2147483647 WHERE "___followers_total" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__instance" SET "___followers_inc"=32767 WHERE "___followers_inc" > 32767`); + await queryRunner.query(`UPDATE "__chart_day__instance" SET "___followers_dec"=32767 WHERE "___followers_dec" > 32767`); + await queryRunner.query(`UPDATE "__chart_day__instance" SET "___drive_totalFiles"=2147483647 WHERE "___drive_totalFiles" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__instance" SET "___drive_incFiles"=2147483647 WHERE "___drive_incFiles" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__instance" SET "___drive_decFiles"=2147483647 WHERE "___drive_decFiles" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__instance" SET "___drive_incUsage"=2147483647 WHERE "___drive_incUsage" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__instance" SET "___drive_decUsage"=2147483647 WHERE "___drive_decUsage" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__per_user_notes" SET "___total"=2147483647 WHERE "___total" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__per_user_notes" SET "___inc"=32767 WHERE "___inc" > 32767`); + await queryRunner.query(`UPDATE "__chart__per_user_notes" SET "___dec"=32767 WHERE "___dec" > 32767`); + await queryRunner.query(`UPDATE "__chart__per_user_notes" SET "___diffs_normal"=32767 WHERE "___diffs_normal" > 32767`); + await queryRunner.query(`UPDATE "__chart__per_user_notes" SET "___diffs_reply"=32767 WHERE "___diffs_reply" > 32767`); + await queryRunner.query(`UPDATE "__chart__per_user_notes" SET "___diffs_renote"=32767 WHERE "___diffs_renote" > 32767`); + await queryRunner.query(`UPDATE "__chart_day__per_user_notes" SET "___total"=2147483647 WHERE "___total" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__per_user_notes" SET "___inc"=32767 WHERE "___inc" > 32767`); + await queryRunner.query(`UPDATE "__chart_day__per_user_notes" SET "___dec"=32767 WHERE "___dec" > 32767`); + await queryRunner.query(`UPDATE "__chart_day__per_user_notes" SET "___diffs_normal"=32767 WHERE "___diffs_normal" > 32767`); + await queryRunner.query(`UPDATE "__chart_day__per_user_notes" SET "___diffs_reply"=32767 WHERE "___diffs_reply" > 32767`); + await queryRunner.query(`UPDATE "__chart_day__per_user_notes" SET "___diffs_renote"=32767 WHERE "___diffs_renote" > 32767`); + await queryRunner.query(`UPDATE "__chart__drive" SET "___local_incCount"=2147483647 WHERE "___local_incCount" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__drive" SET "___local_incSize"=2147483647 WHERE "___local_incSize" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__drive" SET "___local_decCount"=2147483647 WHERE "___local_decCount" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__drive" SET "___local_decSize"=2147483647 WHERE "___local_decSize" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__drive" SET "___remote_incCount"=2147483647 WHERE "___remote_incCount" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__drive" SET "___remote_incSize"=2147483647 WHERE "___remote_incSize" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__drive" SET "___remote_decCount"=2147483647 WHERE "___remote_decCount" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__drive" SET "___remote_decSize"=2147483647 WHERE "___remote_decSize" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__drive" SET "___local_incCount"=2147483647 WHERE "___local_incCount" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__drive" SET "___local_incSize"=2147483647 WHERE "___local_incSize" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__drive" SET "___local_decCount"=2147483647 WHERE "___local_decCount" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__drive" SET "___local_decSize"=2147483647 WHERE "___local_decSize" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__drive" SET "___remote_incCount"=2147483647 WHERE "___remote_incCount" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__drive" SET "___remote_incSize"=2147483647 WHERE "___remote_incSize" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__drive" SET "___remote_decCount"=2147483647 WHERE "___remote_decCount" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__drive" SET "___remote_decSize"=2147483647 WHERE "___remote_decSize" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__per_user_reaction" SET "___local_count"=32767 WHERE "___local_count" > 32767`); + await queryRunner.query(`UPDATE "__chart__per_user_reaction" SET "___remote_count"=32767 WHERE "___remote_count" > 32767`); + await queryRunner.query(`UPDATE "__chart_day__per_user_reaction" SET "___local_count"=32767 WHERE "___local_count" > 32767`); + await queryRunner.query(`UPDATE "__chart_day__per_user_reaction" SET "___remote_count"=32767 WHERE "___remote_count" > 32767`); + await queryRunner.query(`UPDATE "__chart__per_user_following" SET "___local_followings_total"=2147483647 WHERE "___local_followings_total" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__per_user_following" SET "___local_followings_inc"=32767 WHERE "___local_followings_inc" > 32767`); + await queryRunner.query(`UPDATE "__chart__per_user_following" SET "___local_followings_dec"=32767 WHERE "___local_followings_dec" > 32767`); + await queryRunner.query(`UPDATE "__chart__per_user_following" SET "___local_followers_total"=2147483647 WHERE "___local_followers_total" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__per_user_following" SET "___local_followers_inc"=32767 WHERE "___local_followers_inc" > 32767`); + await queryRunner.query(`UPDATE "__chart__per_user_following" SET "___local_followers_dec"=32767 WHERE "___local_followers_dec" > 32767`); + await queryRunner.query(`UPDATE "__chart__per_user_following" SET "___remote_followings_total"=2147483647 WHERE "___remote_followings_total" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__per_user_following" SET "___remote_followings_inc"=32767 WHERE "___remote_followings_inc" > 32767`); + await queryRunner.query(`UPDATE "__chart__per_user_following" SET "___remote_followings_dec"=32767 WHERE "___remote_followings_dec" > 32767`); + await queryRunner.query(`UPDATE "__chart__per_user_following" SET "___remote_followers_total"=2147483647 WHERE "___remote_followers_total" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__per_user_following" SET "___remote_followers_inc"=32767 WHERE "___remote_followers_inc" > 32767`); + await queryRunner.query(`UPDATE "__chart__per_user_following" SET "___remote_followers_dec"=32767 WHERE "___remote_followers_dec" > 32767`); + await queryRunner.query(`UPDATE "__chart_day__per_user_following" SET "___local_followings_total"=2147483647 WHERE "___local_followings_total" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__per_user_following" SET "___local_followings_inc"=32767 WHERE "___local_followings_inc" > 32767`); + await queryRunner.query(`UPDATE "__chart_day__per_user_following" SET "___local_followings_dec"=32767 WHERE "___local_followings_dec" > 32767`); + await queryRunner.query(`UPDATE "__chart_day__per_user_following" SET "___local_followers_total"=2147483647 WHERE "___local_followers_total" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__per_user_following" SET "___local_followers_inc"=32767 WHERE "___local_followers_inc" > 32767`); + await queryRunner.query(`UPDATE "__chart_day__per_user_following" SET "___local_followers_dec"=32767 WHERE "___local_followers_dec" > 32767`); + await queryRunner.query(`UPDATE "__chart_day__per_user_following" SET "___remote_followings_total"=2147483647 WHERE "___remote_followings_total" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__per_user_following" SET "___remote_followings_inc"=32767 WHERE "___remote_followings_inc" > 32767`); + await queryRunner.query(`UPDATE "__chart_day__per_user_following" SET "___remote_followings_dec"=32767 WHERE "___remote_followings_dec" > 32767`); + await queryRunner.query(`UPDATE "__chart_day__per_user_following" SET "___remote_followers_total"=2147483647 WHERE "___remote_followers_total" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__per_user_following" SET "___remote_followers_inc"=32767 WHERE "___remote_followers_inc" > 32767`); + await queryRunner.query(`UPDATE "__chart_day__per_user_following" SET "___remote_followers_dec"=32767 WHERE "___remote_followers_dec" > 32767`); + await queryRunner.query(`UPDATE "__chart__per_user_drive" SET "___totalCount"=2147483647 WHERE "___totalCount" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__per_user_drive" SET "___totalSize"=2147483647 WHERE "___totalSize" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__per_user_drive" SET "___incCount"=32767 WHERE "___incCount" > 32767`); + await queryRunner.query(`UPDATE "__chart__per_user_drive" SET "___incSize"=2147483647 WHERE "___incSize" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__per_user_drive" SET "___decCount"=32767 WHERE "___decCount" > 32767`); + await queryRunner.query(`UPDATE "__chart__per_user_drive" SET "___decSize"=2147483647 WHERE "___decSize" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__per_user_drive" SET "___totalCount"=2147483647 WHERE "___totalCount" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__per_user_drive" SET "___totalSize"=2147483647 WHERE "___totalSize" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__per_user_drive" SET "___incCount"=32767 WHERE "___incCount" > 32767`); + await queryRunner.query(`UPDATE "__chart_day__per_user_drive" SET "___incSize"=2147483647 WHERE "___incSize" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__per_user_drive" SET "___decCount"=32767 WHERE "___decCount" > 32767`); + await queryRunner.query(`UPDATE "__chart_day__per_user_drive" SET "___decSize"=2147483647 WHERE "___decSize" > 2147483647`); + + await queryRunner.query(`ALTER TABLE "__chart__federation" ALTER COLUMN "___instance_total" TYPE integer USING "___instance_total"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__federation" ALTER COLUMN "___instance_inc" TYPE smallint USING "___instance_inc"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart__federation" ALTER COLUMN "___instance_dec" TYPE smallint USING "___instance_dec"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart_day__federation" ALTER COLUMN "___instance_total" TYPE integer USING "___instance_total"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__federation" ALTER COLUMN "___instance_inc" TYPE smallint USING "___instance_inc"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart_day__federation" ALTER COLUMN "___instance_dec" TYPE smallint USING "___instance_dec"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___local_total" TYPE integer USING "___local_total"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___local_inc" TYPE integer USING "___local_inc"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___local_dec" TYPE integer USING "___local_dec"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___local_diffs_normal" TYPE integer USING "___local_diffs_normal"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___local_diffs_reply" TYPE integer USING "___local_diffs_reply"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___local_diffs_renote" TYPE integer USING "___local_diffs_renote"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___remote_total" TYPE integer USING "___remote_total"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___remote_inc" TYPE integer USING "___remote_inc"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___remote_dec" TYPE integer USING "___remote_dec"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___remote_diffs_normal" TYPE integer USING "___remote_diffs_normal"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___remote_diffs_reply" TYPE integer USING "___remote_diffs_reply"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___remote_diffs_renote" TYPE integer USING "___remote_diffs_renote"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___local_total" TYPE integer USING "___local_total"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___local_inc" TYPE integer USING "___local_inc"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___local_dec" TYPE integer USING "___local_dec"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___local_diffs_normal" TYPE integer USING "___local_diffs_normal"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___local_diffs_reply" TYPE integer USING "___local_diffs_reply"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___local_diffs_renote" TYPE integer USING "___local_diffs_renote"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___remote_total" TYPE integer USING "___remote_total"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___remote_inc" TYPE integer USING "___remote_inc"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___remote_dec" TYPE integer USING "___remote_dec"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___remote_diffs_normal" TYPE integer USING "___remote_diffs_normal"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___remote_diffs_reply" TYPE integer USING "___remote_diffs_reply"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___remote_diffs_renote" TYPE integer USING "___remote_diffs_renote"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__users" ALTER COLUMN "___local_total" TYPE integer USING "___local_total"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__users" ALTER COLUMN "___local_inc" TYPE smallint USING "___local_inc"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart__users" ALTER COLUMN "___local_dec" TYPE smallint USING "___local_dec"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart__users" ALTER COLUMN "___remote_total" TYPE integer USING "___remote_total"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__users" ALTER COLUMN "___remote_inc" TYPE smallint USING "___remote_inc"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart__users" ALTER COLUMN "___remote_dec" TYPE smallint USING "___remote_dec"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart_day__users" ALTER COLUMN "___local_total" TYPE integer USING "___local_total"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__users" ALTER COLUMN "___local_inc" TYPE smallint USING "___local_inc"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart_day__users" ALTER COLUMN "___local_dec" TYPE smallint USING "___local_dec"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart_day__users" ALTER COLUMN "___remote_total" TYPE integer USING "___remote_total"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__users" ALTER COLUMN "___remote_inc" TYPE smallint USING "___remote_inc"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart_day__users" ALTER COLUMN "___remote_dec" TYPE smallint USING "___remote_dec"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart__network" ALTER COLUMN "___incomingRequests" TYPE integer USING "___incomingRequests"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__network" ALTER COLUMN "___outgoingRequests" TYPE integer USING "___outgoingRequests"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__network" ALTER COLUMN "___totalTime" TYPE integer USING "___totalTime"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__network" ALTER COLUMN "___incomingBytes" TYPE integer USING "___incomingBytes"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__network" ALTER COLUMN "___outgoingBytes" TYPE integer USING "___outgoingBytes"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__network" ALTER COLUMN "___incomingRequests" TYPE integer USING "___incomingRequests"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__network" ALTER COLUMN "___outgoingRequests" TYPE integer USING "___outgoingRequests"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__network" ALTER COLUMN "___totalTime" TYPE integer USING "___totalTime"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__network" ALTER COLUMN "___incomingBytes" TYPE integer USING "___incomingBytes"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__network" ALTER COLUMN "___outgoingBytes" TYPE integer USING "___outgoingBytes"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___requests_failed" TYPE smallint USING "___requests_failed"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___requests_succeeded" TYPE smallint USING "___requests_succeeded"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___requests_received" TYPE smallint USING "___requests_received"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___notes_total" TYPE integer USING "___notes_total"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___notes_inc" TYPE integer USING "___notes_inc"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___notes_dec" TYPE integer USING "___notes_dec"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___notes_diffs_normal" TYPE integer USING "___notes_diffs_normal"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___notes_diffs_reply" TYPE integer USING "___notes_diffs_reply"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___notes_diffs_renote" TYPE integer USING "___notes_diffs_renote"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___users_total" TYPE integer USING "___users_total"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___users_inc" TYPE smallint USING "___users_inc"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___users_dec" TYPE smallint USING "___users_dec"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___following_total" TYPE integer USING "___following_total"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___following_inc" TYPE smallint USING "___following_inc"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___following_dec" TYPE smallint USING "___following_dec"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___followers_total" TYPE integer USING "___followers_total"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___followers_inc" TYPE smallint USING "___followers_inc"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___followers_dec" TYPE smallint USING "___followers_dec"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___drive_totalFiles" TYPE integer USING "___drive_totalFiles"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___drive_incFiles" TYPE integer USING "___drive_incFiles"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___drive_decFiles" TYPE integer USING "___drive_decFiles"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___drive_incUsage" TYPE integer USING "___drive_incUsage"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___drive_decUsage" TYPE integer USING "___drive_decUsage"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___requests_failed" TYPE smallint USING "___requests_failed"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___requests_succeeded" TYPE smallint USING "___requests_succeeded"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___requests_received" TYPE smallint USING "___requests_received"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___notes_total" TYPE integer USING "___notes_total"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___notes_inc" TYPE integer USING "___notes_inc"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___notes_dec" TYPE integer USING "___notes_dec"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___notes_diffs_normal" TYPE integer USING "___notes_diffs_normal"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___notes_diffs_reply" TYPE integer USING "___notes_diffs_reply"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___notes_diffs_renote" TYPE integer USING "___notes_diffs_renote"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___users_total" TYPE integer USING "___users_total"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___users_inc" TYPE smallint USING "___users_inc"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___users_dec" TYPE smallint USING "___users_dec"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___following_total" TYPE integer USING "___following_total"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___following_inc" TYPE smallint USING "___following_inc"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___following_dec" TYPE smallint USING "___following_dec"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___followers_total" TYPE integer USING "___followers_total"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___followers_inc" TYPE smallint USING "___followers_inc"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___followers_dec" TYPE smallint USING "___followers_dec"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___drive_totalFiles" TYPE integer USING "___drive_totalFiles"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___drive_incFiles" TYPE integer USING "___drive_incFiles"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___drive_decFiles" TYPE integer USING "___drive_decFiles"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___drive_incUsage" TYPE integer USING "___drive_incUsage"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___drive_decUsage" TYPE integer USING "___drive_decUsage"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "___total" TYPE integer USING "___total"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "___inc" TYPE smallint USING "___inc"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "___dec" TYPE smallint USING "___dec"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "___diffs_normal" TYPE smallint USING "___diffs_normal"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "___diffs_reply" TYPE smallint USING "___diffs_reply"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "___diffs_renote" TYPE smallint USING "___diffs_renote"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ALTER COLUMN "___total" TYPE integer USING "___total"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ALTER COLUMN "___inc" TYPE smallint USING "___inc"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ALTER COLUMN "___dec" TYPE smallint USING "___dec"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ALTER COLUMN "___diffs_normal" TYPE smallint USING "___diffs_normal"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ALTER COLUMN "___diffs_reply" TYPE smallint USING "___diffs_reply"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ALTER COLUMN "___diffs_renote" TYPE smallint USING "___diffs_renote"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___local_incCount" TYPE integer USING "___local_incCount"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___local_incSize" TYPE integer USING "___local_incSize"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___local_decCount" TYPE integer USING "___local_decCount"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___local_decSize" TYPE integer USING "___local_decSize"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___remote_incCount" TYPE integer USING "___remote_incCount"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___remote_incSize" TYPE integer USING "___remote_incSize"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___remote_decCount" TYPE integer USING "___remote_decCount"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___remote_decSize" TYPE integer USING "___remote_decSize"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___local_incCount" TYPE integer USING "___local_incCount"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___local_incSize" TYPE integer USING "___local_incSize"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___local_decCount" TYPE integer USING "___local_decCount"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___local_decSize" TYPE integer USING "___local_decSize"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___remote_incCount" TYPE integer USING "___remote_incCount"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___remote_incSize" TYPE integer USING "___remote_incSize"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___remote_decCount" TYPE integer USING "___remote_decCount"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___remote_decSize" TYPE integer USING "___remote_decSize"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_reaction" ALTER COLUMN "___local_count" TYPE smallint USING "___local_count"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_reaction" ALTER COLUMN "___remote_count" TYPE smallint USING "___remote_count"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_reaction" ALTER COLUMN "___local_count" TYPE smallint USING "___local_count"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_reaction" ALTER COLUMN "___remote_count" TYPE smallint USING "___remote_count"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___local_followings_total" TYPE integer USING "___local_followings_total"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___local_followings_inc" TYPE smallint USING "___local_followings_inc"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___local_followings_dec" TYPE smallint USING "___local_followings_dec"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___local_followers_total" TYPE integer USING "___local_followers_total"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___local_followers_inc" TYPE smallint USING "___local_followers_inc"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___local_followers_dec" TYPE smallint USING "___local_followers_dec"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___remote_followings_total" TYPE integer USING "___remote_followings_total"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___remote_followings_inc" TYPE smallint USING "___remote_followings_inc"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___remote_followings_dec" TYPE smallint USING "___remote_followings_dec"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___remote_followers_total" TYPE integer USING "___remote_followers_total"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___remote_followers_inc" TYPE smallint USING "___remote_followers_inc"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___remote_followers_dec" TYPE smallint USING "___remote_followers_dec"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___local_followings_total" TYPE integer USING "___local_followings_total"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___local_followings_inc" TYPE smallint USING "___local_followings_inc"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___local_followings_dec" TYPE smallint USING "___local_followings_dec"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___local_followers_total" TYPE integer USING "___local_followers_total"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___local_followers_inc" TYPE smallint USING "___local_followers_inc"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___local_followers_dec" TYPE smallint USING "___local_followers_dec"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___remote_followings_total" TYPE integer USING "___remote_followings_total"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___remote_followings_inc" TYPE smallint USING "___remote_followings_inc"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___remote_followings_dec" TYPE smallint USING "___remote_followings_dec"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___remote_followers_total" TYPE integer USING "___remote_followers_total"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___remote_followers_inc" TYPE smallint USING "___remote_followers_inc"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___remote_followers_dec" TYPE smallint USING "___remote_followers_dec"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "___totalCount" TYPE integer USING "___totalCount"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "___totalSize" TYPE integer USING "___totalSize"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "___incCount" TYPE smallint USING "___incCount"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "___incSize" TYPE integer USING "___incSize"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "___decCount" TYPE smallint USING "___decCount"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "___decSize" TYPE integer USING "___decSize"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_drive" ALTER COLUMN "___totalCount" TYPE integer USING "___totalCount"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_drive" ALTER COLUMN "___totalSize" TYPE integer USING "___totalSize"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_drive" ALTER COLUMN "___incCount" TYPE smallint USING "___incCount"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_drive" ALTER COLUMN "___incSize" TYPE integer USING "___incSize"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_drive" ALTER COLUMN "___decCount" TYPE smallint USING "___decCount"::smallint`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_drive" ALTER COLUMN "___decSize" TYPE integer USING "___decSize"::integer`); + } + + async down(queryRunner) { + + await queryRunner.query(`ALTER TABLE "__chart__federation" ALTER COLUMN "___instance_total" TYPE bigint USING "___instance_total"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__federation" ALTER COLUMN "___instance_inc" TYPE bigint USING "___instance_inc"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__federation" ALTER COLUMN "___instance_dec" TYPE bigint USING "___instance_dec"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__federation" ALTER COLUMN "___instance_total" TYPE bigint USING "___instance_total"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__federation" ALTER COLUMN "___instance_inc" TYPE bigint USING "___instance_inc"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__federation" ALTER COLUMN "___instance_dec" TYPE bigint USING "___instance_dec"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___local_total" TYPE bigint USING "___local_total"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___local_inc" TYPE bigint USING "___local_inc"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___local_dec" TYPE bigint USING "___local_dec"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___local_diffs_normal" TYPE bigint USING "___local_diffs_normal"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___local_diffs_reply" TYPE bigint USING "___local_diffs_reply"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___local_diffs_renote" TYPE bigint USING "___local_diffs_renote"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___remote_total" TYPE bigint USING "___remote_total"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___remote_inc" TYPE bigint USING "___remote_inc"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___remote_dec" TYPE bigint USING "___remote_dec"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___remote_diffs_normal" TYPE bigint USING "___remote_diffs_normal"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___remote_diffs_reply" TYPE bigint USING "___remote_diffs_reply"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ALTER COLUMN "___remote_diffs_renote" TYPE bigint USING "___remote_diffs_renote"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___local_total" TYPE bigint USING "___local_total"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___local_inc" TYPE bigint USING "___local_inc"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___local_dec" TYPE bigint USING "___local_dec"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___local_diffs_normal" TYPE bigint USING "___local_diffs_normal"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___local_diffs_reply" TYPE bigint USING "___local_diffs_reply"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___local_diffs_renote" TYPE bigint USING "___local_diffs_renote"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___remote_total" TYPE bigint USING "___remote_total"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___remote_inc" TYPE bigint USING "___remote_inc"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___remote_dec" TYPE bigint USING "___remote_dec"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___remote_diffs_normal" TYPE bigint USING "___remote_diffs_normal"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___remote_diffs_reply" TYPE bigint USING "___remote_diffs_reply"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ALTER COLUMN "___remote_diffs_renote" TYPE bigint USING "___remote_diffs_renote"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__users" ALTER COLUMN "___local_total" TYPE bigint USING "___local_total"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__users" ALTER COLUMN "___local_inc" TYPE bigint USING "___local_inc"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__users" ALTER COLUMN "___local_dec" TYPE bigint USING "___local_dec"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__users" ALTER COLUMN "___remote_total" TYPE bigint USING "___remote_total"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__users" ALTER COLUMN "___remote_inc" TYPE bigint USING "___remote_inc"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__users" ALTER COLUMN "___remote_dec" TYPE bigint USING "___remote_dec"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__users" ALTER COLUMN "___local_total" TYPE bigint USING "___local_total"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__users" ALTER COLUMN "___local_inc" TYPE bigint USING "___local_inc"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__users" ALTER COLUMN "___local_dec" TYPE bigint USING "___local_dec"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__users" ALTER COLUMN "___remote_total" TYPE bigint USING "___remote_total"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__users" ALTER COLUMN "___remote_inc" TYPE bigint USING "___remote_inc"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__users" ALTER COLUMN "___remote_dec" TYPE bigint USING "___remote_dec"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__network" ALTER COLUMN "___incomingRequests" TYPE bigint USING "___incomingRequests"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__network" ALTER COLUMN "___outgoingRequests" TYPE bigint USING "___outgoingRequests"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__network" ALTER COLUMN "___totalTime" TYPE bigint USING "___totalTime"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__network" ALTER COLUMN "___incomingBytes" TYPE bigint USING "___incomingBytes"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__network" ALTER COLUMN "___outgoingBytes" TYPE bigint USING "___outgoingBytes"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__network" ALTER COLUMN "___incomingRequests" TYPE bigint USING "___incomingRequests"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__network" ALTER COLUMN "___outgoingRequests" TYPE bigint USING "___outgoingRequests"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__network" ALTER COLUMN "___totalTime" TYPE bigint USING "___totalTime"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__network" ALTER COLUMN "___incomingBytes" TYPE bigint USING "___incomingBytes"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__network" ALTER COLUMN "___outgoingBytes" TYPE bigint USING "___outgoingBytes"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___requests_failed" TYPE bigint USING "___requests_failed"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___requests_succeeded" TYPE bigint USING "___requests_succeeded"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___requests_received" TYPE bigint USING "___requests_received"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___notes_total" TYPE bigint USING "___notes_total"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___notes_inc" TYPE bigint USING "___notes_inc"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___notes_dec" TYPE bigint USING "___notes_dec"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___notes_diffs_normal" TYPE bigint USING "___notes_diffs_normal"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___notes_diffs_reply" TYPE bigint USING "___notes_diffs_reply"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___notes_diffs_renote" TYPE bigint USING "___notes_diffs_renote"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___users_total" TYPE bigint USING "___users_total"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___users_inc" TYPE bigint USING "___users_inc"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___users_dec" TYPE bigint USING "___users_dec"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___following_total" TYPE bigint USING "___following_total"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___following_inc" TYPE bigint USING "___following_inc"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___following_dec" TYPE bigint USING "___following_dec"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___followers_total" TYPE bigint USING "___followers_total"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___followers_inc" TYPE bigint USING "___followers_inc"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___followers_dec" TYPE bigint USING "___followers_dec"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___drive_totalFiles" TYPE bigint USING "___drive_totalFiles"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___drive_incFiles" TYPE bigint USING "___drive_incFiles"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___drive_decFiles" TYPE bigint USING "___drive_decFiles"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___drive_incUsage" TYPE bigint USING "___drive_incUsage"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ALTER COLUMN "___drive_decUsage" TYPE bigint USING "___drive_decUsage"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___requests_failed" TYPE bigint USING "___requests_failed"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___requests_succeeded" TYPE bigint USING "___requests_succeeded"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___requests_received" TYPE bigint USING "___requests_received"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___notes_total" TYPE bigint USING "___notes_total"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___notes_inc" TYPE bigint USING "___notes_inc"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___notes_dec" TYPE bigint USING "___notes_dec"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___notes_diffs_normal" TYPE bigint USING "___notes_diffs_normal"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___notes_diffs_reply" TYPE bigint USING "___notes_diffs_reply"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___notes_diffs_renote" TYPE bigint USING "___notes_diffs_renote"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___users_total" TYPE bigint USING "___users_total"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___users_inc" TYPE bigint USING "___users_inc"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___users_dec" TYPE bigint USING "___users_dec"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___following_total" TYPE bigint USING "___following_total"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___following_inc" TYPE bigint USING "___following_inc"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___following_dec" TYPE bigint USING "___following_dec"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___followers_total" TYPE bigint USING "___followers_total"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___followers_inc" TYPE bigint USING "___followers_inc"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___followers_dec" TYPE bigint USING "___followers_dec"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___drive_totalFiles" TYPE bigint USING "___drive_totalFiles"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___drive_incFiles" TYPE bigint USING "___drive_incFiles"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___drive_decFiles" TYPE bigint USING "___drive_decFiles"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___drive_incUsage" TYPE bigint USING "___drive_incUsage"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ALTER COLUMN "___drive_decUsage" TYPE bigint USING "___drive_decUsage"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "___total" TYPE bigint USING "___total"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "___inc" TYPE bigint USING "___inc"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "___dec" TYPE bigint USING "___dec"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "___diffs_normal" TYPE bigint USING "___diffs_normal"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "___diffs_reply" TYPE bigint USING "___diffs_reply"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ALTER COLUMN "___diffs_renote" TYPE bigint USING "___diffs_renote"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ALTER COLUMN "___total" TYPE bigint USING "___total"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ALTER COLUMN "___inc" TYPE bigint USING "___inc"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ALTER COLUMN "___dec" TYPE bigint USING "___dec"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ALTER COLUMN "___diffs_normal" TYPE bigint USING "___diffs_normal"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ALTER COLUMN "___diffs_reply" TYPE bigint USING "___diffs_reply"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ALTER COLUMN "___diffs_renote" TYPE bigint USING "___diffs_renote"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___local_incCount" TYPE bigint USING "___local_incCount"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___local_incSize" TYPE bigint USING "___local_incSize"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___local_decCount" TYPE bigint USING "___local_decCount"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___local_decSize" TYPE bigint USING "___local_decSize"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___remote_incCount" TYPE bigint USING "___remote_incCount"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___remote_incSize" TYPE bigint USING "___remote_incSize"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___remote_decCount" TYPE bigint USING "___remote_decCount"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__drive" ALTER COLUMN "___remote_decSize" TYPE bigint USING "___remote_decSize"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___local_incCount" TYPE bigint USING "___local_incCount"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___local_incSize" TYPE bigint USING "___local_incSize"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___local_decCount" TYPE bigint USING "___local_decCount"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___local_decSize" TYPE bigint USING "___local_decSize"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___remote_incCount" TYPE bigint USING "___remote_incCount"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___remote_incSize" TYPE bigint USING "___remote_incSize"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___remote_decCount" TYPE bigint USING "___remote_decCount"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__drive" ALTER COLUMN "___remote_decSize" TYPE bigint USING "___remote_decSize"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_reaction" ALTER COLUMN "___local_count" TYPE bigint USING "___local_count"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_reaction" ALTER COLUMN "___remote_count" TYPE bigint USING "___remote_count"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_reaction" ALTER COLUMN "___local_count" TYPE bigint USING "___local_count"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_reaction" ALTER COLUMN "___remote_count" TYPE bigint USING "___remote_count"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___local_followings_total" TYPE bigint USING "___local_followings_total"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___local_followings_inc" TYPE bigint USING "___local_followings_inc"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___local_followings_dec" TYPE bigint USING "___local_followings_dec"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___local_followers_total" TYPE bigint USING "___local_followers_total"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___local_followers_inc" TYPE bigint USING "___local_followers_inc"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___local_followers_dec" TYPE bigint USING "___local_followers_dec"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___remote_followings_total" TYPE bigint USING "___remote_followings_total"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___remote_followings_inc" TYPE bigint USING "___remote_followings_inc"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___remote_followings_dec" TYPE bigint USING "___remote_followings_dec"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___remote_followers_total" TYPE bigint USING "___remote_followers_total"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___remote_followers_inc" TYPE bigint USING "___remote_followers_inc"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ALTER COLUMN "___remote_followers_dec" TYPE bigint USING "___remote_followers_dec"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___local_followings_total" TYPE bigint USING "___local_followings_total"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___local_followings_inc" TYPE bigint USING "___local_followings_inc"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___local_followings_dec" TYPE bigint USING "___local_followings_dec"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___local_followers_total" TYPE bigint USING "___local_followers_total"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___local_followers_inc" TYPE bigint USING "___local_followers_inc"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___local_followers_dec" TYPE bigint USING "___local_followers_dec"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___remote_followings_total" TYPE bigint USING "___remote_followings_total"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___remote_followings_inc" TYPE bigint USING "___remote_followings_inc"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___remote_followings_dec" TYPE bigint USING "___remote_followings_dec"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___remote_followers_total" TYPE bigint USING "___remote_followers_total"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___remote_followers_inc" TYPE bigint USING "___remote_followers_inc"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_following" ALTER COLUMN "___remote_followers_dec" TYPE bigint USING "___remote_followers_dec"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "___totalCount" TYPE bigint USING "___totalCount"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "___totalSize" TYPE bigint USING "___totalSize"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "___incCount" TYPE bigint USING "___incCount"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "___incSize" TYPE bigint USING "___incSize"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "___decCount" TYPE bigint USING "___decCount"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ALTER COLUMN "___decSize" TYPE bigint USING "___decSize"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_drive" ALTER COLUMN "___totalCount" TYPE bigint USING "___totalCount"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_drive" ALTER COLUMN "___totalSize" TYPE bigint USING "___totalSize"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_drive" ALTER COLUMN "___incCount" TYPE bigint USING "___incCount"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_drive" ALTER COLUMN "___incSize" TYPE bigint USING "___incSize"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_drive" ALTER COLUMN "___decCount" TYPE bigint USING "___decCount"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_drive" ALTER COLUMN "___decSize" TYPE bigint USING "___decSize"::bigint`); + } +} diff --git a/packages/backend/migration/1644059847460-chart-v8.js b/packages/backend/migration/1644059847460-chart-v8.js new file mode 100644 index 0000000000000000000000000000000000000000..7c5db0db337c0c0126dab035fdd0afa7d819e708 --- /dev/null +++ b/packages/backend/migration/1644059847460-chart-v8.js @@ -0,0 +1,25 @@ +const { MigrationInterface, QueryRunner } = require("typeorm"); + +module.exports = class chartV81644059847460 { + name = 'chartV81644059847460' + + async up(queryRunner) { + await queryRunner.query(`UPDATE "__chart__active_users" SET "___local_users"=2147483647 WHERE "___local_users" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__active_users" SET "___remote_users"=2147483647 WHERE "___remote_users" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__active_users" SET "___local_users"=2147483647 WHERE "___local_users" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__active_users" SET "___remote_users"=2147483647 WHERE "___remote_users" > 2147483647`); + + await queryRunner.query(`ALTER TABLE "__chart__active_users" ALTER COLUMN "___local_users" TYPE integer USING "___local_users"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" ALTER COLUMN "___remote_users" TYPE integer USING "___remote_users"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ALTER COLUMN "___local_users" TYPE integer USING "___local_users"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ALTER COLUMN "___remote_users" TYPE integer USING "___remote_users"::integer`); + } + + async down(queryRunner) { + + await queryRunner.query(`ALTER TABLE "__chart__active_users" ALTER COLUMN "___local_users" TYPE bigint USING "___local_users"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" ALTER COLUMN "___remote_users" TYPE bigint USING "___remote_users"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ALTER COLUMN "___local_users" TYPE bigint USING "___local_users"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ALTER COLUMN "___remote_users" TYPE bigint USING "___remote_users"::bigint`); + } +} diff --git a/packages/backend/migration/1644060125705-chart-v9.js b/packages/backend/migration/1644060125705-chart-v9.js new file mode 100644 index 0000000000000000000000000000000000000000..bc607067b328a54273672a884abcaf265deaa266 --- /dev/null +++ b/packages/backend/migration/1644060125705-chart-v9.js @@ -0,0 +1,25 @@ +const { MigrationInterface, QueryRunner } = require("typeorm"); + +module.exports = class chartV91644060125705 { + name = 'chartV91644060125705' + + async up(queryRunner) { + await queryRunner.query(`UPDATE "__chart__hashtag" SET "___local_users"=2147483647 WHERE "___local_users" > 2147483647`); + await queryRunner.query(`UPDATE "__chart__hashtag" SET "___remote_users"=2147483647 WHERE "___remote_users" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__hashtag" SET "___local_users"=2147483647 WHERE "___local_users" > 2147483647`); + await queryRunner.query(`UPDATE "__chart_day__hashtag" SET "___remote_users"=2147483647 WHERE "___remote_users" > 2147483647`); + + await queryRunner.query(`ALTER TABLE "__chart__hashtag" ALTER COLUMN "___local_users" TYPE integer USING "___local_users"::integer`); + await queryRunner.query(`ALTER TABLE "__chart__hashtag" ALTER COLUMN "___remote_users" TYPE integer USING "___remote_users"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__hashtag" ALTER COLUMN "___local_users" TYPE integer USING "___local_users"::integer`); + await queryRunner.query(`ALTER TABLE "__chart_day__hashtag" ALTER COLUMN "___remote_users" TYPE integer USING "___remote_users"::integer`); + } + + async down(queryRunner) { + + await queryRunner.query(`ALTER TABLE "__chart__hashtag" ALTER COLUMN "___local_users" TYPE bigint USING "___local_users"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart__hashtag" ALTER COLUMN "___remote_users" TYPE bigint USING "___remote_users"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__hashtag" ALTER COLUMN "___local_users" TYPE bigint USING "___local_users"::bigint`); + await queryRunner.query(`ALTER TABLE "__chart_day__hashtag" ALTER COLUMN "___remote_users" TYPE bigint USING "___remote_users"::bigint`); + } +} diff --git a/packages/backend/migration/1644073149413-chart-v10.js b/packages/backend/migration/1644073149413-chart-v10.js new file mode 100644 index 0000000000000000000000000000000000000000..6ca568718f60d3c15745b053990d7063efca1c5a --- /dev/null +++ b/packages/backend/migration/1644073149413-chart-v10.js @@ -0,0 +1,35 @@ +const { MigrationInterface, QueryRunner } = require("typeorm"); + +module.exports = class chartV101644073149413 { + name = 'chartV101644073149413' + + async up(queryRunner) { + await queryRunner.query(`CREATE TABLE "__chart__ap_request" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "___deliverFailed" integer NOT NULL DEFAULT '0', "___deliverSucceeded" integer NOT NULL DEFAULT '0', "___inboxReceived" integer NOT NULL DEFAULT '0', CONSTRAINT "UQ_e56f4beac5746d44bc3e19c80d0" UNIQUE ("date"), CONSTRAINT "PK_56a25cd447c7ee08876b3baf8d8" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_e56f4beac5746d44bc3e19c80d" ON "__chart__ap_request" ("date") `); + await queryRunner.query(`CREATE TABLE "__chart_day__ap_request" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "___deliverFailed" integer NOT NULL DEFAULT '0', "___deliverSucceeded" integer NOT NULL DEFAULT '0', "___inboxReceived" integer NOT NULL DEFAULT '0', CONSTRAINT "UQ_a848f66d6cec11980a5dd595822" UNIQUE ("date"), CONSTRAINT "PK_9318b49daee320194e23f712e69" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_a848f66d6cec11980a5dd59582" ON "__chart_day__ap_request" ("date") `); + await queryRunner.query(`ALTER TABLE "__chart__federation" ADD "unique_temp___deliveredInstances" character varying array NOT NULL DEFAULT '{}'`); + await queryRunner.query(`ALTER TABLE "__chart__federation" ADD "___deliveredInstances" smallint NOT NULL DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__federation" ADD "unique_temp___inboxInstances" character varying array NOT NULL DEFAULT '{}'`); + await queryRunner.query(`ALTER TABLE "__chart__federation" ADD "___inboxInstances" smallint NOT NULL DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__federation" ADD "unique_temp___deliveredInstances" character varying array NOT NULL DEFAULT '{}'`); + await queryRunner.query(`ALTER TABLE "__chart_day__federation" ADD "___deliveredInstances" smallint NOT NULL DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__federation" ADD "unique_temp___inboxInstances" character varying array NOT NULL DEFAULT '{}'`); + await queryRunner.query(`ALTER TABLE "__chart_day__federation" ADD "___inboxInstances" smallint NOT NULL DEFAULT '0'`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "__chart_day__federation" DROP COLUMN "___inboxInstances"`); + await queryRunner.query(`ALTER TABLE "__chart_day__federation" DROP COLUMN "unique_temp___inboxInstances"`); + await queryRunner.query(`ALTER TABLE "__chart_day__federation" DROP COLUMN "___deliveredInstances"`); + await queryRunner.query(`ALTER TABLE "__chart_day__federation" DROP COLUMN "unique_temp___deliveredInstances"`); + await queryRunner.query(`ALTER TABLE "__chart__federation" DROP COLUMN "___inboxInstances"`); + await queryRunner.query(`ALTER TABLE "__chart__federation" DROP COLUMN "unique_temp___inboxInstances"`); + await queryRunner.query(`ALTER TABLE "__chart__federation" DROP COLUMN "___deliveredInstances"`); + await queryRunner.query(`ALTER TABLE "__chart__federation" DROP COLUMN "unique_temp___deliveredInstances"`); + await queryRunner.query(`DROP INDEX "public"."IDX_a848f66d6cec11980a5dd59582"`); + await queryRunner.query(`DROP TABLE "__chart_day__ap_request"`); + await queryRunner.query(`DROP INDEX "public"."IDX_e56f4beac5746d44bc3e19c80d"`); + await queryRunner.query(`DROP TABLE "__chart__ap_request"`); + } +} diff --git a/packages/backend/migration/1644095659741-chart-v11.js b/packages/backend/migration/1644095659741-chart-v11.js new file mode 100644 index 0000000000000000000000000000000000000000..40b1c3072b831c3ad6fbc3025cc68a7b980dfc2b --- /dev/null +++ b/packages/backend/migration/1644095659741-chart-v11.js @@ -0,0 +1,91 @@ +const { MigrationInterface, QueryRunner } = require("typeorm"); + +module.exports = class chartV111644095659741 { + name = 'chartV111644095659741' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "___local_users"`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "___remote_users"`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "unique_temp___local_users"`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "unique_temp___remote_users"`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "___local_users"`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "___remote_users"`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "unique_temp___local_users"`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "unique_temp___remote_users"`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "unique_temp___users" character varying array NOT NULL DEFAULT '{}'`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "___users" integer NOT NULL DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "unique_temp___notedUsers" character varying array NOT NULL DEFAULT '{}'`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "___notedUsers" smallint NOT NULL DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "unique_temp___registeredWithinWeek" character varying array NOT NULL DEFAULT '{}'`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "___registeredWithinWeek" smallint NOT NULL DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "unique_temp___registeredWithinMonth" character varying array NOT NULL DEFAULT '{}'`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "___registeredWithinMonth" smallint NOT NULL DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "unique_temp___registeredWithinYear" character varying array NOT NULL DEFAULT '{}'`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "___registeredWithinYear" smallint NOT NULL DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "unique_temp___registeredOutsideWeek" character varying array NOT NULL DEFAULT '{}'`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "___registeredOutsideWeek" smallint NOT NULL DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "unique_temp___registeredOutsideMonth" character varying array NOT NULL DEFAULT '{}'`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "___registeredOutsideMonth" smallint NOT NULL DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "unique_temp___registeredOutsideYear" character varying array NOT NULL DEFAULT '{}'`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "___registeredOutsideYear" smallint NOT NULL DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "unique_temp___users" character varying array NOT NULL DEFAULT '{}'`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "___users" integer NOT NULL DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "unique_temp___notedUsers" character varying array NOT NULL DEFAULT '{}'`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "___notedUsers" smallint NOT NULL DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "unique_temp___registeredWithinWeek" character varying array NOT NULL DEFAULT '{}'`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "___registeredWithinWeek" smallint NOT NULL DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "unique_temp___registeredWithinMonth" character varying array NOT NULL DEFAULT '{}'`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "___registeredWithinMonth" smallint NOT NULL DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "unique_temp___registeredWithinYear" character varying array NOT NULL DEFAULT '{}'`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "___registeredWithinYear" smallint NOT NULL DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "unique_temp___registeredOutsideWeek" character varying array NOT NULL DEFAULT '{}'`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "___registeredOutsideWeek" smallint NOT NULL DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "unique_temp___registeredOutsideMonth" character varying array NOT NULL DEFAULT '{}'`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "___registeredOutsideMonth" smallint NOT NULL DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "unique_temp___registeredOutsideYear" character varying array NOT NULL DEFAULT '{}'`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "___registeredOutsideYear" smallint NOT NULL DEFAULT '0'`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "___registeredOutsideYear"`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "unique_temp___registeredOutsideYear"`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "___registeredOutsideMonth"`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "unique_temp___registeredOutsideMonth"`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "___registeredOutsideWeek"`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "unique_temp___registeredOutsideWeek"`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "___registeredWithinYear"`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "unique_temp___registeredWithinYear"`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "___registeredWithinMonth"`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "unique_temp___registeredWithinMonth"`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "___registeredWithinWeek"`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "unique_temp___registeredWithinWeek"`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "___notedUsers"`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "unique_temp___notedUsers"`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "___users"`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "unique_temp___users"`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "___registeredOutsideYear"`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "unique_temp___registeredOutsideYear"`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "___registeredOutsideMonth"`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "unique_temp___registeredOutsideMonth"`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "___registeredOutsideWeek"`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "unique_temp___registeredOutsideWeek"`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "___registeredWithinYear"`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "unique_temp___registeredWithinYear"`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "___registeredWithinMonth"`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "unique_temp___registeredWithinMonth"`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "___registeredWithinWeek"`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "unique_temp___registeredWithinWeek"`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "___notedUsers"`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "unique_temp___notedUsers"`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "___users"`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "unique_temp___users"`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "unique_temp___remote_users" character varying array NOT NULL DEFAULT '{}'`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "unique_temp___local_users" character varying array NOT NULL DEFAULT '{}'`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "___remote_users" integer NOT NULL DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "___local_users" integer NOT NULL DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "unique_temp___remote_users" character varying array NOT NULL DEFAULT '{}'`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "unique_temp___local_users" character varying array NOT NULL DEFAULT '{}'`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "___remote_users" integer NOT NULL DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "___local_users" integer NOT NULL DEFAULT '0'`); + } +} diff --git a/packages/backend/migration/1644328606241-chart-v12.js b/packages/backend/migration/1644328606241-chart-v12.js new file mode 100644 index 0000000000000000000000000000000000000000..226de6ece96262f8e16adb751c962400616dcdd6 --- /dev/null +++ b/packages/backend/migration/1644328606241-chart-v12.js @@ -0,0 +1,27 @@ +const { MigrationInterface, QueryRunner } = require("typeorm"); + +module.exports = class chartV121644328606241 { + name = 'chartV121644328606241' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "__chart__notes" ADD "___local_diffs_withFile" integer NOT NULL DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ADD "___remote_diffs_withFile" integer NOT NULL DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ADD "___local_diffs_withFile" integer NOT NULL DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" ADD "___remote_diffs_withFile" integer NOT NULL DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ADD "___notes_diffs_withFile" integer NOT NULL DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" ADD "___notes_diffs_withFile" integer NOT NULL DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ADD "___diffs_withFile" smallint NOT NULL DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" ADD "___diffs_withFile" smallint NOT NULL DEFAULT '0'`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "__chart_day__per_user_notes" DROP COLUMN "___diffs_withFile"`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" DROP COLUMN "___diffs_withFile"`); + await queryRunner.query(`ALTER TABLE "__chart_day__instance" DROP COLUMN "___notes_diffs_withFile"`); + await queryRunner.query(`ALTER TABLE "__chart__instance" DROP COLUMN "___notes_diffs_withFile"`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" DROP COLUMN "___remote_diffs_withFile"`); + await queryRunner.query(`ALTER TABLE "__chart_day__notes" DROP COLUMN "___local_diffs_withFile"`); + await queryRunner.query(`ALTER TABLE "__chart__notes" DROP COLUMN "___remote_diffs_withFile"`); + await queryRunner.query(`ALTER TABLE "__chart__notes" DROP COLUMN "___local_diffs_withFile"`); + } +} diff --git a/packages/backend/migration/1644331238153-chart-v13.js b/packages/backend/migration/1644331238153-chart-v13.js new file mode 100644 index 0000000000000000000000000000000000000000..ed36659b340b7d6d6cdf875d41ef92e87591a9f2 --- /dev/null +++ b/packages/backend/migration/1644331238153-chart-v13.js @@ -0,0 +1,19 @@ +const { MigrationInterface, QueryRunner } = require("typeorm"); + +module.exports = class chartV131644331238153 { + name = 'chartV131644331238153' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "__chart__federation" ADD "unique_temp___stalled" character varying array NOT NULL DEFAULT '{}'`); + await queryRunner.query(`ALTER TABLE "__chart__federation" ADD "___stalled" smallint NOT NULL DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__federation" ADD "unique_temp___stalled" character varying array NOT NULL DEFAULT '{}'`); + await queryRunner.query(`ALTER TABLE "__chart_day__federation" ADD "___stalled" smallint NOT NULL DEFAULT '0'`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "__chart_day__federation" DROP COLUMN "___stalled"`); + await queryRunner.query(`ALTER TABLE "__chart_day__federation" DROP COLUMN "unique_temp___stalled"`); + await queryRunner.query(`ALTER TABLE "__chart__federation" DROP COLUMN "___stalled"`); + await queryRunner.query(`ALTER TABLE "__chart__federation" DROP COLUMN "unique_temp___stalled"`); + } +} diff --git a/packages/backend/migration/1644344266289-chart-v14.js b/packages/backend/migration/1644344266289-chart-v14.js new file mode 100644 index 0000000000000000000000000000000000000000..8496cc2d42e67453a9d52cd589b558f60c290542 --- /dev/null +++ b/packages/backend/migration/1644344266289-chart-v14.js @@ -0,0 +1,47 @@ +const { MigrationInterface, QueryRunner } = require("typeorm"); + +module.exports = class chartV141644344266289 { + name = 'chartV141644344266289' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "unique_temp___users"`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "___users"`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "unique_temp___notedUsers"`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "___notedUsers"`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "unique_temp___users"`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "___users"`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "unique_temp___notedUsers"`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "___notedUsers"`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "___readWrite" smallint NOT NULL DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "unique_temp___read" character varying array NOT NULL DEFAULT '{}'`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "___read" smallint NOT NULL DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "unique_temp___write" character varying array NOT NULL DEFAULT '{}'`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "___write" smallint NOT NULL DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "___readWrite" smallint NOT NULL DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "unique_temp___read" character varying array NOT NULL DEFAULT '{}'`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "___read" smallint NOT NULL DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "unique_temp___write" character varying array NOT NULL DEFAULT '{}'`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "___write" smallint NOT NULL DEFAULT '0'`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "___write"`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "unique_temp___write"`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "___read"`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "unique_temp___read"`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" DROP COLUMN "___readWrite"`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "___write"`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "unique_temp___write"`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "___read"`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "unique_temp___read"`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "___readWrite"`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "___notedUsers" smallint NOT NULL DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "unique_temp___notedUsers" character varying array NOT NULL DEFAULT '{}'`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "___users" integer NOT NULL DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ADD "unique_temp___users" character varying array NOT NULL DEFAULT '{}'`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "___notedUsers" smallint NOT NULL DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "unique_temp___notedUsers" character varying array NOT NULL DEFAULT '{}'`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "___users" integer NOT NULL DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "unique_temp___users" character varying array NOT NULL DEFAULT '{}'`); + } +} diff --git a/packages/backend/package.json b/packages/backend/package.json index 3541e803f3667e7c916872a240c39b774f6b2f18..d81688cbfe67d928d2741de92130b9fdb418ec4a 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -19,12 +19,11 @@ "@koa/cors": "3.1.0", "@koa/multer": "3.0.0", "@koa/router": "9.0.1", - "@sinonjs/fake-timers": "7.1.2", + "@sinonjs/fake-timers": "9.1.0", "@syuilo/aiscript": "0.11.1", "@types/bcryptjs": "2.4.2", "@types/bull": "3.15.7", "@types/cbor": "6.0.0", - "@types/dateformat": "3.0.1", "@types/escape-regexp": "0.0.1", "@types/glob": "7.2.0", "@types/is-url": "1.2.30", @@ -43,7 +42,7 @@ "@types/koa__multer": "2.0.4", "@types/koa__router": "8.0.11", "@types/mocha": "8.2.3", - "@types/node": "17.0.10", + "@types/node": "17.0.14", "@types/node-fetch": "3.0.3", "@types/nodemailer": "6.4.4", "@types/oauth": "0.9.1", @@ -56,43 +55,40 @@ "@types/ratelimiter": "3.4.3", "@types/redis": "4.0.11", "@types/rename": "1.0.4", - "@types/request-stats": "3.0.0", "@types/sanitize-html": "2.6.2", - "@types/seedrandom": "2.4.28", + "@types/seedrandom": "3.0.1", "@types/sharp": "0.29.5", - "@types/sinonjs__fake-timers": "6.0.4", + "@types/sinonjs__fake-timers": "8.1.1", "@types/speakeasy": "2.0.7", "@types/throttle-debounce": "2.1.0", "@types/tinycolor2": "1.4.3", "@types/tmp": "0.2.3", "@types/uuid": "8.3.4", "@types/web-push": "3.3.2", - "@types/webpack": "5.28.0", - "@types/webpack-stream": "3.2.12", - "@types/websocket": "1.0.4", + "@types/websocket": "1.0.5", "@types/ws": "8.2.2", - "@typescript-eslint/eslint-plugin": "5.10.0", - "@typescript-eslint/parser": "5.10.0", + "@typescript-eslint/eslint-plugin": "5.10.2", + "@typescript-eslint/parser": "5.10.2", "abort-controller": "3.0.0", "archiver": "5.3.0", "autobind-decorator": "2.4.0", "autwh": "0.1.0", - "aws-sdk": "2.1061.0", + "aws-sdk": "2.1067.0", "bcryptjs": "2.4.3", "blurhash": "1.1.4", "broadcast-channel": "4.9.0", - "bull": "4.2.1", + "bull": "4.5.0", "cacheable-lookup": "6.0.4", "cafy": "15.2.1", "cbor": "8.1.0", "chalk": "4.1.2", "cli-highlight": "2.1.11", "content-disposition": "0.5.4", - "crc-32": "1.2.0", - "dateformat": "4.5.1", + "crc-32": "1.2.1", + "date-fns": "2.28.0", "deep-email-validator": "0.1.21", "escape-regexp": "0.0.1", - "eslint": "8.7.0", + "eslint": "8.8.0", "eslint-plugin-import": "2.25.4", "eventemitter3": "4.0.7", "feed": "4.2.2", @@ -105,7 +101,7 @@ "ip-cidr": "3.0.4", "is-svg": "4.3.2", "js-yaml": "4.1.0", - "jsdom": "16.7.0", + "jsdom": "19.0.0", "json5": "2.2.0", "json5-loader": "4.0.1", "jsonld": "5.2.0", @@ -134,7 +130,7 @@ "pg": "8.7.1", "portscanner": "2.2.0", "private-ip": "2.3.3", - "probe-image-size": "7.2.2", + "probe-image-size": "7.2.3", "promise-limit": "2.7.0", "pug": "3.0.2", "punycode": "2.1.1", @@ -147,20 +143,19 @@ "redis-lock": "0.1.4", "reflect-metadata": "0.1.13", "rename": "1.0.4", - "request-stats": "3.0.0", "require-all": "3.0.0", "rndstr": "1.0.0", "s-age": "1.1.2", "sanitize-html": "2.6.1", "seedrandom": "3.0.5", - "sharp": "0.29.3", + "sharp": "0.30.0", "speakeasy": "2.0.0", "strict-event-emitter-types": "2.0.0", "stringz": "2.1.0", "style-loader": "3.3.1", "summaly": "2.5.0", "syslog-pro": "1.0.0", - "systeminformation": "5.9.9", + "systeminformation": "5.11.0", "throttle-debounce": "3.0.1", "tinycolor2": "1.4.2", "tmp": "0.2.1", diff --git a/packages/backend/@types/hcaptcha.d.ts b/packages/backend/src/@types/hcaptcha.d.ts similarity index 100% rename from packages/backend/@types/hcaptcha.d.ts rename to packages/backend/src/@types/hcaptcha.d.ts diff --git a/packages/backend/@types/http-signature.d.ts b/packages/backend/src/@types/http-signature.d.ts similarity index 100% rename from packages/backend/@types/http-signature.d.ts rename to packages/backend/src/@types/http-signature.d.ts diff --git a/packages/backend/@types/jsrsasign.d.ts b/packages/backend/src/@types/jsrsasign.d.ts similarity index 100% rename from packages/backend/@types/jsrsasign.d.ts rename to packages/backend/src/@types/jsrsasign.d.ts diff --git a/packages/backend/@types/koa-json-body.d.ts b/packages/backend/src/@types/koa-json-body.d.ts similarity index 100% rename from packages/backend/@types/koa-json-body.d.ts rename to packages/backend/src/@types/koa-json-body.d.ts diff --git a/packages/backend/@types/koa-slow.d.ts b/packages/backend/src/@types/koa-slow.d.ts similarity index 100% rename from packages/backend/@types/koa-slow.d.ts rename to packages/backend/src/@types/koa-slow.d.ts diff --git a/packages/backend/@types/langmap.d.ts b/packages/backend/src/@types/langmap.d.ts similarity index 100% rename from packages/backend/@types/langmap.d.ts rename to packages/backend/src/@types/langmap.d.ts diff --git a/packages/backend/@types/os-utils.d.ts b/packages/backend/src/@types/os-utils.d.ts similarity index 100% rename from packages/backend/@types/os-utils.d.ts rename to packages/backend/src/@types/os-utils.d.ts diff --git a/packages/backend/@types/package.json.d.ts b/packages/backend/src/@types/package.json.d.ts similarity index 100% rename from packages/backend/@types/package.json.d.ts rename to packages/backend/src/@types/package.json.d.ts diff --git a/packages/backend/@types/probe-image-size.d.ts b/packages/backend/src/@types/probe-image-size.d.ts similarity index 100% rename from packages/backend/@types/probe-image-size.d.ts rename to packages/backend/src/@types/probe-image-size.d.ts diff --git a/packages/backend/src/mfm/from-html.ts b/packages/backend/src/mfm/from-html.ts index fc6d3b3062fc0c13b544dc371dfdf77d047a40c6..21e5ebb7a156e79c83834a05742c450254671d7b 100644 --- a/packages/backend/src/mfm/from-html.ts +++ b/packages/backend/src/mfm/from-html.ts @@ -5,9 +5,7 @@ import { URL } from 'url'; const urlRegex = /^https?:\/\/[\w\/:%#@$&?!()\[\]~.,=+\-]+/; const urlRegexFull = /^https?:\/\/[\w\/:%#@$&?!()\[\]~.,=+\-]+$/; -export function fromHtml(html: string, hashtagNames?: string[]): string | null { - if (html == null) return null; - +export function fromHtml(html: string, hashtagNames?: string[]): string { const dom = parse5.parseFragment(html); let text = ''; diff --git a/packages/backend/src/misc/before-shutdown.ts b/packages/backend/src/misc/before-shutdown.ts index 33abf5fb4d95f7118699744cec23f77d4907b3df..93ac7a1f399e29f96ad348fb98414df5b24739b0 100644 --- a/packages/backend/src/misc/before-shutdown.ts +++ b/packages/backend/src/misc/before-shutdown.ts @@ -24,14 +24,14 @@ const SHUTDOWN_TIMEOUT = 15000; * down the process. * @type {BeforeShutdownListener[]} */ -const shutdownListeners = []; +const shutdownListeners: ((signalOrEvent: string) => void)[] = []; /** * Listen for signals and execute given `fn` function once. * @param {string[]} signals System signals to listen to. * @param {function(string)} fn Function to execute on shutdown. */ -const processOnce = (signals, fn) => { +const processOnce = (signals: string[], fn: (signalOrEvent: string) => void) => { for (const sig of signals) { process.once(sig, fn); } @@ -41,7 +41,7 @@ const processOnce = (signals, fn) => { * Sets a forced shutdown mechanism that will exit the process after `timeout` milliseconds. * @param {number} timeout Time to wait before forcing shutdown (milliseconds) */ -const forceExitAfter = timeout => () => { +const forceExitAfter = (timeout: number) => () => { setTimeout(() => { // Force shutdown after timeout console.warn(`Could not close resources gracefully after ${timeout}ms: forcing shutdown`); @@ -55,7 +55,7 @@ const forceExitAfter = timeout => () => { * be logged out as a warning, but won't prevent other callbacks from executing. * @param {string} signalOrEvent The exit signal or event name received on the process. */ -async function shutdownHandler(signalOrEvent) { +async function shutdownHandler(signalOrEvent: string) { if (process.env.NODE_ENV === 'test') return process.exit(0); console.warn(`Shutting down: received [${signalOrEvent}] signal`); @@ -64,7 +64,9 @@ async function shutdownHandler(signalOrEvent) { try { await listener(signalOrEvent); } catch (err) { - console.warn(`A shutdown handler failed before completing with: ${err.message || err}`); + if (err instanceof Error) { + console.warn(`A shutdown handler failed before completing with: ${err.message || err}`); + } } } @@ -78,7 +80,7 @@ async function shutdownHandler(signalOrEvent) { * @param {BeforeShutdownListener} listener The shutdown listener to register. * @returns {BeforeShutdownListener} Echoes back the supplied `listener`. */ -export function beforeShutdown(listener) { +export function beforeShutdown(listener: () => void) { shutdownListeners.push(listener); return listener; } diff --git a/packages/backend/src/misc/download-url.ts b/packages/backend/src/misc/download-url.ts index 8e1f7b9e249d86436b01e8634cc505d76cb1ed2e..ba2fa9fae07b1959c355357fb33d210965dff1ac 100644 --- a/packages/backend/src/misc/download-url.ts +++ b/packages/backend/src/misc/download-url.ts @@ -38,7 +38,9 @@ export async function downloadUrl(url: string, path: string): Promise<void> { https: httpsAgent, }, http2: false, // default - retry: 0, + retry: { + limit: 0, + }, }).on('response', (res: Got.Response) => { if ((process.env.NODE_ENV === 'production' || process.env.NODE_ENV === 'test') && !config.proxy && res.ip) { if (isPrivateIp(res.ip)) { @@ -75,7 +77,7 @@ export async function downloadUrl(url: string, path: string): Promise<void> { logger.succ(`Download finished: ${chalk.cyan(url)}`); } -function isPrivateIp(ip: string) { +function isPrivateIp(ip: string): boolean { for (const net of config.allowedPrivateNetworks || []) { const cidr = new IPCIDR(net); if (cidr.contains(ip)) { diff --git a/packages/backend/src/misc/gen-identicon.ts b/packages/backend/src/misc/gen-identicon.ts index 5cedd7afaf8e532ef2f09dbd44084fa0caceefcc..fca67fcf21c94ea48445c1fae6e78dfe4e5f6f87 100644 --- a/packages/backend/src/misc/gen-identicon.ts +++ b/packages/backend/src/misc/gen-identicon.ts @@ -39,7 +39,7 @@ const sideN = Math.floor(n / 2); */ export function genIdenticon(seed: string, stream: WriteStream): Promise<void> { const rand = gen.create(seed); - const canvas = p.make(size, size); + const canvas = p.make(size, size, undefined); const ctx = canvas.getContext('2d'); ctx.fillStyle = bg; diff --git a/packages/backend/src/misc/is-duplicate-key-value-error.ts b/packages/backend/src/misc/is-duplicate-key-value-error.ts index 23d8ceb1b7592ed722080f64b3c33c190395c039..04ff191e41339f6a0f97cbbb307d20f05fb4bda2 100644 --- a/packages/backend/src/misc/is-duplicate-key-value-error.ts +++ b/packages/backend/src/misc/is-duplicate-key-value-error.ts @@ -1,3 +1,3 @@ -export function isDuplicateKeyValueError(e: Error): boolean { - return e.message.startsWith('duplicate key value'); +export function isDuplicateKeyValueError(e: unknown | Error): boolean { + return (e as any).message && (e as Error).message.startsWith('duplicate key value'); } diff --git a/packages/backend/src/models/entities/user.ts b/packages/backend/src/models/entities/user.ts index 0aa01ba00a7da1fc99152d5cef18c989364acaf0..e4d9a3ced9faf0b73bc2380ef30a05b66940ef1c 100644 --- a/packages/backend/src/models/entities/user.ts +++ b/packages/backend/src/models/entities/user.ts @@ -225,6 +225,12 @@ export class User { }) public followersUri: string | null; + @Column('boolean', { + default: false, + comment: 'Whether to show users replying to other users in the timeline' + }) + public showTimelineReplies: boolean; + @Index({ unique: true }) @Column('char', { length: 16, nullable: true, unique: true, diff --git a/packages/backend/src/models/repositories/abuse-user-report.ts b/packages/backend/src/models/repositories/abuse-user-report.ts index 943b65eb647d63c30d66569564ab61c71804433d..144195855b071211fc25871868e61586f413c163 100644 --- a/packages/backend/src/models/repositories/abuse-user-report.ts +++ b/packages/backend/src/models/repositories/abuse-user-report.ts @@ -12,7 +12,7 @@ export class AbuseUserReportRepository extends Repository<AbuseUserReport> { return await awaitAll({ id: report.id, - createdAt: report.createdAt, + createdAt: report.createdAt.toISOString(), comment: report.comment, resolved: report.resolved, reporterId: report.reporterId, diff --git a/packages/backend/src/models/repositories/moderation-logs.ts b/packages/backend/src/models/repositories/moderation-logs.ts index 1585d5bfcf236aefc4fd79b311929e56dccb936b..f530613bcc89ca7611f735d655e9ea020217c10a 100644 --- a/packages/backend/src/models/repositories/moderation-logs.ts +++ b/packages/backend/src/models/repositories/moderation-logs.ts @@ -12,7 +12,7 @@ export class ModerationLogRepository extends Repository<ModerationLog> { return await awaitAll({ id: log.id, - createdAt: log.createdAt, + createdAt: log.createdAt.toISOString(), type: log.type, info: log.info, userId: log.userId, diff --git a/packages/backend/src/models/repositories/note-favorite.ts b/packages/backend/src/models/repositories/note-favorite.ts index c5de55c0c0e81e846858ea2a728d157468924309..f4cd64e39397f3dcf57b2eb622fbf7fdd29fa2c5 100644 --- a/packages/backend/src/models/repositories/note-favorite.ts +++ b/packages/backend/src/models/repositories/note-favorite.ts @@ -13,7 +13,7 @@ export class NoteFavoriteRepository extends Repository<NoteFavorite> { return { id: favorite.id, - createdAt: favorite.createdAt, + createdAt: favorite.createdAt.toISOString(), noteId: favorite.noteId, note: await Notes.pack(favorite.note || favorite.noteId, me), }; diff --git a/packages/backend/src/models/repositories/user.ts b/packages/backend/src/models/repositories/user.ts index 2b8398832dfd54d3f7486ddc925b93071554d8ea..33b2b32fee01d7ce15b44cd270c639b9bcc463de 100644 --- a/packages/backend/src/models/repositories/user.ts +++ b/packages/backend/src/models/repositories/user.ts @@ -220,6 +220,7 @@ export class UserRepository extends Repository<User> { isModerator: user.isModerator || falsy, isBot: user.isBot || falsy, isCat: user.isCat || falsy, + showTimelineReplies: user.showTimelineReplies || falsy, instance: user.host ? Instances.findOne({ host: user.host }).then(instance => instance ? { name: instance.name, softwareName: instance.softwareName, diff --git a/packages/backend/src/queue/index.ts b/packages/backend/src/queue/index.ts index f9994c3b59c241a4a8663e1325b5152dc98ff26d..16acabfbf849ffb9ede57ec2a5cfceab5bffc2bd 100644 --- a/packages/backend/src/queue/index.ts +++ b/packages/backend/src/queue/index.ts @@ -6,7 +6,8 @@ import { envOption } from '../env'; import processDeliver from './processors/deliver'; import processInbox from './processors/inbox'; import processDb from './processors/db/index'; -import procesObjectStorage from './processors/object-storage/index'; +import processObjectStorage from './processors/object-storage/index'; +import processSystemQueue from './processors/system/index'; import { queueLogger } from './logger'; import { DriveFile } from '@/models/entities/drive-file'; import { getJobInfo } from './get-job-info'; @@ -255,12 +256,19 @@ export default function() { deliverQueue.process(config.deliverJobConcurrency || 128, processDeliver); inboxQueue.process(config.inboxJobConcurrency || 16, processInbox); processDb(dbQueue); - procesObjectStorage(objectStorageQueue); + processObjectStorage(objectStorageQueue); systemQueue.add('resyncCharts', { }, { repeat: { cron: '0 0 * * *' }, }); + + systemQueue.add('cleanCharts', { + }, { + repeat: { cron: '0 0 * * *' }, + }); + + processSystemQueue(systemQueue); } export function destroy() { diff --git a/packages/backend/src/queue/processors/db/export-blocking.ts b/packages/backend/src/queue/processors/db/export-blocking.ts index 01edaaeb630d3d4654e81309fbed779e5b7a0a2d..f4de9ce0056b0f6a33a84e755a26829dee95803c 100644 --- a/packages/backend/src/queue/processors/db/export-blocking.ts +++ b/packages/backend/src/queue/processors/db/export-blocking.ts @@ -4,7 +4,7 @@ import * as fs from 'fs'; import { queueLogger } from '../../logger'; import { addFile } from '@/services/drive/add-file'; -import * as dateFormat from 'dateformat'; +import { format as dateFormat } from 'date-fns'; import { getFullApAccount } from '@/misc/convert-host'; import { Users, Blockings } from '@/models/index'; import { MoreThan } from 'typeorm'; @@ -85,7 +85,7 @@ export async function exportBlocking(job: Bull.Job<DbUserJobData>, done: any): P stream.end(); logger.succ(`Exported to: ${path}`); - const fileName = 'blocking-' + dateFormat(new Date(), 'yyyy-mm-dd-HH-MM-ss') + '.csv'; + const fileName = 'blocking-' + dateFormat(new Date(), 'yyyy-MM-dd-HH-mm-ss') + '.csv'; const driveFile = await addFile({ user, path, name: fileName, force: true }); logger.succ(`Exported to: ${driveFile.id}`); diff --git a/packages/backend/src/queue/processors/db/export-custom-emojis.ts b/packages/backend/src/queue/processors/db/export-custom-emojis.ts index 240a542fecb11762000044f50b51ad5a1e40f79a..2f7505f1589c4f1798ee952c006d4e80db0e7727 100644 --- a/packages/backend/src/queue/processors/db/export-custom-emojis.ts +++ b/packages/backend/src/queue/processors/db/export-custom-emojis.ts @@ -7,7 +7,7 @@ const mime = require('mime-types'); const archiver = require('archiver'); import { queueLogger } from '../../logger'; import { addFile } from '@/services/drive/add-file'; -import * as dateFormat from 'dateformat'; +import { format as dateFormat } from 'date-fns'; import { Users, Emojis } from '@/models/index'; import { } from '@/queue/types'; import { downloadUrl } from '@/misc/download-url'; @@ -110,7 +110,7 @@ export async function exportCustomEmojis(job: Bull.Job, done: () => void): Promi archiveStream.on('close', async () => { logger.succ(`Exported to: ${archivePath}`); - const fileName = 'custom-emojis-' + dateFormat(new Date(), 'yyyy-mm-dd-HH-MM-ss') + '.zip'; + const fileName = 'custom-emojis-' + dateFormat(new Date(), 'yyyy-MM-dd-HH-mm-ss') + '.zip'; const driveFile = await addFile({ user, path: archivePath, name: fileName, force: true }); logger.succ(`Exported to: ${driveFile.id}`); diff --git a/packages/backend/src/queue/processors/db/export-following.ts b/packages/backend/src/queue/processors/db/export-following.ts index 06572acec1ffbbfeb95454265be2f2bdc7fec31e..2ac558381b68445de8d18fb68b97f3b991c1aa61 100644 --- a/packages/backend/src/queue/processors/db/export-following.ts +++ b/packages/backend/src/queue/processors/db/export-following.ts @@ -4,7 +4,7 @@ import * as fs from 'fs'; import { queueLogger } from '../../logger'; import { addFile } from '@/services/drive/add-file'; -import * as dateFormat from 'dateformat'; +import { format as dateFormat } from 'date-fns'; import { getFullApAccount } from '@/misc/convert-host'; import { Users, Followings, Mutings } from '@/models/index'; import { In, MoreThan, Not } from 'typeorm'; @@ -86,7 +86,7 @@ export async function exportFollowing(job: Bull.Job<DbUserJobData>, done: () => stream.end(); logger.succ(`Exported to: ${path}`); - const fileName = 'following-' + dateFormat(new Date(), 'yyyy-mm-dd-HH-MM-ss') + '.csv'; + const fileName = 'following-' + dateFormat(new Date(), 'yyyy-MM-dd-HH-mm-ss') + '.csv'; const driveFile = await addFile({ user, path, name: fileName, force: true }); logger.succ(`Exported to: ${driveFile.id}`); diff --git a/packages/backend/src/queue/processors/db/export-mute.ts b/packages/backend/src/queue/processors/db/export-mute.ts index 4a856f8ef93c641b146e32865bed36623f73218e..9e917ccbf3424f6fa4723bf2c6515b9d4ede27b9 100644 --- a/packages/backend/src/queue/processors/db/export-mute.ts +++ b/packages/backend/src/queue/processors/db/export-mute.ts @@ -4,7 +4,7 @@ import * as fs from 'fs'; import { queueLogger } from '../../logger'; import { addFile } from '@/services/drive/add-file'; -import * as dateFormat from 'dateformat'; +import { format as dateFormat } from 'date-fns'; import { getFullApAccount } from '@/misc/convert-host'; import { Users, Mutings } from '@/models/index'; import { MoreThan } from 'typeorm'; @@ -85,7 +85,7 @@ export async function exportMute(job: Bull.Job<DbUserJobData>, done: any): Promi stream.end(); logger.succ(`Exported to: ${path}`); - const fileName = 'mute-' + dateFormat(new Date(), 'yyyy-mm-dd-HH-MM-ss') + '.csv'; + const fileName = 'mute-' + dateFormat(new Date(), 'yyyy-MM-dd-HH-mm-ss') + '.csv'; const driveFile = await addFile({ user, path, name: fileName, force: true }); logger.succ(`Exported to: ${driveFile.id}`); diff --git a/packages/backend/src/queue/processors/db/export-notes.ts b/packages/backend/src/queue/processors/db/export-notes.ts index 305abf44cf0c3a76655b29fad8094cd1a0ce34fc..0e65cb88492baf4febdc8f2206cfc8d0fa5603fb 100644 --- a/packages/backend/src/queue/processors/db/export-notes.ts +++ b/packages/backend/src/queue/processors/db/export-notes.ts @@ -4,7 +4,7 @@ import * as fs from 'fs'; import { queueLogger } from '../../logger'; import { addFile } from '@/services/drive/add-file'; -import * as dateFormat from 'dateformat'; +import { format as dateFormat } from 'date-fns'; import { Users, Notes, Polls } from '@/models/index'; import { MoreThan } from 'typeorm'; import { Note } from '@/models/entities/note'; @@ -94,7 +94,7 @@ export async function exportNotes(job: Bull.Job<DbUserJobData>, done: any): Prom stream.end(); logger.succ(`Exported to: ${path}`); - const fileName = 'notes-' + dateFormat(new Date(), 'yyyy-mm-dd-HH-MM-ss') + '.json'; + const fileName = 'notes-' + dateFormat(new Date(), 'yyyy-MM-dd-HH-mm-ss') + '.json'; const driveFile = await addFile({ user, path, name: fileName, force: true }); logger.succ(`Exported to: ${driveFile.id}`); diff --git a/packages/backend/src/queue/processors/db/export-user-lists.ts b/packages/backend/src/queue/processors/db/export-user-lists.ts index f907cf9526e4200c5639062757f1a8098d1dfcf3..fcd2ba336c8064030db78b81c370190a68a1a37c 100644 --- a/packages/backend/src/queue/processors/db/export-user-lists.ts +++ b/packages/backend/src/queue/processors/db/export-user-lists.ts @@ -4,7 +4,7 @@ import * as fs from 'fs'; import { queueLogger } from '../../logger'; import { addFile } from '@/services/drive/add-file'; -import * as dateFormat from 'dateformat'; +import { format as dateFormat } from 'date-fns'; import { getFullApAccount } from '@/misc/convert-host'; import { Users, UserLists, UserListJoinings } from '@/models/index'; import { In } from 'typeorm'; @@ -62,7 +62,7 @@ export async function exportUserLists(job: Bull.Job<DbUserJobData>, done: any): stream.end(); logger.succ(`Exported to: ${path}`); - const fileName = 'user-lists-' + dateFormat(new Date(), 'yyyy-mm-dd-HH-MM-ss') + '.csv'; + const fileName = 'user-lists-' + dateFormat(new Date(), 'yyyy-MM-dd-HH-mm-ss') + '.csv'; const driveFile = await addFile({ user, path, name: fileName, force: true }); logger.succ(`Exported to: ${driveFile.id}`); diff --git a/packages/backend/src/queue/processors/db/import-custom-emojis.ts b/packages/backend/src/queue/processors/db/import-custom-emojis.ts index 04e93671edff374865a7f9706a67cd708d98ffe0..b6c012653429ebd4b14f84889ba0f40c33e42d9c 100644 --- a/packages/backend/src/queue/processors/db/import-custom-emojis.ts +++ b/packages/backend/src/queue/processors/db/import-custom-emojis.ts @@ -41,7 +41,9 @@ export async function importCustomEmojis(job: Bull.Job<DbUserImportJobData>, don fs.writeFileSync(destPath, '', 'binary'); await downloadUrl(file.url, destPath); } catch (e) { // TODO: 何度ã‹å†è©¦è¡Œ - logger.error(e); + if (e instanceof Error || typeof e === 'string') { + logger.error(e); + } throw e; } diff --git a/packages/backend/src/queue/processors/db/import-user-lists.ts b/packages/backend/src/queue/processors/db/import-user-lists.ts index e060e86dd80fa38c86894cb71c8fcf164d04ba42..9b3c0ed60eef00d2a4d389a299d3ee8d52753f6b 100644 --- a/packages/backend/src/queue/processors/db/import-user-lists.ts +++ b/packages/backend/src/queue/processors/db/import-user-lists.ts @@ -51,7 +51,6 @@ export async function importUserLists(job: Bull.Job<DbUserImportJobData>, done: createdAt: new Date(), userId: user.id, name: listName, - userIds: [], }).then(x => UserLists.findOneOrFail(x.identifiers[0])); } @@ -67,9 +66,9 @@ export async function importUserLists(job: Bull.Job<DbUserImportJobData>, done: target = await resolveUser(username, host); } - if (await UserListJoinings.findOne({ userListId: list.id, userId: target.id }) != null) continue; + if (await UserListJoinings.findOne({ userListId: list!.id, userId: target.id }) != null) continue; - pushUserToUserList(target, list); + pushUserToUserList(target, list!); } catch (e) { logger.warn(`Error in line:${linenum} ${e}`); } diff --git a/packages/backend/src/queue/processors/deliver.ts b/packages/backend/src/queue/processors/deliver.ts index 46aeb8cb7ee6bc3dade64d68f630f20a297b58d6..bd91dfc3b57255644f5e0dcc0c6c755f763238c8 100644 --- a/packages/backend/src/queue/processors/deliver.ts +++ b/packages/backend/src/queue/processors/deliver.ts @@ -4,7 +4,7 @@ import request from '@/remote/activitypub/request'; import { registerOrFetchInstanceDoc } from '@/services/register-or-fetch-instance-doc'; import Logger from '@/services/logger'; import { Instances } from '@/models/index'; -import { instanceChart } from '@/services/chart/index'; +import { apRequestChart, federationChart, instanceChart } from '@/services/chart/index'; import { fetchInstanceMetadata } from '@/services/fetch-instance-metadata'; import { fetchMeta } from '@/misc/fetch-meta'; import { toPuny } from '@/misc/convert-host'; @@ -61,6 +61,8 @@ export default async (job: Bull.Job<DeliverJobData>) => { fetchInstanceMetadata(i); instanceChart.requestSent(i.host, true); + apRequestChart.deliverSucc(); + federationChart.deliverd(i.host, true); }); return 'Success'; @@ -74,6 +76,8 @@ export default async (job: Bull.Job<DeliverJobData>) => { }); instanceChart.requestSent(i.host, false); + apRequestChart.deliverFail(); + federationChart.deliverd(i.host, false); }); if (res instanceof StatusError) { diff --git a/packages/backend/src/queue/processors/inbox.ts b/packages/backend/src/queue/processors/inbox.ts index bfdebc007732d5e5b694dcd937cb2a0aea11c3f4..c189256c335682a238a25d2464d6181b89eebcfc 100644 --- a/packages/backend/src/queue/processors/inbox.ts +++ b/packages/backend/src/queue/processors/inbox.ts @@ -5,7 +5,7 @@ import perform from '@/remote/activitypub/perform'; import Logger from '@/services/logger'; import { registerOrFetchInstanceDoc } from '@/services/register-or-fetch-instance-doc'; import { Instances } from '@/models/index'; -import { instanceChart } from '@/services/chart/index'; +import { apRequestChart, federationChart, instanceChart } from '@/services/chart/index'; import { fetchMeta } from '@/misc/fetch-meta'; import { toPuny, extractDbHost } from '@/misc/convert-host'; import { getApId } from '@/remote/activitypub/type'; @@ -54,10 +54,12 @@ export default async (job: Bull.Job<InboxJobData>): Promise<string> => { authUser = await dbResolver.getAuthUserFromApId(getApId(activity.actor)); } catch (e) { // 対象ãŒ4xxãªã‚‰ã‚¹ã‚ップ - if (e instanceof StatusError && e.isClientError) { - return `skip: Ignored deleted actors on both ends ${activity.actor} - ${e.statusCode}`; + if (e instanceof StatusError) { + if (e.isClientError) { + 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}`; } } @@ -141,6 +143,8 @@ export default async (job: Bull.Job<InboxJobData>): Promise<string> => { fetchInstanceMetadata(i); instanceChart.requestReceived(i.host); + apRequestChart.inbox(); + federationChart.inbox(i.host); }); // ã‚¢ã‚¯ãƒ†ã‚£ãƒ“ãƒ†ã‚£ã‚’å‡¦ç† diff --git a/packages/backend/src/queue/processors/system/clean-charts.ts b/packages/backend/src/queue/processors/system/clean-charts.ts new file mode 100644 index 0000000000000000000000000000000000000000..3ae0f495f8f2c3dbf7e1d16425e18a6a547e0e19 --- /dev/null +++ b/packages/backend/src/queue/processors/system/clean-charts.ts @@ -0,0 +1,28 @@ +import * as Bull from 'bull'; + +import { queueLogger } from '../../logger'; +import { activeUsersChart, driveChart, federationChart, hashtagChart, instanceChart, notesChart, perUserDriveChart, perUserFollowingChart, perUserNotesChart, perUserReactionsChart, usersChart, apRequestChart } from '@/services/chart/index'; + +const logger = queueLogger.createSubLogger('clean-charts'); + +export async function cleanCharts(job: Bull.Job<Record<string, unknown>>, done: any): Promise<void> { + logger.info(`Clean charts...`); + + await Promise.all([ + federationChart.clean(), + notesChart.clean(), + usersChart.clean(), + activeUsersChart.clean(), + instanceChart.clean(), + perUserNotesChart.clean(), + driveChart.clean(), + perUserReactionsChart.clean(), + hashtagChart.clean(), + perUserFollowingChart.clean(), + perUserDriveChart.clean(), + apRequestChart.clean(), + ]); + + logger.succ(`All charts successfully cleaned.`); + done(); +} diff --git a/packages/backend/src/queue/processors/system/index.ts b/packages/backend/src/queue/processors/system/index.ts index 8460ea0a9b4280886e433297d33cd120fd6c5df3..636fefc4025c923bffa31f5d6dab37ca0c70c862 100644 --- a/packages/backend/src/queue/processors/system/index.ts +++ b/packages/backend/src/queue/processors/system/index.ts @@ -1,8 +1,10 @@ import * as Bull from 'bull'; import { resyncCharts } from './resync-charts'; +import { cleanCharts } from './clean-charts'; const jobs = { resyncCharts, + cleanCharts, } as Record<string, Bull.ProcessCallbackFunction<Record<string, unknown>> | Bull.ProcessPromiseFunction<Record<string, unknown>>>; export default function(dbQueue: Bull.Queue<Record<string, unknown>>) { diff --git a/packages/backend/src/remote/activitypub/kernel/announce/note.ts b/packages/backend/src/remote/activitypub/kernel/announce/note.ts index e9158f77526eea31d72fc3da2dc60f1111552973..eae92d4180a55f63268d7f64ec357be899df613b 100644 --- a/packages/backend/src/remote/activitypub/kernel/announce/note.ts +++ b/packages/backend/src/remote/activitypub/kernel/announce/note.ts @@ -42,11 +42,14 @@ export default async function(resolver: Resolver, actor: IRemoteUser, activity: renote = await resolveNote(targetUri); } catch (e) { // 対象ãŒ4xxãªã‚‰ã‚¹ã‚ップ - if (e instanceof StatusError && e.isClientError) { - logger.warn(`Ignored announce target ${targetUri} - ${e.statusCode}`); - return; + if (e instanceof StatusError) { + if (e.isClientError) { + logger.warn(`Ignored announce target ${targetUri} - ${e.statusCode}`); + return; + } + + logger.warn(`Error in announce target ${targetUri} - ${e.statusCode || e}`); } - logger.warn(`Error in announce target ${targetUri} - ${e.statusCode || e}`); throw e; } diff --git a/packages/backend/src/remote/activitypub/kernel/flag/index.ts b/packages/backend/src/remote/activitypub/kernel/flag/index.ts index aec6d2daaa7615116d1b7d9808e169561cde32eb..d910e2ebe239c9acd5ed60bdd3eb8f2bd572390e 100644 --- a/packages/backend/src/remote/activitypub/kernel/flag/index.ts +++ b/packages/backend/src/remote/activitypub/kernel/flag/index.ts @@ -10,7 +10,7 @@ export default async (actor: IRemoteUser, activity: IFlag): Promise<string> => { // 対象ユーザーã¯ä¸€ç•ªæœ€åˆã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ ã¨ã—㦠ã‚ã¨ã¯ã‚³ãƒ¡ãƒ³ãƒˆã¨ã—ã¦æ ¼ç´ã™ã‚‹ const uris = getApIds(activity.object); - const userIds = uris.filter(uri => uri.startsWith(config.url + '/users/')).map(uri => uri.split('/').pop()); + const userIds = uris.filter(uri => uri.startsWith(config.url + '/users/')).map(uri => uri.split('/').pop()!); const users = await Users.find({ id: In(userIds), }); diff --git a/packages/backend/src/remote/activitypub/kernel/index.ts b/packages/backend/src/remote/activitypub/kernel/index.ts index 20df28eec62455bdf8df61b03b8658c78fa3ae24..a103e5a1be42c6d9f4a48d6b4328a6338b37877e 100644 --- a/packages/backend/src/remote/activitypub/kernel/index.ts +++ b/packages/backend/src/remote/activitypub/kernel/index.ts @@ -25,8 +25,10 @@ export async function performActivity(actor: IRemoteUser, activity: IObject) { const act = await resolver.resolve(item); try { await performOneActivity(actor, act); - } catch (e) { - apLogger.error(e); + } catch (err) { + if (err instanceof Error || typeof err === 'string') { + apLogger.error(err); + } } } } else { diff --git a/packages/backend/src/remote/activitypub/misc/ld-signature.ts b/packages/backend/src/remote/activitypub/misc/ld-signature.ts index 946914bfaa5ad2321962a911da573b514587b0d2..3b799c755c6a30d79f13d635b03b39e90a8e3efc 100644 --- a/packages/backend/src/remote/activitypub/misc/ld-signature.ts +++ b/packages/backend/src/remote/activitypub/misc/ld-signature.ts @@ -24,7 +24,7 @@ export class LdSignature { } as { type: string; creator: string; - domain: string; + domain?: string; nonce: string; created: string; }; @@ -114,7 +114,7 @@ export class LdSignature { Accept: 'application/ld+json, application/json', }, timeout: this.loderTimeout, - agent: u => u.protocol == 'http:' ? httpAgent : httpsAgent, + agent: u => u.protocol === 'http:' ? httpAgent : httpsAgent, }).then(res => { if (!res.ok) { throw `${res.status} ${res.statusText}`; diff --git a/packages/backend/src/remote/activitypub/models/person.ts b/packages/backend/src/remote/activitypub/models/person.ts index 19a7a70903b3ad520e8066c6d39ece6f47a50e98..aaccf51fa9ddeb0a3ada9f9dab9730f5758f608a 100644 --- a/packages/backend/src/remote/activitypub/models/person.ts +++ b/packages/backend/src/remote/activitypub/models/person.ts @@ -164,6 +164,7 @@ export async function createPerson(uri: string, resolver?: Resolver): Promise<Us tags, isBot, isCat: (person as any).isCat === true, + showTimelineReplies: false, })) as IRemoteUser; await transactionalEntityManager.save(new UserProfile({ diff --git a/packages/backend/src/remote/activitypub/renderer/note.ts b/packages/backend/src/remote/activitypub/renderer/note.ts index 4f9a372b2f4652d0dc6a9521f9236afd93bcdf71..654ab68123e45e595360a82e735c1d84572d6e2b 100644 --- a/packages/backend/src/remote/activitypub/renderer/note.ts +++ b/packages/backend/src/remote/activitypub/renderer/note.ts @@ -11,7 +11,7 @@ import { In } from 'typeorm'; import { Emoji } from '@/models/entities/emoji'; import { Poll } from '@/models/entities/poll'; -export default async function renderNote(note: Note, dive = true, isTalk = false): Promise<any> { +export default async function renderNote(note: Note, dive = true, isTalk = false): Promise<Record<string, unknown>> { const getPromisedFiles = async (ids: string[]) => { if (!ids || ids.length === 0) return []; const items = await DriveFiles.find({ id: In(ids) }); diff --git a/packages/backend/src/remote/activitypub/renderer/ordered-collection.ts b/packages/backend/src/remote/activitypub/renderer/ordered-collection.ts index c4b4337af883cda5341a565ad29046ab23086cd6..ff9a77be3db2250d43e70f0d9e25f1acacdea7a0 100644 --- a/packages/backend/src/remote/activitypub/renderer/ordered-collection.ts +++ b/packages/backend/src/remote/activitypub/renderer/ordered-collection.ts @@ -6,7 +6,14 @@ * @param last URL of last page (optional) * @param orderedItems attached objects (optional) */ -export default function(id: string | null, totalItems: any, first?: string, last?: string, orderedItems?: Record<string, unknown>) { +export default function(id: string | null, totalItems: any, first?: string, last?: string, orderedItems?: Record<string, unknown>[]): { + id: string | null; + type: 'OrderedCollection'; + totalItems: any; + first?: string; + last?: string; + orderedItems?: Record<string, unknown>[]; +} { const page: any = { id, type: 'OrderedCollection', diff --git a/packages/backend/src/server/activitypub/featured.ts b/packages/backend/src/server/activitypub/featured.ts index 40b8d8cc817f170885c3fa203d6a6180ce63c3b3..ed5bfc4267bd77905749dc0a4a4878da64a44ef8 100644 --- a/packages/backend/src/server/activitypub/featured.ts +++ b/packages/backend/src/server/activitypub/featured.ts @@ -32,7 +32,7 @@ export default async (ctx: Router.RouterContext) => { const rendered = renderOrderedCollection( `${config.url}/users/${userId}/collections/featured`, - renderedNotes.length, undefined, undefined, renderedNotes + renderedNotes.length, undefined, undefined, renderedNotes, ); ctx.body = renderActivity(rendered); diff --git a/packages/backend/src/server/api/call.ts b/packages/backend/src/server/api/call.ts index 5bc7d2f25e98feda0e4646392acdb30f62bf61f9..18143340ae8dc9e9f124d129f923a16cf5bf63d2 100644 --- a/packages/backend/src/server/api/call.ts +++ b/packages/backend/src/server/api/call.ts @@ -79,18 +79,28 @@ export default async (endpoint: string, user: User | null | undefined, token: Ac // Cast non JSON input if (ep.meta.requireFile && ep.meta.params) { - const body = (ctx!.request as any).body; for (const k of Object.keys(ep.meta.params)) { const param = ep.meta.params[k]; - if (['Boolean', 'Number'].includes(param.validator.name) && typeof body[k] === 'string') { - body[k] = JSON.parse(body[k]); + if (['Boolean', 'Number'].includes(param.validator.name) && typeof data[k] === 'string') { + try { + data[k] = JSON.parse(data[k]); + } catch (e) { + throw new ApiError({ + message: 'Invalid param.', + code: 'INVALID_PARAM', + id: '0b5f1631-7c1a-41a6-b399-cce335f34d85', + }, { + param: k, + reason: `cannot cast to ${param.validator.name}`, + }) + } } } } // API invoking const before = performance.now(); - return await ep.exec(data, user, token, ctx!.file).catch((e: Error) => { + return await ep.exec(data, user, token, ctx?.file).catch((e: Error) => { if (e instanceof ApiError) { throw e; } else { diff --git a/packages/backend/src/server/api/common/generate-replies-query.ts b/packages/backend/src/server/api/common/generate-replies-query.ts index fbc41b2c253b75f2bec67ff2efcd64ce57c2743d..249064d5894ced164795cc90ab83ed1f1882cbc0 100644 --- a/packages/backend/src/server/api/common/generate-replies-query.ts +++ b/packages/backend/src/server/api/common/generate-replies-query.ts @@ -1,7 +1,7 @@ import { User } from '@/models/entities/user'; import { Brackets, SelectQueryBuilder } from 'typeorm'; -export function generateRepliesQuery(q: SelectQueryBuilder<any>, me?: { id: User['id'] } | null) { +export function generateRepliesQuery(q: SelectQueryBuilder<any>, me?: Pick<User, 'id' | 'showTimelineReplies'> | null) { if (me == null) { q.andWhere(new Brackets(qb => { qb .where(`note.replyId IS NULL`) // 返信ã§ã¯ãªã„ @@ -10,7 +10,7 @@ export function generateRepliesQuery(q: SelectQueryBuilder<any>, me?: { id: User .andWhere('note.replyUserId = note.userId'); })); })); - } else { + } else if(!me.showTimelineReplies) { q.andWhere(new Brackets(qb => { qb .where(`note.replyId IS NULL`) // 返信ã§ã¯ãªã„ .orWhere('note.replyUserId = :meId', { meId: me.id }) // 返信ã ã‘ã©è‡ªåˆ†ã®ãƒŽãƒ¼ãƒˆã¸ã®è¿”ä¿¡ diff --git a/packages/backend/src/server/api/define.ts b/packages/backend/src/server/api/define.ts index 71e5fadde042d5265c7aebe7a1438d9242bebf0c..e0720e2adb80e91d9413100f816713c052b692a5 100644 --- a/packages/backend/src/server/api/define.ts +++ b/packages/backend/src/server/api/define.ts @@ -9,6 +9,7 @@ type NonOptional<T> = T extends undefined ? never : T; type SimpleUserInfo = { id: ILocalUser['id']; + createdAt: ILocalUser['createdAt']; host: ILocalUser['host']; username: ILocalUser['username']; uri: ILocalUser['uri']; diff --git a/packages/backend/src/server/api/endpoints/admin/resolve-abuse-user-report.ts b/packages/backend/src/server/api/endpoints/admin/resolve-abuse-user-report.ts index b00457f0925b5ef8e86d6261e2ccc15dc5d34ff9..a47b69ec1a6f10538c1655c43b8162bd73833da3 100644 --- a/packages/backend/src/server/api/endpoints/admin/resolve-abuse-user-report.ts +++ b/packages/backend/src/server/api/endpoints/admin/resolve-abuse-user-report.ts @@ -36,9 +36,9 @@ export default define(meta, async (ps, me) => { if (ps.forward && report.targetUserHost != null) { const actor = await getInstanceActor(); - const targetUser = await Users.findOne(report.targetUserId); + const targetUser = await Users.findOneOrFail(report.targetUserId); - deliver(actor, renderActivity(renderFlag(actor, [targetUser.uri], report.comment)), targetUser.inbox); + deliver(actor, renderActivity(renderFlag(actor, [targetUser.uri!], report.comment)), targetUser.inbox); } await AbuseUserReports.update(report.id, { diff --git a/packages/backend/src/server/api/endpoints/admin/show-user.ts b/packages/backend/src/server/api/endpoints/admin/show-user.ts index c2a6a294b5ff2a2eb20d2c968a23a1a81ad41673..0d0cc9087a70dbc6eef569a9e6055d42b669f8cd 100644 --- a/packages/backend/src/server/api/endpoints/admin/show-user.ts +++ b/packages/backend/src/server/api/endpoints/admin/show-user.ts @@ -18,144 +18,6 @@ export const meta = { res: { type: 'object', nullable: false, optional: false, - properties: { - id: { - type: 'string', - nullable: false, optional: false, - format: 'id', - }, - createdAt: { - type: 'string', - nullable: false, optional: false, - format: 'date-time', - }, - updatedAt: { - type: 'string', - nullable: true, optional: false, - format: 'date-time', - }, - lastFetchedAt: { - type: 'string', - nullable: true, optional: false, - }, - username: { - type: 'string', - nullable: false, optional: false, - }, - name: { - type: 'string', - nullable: true, optional: false, - }, - folowersCount: { - type: 'number', - nullable: false, optional: true, - }, - followingCount: { - type: 'number', - nullable: false, optional: false, - }, - notesCount: { - type: 'number', - nullable: false, optional: false, - }, - avatarId: { - type: 'string', - nullable: true, optional: false, - }, - bannerId: { - type: 'string', - nullable: true, optional: false, - }, - tags: { - type: 'array', - nullable: false, optional: false, - items: { - type: 'string', - nullable: false, optional: false, - }, - }, - avatarUrl: { - type: 'string', - nullable: true, optional: false, - format: 'url', - }, - bannerUrl: { - type: 'string', - nullable: true, optional: false, - format: 'url', - }, - avatarBlurhash: { - type: 'any', - nullable: true, optional: false, - default: null, - }, - bannerBlurhash: { - type: 'any', - nullable: true, optional: false, - default: null, - }, - isSuspended: { - type: 'boolean', - nullable: false, optional: false, - }, - isSilenced: { - type: 'boolean', - nullable: false, optional: false, - }, - isLocked: { - type: 'boolean', - nullable: false, optional: false, - }, - isBot: { - type: 'boolean', - nullable: false, optional: false, - }, - isCat: { - type: 'boolean', - nullable: false, optional: false, - }, - isAdmin: { - type: 'boolean', - nullable: false, optional: false, - }, - isModerator: { - type: 'boolean', - nullable: false, optional: false, - }, - emojis: { - type: 'array', - nullable: false, optional: false, - items: { - type: 'string', - nullable: false, optional: false, - }, - }, - host: { - type: 'string', - nullable: true, optional: false, - }, - inbox: { - type: 'string', - nullable: true, optional: false, - }, - sharedInbox: { - type: 'string', - nullable: true, optional: false, - }, - featured: { - type: 'string', - nullable: true, optional: false, - }, - uri: { - type: 'string', - nullable: true, optional: false, - }, - token: { - type: 'string', - nullable: true, optional: false, - default: '<MASKED>', - }, - }, }, } as const; diff --git a/packages/backend/src/server/api/endpoints/announcements.ts b/packages/backend/src/server/api/endpoints/announcements.ts index 0bd29607d68532cea1aa81fd1928ae0d1c2c303c..22c13743a8d50330530c5d0431bdc919fad1b874 100644 --- a/packages/backend/src/server/api/endpoints/announcements.ts +++ b/packages/backend/src/server/api/endpoints/announcements.ts @@ -89,5 +89,9 @@ export default define(meta, async (ps, user) => { } } - return ps.withUnreads ? announcements.filter((a: any) => !a.isRead) : announcements; + return (ps.withUnreads ? announcements.filter((a: any) => !a.isRead) : announcements).map((a) => ({ + ...a, + createdAt: a.createdAt.toISOString(), + updatedAt: a.updatedAt?.toISOString() ?? null, + })); }); diff --git a/packages/backend/src/server/api/endpoints/channels/timeline.ts b/packages/backend/src/server/api/endpoints/channels/timeline.ts index 927ce7c741a28f7d3a97133b1a5c6810b62fcc09..2639095f8af46ca23bac7bd2d7272b2189318a7f 100644 --- a/packages/backend/src/server/api/endpoints/channels/timeline.ts +++ b/packages/backend/src/server/api/endpoints/channels/timeline.ts @@ -80,7 +80,7 @@ export default define(meta, async (ps, user) => { const timeline = await query.take(ps.limit!).getMany(); - if (user) activeUsersChart.update(user); + if (user) activeUsersChart.read(user); return await Notes.packMany(timeline, user); }); diff --git a/packages/backend/src/server/api/endpoints/charts/active-users.ts b/packages/backend/src/server/api/endpoints/charts/active-users.ts index f7eadc70893b60b876f503f852f249f2414eede7..a51cd00351c4af3744e722e45474bfa5dfa7dac3 100644 --- a/packages/backend/src/server/api/endpoints/charts/active-users.ts +++ b/packages/backend/src/server/api/endpoints/charts/active-users.ts @@ -22,7 +22,7 @@ export const meta = { }, }, - res: convertLog(activeUsersChart.schema), + // TODO: response definition } as const; // eslint-disable-next-line import/no-default-export diff --git a/packages/backend/src/server/api/endpoints/charts/network.ts b/packages/backend/src/server/api/endpoints/charts/ap-request.ts similarity index 71% rename from packages/backend/src/server/api/endpoints/charts/network.ts rename to packages/backend/src/server/api/endpoints/charts/ap-request.ts index c5a39bbd7656881b302902af17d1a87283957321..38bbddb27a1d955a6d9d46d155b4c85e59015ab9 100644 --- a/packages/backend/src/server/api/endpoints/charts/network.ts +++ b/packages/backend/src/server/api/endpoints/charts/ap-request.ts @@ -1,7 +1,7 @@ import $ from 'cafy'; import define from '../../define'; import { convertLog } from '@/services/chart/core'; -import { networkChart } from '@/services/chart/index'; +import { apRequestChart } from '@/services/chart/index'; export const meta = { tags: ['charts'], @@ -22,10 +22,10 @@ export const meta = { }, }, - res: convertLog(networkChart.schema), + // TODO: response definition } as const; // eslint-disable-next-line import/no-default-export export default define(meta, async (ps) => { - return await networkChart.getChart(ps.span as any, ps.limit!, ps.offset ? new Date(ps.offset) : null); + return await apRequestChart.getChart(ps.span as any, ps.limit!, ps.offset ? new Date(ps.offset) : null); }); diff --git a/packages/backend/src/server/api/endpoints/charts/drive.ts b/packages/backend/src/server/api/endpoints/charts/drive.ts index 364279da95405b3ba71bbaddb8d2a157f90aaaac..4bbb9861f8e4013bb736e872285b4b1d764ce94d 100644 --- a/packages/backend/src/server/api/endpoints/charts/drive.ts +++ b/packages/backend/src/server/api/endpoints/charts/drive.ts @@ -22,7 +22,7 @@ export const meta = { }, }, - res: convertLog(driveChart.schema), + // TODO: response definition } as const; // eslint-disable-next-line import/no-default-export diff --git a/packages/backend/src/server/api/endpoints/charts/federation.ts b/packages/backend/src/server/api/endpoints/charts/federation.ts index 6feb82b6d91eeff8e6b6cfe1ce1b493cc7c08294..237678ffed116e272c33e79452e9b96be9265a49 100644 --- a/packages/backend/src/server/api/endpoints/charts/federation.ts +++ b/packages/backend/src/server/api/endpoints/charts/federation.ts @@ -22,7 +22,7 @@ export const meta = { }, }, - res: convertLog(federationChart.schema), + // TODO: response definition } as const; // eslint-disable-next-line import/no-default-export diff --git a/packages/backend/src/server/api/endpoints/charts/hashtag.ts b/packages/backend/src/server/api/endpoints/charts/hashtag.ts index 99dc77998e04f602bac4361cdf29449878f159ea..6c12cb063ec1a36bad065ecbb5ba5693c61c26f9 100644 --- a/packages/backend/src/server/api/endpoints/charts/hashtag.ts +++ b/packages/backend/src/server/api/endpoints/charts/hashtag.ts @@ -26,7 +26,7 @@ export const meta = { }, }, - res: convertLog(hashtagChart.schema), + // TODO: response definition } as const; // eslint-disable-next-line import/no-default-export diff --git a/packages/backend/src/server/api/endpoints/charts/instance.ts b/packages/backend/src/server/api/endpoints/charts/instance.ts index 23e6fbf2b00f2479f961ef8f9add48c6d0d45f9e..32a10d5a28026e4ad8f957991dc30eeb184ec18f 100644 --- a/packages/backend/src/server/api/endpoints/charts/instance.ts +++ b/packages/backend/src/server/api/endpoints/charts/instance.ts @@ -26,7 +26,7 @@ export const meta = { }, }, - res: convertLog(instanceChart.schema), + // TODO: response definition } as const; // eslint-disable-next-line import/no-default-export diff --git a/packages/backend/src/server/api/endpoints/charts/notes.ts b/packages/backend/src/server/api/endpoints/charts/notes.ts index dcbd80c3e9744b2fb0531c742afeff7ac1245679..09255f1d2da6d25cbcb6575a638ef53a27cdd284 100644 --- a/packages/backend/src/server/api/endpoints/charts/notes.ts +++ b/packages/backend/src/server/api/endpoints/charts/notes.ts @@ -22,7 +22,7 @@ export const meta = { }, }, - res: convertLog(notesChart.schema), + // TODO: response definition } as const; // eslint-disable-next-line import/no-default-export diff --git a/packages/backend/src/server/api/endpoints/charts/user/drive.ts b/packages/backend/src/server/api/endpoints/charts/user/drive.ts index 94787b4a578aee0c25cd4062401ebb73c53bb707..89379858d1a005d5348b3a4fd39bfee3ded25703 100644 --- a/packages/backend/src/server/api/endpoints/charts/user/drive.ts +++ b/packages/backend/src/server/api/endpoints/charts/user/drive.ts @@ -27,7 +27,7 @@ export const meta = { }, }, - res: convertLog(perUserDriveChart.schema), + // TODO: response definition } as const; // eslint-disable-next-line import/no-default-export diff --git a/packages/backend/src/server/api/endpoints/charts/user/following.ts b/packages/backend/src/server/api/endpoints/charts/user/following.ts index effe0c54b9969ce013d0a651c156dcadbfe19c4c..26c3f5c126ee1dd25cef1c6ad9eab12fa97058a5 100644 --- a/packages/backend/src/server/api/endpoints/charts/user/following.ts +++ b/packages/backend/src/server/api/endpoints/charts/user/following.ts @@ -27,7 +27,7 @@ export const meta = { }, }, - res: convertLog(perUserFollowingChart.schema), + // TODO: response definition } as const; // eslint-disable-next-line import/no-default-export diff --git a/packages/backend/src/server/api/endpoints/charts/user/notes.ts b/packages/backend/src/server/api/endpoints/charts/user/notes.ts index df68a5fe524185230da53b5ef4127e4c7d88880a..ecf85becfa2b01beda4681198fee6851ec4a6147 100644 --- a/packages/backend/src/server/api/endpoints/charts/user/notes.ts +++ b/packages/backend/src/server/api/endpoints/charts/user/notes.ts @@ -27,7 +27,7 @@ export const meta = { }, }, - res: convertLog(perUserNotesChart.schema), + // TODO: response definition } as const; // eslint-disable-next-line import/no-default-export diff --git a/packages/backend/src/server/api/endpoints/charts/user/reactions.ts b/packages/backend/src/server/api/endpoints/charts/user/reactions.ts index dcd067305ff9245d75cd31221fead953f2bdafa9..6e08d07511b724c070fd04f45b45d19e09d85aef 100644 --- a/packages/backend/src/server/api/endpoints/charts/user/reactions.ts +++ b/packages/backend/src/server/api/endpoints/charts/user/reactions.ts @@ -27,7 +27,7 @@ export const meta = { }, }, - res: convertLog(perUserReactionsChart.schema), + // TODO: response definition } as const; // eslint-disable-next-line import/no-default-export diff --git a/packages/backend/src/server/api/endpoints/charts/users.ts b/packages/backend/src/server/api/endpoints/charts/users.ts index d32e14ad61210d4b63e0257976205fc98756a599..15a9ec038e4b53a63babc96942de9326b92915d6 100644 --- a/packages/backend/src/server/api/endpoints/charts/users.ts +++ b/packages/backend/src/server/api/endpoints/charts/users.ts @@ -22,7 +22,7 @@ export const meta = { }, }, - res: convertLog(usersChart.schema), + // TODO: response definition } as const; // eslint-disable-next-line import/no-default-export diff --git a/packages/backend/src/server/api/endpoints/drive/files/create.ts b/packages/backend/src/server/api/endpoints/drive/files/create.ts index 877e76677eabe078bae12ed8c63e77229a831757..ac7863ec7edb43ca3c5f30a171b9c5af6d62f300 100644 --- a/packages/backend/src/server/api/endpoints/drive/files/create.ts +++ b/packages/backend/src/server/api/endpoints/drive/files/create.ts @@ -86,7 +86,9 @@ export default define(meta, async (ps, user, _, file, cleanup) => { const driveFile = await addFile({ user, path: file.path, name, comment: ps.comment, folderId: ps.folderId, force: ps.force, sensitive: ps.isSensitive }); return await DriveFiles.pack(driveFile, { self: true }); } catch (e) { - apiLogger.error(e); + if (e instanceof Error || typeof e === 'string') { + apiLogger.error(e); + } throw new ApiError(); } finally { cleanup!(); diff --git a/packages/backend/src/server/api/endpoints/following/create.ts b/packages/backend/src/server/api/endpoints/following/create.ts index 96aede45502277127abf665384fe729de3411905..b840ab7696cd46931f456b230b83a36fffc5c197 100644 --- a/packages/backend/src/server/api/endpoints/following/create.ts +++ b/packages/backend/src/server/api/endpoints/following/create.ts @@ -6,6 +6,7 @@ import define from '../../define'; import { ApiError } from '../../error'; import { getUser } from '../../common/getters'; import { Followings, Users } from '@/models/index'; +import { IdentifiableError } from '@/misc/identifiable-error'; export const meta = { tags: ['following', 'users'], @@ -92,8 +93,10 @@ export default define(meta, async (ps, user) => { try { await create(follower, followee); } catch (e) { - if (e.id === '710e8fb0-b8c3-4922-be49-d5d93d8e6a6e') throw new ApiError(meta.errors.blocking); - if (e.id === '3338392a-f764-498d-8855-db939dcf8c48') throw new ApiError(meta.errors.blocked); + if (e instanceof IdentifiableError) { + if (e.id === '710e8fb0-b8c3-4922-be49-d5d93d8e6a6e') throw new ApiError(meta.errors.blocking); + if (e.id === '3338392a-f764-498d-8855-db939dcf8c48') throw new ApiError(meta.errors.blocked); + } throw e; } diff --git a/packages/backend/src/server/api/endpoints/following/requests/cancel.ts b/packages/backend/src/server/api/endpoints/following/requests/cancel.ts index 19ed02c152f3ec266df5b8293741dd7cf6434c22..c9abbf36decd91616551fdc07fbf8f0aa20d49cc 100644 --- a/packages/backend/src/server/api/endpoints/following/requests/cancel.ts +++ b/packages/backend/src/server/api/endpoints/following/requests/cancel.ts @@ -5,6 +5,7 @@ import define from '../../../define'; import { ApiError } from '../../../error'; import { getUser } from '../../../common/getters'; import { Users } from '@/models/index'; +import { IdentifiableError } from '@/misc/identifiable-error'; export const meta = { tags: ['following', 'account'], @@ -51,7 +52,9 @@ export default define(meta, async (ps, user) => { try { await cancelFollowRequest(followee, user); } catch (e) { - if (e.id === '17447091-ce07-46dd-b331-c1fd4f15b1e7') throw new ApiError(meta.errors.followRequestNotFound); + if (e instanceof IdentifiableError) { + if (e.id === '17447091-ce07-46dd-b331-c1fd4f15b1e7') throw new ApiError(meta.errors.followRequestNotFound); + } throw e; } diff --git a/packages/backend/src/server/api/endpoints/i/update.ts b/packages/backend/src/server/api/endpoints/i/update.ts index 6b7e53aa1fbe201e43e8a8b7074f9fc229cc3618..eb57aa2bfc25e3145da894ef0b4d4fb9f0b0aff0 100644 --- a/packages/backend/src/server/api/endpoints/i/update.ts +++ b/packages/backend/src/server/api/endpoints/i/update.ts @@ -96,6 +96,10 @@ export const meta = { validator: $.optional.bool, }, + showTimelineReplies: { + validator: $.optional.bool, + }, + injectFeaturedNote: { validator: $.optional.bool, }, @@ -197,6 +201,7 @@ export default define(meta, async (ps, _user, token) => { 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.showTimelineReplies === 'boolean') updates.showTimelineReplies = ps.showTimelineReplies; if (typeof ps.carefulBot === 'boolean') profileUpdates.carefulBot = ps.carefulBot; if (typeof ps.autoAcceptFollowed === 'boolean') profileUpdates.autoAcceptFollowed = ps.autoAcceptFollowed; if (typeof ps.noCrawle === 'boolean') profileUpdates.noCrawle = ps.noCrawle; diff --git a/packages/backend/src/server/api/endpoints/notes/global-timeline.ts b/packages/backend/src/server/api/endpoints/notes/global-timeline.ts index cac8b7d8a99633196b7d8cdeba01cb69ac3e51ae..cdd110994e333985bb129d2562ac8e42cfe60d8e 100644 --- a/packages/backend/src/server/api/endpoints/notes/global-timeline.ts +++ b/packages/backend/src/server/api/endpoints/notes/global-timeline.ts @@ -96,7 +96,7 @@ export default define(meta, async (ps, user) => { process.nextTick(() => { if (user) { - activeUsersChart.update(user); + activeUsersChart.read(user); } }); diff --git a/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts b/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts index 9683df4611e5d0edf0885605de8711974677acc4..b43849102622a839ea66e900754624f9808ecc88 100644 --- a/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts +++ b/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts @@ -153,7 +153,7 @@ export default define(meta, async (ps, user) => { process.nextTick(() => { if (user) { - activeUsersChart.update(user); + activeUsersChart.read(user); } }); diff --git a/packages/backend/src/server/api/endpoints/notes/local-timeline.ts b/packages/backend/src/server/api/endpoints/notes/local-timeline.ts index 77766441242e59d7cb0ec854144dac77f667dc8d..ce0bcbeb7bab223094997f88556a05b0349545f6 100644 --- a/packages/backend/src/server/api/endpoints/notes/local-timeline.ts +++ b/packages/backend/src/server/api/endpoints/notes/local-timeline.ts @@ -122,7 +122,7 @@ export default define(meta, async (ps, user) => { process.nextTick(() => { if (user) { - activeUsersChart.update(user); + activeUsersChart.read(user); } }); diff --git a/packages/backend/src/server/api/endpoints/notes/timeline.ts b/packages/backend/src/server/api/endpoints/notes/timeline.ts index 8be2861aece38d3f7717bf3f11506dcd73a1f72e..f8cd083249a76efd568e17ea4390006d264e38ff 100644 --- a/packages/backend/src/server/api/endpoints/notes/timeline.ts +++ b/packages/backend/src/server/api/endpoints/notes/timeline.ts @@ -145,7 +145,7 @@ export default define(meta, async (ps, user) => { process.nextTick(() => { if (user) { - activeUsersChart.update(user); + activeUsersChart.read(user); } }); diff --git a/packages/backend/src/server/api/endpoints/notes/user-list-timeline.ts b/packages/backend/src/server/api/endpoints/notes/user-list-timeline.ts index 89de73fb9d2c78675268231f682abbcc26dae139..3512fb3638c408efde12a81cca5ad941ec1f11a5 100644 --- a/packages/backend/src/server/api/endpoints/notes/user-list-timeline.ts +++ b/packages/backend/src/server/api/endpoints/notes/user-list-timeline.ts @@ -142,7 +142,7 @@ export default define(meta, async (ps, user) => { const timeline = await query.take(ps.limit!).getMany(); - activeUsersChart.update(user); + activeUsersChart.read(user); return await Notes.packMany(timeline, user); }); diff --git a/packages/backend/src/server/api/endpoints/stats.ts b/packages/backend/src/server/api/endpoints/stats.ts index 9879ef2adf3a4c30c134916a5ed0a5c9c3244e61..17281888a6d72fceb6f3e841e17760031a880eb7 100644 --- a/packages/backend/src/server/api/endpoints/stats.ts +++ b/packages/backend/src/server/api/endpoints/stats.ts @@ -56,8 +56,6 @@ export default define(meta, async () => { reactionsCount, //originalReactionsCount, instances, - driveUsageLocal, - driveUsageRemote, ] = await Promise.all([ Notes.count({ cache: 3600000 }), // 1 hour Notes.count({ where: { userHost: null }, cache: 3600000 }), @@ -66,8 +64,6 @@ export default define(meta, async () => { NoteReactions.count({ cache: 3600000 }), // 1 hour //NoteReactions.count({ where: { userHost: null }, cache: 3600000 }), federationChart.getChart('hour', 1, null).then(chart => chart.instance.total[0]), - driveChart.getChart('hour', 1, null).then(chart => chart.local.totalSize[0]), - driveChart.getChart('hour', 1, null).then(chart => chart.remote.totalSize[0]), ]); return { @@ -78,7 +74,7 @@ export default define(meta, async () => { reactionsCount, //originalReactionsCount, instances, - driveUsageLocal, - driveUsageRemote, + driveUsageLocal: 0, + driveUsageRemote: 0, }; }); diff --git a/packages/backend/src/server/api/endpoints/users/search-by-username-and-host.ts b/packages/backend/src/server/api/endpoints/users/search-by-username-and-host.ts index d67625e624fd84ecdc64f8634b0464d4c780484b..72e79c88249ecb86b5df5c397a2429c84e651a45 100644 --- a/packages/backend/src/server/api/endpoints/users/search-by-username-and-host.ts +++ b/packages/backend/src/server/api/endpoints/users/search-by-username-and-host.ts @@ -114,4 +114,6 @@ export default define(meta, async (ps, me) => { return await Users.packMany(users, me, { detail: !!ps.detail }); } + + return []; }); diff --git a/packages/backend/src/server/api/service/discord.ts b/packages/backend/src/server/api/service/discord.ts index f574fe3878a97b58dae299837a14f0b588b39694..dd731c422e84f7102d74d658219e2f856ef2972c 100644 --- a/packages/backend/src/server/api/service/discord.ts +++ b/packages/backend/src/server/api/service/discord.ts @@ -11,18 +11,18 @@ import { fetchMeta } from '@/misc/fetch-meta'; import { Users, UserProfiles } from '@/models/index'; import { ILocalUser } from '@/models/entities/user'; -function getUserToken(ctx: Koa.Context) { +function getUserToken(ctx: Koa.BaseContext): string | null { return ((ctx.headers['cookie'] || '').match(/igi=(\w+)/) || [null, null])[1]; } -function compareOrigin(ctx: Koa.Context) { - function normalizeUrl(url: string) { +function compareOrigin(ctx: Koa.BaseContext): boolean { + function normalizeUrl(url?: string): string { return url ? url.endsWith('/') ? url.substr(0, url.length - 1) : url : ''; } const referer = ctx.headers['referer']; - return (normalizeUrl(referer) == normalizeUrl(config.url)); + return (normalizeUrl(referer) === normalizeUrl(config.url)); } // Init router diff --git a/packages/backend/src/server/api/service/github.ts b/packages/backend/src/server/api/service/github.ts index 5e0839df9378ec8d99640e59ef21ad3cf4938cc1..b23219986a95b17390ff3d15c2199637aa620a2d 100644 --- a/packages/backend/src/server/api/service/github.ts +++ b/packages/backend/src/server/api/service/github.ts @@ -11,18 +11,18 @@ import { fetchMeta } from '@/misc/fetch-meta'; import { Users, UserProfiles } from '@/models/index'; import { ILocalUser } from '@/models/entities/user'; -function getUserToken(ctx: Koa.Context) { +function getUserToken(ctx: Koa.BaseContext): string | null { return ((ctx.headers['cookie'] || '').match(/igi=(\w+)/) || [null, null])[1]; } -function compareOrigin(ctx: Koa.Context) { - function normalizeUrl(url: string) { +function compareOrigin(ctx: Koa.BaseContext): boolean { + function normalizeUrl(url?: string): string { return url ? url.endsWith('/') ? url.substr(0, url.length - 1) : url : ''; } const referer = ctx.headers['referer']; - return (normalizeUrl(referer) == normalizeUrl(config.url)); + return (normalizeUrl(referer) === normalizeUrl(config.url)); } // Init router diff --git a/packages/backend/src/server/api/service/twitter.ts b/packages/backend/src/server/api/service/twitter.ts index 8659b82cbe1d54063ec2087d5ad6e8afdcf56c95..bca00b7924a381299668fc638014d25edaec3eb5 100644 --- a/packages/backend/src/server/api/service/twitter.ts +++ b/packages/backend/src/server/api/service/twitter.ts @@ -10,18 +10,18 @@ import { fetchMeta } from '@/misc/fetch-meta'; import { Users, UserProfiles } from '@/models/index'; import { ILocalUser } from '@/models/entities/user'; -function getUserToken(ctx: Koa.Context) { +function getUserToken(ctx: Koa.BaseContext): string | null { return ((ctx.headers['cookie'] || '').match(/igi=(\w+)/) || [null, null])[1]; } -function compareOrigin(ctx: Koa.Context) { - function normalizeUrl(url: string) { - return url.endsWith('/') ? url.substr(0, url.length - 1) : url; +function compareOrigin(ctx: Koa.BaseContext): boolean { + function normalizeUrl(url?: string): string { + return url == null ? '' : url.endsWith('/') ? url.substr(0, url.length - 1) : url; } const referer = ctx.headers['referer']; - return (normalizeUrl(referer) == normalizeUrl(config.url)); + return (normalizeUrl(referer) === normalizeUrl(config.url)); } // Init router diff --git a/packages/backend/src/server/api/stream/channels/global-timeline.ts b/packages/backend/src/server/api/stream/channels/global-timeline.ts index f14f597aac414aeef73195b636533448177dcea8..ecd87d093dd79dbc07e4e9f8ac09f58b7dab43cf 100644 --- a/packages/backend/src/server/api/stream/channels/global-timeline.ts +++ b/packages/backend/src/server/api/stream/channels/global-timeline.ts @@ -43,7 +43,7 @@ export default class extends Channel { } // 関係ãªã„返信ã¯é™¤å¤– - if (note.reply) { + if (note.reply && !this.user!.showTimelineReplies) { const reply = note.reply; // 「ãƒãƒ£ãƒ³ãƒãƒ«æŽ¥ç¶šä¸»ã¸ã®è¿”ä¿¡ã€ã§ã‚‚ãªã‘ã‚Œã°ã€ã€Œãƒãƒ£ãƒ³ãƒãƒ«æŽ¥ç¶šä¸»ãŒè¡Œã£ãŸè¿”ä¿¡ã€ã§ã‚‚ãªã‘ã‚Œã°ã€ã€ŒæŠ•ç¨¿è€…ã®æŠ•ç¨¿è€…自身ã¸ã®è¿”ä¿¡ã€ã§ã‚‚ãªã„å ´åˆ if (reply.userId !== this.user!.id && note.userId !== this.user!.id && reply.userId !== note.userId) return; diff --git a/packages/backend/src/server/api/stream/channels/home-timeline.ts b/packages/backend/src/server/api/stream/channels/home-timeline.ts index 3bd491421dbe55e21911ffed1fadb1b8abb86f60..445db5c382add75df378ccf4055c49dade808f32 100644 --- a/packages/backend/src/server/api/stream/channels/home-timeline.ts +++ b/packages/backend/src/server/api/stream/channels/home-timeline.ts @@ -54,7 +54,7 @@ export default class extends Channel { } // 関係ãªã„返信ã¯é™¤å¤– - if (note.reply) { + if (note.reply && !this.user!.showTimelineReplies) { const reply = note.reply; // 「ãƒãƒ£ãƒ³ãƒãƒ«æŽ¥ç¶šä¸»ã¸ã®è¿”ä¿¡ã€ã§ã‚‚ãªã‘ã‚Œã°ã€ã€Œãƒãƒ£ãƒ³ãƒãƒ«æŽ¥ç¶šä¸»ãŒè¡Œã£ãŸè¿”ä¿¡ã€ã§ã‚‚ãªã‘ã‚Œã°ã€ã€ŒæŠ•ç¨¿è€…ã®æŠ•ç¨¿è€…自身ã¸ã®è¿”ä¿¡ã€ã§ã‚‚ãªã„å ´åˆ if (reply.userId !== this.user!.id && note.userId !== this.user!.id && reply.userId !== note.userId) return; diff --git a/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts b/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts index 0ae19aa7ce85df49f3c6566a7c85dc6a3ad663fe..c0be71fe2d5ef0828ae26b23661b2b0382faef85 100644 --- a/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts +++ b/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts @@ -62,7 +62,7 @@ export default class extends Channel { if (isInstanceMuted(note, new Set<string>(this.userProfile?.mutedInstances ?? []))) return; // 関係ãªã„返信ã¯é™¤å¤– - if (note.reply) { + if (note.reply && !this.user!.showTimelineReplies) { const reply = note.reply; // 「ãƒãƒ£ãƒ³ãƒãƒ«æŽ¥ç¶šä¸»ã¸ã®è¿”ä¿¡ã€ã§ã‚‚ãªã‘ã‚Œã°ã€ã€Œãƒãƒ£ãƒ³ãƒãƒ«æŽ¥ç¶šä¸»ãŒè¡Œã£ãŸè¿”ä¿¡ã€ã§ã‚‚ãªã‘ã‚Œã°ã€ã€ŒæŠ•ç¨¿è€…ã®æŠ•ç¨¿è€…自身ã¸ã®è¿”ä¿¡ã€ã§ã‚‚ãªã„å ´åˆ if (reply.userId !== this.user!.id && note.userId !== this.user!.id && reply.userId !== note.userId) return; diff --git a/packages/backend/src/server/api/stream/channels/local-timeline.ts b/packages/backend/src/server/api/stream/channels/local-timeline.ts index 3178b1d511e4c99f9746e989eeed4aabd7a3c975..ae8f62ba6136e2118aa15481c53b59259597a48e 100644 --- a/packages/backend/src/server/api/stream/channels/local-timeline.ts +++ b/packages/backend/src/server/api/stream/channels/local-timeline.ts @@ -43,7 +43,7 @@ export default class extends Channel { } // 関係ãªã„返信ã¯é™¤å¤– - if (note.reply) { + if (note.reply && !this.user!.showTimelineReplies) { const reply = note.reply; // 「ãƒãƒ£ãƒ³ãƒãƒ«æŽ¥ç¶šä¸»ã¸ã®è¿”ä¿¡ã€ã§ã‚‚ãªã‘ã‚Œã°ã€ã€Œãƒãƒ£ãƒ³ãƒãƒ«æŽ¥ç¶šä¸»ãŒè¡Œã£ãŸè¿”ä¿¡ã€ã§ã‚‚ãªã‘ã‚Œã°ã€ã€ŒæŠ•ç¨¿è€…ã®æŠ•ç¨¿è€…自身ã¸ã®è¿”ä¿¡ã€ã§ã‚‚ãªã„å ´åˆ if (reply.userId !== this.user!.id && note.userId !== this.user!.id && reply.userId !== note.userId) return; diff --git a/packages/backend/src/server/api/stream/types.ts b/packages/backend/src/server/api/stream/types.ts index e70c26f5e556c1a35c2ee9b95dd53da4762907d9..e2f1c6fc9ca23ceb19358a43a09522e59bfa97b3 100644 --- a/packages/backend/src/server/api/stream/types.ts +++ b/packages/backend/src/server/api/stream/types.ts @@ -105,7 +105,10 @@ export interface NoteStreamTypes { }; reacted: { reaction: string; - emoji?: Emoji; + emoji?: { + name: string; + url: string; + } | null; userId: User['id']; }; unreacted: { diff --git a/packages/backend/src/server/api/streaming.ts b/packages/backend/src/server/api/streaming.ts index ad87311064f444dc7757699302822810ea663441..b706b1b8dfb0a6f89c69234e218195e53fd0562a 100644 --- a/packages/backend/src/server/api/streaming.ts +++ b/packages/backend/src/server/api/streaming.ts @@ -59,7 +59,7 @@ module.exports = (server: http.Server) => { }); connection.on('message', async (data) => { - if (data.utf8Data === 'ping') { + if (data.type === 'utf8' && data.utf8Data === 'ping') { connection.send('pong'); } }); diff --git a/packages/backend/src/server/index.ts b/packages/backend/src/server/index.ts index 764306c7d82a071f1ee2017a0241200b87e99946..4d6b402e645c1bc0c78b1c88c89d4ccc2266c0cd 100644 --- a/packages/backend/src/server/index.ts +++ b/packages/backend/src/server/index.ts @@ -10,7 +10,6 @@ import * as Koa from 'koa'; import * as Router from '@koa/router'; import * as mount from 'koa-mount'; import * as koaLogger from 'koa-logger'; -import * as requestStats from 'request-stats'; import * as slow from 'koa-slow'; import activityPub from './activitypub'; @@ -18,11 +17,9 @@ import nodeinfo from './nodeinfo'; import wellKnown from './well-known'; import config from '@/config/index'; import apiServer from './api/index'; -import { sum } from '@/prelude/array'; import Logger from '@/services/logger'; import { envOption } from '../env'; import { UserProfiles, Users } from '@/models/index'; -import { networkChart } from '@/services/chart/index'; import { genIdenticon } from '@/misc/gen-identicon'; import { createTemp } from '@/misc/create-temp'; import { publishMainStream } from '@/services/stream'; @@ -153,27 +150,4 @@ export default () => new Promise(resolve => { // Listen server.listen(config.port, resolve); - - //#region Network stats - let queue: any[] = []; - - requestStats(server, (stats: any) => { - if (stats.ok) { - queue.push(stats); - } - }); - - // Bulk write - setInterval(() => { - if (queue.length === 0) return; - - const requests = queue.length; - const time = sum(queue.map(x => x.time)); - const incomingBytes = sum(queue.map(x => x.req.byets)); - const outgoingBytes = sum(queue.map(x => x.res.byets)); - queue = []; - - networkChart.update(requests, time, incomingBytes, outgoingBytes); - }, 5000); - //#endregion }); diff --git a/packages/backend/src/server/nodeinfo.ts b/packages/backend/src/server/nodeinfo.ts index 44f32bf882e16bcae36caea60dd800970ad798ea..4209fc7f14e49b4d31b31866f2ceebd37d3de67c 100644 --- a/packages/backend/src/server/nodeinfo.ts +++ b/packages/backend/src/server/nodeinfo.ts @@ -2,7 +2,7 @@ import * as Router from '@koa/router'; import config from '@/config/index'; import { fetchMeta } from '@/misc/fetch-meta'; import { Users, Notes } from '@/models/index'; -import { Not, IsNull, MoreThan } from 'typeorm'; +import { MoreThan } from 'typeorm'; const router = new Router(); @@ -25,14 +25,12 @@ const nodeinfo2 = async () => { activeHalfyear, activeMonth, localPosts, - localComments, ] = await Promise.all([ fetchMeta(true), Users.count({ where: { host: null } }), - Users.count({ where: { host: null, updatedAt: MoreThan(new Date(now - 15552000000)) } }), - Users.count({ where: { host: null, updatedAt: MoreThan(new Date(now - 2592000000)) } }), - Notes.count({ where: { userHost: null, replyId: null } }), - Notes.count({ where: { userHost: null, replyId: Not(IsNull()) } }), + Users.count({ where: { host: null, lastActiveDate: MoreThan(new Date(now - 15552000000)) } }), + Users.count({ where: { host: null, lastActiveDate: MoreThan(new Date(now - 2592000000)) } }), + Notes.count({ where: { userHost: null } }), ]); const proxyAccount = meta.proxyAccountId ? await Users.pack(meta.proxyAccountId).catch(() => null) : null; @@ -52,7 +50,7 @@ const nodeinfo2 = async () => { usage: { users: { total, activeHalfyear, activeMonth }, localPosts, - localComments, + localComments: 0, }, metadata: { nodeName: meta.name, diff --git a/packages/backend/src/server/proxy/proxy-media.ts b/packages/backend/src/server/proxy/proxy-media.ts index c234b70c5528f4a768630d1fe4a01b045c100562..b7dcd0292beb5fb5bf0449da222645d3903618cc 100644 --- a/packages/backend/src/server/proxy/proxy-media.ts +++ b/packages/backend/src/server/proxy/proxy-media.ts @@ -11,6 +11,11 @@ import { FILE_TYPE_BROWSERSAFE } from '@/const'; export async function proxyMedia(ctx: Koa.Context) { const url = 'url' in ctx.query ? ctx.query.url : 'https://' + ctx.params.url; + if (typeof url !== 'string') { + ctx.status = 400; + return; + } + // Create temp file const [path, cleanup] = await createTemp(); diff --git a/packages/backend/src/server/web/index.ts b/packages/backend/src/server/web/index.ts index e95a115aecec20c47552df9425d8abb0513361eb..a0667f0c200ebf75ae295e71b4f437c713f28a8e 100644 --- a/packages/backend/src/server/web/index.ts +++ b/packages/backend/src/server/web/index.ts @@ -276,6 +276,7 @@ router.get('/@:user/pages/:page', async (ctx, next) => { page: _page, profile, instanceName: meta.name || 'Misskey', + icon: meta.iconUrl, }); if (['public'].includes(page.visibility)) { @@ -305,6 +306,7 @@ router.get('/clips/:clip', async (ctx, next) => { clip: _clip, profile, instanceName: meta.name || 'Misskey', + icon: meta.iconUrl, }); ctx.set('Cache-Control', 'public, max-age=180'); @@ -350,6 +352,7 @@ router.get('/channels/:channel', async (ctx, next) => { await ctx.render('channel', { channel: _channel, instanceName: meta.name || 'Misskey', + icon: meta.iconUrl, }); ctx.set('Cache-Control', 'public, max-age=180'); diff --git a/packages/backend/src/server/web/url-preview.ts b/packages/backend/src/server/web/url-preview.ts index 71465c8083661cfcf9afb351f1a4cb05840af070..26fffbea88abe2eb8b985c2e7dd00700503c8096 100644 --- a/packages/backend/src/server/web/url-preview.ts +++ b/packages/backend/src/server/web/url-preview.ts @@ -9,22 +9,34 @@ import { getJson } from '@/misc/fetch'; const logger = new Logger('url-preview'); module.exports = async (ctx: Koa.Context) => { + const url = ctx.query.url; + if (typeof url !== 'string') { + ctx.status = 400; + return; + } + + const lang = ctx.query.lang; + if (Array.isArray(lang)) { + ctx.status = 400; + return; + } + const meta = await fetchMeta(); logger.info(meta.summalyProxy - ? `(Proxy) Getting preview of ${ctx.query.url}@${ctx.query.lang} ...` - : `Getting preview of ${ctx.query.url}@${ctx.query.lang} ...`); + ? `(Proxy) Getting preview of ${url}@${lang} ...` + : `Getting preview of ${url}@${lang} ...`); try { const summary = meta.summalyProxy ? await getJson(`${meta.summalyProxy}?${query({ - url: ctx.query.url, - lang: ctx.query.lang || 'ja-JP', - })}`) : await summaly(ctx.query.url, { + url: url, + lang: lang ?? 'ja-JP', + })}`) : await summaly(url, { followRedirects: false, - lang: ctx.query.lang || 'ja-JP', + lang: lang ?? 'ja-JP', }); - logger.succ(`Got preview of ${ctx.query.url}: ${summary.title}`); + logger.succ(`Got preview of ${url}: ${summary.title}`); summary.icon = wrap(summary.icon); summary.thumbnail = wrap(summary.thumbnail); @@ -33,8 +45,8 @@ module.exports = async (ctx: Koa.Context) => { ctx.set('Cache-Control', 'max-age=604800, immutable'); ctx.body = summary; - } catch (e) { - logger.warn(`Failed to get preview of ${ctx.query.url}: ${e}`); + } catch (err) { + logger.warn(`Failed to get preview of ${url}: ${err}`); ctx.status = 200; ctx.set('Cache-Control', 'max-age=86400, immutable'); ctx.body = '{}'; diff --git a/packages/backend/src/server/web/views/base.pug b/packages/backend/src/server/web/views/base.pug index 42c068c403015d21b2ffaee53f7ae5bef15e4d07..b8b733dd6016109dc6d42008ec54948b6aa3c564 100644 --- a/packages/backend/src/server/web/views/base.pug +++ b/packages/backend/src/server/web/views/base.pug @@ -21,6 +21,7 @@ html meta(name='referrer' content='origin') meta(name='theme-color' content='#86b300') meta(name='theme-color-orig' content='#86b300') + meta(property='twitter:card' content='summary') meta(property='og:site_name' content= instanceName || 'Misskey') meta(name='viewport' content='width=device-width, initial-scale=1') link(rel='icon' href= icon || '/favicon.ico') @@ -29,8 +30,8 @@ html link(rel='prefetch' href='https://xn--931a.moe/assets/info.jpg') link(rel='prefetch' href='https://xn--931a.moe/assets/not-found.jpg') link(rel='prefetch' href='https://xn--931a.moe/assets/error.jpg') - link(rel='preload' href='https://use.fontawesome.com/releases/v5.15.3/css/all.css' as='style') - link(rel='stylesheet' href='https://use.fontawesome.com/releases/v5.15.3/css/all.css') + link(rel='preload' href='/assets/fontawesome/css/all.css' as='style') + link(rel='stylesheet' href='/assets/fontawesome/css/all.css') title block title @@ -42,7 +43,9 @@ html block meta block og - meta(property='og:image' content=img) + meta(property='og:title' content= title || 'Misskey') + meta(property='og:description' content= desc || '✨🌎✨ A interplanetary communication platform ✨🚀✨') + meta(property='og:image' content= img) style include ../style.css diff --git a/packages/backend/src/server/web/views/channel.pug b/packages/backend/src/server/web/views/channel.pug index 273632f0e0d97ff685ee9c1f09ef31a5abc9173b..486f0ecc47bc2cc1b5ec963b2dd627dcc1da62f0 100644 --- a/packages/backend/src/server/web/views/channel.pug +++ b/packages/backend/src/server/web/views/channel.pug @@ -16,6 +16,3 @@ block og meta(property='og:description' content= channel.description) meta(property='og:url' content= url) meta(property='og:image' content= channel.bannerUrl) - -block meta - meta(name='twitter:card' content='summary') diff --git a/packages/backend/src/server/web/views/clip.pug b/packages/backend/src/server/web/views/clip.pug index 8de53f19d61f5e7784d3c1eb8713fd65ff4679cc..7a84d50f6cbb8bcd1370a9c3e00bccbbc34aa7d6 100644 --- a/packages/backend/src/server/web/views/clip.pug +++ b/packages/backend/src/server/web/views/clip.pug @@ -26,8 +26,6 @@ block meta meta(name='misskey:user-id' content=user.id) meta(name='misskey:clip-id' content=clip.id) - meta(name='twitter:card' content='summary') - // todo if user.twitter meta(name='twitter:creator' content=`@${user.twitter.screenName}`) diff --git a/packages/backend/src/server/web/views/gallery-post.pug b/packages/backend/src/server/web/views/gallery-post.pug index 95bbb2437c2d1fb9e448420f3bda3c2c55b069ce..ca0663a4811edd549040876532318625856063cf 100644 --- a/packages/backend/src/server/web/views/gallery-post.pug +++ b/packages/backend/src/server/web/views/gallery-post.pug @@ -25,8 +25,6 @@ block meta meta(name='misskey:user-username' content=user.username) meta(name='misskey:user-id' content=user.id) - meta(name='twitter:card' content='summary') - // todo if user.twitter meta(name='twitter:creator' content=`@${user.twitter.screenName}`) diff --git a/packages/backend/src/server/web/views/note.pug b/packages/backend/src/server/web/views/note.pug index fce91bdabeabdf3349ca6d0c5081c4fd46890975..34b03f9833a0a8931b1231ef5105bd1446ad04e8 100644 --- a/packages/backend/src/server/web/views/note.pug +++ b/packages/backend/src/server/web/views/note.pug @@ -26,9 +26,7 @@ block meta meta(name='misskey:user-username' content=user.username) meta(name='misskey:user-id' content=user.id) meta(name='misskey:note-id' content=note.id) - - meta(name='twitter:card' content='summary') - + // todo if user.twitter meta(name='twitter:creator' content=`@${user.twitter.screenName}`) diff --git a/packages/backend/src/server/web/views/page.pug b/packages/backend/src/server/web/views/page.pug index cb9e1039e12a4efe52fd507817b9ef01bb2e5a33..b6c9548025a75cab7fdfd050bf7c4d26cbf74685 100644 --- a/packages/backend/src/server/web/views/page.pug +++ b/packages/backend/src/server/web/views/page.pug @@ -26,8 +26,6 @@ block meta meta(name='misskey:user-id' content=user.id) meta(name='misskey:page-id' content=page.id) - meta(name='twitter:card' content='summary') - // todo if user.twitter meta(name='twitter:creator' content=`@${user.twitter.screenName}`) diff --git a/packages/backend/src/server/web/views/user.pug b/packages/backend/src/server/web/views/user.pug index 1a8a6b44139769342b60cc74cf3829a1b0b7fbd6..2adec0f8892aeda5484646e8ac2e8ff9d70c1a9b 100644 --- a/packages/backend/src/server/web/views/user.pug +++ b/packages/backend/src/server/web/views/user.pug @@ -25,8 +25,6 @@ block meta meta(name='misskey:user-username' content=user.username) meta(name='misskey:user-id' content=user.id) - meta(name='twitter:card' content='summary') - if profile.twitter meta(name='twitter:creator' content=`@${profile.twitter.screenName}`) diff --git a/packages/backend/src/services/chart/charts/active-users.ts b/packages/backend/src/services/chart/charts/active-users.ts index 9490101e36ba462dc028f0aed0be0cce89c16391..87dd95f4dc169fc9d17773fd177cb25724a66f5d 100644 --- a/packages/backend/src/services/chart/charts/active-users.ts +++ b/packages/backend/src/services/chart/charts/active-users.ts @@ -1,51 +1,44 @@ import autobind from 'autobind-decorator'; -import Chart, { Obj, DeepPartial } from '../core'; +import Chart, { KVs } from '../core'; import { User } from '@/models/entities/user'; -import { SchemaType } from '@/misc/schema'; import { Users } from '@/models/index'; import { name, schema } from './entities/active-users'; -type ActiveUsersLog = SchemaType<typeof schema>; +const week = 1000 * 60 * 60 * 24 * 7; +const month = 1000 * 60 * 60 * 24 * 30; +const year = 1000 * 60 * 60 * 24 * 365; /** * アクティブユーザーã«é–¢ã™ã‚‹ãƒãƒ£ãƒ¼ãƒˆ */ // eslint-disable-next-line import/no-default-export -export default class ActiveUsersChart extends Chart<ActiveUsersLog> { +export default class ActiveUsersChart extends Chart<typeof schema> { constructor() { super(name, schema); } @autobind - protected genNewLog(latest: ActiveUsersLog): DeepPartial<ActiveUsersLog> { + protected async queryCurrentState(): Promise<Partial<KVs<typeof schema>>> { return {}; } @autobind - protected aggregate(logs: ActiveUsersLog[]): ActiveUsersLog { - return { - local: { - users: logs.reduce((a, b) => a.concat(b.local.users), [] as ActiveUsersLog['local']['users']), - }, - remote: { - users: logs.reduce((a, b) => a.concat(b.remote.users), [] as ActiveUsersLog['remote']['users']), - }, - }; - } - - @autobind - protected async fetchActual(): Promise<DeepPartial<ActiveUsersLog>> { - return {}; + public async read(user: { id: User['id'], host: null, createdAt: User['createdAt'] }): Promise<void> { + await this.commit({ + 'read': [user.id], + 'registeredWithinWeek': (Date.now() - user.createdAt.getTime() < week) ? [user.id] : [], + 'registeredWithinMonth': (Date.now() - user.createdAt.getTime() < month) ? [user.id] : [], + 'registeredWithinYear': (Date.now() - user.createdAt.getTime() < year) ? [user.id] : [], + 'registeredOutsideWeek': (Date.now() - user.createdAt.getTime() > week) ? [user.id] : [], + 'registeredOutsideMonth': (Date.now() - user.createdAt.getTime() > month) ? [user.id] : [], + 'registeredOutsideYear': (Date.now() - user.createdAt.getTime() > year) ? [user.id] : [], + }); } @autobind - public async update(user: { id: User['id'], host: User['host'] }): Promise<void> { - const update: Obj = { - users: [user.id], - }; - - await this.inc({ - [Users.isLocalUser(user) ? 'local' : 'remote']: update, + public async write(user: { id: User['id'], host: null, createdAt: User['createdAt'] }): Promise<void> { + await this.commit({ + 'write': [user.id], }); } } diff --git a/packages/backend/src/services/chart/charts/ap-request.ts b/packages/backend/src/services/chart/charts/ap-request.ts new file mode 100644 index 0000000000000000000000000000000000000000..bac5e425c80a61e894a7880b7aaf576969c7e918 --- /dev/null +++ b/packages/backend/src/services/chart/charts/ap-request.ts @@ -0,0 +1,39 @@ +import autobind from 'autobind-decorator'; +import Chart, { KVs } from '../core'; +import { name, schema } from './entities/ap-request'; + +/** + * Chart about ActivityPub requests + */ +// eslint-disable-next-line import/no-default-export +export default class ApRequestChart extends Chart<typeof schema> { + constructor() { + super(name, schema); + } + + @autobind + protected async queryCurrentState(): Promise<Partial<KVs<typeof schema>>> { + return {}; + } + + @autobind + public async deliverSucc(): Promise<void> { + await this.commit({ + 'deliverSucceeded': 1, + }); + } + + @autobind + public async deliverFail(): Promise<void> { + await this.commit({ + 'deliverFailed': 1, + }); + } + + @autobind + public async inbox(): Promise<void> { + await this.commit({ + 'inboxReceived': 1, + }); + } +} diff --git a/packages/backend/src/services/chart/charts/drive.ts b/packages/backend/src/services/chart/charts/drive.ts index 06cf7ebeeba29b3bf1399aa2b616f042b2527523..2f00adae2b231e9d70dd6e12b591c4d246c37521 100644 --- a/packages/backend/src/services/chart/charts/drive.ts +++ b/packages/backend/src/services/chart/charts/drive.ts @@ -1,95 +1,37 @@ import autobind from 'autobind-decorator'; -import Chart, { Obj, DeepPartial } from '../core'; -import { SchemaType } from '@/misc/schema'; +import Chart, { KVs } from '../core'; import { DriveFiles } from '@/models/index'; import { Not, IsNull } from 'typeorm'; import { DriveFile } from '@/models/entities/drive-file'; import { name, schema } from './entities/drive'; -type DriveLog = SchemaType<typeof schema>; - /** * ドライブã«é–¢ã™ã‚‹ãƒãƒ£ãƒ¼ãƒˆ */ // eslint-disable-next-line import/no-default-export -export default class DriveChart extends Chart<DriveLog> { +export default class DriveChart extends Chart<typeof schema> { constructor() { super(name, schema); } @autobind - protected genNewLog(latest: DriveLog): DeepPartial<DriveLog> { - return { - local: { - totalCount: latest.local.totalCount, - totalSize: latest.local.totalSize, - }, - remote: { - totalCount: latest.remote.totalCount, - totalSize: latest.remote.totalSize, - }, - }; - } - - @autobind - protected aggregate(logs: DriveLog[]): DriveLog { - return { - local: { - totalCount: logs[0].local.totalCount, - totalSize: logs[0].local.totalSize, - incCount: logs.reduce((a, b) => a + b.local.incCount, 0), - incSize: logs.reduce((a, b) => a + b.local.incSize, 0), - decCount: logs.reduce((a, b) => a + b.local.decCount, 0), - decSize: logs.reduce((a, b) => a + b.local.decSize, 0), - }, - remote: { - totalCount: logs[0].remote.totalCount, - totalSize: logs[0].remote.totalSize, - incCount: logs.reduce((a, b) => a + b.remote.incCount, 0), - incSize: logs.reduce((a, b) => a + b.remote.incSize, 0), - decCount: logs.reduce((a, b) => a + b.remote.decCount, 0), - decSize: logs.reduce((a, b) => a + b.remote.decSize, 0), - }, - }; - } - - @autobind - protected async fetchActual(): Promise<DeepPartial<DriveLog>> { - const [localCount, remoteCount, localSize, remoteSize] = await Promise.all([ - DriveFiles.count({ userHost: null }), - DriveFiles.count({ userHost: Not(IsNull()) }), - DriveFiles.calcDriveUsageOfLocal(), - DriveFiles.calcDriveUsageOfRemote(), - ]); - - return { - local: { - totalCount: localCount, - totalSize: localSize, - }, - remote: { - totalCount: remoteCount, - totalSize: remoteSize, - }, - }; + protected async queryCurrentState(): Promise<Partial<KVs<typeof schema>>> { + return {}; } @autobind public async update(file: DriveFile, isAdditional: boolean): Promise<void> { - const update: Obj = {}; - - update.totalCount = isAdditional ? 1 : -1; - update.totalSize = isAdditional ? file.size : -file.size; - if (isAdditional) { - update.incCount = 1; - update.incSize = file.size; - } else { - update.decCount = 1; - update.decSize = file.size; - } - - await this.inc({ - [file.userHost === null ? 'local' : 'remote']: update, + const fileSizeKb = file.size / 1000; + await this.commit(file.userHost === null ? { + 'local.incCount': isAdditional ? 1 : 0, + 'local.incSize': isAdditional ? fileSizeKb : 0, + 'local.decCount': isAdditional ? 0 : 1, + 'local.decSize': isAdditional ? 0 : fileSizeKb, + } : { + 'remote.incCount': isAdditional ? 1 : 0, + 'remote.incSize': isAdditional ? fileSizeKb : 0, + 'remote.decCount': isAdditional ? 0 : 1, + 'remote.decSize': isAdditional ? 0 : fileSizeKb, }); } } diff --git a/packages/backend/src/services/chart/charts/entities/active-users.ts b/packages/backend/src/services/chart/charts/entities/active-users.ts index d6b49c86c364bb84f6b221654c08f0a780b87f79..843843836d6d9dc3e010b8710f15ad46e3bdd3dd 100644 --- a/packages/backend/src/services/chart/charts/entities/active-users.ts +++ b/packages/backend/src/services/chart/charts/entities/active-users.ts @@ -2,35 +2,16 @@ import Chart from '../../core'; export const name = 'activeUsers'; -const logSchema = { - /** - * アクティブユーザー - */ - users: { - type: 'array' as const, - optional: false as const, nullable: false as const, - items: { - type: 'string' as const, - optional: false as const, nullable: false as const, - }, - }, -}; - export const schema = { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - local: { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: logSchema, - }, - remote: { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: logSchema, - }, - }, -}; + 'readWrite': { intersection: ['read', 'write'], range: 'small' }, + 'read': { uniqueIncrement: true, range: 'small' }, + 'write': { uniqueIncrement: true, range: 'small' }, + 'registeredWithinWeek': { uniqueIncrement: true, range: 'small' }, + 'registeredWithinMonth': { uniqueIncrement: true, range: 'small' }, + 'registeredWithinYear': { uniqueIncrement: true, range: 'small' }, + 'registeredOutsideWeek': { uniqueIncrement: true, range: 'small' }, + 'registeredOutsideMonth': { uniqueIncrement: true, range: 'small' }, + 'registeredOutsideYear': { uniqueIncrement: true, range: 'small' }, +} as const; export const entity = Chart.schemaToEntity(name, schema); diff --git a/packages/backend/src/services/chart/charts/entities/ap-request.ts b/packages/backend/src/services/chart/charts/entities/ap-request.ts new file mode 100644 index 0000000000000000000000000000000000000000..21fb40d1385b2333c98902c6070460f899f76403 --- /dev/null +++ b/packages/backend/src/services/chart/charts/entities/ap-request.ts @@ -0,0 +1,11 @@ +import Chart from '../../core'; + +export const name = 'apRequest'; + +export const schema = { + 'deliverFailed': { }, + 'deliverSucceeded': { }, + 'inboxReceived': { }, +} as const; + +export const entity = Chart.schemaToEntity(name, schema); diff --git a/packages/backend/src/services/chart/charts/entities/drive.ts b/packages/backend/src/services/chart/charts/entities/drive.ts index 3362cbd4cb0863d1970e04c0993f075677fe2850..c5cdfd85bd732549082971d8ccebb1397e75c7c2 100644 --- a/packages/backend/src/services/chart/charts/entities/drive.ts +++ b/packages/backend/src/services/chart/charts/entities/drive.ts @@ -2,71 +2,15 @@ import Chart from '../../core'; export const name = 'drive'; -const logSchema = { - /** - * 集計期間時点ã§ã®ã€å…¨ãƒ‰ãƒ©ã‚¤ãƒ–ファイル数 - */ - totalCount: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - - /** - * 集計期間時点ã§ã®ã€å…¨ãƒ‰ãƒ©ã‚¤ãƒ–ファイルã®åˆè¨ˆã‚µã‚¤ã‚º - */ - totalSize: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - - /** - * å¢—åŠ ã—ãŸãƒ‰ãƒ©ã‚¤ãƒ–ファイル数 - */ - incCount: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - - /** - * å¢—åŠ ã—ãŸãƒ‰ãƒ©ã‚¤ãƒ–ä½¿ç”¨é‡ - */ - incSize: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - - /** - * 減少ã—ãŸãƒ‰ãƒ©ã‚¤ãƒ–ファイル数 - */ - decCount: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - - /** - * 減少ã—ãŸãƒ‰ãƒ©ã‚¤ãƒ–ä½¿ç”¨é‡ - */ - decSize: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, -}; - export const schema = { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - local: { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: logSchema, - }, - remote: { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: logSchema, - }, - }, -}; + 'local.incCount': {}, + 'local.incSize': {}, // in kilobyte + 'local.decCount': {}, + 'local.decSize': {}, // in kilobyte + 'remote.incCount': {}, + 'remote.incSize': {}, // in kilobyte + 'remote.decCount': {}, + 'remote.decSize': {}, // in kilobyte +} as const; export const entity = Chart.schemaToEntity(name, schema); diff --git a/packages/backend/src/services/chart/charts/entities/federation.ts b/packages/backend/src/services/chart/charts/entities/federation.ts index 836116bd0600716fb4c3ed174370325a4c870764..0c8c20991d58d5c3245c8d2b1ef703a630d0f37e 100644 --- a/packages/backend/src/services/chart/charts/entities/federation.ts +++ b/packages/backend/src/services/chart/charts/entities/federation.ts @@ -3,28 +3,12 @@ import Chart from '../../core'; export const name = 'federation'; export const schema = { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - instance: { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - total: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - inc: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - dec: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - }, - }, - }, -}; + 'instance.total': { accumulate: true }, + 'instance.inc': { range: 'small' }, + 'instance.dec': { range: 'small' }, + 'deliveredInstances': { uniqueIncrement: true, range: 'small' }, + 'inboxInstances': { uniqueIncrement: true, range: 'small' }, + 'stalled': { uniqueIncrement: true, range: 'small' }, +} as const; export const entity = Chart.schemaToEntity(name, schema); diff --git a/packages/backend/src/services/chart/charts/entities/hashtag.ts b/packages/backend/src/services/chart/charts/entities/hashtag.ts index 43e15456a555c76664489e80cf05433e5d57728d..bd2ae38a165aa305b835a58bf8397466655cd991 100644 --- a/packages/backend/src/services/chart/charts/entities/hashtag.ts +++ b/packages/backend/src/services/chart/charts/entities/hashtag.ts @@ -2,35 +2,9 @@ import Chart from '../../core'; export const name = 'hashtag'; -const logSchema = { - /** - * 投稿ã—ãŸãƒ¦ãƒ¼ã‚¶ãƒ¼ - */ - users: { - type: 'array' as const, - optional: false as const, nullable: false as const, - items: { - type: 'string' as const, - optional: false as const, nullable: false as const, - }, - }, -}; - export const schema = { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - local: { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: logSchema, - }, - remote: { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: logSchema, - }, - }, -}; + 'local.users': { uniqueIncrement: true }, + 'remote.users': { uniqueIncrement: true }, +} as const; export const entity = Chart.schemaToEntity(name, schema, true); diff --git a/packages/backend/src/services/chart/charts/entities/instance.ts b/packages/backend/src/services/chart/charts/entities/instance.ts index 9d1f651dbbfe75678b56fcda2e0b21e369ff758e..b98e1640c8f1e7654d29ef15547e296a373c4751 100644 --- a/packages/backend/src/services/chart/charts/entities/instance.ts +++ b/packages/backend/src/services/chart/charts/entities/instance.ts @@ -3,156 +3,30 @@ import Chart from '../../core'; export const name = 'instance'; export const schema = { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - requests: { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - failed: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - succeeded: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - received: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - }, - }, - - notes: { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - total: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - inc: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - dec: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - - diffs: { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - normal: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - - reply: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - - renote: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - }, - }, - }, - }, - - users: { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - total: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - inc: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - dec: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - }, - }, - - following: { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - total: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - inc: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - dec: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - }, - }, - - followers: { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - total: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - inc: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - dec: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - }, - }, - - drive: { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - totalFiles: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - totalUsage: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - incFiles: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - incUsage: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - decFiles: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - decUsage: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - }, - }, - }, -}; + 'requests.failed': { range: 'small' }, + 'requests.succeeded': { range: 'small' }, + 'requests.received': { range: 'small' }, + 'notes.total': { accumulate: true }, + 'notes.inc': {}, + 'notes.dec': {}, + 'notes.diffs.normal': {}, + 'notes.diffs.reply': {}, + 'notes.diffs.renote': {}, + 'notes.diffs.withFile': {}, + 'users.total': { accumulate: true }, + 'users.inc': { range: 'small' }, + 'users.dec': { range: 'small' }, + 'following.total': { accumulate: true }, + 'following.inc': { range: 'small' }, + 'following.dec': { range: 'small' }, + 'followers.total': { accumulate: true }, + 'followers.inc': { range: 'small' }, + 'followers.dec': { range: 'small' }, + 'drive.totalFiles': { accumulate: true }, + 'drive.incFiles': {}, + 'drive.decFiles': {}, + 'drive.incUsage': {}, // in kilobyte + 'drive.decUsage': {}, // in kilobyte +} as const; export const entity = Chart.schemaToEntity(name, schema, true); diff --git a/packages/backend/src/services/chart/charts/entities/network.ts b/packages/backend/src/services/chart/charts/entities/network.ts deleted file mode 100644 index 3d4fffb855de7939c6813451de9aa0a2cfe693b5..0000000000000000000000000000000000000000 --- a/packages/backend/src/services/chart/charts/entities/network.ts +++ /dev/null @@ -1,32 +0,0 @@ -import Chart from '../../core'; - -export const name = 'network'; - -export const schema = { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - incomingRequests: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - outgoingRequests: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - totalTime: { // TIP: (totalTime / incomingRequests) ã§ã²ã¨ã¤ã®ãƒªã‚¯ã‚¨ã‚¹ãƒˆã«å¹³å‡ã§ã©ã‚Œãらã„ã®æ™‚é–“ãŒã‹ã‹ã£ãŸã‹çŸ¥ã‚Œã‚‹ - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - incomingBytes: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - outgoingBytes: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - }, -}; - -export const entity = Chart.schemaToEntity(name, schema); diff --git a/packages/backend/src/services/chart/charts/entities/notes.ts b/packages/backend/src/services/chart/charts/entities/notes.ts index 554d3abe126848828ffdea8f7b9c0b321cf31989..f9b9b20eedfd72d8b60e249008d325274989300e 100644 --- a/packages/backend/src/services/chart/charts/entities/notes.ts +++ b/packages/backend/src/services/chart/charts/entities/notes.ts @@ -2,59 +2,21 @@ import Chart from '../../core'; export const name = 'notes'; -const logSchema = { - total: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - - inc: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - - dec: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - - diffs: { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - normal: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - - reply: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - - renote: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - }, - }, -}; - export const schema = { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - local: { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: logSchema, - }, - remote: { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: logSchema, - }, - }, -}; + 'local.total': { accumulate: true }, + 'local.inc': {}, + 'local.dec': {}, + 'local.diffs.normal': {}, + 'local.diffs.reply': {}, + 'local.diffs.renote': {}, + 'local.diffs.withFile': {}, + 'remote.total': { accumulate: true }, + 'remote.inc': {}, + 'remote.dec': {}, + 'remote.diffs.normal': {}, + 'remote.diffs.reply': {}, + 'remote.diffs.renote': {}, + 'remote.diffs.withFile': {}, +} as const; export const entity = Chart.schemaToEntity(name, schema); diff --git a/packages/backend/src/services/chart/charts/entities/per-user-drive.ts b/packages/backend/src/services/chart/charts/entities/per-user-drive.ts index ebf64e733e5ccd7b72c14fb4bcbf4e8f6449277d..00d85b1620fbae247dcb6e9d615423e65a11b8c7 100644 --- a/packages/backend/src/services/chart/charts/entities/per-user-drive.ts +++ b/packages/backend/src/services/chart/charts/entities/per-user-drive.ts @@ -3,57 +3,12 @@ import Chart from '../../core'; export const name = 'perUserDrive'; export const schema = { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - /** - * 集計期間時点ã§ã®ã€å…¨ãƒ‰ãƒ©ã‚¤ãƒ–ファイル数 - */ - totalCount: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - - /** - * 集計期間時点ã§ã®ã€å…¨ãƒ‰ãƒ©ã‚¤ãƒ–ファイルã®åˆè¨ˆã‚µã‚¤ã‚º - */ - totalSize: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - - /** - * å¢—åŠ ã—ãŸãƒ‰ãƒ©ã‚¤ãƒ–ファイル数 - */ - incCount: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - - /** - * å¢—åŠ ã—ãŸãƒ‰ãƒ©ã‚¤ãƒ–ä½¿ç”¨é‡ - */ - incSize: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - - /** - * 減少ã—ãŸãƒ‰ãƒ©ã‚¤ãƒ–ファイル数 - */ - decCount: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - - /** - * 減少ã—ãŸãƒ‰ãƒ©ã‚¤ãƒ–ä½¿ç”¨é‡ - */ - decSize: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - }, -}; + 'totalCount': { accumulate: true }, + 'totalSize': { accumulate: true }, // in kilobyte + 'incCount': { range: 'small' }, + 'incSize': {}, // in kilobyte + 'decCount': { range: 'small' }, + 'decSize': {}, // in kilobyte +} as const; export const entity = Chart.schemaToEntity(name, schema, true); diff --git a/packages/backend/src/services/chart/charts/entities/per-user-following.ts b/packages/backend/src/services/chart/charts/entities/per-user-following.ts index 8016c5fe979953bba8340ae8196898b652d97661..1efd4977fcd5b84047e71be59cbc3eaa3c11be3b 100644 --- a/packages/backend/src/services/chart/charts/entities/per-user-following.ts +++ b/packages/backend/src/services/chart/charts/entities/per-user-following.ts @@ -2,89 +2,19 @@ import Chart from '../../core'; export const name = 'perUserFollowing'; -const logSchema = { - /** - * フォãƒãƒ¼ã—ã¦ã„ã‚‹ - */ - followings: { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - /** - * フォãƒãƒ¼ã—ã¦ã„ã‚‹åˆè¨ˆ - */ - total: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - - /** - * フォãƒãƒ¼ã—ãŸæ•° - */ - inc: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - - /** - * フォãƒãƒ¼è§£é™¤ã—ãŸæ•° - */ - dec: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - }, - }, - - /** - * フォãƒãƒ¼ã•ã‚Œã¦ã„ã‚‹ - */ - followers: { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - /** - * フォãƒãƒ¼ã•ã‚Œã¦ã„ã‚‹åˆè¨ˆ - */ - total: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - - /** - * フォãƒãƒ¼ã•ã‚ŒãŸæ•° - */ - inc: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - - /** - * フォãƒãƒ¼è§£é™¤ã•ã‚ŒãŸæ•° - */ - dec: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - }, - }, -}; - export const schema = { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - local: { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: logSchema, - }, - remote: { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: logSchema, - }, - }, -}; + 'local.followings.total': { accumulate: true }, + 'local.followings.inc': { range: 'small' }, + 'local.followings.dec': { range: 'small' }, + 'local.followers.total': { accumulate: true }, + 'local.followers.inc': { range: 'small' }, + 'local.followers.dec': { range: 'small' }, + 'remote.followings.total': { accumulate: true }, + 'remote.followings.inc': { range: 'small' }, + 'remote.followings.dec': { range: 'small' }, + 'remote.followers.total': { accumulate: true }, + 'remote.followers.inc': { range: 'small' }, + 'remote.followers.dec': { range: 'small' }, +} as const; export const entity = Chart.schemaToEntity(name, schema, true); diff --git a/packages/backend/src/services/chart/charts/entities/per-user-notes.ts b/packages/backend/src/services/chart/charts/entities/per-user-notes.ts index d8f645b36edd3ac0f8b0bb199e166fd023eaa612..562cde9b000e4e06c3c5a97faf4699754ea5c7a5 100644 --- a/packages/backend/src/services/chart/charts/entities/per-user-notes.ts +++ b/packages/backend/src/services/chart/charts/entities/per-user-notes.ts @@ -3,45 +3,13 @@ import Chart from '../../core'; export const name = 'perUserNotes'; export const schema = { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - total: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - - inc: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - - dec: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - - diffs: { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - normal: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - - reply: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - - renote: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - }, - }, - }, -}; + 'total': { accumulate: true }, + 'inc': { range: 'small' }, + 'dec': { range: 'small' }, + 'diffs.normal': { range: 'small' }, + 'diffs.reply': { range: 'small' }, + 'diffs.renote': { range: 'small' }, + 'diffs.withFile': { range: 'small' }, +} as const; export const entity = Chart.schemaToEntity(name, schema, true); diff --git a/packages/backend/src/services/chart/charts/entities/per-user-reactions.ts b/packages/backend/src/services/chart/charts/entities/per-user-reactions.ts index bcb7012661e040f2e563f365faa4455d77762e4d..ab315d24c9ecc3511bb0a2f175b9ce670c406257 100644 --- a/packages/backend/src/services/chart/charts/entities/per-user-reactions.ts +++ b/packages/backend/src/services/chart/charts/entities/per-user-reactions.ts @@ -2,31 +2,9 @@ import Chart from '../../core'; export const name = 'perUserReaction'; -const logSchema = { - /** - * 被リアクション数 - */ - count: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, -}; - export const schema = { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - local: { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: logSchema, - }, - remote: { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: logSchema, - }, - }, -}; + 'local.count': { range: 'small' }, + 'remote.count': { range: 'small' }, +} as const; export const entity = Chart.schemaToEntity(name, schema, true); diff --git a/packages/backend/src/services/chart/charts/entities/test-grouped.ts b/packages/backend/src/services/chart/charts/entities/test-grouped.ts index ca1c8c57004345022bef565a5c75634aa5c60647..78c2bbd5480f5bee2bf7ce28177525bfab8d1814 100644 --- a/packages/backend/src/services/chart/charts/entities/test-grouped.ts +++ b/packages/backend/src/services/chart/charts/entities/test-grouped.ts @@ -3,30 +3,9 @@ import Chart from '../../core'; export const name = 'testGrouped'; export const schema = { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - foo: { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - total: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - - inc: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - - dec: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - }, - }, - }, -}; + 'foo.total': { accumulate: true }, + 'foo.inc': {}, + 'foo.dec': {}, +} as const; export const entity = Chart.schemaToEntity(name, schema, true); diff --git a/packages/backend/src/services/chart/charts/entities/test-intersection.ts b/packages/backend/src/services/chart/charts/entities/test-intersection.ts new file mode 100644 index 0000000000000000000000000000000000000000..dc56eb93f5327e9f7293f4aa6db0ea206b22ef65 --- /dev/null +++ b/packages/backend/src/services/chart/charts/entities/test-intersection.ts @@ -0,0 +1,11 @@ +import Chart from '../../core'; + +export const name = 'testIntersection'; + +export const schema = { + 'a': { uniqueIncrement: true }, + 'b': { uniqueIncrement: true }, + 'aAndB': { intersection: ['a', 'b'] }, +} as const; + +export const entity = Chart.schemaToEntity(name, schema); diff --git a/packages/backend/src/services/chart/charts/entities/test-unique.ts b/packages/backend/src/services/chart/charts/entities/test-unique.ts index 2e917ee9edbe706a1d72e1a976ac8241a50af4d6..dc7c1520e1a0fb8dbf3ed69bc63d3f3959e7d228 100644 --- a/packages/backend/src/services/chart/charts/entities/test-unique.ts +++ b/packages/backend/src/services/chart/charts/entities/test-unique.ts @@ -3,18 +3,7 @@ import Chart from '../../core'; export const name = 'testUnique'; export const schema = { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - foo: { - type: 'array' as const, - optional: false as const, nullable: false as const, - items: { - type: 'string' as const, - optional: false as const, nullable: false as const, - }, - }, - }, -}; + 'foo': { uniqueIncrement: true }, +} as const; export const entity = Chart.schemaToEntity(name, schema); diff --git a/packages/backend/src/services/chart/charts/entities/test.ts b/packages/backend/src/services/chart/charts/entities/test.ts index fa536ff2cf24d764ff80919213b8e3a919aee15a..edfa4c524b98fc0c61687c8c874f3efdcdbfabad 100644 --- a/packages/backend/src/services/chart/charts/entities/test.ts +++ b/packages/backend/src/services/chart/charts/entities/test.ts @@ -3,30 +3,9 @@ import Chart from '../../core'; export const name = 'test'; export const schema = { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - foo: { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - total: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - - inc: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - - dec: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - }, - }, - }, -}; + 'foo.total': { accumulate: true }, + 'foo.inc': {}, + 'foo.dec': {}, +} as const; export const entity = Chart.schemaToEntity(name, schema); diff --git a/packages/backend/src/services/chart/charts/entities/users.ts b/packages/backend/src/services/chart/charts/entities/users.ts index 08d51c941428ab5d0448362a7f942e13a3c0f8d4..d2cec724972034aa9bbaf8f9ac20b375a1594497 100644 --- a/packages/backend/src/services/chart/charts/entities/users.ts +++ b/packages/backend/src/services/chart/charts/entities/users.ts @@ -2,47 +2,13 @@ import Chart from '../../core'; export const name = 'users'; -const logSchema = { - /** - * 集計期間時点ã§ã®ã€å…¨ãƒ¦ãƒ¼ã‚¶ãƒ¼æ•° - */ - total: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - - /** - * å¢—åŠ ã—ãŸãƒ¦ãƒ¼ã‚¶ãƒ¼æ•° - */ - inc: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - - /** - * 減少ã—ãŸãƒ¦ãƒ¼ã‚¶ãƒ¼æ•° - */ - dec: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, -}; - export const schema = { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - local: { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: logSchema, - }, - remote: { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: logSchema, - }, - }, -}; + 'local.total': { accumulate: true }, + 'local.inc': { range: 'small' }, + 'local.dec': { range: 'small' }, + 'remote.total': { accumulate: true }, + 'remote.inc': { range: 'small' }, + 'remote.dec': { range: 'small' }, +} as const; export const entity = Chart.schemaToEntity(name, schema); diff --git a/packages/backend/src/services/chart/charts/federation.ts b/packages/backend/src/services/chart/charts/federation.ts index 8abb18b51fe186407cc9803da962d7818967234e..19c75c98adedfbda45e21de0d451b1a2e744a11d 100644 --- a/packages/backend/src/services/chart/charts/federation.ts +++ b/packages/backend/src/services/chart/charts/federation.ts @@ -1,66 +1,50 @@ import autobind from 'autobind-decorator'; -import Chart, { Obj, DeepPartial } from '../core'; -import { SchemaType } from '@/misc/schema'; +import Chart, { KVs } from '../core'; import { Instances } from '@/models/index'; import { name, schema } from './entities/federation'; -type FederationLog = SchemaType<typeof schema>; - /** * フェデレーションã«é–¢ã™ã‚‹ãƒãƒ£ãƒ¼ãƒˆ */ // eslint-disable-next-line import/no-default-export -export default class FederationChart extends Chart<FederationLog> { +export default class FederationChart extends Chart<typeof schema> { constructor() { super(name, schema); } @autobind - protected genNewLog(latest: FederationLog): DeepPartial<FederationLog> { - return { - instance: { - total: latest.instance.total, - }, - }; - } - - @autobind - protected aggregate(logs: FederationLog[]): FederationLog { - return { - instance: { - total: logs[0].instance.total, - inc: logs.reduce((a, b) => a + b.instance.inc, 0), - dec: logs.reduce((a, b) => a + b.instance.dec, 0), - }, - }; - } - - @autobind - protected async fetchActual(): Promise<DeepPartial<FederationLog>> { + protected async queryCurrentState(): Promise<Partial<KVs<typeof schema>>> { const [total] = await Promise.all([ Instances.count({}), ]); return { - instance: { - total: total, - }, + 'instance.total': total, }; } @autobind public async update(isAdditional: boolean): Promise<void> { - const update: Obj = {}; + await this.commit({ + 'instance.total': isAdditional ? 1 : -1, + 'instance.inc': isAdditional ? 1 : 0, + 'instance.dec': isAdditional ? 0 : 1, + }); + } - update.total = isAdditional ? 1 : -1; - if (isAdditional) { - update.inc = 1; - } else { - update.dec = 1; - } + @autobind + public async deliverd(host: string, succeeded: boolean): Promise<void> { + await this.commit(succeeded ? { + 'deliveredInstances': [host], + } : { + 'stalled': [host], + }); + } - await this.inc({ - instance: update, + @autobind + public async inbox(host: string): Promise<void> { + await this.commit({ + 'inboxInstances': [host], }); } } diff --git a/packages/backend/src/services/chart/charts/hashtag.ts b/packages/backend/src/services/chart/charts/hashtag.ts index 34e0614643abc7a21c6f324c80f3c3251eb5902a..0b7bc467d2507f18e0675d00e136703a27f57c7e 100644 --- a/packages/backend/src/services/chart/charts/hashtag.ts +++ b/packages/backend/src/services/chart/charts/hashtag.ts @@ -1,51 +1,28 @@ import autobind from 'autobind-decorator'; -import Chart, { Obj, DeepPartial } from '../core'; +import Chart, { KVs } from '../core'; import { User } from '@/models/entities/user'; -import { SchemaType } from '@/misc/schema'; import { Users } from '@/models/index'; import { name, schema } from './entities/hashtag'; -type HashtagLog = SchemaType<typeof schema>; - /** * ãƒãƒƒã‚·ãƒ¥ã‚¿ã‚°ã«é–¢ã™ã‚‹ãƒãƒ£ãƒ¼ãƒˆ */ // eslint-disable-next-line import/no-default-export -export default class HashtagChart extends Chart<HashtagLog> { +export default class HashtagChart extends Chart<typeof schema> { constructor() { super(name, schema, true); } @autobind - protected genNewLog(latest: HashtagLog): DeepPartial<HashtagLog> { - return {}; - } - - @autobind - protected aggregate(logs: HashtagLog[]): HashtagLog { - return { - local: { - users: logs.reduce((a, b) => a.concat(b.local.users), [] as HashtagLog['local']['users']), - }, - remote: { - users: logs.reduce((a, b) => a.concat(b.remote.users), [] as HashtagLog['remote']['users']), - }, - }; - } - - @autobind - protected async fetchActual(): Promise<DeepPartial<HashtagLog>> { + protected async queryCurrentState(): Promise<Partial<KVs<typeof schema>>> { return {}; } @autobind public async update(hashtag: string, user: { id: User['id'], host: User['host'] }): Promise<void> { - const update: Obj = { - users: [user.id], - }; - - await this.inc({ - [Users.isLocalUser(user) ? 'local' : 'remote']: update, + await this.commit({ + 'local.users': Users.isLocalUser(user) ? [user.id] : [], + 'remote.users': Users.isLocalUser(user) ? [] : [user.id], }, hashtag); } } diff --git a/packages/backend/src/services/chart/charts/instance.ts b/packages/backend/src/services/chart/charts/instance.ts index 7f3419b69cf02e995763ba43e7997aa521b882bd..5ea4d567e108e16f4eab616071b68ecb5692014e 100644 --- a/packages/backend/src/services/chart/charts/instance.ts +++ b/packages/backend/src/services/chart/charts/instance.ts @@ -1,221 +1,110 @@ import autobind from 'autobind-decorator'; -import Chart, { Obj, DeepPartial } from '../core'; -import { SchemaType } from '@/misc/schema'; +import Chart, { KVs } from '../core'; import { DriveFiles, Followings, Users, Notes } from '@/models/index'; import { DriveFile } from '@/models/entities/drive-file'; import { Note } from '@/models/entities/note'; import { toPuny } from '@/misc/convert-host'; import { name, schema } from './entities/instance'; -type InstanceLog = SchemaType<typeof schema>; - /** * インスタンスã”ã¨ã®ãƒãƒ£ãƒ¼ãƒˆ */ // eslint-disable-next-line import/no-default-export -export default class InstanceChart extends Chart<InstanceLog> { +export default class InstanceChart extends Chart<typeof schema> { constructor() { super(name, schema, true); } @autobind - protected genNewLog(latest: InstanceLog): DeepPartial<InstanceLog> { - return { - notes: { - total: latest.notes.total, - }, - users: { - total: latest.users.total, - }, - following: { - total: latest.following.total, - }, - followers: { - total: latest.followers.total, - }, - drive: { - totalFiles: latest.drive.totalFiles, - totalUsage: latest.drive.totalUsage, - }, - }; - } - - @autobind - protected aggregate(logs: InstanceLog[]): InstanceLog { - return { - requests: { - failed: logs.reduce((a, b) => a + b.requests.failed, 0), - succeeded: logs.reduce((a, b) => a + b.requests.succeeded, 0), - received: logs.reduce((a, b) => a + b.requests.received, 0), - }, - notes: { - total: logs[0].notes.total, - inc: logs.reduce((a, b) => a + b.notes.inc, 0), - dec: logs.reduce((a, b) => a + b.notes.dec, 0), - diffs: { - reply: logs.reduce((a, b) => a + b.notes.diffs.reply, 0), - renote: logs.reduce((a, b) => a + b.notes.diffs.renote, 0), - normal: logs.reduce((a, b) => a + b.notes.diffs.normal, 0), - }, - }, - users: { - total: logs[0].users.total, - inc: logs.reduce((a, b) => a + b.users.inc, 0), - dec: logs.reduce((a, b) => a + b.users.dec, 0), - }, - following: { - total: logs[0].following.total, - inc: logs.reduce((a, b) => a + b.following.inc, 0), - dec: logs.reduce((a, b) => a + b.following.dec, 0), - }, - followers: { - total: logs[0].followers.total, - inc: logs.reduce((a, b) => a + b.followers.inc, 0), - dec: logs.reduce((a, b) => a + b.followers.dec, 0), - }, - drive: { - totalFiles: logs[0].drive.totalFiles, - totalUsage: logs[0].drive.totalUsage, - incFiles: logs.reduce((a, b) => a + b.drive.incFiles, 0), - incUsage: logs.reduce((a, b) => a + b.drive.incUsage, 0), - decFiles: logs.reduce((a, b) => a + b.drive.decFiles, 0), - decUsage: logs.reduce((a, b) => a + b.drive.decUsage, 0), - }, - }; - } - - @autobind - protected async fetchActual(group: string): Promise<DeepPartial<InstanceLog>> { + protected async queryCurrentState(group: string): Promise<Partial<KVs<typeof schema>>> { const [ notesCount, usersCount, followingCount, followersCount, driveFiles, - driveUsage, + //driveUsage, ] = await Promise.all([ Notes.count({ userHost: group }), Users.count({ host: group }), Followings.count({ followerHost: group }), Followings.count({ followeeHost: group }), DriveFiles.count({ userHost: group }), - DriveFiles.calcDriveUsageOfHost(group), + //DriveFiles.calcDriveUsageOfHost(group), ]); return { - notes: { - total: notesCount, - }, - users: { - total: usersCount, - }, - following: { - total: followingCount, - }, - followers: { - total: followersCount, - }, - drive: { - totalFiles: driveFiles, - totalUsage: driveUsage, - }, + 'notes.total': notesCount, + 'users.total': usersCount, + 'following.total': followingCount, + 'followers.total': followersCount, + 'drive.totalFiles': driveFiles, }; } @autobind public async requestReceived(host: string): Promise<void> { - await this.inc({ - requests: { - received: 1, - }, + await this.commit({ + 'requests.received': 1, }, toPuny(host)); } @autobind public async requestSent(host: string, isSucceeded: boolean): Promise<void> { - const update: Obj = {}; - - if (isSucceeded) { - update.succeeded = 1; - } else { - update.failed = 1; - } - - await this.inc({ - requests: update, + await this.commit({ + 'requests.succeeded': isSucceeded ? 1 : 0, + 'requests.failed': isSucceeded ? 0 : 1, }, toPuny(host)); } @autobind public async newUser(host: string): Promise<void> { - await this.inc({ - users: { - total: 1, - inc: 1, - }, + await this.commit({ + 'users.total': 1, + 'users.inc': 1, }, toPuny(host)); } @autobind public async updateNote(host: string, note: Note, isAdditional: boolean): Promise<void> { - const diffs = {} as Record<string, unknown>; - - if (note.replyId != null) { - diffs.reply = isAdditional ? 1 : -1; - } else if (note.renoteId != null) { - diffs.renote = isAdditional ? 1 : -1; - } else { - diffs.normal = isAdditional ? 1 : -1; - } - - await this.inc({ - notes: { - total: isAdditional ? 1 : -1, - inc: isAdditional ? 1 : 0, - dec: isAdditional ? 0 : 1, - diffs: diffs, - }, + await this.commit({ + 'notes.total': isAdditional ? 1 : -1, + 'notes.inc': isAdditional ? 1 : 0, + 'notes.dec': isAdditional ? 0 : 1, + 'notes.diffs.normal': note.replyId == null && note.renoteId == null ? (isAdditional ? 1 : -1) : 0, + 'notes.diffs.renote': note.renoteId != null ? (isAdditional ? 1 : -1) : 0, + 'notes.diffs.reply': note.replyId != null ? (isAdditional ? 1 : -1) : 0, + 'notes.diffs.withFile': note.fileIds.length > 0 ? (isAdditional ? 1 : -1) : 0, }, toPuny(host)); } @autobind public async updateFollowing(host: string, isAdditional: boolean): Promise<void> { - await this.inc({ - following: { - total: isAdditional ? 1 : -1, - inc: isAdditional ? 1 : 0, - dec: isAdditional ? 0 : 1, - }, + await this.commit({ + 'following.total': isAdditional ? 1 : -1, + 'following.inc': isAdditional ? 1 : 0, + 'following.dec': isAdditional ? 0 : 1, }, toPuny(host)); } @autobind public async updateFollowers(host: string, isAdditional: boolean): Promise<void> { - await this.inc({ - followers: { - total: isAdditional ? 1 : -1, - inc: isAdditional ? 1 : 0, - dec: isAdditional ? 0 : 1, - }, + await this.commit({ + 'followers.total': isAdditional ? 1 : -1, + 'followers.inc': isAdditional ? 1 : 0, + 'followers.dec': isAdditional ? 0 : 1, }, toPuny(host)); } @autobind public async updateDrive(file: DriveFile, isAdditional: boolean): Promise<void> { - const update: Obj = {}; - - update.totalFiles = isAdditional ? 1 : -1; - update.totalUsage = isAdditional ? file.size : -file.size; - if (isAdditional) { - update.incFiles = 1; - update.incUsage = file.size; - } else { - update.decFiles = 1; - update.decUsage = file.size; - } - - await this.inc({ - drive: update, + const fileSizeKb = file.size / 1000; + await this.commit({ + 'drive.totalFiles': isAdditional ? 1 : -1, + 'drive.incFiles': isAdditional ? 1 : 0, + 'drive.incUsage': isAdditional ? fileSizeKb : 0, + 'drive.decFiles': isAdditional ? 1 : 0, + 'drive.decUsage': isAdditional ? fileSizeKb : 0, }, file.userHost); } } diff --git a/packages/backend/src/services/chart/charts/network.ts b/packages/backend/src/services/chart/charts/network.ts deleted file mode 100644 index 73ea2f7e19201d41e9563ad5d2e66bd79c2236e2..0000000000000000000000000000000000000000 --- a/packages/backend/src/services/chart/charts/network.ts +++ /dev/null @@ -1,49 +0,0 @@ -import autobind from 'autobind-decorator'; -import Chart, { DeepPartial } from '../core'; -import { SchemaType } from '@/misc/schema'; -import { name, schema } from './entities/network'; - -type NetworkLog = SchemaType<typeof schema>; - -/** - * ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã«é–¢ã™ã‚‹ãƒãƒ£ãƒ¼ãƒˆ - */ -// eslint-disable-next-line import/no-default-export -export default class NetworkChart extends Chart<NetworkLog> { - constructor() { - super(name, schema); - } - - @autobind - protected genNewLog(latest: NetworkLog): DeepPartial<NetworkLog> { - return {}; - } - - @autobind - protected aggregate(logs: NetworkLog[]): NetworkLog { - return { - incomingRequests: logs.reduce((a, b) => a + b.incomingRequests, 0), - outgoingRequests: logs.reduce((a, b) => a + b.outgoingRequests, 0), - totalTime: logs.reduce((a, b) => a + b.totalTime, 0), - incomingBytes: logs.reduce((a, b) => a + b.incomingBytes, 0), - outgoingBytes: logs.reduce((a, b) => a + b.outgoingBytes, 0), - }; - } - - @autobind - protected async fetchActual(): Promise<DeepPartial<NetworkLog>> { - return {}; - } - - @autobind - public async update(incomingRequests: number, time: number, incomingBytes: number, outgoingBytes: number): Promise<void> { - const inc: DeepPartial<NetworkLog> = { - incomingRequests: incomingRequests, - totalTime: time, - incomingBytes: incomingBytes, - outgoingBytes: outgoingBytes, - }; - - await this.inc(inc); - } -} diff --git a/packages/backend/src/services/chart/charts/notes.ts b/packages/backend/src/services/chart/charts/notes.ts index 86cda172254394146ceac87ab2d76ff8471ea4cd..5c56a9a7189eff2fb717da768ca6ac5b399daf5a 100644 --- a/packages/backend/src/services/chart/charts/notes.ts +++ b/packages/backend/src/services/chart/charts/notes.ts @@ -1,101 +1,44 @@ import autobind from 'autobind-decorator'; -import Chart, { Obj, DeepPartial } from '../core'; -import { SchemaType } from '@/misc/schema'; +import Chart, { KVs } from '../core'; import { Notes } from '@/models/index'; import { Not, IsNull } from 'typeorm'; import { Note } from '@/models/entities/note'; import { name, schema } from './entities/notes'; -type NotesLog = SchemaType<typeof schema>; - /** * ノートã«é–¢ã™ã‚‹ãƒãƒ£ãƒ¼ãƒˆ */ // eslint-disable-next-line import/no-default-export -export default class NotesChart extends Chart<NotesLog> { +export default class NotesChart extends Chart<typeof schema> { constructor() { super(name, schema); } @autobind - protected genNewLog(latest: NotesLog): DeepPartial<NotesLog> { - return { - local: { - total: latest.local.total, - }, - remote: { - total: latest.remote.total, - }, - }; - } - - @autobind - protected aggregate(logs: NotesLog[]): NotesLog { - return { - local: { - total: logs[0].local.total, - inc: logs.reduce((a, b) => a + b.local.inc, 0), - dec: logs.reduce((a, b) => a + b.local.dec, 0), - diffs: { - reply: logs.reduce((a, b) => a + b.local.diffs.reply, 0), - renote: logs.reduce((a, b) => a + b.local.diffs.renote, 0), - normal: logs.reduce((a, b) => a + b.local.diffs.normal, 0), - }, - }, - remote: { - total: logs[0].remote.total, - inc: logs.reduce((a, b) => a + b.remote.inc, 0), - dec: logs.reduce((a, b) => a + b.remote.dec, 0), - diffs: { - reply: logs.reduce((a, b) => a + b.remote.diffs.reply, 0), - renote: logs.reduce((a, b) => a + b.remote.diffs.renote, 0), - normal: logs.reduce((a, b) => a + b.remote.diffs.normal, 0), - }, - }, - }; - } - - @autobind - protected async fetchActual(): Promise<DeepPartial<NotesLog>> { + protected async queryCurrentState(): Promise<Partial<KVs<typeof schema>>> { const [localCount, remoteCount] = await Promise.all([ Notes.count({ userHost: null }), Notes.count({ userHost: Not(IsNull()) }), ]); return { - local: { - total: localCount, - }, - remote: { - total: remoteCount, - }, + 'local.total': localCount, + 'remote.total': remoteCount, }; } @autobind public async update(note: Note, isAdditional: boolean): Promise<void> { - const update: Obj = { - diffs: {}, - }; - - update.total = isAdditional ? 1 : -1; - - if (isAdditional) { - update.inc = 1; - } else { - update.dec = 1; - } - - if (note.replyId != null) { - update.diffs.reply = isAdditional ? 1 : -1; - } else if (note.renoteId != null) { - update.diffs.renote = isAdditional ? 1 : -1; - } else { - update.diffs.normal = isAdditional ? 1 : -1; - } - - await this.inc({ - [note.userHost === null ? 'local' : 'remote']: update, + const prefix = note.userHost === null ? 'local' : 'remote'; + + await this.commit({ + [`${prefix}.total`]: isAdditional ? 1 : -1, + [`${prefix}.inc`]: isAdditional ? 1 : 0, + [`${prefix}.dec`]: isAdditional ? 0 : 1, + [`${prefix}.diffs.normal`]: note.replyId == null && note.renoteId == null ? (isAdditional ? 1 : -1) : 0, + [`${prefix}.diffs.renote`]: note.renoteId != null ? (isAdditional ? 1 : -1) : 0, + [`${prefix}.diffs.reply`]: note.replyId != null ? (isAdditional ? 1 : -1) : 0, + [`${prefix}.diffs.withFile`]: note.fileIds.length > 0 ? (isAdditional ? 1 : -1) : 0, }); } } diff --git a/packages/backend/src/services/chart/charts/per-user-drive.ts b/packages/backend/src/services/chart/charts/per-user-drive.ts index fff790367f29b554af1912be6bd25add76b9b98c..969ed018f9019b826764274d426306e60f0313be 100644 --- a/packages/backend/src/services/chart/charts/per-user-drive.ts +++ b/packages/backend/src/services/chart/charts/per-user-drive.ts @@ -1,68 +1,41 @@ import autobind from 'autobind-decorator'; -import Chart, { Obj, DeepPartial } from '../core'; -import { SchemaType } from '@/misc/schema'; +import Chart, { KVs } from '../core'; import { DriveFiles } from '@/models/index'; import { DriveFile } from '@/models/entities/drive-file'; import { name, schema } from './entities/per-user-drive'; -type PerUserDriveLog = SchemaType<typeof schema>; - /** * ユーザーã”ã¨ã®ãƒ‰ãƒ©ã‚¤ãƒ–ã«é–¢ã™ã‚‹ãƒãƒ£ãƒ¼ãƒˆ */ // eslint-disable-next-line import/no-default-export -export default class PerUserDriveChart extends Chart<PerUserDriveLog> { +export default class PerUserDriveChart extends Chart<typeof schema> { constructor() { super(name, schema, true); } @autobind - protected genNewLog(latest: PerUserDriveLog): DeepPartial<PerUserDriveLog> { - return { - totalCount: latest.totalCount, - totalSize: latest.totalSize, - }; - } - - @autobind - protected aggregate(logs: PerUserDriveLog[]): PerUserDriveLog { - return { - totalCount: logs[0].totalCount, - totalSize: logs[0].totalSize, - incCount: logs.reduce((a, b) => a + b.incCount, 0), - incSize: logs.reduce((a, b) => a + b.incSize, 0), - decCount: logs.reduce((a, b) => a + b.decCount, 0), - decSize: logs.reduce((a, b) => a + b.decSize, 0), - }; - } - - @autobind - protected async fetchActual(group: string): Promise<DeepPartial<PerUserDriveLog>> { + protected async queryCurrentState(group: string): Promise<Partial<KVs<typeof schema>>> { const [count, size] = await Promise.all([ DriveFiles.count({ userId: group }), DriveFiles.calcDriveUsageOf(group), ]); return { - totalCount: count, - totalSize: size, + 'totalCount': count, + 'totalSize': size, }; } @autobind public async update(file: DriveFile, isAdditional: boolean): Promise<void> { - const update: Obj = {}; - - update.totalCount = isAdditional ? 1 : -1; - update.totalSize = isAdditional ? file.size : -file.size; - if (isAdditional) { - update.incCount = 1; - update.incSize = file.size; - } else { - update.decCount = 1; - update.decSize = file.size; - } - - await this.inc(update, file.userId); + const fileSizeKb = file.size / 1000; + await this.commit({ + 'totalCount': isAdditional ? 1 : -1, + 'totalSize': isAdditional ? fileSizeKb : -fileSizeKb, + 'incCount': isAdditional ? 1 : 0, + 'incSize': isAdditional ? fileSizeKb : 0, + 'decCount': isAdditional ? 0 : 1, + 'decSize': isAdditional ? 0 : fileSizeKb, + }, file.userId); } } diff --git a/packages/backend/src/services/chart/charts/per-user-following.ts b/packages/backend/src/services/chart/charts/per-user-following.ts index d0a80abdafe541fa9050acf2f5c8374743e0966e..cdd0aad9470a471ea6de095a3fae54f2eaf1f3d3 100644 --- a/packages/backend/src/services/chart/charts/per-user-following.ts +++ b/packages/backend/src/services/chart/charts/per-user-following.ts @@ -1,76 +1,21 @@ import autobind from 'autobind-decorator'; -import Chart, { Obj, DeepPartial } from '../core'; -import { SchemaType } from '@/misc/schema'; +import Chart, { KVs } from '../core'; import { Followings, Users } from '@/models/index'; import { Not, IsNull } from 'typeorm'; import { User } from '@/models/entities/user'; import { name, schema } from './entities/per-user-following'; -type PerUserFollowingLog = SchemaType<typeof schema>; - /** * ユーザーã”ã¨ã®ãƒ•ã‚©ãƒãƒ¼ã«é–¢ã™ã‚‹ãƒãƒ£ãƒ¼ãƒˆ */ // eslint-disable-next-line import/no-default-export -export default class PerUserFollowingChart extends Chart<PerUserFollowingLog> { +export default class PerUserFollowingChart extends Chart<typeof schema> { constructor() { super(name, schema, true); } @autobind - protected genNewLog(latest: PerUserFollowingLog): DeepPartial<PerUserFollowingLog> { - return { - local: { - followings: { - total: latest.local.followings.total, - }, - followers: { - total: latest.local.followers.total, - }, - }, - remote: { - followings: { - total: latest.remote.followings.total, - }, - followers: { - total: latest.remote.followers.total, - }, - }, - }; - } - - @autobind - protected aggregate(logs: PerUserFollowingLog[]): PerUserFollowingLog { - return { - local: { - followings: { - total: logs[0].local.followings.total, - inc: logs.reduce((a, b) => a + b.local.followings.inc, 0), - dec: logs.reduce((a, b) => a + b.local.followings.dec, 0), - }, - followers: { - total: logs[0].local.followers.total, - inc: logs.reduce((a, b) => a + b.local.followers.inc, 0), - dec: logs.reduce((a, b) => a + b.local.followers.dec, 0), - }, - }, - remote: { - followings: { - total: logs[0].remote.followings.total, - inc: logs.reduce((a, b) => a + b.remote.followings.inc, 0), - dec: logs.reduce((a, b) => a + b.remote.followings.dec, 0), - }, - followers: { - total: logs[0].remote.followers.total, - inc: logs.reduce((a, b) => a + b.remote.followers.inc, 0), - dec: logs.reduce((a, b) => a + b.remote.followers.dec, 0), - }, - }, - }; - } - - @autobind - protected async fetchActual(group: string): Promise<DeepPartial<PerUserFollowingLog>> { + protected async queryCurrentState(group: string): Promise<Partial<KVs<typeof schema>>> { const [ localFollowingsCount, localFollowersCount, @@ -84,42 +29,27 @@ export default class PerUserFollowingChart extends Chart<PerUserFollowingLog> { ]); return { - local: { - followings: { - total: localFollowingsCount, - }, - followers: { - total: localFollowersCount, - }, - }, - remote: { - followings: { - total: remoteFollowingsCount, - }, - followers: { - total: remoteFollowersCount, - }, - }, + 'local.followings.total': localFollowingsCount, + 'local.followers.total': localFollowersCount, + 'remote.followings.total': remoteFollowingsCount, + 'remote.followers.total': remoteFollowersCount, }; } @autobind public async update(follower: { id: User['id']; host: User['host']; }, followee: { id: User['id']; host: User['host']; }, isFollow: boolean): Promise<void> { - const update: Obj = {}; - - update.total = isFollow ? 1 : -1; - - if (isFollow) { - update.inc = 1; - } else { - update.dec = 1; - } + const prefixFollower = Users.isLocalUser(follower) ? 'local' : 'remote'; + const prefixFollowee = Users.isLocalUser(followee) ? 'local' : 'remote'; - this.inc({ - [Users.isLocalUser(follower) ? 'local' : 'remote']: { followings: update }, + this.commit({ + [`${prefixFollower}.followings.total`]: isFollow ? 1 : -1, + [`${prefixFollower}.followings.inc`]: isFollow ? 1 : 0, + [`${prefixFollower}.followings.dec`]: isFollow ? 0 : 1, }, follower.id); - this.inc({ - [Users.isLocalUser(followee) ? 'local' : 'remote']: { followers: update }, + this.commit({ + [`${prefixFollowee}.followers.total`]: isFollow ? 1 : -1, + [`${prefixFollowee}.followers.inc`]: isFollow ? 1 : 0, + [`${prefixFollowee}.followers.dec`]: isFollow ? 0 : 1, }, followee.id); } } diff --git a/packages/backend/src/services/chart/charts/per-user-notes.ts b/packages/backend/src/services/chart/charts/per-user-notes.ts index d048c888856a329a385a1eacec344b15b02f63fb..6a4f0363b2d4dbf19ce3e44c7af595f122742d62 100644 --- a/packages/backend/src/services/chart/charts/per-user-notes.ts +++ b/packages/backend/src/services/chart/charts/per-user-notes.ts @@ -1,45 +1,21 @@ import autobind from 'autobind-decorator'; -import Chart, { Obj, DeepPartial } from '../core'; +import Chart, { KVs } from '../core'; import { User } from '@/models/entities/user'; -import { SchemaType } from '@/misc/schema'; import { Notes } from '@/models/index'; import { Note } from '@/models/entities/note'; import { name, schema } from './entities/per-user-notes'; -type PerUserNotesLog = SchemaType<typeof schema>; - /** * ユーザーã”ã¨ã®ãƒŽãƒ¼ãƒˆã«é–¢ã™ã‚‹ãƒãƒ£ãƒ¼ãƒˆ */ // eslint-disable-next-line import/no-default-export -export default class PerUserNotesChart extends Chart<PerUserNotesLog> { +export default class PerUserNotesChart extends Chart<typeof schema> { constructor() { super(name, schema, true); } @autobind - protected genNewLog(latest: PerUserNotesLog): DeepPartial<PerUserNotesLog> { - return { - total: latest.total, - }; - } - - @autobind - protected aggregate(logs: PerUserNotesLog[]): PerUserNotesLog { - return { - total: logs[0].total, - inc: logs.reduce((a, b) => a + b.inc, 0), - dec: logs.reduce((a, b) => a + b.dec, 0), - diffs: { - reply: logs.reduce((a, b) => a + b.diffs.reply, 0), - renote: logs.reduce((a, b) => a + b.diffs.renote, 0), - normal: logs.reduce((a, b) => a + b.diffs.normal, 0), - }, - }; - } - - @autobind - protected async fetchActual(group: string): Promise<DeepPartial<PerUserNotesLog>> { + protected async queryCurrentState(group: string): Promise<Partial<KVs<typeof schema>>> { const [count] = await Promise.all([ Notes.count({ userId: group }), ]); @@ -51,26 +27,14 @@ export default class PerUserNotesChart extends Chart<PerUserNotesLog> { @autobind public async update(user: { id: User['id'] }, note: Note, isAdditional: boolean): Promise<void> { - const update: Obj = { - diffs: {}, - }; - - update.total = isAdditional ? 1 : -1; - - if (isAdditional) { - update.inc = 1; - } else { - update.dec = 1; - } - - if (note.replyId != null) { - update.diffs.reply = isAdditional ? 1 : -1; - } else if (note.renoteId != null) { - update.diffs.renote = isAdditional ? 1 : -1; - } else { - update.diffs.normal = isAdditional ? 1 : -1; - } - - await this.inc(update, user.id); + await this.commit({ + 'total': isAdditional ? 1 : -1, + 'inc': isAdditional ? 1 : 0, + 'dec': isAdditional ? 0 : 1, + 'diffs.normal': note.replyId == null && note.renoteId == null ? (isAdditional ? 1 : -1) : 0, + 'diffs.renote': note.renoteId != null ? (isAdditional ? 1 : -1) : 0, + 'diffs.reply': note.replyId != null ? (isAdditional ? 1 : -1) : 0, + 'diffs.withFile': note.fileIds.length > 0 ? (isAdditional ? 1 : -1) : 0, + }, user.id); } } diff --git a/packages/backend/src/services/chart/charts/per-user-reactions.ts b/packages/backend/src/services/chart/charts/per-user-reactions.ts index 2f5353340de95b3ea61a342d76c2a79a3be404bc..2ec347f40ace4efb3ab341ce65526eea735e71a3 100644 --- a/packages/backend/src/services/chart/charts/per-user-reactions.ts +++ b/packages/backend/src/services/chart/charts/per-user-reactions.ts @@ -1,48 +1,29 @@ import autobind from 'autobind-decorator'; -import Chart, { DeepPartial } from '../core'; +import Chart, { KVs } from '../core'; import { User } from '@/models/entities/user'; import { Note } from '@/models/entities/note'; -import { SchemaType } from '@/misc/schema'; import { Users } from '@/models/index'; import { name, schema } from './entities/per-user-reactions'; -type PerUserReactionsLog = SchemaType<typeof schema>; - /** * ユーザーã”ã¨ã®ãƒªã‚¢ã‚¯ã‚·ãƒ§ãƒ³ã«é–¢ã™ã‚‹ãƒãƒ£ãƒ¼ãƒˆ */ // eslint-disable-next-line import/no-default-export -export default class PerUserReactionsChart extends Chart<PerUserReactionsLog> { +export default class PerUserReactionsChart extends Chart<typeof schema> { constructor() { super(name, schema, true); } @autobind - protected genNewLog(latest: PerUserReactionsLog): DeepPartial<PerUserReactionsLog> { - return {}; - } - - @autobind - protected aggregate(logs: PerUserReactionsLog[]): PerUserReactionsLog { - return { - local: { - count: logs.reduce((a, b) => a + b.local.count, 0), - }, - remote: { - count: logs.reduce((a, b) => a + b.remote.count, 0), - }, - }; - } - - @autobind - protected async fetchActual(group: string): Promise<DeepPartial<PerUserReactionsLog>> { + protected async queryCurrentState(group: string): Promise<Partial<KVs<typeof schema>>> { return {}; } @autobind public async update(user: { id: User['id'], host: User['host'] }, note: Note): Promise<void> { - this.inc({ - [Users.isLocalUser(user) ? 'local' : 'remote']: { count: 1 }, + const prefix = Users.isLocalUser(user) ? 'local' : 'remote'; + this.commit({ + [`${prefix}.count`]: 1, }, note.userId); } } diff --git a/packages/backend/src/services/chart/charts/test-grouped.ts b/packages/backend/src/services/chart/charts/test-grouped.ts index c851d2df0140cc7734d720dcb1790b86ee0ed627..5f0b1aafdc6df74d256b5384b4572792902033cf 100644 --- a/packages/backend/src/services/chart/charts/test-grouped.ts +++ b/packages/backend/src/services/chart/charts/test-grouped.ts @@ -1,15 +1,12 @@ import autobind from 'autobind-decorator'; -import Chart, { Obj, DeepPartial } from '../core'; -import { SchemaType } from '@/misc/schema'; +import Chart, { KVs } from '../core'; import { name, schema } from './entities/test-grouped'; -type TestGroupedLog = SchemaType<typeof schema>; - /** * For testing */ // eslint-disable-next-line import/no-default-export -export default class TestGroupedChart extends Chart<TestGroupedLog> { +export default class TestGroupedChart extends Chart<typeof schema> { private total = {} as Record<string, number>; constructor() { @@ -17,31 +14,9 @@ export default class TestGroupedChart extends Chart<TestGroupedLog> { } @autobind - protected genNewLog(latest: TestGroupedLog): DeepPartial<TestGroupedLog> { - return { - foo: { - total: latest.foo.total, - }, - }; - } - - @autobind - protected aggregate(logs: TestGroupedLog[]): TestGroupedLog { + protected async queryCurrentState(group: string): Promise<Partial<KVs<typeof schema>>> { return { - foo: { - total: logs[0].foo.total, - inc: logs.reduce((a, b) => a + b.foo.inc, 0), - dec: logs.reduce((a, b) => a + b.foo.dec, 0), - }, - }; - } - - @autobind - protected async fetchActual(group: string): Promise<DeepPartial<TestGroupedLog>> { - return { - foo: { - total: this.total[group], - }, + 'foo.total': this.total[group], }; } @@ -49,14 +24,11 @@ export default class TestGroupedChart extends Chart<TestGroupedLog> { public async increment(group: string): Promise<void> { if (this.total[group] == null) this.total[group] = 0; - const update: Obj = {}; - - update.total = 1; - update.inc = 1; this.total[group]++; - await this.inc({ - foo: update, + await this.commit({ + 'foo.total': 1, + 'foo.inc': 1, }, group); } } diff --git a/packages/backend/src/services/chart/charts/test-intersection.ts b/packages/backend/src/services/chart/charts/test-intersection.ts new file mode 100644 index 0000000000000000000000000000000000000000..c6ba71a9567f52e356d30709d3dbcae810832789 --- /dev/null +++ b/packages/backend/src/services/chart/charts/test-intersection.ts @@ -0,0 +1,32 @@ +import autobind from 'autobind-decorator'; +import Chart, { KVs } from '../core'; +import { name, schema } from './entities/test-intersection'; + +/** + * For testing + */ +// eslint-disable-next-line import/no-default-export +export default class TestIntersectionChart extends Chart<typeof schema> { + constructor() { + super(name, schema); + } + + @autobind + protected async queryCurrentState(): Promise<Partial<KVs<typeof schema>>> { + return {}; + } + + @autobind + public async addA(key: string): Promise<void> { + await this.commit({ + a: [key], + }); + } + + @autobind + public async addB(key: string): Promise<void> { + await this.commit({ + b: [key], + }); + } +} diff --git a/packages/backend/src/services/chart/charts/test-unique.ts b/packages/backend/src/services/chart/charts/test-unique.ts index 3564f675adfd1d7471d57c3310d8cd1b3cf90d73..e67036acefa048e14974547890c5ad08241067fe 100644 --- a/packages/backend/src/services/chart/charts/test-unique.ts +++ b/packages/backend/src/services/chart/charts/test-unique.ts @@ -1,39 +1,24 @@ import autobind from 'autobind-decorator'; -import Chart, { DeepPartial } from '../core'; -import { SchemaType } from '@/misc/schema'; +import Chart, { KVs } from '../core'; import { name, schema } from './entities/test-unique'; -type TestUniqueLog = SchemaType<typeof schema>; - /** * For testing */ // eslint-disable-next-line import/no-default-export -export default class TestUniqueChart extends Chart<TestUniqueLog> { +export default class TestUniqueChart extends Chart<typeof schema> { constructor() { super(name, schema); } @autobind - protected genNewLog(latest: TestUniqueLog): DeepPartial<TestUniqueLog> { - return {}; - } - - @autobind - protected aggregate(logs: TestUniqueLog[]): TestUniqueLog { - return { - foo: logs.reduce((a, b) => a.concat(b.foo), [] as TestUniqueLog['foo']), - }; - } - - @autobind - protected async fetchActual(): Promise<DeepPartial<TestUniqueLog>> { + protected async queryCurrentState(): Promise<Partial<KVs<typeof schema>>> { return {}; } @autobind public async uniqueIncrement(key: string): Promise<void> { - await this.inc({ + await this.commit({ foo: [key], }); } diff --git a/packages/backend/src/services/chart/charts/test.ts b/packages/backend/src/services/chart/charts/test.ts index 06add7ede9225143a0ce0d60162a002d0085aa9e..878acd51beb1be1e9e890d2f9e48703f5ed93acd 100644 --- a/packages/backend/src/services/chart/charts/test.ts +++ b/packages/backend/src/services/chart/charts/test.ts @@ -1,15 +1,12 @@ import autobind from 'autobind-decorator'; -import Chart, { Obj, DeepPartial } from '../core'; -import { SchemaType } from '@/misc/schema'; +import Chart, { KVs } from '../core'; import { name, schema } from './entities/test'; -type TestLog = SchemaType<typeof schema>; - /** * For testing */ // eslint-disable-next-line import/no-default-export -export default class TestChart extends Chart<TestLog> { +export default class TestChart extends Chart<typeof schema> { public total = 0; // publicã«ã™ã‚‹ã®ã¯ãƒ†ã‚¹ãƒˆã®ãŸã‚ constructor() { @@ -17,57 +14,29 @@ export default class TestChart extends Chart<TestLog> { } @autobind - protected genNewLog(latest: TestLog): DeepPartial<TestLog> { + protected async queryCurrentState(): Promise<Partial<KVs<typeof schema>>> { return { - foo: { - total: latest.foo.total, - }, - }; - } - - @autobind - protected aggregate(logs: TestLog[]): TestLog { - return { - foo: { - total: logs[0].foo.total, - inc: logs.reduce((a, b) => a + b.foo.inc, 0), - dec: logs.reduce((a, b) => a + b.foo.dec, 0), - }, - }; - } - - @autobind - protected async fetchActual(): Promise<DeepPartial<TestLog>> { - return { - foo: { - total: this.total, - }, + 'foo.total': this.total, }; } @autobind public async increment(): Promise<void> { - const update: Obj = {}; - - update.total = 1; - update.inc = 1; this.total++; - await this.inc({ - foo: update, + await this.commit({ + 'foo.total': 1, + 'foo.inc': 1, }); } @autobind public async decrement(): Promise<void> { - const update: Obj = {}; - - update.total = -1; - update.dec = 1; this.total--; - await this.inc({ - foo: update, + await this.commit({ + 'foo.total': -1, + 'foo.dec': 1, }); } } diff --git a/packages/backend/src/services/chart/charts/users.ts b/packages/backend/src/services/chart/charts/users.ts index c36c6cd979694c5905f0c51391e30f9c83b3d7e0..50fca3a8d6b953208e97a0fb402a5a973946f47c 100644 --- a/packages/backend/src/services/chart/charts/users.ts +++ b/packages/backend/src/services/chart/charts/users.ts @@ -1,80 +1,40 @@ import autobind from 'autobind-decorator'; -import Chart, { Obj, DeepPartial } from '../core'; -import { SchemaType } from '@/misc/schema'; +import Chart, { KVs } from '../core'; import { Users } from '@/models/index'; import { Not, IsNull } from 'typeorm'; import { User } from '@/models/entities/user'; import { name, schema } from './entities/users'; -type UsersLog = SchemaType<typeof schema>; - /** * ユーザー数ã«é–¢ã™ã‚‹ãƒãƒ£ãƒ¼ãƒˆ */ // eslint-disable-next-line import/no-default-export -export default class UsersChart extends Chart<UsersLog> { +export default class UsersChart extends Chart<typeof schema> { constructor() { super(name, schema); } @autobind - protected genNewLog(latest: UsersLog): DeepPartial<UsersLog> { - return { - local: { - total: latest.local.total, - }, - remote: { - total: latest.remote.total, - }, - }; - } - - @autobind - protected aggregate(logs: UsersLog[]): UsersLog { - return { - local: { - total: logs[0].local.total, - inc: logs.reduce((a, b) => a + b.local.inc, 0), - dec: logs.reduce((a, b) => a + b.local.dec, 0), - }, - remote: { - total: logs[0].remote.total, - inc: logs.reduce((a, b) => a + b.remote.inc, 0), - dec: logs.reduce((a, b) => a + b.remote.dec, 0), - }, - }; - } - - @autobind - protected async fetchActual(): Promise<DeepPartial<UsersLog>> { + protected async queryCurrentState(): Promise<Partial<KVs<typeof schema>>> { const [localCount, remoteCount] = await Promise.all([ Users.count({ host: null }), Users.count({ host: Not(IsNull()) }), ]); return { - local: { - total: localCount, - }, - remote: { - total: remoteCount, - }, + 'local.total': localCount, + 'remote.total': remoteCount, }; } @autobind public async update(user: { id: User['id'], host: User['host'] }, isAdditional: boolean): Promise<void> { - const update: Obj = {}; - - update.total = isAdditional ? 1 : -1; - if (isAdditional) { - update.inc = 1; - } else { - update.dec = 1; - } + const prefix = Users.isLocalUser(user) ? 'local' : 'remote'; - await this.inc({ - [Users.isLocalUser(user) ? 'local' : 'remote']: update, + await this.commit({ + [`${prefix}.total`]: isAdditional ? 1 : -1, + [`${prefix}.inc`]: isAdditional ? 1 : 0, + [`${prefix}.dec`]: isAdditional ? 0 : 1, }); } } diff --git a/packages/backend/src/services/chart/core.ts b/packages/backend/src/services/chart/core.ts index e406449f4f7b2e04710cae83d72ff825c0d7fada..5888e1a144af4679f23f8286f95ff5a80d52f9e6 100644 --- a/packages/backend/src/services/chart/core.ts +++ b/packages/backend/src/services/chart/core.ts @@ -7,24 +7,19 @@ import * as nestedProperty from 'nested-property'; import autobind from 'autobind-decorator'; import Logger from '../logger'; -import { Schema } from '@/misc/schema'; import { EntitySchema, getRepository, Repository, LessThan, Between } from 'typeorm'; import { dateUTC, isTimeSame, isTimeBefore, subtractTime, addTime } from '@/prelude/time'; import { getChartInsertLock } from '@/misc/app-lock'; const logger = new Logger('chart', 'white', process.env.NODE_ENV !== 'test'); -export type Obj = { [key: string]: any }; +const columnPrefix = '___' as const; +const uniqueTempColumnPrefix = 'unique_temp___' as const; +const columnDot = '_' as const; -export type DeepPartial<T> = { - [P in keyof T]?: DeepPartial<T[P]>; -}; - -type ArrayValue<T> = { - [P in keyof T]: T[P] extends number ? T[P][] : ArrayValue<T[P]>; -}; +type KeyToColumnName<T extends string> = T extends `${infer R1}.${infer R2}` ? `${R1}${typeof columnDot}${KeyToColumnName<R2>}` : T; -type Log = { +type RawRecord<S extends Schema> = { id: number; /** @@ -36,6 +31,10 @@ type Log = { * 集計日時ã®Unixタイムスタンプ(秒) */ date: number; +} & { + [K in keyof S as `${typeof uniqueTempColumnPrefix}${KeyToColumnName<string & K>}`]: S[K]['uniqueIncrement'] extends true ? string[] : never; +} & { + [K in keyof S as `${typeof columnPrefix}${KeyToColumnName<string & K>}`]: number; }; const camelToSnake = (str: string): string => { @@ -44,123 +43,74 @@ const camelToSnake = (str: string): string => { const removeDuplicates = (array: any[]) => Array.from(new Set(array)); +type Schema = Record<string, { + uniqueIncrement?: boolean; + + intersection?: string[] | ReadonlyArray<string>; + + range?: 'big' | 'small' | 'medium'; + + // previousãªå€¤ã‚’引ã継ãã‹ã©ã†ã‹ + accumulate?: boolean; +}>; + +type Commit<S extends Schema> = { + [K in keyof S]?: S[K]['uniqueIncrement'] extends true ? string[] : number; +}; + +export type KVs<S extends Schema> = { + [K in keyof S]: number; +}; + +type ChartResult<T extends Schema> = { + [P in keyof T]: number[]; +}; + /** * 様々ãªãƒãƒ£ãƒ¼ãƒˆã®ç®¡ç†ã‚’å¸ã‚‹ã‚¯ãƒ©ã‚¹ */ // eslint-disable-next-line import/no-default-export -export default abstract class Chart<T extends Record<string, any>> { - private static readonly columnPrefix = '___'; - private static readonly columnDot = '_'; +export default abstract class Chart<T extends Schema> { + public schema: T; private name: string; private buffer: { - diff: DeepPartial<T>; + diff: Commit<T>; group: string | null; }[] = []; - public schema: Schema; - protected repositoryForHour: Repository<Log>; - protected repositoryForDay: Repository<Log>; - - protected abstract genNewLog(latest: T): DeepPartial<T>; - - /** - * @param logs 日時ãŒæ–°ã—ã„æ–¹ãŒå…ˆé - */ - protected abstract aggregate(logs: T[]): T; + protected repositoryForHour: Repository<RawRecord<T>>; + protected repositoryForDay: Repository<RawRecord<T>>; - protected abstract fetchActual(group: string | null): Promise<DeepPartial<T>>; + protected abstract queryCurrentState(group: string | null): Promise<Partial<KVs<T>>>; @autobind - private static convertSchemaToFlatColumnDefinitions(schema: Schema) { - const columns = {} as Record<string, unknown>; - const flatColumns = (x: Obj, path?: string) => { - for (const [k, v] of Object.entries(x)) { - const p = path ? `${path}${this.columnDot}${k}` : k; - if (v.type === 'object') { - flatColumns(v.properties, p); - } else if (v.type === 'number') { - columns[this.columnPrefix + p] = { - type: 'bigint', - }; - } else if (v.type === 'array' && v.items.type === 'string') { - columns[this.columnPrefix + p] = { - type: 'varchar', - array: true, - }; - } + private static convertSchemaToColumnDefinitions(schema: Schema): Record<string, { type: string; array?: boolean; default?: any; }> { + const columns = {} as Record<string, { type: string; array?: boolean; default?: any; }>; + for (const [k, v] of Object.entries(schema)) { + const name = k.replaceAll('.', columnDot); + const type = v.range === 'big' ? 'bigint' : v.range === 'small' ? 'smallint' : 'integer'; + if (v.uniqueIncrement) { + columns[uniqueTempColumnPrefix + name] = { + type: 'varchar', + array: true, + default: '{}', + }; + columns[columnPrefix + name] = { + type, + default: 0, + }; + } else { + columns[columnPrefix + name] = { + type, + default: 0, + }; } - }; - flatColumns(schema.properties!); - return columns; - } - - @autobind - private static convertFlattenColumnsToObject(x: Record<string, unknown>): Record<string, unknown> { - const obj = {} as Record<string, unknown>; - for (const k of Object.keys(x).filter(k => k.startsWith(Chart.columnPrefix))) { - // now k is ___x_y_z - const path = k.substr(Chart.columnPrefix.length).split(Chart.columnDot).join('.'); - nestedProperty.set(obj, path, x[k]); } - return obj; - } - - @autobind - private static convertObjectToFlattenColumns(x: Record<string, unknown>) { - const columns = {} as Record<string, number | unknown[]>; - const flatten = (x: Obj, path?: string) => { - for (const [k, v] of Object.entries(x)) { - const p = path ? `${path}${this.columnDot}${k}` : k; - if (typeof v === 'object' && !Array.isArray(v)) { - flatten(v, p); - } else { - columns[this.columnPrefix + p] = v; - } - } - }; - flatten(x); return columns; } @autobind - private static countUniqueFields(x: Record<string, unknown>) { - const exec = (x: Obj) => { - const res = {} as Record<string, unknown>; - for (const [k, v] of Object.entries(x)) { - if (typeof v === 'object' && !Array.isArray(v)) { - res[k] = exec(v); - } else if (Array.isArray(v)) { - res[k] = Array.from(new Set(v)).length; - } else { - res[k] = v; - } - } - return res; - }; - return exec(x); - } - - @autobind - private static convertQuery(diff: Record<string, number | unknown[]>) { - const query: Record<string, () => string> = {}; - - for (const [k, v] of Object.entries(diff)) { - if (typeof v === 'number') { - if (v > 0) query[k] = () => `"${k}" + ${v}`; - if (v < 0) query[k] = () => `"${k}" - ${Math.abs(v)}`; - } else if (Array.isArray(v)) { - // TODO: item ãŒæ–‡å—列以外ã®å ´åˆã‚‚対応 - // TODO: item ã‚’SQLエスケープ - const items = v.map(item => `"${item}"`).join(','); - query[k] = () => `array_cat("${k}", '{${items}}'::varchar[])`; - } - } - - return query; - } - - @autobind - private static dateToTimestamp(x: Date): Log['date'] { + private static dateToTimestamp(x: Date): number { return Math.floor(x.getTime() / 1000); } @@ -207,7 +157,7 @@ export default abstract class Chart<T extends Record<string, any>> { length: 128, }, } : {}), - ...Chart.convertSchemaToFlatColumnDefinitions(schema), + ...Chart.convertSchemaToColumnDefinitions(schema), }, indices: [{ columns: grouped ? ['date', 'group'] : ['date'], @@ -233,37 +183,39 @@ export default abstract class Chart<T extends Record<string, any>> { }; } - constructor(name: string, schema: Schema, grouped = false) { + constructor(name: string, schema: T, grouped = false) { this.name = name; this.schema = schema; const { hour, day } = Chart.schemaToEntity(name, schema, grouped); - this.repositoryForHour = getRepository<Log>(hour); - this.repositoryForDay = getRepository<Log>(day); + this.repositoryForHour = getRepository<RawRecord<T>>(hour); + this.repositoryForDay = getRepository<RawRecord<T>>(day); } @autobind - private getNewLog(latest: T | null): T { - const log = latest ? this.genNewLog(latest) : {}; - const flatColumns = (x: Obj, path?: string) => { - for (const [k, v] of Object.entries(x)) { - const p = path ? `${path}.${k}` : k; - if (v.type === 'object') { - flatColumns(v.properties, p); - } else { - if (nestedProperty.get(log, p) == null) { - const emptyValue = v.type === 'number' ? 0 : []; - nestedProperty.set(log, p, emptyValue); - } - } + private convertRawRecord(x: RawRecord<T>): KVs<T> { + const kvs = {} as KVs<T>; + for (const k of Object.keys(x).filter(k => k.startsWith(columnPrefix))) { + kvs[k.substr(columnPrefix.length).split(columnDot).join('.')] = x[k]; + } + return kvs; + } + + @autobind + private getNewLog(latest: KVs<T> | null): KVs<T> { + const log = {} as Record<keyof T, number>; + for (const [k, v] of Object.entries(this.schema)) { + if (v.accumulate && latest) { + log[k] = latest[k]; + } else { + log[k] = 0; } - }; - flatColumns(this.schema.properties!); - return log as T; + } + return log as KVs<T>; } @autobind - private getLatestLog(group: string | null, span: 'hour' | 'day'): Promise<Log | null> { + private getLatestLog(group: string | null, span: 'hour' | 'day'): Promise<RawRecord<T> | null> { const repository = span === 'hour' ? this.repositoryForHour : span === 'day' ? this.repositoryForDay : @@ -282,7 +234,7 @@ export default abstract class Chart<T extends Record<string, any>> { * ç¾åœ¨(=今ã®Hour or Day)ã®ãƒã‚°ã‚’データベースã‹ã‚‰æŽ¢ã—ã¦ã€ã‚ã‚Œã°ãれを返ã—ã€ãªã‘ã‚Œã°ä½œæˆã—ã¦è¿”ã—ã¾ã™ã€‚ */ @autobind - private async claimCurrentLog(group: string | null, span: 'hour' | 'day'): Promise<Log> { + private async claimCurrentLog(group: string | null, span: 'hour' | 'day'): Promise<RawRecord<T>> { const [y, m, d, h] = Chart.getCurrentDate(); const current = dateUTC( @@ -306,8 +258,8 @@ export default abstract class Chart<T extends Record<string, any>> { return currentLog; } - let log: Log; - let data: T; + let log: RawRecord<T>; + let data: KVs<T>; // 集計期間ãŒå¤‰ã‚ã£ã¦ã‹ã‚‰ã€åˆã‚ã¦ã®ãƒãƒ£ãƒ¼ãƒˆæ›´æ–°ãªã‚‰ // 最も最近ã®ãƒã‚°ã‚’æŒã£ã¦ãã‚‹ @@ -318,10 +270,8 @@ export default abstract class Chart<T extends Record<string, any>> { const latest = await this.getLatestLog(group, span); if (latest != null) { - const obj = Chart.convertFlattenColumnsToObject(latest) as T; - // 空ãƒã‚°ãƒ‡ãƒ¼ã‚¿ã‚’ä½œæˆ - data = this.getNewLog(obj); + data = this.getNewLog(this.convertRawRecord(latest)); } else { // ãƒã‚°ãŒå˜åœ¨ã—ãªã‹ã£ãŸã‚‰ // (Misskeyインスタンスを建ã¦ã¦åˆã‚ã¦ã®ãƒãƒ£ãƒ¼ãƒˆæ›´æ–°æ™‚ãªã©) @@ -346,11 +296,17 @@ export default abstract class Chart<T extends Record<string, any>> { // ãƒã‚°ãŒã‚ã‚Œã°ãれを返ã—ã¦çµ‚了 if (currentLog != null) return currentLog; + const columns = {} as Record<string, number | unknown[]>; + for (const [k, v] of Object.entries(data)) { + const name = k.replaceAll('.', columnDot); + columns[columnPrefix + name] = v; + } + // æ–°è¦ãƒã‚°æŒ¿å…¥ log = await repository.insert({ date: date, ...(group ? { group: group } : {}), - ...Chart.convertObjectToFlattenColumns(data), + ...columns, }).then(x => repository.findOneOrFail(x.identifiers[0])); logger.info(`${this.name + (group ? `:${group}` : '')}(${span}): New commit created`); @@ -362,7 +318,10 @@ export default abstract class Chart<T extends Record<string, any>> { } @autobind - protected commit(diff: DeepPartial<T>, group: string | null = null): void { + protected commit(diff: Commit<T>, group: string | null = null): void { + for (const [k, v] of Object.entries(diff)) { + if (v == null || v === 0 || (Array.isArray(v) && v.length === 0)) delete diff[k]; + } this.buffer.push({ diff, group, }); @@ -381,13 +340,11 @@ export default abstract class Chart<T extends Record<string, any>> { // ãã®ãƒã‚°ã¯æœ¬æ¥ã¯ 01:00~ ã®ãƒã‚°ã¨ã—ã¦DBã«ä¿å˜ã•ã‚Œã¦æ¬²ã—ã„ã®ã«ã€02:00~ ã®ãƒã‚°æ‰±ã„ã«ãªã£ã¦ã—ã¾ã†ã€‚ // ã“れを回é¿ã™ã‚‹ãŸã‚ã®å®Ÿè£…ã¯è¤‡é›‘ã«ãªã‚Šãã†ãªãŸã‚ã€ä¸€æ—¦ä¿ç•™ã€‚ - const update = async (logHour: Log, logDay: Log): Promise<void> => { + const update = async (logHour: RawRecord<T>, logDay: RawRecord<T>): Promise<void> => { const finalDiffs = {} as Record<string, number | unknown[]>; for (const diff of this.buffer.filter(q => q.group == null || (q.group === logHour.group)).map(q => q.diff)) { - const columns = Chart.convertObjectToFlattenColumns(diff); - - for (const [k, v] of Object.entries(columns)) { + for (const [k, v] of Object.entries(diff)) { if (finalDiffs[k] == null) { finalDiffs[k] = v; } else { @@ -400,18 +357,72 @@ export default abstract class Chart<T extends Record<string, any>> { } } - const query = Chart.convertQuery(finalDiffs); + const queryForHour: Record<string, number | (() => string)> = {}; + const queryForDay: Record<string, number | (() => string)> = {}; + for (const [k, v] of Object.entries(finalDiffs)) { + if (typeof v === 'number') { + const name = columnPrefix + k.replaceAll('.', columnDot); + if (v > 0) queryForHour[name] = () => `"${name}" + ${v}`; + if (v < 0) queryForHour[name] = () => `"${name}" - ${Math.abs(v)}`; + if (v > 0) queryForDay[name] = () => `"${name}" + ${v}`; + if (v < 0) queryForDay[name] = () => `"${name}" - ${Math.abs(v)}`; + } else if (Array.isArray(v) && v.length > 0) { // ユニークインクリメント + const tempColumnName = uniqueTempColumnPrefix + k.replaceAll('.', columnDot); + // TODO: item ã‚’SQLエスケープ + const itemsForHour = v.filter(item => !logHour[tempColumnName].includes(item)).map(item => `"${item}"`); + const itemsForDay = v.filter(item => !logDay[tempColumnName].includes(item)).map(item => `"${item}"`); + if (itemsForHour.length > 0) queryForHour[tempColumnName] = () => `array_cat("${tempColumnName}", '{${itemsForHour.join(',')}}'::varchar[])`; + if (itemsForDay.length > 0) queryForDay[tempColumnName] = () => `array_cat("${tempColumnName}", '{${itemsForDay.join(',')}}'::varchar[])`; + } + } + + // bake unique count + for (const [k, v] of Object.entries(finalDiffs)) { + if (this.schema[k].uniqueIncrement) { + const name = columnPrefix + k.replaceAll('.', columnDot); + const tempColumnName = uniqueTempColumnPrefix + k.replaceAll('.', columnDot); + queryForHour[name] = new Set([...v, ...logHour[tempColumnName]]).size; + queryForDay[name] = new Set([...v, ...logDay[tempColumnName]]).size; + } + } + + // compute intersection + // TODO: intersectionã«æŒ‡å®šã•ã‚ŒãŸã‚«ãƒ©ãƒ ãŒintersectionã ã£ãŸå ´åˆã®å¯¾å¿œ + for (const [k, v] of Object.entries(this.schema)) { + const intersection = v.intersection; + if (intersection) { + const name = columnPrefix + k.replaceAll('.', columnDot); + const firstKey = intersection[0]; + const firstTempColumnName = uniqueTempColumnPrefix + firstKey.replaceAll('.', columnDot); + const currentValuesForHour = new Set([...(finalDiffs[firstKey] ?? []), ...logHour[firstTempColumnName]]); + const currentValuesForDay = new Set([...(finalDiffs[firstKey] ?? []), ...logDay[firstTempColumnName]]); + for (let i = 1; i < intersection.length; i++) { + const targetKey = intersection[i]; + const targetTempColumnName = uniqueTempColumnPrefix + targetKey.replaceAll('.', columnDot); + const targetValuesForHour = new Set([...(finalDiffs[targetKey] ?? []), ...logHour[targetTempColumnName]]); + const targetValuesForDay = new Set([...(finalDiffs[targetKey] ?? []), ...logDay[targetTempColumnName]]); + currentValuesForHour.forEach(v => { + if (!targetValuesForHour.has(v)) currentValuesForHour.delete(v); + }); + currentValuesForDay.forEach(v => { + if (!targetValuesForDay.has(v)) currentValuesForDay.delete(v); + }); + } + queryForHour[name] = currentValuesForHour.size; + queryForDay[name] = currentValuesForDay.size; + } + } // ãƒã‚°æ›´æ–° await Promise.all([ this.repositoryForHour.createQueryBuilder() .update() - .set(query) + .set(queryForHour) .where('id = :id', { id: logHour.id }) .execute(), this.repositoryForDay.createQueryBuilder() .update() - .set(query) + .set(queryForDay) .where('id = :id', { id: logDay.id }) .execute(), ]); @@ -435,18 +446,28 @@ export default abstract class Chart<T extends Record<string, any>> { @autobind public async resync(group: string | null = null): Promise<void> { - const data = await this.fetchActual(group); + const data = await this.queryCurrentState(group); - const update = async (logHour: Log, logDay: Log): Promise<void> => { + const columns = {} as Record<string, number>; + for (const [k, v] of Object.entries(data)) { + const name = k.replaceAll('.', columnDot); + columns[columnPrefix + name] = v; + } + + if (Object.keys(columns).length === 0) { + return; + } + + const update = async (logHour: RawRecord<T>, logDay: RawRecord<T>): Promise<void> => { await Promise.all([ this.repositoryForHour.createQueryBuilder() .update() - .set(Chart.convertObjectToFlattenColumns(data)) + .set(columns as any) .where('id = :id', { id: logHour.id }) .execute(), this.repositoryForDay.createQueryBuilder() .update() - .set(Chart.convertObjectToFlattenColumns(data)) + .set(columns as any) .where('id = :id', { id: logDay.id }) .execute(), ]); @@ -460,12 +481,43 @@ export default abstract class Chart<T extends Record<string, any>> { } @autobind - protected async inc(inc: DeepPartial<T>, group: string | null = null): Promise<void> { - await this.commit(inc, group); + public async clean(): Promise<void> { + const current = dateUTC(Chart.getCurrentDate()); + + // 一日以上å‰ã‹ã¤ä¸‰æ—¥ä»¥å†… + const gt = Chart.dateToTimestamp(current) - (60 * 60 * 24 * 3); + const lt = Chart.dateToTimestamp(current) - (60 * 60 * 24); + + const columns = {} as Record<string, number>; + for (const [k, v] of Object.entries(this.schema)) { + if (v.uniqueIncrement) { + const name = k.replaceAll('.', columnDot); + columns[uniqueTempColumnPrefix + name] = []; + } + } + + if (Object.keys(columns).length === 0) { + return; + } + + await Promise.all([ + this.repositoryForHour.createQueryBuilder() + .update() + .set(columns as any) + .where('date > :gt', { gt }) + .andWhere('date < :lt', { lt }) + .execute(), + this.repositoryForDay.createQueryBuilder() + .update() + .set(columns as any) + .where('date > :gt', { gt }) + .andWhere('date < :lt', { lt }) + .execute(), + ]); } @autobind - public async getChart(span: 'hour' | 'day', amount: number, cursor: Date | null, group: string | null = null): Promise<ArrayValue<T>> { + public async getChartRaw(span: 'hour' | 'day', amount: number, cursor: Date | null, group: string | null = null): Promise<ChartResult<T>> { const [y, m, d, h, _m, _s, _ms] = cursor ? Chart.parseDate(subtractTime(addTime(cursor, 1, span), 1)) : Chart.getCurrentDate(); const [y2, m2, d2, h2] = cursor ? Chart.parseDate(addTime(cursor, 1, span)) : [] as never; @@ -526,7 +578,7 @@ export default abstract class Chart<T extends Record<string, any>> { } } - const chart: T[] = []; + const chart: KVs<T>[] = []; for (let i = (amount - 1); i >= 0; i--) { const current = @@ -537,17 +589,16 @@ export default abstract class Chart<T extends Record<string, any>> { const log = logs.find(l => isTimeSame(new Date(l.date * 1000), current)); if (log) { - const data = Chart.convertFlattenColumnsToObject(log); - chart.unshift(Chart.countUniqueFields(data) as T); + chart.unshift(this.convertRawRecord(log)); } else { // 隙間埋゠const latest = logs.find(l => isTimeBefore(new Date(l.date * 1000), current)); - const data = latest ? Chart.convertFlattenColumnsToObject(latest) as T : null; - chart.unshift(Chart.countUniqueFields(this.getNewLog(data)) as T); + const data = latest ? this.convertRawRecord(latest) : null; + chart.unshift(this.getNewLog(data)); } } - const res = {} as Record<string, unknown>; + const res = {} as ChartResult<T>; /** * [{ foo: 1, bar: 5 }, { foo: 2, bar: 6 }, { foo: 3, bar: 7 }] @@ -555,36 +606,26 @@ export default abstract class Chart<T extends Record<string, any>> { * { foo: [1, 2, 3], bar: [5, 6, 7] } * ã«ã™ã‚‹ */ - const compact = (x: Obj, path?: string): void => { - for (const [k, v] of Object.entries(x)) { - const p = path ? `${path}.${k}` : k; - if (typeof v === 'object' && !Array.isArray(v)) { - compact(v, p); + for (const record of chart) { + for (const [k, v] of Object.entries(record)) { + if (res[k]) { + res[k].push(v); } else { - const values = chart.map(s => nestedProperty.get(s, p)); - nestedProperty.set(res, p, values); + res[k] = [v]; } } - }; - - compact(chart[0]); + } - return res as ArrayValue<T>; + return res; } -} -export function convertLog(logSchema: Schema): Schema { - const v: Schema = JSON.parse(JSON.stringify(logSchema)); // copy - if (v.type === 'number') { - v.type = 'array'; - v.items = { - type: 'number' as const, - optional: false as const, nullable: false as const, - }; - } else if (v.type === 'object') { - for (const k of Object.keys(v.properties!)) { - v.properties![k] = convertLog(v.properties![k]); + @autobind + public async getChart(span: 'hour' | 'day', amount: number, cursor: Date | null, group: string | null = null): Promise<Record<string, unknown>> { + const result = await this.getChartRaw(span, amount, cursor, group); + const object = {}; + for (const [k, v] of Object.entries(result)) { + nestedProperty.set(object, k, v); } + return object; } - return v; } diff --git a/packages/backend/src/services/chart/entities.ts b/packages/backend/src/services/chart/entities.ts index dedbd470804b1e2f80e5014775554d56a031fbcf..569b3285573d5b66b7be310380587128d8b4c6b2 100644 --- a/packages/backend/src/services/chart/entities.ts +++ b/packages/backend/src/services/chart/entities.ts @@ -1,7 +1,6 @@ import { entity as FederationChart } from './charts/entities/federation'; import { entity as NotesChart } from './charts/entities/notes'; import { entity as UsersChart } from './charts/entities/users'; -import { entity as NetworkChart } from './charts/entities/network'; import { entity as ActiveUsersChart } from './charts/entities/active-users'; import { entity as InstanceChart } from './charts/entities/instance'; import { entity as PerUserNotesChart } from './charts/entities/per-user-notes'; @@ -10,12 +9,12 @@ import { entity as PerUserReactionsChart } from './charts/entities/per-user-reac import { entity as HashtagChart } from './charts/entities/hashtag'; import { entity as PerUserFollowingChart } from './charts/entities/per-user-following'; import { entity as PerUserDriveChart } from './charts/entities/per-user-drive'; +import { entity as ApRequestChart } from './charts/entities/ap-request'; export const entities = [ FederationChart.hour, FederationChart.day, NotesChart.hour, NotesChart.day, UsersChart.hour, UsersChart.day, - NetworkChart.hour, NetworkChart.day, ActiveUsersChart.hour, ActiveUsersChart.day, InstanceChart.hour, InstanceChart.day, PerUserNotesChart.hour, PerUserNotesChart.day, @@ -24,4 +23,5 @@ export const entities = [ HashtagChart.hour, HashtagChart.day, PerUserFollowingChart.hour, PerUserFollowingChart.day, PerUserDriveChart.hour, PerUserDriveChart.day, + ApRequestChart.hour, ApRequestChart.day, ]; diff --git a/packages/backend/src/services/chart/index.ts b/packages/backend/src/services/chart/index.ts index 0b9887b36f7226b688d85fc2df120380fd1a8fe3..1c0f7aadc15c8a0c4c4a4b4adc63ec34d6043fb5 100644 --- a/packages/backend/src/services/chart/index.ts +++ b/packages/backend/src/services/chart/index.ts @@ -3,7 +3,6 @@ import { beforeShutdown } from '@/misc/before-shutdown'; import FederationChart from './charts/federation'; import NotesChart from './charts/notes'; import UsersChart from './charts/users'; -import NetworkChart from './charts/network'; import ActiveUsersChart from './charts/active-users'; import InstanceChart from './charts/instance'; import PerUserNotesChart from './charts/per-user-notes'; @@ -12,11 +11,11 @@ import PerUserReactionsChart from './charts/per-user-reactions'; import HashtagChart from './charts/hashtag'; import PerUserFollowingChart from './charts/per-user-following'; import PerUserDriveChart from './charts/per-user-drive'; +import ApRequestChart from './charts/ap-request'; export const federationChart = new FederationChart(); export const notesChart = new NotesChart(); export const usersChart = new UsersChart(); -export const networkChart = new NetworkChart(); export const activeUsersChart = new ActiveUsersChart(); export const instanceChart = new InstanceChart(); export const perUserNotesChart = new PerUserNotesChart(); @@ -25,12 +24,12 @@ export const perUserReactionsChart = new PerUserReactionsChart(); export const hashtagChart = new HashtagChart(); export const perUserFollowingChart = new PerUserFollowingChart(); export const perUserDriveChart = new PerUserDriveChart(); +export const apRequestChart = new ApRequestChart(); const charts = [ federationChart, notesChart, usersChart, - networkChart, activeUsersChart, instanceChart, perUserNotesChart, @@ -39,6 +38,7 @@ const charts = [ hashtagChart, perUserFollowingChart, perUserDriveChart, + apRequestChart, ]; // 20分ãŠãã«ãƒ¡ãƒ¢ãƒªæƒ…å ±ã‚’DBã«æ›¸ã込㿠diff --git a/packages/backend/src/services/drive/add-file.ts b/packages/backend/src/services/drive/add-file.ts index a89e068f45593349d3625e7d697505cf66d455d9..9a8a54390448e5a4da95b9deb882810efdd8e819 100644 --- a/packages/backend/src/services/drive/add-file.ts +++ b/packages/backend/src/services/drive/add-file.ts @@ -160,8 +160,8 @@ export async function generateAlts(path: string, type: string, generateWeb: bool webpublic: null, thumbnail, }; - } catch (e) { - logger.warn(`GenerateVideoThumbnail failed: ${e}`); + } catch (err) { + logger.warn(`GenerateVideoThumbnail failed: ${err}`); return { webpublic: null, thumbnail: null, @@ -191,8 +191,8 @@ export async function generateAlts(path: string, type: string, generateWeb: bool thumbnail: null, }; } - } catch (e) { - logger.warn(`sharp failed: ${e}`); + } catch (err) { + logger.warn(`sharp failed: ${err}`); return { webpublic: null, thumbnail: null, @@ -215,8 +215,8 @@ export async function generateAlts(path: string, type: string, generateWeb: bool } else { logger.debug(`web image not created (not an required image)`); } - } catch (e) { - logger.warn(`web image not created (an error occured)`, e); + } catch (err) { + logger.warn(`web image not created (an error occured)`, err as Error); } } else { logger.info(`web image not created (from remote)`); @@ -234,8 +234,8 @@ export async function generateAlts(path: string, type: string, generateWeb: bool } else { logger.debug(`thumbnail not created (not an required file)`); } - } catch (e) { - logger.warn(`thumbnail not created (an error occured)`, e); + } catch (err) { + logger.warn(`thumbnail not created (an error occured)`, err as Error); } // #endregion thumbnail @@ -451,9 +451,9 @@ export async function addFile({ file.storedInternal = false; file = await DriveFiles.insert(file).then(x => DriveFiles.findOneOrFail(x.identifiers[0])); - } catch (e) { + } catch (err) { // duplicate key error (when already registered) - if (isDuplicateKeyValueError(e)) { + if (isDuplicateKeyValueError(err)) { logger.info(`already registered ${file.uri}`); file = await DriveFiles.findOne({ @@ -461,8 +461,8 @@ export async function addFile({ userId: user ? user.id : null, }) as DriveFile; } else { - logger.error(e); - throw e; + logger.error(err as Error); + throw err; } } } else { diff --git a/packages/backend/src/services/logger.ts b/packages/backend/src/services/logger.ts index 626cc6b44cf2a7d643face25dd26c55fbed66a0f..1962088b639e8204a70ead8b37ff9dcb7fb03154 100644 --- a/packages/backend/src/services/logger.ts +++ b/packages/backend/src/services/logger.ts @@ -1,6 +1,6 @@ import * as cluster from 'cluster'; import * as chalk from 'chalk'; -import * as dateformat from 'dateformat'; +import { format as dateFormat } from 'date-fns'; import { envOption } from '../env'; import config from '@/config/index'; @@ -57,7 +57,7 @@ export default class Logger { return; } - const time = dateformat(new Date(), 'HH:MM:ss'); + const time = dateFormat(new Date(), 'HH:mm:ss'); const worker = cluster.isPrimary ? '*' : cluster.worker.id; const l = level === 'error' ? important ? chalk.bgRed.white('ERR ') : chalk.red('ERR ') : @@ -116,7 +116,7 @@ export default class Logger { } public debug(message: string, data?: Record<string, any> | null, important = false): void { // デãƒãƒƒã‚°ç”¨ã«ä½¿ã†(開発者ã«å¿…è¦ã ãŒåˆ©ç”¨è€…ã«ä¸è¦ãªæƒ…å ±) - if (process.env.NODE_ENV != 'production' || envOption.verbose) { + if (process.env.NODE_ENV !== 'production' || envOption.verbose) { this.log('debug', message, data, important); } } diff --git a/packages/backend/src/services/note/create.ts b/packages/backend/src/services/note/create.ts index fb22bd659396d749da06021d403053453215574b..7a4c2cef12c9b2856f8af9312d283e358d9f306d 100644 --- a/packages/backend/src/services/note/create.ts +++ b/packages/backend/src/services/note/create.ts @@ -59,7 +59,7 @@ class NotificationManager { if (exist) { // 「メンションã•ã‚Œã¦ã„ã‚‹ã‹ã¤è¿”ä¿¡ã•ã‚Œã¦ã„ã‚‹ã€å ´åˆã¯ã€ãƒ¡ãƒ³ã‚·ãƒ§ãƒ³ã¨ã—ã¦ã®é€šçŸ¥ã§ã¯ãªã返信ã¨ã—ã¦ã®é€šçŸ¥ã«ã™ã‚‹ - if (reason != 'mention') { + if (reason !== 'mention') { exist.reason = reason; } } else { @@ -111,7 +111,7 @@ type Option = { app?: App | null; }; -export default async (user: { id: User['id']; username: User['username']; host: User['host']; isSilenced: User['isSilenced']; }, data: Option, silent = false) => new Promise<Note>(async (res, rej) => { +export default async (user: { id: User['id']; username: User['username']; host: User['host']; isSilenced: User['isSilenced']; createdAt: User['createdAt']; }, data: Option, silent = false) => new Promise<Note>(async (res, rej) => { // ãƒãƒ£ãƒ³ãƒãƒ«å¤–ã«ãƒªãƒ—ライã—ãŸã‚‰å¯¾è±¡ã®ã‚¹ã‚³ãƒ¼ãƒ—ã«åˆã‚ã›ã‚‹ // (クライアントサイドã§ã‚„ã£ã¦ã‚‚良ã„処ç†ã ã¨æ€ã†ã‘ã©ã¨ã‚Šã‚ãˆãšã‚µãƒ¼ãƒãƒ¼ã‚µã‚¤ãƒ‰ã§) if (data.reply && data.channel && data.reply.channelId !== data.channel.id) { @@ -201,7 +201,7 @@ export default async (user: { id: User['id']; username: User['username']; host: mentionedUsers.push(await Users.findOneOrFail(data.reply.userId)); } - if (data.visibility == 'specified') { + if (data.visibility === 'specified') { if (data.visibleUsers == null) throw new Error('invalid param'); for (const u of data.visibleUsers) { @@ -297,11 +297,10 @@ export default async (user: { id: User['id']; username: User['username']; host: } if (!silent) { - // ãƒãƒ¼ã‚«ãƒ«ãƒ¦ãƒ¼ã‚¶ãƒ¼ã®ãƒãƒ£ãƒ¼ãƒˆã¯ã‚¿ã‚¤ãƒ ラインå–得時ã«æ›´æ–°ã—ã¦ã„ã‚‹ã®ã§ãƒªãƒ¢ãƒ¼ãƒˆãƒ¦ãƒ¼ã‚¶ãƒ¼ã®å ´åˆã ã‘ã§ã‚ˆã„ - if (Users.isRemoteUser(user)) activeUsersChart.update(user); + if (Users.isLocalUser(user)) activeUsersChart.write(user); // 未èªé€šçŸ¥ã‚’ä½œæˆ - if (data.visibility == 'specified') { + if (data.visibility === 'specified') { if (data.visibleUsers == null) throw new Error('invalid param'); for (const u of data.visibleUsers) { @@ -439,7 +438,7 @@ export default async (user: { id: User['id']; username: User['username']; host: async function renderNoteOrRenoteActivity(data: Option, note: Note) { if (data.localOnly) return null; - const content = data.renote && data.text == null && data.poll == null && (data.files == null || data.files.length == 0) + const content = data.renote && data.text == null && data.poll == null && (data.files == null || data.files.length === 0) ? renderAnnounce(data.renote.uri ? data.renote.uri : `${config.url}/notes/${data.renote.id}`, note) : renderCreate(await renderNote(note, false), note); @@ -478,7 +477,7 @@ async function insertNote(user: { id: User['id']; host: User['host']; }, data: O userId: user.id, localOnly: data.localOnly!, visibility: data.visibility as any, - visibleUserIds: data.visibility == 'specified' + visibleUserIds: data.visibility === 'specified' ? data.visibleUsers ? data.visibleUsers.map(u => u.id) : [] @@ -502,7 +501,7 @@ async function insertNote(user: { id: User['id']; host: User['host']; }, data: O insert.mentions = mentionedUsers.map(u => u.id); const profiles = await UserProfiles.find({ userId: In(insert.mentions) }); insert.mentionedRemoteUsers = JSON.stringify(mentionedUsers.filter(u => Users.isRemoteUser(u)).map(u => { - const profile = profiles.find(p => p.userId == u.id); + const profile = profiles.find(p => p.userId === u.id); const url = profile != null ? profile.url : null; return { uri: u.uri, diff --git a/packages/backend/src/services/note/delete.ts b/packages/backend/src/services/note/delete.ts index 64383ee92838cfdafe50c35162bc2058965bc0a6..77723fe8b791d09f069f77b0eb2e2960720df398 100644 --- a/packages/backend/src/services/note/delete.ts +++ b/packages/backend/src/services/note/delete.ts @@ -39,7 +39,7 @@ export default async function(user: User, note: Note, quiet = false) { let renote: Note | undefined; // if deletd note is renote - if (note.renoteId && note.text == null && !note.hasPoll && (note.fileIds == null || note.fileIds.length == 0)) { + if (note.renoteId && note.text == null && !note.hasPoll && (note.fileIds == null || note.fileIds.length === 0)) { renote = await Notes.findOne({ id: note.renoteId, }); diff --git a/packages/backend/src/services/note/reaction/create.ts b/packages/backend/src/services/note/reaction/create.ts index 47f46419ddbbe9968bed90dabeaa3746202b289c..c01d43c22117c474bb8281cd62281a30f354a1c0 100644 --- a/packages/backend/src/services/note/reaction/create.ts +++ b/packages/backend/src/services/note/reaction/create.ts @@ -76,7 +76,7 @@ export default async (user: { id: User['id']; host: User['host']; }, note: Note, // カスタム絵文å—リアクションã ã£ãŸã‚‰çµµæ–‡å—æƒ…å ±ã‚‚é€ã‚‹ const decodedReaction = decodeReaction(reaction); - let emoji = await Emojis.findOne({ + const emoji = await Emojis.findOne({ where: { name: decodedReaction.name, host: decodedReaction.host, diff --git a/packages/backend/src/services/note/read.ts b/packages/backend/src/services/note/read.ts index aaf1c5ed7148dafb63366bafee030ac0105b719d..032f1e84e604bffa9753b694cfa5bb5125421c19 100644 --- a/packages/backend/src/services/note/read.ts +++ b/packages/backend/src/services/note/read.ts @@ -52,7 +52,7 @@ export default async function( if (note.user != null) { // ãŸã¶ã‚“nullã«ãªã‚‹ã“ã¨ã¯ç„¡ã„ã¯ãšã ã‘ã©ä¸€å¿œ for (const antenna of myAntennas) { - if (await checkHitAntenna(antenna, note, note.user as any, undefined, Array.from(following))) { + if (await checkHitAntenna(antenna, note, note.user, undefined, Array.from(following))) { readAntennaNotes.push(note); } } diff --git a/packages/backend/src/services/send-email.ts b/packages/backend/src/services/send-email.ts index f5f36148f6db630cd291d079a6d7ef55141b9110..1fd406cb685e5d90d5a00a300d77c9d29735a90b 100644 --- a/packages/backend/src/services/send-email.ts +++ b/packages/backend/src/services/send-email.ts @@ -114,9 +114,9 @@ export async function sendEmail(to: string, subject: string, html: string, text: </html>`, }); - logger.info('Message sent: %s', info.messageId); - } catch (e) { - logger.error(e); - throw e; + logger.info(`Message sent: ${info.messageId}`); + } catch (err) { + logger.error(err as Error); + throw err; } } diff --git a/packages/backend/test/chart.ts b/packages/backend/test/chart.ts index 66000bc9285fd873bc22b1a518712e2a38925e21..bd8d4c8171046d0959dcba181eae945755508313 100644 --- a/packages/backend/test/chart.ts +++ b/packages/backend/test/chart.ts @@ -6,14 +6,17 @@ import { async, initTestDb } from './utils'; import TestChart from '../src/services/chart/charts/test'; import TestGroupedChart from '../src/services/chart/charts/test-grouped'; import TestUniqueChart from '../src/services/chart/charts/test-unique'; +import TestIntersectionChart from '../src/services/chart/charts/test-intersection'; import * as _TestChart from '../src/services/chart/charts/entities/test'; import * as _TestGroupedChart from '../src/services/chart/charts/entities/test-grouped'; import * as _TestUniqueChart from '../src/services/chart/charts/entities/test-unique'; +import * as _TestIntersectionChart from '../src/services/chart/charts/entities/test-intersection'; describe('Chart', () => { let testChart: TestChart; let testGroupedChart: TestGroupedChart; let testUniqueChart: TestUniqueChart; + let testIntersectionChart: TestIntersectionChart; let clock: lolex.Clock; beforeEach(async(async () => { @@ -21,11 +24,13 @@ describe('Chart', () => { _TestChart.entity.hour, _TestChart.entity.day, _TestGroupedChart.entity.hour, _TestGroupedChart.entity.day, _TestUniqueChart.entity.hour, _TestUniqueChart.entity.day, + _TestIntersectionChart.entity.hour, _TestIntersectionChart.entity.day, ]); testChart = new TestChart(); testGroupedChart = new TestGroupedChart(); testUniqueChart = new TestUniqueChart(); + testIntersectionChart = new TestIntersectionChart(); clock = lolex.install({ now: new Date(Date.UTC(2000, 0, 1, 0, 0, 0)) @@ -426,6 +431,53 @@ describe('Chart', () => { foo: [2, 0, 0], }); })); + + describe('Intersection', () => { + it('æ¡ä»¶ãŒæº€ãŸã•ã‚Œã¦ã„ãªã„å ´åˆã¯ã‚«ã‚¦ãƒ³ãƒˆã•ã‚Œãªã„', async(async () => { + await testIntersectionChart.addA('alice'); + await testIntersectionChart.addA('bob'); + await testIntersectionChart.addB('carol'); + await testIntersectionChart.save(); + + const chartHours = await testIntersectionChart.getChart('hour', 3, null); + const chartDays = await testIntersectionChart.getChart('day', 3, null); + + assert.deepStrictEqual(chartHours, { + a: [2, 0, 0], + b: [1, 0, 0], + aAndB: [0, 0, 0], + }); + + assert.deepStrictEqual(chartDays, { + a: [2, 0, 0], + b: [1, 0, 0], + aAndB: [0, 0, 0], + }); + })); + + it('æ¡ä»¶ãŒæº€ãŸã•ã‚Œã¦ã„ã‚‹å ´åˆã«ã‚«ã‚¦ãƒ³ãƒˆã•ã‚Œã‚‹', async(async () => { + await testIntersectionChart.addA('alice'); + await testIntersectionChart.addA('bob'); + await testIntersectionChart.addB('carol'); + await testIntersectionChart.addB('alice'); + await testIntersectionChart.save(); + + const chartHours = await testIntersectionChart.getChart('hour', 3, null); + const chartDays = await testIntersectionChart.getChart('day', 3, null); + + assert.deepStrictEqual(chartHours, { + a: [2, 0, 0], + b: [2, 0, 0], + aAndB: [1, 0, 0], + }); + + assert.deepStrictEqual(chartDays, { + a: [2, 0, 0], + b: [2, 0, 0], + aAndB: [1, 0, 0], + }); + })); + }); }); describe('Resync', () => { diff --git a/packages/backend/tsconfig.json b/packages/backend/tsconfig.json index 3311e117de8a3307aab872b2e325bba85030513b..f3252b2860036449dc024a707caa547e7dcfe23c 100644 --- a/packages/backend/tsconfig.json +++ b/packages/backend/tsconfig.json @@ -30,7 +30,7 @@ "outDir": "./built", "typeRoots": [ "./node_modules/@types", - "./@types" + "./src/@types" ], "lib": [ "esnext" diff --git a/packages/backend/yarn.lock b/packages/backend/yarn.lock index 5bf6e05a71986b063ca72b1db51620fbce82805b..c4afef8b5c416392b3afe60b971c55242e642da3 100644 --- a/packages/backend/yarn.lock +++ b/packages/backend/yarn.lock @@ -238,9 +238,9 @@ integrity sha512-JiX9vxoKMmu8Y3Zr2RVathBL1Cdu4Nt4MuNWemt1Nc06A0RAin9c5FArkhGsyMBWfCu4zj+9b+GxtjAnE4qqLQ== "@sindresorhus/is@^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.0.0.tgz#2ff674e9611b45b528896d820d3d7a812de2f0e4" - integrity sha512-FyD2meJpDPjyNQejSjvnhpgI/azsQkA4lGbuu5BQZfjvJ9cbRZXzeWL2HceCekW4lixO9JPesIIQkSoLjeJHNQ== + version "4.4.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.4.0.tgz#e277e5bdbdf7cb1e20d320f02f5e2ed113cd3185" + integrity sha512-QppPM/8l3Mawvh4rn9CNEYIU9bxpXUCRMaX9yUpvBk1nMKusLKpfXGDEKExKaPhLzcn3lzil7pR6rnJ11HgeRQ== "@sinonjs/commons@^1.7.0": version "1.7.2" @@ -249,10 +249,10 @@ dependencies: type-detect "4.0.8" -"@sinonjs/fake-timers@7.1.2": - version "7.1.2" - resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-7.1.2.tgz#2524eae70c4910edccf99b2f4e6efc5894aff7b5" - integrity sha512-iQADsW4LBMISqZ6Ci1dupJL9pprqwcVFTcOsEmQOEhW+KLCVn/Y4Jrvg2k19fIHCp+iFprriYPTdRcQR8NbUPg== +"@sinonjs/fake-timers@9.1.0": + version "9.1.0" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-9.1.0.tgz#8c92c56f195e0bed4c893ba59c8e3d55831ca0df" + integrity sha512-M8vapsv9qQupMdzrVzkn5rb9jG7aUTEPAZdMtME2PuBaefksFZVE2C1g4LBRTkF/k3nRDNbDc5tp5NFC1PEYxA== dependencies: "@sinonjs/commons" "^1.7.0" @@ -289,6 +289,11 @@ resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== +"@tootallnate/once@2": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" + integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== + "@tsconfig/node10@^1.0.7": version "1.0.7" resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.7.tgz#1eb1de36c73478a2479cc661ef5af1c16d86d606" @@ -316,11 +321,6 @@ dependencies: "@types/node" "*" -"@types/anymatch@*": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-1.3.1.tgz#336badc1beecb9dacc38bea2cf32adf627a8421a" - integrity sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA== - "@types/bcryptjs@2.4.2": version "2.4.2" resolved "https://registry.yarnpkg.com/@types/bcryptjs/-/bcryptjs-2.4.2.tgz#e3530eac9dd136bfdfb0e43df2c4c5ce1f77dfae" @@ -386,11 +386,6 @@ "@types/keygrip" "*" "@types/node" "*" -"@types/dateformat@3.0.1": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@types/dateformat/-/dateformat-3.0.1.tgz#98d747a2e5e9a56070c6bf14e27bff56204e34cc" - integrity sha512-KlPPdikagvL6ELjWsljbyDIPzNCeliYkqRpI+zea99vBBbCIA5JNshZAwQKTON139c87y9qvTFVgkFd14rtS4g== - "@types/disposable-email-domains@^1.0.1": version "1.0.2" resolved "https://registry.yarnpkg.com/@types/disposable-email-domains/-/disposable-email-domains-1.0.2.tgz#0280f6b38fa7f14e54b056a434135ecd254483b1" @@ -401,27 +396,6 @@ resolved "https://registry.yarnpkg.com/@types/escape-regexp/-/escape-regexp-0.0.1.tgz#f1a977ccdf2ef059e9862bd3af5e92cbbe723e0e" integrity sha512-ogj/ZTIdeFkiuxDwawYuZSIgC6suFGgBeZPr6Xs5lHEcvIXTjXGtH+/n8f1XhZhespaUwJ5LIGRICPji972FLw== -"@types/eslint-scope@^3.7.0": - version "3.7.0" - resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.0.tgz#4792816e31119ebd506902a482caec4951fabd86" - integrity sha512-O/ql2+rrCUe2W2rs7wMR+GqPRcgB6UiqN5RhrR5xruFlY7l9YLMn0ZkDzjoHLeiFkR8MCQZVudUuuvQ2BLC9Qw== - dependencies: - "@types/eslint" "*" - "@types/estree" "*" - -"@types/eslint@*": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-7.2.0.tgz#eb5c5b575237334df24c53195e37b53d66478d7b" - integrity sha512-LpUXkr7fnmPXWGxB0ZuLEzNeTURuHPavkC5zuU4sg62/TgL5ZEjamr5Y8b6AftwHtx2bPJasI+CL0TT2JwQ7aA== - dependencies: - "@types/estree" "*" - "@types/json-schema" "*" - -"@types/estree@*", "@types/estree@^0.0.46": - version "0.0.46" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.46.tgz#0fb6bfbbeabd7a30880504993369c4bf1deab1fe" - integrity sha512-laIjwTQaD+5DukBZaygQ79K1Z0jb1bPEMRrkXSLjtCcZm+abyp5YbrqpSLzD42FwWW6gK/aS4NYpJ804nG2brg== - "@types/express-serve-static-core@*": version "4.17.5" resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.5.tgz#a00ac7dadd746ae82477443e4d480a6a93ea083c" @@ -496,11 +470,6 @@ "@types/parse5" "*" "@types/tough-cookie" "*" -"@types/json-schema@*": - version "7.0.5" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.5.tgz#dcce4430e64b443ba8945f0290fb564ad5bac6dd" - integrity sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ== - "@types/json-schema@^7.0.6": version "7.0.6" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.6.tgz#f4c7ec43e81b319a9815115031709f26987891f0" @@ -665,10 +634,10 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-16.6.2.tgz#331b7b9f8621c638284787c5559423822fdffc50" integrity sha512-LSw8TZt12ZudbpHc6EkIyDM3nHVWKYrAvGy6EAJfNfjusbwnThqjqxUKKRwuV3iWYeW/LYMzNgaq3MaLffQ2xA== -"@types/node@17.0.10": - version "17.0.10" - resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.10.tgz#616f16e9d3a2a3d618136b1be244315d95bd7cab" - integrity sha512-S/3xB4KzyFxYGCppyDt68yzBU9ysL88lSdIah4D6cptdcltc4NCPCAMc0+PCpg/lLIyC7IPvj2Z52OJWeIUkog== +"@types/node@17.0.14": + version "17.0.14" + resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.14.tgz#33b9b94f789a8fedd30a68efdbca4dbb06b61f20" + integrity sha512-SbjLmERksKOGzWzPNuW7fJM7fk3YXVTFiZWB/Hs99gwhk+/dnrQRPBQjPW9aO+fi1tAffi9PrwFvsmOKmDTyng== "@types/node@^14.11.8": version "14.17.9" @@ -770,13 +739,6 @@ resolved "https://registry.yarnpkg.com/@types/rename/-/rename-1.0.4.tgz#30c6f0306042591a560361ea02639e89647dd173" integrity sha512-eV81+6bVv2mdCBahkMefjEUwAjKDAP3AuyhqWCWRxcRaeVdUeHUBaoq2zSz+5HNHF2jzTajMcfLvJsy4K3cbwA== -"@types/request-stats@3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/request-stats/-/request-stats-3.0.0.tgz#d3909a9f778b8ae0b42fb8c1ed20cb936ed95f99" - integrity sha512-POsDF7nETH8up49iBNvbZuO0pEk9F+TG0rXCkvjxCClcOS99xfF+mKmJteYlwKYpuRKkixzysKlL8rwN1hU2lw== - dependencies: - "@types/node" "*" - "@types/responselike@*", "@types/responselike@^1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.0.tgz#251f4fe7d154d2bad125abe1b429b23afd262e29" @@ -791,10 +753,10 @@ dependencies: htmlparser2 "^6.0.0" -"@types/seedrandom@2.4.28": - version "2.4.28" - resolved "https://registry.yarnpkg.com/@types/seedrandom/-/seedrandom-2.4.28.tgz#9ce8fa048c1e8c85cb71d7fe4d704e000226036f" - integrity sha512-SMA+fUwULwK7sd/ZJicUztiPs8F1yCPwF3O23Z9uQ32ME5Ha0NmDK9+QTsYE4O2tHXChzXomSWWeIhCnoN1LqA== +"@types/seedrandom@3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@types/seedrandom/-/seedrandom-3.0.1.tgz#1254750a4fec4aff2ebec088ccd0bb02e91fedb4" + integrity sha512-giB9gzDeiCeloIXDgzFBCgjj1k4WxcDrZtGl6h1IqmUPlxF+Nx8Ve+96QCyDZ/HseB/uvDsKbpib9hU5cU53pw== "@types/serve-static@*": version "1.13.3" @@ -811,15 +773,10 @@ dependencies: "@types/node" "*" -"@types/sinonjs__fake-timers@6.0.4": - version "6.0.4" - resolved "https://registry.yarnpkg.com/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.4.tgz#0ecc1b9259b76598ef01942f547904ce61a6a77d" - integrity sha512-IFQTJARgMUBF+xVd2b+hIgXWrZEjND3vJtRCvIelcFB5SIXfjV4bOHbHJ0eXKh+0COrBRc8MqteKAz/j88rE0A== - -"@types/source-list-map@*": - version "0.1.2" - resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.2.tgz#0078836063ffaf17412349bba364087e0ac02ec9" - integrity sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA== +"@types/sinonjs__fake-timers@8.1.1": + version "8.1.1" + resolved "https://registry.yarnpkg.com/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz#b49c2c70150141a15e0fa7e79cf1f92a72934ce3" + integrity sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g== "@types/speakeasy@2.0.7": version "2.0.7" @@ -828,11 +785,6 @@ dependencies: "@types/node" "*" -"@types/tapable@^1": - version "1.0.7" - resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.7.tgz#545158342f949e8fd3bfd813224971ecddc3fac4" - integrity sha512-0VBprVqfgFD7Ehb2vd8Lh9TG3jP98gvr8rgehQqzztZNI7o8zS8Ad4jyZneKELphpuE212D8J70LnSNQSyO6bQ== - "@types/throttle-debounce@2.1.0": version "2.1.0" resolved "https://registry.yarnpkg.com/@types/throttle-debounce/-/throttle-debounce-2.1.0.tgz#1c3df624bfc4b62f992d3012b84c56d41eab3776" @@ -853,13 +805,6 @@ resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.0.tgz#fef1904e4668b6e5ecee60c52cc6a078ffa6697d" integrity sha512-I99sngh224D0M7XgW1s120zxCt3VYQ3IQsuw3P3jbq5GG4yc79+ZjyKznyOGIQrflfylLgcfekeZW/vk0yng6A== -"@types/uglify-js@*": - version "3.9.0" - resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.9.0.tgz#4490a140ca82aa855ad68093829e7fd6ae94ea87" - integrity sha512-3ZcoyPYHVOCcLpnfZwD47KFLr8W/mpUcgjpf1M4Q78TMJIw7KMAHSjiCLJp1z3ZrBR9pTLbe191O0TldFK5zcw== - dependencies: - source-map "^0.6.1" - "@types/uuid@8.3.4": version "8.3.4" resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.4.tgz#bd86a43617df0594787d38b735f55c805becf1bc" @@ -872,48 +817,10 @@ dependencies: "@types/node" "*" -"@types/webpack-sources@*": - version "0.1.7" - resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-0.1.7.tgz#0a330a9456113410c74a5d64180af0cbca007141" - integrity sha512-XyaHrJILjK1VHVC4aVlKsdNN5KBTwufMb43cQs+flGxtPAf/1Qwl8+Q0tp5BwEGaI8D6XT1L+9bSWXckgkjTLw== - dependencies: - "@types/node" "*" - "@types/source-list-map" "*" - source-map "^0.6.1" - -"@types/webpack-stream@3.2.12": - version "3.2.12" - resolved "https://registry.yarnpkg.com/@types/webpack-stream/-/webpack-stream-3.2.12.tgz#cf13e64067a662a7acd8cd0524b3f64c86b0ecb6" - integrity sha512-znMUl4kKT0V0SwkUgRgwUNSAO7J5I/jdTCBNy3utkCsgMJ3IHp4FBTDwsQC+tfQ73TWeKIH05QNmbUYmeGThGw== - dependencies: - "@types/node" "*" - "@types/webpack" "^4" - -"@types/webpack@5.28.0": - version "5.28.0" - resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-5.28.0.tgz#78dde06212f038d77e54116cfe69e88ae9ed2c03" - integrity sha512-8cP0CzcxUiFuA9xGJkfeVpqmWTk9nx6CWwamRGCj95ph1SmlRRk9KlCZ6avhCbZd4L68LvYT6l1kpdEnQXrF8w== - dependencies: - "@types/node" "*" - tapable "^2.2.0" - webpack "^5" - -"@types/webpack@^4": - version "4.41.27" - resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.27.tgz#f47da488c8037e7f1b2dbf2714fbbacb61ec0ffc" - integrity sha512-wK/oi5gcHi72VMTbOaQ70VcDxSQ1uX8S2tukBK9ARuGXrYM/+u4ou73roc7trXDNmCxCoerE8zruQqX/wuHszA== - dependencies: - "@types/anymatch" "*" - "@types/node" "*" - "@types/tapable" "^1" - "@types/uglify-js" "*" - "@types/webpack-sources" "*" - source-map "^0.6.0" - -"@types/websocket@1.0.4": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@types/websocket/-/websocket-1.0.4.tgz#1dc497280d8049a5450854dd698ee7e6ea9e60b8" - integrity sha512-qn1LkcFEKK8RPp459jkjzsfpbsx36BBt3oC3pITYtkoBw/aVX+EZFa5j3ThCRTNpLFvIMr5dSTD4RaMdilIOpA== +"@types/websocket@1.0.5": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@types/websocket/-/websocket-1.0.5.tgz#3fb80ed8e07f88e51961211cd3682a3a4a81569c" + integrity sha512-NbsqiNX9CnEfC1Z0Vf4mE1SgAJ07JnRYcNex7AJ9zAVzmiGHmjKFEk7O4TJIsgv2B1sLEb6owKFZrACwdYngsQ== dependencies: "@types/node" "*" @@ -929,14 +836,14 @@ resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.8.2.tgz#808c9fa7e4517274ed555fa158f2de4b4f468e71" integrity sha512-HrCIVMLjE1MOozVoD86622S7aunluLb2PJdPfb3nYiEtohm8mIB/vyv0Fd37AdeMFrTUQXEunw78YloMA3Qilg== -"@typescript-eslint/eslint-plugin@5.10.0": - version "5.10.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.10.0.tgz#e90afea96dff8620892ad216b0e4ccdf8ee32d3a" - integrity sha512-XXVKnMsq2fuu9K2KsIxPUGqb6xAImz8MEChClbXmE3VbveFtBUU5bzM6IPVWqzyADIgdkS2Ws/6Xo7W2TeZWjQ== +"@typescript-eslint/eslint-plugin@5.10.2": + version "5.10.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.10.2.tgz#f8c1d59fc37bd6d9d11c97267fdfe722c4777152" + integrity sha512-4W/9lLuE+v27O/oe7hXJKjNtBLnZE8tQAFpapdxwSVHqtmIoPB1gph3+ahNwVuNL37BX7YQHyGF9Xv6XCnIX2Q== dependencies: - "@typescript-eslint/scope-manager" "5.10.0" - "@typescript-eslint/type-utils" "5.10.0" - "@typescript-eslint/utils" "5.10.0" + "@typescript-eslint/scope-manager" "5.10.2" + "@typescript-eslint/type-utils" "5.10.2" + "@typescript-eslint/utils" "5.10.2" debug "^4.3.2" functional-red-black-tree "^1.0.1" ignore "^5.1.8" @@ -944,69 +851,69 @@ semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/parser@5.10.0": - version "5.10.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.10.0.tgz#8f59e036f5f1cffc178cacbd5ccdd02aeb96c91c" - integrity sha512-pJB2CCeHWtwOAeIxv8CHVGJhI5FNyJAIpx5Pt72YkK3QfEzt6qAlXZuyaBmyfOdM62qU0rbxJzNToPTVeJGrQw== +"@typescript-eslint/parser@5.10.2": + version "5.10.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.10.2.tgz#b6076d27cc5499ce3f2c625f5ccde946ecb7db9a" + integrity sha512-JaNYGkaQVhP6HNF+lkdOr2cAs2wdSZBoalE22uYWq8IEv/OVH0RksSGydk+sW8cLoSeYmC+OHvRyv2i4AQ7Czg== dependencies: - "@typescript-eslint/scope-manager" "5.10.0" - "@typescript-eslint/types" "5.10.0" - "@typescript-eslint/typescript-estree" "5.10.0" + "@typescript-eslint/scope-manager" "5.10.2" + "@typescript-eslint/types" "5.10.2" + "@typescript-eslint/typescript-estree" "5.10.2" debug "^4.3.2" -"@typescript-eslint/scope-manager@5.10.0": - version "5.10.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.10.0.tgz#bb5d872e8b9e36203908595507fbc4d3105329cb" - integrity sha512-tgNgUgb4MhqK6DoKn3RBhyZ9aJga7EQrw+2/OiDk5hKf3pTVZWyqBi7ukP+Z0iEEDMF5FDa64LqODzlfE4O/Dg== +"@typescript-eslint/scope-manager@5.10.2": + version "5.10.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.10.2.tgz#92c0bc935ec00f3d8638cdffb3d0e70c9b879639" + integrity sha512-39Tm6f4RoZoVUWBYr3ekS75TYgpr5Y+X0xLZxXqcZNDWZdJdYbKd3q2IR4V9y5NxxiPu/jxJ8XP7EgHiEQtFnw== dependencies: - "@typescript-eslint/types" "5.10.0" - "@typescript-eslint/visitor-keys" "5.10.0" + "@typescript-eslint/types" "5.10.2" + "@typescript-eslint/visitor-keys" "5.10.2" -"@typescript-eslint/type-utils@5.10.0": - version "5.10.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.10.0.tgz#8524b9479c19c478347a7df216827e749e4a51e5" - integrity sha512-TzlyTmufJO5V886N+hTJBGIfnjQDQ32rJYxPaeiyWKdjsv2Ld5l8cbS7pxim4DeNs62fKzRSt8Q14Evs4JnZyQ== +"@typescript-eslint/type-utils@5.10.2": + version "5.10.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.10.2.tgz#ad5acdf98a7d2ab030bea81f17da457519101ceb" + integrity sha512-uRKSvw/Ccs5FYEoXW04Z5VfzF2iiZcx8Fu7DGIB7RHozuP0VbKNzP1KfZkHBTM75pCpsWxIthEH1B33dmGBKHw== dependencies: - "@typescript-eslint/utils" "5.10.0" + "@typescript-eslint/utils" "5.10.2" debug "^4.3.2" tsutils "^3.21.0" -"@typescript-eslint/types@5.10.0": - version "5.10.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.10.0.tgz#beb3cb345076f5b088afe996d57bcd1dfddaa75c" - integrity sha512-wUljCgkqHsMZbw60IbOqT/puLfyqqD5PquGiBo1u1IS3PLxdi3RDGlyf032IJyh+eQoGhz9kzhtZa+VC4eWTlQ== +"@typescript-eslint/types@5.10.2": + version "5.10.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.10.2.tgz#604d15d795c4601fffba6ecb4587ff9fdec68ce8" + integrity sha512-Qfp0qk/5j2Rz3p3/WhWgu4S1JtMcPgFLnmAKAW061uXxKSa7VWKZsDXVaMXh2N60CX9h6YLaBoy9PJAfCOjk3w== -"@typescript-eslint/typescript-estree@5.10.0": - version "5.10.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.10.0.tgz#4be24a3dea0f930bb1397c46187d0efdd955a224" - integrity sha512-x+7e5IqfwLwsxTdliHRtlIYkgdtYXzE0CkFeV6ytAqq431ZyxCFzNMNR5sr3WOlIG/ihVZr9K/y71VHTF/DUQA== +"@typescript-eslint/typescript-estree@5.10.2": + version "5.10.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.10.2.tgz#810906056cd3ddcb35aa333fdbbef3713b0fe4a7" + integrity sha512-WHHw6a9vvZls6JkTgGljwCsMkv8wu8XU8WaYKeYhxhWXH/atZeiMW6uDFPLZOvzNOGmuSMvHtZKd6AuC8PrwKQ== dependencies: - "@typescript-eslint/types" "5.10.0" - "@typescript-eslint/visitor-keys" "5.10.0" + "@typescript-eslint/types" "5.10.2" + "@typescript-eslint/visitor-keys" "5.10.2" debug "^4.3.2" globby "^11.0.4" is-glob "^4.0.3" semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/utils@5.10.0": - version "5.10.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.10.0.tgz#c3d152a85da77c400e37281355561c72fb1b5a65" - integrity sha512-IGYwlt1CVcFoE2ueW4/ioEwybR60RAdGeiJX/iDAw0t5w0wK3S7QncDwpmsM70nKgGTuVchEWB8lwZwHqPAWRg== +"@typescript-eslint/utils@5.10.2": + version "5.10.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.10.2.tgz#1fcd37547c32c648ab11aea7173ec30060ee87a8" + integrity sha512-vuJaBeig1NnBRkf7q9tgMLREiYD7zsMrsN1DA3wcoMDvr3BTFiIpKjGiYZoKPllfEwN7spUjv7ZqD+JhbVjEPg== dependencies: "@types/json-schema" "^7.0.9" - "@typescript-eslint/scope-manager" "5.10.0" - "@typescript-eslint/types" "5.10.0" - "@typescript-eslint/typescript-estree" "5.10.0" + "@typescript-eslint/scope-manager" "5.10.2" + "@typescript-eslint/types" "5.10.2" + "@typescript-eslint/typescript-estree" "5.10.2" eslint-scope "^5.1.1" eslint-utils "^3.0.0" -"@typescript-eslint/visitor-keys@5.10.0": - version "5.10.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.10.0.tgz#770215497ad67cd15a572b52089991d5dfe06281" - integrity sha512-GMxj0K1uyrFLPKASLmZzCuSddmjZVbVj3Ouy5QVuIGKZopxvOr24JsS7gruz6C3GExE01mublZ3mIBOaon9zuQ== +"@typescript-eslint/visitor-keys@5.10.2": + version "5.10.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.10.2.tgz#fdbf272d8e61c045d865bd6c8b41bea73d222f3d" + integrity sha512-zHIhYGGGrFJvvyfwHk5M08C5B5K4bewkm+rrvNTKk1/S15YHR+SA/QUF8ZWscXSfEaB8Nn2puZj+iHcoxVOD/Q== dependencies: - "@typescript-eslint/types" "5.10.0" + "@typescript-eslint/types" "5.10.2" eslint-visitor-keys "^3.0.0" "@ungap/promise-all-settled@1.1.2": @@ -1014,137 +921,6 @@ resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== -"@webassemblyjs/ast@1.11.0": - version "1.11.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.0.tgz#a5aa679efdc9e51707a4207139da57920555961f" - integrity sha512-kX2W49LWsbthrmIRMbQZuQDhGtjyqXfEmmHyEi4XWnSZtPmxY0+3anPIzsnRb45VH/J55zlOfWvZuY47aJZTJg== - dependencies: - "@webassemblyjs/helper-numbers" "1.11.0" - "@webassemblyjs/helper-wasm-bytecode" "1.11.0" - -"@webassemblyjs/floating-point-hex-parser@1.11.0": - version "1.11.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.0.tgz#34d62052f453cd43101d72eab4966a022587947c" - integrity sha512-Q/aVYs/VnPDVYvsCBL/gSgwmfjeCb4LW8+TMrO3cSzJImgv8lxxEPM2JA5jMrivE7LSz3V+PFqtMbls3m1exDA== - -"@webassemblyjs/helper-api-error@1.11.0": - version "1.11.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.0.tgz#aaea8fb3b923f4aaa9b512ff541b013ffb68d2d4" - integrity sha512-baT/va95eXiXb2QflSx95QGT5ClzWpGaa8L7JnJbgzoYeaA27FCvuBXU758l+KXWRndEmUXjP0Q5fibhavIn8w== - -"@webassemblyjs/helper-buffer@1.11.0": - version "1.11.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.0.tgz#d026c25d175e388a7dbda9694e91e743cbe9b642" - integrity sha512-u9HPBEl4DS+vA8qLQdEQ6N/eJQ7gT7aNvMIo8AAWvAl/xMrcOSiI2M0MAnMCy3jIFke7bEee/JwdX1nUpCtdyA== - -"@webassemblyjs/helper-numbers@1.11.0": - version "1.11.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.0.tgz#7ab04172d54e312cc6ea4286d7d9fa27c88cd4f9" - integrity sha512-DhRQKelIj01s5IgdsOJMKLppI+4zpmcMQ3XboFPLwCpSNH6Hqo1ritgHgD0nqHeSYqofA6aBN/NmXuGjM1jEfQ== - dependencies: - "@webassemblyjs/floating-point-hex-parser" "1.11.0" - "@webassemblyjs/helper-api-error" "1.11.0" - "@xtuc/long" "4.2.2" - -"@webassemblyjs/helper-wasm-bytecode@1.11.0": - version "1.11.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.0.tgz#85fdcda4129902fe86f81abf7e7236953ec5a4e1" - integrity sha512-MbmhvxXExm542tWREgSFnOVo07fDpsBJg3sIl6fSp9xuu75eGz5lz31q7wTLffwL3Za7XNRCMZy210+tnsUSEA== - -"@webassemblyjs/helper-wasm-section@1.11.0": - version "1.11.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.0.tgz#9ce2cc89300262509c801b4af113d1ca25c1a75b" - integrity sha512-3Eb88hcbfY/FCukrg6i3EH8H2UsD7x8Vy47iVJrP967A9JGqgBVL9aH71SETPx1JrGsOUVLo0c7vMCN22ytJew== - dependencies: - "@webassemblyjs/ast" "1.11.0" - "@webassemblyjs/helper-buffer" "1.11.0" - "@webassemblyjs/helper-wasm-bytecode" "1.11.0" - "@webassemblyjs/wasm-gen" "1.11.0" - -"@webassemblyjs/ieee754@1.11.0": - version "1.11.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.0.tgz#46975d583f9828f5d094ac210e219441c4e6f5cf" - integrity sha512-KXzOqpcYQwAfeQ6WbF6HXo+0udBNmw0iXDmEK5sFlmQdmND+tr773Ti8/5T/M6Tl/413ArSJErATd8In3B+WBA== - dependencies: - "@xtuc/ieee754" "^1.2.0" - -"@webassemblyjs/leb128@1.11.0": - version "1.11.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.0.tgz#f7353de1df38aa201cba9fb88b43f41f75ff403b" - integrity sha512-aqbsHa1mSQAbeeNcl38un6qVY++hh8OpCOzxhixSYgbRfNWcxJNJQwe2rezK9XEcssJbbWIkblaJRwGMS9zp+g== - dependencies: - "@xtuc/long" "4.2.2" - -"@webassemblyjs/utf8@1.11.0": - version "1.11.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.0.tgz#86e48f959cf49e0e5091f069a709b862f5a2cadf" - integrity sha512-A/lclGxH6SpSLSyFowMzO/+aDEPU4hvEiooCMXQPcQFPPJaYcPQNKGOCLUySJsYJ4trbpr+Fs08n4jelkVTGVw== - -"@webassemblyjs/wasm-edit@1.11.0": - version "1.11.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.0.tgz#ee4a5c9f677046a210542ae63897094c2027cb78" - integrity sha512-JHQ0damXy0G6J9ucyKVXO2j08JVJ2ntkdJlq1UTiUrIgfGMmA7Ik5VdC/L8hBK46kVJgujkBIoMtT8yVr+yVOQ== - dependencies: - "@webassemblyjs/ast" "1.11.0" - "@webassemblyjs/helper-buffer" "1.11.0" - "@webassemblyjs/helper-wasm-bytecode" "1.11.0" - "@webassemblyjs/helper-wasm-section" "1.11.0" - "@webassemblyjs/wasm-gen" "1.11.0" - "@webassemblyjs/wasm-opt" "1.11.0" - "@webassemblyjs/wasm-parser" "1.11.0" - "@webassemblyjs/wast-printer" "1.11.0" - -"@webassemblyjs/wasm-gen@1.11.0": - version "1.11.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.0.tgz#3cdb35e70082d42a35166988dda64f24ceb97abe" - integrity sha512-BEUv1aj0WptCZ9kIS30th5ILASUnAPEvE3tVMTrItnZRT9tXCLW2LEXT8ezLw59rqPP9klh9LPmpU+WmRQmCPQ== - dependencies: - "@webassemblyjs/ast" "1.11.0" - "@webassemblyjs/helper-wasm-bytecode" "1.11.0" - "@webassemblyjs/ieee754" "1.11.0" - "@webassemblyjs/leb128" "1.11.0" - "@webassemblyjs/utf8" "1.11.0" - -"@webassemblyjs/wasm-opt@1.11.0": - version "1.11.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.0.tgz#1638ae188137f4bb031f568a413cd24d32f92978" - integrity sha512-tHUSP5F4ywyh3hZ0+fDQuWxKx3mJiPeFufg+9gwTpYp324mPCQgnuVKwzLTZVqj0duRDovnPaZqDwoyhIO8kYg== - dependencies: - "@webassemblyjs/ast" "1.11.0" - "@webassemblyjs/helper-buffer" "1.11.0" - "@webassemblyjs/wasm-gen" "1.11.0" - "@webassemblyjs/wasm-parser" "1.11.0" - -"@webassemblyjs/wasm-parser@1.11.0": - version "1.11.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.0.tgz#3e680b8830d5b13d1ec86cc42f38f3d4a7700754" - integrity sha512-6L285Sgu9gphrcpDXINvm0M9BskznnzJTE7gYkjDbxET28shDqp27wpruyx3C2S/dvEwiigBwLA1cz7lNUi0kw== - dependencies: - "@webassemblyjs/ast" "1.11.0" - "@webassemblyjs/helper-api-error" "1.11.0" - "@webassemblyjs/helper-wasm-bytecode" "1.11.0" - "@webassemblyjs/ieee754" "1.11.0" - "@webassemblyjs/leb128" "1.11.0" - "@webassemblyjs/utf8" "1.11.0" - -"@webassemblyjs/wast-printer@1.11.0": - version "1.11.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.0.tgz#680d1f6a5365d6d401974a8e949e05474e1fab7e" - integrity sha512-Fg5OX46pRdTgB7rKIUojkh9vXaVN6sGYCnEiJN1GYkb0RPwShZXp6KTDqmoMdQPKhcroOXh3fEzmkWmCYaKYhQ== - dependencies: - "@webassemblyjs/ast" "1.11.0" - "@xtuc/long" "4.2.2" - -"@xtuc/ieee754@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" - integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== - -"@xtuc/long@4.2.2": - version "4.2.2" - resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" - integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== - abab@^2.0.3, abab@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" @@ -1198,22 +974,12 @@ acorn@^7.1.1: resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -acorn@^8.0.4: - version "8.1.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.1.0.tgz#52311fd7037ae119cbb134309e901aa46295b3fe" - integrity sha512-LWCF/Wn0nfHOmJ9rzQApGnxnvgfROzGilS8936rqN/lfcYkY9MYZzdMqN+2NJ4SlTc+m5HiSa+kNfDtI64dwUA== - -acorn@^8.2.4: - version "8.2.4" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.2.4.tgz#caba24b08185c3b56e3168e97d15ed17f4d31fd0" - integrity sha512-Ibt84YwBDDA890eDiDCEqcbwvHlBvzzDkU2cGBBDDI1QWT12jTiXIOn2CIw5KK4i6N5Z2HUxwYjzriDyqaqqZg== - acorn@^8.4.1: version "8.4.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.4.1.tgz#56c36251fc7cabc7096adc18f05afe814321a28c" integrity sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA== -acorn@^8.7.0: +acorn@^8.5.0, acorn@^8.7.0: version "8.7.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf" integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ== @@ -1476,10 +1242,10 @@ autwh@0.1.0: dependencies: oauth "0.9.15" -aws-sdk@2.1061.0: - version "2.1061.0" - resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.1061.0.tgz#79c75e6856e5a59e0857d0d066a8ff5ff5e0d752" - integrity sha512-T29yV+EPo4Fis9hAArxAXS/u6utKnlBq3DEu85LTSIA8i6e6Xg7e9u7Rveo8DmrlVrf7EGCNThaeF9WERHnwLg== +aws-sdk@2.1067.0: + version "2.1067.0" + resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.1067.0.tgz#2e7f5a2d765fcf77a45f25fdd1f12a64942628a7" + integrity sha512-3Ys1k4cNQy4z37IpPjQ9c5ldkXMeZGbWoarKHynPPY3WCEj+Nw2u6zk484fA9/lTHNN3YesLuZ0OmEzGgjFEOw== dependencies: buffer "4.9.2" events "1.1.1" @@ -1638,17 +1404,6 @@ browser-stdout@1.3.1: resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== -browserslist@^4.14.5: - version "4.16.3" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.3.tgz#340aa46940d7db878748567c5dea24a48ddf3717" - integrity sha512-vIyhWmIkULaq04Gt93txdh+j02yX/JzlyhLYbV3YQCn/zvES3JnY7TifHHvvr1w5hTDluNKMkV05cs4vy8Q7sw== - dependencies: - caniuse-lite "^1.0.30001181" - colorette "^1.2.1" - electron-to-chromium "^1.3.649" - escalade "^3.1.1" - node-releases "^1.1.70" - buffer-crc32@^0.2.1, buffer-crc32@^0.2.13: version "0.2.13" resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" @@ -1711,16 +1466,17 @@ bufferutil@^4.0.1: dependencies: node-gyp-build "~3.7.0" -bull@4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/bull/-/bull-4.2.1.tgz#c5a7e1496c7903274ce90192e4e5cb18f6c866c0" - integrity sha512-YkCQZMOub++siHw3SbYYXZ5xGEn6Tt3BPoCVq/irPNCxUqUYzta8yDlXyyAsfMKMVj0M7PcnynUabfMf9PFpOA== +bull@4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/bull/-/bull-4.5.0.tgz#d6106b011b711ffb76c687d7f2db416955225f64" + integrity sha512-BejJxGwNNQPIrK1jFTN74kymFORYQ6ZyXWNsZx+6jtDtafQNUMHNSdoepabLLmeldmUvgAHvZDDIJWFGEo2MYg== dependencies: - cron-parser "^2.13.0" + cron-parser "^4.2.1" debuglog "^1.0.0" get-port "^5.1.1" ioredis "^4.27.0" lodash "^4.17.21" + msgpackr "^1.5.2" p-timeout "^3.2.0" semver "^7.3.2" uuid "^8.3.0" @@ -1821,11 +1577,6 @@ camelcase@^6.0.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809" integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== -caniuse-lite@^1.0.30001181: - version "1.0.30001191" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001191.tgz#bacb432b6701f690c8c5f7c680166b9a9f0843d9" - integrity sha512-xJJqzyd+7GCJXkcoBiQ1GuxEiOBCLQ0aVW9HMekifZsAVGdj5eJ4mFB9fEhSHipq9IOk/QXFJUiIr9lZT+EsGw== - canonicalize@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/canonicalize/-/canonicalize-1.0.1.tgz#657b4f3fa38a6ecb97a9e5b7b26d7a19cc6e0da9" @@ -1945,13 +1696,6 @@ chownr@^2.0.0: resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== -chrome-trace-event@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz#234090ee97c7d4ad1a2c4beae27505deffc608a4" - integrity sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ== - dependencies: - tslib "^1.9.0" - clean-stack@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" @@ -2053,10 +1797,10 @@ color-name@^1.0.0, color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== -color-string@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.6.0.tgz#c3915f61fe267672cb7e1e064c9d692219f6c312" - integrity sha512-c/hGS+kRWJutUBEngKKmk4iH3sD59MBkoxVapS/0wgpCz2u7XsNloxknyvBhzwEs1IbV36D9PwqLPJ2DTu3vMA== +color-string@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.9.0.tgz#63b6ebd1bec11999d1df3a79a7569451ac2be8aa" + integrity sha512-9Mrz2AQLefkH1UvASKj6v6hj/7eWgjnT/cVsR8CumieLoT+g900exWeNogqtweI8dxloXN9BDQTYro1oWu/5CQ== dependencies: color-name "^1.0.0" simple-swizzle "^0.2.2" @@ -2066,15 +1810,15 @@ color-support@^1.1.2: resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== -color@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/color/-/color-4.0.1.tgz#21df44cd10245a91b1ccf5ba031609b0e10e7d67" - integrity sha512-rpZjOKN5O7naJxkH2Rx1sZzzBgaiWECc6BYXjeCE6kF0kcASJYbUq02u7JqIHwCb/j3NhV+QhRL2683aICeGZA== +color@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/color/-/color-4.2.0.tgz#0c782459a3e98838ea01e4bc0fb43310ca35af78" + integrity sha512-hHTcrbvEnGjC7WBMk6ibQWFVDgEFTVmjrz2Q5HlU6ltwxv0JJN2Z8I7uRbWeQLF04dikxs8zgyZkazRJvSMtyQ== dependencies: color-convert "^2.0.1" - color-string "^1.6.0" + color-string "^1.9.0" -colorette@^1.2.0, colorette@^1.2.1: +colorette@^1.2.0: version "1.2.2" resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w== @@ -2086,7 +1830,7 @@ combined-stream@^1.0.8: dependencies: delayed-stream "~1.0.0" -commander@^2.19.0, commander@^2.20.0: +commander@^2.19.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== @@ -2195,7 +1939,15 @@ core-util-is@1.0.2, core-util-is@~1.0.0: resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= -crc-32@1.2.0, crc-32@^1.2.0: +crc-32@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.1.tgz#436d2bcaad27bcb6bd073a2587139d3024a16460" + integrity sha512-Dn/xm/1vFFgs3nfrpEVScHoIslO9NZRITWGz/1E/St6u4xw99vfZzVkW0OSnzx2h9egej9xwMCEut6sqwokM/w== + dependencies: + exit-on-epipe "~1.0.1" + printj "~1.3.1" + +crc-32@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.0.tgz#cb2db6e29b88508e32d9dd0ec1693e7b41a18208" integrity sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA== @@ -2216,13 +1968,12 @@ create-require@^1.1.0: resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== -cron-parser@^2.13.0: - version "2.13.0" - resolved "https://registry.yarnpkg.com/cron-parser/-/cron-parser-2.13.0.tgz#6f930bb6f2931790d2a9eec83b3ec276e27a6725" - integrity sha512-UWeIpnRb0eyoWPVk+pD3TDpNx3KCFQeezO224oJIkktBrcW6RoAPOx5zIKprZGfk6vcYSmA8yQXItejSaDBhbQ== +cron-parser@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/cron-parser/-/cron-parser-4.2.1.tgz#b43205d05ccd5c93b097dae64f3bd811f5993af3" + integrity sha512-5sJBwDYyCp+0vU5b7POl8zLWfgV5fOHxlc45FWoWdHecGC7MQHCjx0CHivCMRnGFovghKhhyYM+Zm9DcY5qcHg== dependencies: - is-nan "^1.2.1" - moment-timezone "^0.5.25" + luxon "^1.28.0" cross-env@7.0.3: version "7.0.3" @@ -2255,10 +2006,10 @@ css-what@2.1: resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2" integrity sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg== -cssom@^0.4.4: - version "0.4.4" - resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10" - integrity sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw== +cssom@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.5.0.tgz#d254fa92cd8b6fbd83811b9fbaed34663cc17c36" + integrity sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw== cssom@~0.3.6: version "0.3.8" @@ -2297,19 +2048,19 @@ data-uri-to-buffer@^4.0.0: resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz#b5db46aea50f6176428ac05b73be39a57701a64b" integrity sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA== -data-urls@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b" - integrity sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ== +data-urls@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-3.0.1.tgz#597fc2ae30f8bc4dbcf731fcd1b1954353afc6f8" + integrity sha512-Ds554NeT5Gennfoo9KN50Vh6tpgtvYEwraYjejXnyTpu1C7oXKxdFk75REooENHE8ndTVOJuv+BEs4/J/xcozw== dependencies: abab "^2.0.3" - whatwg-mimetype "^2.3.0" - whatwg-url "^8.0.0" + whatwg-mimetype "^3.0.0" + whatwg-url "^10.0.0" -dateformat@4.5.1: - version "4.5.1" - resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-4.5.1.tgz#c20e7a9ca77d147906b6dc2261a8be0a5bd2173c" - integrity sha512-OD0TZ+B7yP7ZgpJf5K2DIbj3FZvFvxgFUuaqA/V5zTjAtAAXZ1E8bktHxmAGs4x5b7PflqA9LeQ84Og7wYtF7Q== +date-fns@2.28.0: + version "2.28.0" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.28.0.tgz#9570d656f5fc13143e50c975a3b6bbeb46cd08b2" + integrity sha512-8d35hViGYx/QH0icHYCeLmsLmMUheMmTyV9Fcm6gvNwdw31yXXH+O85sOBJ+OLnLQMKZowvpKb6FgMIQjcpvQw== debug@2, debug@^2.2.0, debug@^2.5.2, debug@^2.6.9: version "2.6.9" @@ -2368,10 +2119,10 @@ decamelize@^4.0.0: resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== -decimal.js@^10.2.1: - version "10.2.1" - resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.2.1.tgz#238ae7b0f0c793d3e3cea410108b35a2c01426a3" - integrity sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw== +decimal.js@^10.3.1: + version "10.3.1" + resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.3.1.tgz#d8c3a444a9c6774ba60ca6ad7261c3a94fd5e783" + integrity sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ== decompress-response@^6.0.0: version "6.0.0" @@ -2462,10 +2213,10 @@ detect-file@^1.0.0: resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7" integrity sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc= -detect-libc@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" - integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= +detect-libc@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.0.tgz#c528bc09bc6d1aa30149228240917c225448f204" + integrity sha512-S55LzUl8HUav8l9E2PBTlC5PAJrHK7tkM+XXFGD+fbsbkTzhCpG6K05LxJcUOEWzMa4v6ptcMZ9s3fOdJDu0Zw== detect-node@2.1.0, detect-node@^2.1.0: version "2.1.0" @@ -2566,12 +2317,12 @@ domelementtype@^2.2.0: resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57" integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A== -domexception@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/domexception/-/domexception-2.0.1.tgz#fb44aefba793e1574b0af6aed2801d057529f304" - integrity sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg== +domexception@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/domexception/-/domexception-4.0.0.tgz#4ad1be56ccadc86fc76d033353999a8037d03673" + integrity sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw== dependencies: - webidl-conversions "^5.0.0" + webidl-conversions "^7.0.0" domhandler@^2.3.0: version "2.4.2" @@ -2661,11 +2412,6 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= -electron-to-chromium@^1.3.649: - version "1.3.672" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.672.tgz#3a6e335016dab4bc584d5292adc4f98f54541f6a" - integrity sha512-gFQe7HBb0lbOMqK2GAS5/1F+B0IMdYiAgB9OT/w1F4M7lgJK2aNOMNOM622aEax+nS1cTMytkiT0uMOkbtFmHw== - emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" @@ -2708,14 +2454,6 @@ enhanced-resolve@^5.0.0: graceful-fs "^4.2.4" tapable "^2.2.0" -enhanced-resolve@^5.7.0: - version "5.7.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.7.0.tgz#525c5d856680fbd5052de453ac83e32049958b5c" - integrity sha512-6njwt/NsZFUKhM6j9U8hzVyD4E4r0x7NQzhTCbcWOJ0IQjNSAoalWmb0AE51Wn+fwan5qVESWi7t2ToBxs9vrw== - dependencies: - graceful-fs "^4.2.4" - tapable "^2.2.0" - entities@^1.1.1, entities@~1.1.1: version "1.1.2" resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" @@ -2762,11 +2500,6 @@ es-abstract@^1.19.0, es-abstract@^1.19.1: string.prototype.trimstart "^1.0.4" unbox-primitive "^1.0.1" -es-module-lexer@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.4.0.tgz#21f4181cc8b7eee06855f1c59e6087c7bc4f77b0" - integrity sha512-iuEGihqqhKWFgh72Q/Jtch7V2t/ft8w8IPP2aEN8ArYKO+IWyo6hsi96hCdgyeEDQIV3InhYQ9BlwUFPGXrbEQ== - es-to-primitive@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" @@ -2912,10 +2645,10 @@ eslint-visitor-keys@^3.1.0, eslint-visitor-keys@^3.2.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.2.0.tgz#6fbb166a6798ee5991358bc2daa1ba76cc1254a1" integrity sha512-IOzT0X126zn7ALX0dwFiUQEdsfzrm4+ISsQS8nukaJXwEyYKRSnEIIDULYg1mCtGp7UUXgfGl7BIolXREQK+XQ== -eslint@8.7.0: - version "8.7.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.7.0.tgz#22e036842ee5b7cf87b03fe237731675b4d3633c" - integrity sha512-ifHYzkBGrzS2iDU7KjhCAVMGCvF6M3Xfs8X8b37cgrUlDt6bWRTpRh6T/gtSXv1HJ/BUGgmjvNvOEGu85Iif7w== +eslint@8.8.0: + version "8.8.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.8.0.tgz#9762b49abad0cb4952539ffdb0a046392e571a2d" + integrity sha512-H3KXAzQGBH1plhYS3okDix2ZthuYJlQQEGE5k0IKuEqUSiyu4AmxxlJ2MtTYeJ3xB4jDhcYCwGOg2TXYdnDXlQ== dependencies: "@eslint/eslintrc" "^1.0.5" "@humanwhocodes/config-array" "^0.9.2" @@ -3021,11 +2754,6 @@ events@1.1.1: resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" integrity sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ= -events@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/events/-/events-3.2.0.tgz#93b87c18f8efcd4202a461aec4dfc0556b639379" - integrity sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg== - execa@6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/execa/-/execa-6.0.0.tgz#598b46f09ae44f5d8097a30cfb1681d0f0371503" @@ -3241,10 +2969,10 @@ follow-redirects@^1.14.4: resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.7.tgz#2004c02eb9436eee9a21446a6477debf17e81685" integrity sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ== -form-data@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.0.tgz#31b7e39c85f1355b7139ee0c647cf0de7f83c682" - integrity sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg== +form-data@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== dependencies: asynckit "^0.4.0" combined-stream "^1.0.8" @@ -3419,11 +3147,6 @@ glob-parent@^6.0.1: dependencies: is-glob "^4.0.3" -glob-to-regexp@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" - integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== - glob@7.1.6, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: version "7.1.6" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" @@ -3619,12 +3342,12 @@ hpagent@^0.1.1: resolved "https://registry.yarnpkg.com/hpagent/-/hpagent-0.1.1.tgz#66f67f16e5c7a8b59a068e40c2658c2c749ad5e2" integrity sha512-IxJWQiY0vmEjetHdoE9HZjD4Cx+mYTr25tR7JCxXaiI3QxW0YqYyM11KyZbHufoa/piWhMb2+D3FGpMgmA2cFQ== -html-encoding-sniffer@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3" - integrity sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ== +html-encoding-sniffer@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz#2cb1a8cf0db52414776e5b2a7a04d5dd98158de9" + integrity sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA== dependencies: - whatwg-encoding "^1.0.5" + whatwg-encoding "^2.0.0" html-entities@2.3.2: version "2.3.2" @@ -3687,13 +3410,6 @@ http-errors@~1.6.2: setprototypeof "1.1.0" statuses ">= 1.4.0 < 2" -http-headers@^3.0.1: - version "3.0.2" - resolved "https://registry.yarnpkg.com/http-headers/-/http-headers-3.0.2.tgz#5147771292f0b39d6778d930a3a59a76fc7ef44d" - integrity sha512-87E1I+2Wg4dxxz4rcxElo3dxO/w1ZtgL1yA0Sb6vH3qU16vRKq1NjWQv9SCY3ly2OQROcoxHZOUpmelS+k6wOw== - dependencies: - next-line "^1.1.0" - http-proxy-agent@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" @@ -3703,6 +3419,15 @@ http-proxy-agent@^4.0.1: agent-base "6" debug "4" +http-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" + integrity sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w== + dependencies: + "@tootallnate/once" "2" + agent-base "6" + debug "4" + http-signature@1.3.6: version "1.3.6" resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.3.6.tgz#cb6fbfdf86d1c974f343be94e87f7fc128662cf9" @@ -3712,7 +3437,7 @@ http-signature@1.3.6: jsprim "^2.0.2" sshpk "^1.14.1" -http2-wrapper@^1.0.0-beta.5.0: +http2-wrapper@^1.0.0-beta.5.0, http2-wrapper@^1.0.0-beta.5.2: version "1.0.3" resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.3.tgz#b8f55e0c1f25d4ebd08b3b0c2c079f9590800b3d" integrity sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg== @@ -3720,14 +3445,6 @@ http2-wrapper@^1.0.0-beta.5.0: quick-lru "^5.1.1" resolve-alpn "^1.0.0" -http2-wrapper@^1.0.0-beta.5.2: - version "1.0.0-beta.5.2" - resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.0-beta.5.2.tgz#8b923deb90144aea65cf834b016a340fc98556f3" - integrity sha512-xYz9goEyBnC8XwXDTuC/MZ6t+MrKVQZOk4s7+PaDkwIsQd8IwqvM+0M6bA/2lvG8GHXcPdf+MejTUeO2LCPCeQ== - dependencies: - quick-lru "^5.1.1" - resolve-alpn "^1.0.0" - http_ece@1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/http_ece/-/http_ece-1.1.0.tgz#74780c6eb32d8ddfe9e36a83abcd81fe0cd4fb75" @@ -3767,6 +3484,13 @@ iconv-lite@0.4.24, iconv-lite@^0.4.4: dependencies: safer-buffer ">= 2.1.2 < 3" +iconv-lite@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + iconv-lite@^0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.2.tgz#ce13d1875b0c3a674bd6a04b7f76b01b1b6ded01" @@ -4043,13 +3767,6 @@ is-lambda@^1.0.1: resolved "https://registry.yarnpkg.com/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5" integrity sha1-PZh3iZ5qU+/AFgUEzeFfgubwYdU= -is-nan@^1.2.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/is-nan/-/is-nan-1.3.0.tgz#85d1f5482f7051c2019f5673ccebdb06f3b0db03" - integrity sha512-z7bbREymOqt2CCaZVly8aC4ML3Xhfi0ekuOnjO2L8vKdl+CttdVoGZQhd4adMFAsxQ5VeRVwORs4tU8RH+HFtQ== - dependencies: - define-properties "^1.1.3" - is-negative-zero@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24" @@ -4184,15 +3901,6 @@ isexe@^2.0.0: resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= -jest-worker@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" - integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ== - dependencies: - "@types/node" "*" - merge-stream "^2.0.0" - supports-color "^7.0.0" - jmespath@0.16.0: version "0.16.0" resolved "https://registry.yarnpkg.com/jmespath/-/jmespath-0.16.0.tgz#b15b0a85dfd4d930d43e69ed605943c802785076" @@ -4253,23 +3961,23 @@ jschardet@3.0.0: resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-3.0.0.tgz#898d2332e45ebabbdb6bf2feece9feea9a99e882" integrity sha512-lJH6tJ77V8Nzd5QWRkFYCLc13a3vADkh3r/Fi8HupZGWk2OVVDfnZP8V/VgQgZ+lzW0kG2UGb5hFgt3V3ndotQ== -jsdom@16.7.0: - version "16.7.0" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.7.0.tgz#918ae71965424b197c819f8183a754e18977b710" - integrity sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw== +jsdom@19.0.0: + version "19.0.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-19.0.0.tgz#93e67c149fe26816d38a849ea30ac93677e16b6a" + integrity sha512-RYAyjCbxy/vri/CfnjUWJQQtZ3LKlLnDqj+9XLNnJPgEGeirZs3hllKR20re8LUZ6o1b1X4Jat+Qd26zmP41+A== dependencies: abab "^2.0.5" - acorn "^8.2.4" + acorn "^8.5.0" acorn-globals "^6.0.0" - cssom "^0.4.4" + cssom "^0.5.0" cssstyle "^2.3.0" - data-urls "^2.0.0" - decimal.js "^10.2.1" - domexception "^2.0.1" + data-urls "^3.0.1" + decimal.js "^10.3.1" + domexception "^4.0.0" escodegen "^2.0.0" - form-data "^3.0.0" - html-encoding-sniffer "^2.0.1" - http-proxy-agent "^4.0.1" + form-data "^4.0.0" + html-encoding-sniffer "^3.0.0" + http-proxy-agent "^5.0.0" https-proxy-agent "^5.0.0" is-potential-custom-element-name "^1.0.1" nwsapi "^2.2.0" @@ -4278,24 +3986,19 @@ jsdom@16.7.0: symbol-tree "^3.2.4" tough-cookie "^4.0.0" w3c-hr-time "^1.0.2" - w3c-xmlserializer "^2.0.0" - webidl-conversions "^6.1.0" - whatwg-encoding "^1.0.5" - whatwg-mimetype "^2.3.0" - whatwg-url "^8.5.0" - ws "^7.4.6" - xml-name-validator "^3.0.0" + w3c-xmlserializer "^3.0.0" + webidl-conversions "^7.0.0" + whatwg-encoding "^2.0.0" + whatwg-mimetype "^3.0.0" + whatwg-url "^10.0.0" + ws "^8.2.3" + xml-name-validator "^4.0.0" json-buffer@3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== -json-parse-better-errors@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" - integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== - json-schema-traverse@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" @@ -4610,11 +4313,6 @@ listenercount@~1.0.1: resolved "https://registry.yarnpkg.com/listenercount/-/listenercount-1.0.1.tgz#84c8a72ab59c4725321480c975e6508342e70937" integrity sha1-hMinKrWcRyUyFIDJdeZQg0LnCTc= -loader-runner@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.2.0.tgz#d7022380d66d14c5fb1d496b89864ebcfd478384" - integrity sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw== - loader-utils@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.0.tgz#e4cace5b816d425a166b5f097e10cd12b36064b0" @@ -4731,17 +4429,12 @@ lodash.some@^4.4.0: resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d" integrity sha1-G7nzFO9ri63tE7VJFpsqlF62jk0= -lodash.sortby@^4.7.0: - version "4.7.0" - resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" - integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= - lodash.union@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash.union/-/lodash.union-4.6.0.tgz#48bb5088409f16f1821666641c44dd1aaae3cd88" integrity sha1-SLtQiECfFvGCFmZkHETdGqrjzYg= -lodash@^4.17.14, lodash@^4.17.19, lodash@^4.17.21, lodash@^4.7.0: +lodash@^4.17.14, lodash@^4.17.19, lodash@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -4773,6 +4466,11 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" +luxon@^1.28.0: + version "1.28.0" + resolved "https://registry.yarnpkg.com/luxon/-/luxon-1.28.0.tgz#e7f96daad3938c06a62de0fb027115d251251fbf" + integrity sha512-TfTiyvZhwBYM/7QdAVDh+7dBTBA29v4ik0Ce9zda3Mnf8on1S5KJI8P2jKFZ8+5C0jhmr0KwJEO/Wdpm0VeWJQ== + mailcheck@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/mailcheck/-/mailcheck-1.1.1.tgz#d87cf6ba0b64ba512199dbf93f1489f479591e34" @@ -4867,7 +4565,7 @@ mime-types@2.1.34: dependencies: mime-db "1.51.0" -mime-types@^2.1.12, mime-types@^2.1.18, mime-types@^2.1.27, mime-types@~2.1.24: +mime-types@^2.1.12, mime-types@^2.1.18, mime-types@~2.1.24: version "2.1.27" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== @@ -5029,14 +4727,7 @@ mocha@8.4.0: yargs-parser "20.2.4" yargs-unparser "2.0.0" -moment-timezone@^0.5.25: - version "0.5.28" - resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.28.tgz#f093d789d091ed7b055d82aa81a82467f72e4338" - integrity sha512-TDJkZvAyKIVWg5EtVqRzU97w0Rb0YVbfpqyjgu6GwXCAohVRqwZjf4fOzDE6p1Ch98Sro/8hQQi65WDXW5STPw== - dependencies: - moment ">= 2.9.0" - -"moment@>= 2.9.0", moment@^2.22.2: +moment@^2.22.2: version "2.24.0" resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b" integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg== @@ -5061,6 +4752,21 @@ ms@3.0.0-canary.1: resolved "https://registry.yarnpkg.com/ms/-/ms-3.0.0-canary.1.tgz#c7b34fbce381492fd0b345d1cf56e14d67b77b80" integrity sha512-kh8ARjh8rMN7Du2igDRO9QJnqCb2xYTJxyQYK7vJJS4TvLLmsbyhiKpSW+t+y26gyOyMd0riphX0GeWKU3ky5g== +msgpackr-extract@^1.0.14: + version "1.0.16" + resolved "https://registry.yarnpkg.com/msgpackr-extract/-/msgpackr-extract-1.0.16.tgz#701c4f6e6f25c100ae84557092274e8fffeefe45" + integrity sha512-fxdRfQUxPrL/TizyfYfMn09dK58e+d65bRD/fcaVH4052vj30QOzzqxcQIS7B0NsqlypEQ/6Du3QmP2DhWFfCA== + dependencies: + nan "^2.14.2" + node-gyp-build "^4.2.3" + +msgpackr@^1.5.2: + version "1.5.4" + resolved "https://registry.yarnpkg.com/msgpackr/-/msgpackr-1.5.4.tgz#2b6ea6cb7d79c0ad98fc76c68163c48eda50cf0d" + integrity sha512-Z7w5Jg+2Q9z9gJxeM68d7tSuWZZGnFIRhZnyqcZCa/1dKkhOCNvR1TUV3zzJ3+vj78vlwKRzUgVDlW4jiSOeDA== + optionalDependencies: + msgpackr-extract "^1.0.14" + multer@1.4.4: version "1.4.4" resolved "https://registry.yarnpkg.com/multer/-/multer-1.4.4.tgz#e2bc6cac0df57a8832b858d7418ccaa8ebaf7d8c" @@ -5089,7 +4795,7 @@ mz@^2.4.0, mz@^2.7.0: object-assign "^4.0.1" thenify-all "^1.0.0" -nan@^2.15.0: +nan@^2.14.2, nan@^2.15.0: version "2.15.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.15.0.tgz#3f34a473ff18e15c1b5626b62903b5ad6e665fee" integrity sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ== @@ -5135,11 +4841,6 @@ negotiator@0.6.2, negotiator@^0.6.2: resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== -neo-async@^2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" - integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== - nested-property@4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/nested-property/-/nested-property-4.0.0.tgz#a67b5a31991e701e03cdbaa6453bc5b1011bb88d" @@ -5150,11 +4851,6 @@ netmask@^2.0.2: resolved "https://registry.yarnpkg.com/netmask/-/netmask-2.0.2.tgz#8b01a07644065d536383835823bc52004ebac5e7" integrity sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg== -next-line@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/next-line/-/next-line-1.1.0.tgz#fcae57853052b6a9bae8208e40dd7d3c2d304603" - integrity sha1-/K5XhTBStqm66CCOQN19PC0wRgM= - next-tick@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" @@ -5167,10 +4863,10 @@ node-abi@^3.3.0: dependencies: semver "^7.3.5" -node-addon-api@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-4.2.0.tgz#117cbb5a959dff0992e1c586ae0393573e4d2a87" - integrity sha512-eazsqzwG2lskuzBqCGPi7Ac2UgOoMz8JVOXVhTvvPDYhthvNpefx8jWD8Np7Gv+2Sz0FlPWZk0nJV0z598Wn8Q== +node-addon-api@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-4.3.0.tgz#52a1a0b475193e0928e98e0426a0d1254782b77f" + integrity sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ== node-domexception@^1.0.0: version "1.0.0" @@ -5199,6 +4895,11 @@ node-fetch@3.0.0-beta.9: data-uri-to-buffer "^3.0.1" fetch-blob "^2.1.1" +node-gyp-build@^4.2.3: + version "4.3.0" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.3.0.tgz#9f256b03e5826150be39c764bf51e993946d71a3" + integrity sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q== + node-gyp-build@~3.7.0: version "3.7.0" resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-3.7.0.tgz#daa77a4f547b9aed3e2aac779eaf151afd60ec8d" @@ -5220,11 +4921,6 @@ node-gyp@^8.4.1: tar "^6.1.2" which "^2.0.2" -node-releases@^1.1.70: - version "1.1.71" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.71.tgz#cb1334b179896b1c89ecfdd4b725fb7bbdfc7dbb" - integrity sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg== - nodemailer@6.7.2: version "6.7.2" resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.7.2.tgz#44b2ad5f7ed71b7067f7a21c4fedabaec62b85e0" @@ -5464,13 +5160,6 @@ p-limit@^3.0.2: dependencies: p-try "^2.0.0" -p-limit@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" - integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== - dependencies: - yocto-queue "^0.1.0" - p-locate@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" @@ -5743,12 +5432,12 @@ postgres-interval@^1.1.0: dependencies: xtend "^4.0.0" -prebuild-install@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.0.0.tgz#3c5ce3902f1cb9d6de5ae94ca53575e4af0c1574" - integrity sha512-IvSenf33K7JcgddNz2D5w521EgO+4aMMjFt73Uk9FRzQ7P+QZPKrp7qPsDydsSwjGt3T5xRNnM1bj1zMTD5fTA== +prebuild-install@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.0.1.tgz#c10075727c318efe72412f333e0ef625beaf3870" + integrity sha512-QBSab31WqkyxpnMWQxubYAHR5S9B2+r81ucocew34Fkl98FhvKIF50jIJnNOBmAZfyNV7vE5T6gd3hTVWgY6tg== dependencies: - detect-libc "^1.0.3" + detect-libc "^2.0.0" expand-template "^2.0.3" github-from-package "0.0.0" minimist "^1.2.3" @@ -5786,6 +5475,11 @@ printj@~1.1.0: resolved "https://registry.yarnpkg.com/printj/-/printj-1.1.2.tgz#d90deb2975a8b9f600fb3a1c94e3f4c53c78a222" integrity sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ== +printj@~1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/printj/-/printj-1.3.1.tgz#9af6b1d55647a1587ac44f4c1654a4b95b8e12cb" + integrity sha512-GA3TdL8szPK4AQ2YnOe/b+Y1jUFwmmGMMK/qbY7VcE3Z7FU8JstbKiKRzO6CIiAKPhTO8m01NoQ0V5f3jc4OGg== + private-ip@2.3.3: version "2.3.3" resolved "https://registry.yarnpkg.com/private-ip/-/private-ip-2.3.3.tgz#1e80ff8443e5ac78f555631aec3ea6ff027fa6aa" @@ -5796,10 +5490,10 @@ private-ip@2.3.3: is-ip "^3.1.0" netmask "^2.0.2" -probe-image-size@7.2.2: - version "7.2.2" - resolved "https://registry.yarnpkg.com/probe-image-size/-/probe-image-size-7.2.2.tgz#e5851b9be7864f21e3bac5e6e4fac9da9055b412" - integrity sha512-QUm+w1S9WTsT5GZB830u0BHExrUmF0J4fyRm5kbLUMEP3fl9UVYXc3xOBVqZNnH9tnvVEJO8vDk3PMtsLqjxug== +probe-image-size@7.2.3: + version "7.2.3" + resolved "https://registry.yarnpkg.com/probe-image-size/-/probe-image-size-7.2.3.tgz#d49c64be540ec8edea538f6f585f65a9b3ab4309" + integrity sha512-HubhG4Rb2UH8YtV4ba0Vp5bQ7L78RTONYu/ujmCu5nBI8wGv24s4E9xSKBi0N1MowRpxk76pFCpJtW0KPzOK0w== dependencies: lodash.merge "^4.6.2" needle "^2.5.2" @@ -6194,14 +5888,6 @@ rename@1.0.4: dependencies: debug "^2.5.2" -request-stats@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/request-stats/-/request-stats-3.0.0.tgz#769155dc8974d78d4a1cb87bbf14eaab985afe25" - integrity sha1-dpFV3Il0141KHLh7vxTqq5ha/iU= - dependencies: - http-headers "^3.0.1" - once "^1.4.0" - require-all@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/require-all/-/require-all-3.0.0.tgz#473d49704be310115ce124f77383b1ebd8671312" @@ -6397,7 +6083,7 @@ semver@^7.3.5: dependencies: lru-cache "^6.0.0" -serialize-javascript@5.0.1, serialize-javascript@^5.0.1: +serialize-javascript@5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-5.0.1.tgz#7886ec848049a462467a97d3d918ebb2aaf934f4" integrity sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA== @@ -6432,17 +6118,17 @@ sha.js@^2.4.11: inherits "^2.0.1" safe-buffer "^5.0.1" -sharp@0.29.3: - version "0.29.3" - resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.29.3.tgz#0da183d626094c974516a48fab9b3e4ba92eb5c2" - integrity sha512-fKWUuOw77E4nhpyzCCJR1ayrttHoFHBT2U/kR/qEMRhvPEcluG4BKj324+SCO1e84+knXHwhJ1HHJGnUt4ElGA== +sharp@0.30.0: + version "0.30.0" + resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.30.0.tgz#b2dd62d5f14088b11c72212354f31dff6511b070" + integrity sha512-L3m/l6yQFr3oGBUzcSAlN/R9yGFPYqM9FpMUe6Z4nHg4sWtP3hW1rcz+aaHklhD4wX5Jqh5PY9z+A1d4Qt3Hfg== dependencies: - color "^4.0.1" - detect-libc "^1.0.3" - node-addon-api "^4.2.0" - prebuild-install "^7.0.0" + color "^4.2.0" + detect-libc "^2.0.0" + node-addon-api "^4.3.0" + prebuild-install "^7.0.1" semver "^7.3.5" - simple-get "^4.0.0" + simple-get "^4.0.1" tar-fs "^2.1.1" tunnel-agent "^0.6.0" @@ -6496,6 +6182,15 @@ simple-get@^4.0.0: once "^1.3.1" simple-concat "^1.0.0" +simple-get@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-4.0.1.tgz#4a39db549287c979d352112fa03fd99fd6bc3543" + integrity sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA== + dependencies: + decompress-response "^6.0.0" + once "^1.3.1" + simple-concat "^1.0.0" + simple-swizzle@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" @@ -6530,34 +6225,16 @@ socks@^2.6.1: ip "^1.1.5" smart-buffer "^4.1.0" -source-list-map@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" - integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== - source-map-js@^0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-0.6.2.tgz#0bb5de631b41cfbda6cfba8bd05a80efdfd2385e" integrity sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug== -source-map-support@~0.5.19: - version "0.5.19" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" - integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: +source-map@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== -source-map@~0.7.2: - version "0.7.3" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" - integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== - speakeasy@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/speakeasy/-/speakeasy-2.0.0.tgz#85c91a071b09a5cb8642590d983566165f57613a" @@ -6794,7 +6471,7 @@ supports-color@^5.3.0: dependencies: has-flag "^3.0.0" -supports-color@^7.0.0, supports-color@^7.1.0: +supports-color@^7.1.0: version "7.2.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== @@ -6813,12 +6490,12 @@ syslog-pro@1.0.0: dependencies: moment "^2.22.2" -systeminformation@5.9.9: - version "5.9.9" - resolved "https://registry.yarnpkg.com/systeminformation/-/systeminformation-5.9.9.tgz#aa8234a138363bd988f438fed3273370f79d7e30" - integrity sha512-xciy6NKCLfs4dqMD1Tdlo7v1/g0NfdA1EKsIptUQjlcVvpwHyjifAbNOF7ppFezGSMXxYE8me+l2+RlFF4lyTg== +systeminformation@5.11.0: + version "5.11.0" + resolved "https://registry.yarnpkg.com/systeminformation/-/systeminformation-5.11.0.tgz#2060779e1e7c7372192dbcd850c65cfd85f4ea71" + integrity sha512-mI/5nFK7NUe9Qbmy65WoB5TlCWKAhP4kG0w6uR2mZM8Mpdi8b45b3hTIK3W5+kQYZnYFWeS9/O5nn5rdcSvqfA== -tapable@^2.1.1, tapable@^2.2.0: +tapable@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.0.tgz#5c373d281d9c672848213d0e037d1c4165ab426b" integrity sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw== @@ -6889,27 +6566,6 @@ tar@^6.1.2: mkdirp "^1.0.3" yallist "^4.0.0" -terser-webpack-plugin@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.1.1.tgz#7effadee06f7ecfa093dbbd3e9ab23f5f3ed8673" - integrity sha512-5XNNXZiR8YO6X6KhSGXfY0QrGrCRlSwAEjIIrlRQR4W8nP69TaJUlh3bkuac6zzgspiGPfKEHcY295MMVExl5Q== - dependencies: - jest-worker "^26.6.2" - p-limit "^3.1.0" - schema-utils "^3.0.0" - serialize-javascript "^5.0.1" - source-map "^0.6.1" - terser "^5.5.1" - -terser@^5.5.1: - version "5.5.1" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.5.1.tgz#540caa25139d6f496fdea056e414284886fb2289" - integrity sha512-6VGWZNVP2KTUcltUQJ25TtNjx/XgdDsBDKGt8nN0MpydU36LmbPPcMBd2kmtZNNGVVDLg44k7GKeHHj+4zPIBQ== - dependencies: - commander "^2.20.0" - source-map "~0.7.2" - source-map-support "~0.5.19" - text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" @@ -6990,10 +6646,10 @@ tough-cookie@^4.0.0: punycode "^2.1.1" universalify "^0.1.2" -tr46@^2.0.0, tr46@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.0.2.tgz#03273586def1595ae08fedb38d7733cee91d2479" - integrity sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg== +tr46@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-3.0.0.tgz#555c4e297a950617e8eeddef633c87d4d9d6cbf9" + integrity sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA== dependencies: punycode "^2.1.1" @@ -7057,7 +6713,7 @@ tsconfig-paths@3.12.0, tsconfig-paths@^3.12.0: minimist "^1.2.0" strip-bom "^3.0.0" -tslib@^1.8.1, tslib@^1.9.0: +tslib@^1.8.1: version "1.11.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35" integrity sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA== @@ -7318,20 +6974,12 @@ w3c-hr-time@^1.0.2: dependencies: browser-process-hrtime "^1.0.0" -w3c-xmlserializer@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz#3e7104a05b75146cc60f564380b7f683acf1020a" - integrity sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA== - dependencies: - xml-name-validator "^3.0.0" - -watchpack@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.0.0.tgz#b12248f32f0fd4799b7be0802ad1f6573a45955c" - integrity sha512-xSdCxxYZWNk3VK13bZRYhsQpfa8Vg63zXG+3pyU8ouqSLRCv4IGXIp9Kr226q6GBkGRlZrST2wwKtjfKz2m7Cg== +w3c-xmlserializer@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-3.0.0.tgz#06cdc3eefb7e4d0b20a560a5a3aeb0d2d9a65923" + integrity sha512-3WFqGEgSXIyGhOmAFtlicJNMjEps8b1MG31NCA0/vOF9+nKMUW1ckhi9cnNHmf88Rzw5V+dwIwsm2C7X8k9aQg== dependencies: - glob-to-regexp "^0.4.1" - graceful-fs "^4.1.2" + xml-name-validator "^4.0.0" web-push@3.4.5: version "3.4.5" @@ -7350,52 +6998,10 @@ web-streams-polyfill@^3.0.3: resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.2.0.tgz#a6b74026b38e4885869fb5c589e90b95ccfc7965" integrity sha512-EqPmREeOzttaLRm5HS7io98goBgZ7IVz79aDvqjD0kYXLtFZTc0T/U6wHTPKyIjb+MdN7DFIIX6hgdBEpWmfPA== -webidl-conversions@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff" - integrity sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA== - -webidl-conversions@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514" - integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w== - -webpack-sources@^2.1.1: - version "2.2.0" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-2.2.0.tgz#058926f39e3d443193b6c31547229806ffd02bac" - integrity sha512-bQsA24JLwcnWGArOKUxYKhX3Mz/nK1Xf6hxullKERyktjNMC4x8koOeaDNTA2fEJ09BdWLbM/iTW0ithREUP0w== - dependencies: - source-list-map "^2.0.1" - source-map "^0.6.1" - -webpack@^5: - version "5.33.2" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.33.2.tgz#c049717c9b038febf5a72fd2f53319ad59a8c1fc" - integrity sha512-X4b7F1sYBmJx8mlh2B7mV5szEkE0jYNJ2y3akgAP0ERi0vLCG1VvdsIxt8lFd4st6SUy0lf7W0CCQS566MBpJg== - dependencies: - "@types/eslint-scope" "^3.7.0" - "@types/estree" "^0.0.46" - "@webassemblyjs/ast" "1.11.0" - "@webassemblyjs/wasm-edit" "1.11.0" - "@webassemblyjs/wasm-parser" "1.11.0" - acorn "^8.0.4" - browserslist "^4.14.5" - chrome-trace-event "^1.0.2" - enhanced-resolve "^5.7.0" - es-module-lexer "^0.4.0" - eslint-scope "^5.1.1" - events "^3.2.0" - glob-to-regexp "^0.4.1" - graceful-fs "^4.2.4" - json-parse-better-errors "^1.0.2" - loader-runner "^4.2.0" - mime-types "^2.1.27" - neo-async "^2.6.2" - schema-utils "^3.0.0" - tapable "^2.1.1" - terser-webpack-plugin "^5.1.1" - watchpack "^2.0.0" - webpack-sources "^2.1.1" +webidl-conversions@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz#256b4e1882be7debbf01d05f0aa2039778ea080a" + integrity sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g== websocket@1.0.34: version "1.0.34" @@ -7409,35 +7015,25 @@ websocket@1.0.34: utf-8-validate "^5.0.2" yaeti "^0.0.6" -whatwg-encoding@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" - integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== +whatwg-encoding@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz#e7635f597fd87020858626805a2729fa7698ac53" + integrity sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg== dependencies: - iconv-lite "0.4.24" + iconv-lite "0.6.3" -whatwg-mimetype@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" - integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== - -whatwg-url@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.0.0.tgz#37f256cb746398e19b107bd6ef820b4ae2d15871" - integrity sha512-41ou2Dugpij8/LPO5Pq64K5q++MnRCBpEHvQr26/mArEKTkCV5aoXIqyhuYtE0pkqScXwhf2JP57rkRTYM29lQ== - dependencies: - lodash.sortby "^4.7.0" - tr46 "^2.0.0" - webidl-conversions "^5.0.0" +whatwg-mimetype@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz#5fa1a7623867ff1af6ca3dc72ad6b8a4208beba7" + integrity sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q== -whatwg-url@^8.5.0: - version "8.5.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.5.0.tgz#7752b8464fc0903fec89aa9846fc9efe07351fd3" - integrity sha512-fy+R77xWv0AiqfLl4nuGUlQ3/6b5uNfQ4WAbGQVMYshCTCCPK9psC1nWh3XHuxGVCtlcDDQPQW1csmmIQo+fwg== +whatwg-url@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-10.0.0.tgz#37264f720b575b4a311bd4094ed8c760caaa05da" + integrity sha512-CLxxCmdUby142H5FZzn4D8ikO1cmypvXVQktsgosNy4a4BHrDHeciBBGZhb0bNoR5/MltoCatso+vFjjGx8t0w== dependencies: - lodash "^4.7.0" - tr46 "^2.0.2" - webidl-conversions "^6.1.0" + tr46 "^3.0.0" + webidl-conversions "^7.0.0" which-boxed-primitive@^1.0.2: version "1.0.2" @@ -7526,16 +7122,11 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= -ws@8.4.2: +ws@8.4.2, ws@^8.2.3: version "8.4.2" resolved "https://registry.yarnpkg.com/ws/-/ws-8.4.2.tgz#18e749868d8439f2268368829042894b6907aa0b" integrity sha512-Kbk4Nxyq7/ZWqr/tarI9yIt/+iNNFOjBXEWgTb4ydaNHBNGgvf2QHbS9fdfsndfjFlFwEd4Al+mw83YkaD10ZA== -ws@^7.4.6: - version "7.5.3" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.3.tgz#160835b63c7d97bfab418fc1b8a9fced2ac01a74" - integrity sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg== - xev@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/xev/-/xev-2.0.1.tgz#24484173a22115bc8a990ef5d4d5129695b827a7" @@ -7548,10 +7139,10 @@ xml-js@^1.6.11: dependencies: sax "^1.2.4" -xml-name-validator@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" - integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== +xml-name-validator@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-4.0.0.tgz#79a006e2e63149a8600f15430f0a4725d1524835" + integrity sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw== xml2js@0.4.19: version "0.4.19" @@ -7695,11 +7286,6 @@ yn@3.1.1: resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== -yocto-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" - integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== - zen-observable-ts@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-1.0.0.tgz#30d1202b81d8ba4c489e3781e8ca09abf0075e70" diff --git a/packages/client/package.json b/packages/client/package.json index b840bafe8c370f8ea9414ce7e6ee53038cb8d846..cf4214e72b1aaf25e6fa619eaa1734f15ce58fb5 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -11,8 +11,8 @@ }, "dependencies": { "@discordapp/twemoji": "13.1.0", + "@fortawesome/fontawesome-free": "6.0.0-beta3", "@syuilo/aiscript": "0.11.1", - "@types/dateformat": "3.0.1", "@types/escape-regexp": "0.0.1", "@types/glob": "7.2.0", "@types/gulp": "4.0.9", @@ -26,7 +26,6 @@ "@types/punycode": "2.1.0", "@types/qrcode": "1.4.2", "@types/random-seed": "0.3.3", - "@types/request-stats": "3.0.0", "@types/seedrandom": "2.4.28", "@types/throttle-debounce": "2.1.0", "@types/tinycolor2": "1.4.3", @@ -47,6 +46,7 @@ "broadcast-channel": "4.9.0", "chart.js": "3.7.0", "chartjs-adapter-date-fns": "2.0.0", + "chartjs-plugin-gradient": "0.2.1", "chartjs-plugin-zoom": "1.2.0", "compare-versions": "4.1.3", "content-disposition": "0.5.4", @@ -87,7 +87,6 @@ "querystring": "0.2.1", "random-seed": "0.3.0", "reflect-metadata": "0.1.13", - "request-stats": "3.0.0", "rndstr": "1.0.0", "s-age": "1.1.2", "sass": "1.49.0", diff --git a/packages/client/src/components/chart-tooltip.vue b/packages/client/src/components/chart-tooltip.vue index b080eaf2b45899ed22803289aaafc5d4a2731e70..20e094a5a7e82441146bd47cc2053272689e338a 100644 --- a/packages/client/src/components/chart-tooltip.vue +++ b/packages/client/src/components/chart-tooltip.vue @@ -1,5 +1,5 @@ <template> -<MkTooltip ref="tooltip" :showing="showing" :x="x" :y="y" :max-width="340" @closed="emit('closed')"> +<MkTooltip ref="tooltip" :showing="showing" :x="x" :y="y" :max-width="340" :direction="'left'" :inner-margin="16" @closed="emit('closed')"> <div v-if="title" class="qpcyisrl"> <div class="title">{{ title }}</div> <div v-for="x in series" class="series"> diff --git a/packages/client/src/components/chart.vue b/packages/client/src/components/chart.vue index 3e46c51b473dbce9c12c7c94ef72e469f6c392ae..ced0d481c49c662affaab2e9259de1a7af6cda16 100644 --- a/packages/client/src/components/chart.vue +++ b/packages/client/src/components/chart.vue @@ -29,6 +29,7 @@ import { import 'chartjs-adapter-date-fns'; import { enUS } from 'date-fns/locale'; import zoomPlugin from 'chartjs-plugin-zoom'; +import gradient from 'chartjs-plugin-gradient'; import * as os from '@/os'; import { defaultStore } from '@/store'; import MkChartTooltip from '@/components/chart-tooltip.vue'; @@ -49,6 +50,7 @@ Chart.register( SubTitle, Filler, zoomPlugin, + gradient, ); const sum = (...arr) => arr.reduce((r, a) => r.map((b, i) => a[i] + b)); @@ -61,9 +63,17 @@ const alpha = (hex, a) => { return `rgba(${r}, ${g}, ${b}, ${a})`; }; -const colors = ['#008FFB', '#00E396', '#FEB019', '#FF4560']; +const colors = { + blue: '#008FFB', + green: '#00E396', + yellow: '#FEB019', + red: '#FF4560', + purple: '#e300db', + orange: '#fe6919', +}; +const colorSets = [colors.blue, colors.green, colors.yellow, colors.red, colors.purple]; const getColor = (i) => { - return colors[i % colors.length]; + return colorSets[i % colorSets.length]; }; export default defineComponent({ @@ -95,6 +105,11 @@ export default defineComponent({ required: false, default: false }, + bar: { + type: Boolean, + required: false, + default: false + }, aspectRatio: { type: Number, required: false, @@ -186,22 +201,36 @@ export default defineComponent({ // フォントカラー Chart.defaults.color = getComputedStyle(document.documentElement).getPropertyValue('--fg'); + const maxes = data.series.map((x, i) => Math.max(...x.data.map(d => d.y))); + chartInstance = new Chart(chartEl.value, { - type: 'line', + type: props.bar ? 'bar' : 'line', data: { labels: new Array(props.limit).fill(0).map((_, i) => getDate(i).toLocaleString()).slice().reverse(), datasets: data.series.map((x, i) => ({ parsing: false, label: x.name, data: x.data.slice().reverse(), + tension: 0.3, pointRadius: 0, - tension: 0, borderWidth: 2, borderColor: x.color ? x.color : getColor(i), borderDash: x.borderDash || [], borderJoinStyle: 'round', backgroundColor: alpha(x.color ? x.color : getColor(i), 0.1), + gradient: { + backgroundColor: { + axis: 'y', + colors: { + 0: alpha(x.color ? x.color : getColor(i), 0), + [maxes[i]]: alpha(x.color ? x.color : getColor(i), 0.1), + }, + }, + }, + barPercentage: 0.9, + categoryPercentage: 0.9, fill: x.type === 'area', + clip: 8, hidden: !!x.hidden, })), }, @@ -210,7 +239,7 @@ export default defineComponent({ layout: { padding: { left: 0, - right: 0, + right: 8, top: 0, bottom: 0, }, @@ -218,6 +247,7 @@ export default defineComponent({ scales: { x: { type: 'time', + stacked: props.stacked, time: { stepSize: 1, unit: props.span === 'day' ? 'month' : 'day', @@ -228,6 +258,8 @@ export default defineComponent({ }, ticks: { display: props.detailed, + maxRotation: 0, + autoSkipPadding: 16, }, adapters: { date: { @@ -245,12 +277,21 @@ export default defineComponent({ }, ticks: { display: props.detailed, + //mirror: true, }, }, }, interaction: { intersect: false, + mode: 'index', }, + elements: { + point: { + hoverRadius: 5, + hoverBorderWidth: 2, + }, + }, + animation: false, plugins: { legend: { display: props.detailed, @@ -294,6 +335,7 @@ export default defineComponent({ }, } }, + gradient, }, }, plugins: [{ @@ -324,20 +366,60 @@ export default defineComponent({ // TODO }; - const fetchFederationInstancesChart = async (total: boolean): Promise<typeof data> => { + const fetchFederationChart = async (): Promise<typeof data> => { const raw = await os.api('charts/federation', { limit: props.limit, span: props.span }); return { series: [{ - name: 'Instances', + name: 'Total', type: 'area', - data: format(total - ? raw.instance.total - : sum(raw.instance.inc, negate(raw.instance.dec)) - ), + data: format(raw.instance.total), + color: '#888888', + }, { + name: 'Inc/Dec', + type: 'area', + data: format(sum(raw.instance.inc, negate(raw.instance.dec))), + color: colors.purple, + }, { + name: 'Received', + type: 'area', + data: format(raw.inboxInstances), + color: colors.blue, + }, { + name: 'Delivered', + type: 'area', + data: format(raw.deliveredInstances), + color: colors.green, + }, { + name: 'Stalled', + type: 'area', + data: format(raw.stalled), + color: colors.red, }], }; }; + const fetchApRequestChart = async (): Promise<typeof data> => { + const raw = await os.api('charts/ap-request', { limit: props.limit, span: props.span }); + return { + series: [{ + name: 'In', + type: 'area', + color: '#008FFB', + data: format(raw.inboxReceived) + }, { + name: 'Out (succ)', + type: 'area', + color: '#00E396', + data: format(raw.deliverSucceeded) + }, { + name: 'Out (fail)', + type: 'area', + color: '#FEB019', + data: format(raw.deliverFailed) + }] + }; + }; + const fetchNotesChart = async (type: string): Promise<typeof data> => { const raw = await os.api('charts/notes', { limit: props.limit, span: props.span }); return { @@ -349,6 +431,7 @@ export default defineComponent({ ? sum(raw.local.inc, negate(raw.local.dec), raw.remote.inc, negate(raw.remote.dec)) : sum(raw[type].inc, negate(raw[type].dec)) ), + color: '#888888', }, { name: 'Renotes', type: 'area', @@ -356,6 +439,7 @@ export default defineComponent({ ? sum(raw.local.diffs.renote, raw.remote.diffs.renote) : raw[type].diffs.renote ), + color: colors.green, }, { name: 'Replies', type: 'area', @@ -363,6 +447,7 @@ export default defineComponent({ ? sum(raw.local.diffs.reply, raw.remote.diffs.reply) : raw[type].diffs.reply ), + color: colors.yellow, }, { name: 'Normal', type: 'area', @@ -370,6 +455,15 @@ export default defineComponent({ ? sum(raw.local.diffs.normal, raw.remote.diffs.normal) : raw[type].diffs.normal ), + color: colors.blue, + }, { + name: 'With file', + type: 'area', + data: format(type == 'combined' + ? sum(raw.local.diffs.withFile, raw.remote.diffs.withFile) + : raw[type].diffs.withFile + ), + color: colors.purple, }], }; }; @@ -425,17 +519,50 @@ export default defineComponent({ const raw = await os.api('charts/active-users', { limit: props.limit, span: props.span }); return { series: [{ - name: 'Combined', - type: 'line', - data: format(sum(raw.local.users, raw.remote.users)), + name: 'Read & Write', + type: 'area', + data: format(raw.readWrite), + color: colors.orange, }, { - name: 'Local', + name: 'Write', type: 'area', - data: format(raw.local.users), + data: format(raw.write), + color: colors.blue, }, { - name: 'Remote', + name: 'Read', + type: 'area', + data: format(raw.read), + color: '#888888', + }, { + name: '< Week', type: 'area', - data: format(raw.remote.users), + data: format(raw.registeredWithinWeek), + color: colors.green, + }, { + name: '< Month', + type: 'area', + data: format(raw.registeredWithinMonth), + color: colors.yellow, + }, { + name: '< Year', + type: 'area', + data: format(raw.registeredWithinYear), + color: colors.red, + }, { + name: '> Week', + type: 'area', + data: format(raw.registeredOutsideWeek), + color: colors.yellow, + }, { + name: '> Month', + type: 'area', + data: format(raw.registeredOutsideMonth), + color: colors.red, + }, { + name: '> Year', + type: 'area', + data: format(raw.registeredOutsideYear), + color: colors.purple, }], }; }; @@ -476,26 +603,6 @@ export default defineComponent({ }; }; - const fetchDriveTotalChart = async (): Promise<typeof data> => { - const raw = await os.api('charts/drive', { limit: props.limit, span: props.span }); - return { - bytes: true, - series: [{ - name: 'Combined', - type: 'line', - data: format(sum(raw.local.totalSize, raw.remote.totalSize)), - }, { - name: 'Local', - type: 'area', - data: format(raw.local.totalSize), - }, { - name: 'Remote', - type: 'area', - data: format(raw.remote.totalSize), - }], - }; - }; - const fetchDriveFilesChart = async (): Promise<typeof data> => { const raw = await os.api('charts/drive', { limit: props.limit, span: props.span }); return { @@ -531,25 +638,6 @@ export default defineComponent({ }; }; - const fetchDriveFilesTotalChart = async (): Promise<typeof data> => { - const raw = await os.api('charts/drive', { limit: props.limit, span: props.span }); - return { - series: [{ - name: 'Combined', - type: 'line', - data: format(sum(raw.local.totalCount, raw.remote.totalCount)), - }, { - name: 'Local', - type: 'area', - data: format(raw.local.totalCount), - }, { - name: 'Remote', - type: 'area', - data: format(raw.remote.totalCount), - }], - }; - }; - const fetchInstanceRequestsChart = async (): Promise<typeof data> => { const raw = await os.api('charts/instance', { host: props.args.host, limit: props.limit, span: props.span }); return { @@ -680,11 +768,26 @@ export default defineComponent({ }; }; + const fetchPerUserDriveChart = async (): Promise<typeof data> => { + const raw = await os.api('charts/user/drive', { userId: props.args.user.id, limit: props.limit, span: props.span }); + return { + series: [{ + name: 'Inc', + type: 'area', + data: format(raw.incSize), + }, { + name: 'Dec', + type: 'area', + data: format(raw.decSize), + }], + }; + }; + const fetchAndRender = async () => { const fetchData = () => { switch (props.src) { - case 'federation-instances': return fetchFederationInstancesChart(false); - case 'federation-instances-total': return fetchFederationInstancesChart(true); + case 'federation': return fetchFederationChart(); + case 'ap-request': return fetchApRequestChart(); case 'users': return fetchUsersChart(false); case 'users-total': return fetchUsersChart(true); case 'active-users': return fetchActiveUsersChart(); @@ -693,9 +796,7 @@ export default defineComponent({ case 'remote-notes': return fetchNotesChart('remote'); case 'notes-total': return fetchNotesTotalChart(); case 'drive': return fetchDriveChart(); - case 'drive-total': return fetchDriveTotalChart(); case 'drive-files': return fetchDriveFilesChart(); - case 'drive-files-total': return fetchDriveFilesTotalChart(); case 'instance-requests': return fetchInstanceRequestsChart(); case 'instance-users': return fetchInstanceUsersChart(false); @@ -710,6 +811,7 @@ export default defineComponent({ case 'instance-drive-files-total': return fetchInstanceDriveFilesChart(true); case 'per-user-notes': return fetchPerUserNotesChart(); + case 'per-user-drive': return fetchPerUserDriveChart(); } }; fetching.value = true; diff --git a/packages/client/src/components/emoji-picker.vue b/packages/client/src/components/emoji-picker.vue index 6999ad6517853ee3b9a3b7483117a64b53c894f3..3e1208979f0b83209df09e2b86a130db97aed907 100644 --- a/packages/client/src/components/emoji-picker.vue +++ b/packages/client/src/components/emoji-picker.vue @@ -81,7 +81,7 @@ import { getStaticImageUrl } from '@/scripts/get-static-image-url'; import Ripple from '@/components/ripple.vue'; import * as os from '@/os'; import { isTouchUsing } from '@/scripts/touch'; -import { isMobile } from '@/scripts/is-mobile'; +import { deviceKind } from '@/scripts/device-kind'; import { emojiCategories, instance } from '@/instance'; import XSection from './emoji-picker.section.vue'; import { i18n } from '@/i18n'; @@ -263,7 +263,7 @@ watch(q, () => { }); function focus() { - if (!isMobile && !isTouchUsing) { + if (!['smartphone', 'tablet'].includes(deviceKind) && !isTouchUsing) { search.value?.focus({ preventScroll: true }); diff --git a/packages/client/src/components/instance-stats.vue b/packages/client/src/components/instance-stats.vue index 409c3a49caa9a71416d23461ff2d50c8eb2bc7a1..d2aa5a151aaa6db05eb50ca5f923de9a9c56432c 100644 --- a/packages/client/src/components/instance-stats.vue +++ b/packages/client/src/components/instance-stats.vue @@ -3,8 +3,8 @@ <div class="selects" style="display: flex;"> <MkSelect v-model="chartSrc" style="margin: 0; flex: 1;"> <optgroup :label="$ts.federation"> - <option value="federation-instances">{{ $ts._charts.federationInstancesIncDec }}</option> - <option value="federation-instances-total">{{ $ts._charts.federationInstancesTotal }}</option> + <option value="federation">{{ $ts._charts.federation }}</option> + <option value="ap-request">{{ $ts._charts.apRequest }}</option> </optgroup> <optgroup :label="$ts.users"> <option value="users">{{ $ts._charts.usersIncDec }}</option> @@ -19,9 +19,7 @@ </optgroup> <optgroup :label="$ts.drive"> <option value="drive-files">{{ $ts._charts.filesIncDec }}</option> - <option value="drive-files-total">{{ $ts._charts.filesTotal }}</option> <option value="drive">{{ $ts._charts.storageUsageIncDec }}</option> - <option value="drive-total">{{ $ts._charts.storageUsageTotal }}</option> </optgroup> </MkSelect> <MkSelect v-model="chartSpan" style="margin: 0 0 0 10px;"> diff --git a/packages/client/src/components/instance-ticker.vue b/packages/client/src/components/instance-ticker.vue index 77fd8bb344444c9fde50b0753aed7c128c8e4ab5..9b0a18ec90058b1168419f6d8c4e94d2522f5440 100644 --- a/packages/client/src/components/instance-ticker.vue +++ b/packages/client/src/components/instance-ticker.vue @@ -7,15 +7,27 @@ <script lang="ts" setup> import { } from 'vue'; +import { instanceName } from '@/config'; const props = defineProps<{ - instance: any; // TODO + instance?: { + faviconUrl?: string + name: string + themeColor?: string + } }>(); -const themeColor = props.instance.themeColor || '#777777'; +// if no instance data is given, this is for the local instance +const instance = props.instance ?? { + faviconUrl: '/favicon.ico', + name: instanceName, + themeColor: (document.querySelector('meta[name="theme-color-orig"]') as HTMLMetaElement)?.content +}; + +const themeColor = instance.themeColor ?? '#777777'; const bg = { - background: `linear-gradient(90deg, ${themeColor}, ${themeColor + '00'})` + background: `linear-gradient(90deg, ${themeColor}, ${themeColor}00)` }; </script> diff --git a/packages/client/src/components/post-form.vue b/packages/client/src/components/post-form.vue index 535218ecf984937c769c359a35d2a20982d6ef95..64a6478f45365edf1dbe7e7db52fa648d54d4876 100644 --- a/packages/client/src/components/post-form.vue +++ b/packages/client/src/components/post-form.vue @@ -342,6 +342,7 @@ function addTag(tag: string) { function focus() { textareaEl.focus(); + textareaEl.setSelectionRange(textareaEl.value.length, textareaEl.value.length); } function chooseFileFrom(ev) { diff --git a/packages/client/src/components/ui/modal.vue b/packages/client/src/components/ui/modal.vue index 3c3bb5c2266973fb04d34e41a30bb1a18806ca80..b42c0e4d426fe5f279ebc7ca4f87875d035dff48 100644 --- a/packages/client/src/components/ui/modal.vue +++ b/packages/client/src/components/ui/modal.vue @@ -14,6 +14,7 @@ import { nextTick, onMounted, computed, ref, watch, provide } from 'vue'; import * as os from '@/os'; import { isTouchUsing } from '@/scripts/touch'; import { defaultStore } from '@/store'; +import { deviceKind } from '@/scripts/device-kind'; function getFixedContainer(el: Element | null): Element | null { if (el == null || el.tagName === 'BODY') return null; @@ -62,7 +63,7 @@ const content = ref<HTMLElement>(); const zIndex = os.claimZIndex(props.zPriority); const type = computed(() => { if (props.preferType === 'auto') { - if (!defaultStore.state.disableDrawer && isTouchUsing && window.innerWidth < 500 && window.innerHeight < 1000) { + if (!defaultStore.state.disableDrawer && isTouchUsing && deviceKind === 'smartphone') { return 'drawer'; } else { return props.src != null ? 'popup' : 'dialog'; diff --git a/packages/client/src/components/ui/tooltip.vue b/packages/client/src/components/ui/tooltip.vue index 1892877cc106a809c2d33991bccbb10ccff37fee..3ccd1b73169396704eae874808689d4c7b403b94 100644 --- a/packages/client/src/components/ui/tooltip.vue +++ b/packages/client/src/components/ui/tooltip.vue @@ -17,8 +17,12 @@ const props = withDefaults(defineProps<{ y?: number; text?: string; maxWidth?: number; + direction?: 'top' | 'bottom' | 'right' | 'left'; + innerMargin?: number; }>(), { maxWidth: 250, + direction: 'top', + innerMargin: 0, }); const emit = defineEmits<{ @@ -34,39 +38,144 @@ const setPosition = () => { const contentWidth = el.value.offsetWidth; const contentHeight = el.value.offsetHeight; - let left: number; - let top: number; - let rect: DOMRect; if (props.targetElement) { rect = props.targetElement.getBoundingClientRect(); + } + + const calcPosWhenTop = () => { + let left: number; + let top: number; + + if (props.targetElement) { + left = rect.left + window.pageXOffset + (props.targetElement.offsetWidth / 2); + top = (rect.top + window.pageYOffset - contentHeight) - props.innerMargin; + } else { + left = props.x; + top = (props.y - contentHeight) - props.innerMargin; + } + + left -= (el.value.offsetWidth / 2); + + if (left + contentWidth - window.pageXOffset > window.innerWidth) { + left = window.innerWidth - contentWidth + window.pageXOffset - 1; + } + + return [left, top]; + } + + const calcPosWhenBottom = () => { + let left: number; + let top: number; + + if (props.targetElement) { + left = rect.left + window.pageXOffset + (props.targetElement.offsetWidth / 2); + top = (rect.top + window.pageYOffset + props.targetElement.offsetHeight) + props.innerMargin; + } else { + left = props.x; + top = (props.y) + props.innerMargin; + } + + left -= (el.value.offsetWidth / 2); - left = rect.left + window.pageXOffset + (props.targetElement.offsetWidth / 2); - top = rect.top + window.pageYOffset - contentHeight; + if (left + contentWidth - window.pageXOffset > window.innerWidth) { + left = window.innerWidth - contentWidth + window.pageXOffset - 1; + } - el.value.style.transformOrigin = 'center bottom'; - } else { - left = props.x; - top = props.y - contentHeight; + return [left, top]; } - left -= (el.value.offsetWidth / 2); + const calcPosWhenLeft = () => { + let left: number; + let top: number; + + if (props.targetElement) { + left = (rect.left + window.pageXOffset - contentWidth) - props.innerMargin; + top = rect.top + window.pageYOffset + (props.targetElement.offsetHeight / 2); + } else { + left = (props.x - contentWidth) - props.innerMargin; + top = props.y; + } + + top -= (el.value.offsetHeight / 2); + + if (top + contentHeight - window.pageYOffset > window.innerHeight) { + top = window.innerHeight - contentHeight + window.pageYOffset - 1; + } - if (left + contentWidth - window.pageXOffset > window.innerWidth) { - left = window.innerWidth - contentWidth + window.pageXOffset - 1; + return [left, top]; } - // ツールãƒãƒƒãƒ—を上ã«å‘ã‹ã£ã¦è¡¨ç¤ºã™ã‚‹ã‚¹ãƒšãƒ¼ã‚¹ãŒãªã‘ã‚Œã°ä¸‹ã«å‘ã‹ã£ã¦å‡ºã™ - if (top - window.pageYOffset < 0) { + const calcPosWhenRight = () => { + let left: number; + let top: number; + if (props.targetElement) { - top = rect.top + window.pageYOffset + props.targetElement.offsetHeight; - el.value.style.transformOrigin = 'center top'; + left = (rect.left + window.pageXOffset) + props.innerMargin; + top = rect.top + window.pageYOffset + (props.targetElement.offsetHeight / 2); } else { + left = props.x + props.innerMargin; top = props.y; } + + top -= (el.value.offsetHeight / 2); + + if (top + contentHeight - window.pageYOffset > window.innerHeight) { + top = window.innerHeight - contentHeight + window.pageYOffset - 1; + } + + return [left, top]; + } + + const calc = (): { + left: number; + top: number; + transformOrigin: string; + } => { + switch (props.direction) { + case 'top': { + const [left, top] = calcPosWhenTop(); + + // ツールãƒãƒƒãƒ—を上ã«å‘ã‹ã£ã¦è¡¨ç¤ºã™ã‚‹ã‚¹ãƒšãƒ¼ã‚¹ãŒãªã‘ã‚Œã°ä¸‹ã«å‘ã‹ã£ã¦å‡ºã™ + if (top - window.pageYOffset < 0) { + const [left, top] = calcPosWhenBottom(); + return { left, top, transformOrigin: 'center top' }; + } + + return { left, top, transformOrigin: 'center bottom' }; + } + + case 'bottom': { + const [left, top] = calcPosWhenBottom(); + // TODO: ツールãƒãƒƒãƒ—を下ã«å‘ã‹ã£ã¦è¡¨ç¤ºã™ã‚‹ã‚¹ãƒšãƒ¼ã‚¹ãŒãªã‘ã‚Œã°ä¸Šã«å‘ã‹ã£ã¦å‡ºã™ + return { left, top, transformOrigin: 'center top' }; + } + + case 'left': { + const [left, top] = calcPosWhenLeft(); + + // ツールãƒãƒƒãƒ—ã‚’å·¦ã«å‘ã‹ã£ã¦è¡¨ç¤ºã™ã‚‹ã‚¹ãƒšãƒ¼ã‚¹ãŒãªã‘ã‚Œã°å³ã«å‘ã‹ã£ã¦å‡ºã™ + if (left - window.pageXOffset < 0) { + const [left, top] = calcPosWhenRight(); + return { left, top, transformOrigin: 'left center' }; + } + + return { left, top, transformOrigin: 'right center' }; + } + + case 'right': { + const [left, top] = calcPosWhenRight(); + // TODO: ツールãƒãƒƒãƒ—ã‚’å³ã«å‘ã‹ã£ã¦è¡¨ç¤ºã™ã‚‹ã‚¹ãƒšãƒ¼ã‚¹ãŒãªã‘ã‚Œã°å·¦ã«å‘ã‹ã£ã¦å‡ºã™ + return { left, top, transformOrigin: 'left center' }; + } + } + + return null as never; } + const { left, top, transformOrigin } = calc(); + el.value.style.transformOrigin = transformOrigin; el.value.style.left = left + 'px'; el.value.style.top = top + 'px'; }; diff --git a/packages/client/src/directives/get-size.ts b/packages/client/src/directives/get-size.ts index e3b5dea0f3337ea689d7fc256bae13208cec7c82..1fcd0718dc034808ad43c118fa47392005b9e9b9 100644 --- a/packages/client/src/directives/get-size.ts +++ b/packages/client/src/directives/get-size.ts @@ -1,34 +1,55 @@ import { Directive } from 'vue'; -export default { - mounted(src, binding, vn) { - const calc = () => { - const height = src.clientHeight; - const width = src.clientWidth; - - // è¦ç´ ãŒ(一時的ã«)DOMã«å˜åœ¨ã—ãªã„ã¨ãã¯è¨ˆç®—スã‚ップ - if (height === 0) return; - - binding.value(width, height); - }; +const mountings = new Map<Element, { + resize: ResizeObserver; + intersection?: IntersectionObserver; + fn: (w: number, h: number) => void; +}>(); + +function calc(src: Element) { + const info = mountings.get(src); + const height = src.clientHeight; + const width = src.clientWidth; + + if (!info) return; + + // アクティベートå‰ãªã©ã§srcãŒæç”»ã•ã‚Œã¦ã„ãªã„å ´åˆ + if (!height) { + // IntersectionObserverã§è¡¨ç¤ºæ¤œå‡ºã™ã‚‹ + if (!info.intersection) { + info.intersection = new IntersectionObserver(entries => { + if (entries.some(entry => entry.isIntersecting)) calc(src); + }); + } + info.intersection.observe(src); + return; + } + if (info.intersection) { + info.intersection.disconnect() + delete info.intersection; + }; - calc(); + info.fn(width, height); +}; - // Vue3ã§ã¯ä½¿ãˆãªããªã£ãŸ - // ç„¡ãã¦ã‚‚大丈夫ã‹...? - // TODO: ↑大丈夫ã˜ã‚ƒãªã‹ã£ãŸã®ã§è§£æ±ºç–を探㙠- //vn.context.$on('hook:activated', calc); +export default { + mounted(src, binding, vn) { - const ro = new ResizeObserver((entries, observer) => { - calc(); + const resize = new ResizeObserver((entries, observer) => { + calc(src); }); - ro.observe(src); + resize.observe(src); - src._get_size_ro_ = ro; + mountings.set(src, { resize, fn: binding.value, }); + calc(src); }, unmounted(src, binding, vn) { binding.value(0, 0); - src._get_size_ro_.unobserve(src); + const info = mountings.get(src); + if (!info) return; + info.resize.disconnect(); + if (info.intersection) info.intersection.disconnect(); + mountings.delete(src); } -} as Directive; +} as Directive<Element, (w: number, h: number) => void>; diff --git a/packages/client/src/directives/size.ts b/packages/client/src/directives/size.ts index a72a97abcc12c054293cb489218dcf0e38a8593b..36f649f1803650065c48aad1a19ff539d50ef434 100644 --- a/packages/client/src/directives/size.ts +++ b/packages/client/src/directives/size.ts @@ -1,68 +1,107 @@ import { Directive } from 'vue'; +type Value = { max?: number[]; min?: number[]; }; + //const observers = new Map<Element, ResizeObserver>(); +const mountings = new Map<Element, { + value: Value; + resize: ResizeObserver; + intersection?: IntersectionObserver; + previousWidth: number; +}>(); + +type ClassOrder = { + add: string[]; + remove: string[]; +}; + +const cache = new Map<string, ClassOrder>(); + +function getClassOrder(width: number, queue: Value): ClassOrder { + const getMaxClass = (v: number) => `max-width_${v}px`; + const getMinClass = (v: number) => `min-width_${v}px`; + + return { + add: [ + ...(queue.max ? queue.max.filter(v => width <= v).map(getMaxClass) : []), + ...(queue.min ? queue.min.filter(v => width >= v).map(getMinClass) : []), + ], + remove: [ + ...(queue.max ? queue.max.filter(v => width > v).map(getMaxClass) : []), + ...(queue.min ? queue.min.filter(v => width < v).map(getMinClass) : []), + ] + }; +} + +function applyClassOrder(el: Element, order: ClassOrder) { + el.classList.add(...order.add); + el.classList.remove(...order.remove); +} + +function getOrderName(width: number, queue: Value): string { + return `${width}|${queue.max ? queue.max.join(',') : ''}|${queue.min ? queue.min.join(',') : ''}`; +} + +function calc(el: Element) { + const info = mountings.get(el); + const width = el.clientWidth; + + if (!info || info.previousWidth === width) return; + + // アクティベートå‰ãªã©ã§srcãŒæç”»ã•ã‚Œã¦ã„ãªã„å ´åˆ + if (!width) { + // IntersectionObserverã§è¡¨ç¤ºæ¤œå‡ºã™ã‚‹ + if (!info.intersection) { + info.intersection = new IntersectionObserver(entries => { + if (entries.some(entry => entry.isIntersecting)) calc(el); + }); + } + info.intersection.observe(el); + return; + } + if (info.intersection) { + info.intersection.disconnect() + delete info.intersection; + }; + + mountings.set(el, Object.assign(info, { previousWidth: width })); + + const cached = cache.get(getOrderName(width, info.value)); + if (cached) { + applyClassOrder(el, cached); + } else { + const order = getClassOrder(width, info.value); + cache.set(getOrderName(width, info.value), order); + applyClassOrder(el, order); + } +} export default { mounted(src, binding, vn) { - const query = binding.value; - - const addClass = (el: Element, cls: string) => { - el.classList.add(cls); - }; - - const removeClass = (el: Element, cls: string) => { - el.classList.remove(cls); - }; - - const calc = () => { - const width = src.clientWidth; - - // è¦ç´ ãŒ(一時的ã«)DOMã«å˜åœ¨ã—ãªã„ã¨ãã¯è¨ˆç®—スã‚ップ - if (width === 0) return; - - if (query.max) { - for (const v of query.max) { - if (width <= v) { - addClass(src, 'max-width_' + v + 'px'); - } else { - removeClass(src, 'max-width_' + v + 'px'); - } - } - } - if (query.min) { - for (const v of query.min) { - if (width >= v) { - addClass(src, 'min-width_' + v + 'px'); - } else { - removeClass(src, 'min-width_' + v + 'px'); - } - } - } - }; - - calc(); - - window.addEventListener('resize', calc); - - // Vue3ã§ã¯ä½¿ãˆãªããªã£ãŸ - // ç„¡ãã¦ã‚‚大丈夫ã‹...? - // TODO: ↑大丈夫ã˜ã‚ƒãªã‹ã£ãŸã®ã§è§£æ±ºç–を探㙠- //vn.context.$on('hook:activated', calc); - - //const ro = new ResizeObserver((entries, observer) => { - // calc(); - //}); - - //ro.observe(el); - - // TODO: æ–°ãŸã«ãƒ—ãƒãƒ‘ティを作るã®ã‚’ã‚„ã‚Mapを使ㆠ- // ãŸã メモリ的ã«ã¯â†“ã®æ–¹ãŒçœãƒ¡ãƒ¢ãƒªã‹ã‚‚ã—ã‚Œãªã„ã®ã§æ¤œè¨Žä¸ - //el._ro_ = ro; - src._calc_ = calc; + const resize = new ResizeObserver((entries, observer) => { + calc(src); + }); + + mountings.set(src, { + value: binding.value, + resize, + previousWidth: 0, + }); + + calc(src); + resize.observe(src); + }, + + updated(src, binding, vn) { + mountings.set(src, Object.assign({}, mountings.get(src), { value: binding.value })); + calc(src); }, unmounted(src, binding, vn) { - //el._ro_.unobserve(el); - window.removeEventListener('resize', src._calc_); + const info = mountings.get(src); + if (!info) return; + info.resize.disconnect(); + if (info.intersection) info.intersection.disconnect(); + mountings.delete(src); } -} as Directive; +} as Directive<Element, Value>; diff --git a/packages/client/src/init.ts b/packages/client/src/init.ts index 81e41febd1886d8f2b5b40e0c3ae72d4c46a9570..b7fc8b1d1e438ca0d545bb0224a1678ed8863e31 100644 --- a/packages/client/src/init.ts +++ b/packages/client/src/init.ts @@ -14,7 +14,7 @@ if (localStorage.getItem('accounts') != null) { //#endregion import { computed, createApp, watch, markRaw, version as vueVersion } from 'vue'; -import * as compareVersions from 'compare-versions'; +import compareVersions from 'compare-versions'; import widgets from '@/widgets'; import directives from '@/directives'; @@ -32,7 +32,7 @@ import { defaultStore, ColdDeviceStorage } from '@/store'; import { fetchInstance, instance } from '@/instance'; import { makeHotkey } from '@/scripts/hotkey'; import { search } from '@/scripts/search'; -import { isMobile } from '@/scripts/is-mobile'; +import { deviceKind } from '@/scripts/device-kind'; import { initializeSw } from '@/scripts/initialize-sw'; import { reloadChannel } from '@/scripts/unison-reload'; import { reactionPicker } from '@/scripts/reaction-picker'; @@ -92,7 +92,7 @@ window.addEventListener('resize', () => { //#endregion // If mobile, insert the viewport meta tag -if (isMobile || window.innerWidth <= 1024) { +if (['smartphone', 'tablet'].includes(deviceKind)) { const viewport = document.getElementsByName('viewport').item(0); viewport.setAttribute('content', `${viewport.getAttribute('content')},minimum-scale=1,maximum-scale=1,user-scalable=no`); diff --git a/packages/client/src/pages/about.vue b/packages/client/src/pages/about.vue index d5bab4baf84c9cf904df58b79117443db9e99aa0..6cc2e387ec40504155d5849579a98e364f7f5ae5 100644 --- a/packages/client/src/pages/about.vue +++ b/packages/client/src/pages/about.vue @@ -1,5 +1,5 @@ <template> -<MkSpacer :content-max="600" :margin-min="20"> +<MkSpacer v-if="tab === 'overview'" :content-max="600" :margin-min="20"> <div class="_formRoot"> <div class="_formBlock fwhjspax" :style="{ backgroundImage: `url(${ $instance.bannerUrl })` }"> <div class="content"> @@ -65,35 +65,50 @@ </FormSection> </div> </MkSpacer> +<MkSpacer v-else-if="tab === 'charts'" :content-max="1200" :margin-min="20"> + <MkInstanceStats :chart-limit="500" :detailed="true"/> +</MkSpacer> </template> <script lang="ts" setup> -import { ref } from 'vue'; +import { ref, computed } from 'vue'; import { version, instanceName } from '@/config'; import FormLink from '@/components/form/link.vue'; import FormSection from '@/components/form/section.vue'; import FormSuspense from '@/components/form/suspense.vue'; import FormSplit from '@/components/form/split.vue'; import MkKeyValue from '@/components/key-value.vue'; +import MkInstanceStats from '@/components/instance-stats.vue'; import * as os from '@/os'; import number from '@/filters/number'; import * as symbols from '@/symbols'; import { host } from '@/config'; import { i18n } from '@/i18n'; -const stats = ref(null); +let stats = $ref(null); +let tab = $ref('overview'); const initStats = () => os.api('stats', { }).then((res) => { - stats.value = res; + stats = res; }); defineExpose({ - [symbols.PAGE_INFO]: { + [symbols.PAGE_INFO]: computed(() => ({ title: i18n.ts.instanceInfo, icon: 'fas fa-info-circle', bg: 'var(--bg)', - }, + tabs: [{ + active: tab === 'overview', + title: i18n.ts.overview, + onClick: () => { tab = 'overview'; }, + }, { + active: tab === 'charts', + title: i18n.ts.charts, + icon: 'fas fa-chart-bar', + onClick: () => { tab = 'charts'; }, + },], + })), }); </script> diff --git a/packages/client/src/pages/admin/files.vue b/packages/client/src/pages/admin/files.vue index 87dd12f489528c603128f906ceaa869ddd651aa0..c62f053092bb85e267caf58eb128f54b79a9b789 100644 --- a/packages/client/src/pages/admin/files.vue +++ b/packages/client/src/pages/admin/files.vue @@ -28,7 +28,7 @@ <template #label>MIME type</template> </MkInput> </div> - <MkPagination v-slot="{items}" ref="files" :pagination="pagination" class="urempief"> + <MkPagination v-slot="{items}" :pagination="pagination" class="urempief"> <button v-for="file in items" :key="file.id" class="file _panel _button _gap" @click="show(file, $event)"> <MkDriveFileThumbnail class="thumbnail" :file="file" fit="contain"/> <div class="body"> @@ -54,8 +54,8 @@ </div> </template> -<script lang="ts"> -import { computed, defineComponent } from 'vue'; +<script lang="ts" setup> +import { computed } from 'vue'; import MkButton from '@/components/ui/button.vue'; import MkInput from '@/components/form/input.vue'; import MkSelect from '@/components/form/select.vue'; @@ -65,80 +65,63 @@ import MkDriveFileThumbnail from '@/components/drive-file-thumbnail.vue'; import bytes from '@/filters/bytes'; import * as os from '@/os'; import * as symbols from '@/symbols'; +import { i18n } from '@/i18n'; + +let q = $ref(null); +let origin = $ref('local'); +let type = $ref(null); +let searchHost = $ref(''); +const pagination = { + endpoint: 'admin/drive/files' as const, + limit: 10, + params: computed(() => ({ + type: (type && type !== '') ? type : null, + origin: origin, + hostname: (searchHost && searchHost !== '') ? searchHost : null, + })), +}; + +function clear() { + os.confirm({ + type: 'warning', + text: i18n.ts.clearCachedFilesConfirm, + }).then(({ canceled }) => { + if (canceled) return; + + os.apiWithDialog('admin/drive/clean-remote-files', {}); + }); +} -export default defineComponent({ - components: { - MkButton, - MkInput, - MkSelect, - MkPagination, - MkContainer, - MkDriveFileThumbnail, - }, - - emits: ['info'], - - data() { - return { - [symbols.PAGE_INFO]: { - title: this.$ts.files, - icon: 'fas fa-cloud', - bg: 'var(--bg)', - actions: [{ - text: this.$ts.clearCachedFiles, - icon: 'fas fa-trash-alt', - handler: this.clear - }] - }, - q: null, - origin: 'local', - type: null, - searchHost: '', - pagination: { - endpoint: 'admin/drive/files' as const, - limit: 10, - params: computed(() => ({ - type: (this.type && this.type !== '') ? this.type : null, - origin: this.origin, - hostname: (this.searchHost && this.searchHost !== '') ? this.searchHost : null, - })), - }, - } - }, - - methods: { - clear() { - os.confirm({ - type: 'warning', - text: this.$ts.clearCachedFilesConfirm, - }).then(({ canceled }) => { - if (canceled) return; +function show(file) { + os.popup(import('./file-dialog.vue'), { + fileId: file.id + }, {}, 'closed'); +} - os.apiWithDialog('admin/drive/clean-remote-files', {}); +function find() { + os.api('admin/drive/show-file', q.startsWith('http://') || q.startsWith('https://') ? { url: q.trim() } : { fileId: q.trim() }).then(file => { + show(file); + }).catch(err => { + if (err.code === 'NO_SUCH_FILE') { + os.alert({ + type: 'error', + text: i18n.ts.notFound }); - }, - - show(file, ev) { - os.popup(import('./file-dialog.vue'), { - fileId: file.id - }, {}, 'closed'); - }, - - find() { - os.api('admin/drive/show-file', this.q.startsWith('http://') || this.q.startsWith('https://') ? { url: this.q.trim() } : { fileId: this.q.trim() }).then(file => { - this.show(file); - }).catch(e => { - if (e.code === 'NO_SUCH_FILE') { - os.alert({ - type: 'error', - text: this.$ts.notFound - }); - } - }); - }, + } + }); +} - bytes - } +defineExpose({ + [symbols.PAGE_INFO]: computed(() => ({ + title: i18n.ts.files, + icon: 'fas fa-cloud', + bg: 'var(--bg)', + actions: [{ + text: i18n.ts.clearCachedFiles, + icon: 'fas fa-trash-alt', + handler: clear, + }], + })), }); </script> diff --git a/packages/client/src/pages/admin/users.vue b/packages/client/src/pages/admin/users.vue index 03e155ddcfc5cca731d8378188f94448f4a7e47f..f05aa5ff4531569730f66b1f032aa11b73dbc4f0 100644 --- a/packages/client/src/pages/admin/users.vue +++ b/packages/client/src/pages/admin/users.vue @@ -36,7 +36,7 @@ </MkInput> </div> - <MkPagination v-slot="{items}" ref="users" :pagination="pagination" class="users"> + <MkPagination v-slot="{items}" ref="paginationComponent" :pagination="pagination" class="users"> <button v-for="user in items" :key="user.id" class="user _panel _button _gap" @click="show(user)"> <MkAvatar class="avatar" :user="user" :disable-link="true" :show-indicator="true"/> <div class="body"> @@ -61,9 +61,8 @@ </div> </template> -<script lang="ts"> -import { computed, defineComponent } from 'vue'; -import MkButton from '@/components/ui/button.vue'; +<script lang="ts" setup> +import { computed } from 'vue'; import MkInput from '@/components/form/input.vue'; import MkSelect from '@/components/form/select.vue'; import MkPagination from '@/components/ui/pagination.vue'; @@ -71,94 +70,79 @@ import { acct } from '@/filters/user'; import * as os from '@/os'; import * as symbols from '@/symbols'; import { lookupUser } from '@/scripts/lookup-user'; +import { i18n } from '@/i18n'; + +let paginationComponent = $ref<InstanceType<typeof MkPagination>>(); + +let sort = $ref('+createdAt'); +let state = $ref('all'); +let origin = $ref('local'); +let searchUsername = $ref(''); +let searchHost = $ref(''); +const pagination = { + endpoint: 'admin/show-users' as const, + limit: 10, + params: computed(() => ({ + sort: sort, + state: state, + origin: origin, + username: searchUsername, + hostname: searchHost, + })), + offsetMode: true +}; + +function searchUser() { + os.selectUser().then(user => { + show(user); + }); +} -export default defineComponent({ - components: { - MkButton, - MkInput, - MkSelect, - MkPagination, - }, - - emits: ['info'], - - data() { - return { - [symbols.PAGE_INFO]: { - title: this.$ts.users, - icon: 'fas fa-users', - bg: 'var(--bg)', - actions: [{ - icon: 'fas fa-search', - text: this.$ts.search, - handler: this.searchUser - }, { - asFullButton: true, - icon: 'fas fa-plus', - text: this.$ts.addUser, - handler: this.addUser - }, { - asFullButton: true, - icon: 'fas fa-search', - text: this.$ts.lookup, - handler: this.lookupUser - }], - }, - sort: '+createdAt', - state: 'all', - origin: 'local', - searchUsername: '', - searchHost: '', - pagination: { - endpoint: 'admin/show-users' as const, - limit: 10, - params: computed(() => ({ - sort: this.sort, - state: this.state, - origin: this.origin, - username: this.searchUsername, - hostname: this.searchHost, - })), - offsetMode: true - }, - } - }, - - methods: { - lookupUser, - - searchUser() { - os.selectUser().then(user => { - this.show(user); - }); - }, - - async addUser() { - const { canceled: canceled1, result: username } = await os.inputText({ - title: this.$ts.username, - }); - if (canceled1) return; - - const { canceled: canceled2, result: password } = await os.inputText({ - title: this.$ts.password, - type: 'password' - }); - if (canceled2) return; - - os.apiWithDialog('admin/accounts/create', { - username: username, - password: password, - }).then(res => { - this.$refs.users.reload(); - }); - }, - - show(user) { - os.pageWindow(`/user-info/${user.id}`); - }, - - acct - } +async function addUser() { + const { canceled: canceled1, result: username } = await os.inputText({ + title: i18n.ts.username, + }); + if (canceled1) return; + + const { canceled: canceled2, result: password } = await os.inputText({ + title: i18n.ts.password, + type: 'password' + }); + if (canceled2) return; + + os.apiWithDialog('admin/accounts/create', { + username: username, + password: password, + }).then(res => { + paginationComponent.reload(); + }); +} + +function show(user) { + os.pageWindow(`/user-info/${user.id}`); +} + +defineExpose({ + [symbols.PAGE_INFO]: computed(() => ({ + title: i18n.ts.users, + icon: 'fas fa-users', + bg: 'var(--bg)', + actions: [{ + icon: 'fas fa-search', + text: i18n.ts.search, + handler: searchUser + }, { + asFullButton: true, + icon: 'fas fa-plus', + text: i18n.ts.addUser, + handler: addUser + }, { + asFullButton: true, + icon: 'fas fa-search', + text: i18n.ts.lookup, + handler: lookupUser + }], + })), }); </script> diff --git a/packages/client/src/pages/settings/drive.vue b/packages/client/src/pages/settings/drive.vue index 134fa633080c1a5fe80fa350caaf09513ed55523..9309eb5ec76be0a5986a516997c1d3b808fa8da9 100644 --- a/packages/client/src/pages/settings/drive.vue +++ b/packages/client/src/pages/settings/drive.vue @@ -19,7 +19,7 @@ <FormSection> <template #label>{{ $ts.statistics }}</template> - <div ref="chart"></div> + <MkChart src="per-user-drive" :args="{ user: $i }" span="day" :limit="7 * 5" :bar="true" :stacked="true" :detailed="false" :aspect-ratio="6"/> </FormSection> <FormSection> @@ -45,8 +45,7 @@ import * as os from '@/os'; import bytes from '@/filters/bytes'; import * as symbols from '@/symbols'; import { defaultStore } from '@/store'; - -// TODO: render chart +import MkChart from '@/components/chart.vue'; export default defineComponent({ components: { @@ -55,6 +54,7 @@ export default defineComponent({ FormSection, MkKeyValue, FormSplit, + MkChart, }, emits: ['info'], diff --git a/packages/client/src/pages/settings/general.vue b/packages/client/src/pages/settings/general.vue index 2e159e56a91e23c168d6e7f2503bed86d418ed37..c8f6f5832216f39b9027109fbe5114811d9dfcc6 100644 --- a/packages/client/src/pages/settings/general.vue +++ b/packages/client/src/pages/settings/general.vue @@ -12,6 +12,14 @@ </template> </FormSelect> + <FormRadios v-model="overridedDeviceKind" class="_formBlock"> + <template #label>{{ $ts.overridedDeviceKind }}</template> + <option :value="null">{{ $ts.auto }}</option> + <option value="smartphone"><i class="fas fa-mobile-alt"/> {{ $ts.smartphone }}</option> + <option value="tablet"><i class="fas fa-tablet-alt"/> {{ $ts.tablet }}</option> + <option value="desktop"><i class="fas fa-desktop"/> {{ $ts.desktop }}</option> + </FormRadios> + <FormSwitch v-model="showFixedPostForm" class="_formBlock">{{ $ts.showFixedPostForm }}</FormSwitch> <FormSection> @@ -127,6 +135,7 @@ export default defineComponent({ }, computed: { + overridedDeviceKind: defaultStore.makeGetterSetter('overridedDeviceKind'), serverDisconnectedBehavior: defaultStore.makeGetterSetter('serverDisconnectedBehavior'), reduceAnimation: defaultStore.makeGetterSetter('animation', v => !v, v => !v), useBlurEffectForModal: defaultStore.makeGetterSetter('useBlurEffectForModal'), @@ -193,6 +202,10 @@ export default defineComponent({ instanceTicker() { this.reloadAsk(); }, + + overridedDeviceKind() { + this.reloadAsk(); + }, }, methods: { diff --git a/packages/client/src/pages/settings/privacy.vue b/packages/client/src/pages/settings/privacy.vue index cfae7e9ca8c1468285c5390cefe7e610ad8531b0..a84d2f8786d8480807eb97a8f6418023e3d36995 100644 --- a/packages/client/src/pages/settings/privacy.vue +++ b/packages/client/src/pages/settings/privacy.vue @@ -8,7 +8,7 @@ <template #caption>{{ $ts.makeReactionsPublicDescription }}</template> </FormSwitch> - <FormSelect v-model="ffVisibility" class="_formBlock"> + <FormSelect v-model="ffVisibility" class="_formBlock" @update:modelValue="save()"> <template #label>{{ $ts.ffVisibility }}</template> <option value="public">{{ $ts._ffVisibility.public }}</option> <option value="followers">{{ $ts._ffVisibility.followers }}</option> diff --git a/packages/client/src/pages/settings/profile.vue b/packages/client/src/pages/settings/profile.vue index 66b654d87f6ecf37139371433330acab626c87bd..9b30d1c8e0ae510742585aa6ab54a4218566694d 100644 --- a/packages/client/src/pages/settings/profile.vue +++ b/packages/client/src/pages/settings/profile.vue @@ -38,7 +38,7 @@ </FormSlot> <FormSwitch v-model="profile.isCat" class="_formBlock">{{ i18n.ts.flagAsCat }}<template #caption>{{ i18n.ts.flagAsCatDescription }}</template></FormSwitch> - + <FormSwitch v-model="profile.showTimelineReplies" class="_formBlock">{{ i18n.ts.flagShowTimelineReplies }}<template #caption>{{ i18n.ts.flagShowTimelineRepliesDescription }}</template></FormSwitch> <FormSwitch v-model="profile.isBot" class="_formBlock">{{ i18n.ts.flagAsBot }}<template #caption>{{ i18n.ts.flagAsBotDescription }}</template></FormSwitch> <FormSwitch v-model="profile.alwaysMarkNsfw" class="_formBlock">{{ i18n.ts.alwaysMarkSensitive }}</FormSwitch> @@ -68,6 +68,7 @@ const profile = reactive({ lang: $i.lang, isBot: $i.isBot, isCat: $i.isCat, + showTimelineReplies: $i.showTimelineReplies, alwaysMarkNsfw: $i.alwaysMarkNsfw, }); @@ -97,6 +98,7 @@ function save() { lang: profile.lang || null, isBot: !!profile.isBot, isCat: !!profile.isCat, + showTimelineReplies: !!profile.showTimelineReplies, alwaysMarkNsfw: !!profile.alwaysMarkNsfw, }); } diff --git a/packages/client/src/pages/timeline.vue b/packages/client/src/pages/timeline.vue index b2266d22c3ef4aab763da2715491779ba268210b..79f00c4b44899a5ab4832b8c3bcc0488de6c2ab9 100644 --- a/packages/client/src/pages/timeline.vue +++ b/packages/client/src/pages/timeline.vue @@ -46,8 +46,10 @@ const keymap = { const tlComponent = $ref<InstanceType<typeof XTimeline>>(); const rootEl = $ref<HTMLElement>(); -let src = $ref<'home' | 'local' | 'social' | 'global'>(defaultStore.state.tl.src); let queue = $ref(0); +const src = $computed(() => defaultStore.reactiveState.tl.value.src); + +watch ($$(src), () => queue = 0); function queueUpdated(q: number): void { queue = q; @@ -60,7 +62,7 @@ function top(): void { async function chooseList(ev: MouseEvent): Promise<void> { const lists = await os.api('users/lists/list'); const items = lists.map(list => ({ - type: 'link', + type: 'link' as const, text: list.name, to: `/timeline/list/${list.id}`, })); @@ -70,7 +72,7 @@ async function chooseList(ev: MouseEvent): Promise<void> { async function chooseAntenna(ev: MouseEvent): Promise<void> { const antennas = await os.api('antennas/list'); const items = antennas.map(antenna => ({ - type: 'link', + type: 'link' as const, text: antenna.name, indicate: antenna.hasUnreadNote, to: `/timeline/antenna/${antenna.id}`, @@ -81,7 +83,7 @@ async function chooseAntenna(ev: MouseEvent): Promise<void> { async function chooseChannel(ev: MouseEvent): Promise<void> { const channels = await os.api('channels/followed'); const items = channels.map(channel => ({ - type: 'link', + type: 'link' as const, text: channel.name, indicate: channel.hasUnreadNote, to: `/channels/${channel.id}`, @@ -89,9 +91,10 @@ async function chooseChannel(ev: MouseEvent): Promise<void> { os.popupMenu(items, ev.currentTarget ?? ev.target); } -function saveSrc(): void { +function saveSrc(newSrc: 'home' | 'local' | 'social' | 'global'): void { defaultStore.set('tl', { - src: src, + ...defaultStore.state.tl, + src: newSrc, }); } @@ -135,25 +138,25 @@ defineExpose({ title: i18n.ts._timelines.home, icon: 'fas fa-home', iconOnly: true, - onClick: () => { src = 'home'; saveSrc(); }, + onClick: () => { saveSrc('home'); }, }, ...(isLocalTimelineAvailable ? [{ active: src === 'local', title: i18n.ts._timelines.local, icon: 'fas fa-comments', iconOnly: true, - onClick: () => { src = 'local'; saveSrc(); }, + onClick: () => { saveSrc('local'); }, }, { active: src === 'social', title: i18n.ts._timelines.social, icon: 'fas fa-share-alt', iconOnly: true, - onClick: () => { src = 'social'; saveSrc(); }, + onClick: () => { saveSrc('social'); }, }] : []), ...(isGlobalTimelineAvailable ? [{ active: src === 'global', title: i18n.ts._timelines.global, icon: 'fas fa-globe', iconOnly: true, - onClick: () => { src = 'global'; saveSrc(); }, + onClick: () => { saveSrc('global'); }, }] : [])], })), }); diff --git a/packages/client/src/pages/user/index.activity.vue b/packages/client/src/pages/user/index.activity.vue index 43a4f476f1942ead8053ccedd16a30c95e07d3c7..ebb251d4ccee5b6bba17987be66d65423cbd4dad 100644 --- a/packages/client/src/pages/user/index.activity.vue +++ b/packages/client/src/pages/user/index.activity.vue @@ -3,7 +3,7 @@ <template #header><i class="fas fa-chart-bar" style="margin-right: 0.5em;"></i>{{ $ts.activity }}</template> <div style="padding: 8px;"> - <MkChart src="per-user-notes" :args="{ user, withoutAll: true }" span="day" :limit="limit" :stacked="true" :detailed="false" :aspect-ratio="6"/> + <MkChart src="per-user-notes" :args="{ user, withoutAll: true }" span="day" :limit="limit" :bar="true" :stacked="true" :detailed="false" :aspect-ratio="5"/> </div> </MkContainer> </template> diff --git a/packages/client/src/scripts/device-kind.ts b/packages/client/src/scripts/device-kind.ts new file mode 100644 index 0000000000000000000000000000000000000000..544cac0604d3e370e703e93d509624f60a3cb8e3 --- /dev/null +++ b/packages/client/src/scripts/device-kind.ts @@ -0,0 +1,10 @@ +import { defaultStore } from '@/store'; + +const ua = navigator.userAgent.toLowerCase(); +const isTablet = /ipad/.test(ua) || (/mobile|iphone|android/.test(ua) && window.innerWidth > 700); +const isSmartphone = !isTablet && /mobile|iphone|android/.test(ua); + +export const deviceKind = defaultStore.state.overridedDeviceKind ? defaultStore.state.overridedDeviceKind + : isSmartphone ? 'smartphone' + : isTablet ? 'tablet' + : 'desktop'; diff --git a/packages/client/src/scripts/is-mobile.ts b/packages/client/src/scripts/is-mobile.ts deleted file mode 100644 index 60cb59f91e7513859daf84c2784e00586b78e2b2..0000000000000000000000000000000000000000 --- a/packages/client/src/scripts/is-mobile.ts +++ /dev/null @@ -1,2 +0,0 @@ -const ua = navigator.userAgent.toLowerCase(); -export const isMobile = /mobile|iphone|ipad|android/.test(ua); diff --git a/packages/client/src/store.ts b/packages/client/src/store.ts index b80fc8bbe38d764747aa272bd0546ad46cecca76..0e71060cdaa6e96f850077ad753b8cebbe09cefe 100644 --- a/packages/client/src/store.ts +++ b/packages/client/src/store.ts @@ -106,6 +106,10 @@ export const defaultStore = markRaw(new Storage('base', { } }, + overridedDeviceKind: { + where: 'device', + default: null as null | 'smartphone' | 'tablet' | 'desktop', + }, serverDisconnectedBehavior: { where: 'device', default: 'quiet' as 'quiet' | 'reload' | 'dialog' diff --git a/packages/client/yarn.lock b/packages/client/yarn.lock index 76be45f145874ba4e227d5381a7805095297b03d..e06e376bc5985eeaf167b769ca858d432cef1832 100644 --- a/packages/client/yarn.lock +++ b/packages/client/yarn.lock @@ -130,6 +130,11 @@ minimatch "^3.0.4" strip-json-comments "^3.1.1" +"@fortawesome/fontawesome-free@6.0.0-beta3": + version "6.0.0-beta3" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-6.0.0-beta3.tgz#120e4a158a0de983924ce151bc35f27de46398b7" + integrity sha512-4SqOuhC8tSLeQvbW1nDmq6T7+8vdSgHy/w7PRwCFzMQCbKuYFIir/3UuWsV1QblX1lt7SGlSgwbaCv9XhRt8HA== + "@hapi/hoek@^9.0.0": version "9.2.0" resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.2.0.tgz#f3933a44e365864f4dad5db94158106d511e8131" @@ -266,11 +271,6 @@ resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== -"@types/dateformat@3.0.1": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@types/dateformat/-/dateformat-3.0.1.tgz#98d747a2e5e9a56070c6bf14e27bff56204e34cc" - integrity sha512-KlPPdikagvL6ELjWsljbyDIPzNCeliYkqRpI+zea99vBBbCIA5JNshZAwQKTON139c87y9qvTFVgkFd14rtS4g== - "@types/escape-regexp@0.0.1": version "0.0.1" resolved "https://registry.yarnpkg.com/@types/escape-regexp/-/escape-regexp-0.0.1.tgz#f1a977ccdf2ef059e9862bd3af5e92cbbe723e0e" @@ -460,13 +460,6 @@ resolved "https://registry.yarnpkg.com/@types/random-seed/-/random-seed-0.3.3.tgz#7741f7b0a4513198a9396ce4ad25832f799a6727" integrity sha512-kHsCbIRHNXJo6EN5W8EA5b4i1hdT6jaZke5crBPLUcLqaLdZ0QBq8QVMbafHzhjFF83Cl9qlee2dChD18d/kPg== -"@types/request-stats@3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/request-stats/-/request-stats-3.0.0.tgz#d3909a9f778b8ae0b42fb8c1ed20cb936ed95f99" - integrity sha512-POsDF7nETH8up49iBNvbZuO0pEk9F+TG0rXCkvjxCClcOS99xfF+mKmJteYlwKYpuRKkixzysKlL8rwN1hU2lw== - dependencies: - "@types/node" "*" - "@types/seedrandom@2.4.28": version "2.4.28" resolved "https://registry.yarnpkg.com/@types/seedrandom/-/seedrandom-2.4.28.tgz#9ce8fa048c1e8c85cb71d7fe4d704e000226036f" @@ -1591,6 +1584,11 @@ chartjs-adapter-date-fns@2.0.0: resolved "https://registry.yarnpkg.com/chartjs-adapter-date-fns/-/chartjs-adapter-date-fns-2.0.0.tgz#5e53b2f660b993698f936f509c86dddf9ed44c6b" integrity sha512-rmZINGLe+9IiiEB0kb57vH3UugAtYw33anRiw5kS2Tu87agpetDDoouquycWc9pRsKtQo5j+vLsYHyr8etAvFw== +chartjs-plugin-gradient@0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/chartjs-plugin-gradient/-/chartjs-plugin-gradient-0.2.1.tgz#9d6d4f1a04a8d2ffca769adb068df4d0678b8f8f" + integrity sha512-hcNQ+B0LuiK9QXhbEc0tUtW3s0a8lOBUJViOCw2xHbnNCIp3Pul/tQHR1aIjMo3HiHu4nOb7NKqFd4NTUEsi4Q== + chartjs-plugin-zoom@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/chartjs-plugin-zoom/-/chartjs-plugin-zoom-1.2.0.tgz#dad0861b2d171bca1f6d11b3e3e917bc12b950ff" @@ -3224,13 +3222,6 @@ homedir-polyfill@^1.0.1: dependencies: parse-passwd "^1.0.0" -http-headers@^3.0.1: - version "3.0.2" - resolved "https://registry.yarnpkg.com/http-headers/-/http-headers-3.0.2.tgz#5147771292f0b39d6778d930a3a59a76fc7ef44d" - integrity sha512-87E1I+2Wg4dxxz4rcxElo3dxO/w1ZtgL1yA0Sb6vH3qU16vRKq1NjWQv9SCY3ly2OQROcoxHZOUpmelS+k6wOw== - dependencies: - next-line "^1.1.0" - http-signature@~1.3.6: version "1.3.6" resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.3.6.tgz#cb6fbfdf86d1c974f343be94e87f7fc128662cf9" @@ -4248,11 +4239,6 @@ netmask@^2.0.2: resolved "https://registry.yarnpkg.com/netmask/-/netmask-2.0.2.tgz#8b01a07644065d536383835823bc52004ebac5e7" integrity sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg== -next-line@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/next-line/-/next-line-1.1.0.tgz#fcae57853052b6a9bae8208e40dd7d3c2d304603" - integrity sha1-/K5XhTBStqm66CCOQN19PC0wRgM= - next-tick@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" @@ -5177,14 +5163,6 @@ request-progress@^3.0.0: dependencies: throttleit "^1.0.0" -request-stats@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/request-stats/-/request-stats-3.0.0.tgz#769155dc8974d78d4a1cb87bbf14eaab985afe25" - integrity sha1-dpFV3Il0141KHLh7vxTqq5ha/iU= - dependencies: - http-headers "^3.0.1" - once "^1.4.0" - require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" diff --git a/scripts/dev.js b/scripts/dev.js index 7096f3bf6514363b1d72724225cf69a7f3c56cf6..b7dd870c4197b5b2cb23037988fe8a7b5c455ff8 100644 --- a/scripts/dev.js +++ b/scripts/dev.js @@ -1,6 +1,12 @@ const execa = require('execa'); (async () => { + await execa('npm', ['run', 'clean'], { + cwd: __dirname + '/../', + stdout: process.stdout, + stderr: process.stderr, + }); + execa('npx', ['gulp', 'watch'], { cwd: __dirname + '/../', stdout: process.stdout, diff --git a/yarn.lock b/yarn.lock index 82d2272f6b215f73d8733e574d04ff5f65652ef3..739f06e831318acff7260463ac29b9ab0ebbee1f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1117,10 +1117,10 @@ csso@~2.3.1: clap "^1.0.9" source-map "^0.5.3" -cypress@9.3.1: - version "9.3.1" - resolved "https://registry.yarnpkg.com/cypress/-/cypress-9.3.1.tgz#8116f52d49d6daf90a91e88f3eafd940234d2958" - integrity sha512-BODdPesxX6bkVUnH8BVsV8I/jn57zQtO1FEOUTiuG2us3kslW7g0tcuwiny7CKCmJUZz8S/D587ppC+s58a+5Q== +cypress@9.4.1: + version "9.4.1" + resolved "https://registry.yarnpkg.com/cypress/-/cypress-9.4.1.tgz#1a4ba706435829c24b7edf350c2b059e05da9084" + integrity sha512-+JgMG9uT+QFx97JU9kOHE3jO3+0UdkQ9H1oCBiC7A74qme7Jkdy2sYDBCPjjGczutnWnGUTMRlwiNMP/Uq6LrQ== dependencies: "@cypress/request" "^2.88.10" "@cypress/xvfb" "^1.2.4" @@ -1159,10 +1159,10 @@ cypress@9.3.1: pretty-bytes "^5.6.0" proxy-from-env "1.0.0" request-progress "^3.0.0" + semver "^7.3.2" supports-color "^8.1.1" tmp "~0.2.1" untildify "^4.0.0" - url "^0.11.0" yauzl "^2.10.0" d@1, d@^1.0.1: @@ -3422,11 +3422,6 @@ pumpify@^1.3.5: inherits "^2.0.3" pump "^2.0.0" -punycode@1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" - integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= - punycode@^2.1.0, punycode@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" @@ -3450,11 +3445,6 @@ query-string@^4.1.0: object-assign "^4.1.0" strict-uri-encode "^1.0.0" -querystring@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" - integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= - queue-microtask@^1.2.2: version "1.2.3" resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" @@ -3736,7 +3726,7 @@ semver-greatest-satisfied-range@^1.1.0: resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== -semver@^7.3.5: +semver@^7.3.2, semver@^7.3.5: version "7.3.5" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== @@ -4353,14 +4343,6 @@ urix@^0.1.0: resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= -url@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" - integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= - dependencies: - punycode "1.3.2" - querystring "0.2.0" - use@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f"