diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index 3e5b59cb0..000000000 --- a/.eslintrc +++ /dev/null @@ -1,13 +0,0 @@ -{ - "parserOptions": { - "parser": "@typescript-eslint/parser" - }, - "extends": [ - "eslint:recommended" - ], - "rules": { - "no-console": 0, - "no-unused-vars": 0, - "no-empty": 0 - } -} diff --git a/.github/misskey/test.yml b/.github/misskey/test.yml index ae18a841b..cd33f8a93 100644 --- a/.github/misskey/test.yml +++ b/.github/misskey/test.yml @@ -1,12 +1,15 @@ url: 'http://misskey.local' -port: 8080 + +# ローカルでテストするときにポートを被らないようにするためデフォルトのものとは変える(以下同じ) +port: 61812 + db: host: localhost - port: 5432 + port: 54312 db: test-misskey user: postgres pass: '' redis: host: localhost - port: 6379 + port: 56312 id: aid diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 045d20980..e220d714d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -41,7 +41,7 @@ jobs: - name: Check yarn.lock run: git diff --exit-code yarn.lock - name: Copy Configure - run: cp test/test.yml .config + run: cp .github/misskey/test.yml .config - name: Build run: yarn build - name: Test @@ -80,7 +80,7 @@ jobs: - name: Check yarn.lock run: git diff --exit-code yarn.lock - name: Copy Configure - run: cp test/test.yml .config + run: cp .github/misskey/test.yml .config - name: Build run: yarn build - name: Test diff --git a/.gitignore b/.gitignore index f8baa4384..9928d93aa 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,7 @@ /.idea # Node.js -/node_modules +node_modules report.*.json # Cypress @@ -20,7 +20,7 @@ cypress/videos # misskey /build -/built +built /data /.cache-loader /db diff --git a/.imgbotconfig b/.imgbotconfig deleted file mode 100644 index 6a1dfe1ed..000000000 --- a/.imgbotconfig +++ /dev/null @@ -1,5 +0,0 @@ -{ - "ignoredFiles": [ - "test/resources/*" - ] -} diff --git a/CHANGELOG.md b/CHANGELOG.md index 6847049bb..032d76e45 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,27 @@ --> +## 12.96.0 (2021/11/13) + +### Improvements +- フォロー/フォロワーを非公開にできるように +- インスタンスプロフィールレンダリング ready +- 通知のリアクションアイコンをホバーで拡大できるように +- RenoteボタンをホバーでRenoteしたユーザー一覧を表示するように +- 返信の際にメンションを含めるように +- 通報があったときに管理者へEメールで通知されるように +- メールアドレスのバリデーションを強化 + +### Bugfixes +- アカウント削除処理があると高負荷になる問題を修正 +- クライアント: 長いメニューが画面からはみ出す問題を修正 +- クライアント: コントロールパネルのジョブキューに個々のジョブが表示されないのを修正 +- クライアント: fix missing i18n string +- fix html conversion issue with code blocks + +### Changes +- ノートにモバイルからの投稿か否かの情報を含めないように + ## 12.95.0 (2021/10/31) ### Improvements diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 76267ab30..11b732953 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -49,10 +49,6 @@ If your language is not listed in Crowdin, please open an issue. ![Crowdin](https://d322cqt584bo4o.cloudfront.net/misskey/localized.svg) -## Documentation -* Documents for instance admins are located in [`/docs`](/docs). -* Documents for end users are located in [`/src/docs`](/src/docs). - ## Testing - Test codes are located in [`/test`](/test). @@ -180,7 +176,7 @@ MongoDBは`null`で返してきてたので、その感覚で`if (x === null)` ### Migration作成方法 ``` -npx ts-node ./node_modules/typeorm/cli.js migration:generate -n 変更の名前 +npx ts-node ./node_modules/typeorm/cli.js migration:generate -n 変更の名前 -o ``` 作成されたスクリプトは不必要な変更を含むため除去してください。 diff --git a/Dockerfile b/Dockerfile index 58e3eda11..6ba8d296d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -26,6 +26,10 @@ ENTRYPOINT ["/sbin/tini", "--"] COPY --from=builder /misskey/node_modules ./node_modules COPY --from=builder /misskey/built ./built +COPY --from=builder /misskey/packages/backend/node_modules ./packages/backend/node_modules +COPY --from=builder /misskey/packages/backend/built ./packages/backend/built +COPY --from=builder /misskey/packages/client/node_modules ./packages/client/node_modules +COPY --from=builder /misskey/packages/client/built ./packages/client/built COPY . ./ CMD ["npm", "run", "migrateandstart"] diff --git a/crowdin.yml b/crowdin.yml index 2d2cd5a49..774ddc7a6 100644 --- a/crowdin.yml +++ b/crowdin.yml @@ -2,6 +2,3 @@ files: - source: /locales/ja-JP.yml translation: /locales/%locale%.yml update_option: update_as_unapproved - - source: /src/docs/ja-JP/**/*.md - translation: /src/docs/%locale%/**/%original_file_name% - update_option: update_as_unapproved diff --git a/gulpfile.js b/gulpfile.js new file mode 100644 index 000000000..a86185324 --- /dev/null +++ b/gulpfile.js @@ -0,0 +1,62 @@ +/** + * Gulp tasks + */ + +const fs = require('fs'); +const gulp = require('gulp'); +const replace = require('gulp-replace'); +const terser = require('gulp-terser'); +const cssnano = require('gulp-cssnano'); + +const locales = require('./locales'); +const meta = require('./package.json'); + +gulp.task('copy:backend:views', () => + gulp.src('./packages/backend/src/server/web/views/**/*').pipe(gulp.dest('./packages/backend/built/server/web/views')) +); + +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:locales', cb => { + fs.mkdirSync('./built/_client_dist_/locales', { recursive: true }); + + const v = { '_version_': meta.version }; + + for (const [lang, locale] of Object.entries(locales)) { + fs.writeFileSync(`./built/_client_dist_/locales/${lang}.${meta.version}.json`, JSON.stringify({ ...locale, ...v }), 'utf-8'); + } + + cb(); +}); + +gulp.task('build:backend:script', () => { + return gulp.src(['./packages/backend/src/server/web/boot.js', './packages/backend/src/server/web/bios.js', './packages/backend/src/server/web/cli.js']) + .pipe(replace('VERSION', JSON.stringify(meta.version))) + .pipe(replace('LANGS', JSON.stringify(Object.keys(locales)))) + .pipe(terser({ + toplevel: true + })) + .pipe(gulp.dest('./packages/backend/built/server/web/')); +}); + +gulp.task('build:backend:style', () => { + return gulp.src(['./packages/backend/src/server/web/style.css', './packages/backend/src/server/web/bios.css', './packages/backend/src/server/web/cli.css']) + .pipe(cssnano({ + zindex: false + })) + .pipe(gulp.dest('./packages/backend/built/server/web/')); +}); + +gulp.task('build', gulp.parallel( + 'copy:client:locales', 'copy:backend:views', 'build:backend:script', 'build:backend:style', 'copy:client:fonts' +)); + +gulp.task('default', gulp.task('build')); + +gulp.task('watch', () => { + gulp.watch([ + './packages/**/*', + ], { ignoreInitial: false }, gulp.task('build')); +}); diff --git a/gulpfile.ts b/gulpfile.ts deleted file mode 100644 index 2cdcbdb6f..000000000 --- a/gulpfile.ts +++ /dev/null @@ -1,80 +0,0 @@ -/** - * Gulp tasks - */ - -import * as fs from 'fs'; -import * as gulp from 'gulp'; -import rimraf from 'rimraf'; -const replace = require('gulp-replace'); -const terser = require('gulp-terser'); -const cssnano = require('gulp-cssnano'); - -const locales: { [x: string]: any } = require('./locales'); -const meta = require('./package.json'); - -gulp.task('build:copy:views', () => - gulp.src('./src/server/web/views/**/*').pipe(gulp.dest('./built/server/web/views')) -); - -gulp.task('build:copy:fonts', () => - gulp.src('./node_modules/three/examples/fonts/**/*').pipe(gulp.dest('./built/assets/fonts/')) -); - -gulp.task('build:copy:locales', cb => { - fs.mkdirSync('./built/assets/locales', { recursive: true }); - - const v = { '_version_': meta.version }; - - for (const [lang, locale] of Object.entries(locales)) { - fs.writeFileSync(`./built/assets/locales/${lang}.${meta.version}.json`, JSON.stringify({ ...locale, ...v }), 'utf-8'); - } - - cb(); -}); - -gulp.task('build:client:script', () => { - return gulp.src(['./src/server/web/boot.js', './src/server/web/bios.js', './src/server/web/cli.js']) - .pipe(replace('VERSION', JSON.stringify(meta.version))) - .pipe(replace('LANGS', JSON.stringify(Object.keys(locales)))) - .pipe(terser({ - toplevel: true - })) - .pipe(gulp.dest('./built/server/web/')); -}); - -gulp.task('build:client:style', () => { - return gulp.src(['./src/server/web/style.css', './src/server/web/bios.css', './src/server/web/cli.css']) - .pipe(cssnano({ - zindex: false - })) - .pipe(gulp.dest('./built/server/web/')); -}); - -gulp.task('build:copy', gulp.parallel('build:copy:locales', 'build:copy:views', 'build:client:script', 'build:client:style', 'build:copy:fonts', () => - gulp.src([ - './src/emojilist.json', - './src/**/assets/**/*', - '!./src/client/assets/**/*' - ]).pipe(gulp.dest('./built/')) -)); - -gulp.task('clean', cb => - rimraf('./built', cb) -); - -gulp.task('cleanall', gulp.parallel('clean', cb => - rimraf('./node_modules', cb) -)); - -gulp.task('build', gulp.parallel( - 'build:copy', -)); - -gulp.task('default', gulp.task('build')); - -gulp.task('watch', () => { - gulp.watch([ - './src/**/*', - '!./src/client/**/*' - ], { ignoreInitial: false }, gulp.task('build')); -}); diff --git a/index.js b/index.js deleted file mode 100644 index aa103e667..000000000 --- a/index.js +++ /dev/null @@ -1,17 +0,0 @@ -/* -import * as fs from 'fs'; - -if (fs.existsSync('./built')) { - import('./built/index.js').then(built => built()); -} else { - console.log('Built code is not found. Probably an error occurred during a build or you just forgot to build.'); -} -*/ - -const fs = require('fs'); - -if (fs.existsSync('./built')) { - require('./built').default(); -} else { - console.log('Built code is not found. Probably an error occurred during a build or you just forgot to build.'); -} diff --git a/locales/fr-FR.yml b/locales/fr-FR.yml index c3964fff6..5d67b5269 100644 --- a/locales/fr-FR.yml +++ b/locales/fr-FR.yml @@ -797,6 +797,15 @@ unread: "Non lu" filter: "Filtre" controlPanel: "Panneau de contrôle" manageAccounts: "Gérer les comptes" +classic: "Classique" +_emailUnavailable: + format: "Le format de cette adresse de courriel est invalide" + mx: "Ce serveur de courriels est invalide" + smtp: "Ce serveur de courriels ne répond pas" +_ffVisibility: + public: "Public" + followers: "Visible uniquement pour les abonné·e·s" + private: "Privé" _signup: almostThere: "Bientôt fini" emailAddressInfo: "Insérez votre adresse e-mail." @@ -808,13 +817,6 @@ _accountDelete: requestAccountDelete: "Demander la suppression de votre compte" started: "La procédure de suppression a commencé." inProgress: "Suppression en cours" -_docs: - continueReading: "Lire plus" - features: "Fonctionnalités" - generalTopics: "Sujets généraux" - advancedTopics: "Sujets avancés" - admin: "Gestion" - translateWarn: "Ceci est une traduction dont le contenu peut différer du texte original." _ad: back: "Retour" reduceFrequencyOfThisAd: "Voir cette publicité moins souvent" diff --git a/locales/id-ID.yml b/locales/id-ID.yml index 06df4ce8e..f4997e3a6 100644 --- a/locales/id-ID.yml +++ b/locales/id-ID.yml @@ -81,6 +81,8 @@ somethingHappened: "Terjadi kesalahan" retry: "Coba lagi" pageLoadError: "Gagal memuat halaman." pageLoadErrorDescription: "Umumnya disebabkan jaringan atau tembolok perambah. Cobalah bersihkan tembolok peramban lalu tunggu sesaat sebelum mencoba kembali." +serverIsDead: "Tidak ada respon dari server. Mohon tunggu dan coba beberapa saat lagi." +youShouldUpgradeClient: "Untuk melihat halaman ini, mohon muat ulang untuk memutakhirkan klienmu." enterListName: "Masukkan nama daftar" privacy: "Privasi" makeFollowManuallyApprove: "Permintaan mengikuti membutuhkan persetujuan" @@ -529,6 +531,8 @@ removeAllFollowing: "Tahan semua mengikuti" removeAllFollowingDescription: "Batal mengikuti semua akun dari {host}. Mohon jalankan ini ketika instansi sudah tidak ada lagi." userSuspended: "Pengguna ini telah dibekukan." userSilenced: "Pengguna ini telah dibungkam." +yourAccountSuspendedTitle: "Akun ini dibekukan" +yourAccountSuspendedDescription: "Akun ini dibekukan karena melanggar ketentuan penggunaan layanan server atau semacamnya. Hubungi admin apabila ingin tahu alasan lebih lanjut. Mohon untuk tidak membuat akun baru." menu: "Menu" divider: "Pembagi" addItem: "Tambahkan item" @@ -616,6 +620,8 @@ 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." +reporteeOrigin: "Yang dilaporkan" +reporterOrigin: "Pelapor" send: "Kirim" abuseMarkAsResolved: "Tandai laporan sebagai selesai" openInNewTab: "Buka di tab baru" @@ -762,6 +768,7 @@ middle: "Sedang" low: "Rendah" emailNotConfiguredWarning: "Alamat surel tidak disetel." ratio: "Rasio" +previewNoteText: "Tampilkan pratinjau" customCss: "Custom CSS" customCssWarn: "Pengaturan ini seharusnya digunakan jika kamu tahu cara kerjanya. Memasukkan nilai yang tidak tepat dapat menyebabkan klien tidak berfungsi semestinya." global: "Global" @@ -779,8 +786,40 @@ translate: "Terjemahkan" translatedFrom: "Terjemahkan dari {x}" accountDeletionInProgress: "Penghapusan akun sedang dalam proses" usernameInfo: "Nama yang mengidentifikasikan akun kamu dari yang lain pada server ini. Kamu dapat menggunakan alfabet (a~z, A~Z), digit (0~9) atau garis bawah (_). Username tidak dapat diubah setelahnya." +aiChanMode: "Mode Ai" keepCw: "Biarkan Peringatan Konten" +pubSub: "Akun Pub/Sub" +lastCommunication: "Komunikasi terakhir" +resolved: "Selesai" +unresolved: "Belum selesai" +itsOn: "Aktif" +itsOff: "Nonaktif" +emailRequiredForSignup: "Membutuhkan alamat surel untuk mendaftar" +unread: "Belum dibaca" +filter: "Saring" controlPanel: "Panel kontrol" +manageAccounts: "Kelola Akun" +makeReactionsPublic: "Tampilkan riwayat reaksi ke publik" +makeReactionsPublicDescription: "Pengaturan ini akan membuat daftar dari semua reaksi masa lalu kamu ditampilkan secara publik." +classic: "Klasik" +muteThread: "Bisukan thread" +unmuteThread: "Suarakan thread" +ffVisibility: "Visibilitas Mengikuti/Pengikut" +ffVisibilityDescription: "Mengatur siapa yang dapat melihat pengikutmu dan yang kamu ikuti." +_emailUnavailable: + used: "Alamat surel ini telah digunakan" + format: "Format tidak valid." + disposable: "Alamat surel temporer tidak dapat digunakan" + mx: "Server alamat surel ini tidak valid" + smtp: "Server alamat surel ini tidak merespon" +_ffVisibility: + public: "Terbitkan" + followers: "Tampil untuk pengikut saja" + private: "Tersembunyi" +_signup: + almostThere: "Hampir selesai" + emailAddressInfo: "Mohon masukkan alamat surel kamu." + emailSent: "Konfirmasi surel telah dikirimkan ke alamat surel kamu ({email}). Mohon klik tautan yang tercantum di dalamnya untuk menyelesaikan pembuatan akun." _accountDelete: accountDelete: "Hapus akun" mayTakeTime: "Karena penghapusan akun merupakan proses yang berat dan intensif, kemungkinan dapat membutuhkan waktu untuk menyelesaikan tergantung daripada berapa banyak konten yang kamu buat dan berapa banyak berkas yang telah kamu unggah." @@ -788,13 +827,6 @@ _accountDelete: requestAccountDelete: "Minta penghapusan akun" started: "Penghapusan telah dimulai" inProgress: "Penghapusan sedang dalam proses" -_docs: - continueReading: "Baca lebih lanjut" - features: "Fitur" - generalTopics: "Topik umum" - advancedTopics: "Topik tingkat lanjut" - admin: "Manajemen" - translateWarn: "Ini merupakan dokumen terjemahan. Konten di dalamnya kemungkinan dapat berbeda dari yang aslinya." _ad: back: "Kembali" reduceFrequencyOfThisAd: "Tampilkan iklan ini lebih sedikit" @@ -895,6 +927,8 @@ _mfm: fontDescription: "Setel font yang ditampilkan untuk konten." rainbow: "Pelangi" rainbowDescription: "Membuat konten muncul dalam warna pelangi." + sparkle: "Kelap-kelip" + sparkleDescription: "Memberikan konten efek partikel kelap-kelip." _reversi: reversi: "Reversi" gameSettings: "Pengaturan permainan" @@ -1121,6 +1155,10 @@ _permissions: "write:user-groups": "Sunting atau hapus grup pengguna" "read:channels": "Lihat saluran" "write:channels": "Sunting saluran" + "read:gallery": "Lihat galeri" + "write:gallery": "Sunting galeri" + "read:gallery-likes": "Lihat daftar postingan galeri yang disukai" + "write:gallery-likes": "Sunting daftar postingan galeri yang disukai" _auth: shareAccess: "Apakah kamu ingin mengijinkan \"{name}\" untuk mengakses akun ini?" shareAccessAsk: "Apakah kamu ingin mengijinkan aplikasi ini untuk mengakses akun kamu?" diff --git a/locales/index.js b/locales/index.js index 35f9972ff..a0181cd7a 100644 --- a/locales/index.js +++ b/locales/index.js @@ -19,9 +19,11 @@ const languages = [ 'da-DK', 'de-DE', 'en-US', + 'eo-UY', 'es-ES', 'fr-FR', 'id-ID', + 'it-IT', 'ja-JP', 'ja-KS', 'kab-KAB', diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 1326369f8..ababad4f0 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -620,6 +620,8 @@ reportAbuse: "通報" reportAbuseOf: "{name}を通報する" fillAbuseReportDescription: "通報理由の詳細を記入してください。対象のノートがある場合はそのURLも記入してください。" abuseReported: "内容が送信されました。ご報告ありがとうございました。" +reporteeOrigin: "通報先" +reporterOrigin: "通報元" send: "送信" abuseMarkAsResolved: "対応済みにする" openInNewTab: "新しいタブで開く" @@ -802,6 +804,20 @@ makeReactionsPublicDescription: "あなたがしたリアクション一覧を classic: "クラシック" muteThread: "スレッドをミュート" unmuteThread: "スレッドのミュートを解除" +ffVisibility: "つながりの公開範囲" +ffVisibilityDescription: "自分のフォロー/フォロワー情報の公開範囲を設定できます。" + +_emailUnavailable: + used: "既に使用されています" + format: "形式が正しくありません" + disposable: "恒久的に使用可能なアドレスではありません" + mx: "正しいメールサーバーではありません" + smtp: "メールサーバーが応答しません" + +_ffVisibility: + public: "公開" + followers: "フォロワーだけに公開" + private: "非公開" _signup: almostThere: "ほとんど完了です" @@ -816,14 +832,6 @@ _accountDelete: started: "削除処理が開始されました。" inProgress: "削除が進行中" -_docs: - continueReading: "続きを読む" - features: "機能" - generalTopics: "一般的なトピック" - advancedTopics: "高度なトピック" - admin: "管理" - translateWarn: "このドキュメントは翻訳されたものです。オリジナルとは内容が異なる場合があります。" - _ad: back: "戻る" reduceFrequencyOfThisAd: "この広告の表示頻度を下げる" diff --git a/locales/tr-TR.yml b/locales/tr-TR.yml new file mode 100644 index 000000000..46204d33c --- /dev/null +++ b/locales/tr-TR.yml @@ -0,0 +1,62 @@ +--- +_lang_: "Türkçe" +introMisskey: "Açık kaynaklı bir dağıtılmış mikroblog hizmeti olan Misskey'e hoş geldiniz.\nMisskey, neler olup bittiğini paylaşmak ve herkese sizden bahsetmek için \"notlar\" oluşturmanıza olanak tanıyan, açık kaynaklı, dağıtılmış bir mikroblog hizmetidir.\nHerkesin notlarına kendi tepkilerinizi hızlıca eklemek için \"Tepkiler\" özelliğini de kullanabilirsiniz👍.\nYeni bir dünyayı keşfedin🚀." +monthAndDay: "{month}Ay {day}Gün" +search: "Arama" +notifications: "Bildirim" +username: "Kullanıcı Adı" +password: "Şifre" +forgotPassword: "şifremi unuttum" +ok: "TAMAM" +gotIt: "Anladım" +cancel: "İptal" +enterUsername: "Kullanıcı adınızı giriniz" +noNotes: "Notlar mevcut değil." +noNotifications: "Bildirim bulunmuyor" +settings: "Ayarlar" +basicSettings: "Temel Ayarlar" +otherSettings: "Diğer Ayarlar" +openInWindow: "Bir pencere ile aç" +profile: "Profil" +timeline: "Zaman çizelgesi" +noAccountDescription: "Bu kullanıcı henüz biyografisini yazmadı" +login: "Giriş Yap " +logout: "Çıkış Yap" +signup: "Kayıt Ol" +uploading: "Yükleniyor" +users: "Kullanıcı" +addUser: "Kullanıcı Ekle" +favorite: "Favoriler" +favorites: "Favoriler" +unfavorite: "Favorilerden Kaldır" +favorited: "Favorilerime eklendi." +alreadyFavorited: "Zaten favorilerinizde kayıtlı." +pin: "Sabitlenmiş" +unpin: "Sabitlemeyi kaldır" +copyContent: "İçeriği kopyala" +copyLink: "Bağlantıyı Kopyala" +delete: "Sil" +deleteAndEdit: "Sil ve yeniden düzenle" +deleteAndEditConfirm: "Bu notu silip yeniden düzenlemek istiyor musunuz? Bu nota ilişkin tüm Tepkiler, Yeniden Notlar ve Yanıtlar da silinecektir." +addToList: "Listeye ekle" +sendMessage: "Mesaj Gönder" +copyUsername: "Kullanıcı Adını Kopyala" +searchUser: "Kullanıcıları ara" +pinned: "Sabitlenmiş" +remove: "Sil" +smtpUser: "Kullanıcı Adı" +smtpPass: "Şifre" +user: "Kullanıcı" +_mfm: + search: "Arama" +_sfx: + notification: "Bildirim" +_widgets: + notifications: "Bildirim" + timeline: "Zaman çizelgesi" +_profile: + username: "Kullanıcı Adı" +_deck: + _columns: + notifications: "Bildirim" + tl: "Zaman çizelgesi" diff --git a/migration/1000000000000-Init.ts b/migration/1000000000000-Init.ts deleted file mode 100644 index ce54d8a7e..000000000 --- a/migration/1000000000000-Init.ts +++ /dev/null @@ -1,485 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class Init1000000000000 implements MigrationInterface { - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE TYPE "log_level_enum" AS ENUM('error', 'warning', 'info', 'success', 'debug')`); - await queryRunner.query(`CREATE TABLE "log" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "domain" character varying(64) array NOT NULL DEFAULT '{}'::varchar[], "level" "log_level_enum" NOT NULL, "worker" character varying(8) NOT NULL, "machine" character varying(128) NOT NULL, "message" character varying(1024) NOT NULL, "data" jsonb NOT NULL DEFAULT '{}', CONSTRAINT "PK_350604cbdf991d5930d9e618fbd" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE INDEX "IDX_8e4eb51a35d81b64dda28eed0a" ON "log" ("createdAt") `); - await queryRunner.query(`CREATE INDEX "IDX_8cb40cfc8f3c28261e6f887b03" ON "log" ("domain") `); - await queryRunner.query(`CREATE INDEX "IDX_584b536b49e53ac81beb39a177" ON "log" ("level") `); - await queryRunner.query(`CREATE TABLE "drive_folder" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "name" character varying(128) NOT NULL, "userId" character varying(32), "parentId" character varying(32), CONSTRAINT "PK_7a0c089191f5ebdc214e0af808a" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE INDEX "IDX_02878d441ceae15ce060b73daf" ON "drive_folder" ("createdAt") `); - await queryRunner.query(`CREATE INDEX "IDX_f4fc06e49c0171c85f1c48060d" ON "drive_folder" ("userId") `); - await queryRunner.query(`CREATE INDEX "IDX_00ceffb0cdc238b3233294f08f" ON "drive_folder" ("parentId") `); - await queryRunner.query(`CREATE TABLE "drive_file" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32), "userHost" character varying(128), "md5" character varying(32) NOT NULL, "name" character varying(256) NOT NULL, "type" character varying(128) NOT NULL, "size" integer NOT NULL, "comment" character varying(512), "properties" jsonb NOT NULL DEFAULT '{}', "storedInternal" boolean NOT NULL, "url" character varying(512) NOT NULL, "thumbnailUrl" character varying(512), "webpublicUrl" character varying(512), "accessKey" character varying(256), "thumbnailAccessKey" character varying(256), "webpublicAccessKey" character varying(256), "uri" character varying(512), "src" character varying(512), "folderId" character varying(32), "isSensitive" boolean NOT NULL DEFAULT false, "isLink" boolean NOT NULL DEFAULT false, CONSTRAINT "PK_43ddaaaf18c9e68029b7cbb032e" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE INDEX "IDX_c8dfad3b72196dd1d6b5db168a" ON "drive_file" ("createdAt") `); - await queryRunner.query(`CREATE INDEX "IDX_860fa6f6c7df5bb887249fba22" ON "drive_file" ("userId") `); - await queryRunner.query(`CREATE INDEX "IDX_92779627994ac79277f070c91e" ON "drive_file" ("userHost") `); - await queryRunner.query(`CREATE INDEX "IDX_37bb9a1b4585f8a3beb24c62d6" ON "drive_file" ("md5") `); - await queryRunner.query(`CREATE INDEX "IDX_a40b8df8c989d7db937ea27cf6" ON "drive_file" ("type") `); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_d85a184c2540d2deba33daf642" ON "drive_file" ("accessKey") `); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_e74022ce9a074b3866f70e0d27" ON "drive_file" ("thumbnailAccessKey") `); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_c55b2b7c284d9fef98026fc88e" ON "drive_file" ("webpublicAccessKey") `); - await queryRunner.query(`CREATE INDEX "IDX_e5848eac4940934e23dbc17581" ON "drive_file" ("uri") `); - await queryRunner.query(`CREATE INDEX "IDX_bb90d1956dafc4068c28aa7560" ON "drive_file" ("folderId") `); - await queryRunner.query(`CREATE TABLE "user" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "updatedAt" TIMESTAMP WITH TIME ZONE, "lastFetchedAt" TIMESTAMP WITH TIME ZONE, "username" character varying(128) NOT NULL, "usernameLower" character varying(128) NOT NULL, "name" character varying(128), "followersCount" integer NOT NULL DEFAULT 0, "followingCount" integer NOT NULL DEFAULT 0, "notesCount" integer NOT NULL DEFAULT 0, "avatarId" character varying(32), "bannerId" character varying(32), "tags" character varying(128) array NOT NULL DEFAULT '{}'::varchar[], "avatarUrl" character varying(512), "bannerUrl" character varying(512), "avatarColor" character varying(32), "bannerColor" character varying(32), "isSuspended" boolean NOT NULL DEFAULT false, "isSilenced" boolean NOT NULL DEFAULT false, "isLocked" boolean NOT NULL DEFAULT false, "isBot" boolean NOT NULL DEFAULT false, "isCat" boolean NOT NULL DEFAULT false, "isAdmin" boolean NOT NULL DEFAULT false, "isModerator" boolean NOT NULL DEFAULT false, "isVerified" boolean NOT NULL DEFAULT false, "emojis" character varying(128) array NOT NULL DEFAULT '{}'::varchar[], "host" character varying(128), "inbox" character varying(512), "sharedInbox" character varying(512), "featured" character varying(512), "uri" character varying(512), "token" character(16), CONSTRAINT "UQ_a854e557b1b14814750c7c7b0c9" UNIQUE ("token"), CONSTRAINT "REL_58f5c71eaab331645112cf8cfa" UNIQUE ("avatarId"), CONSTRAINT "REL_afc64b53f8db3707ceb34eb28e" UNIQUE ("bannerId"), CONSTRAINT "PK_cace4a159ff9f2512dd42373760" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE INDEX "IDX_e11e649824a45d8ed01d597fd9" ON "user" ("createdAt") `); - await queryRunner.query(`CREATE INDEX "IDX_80ca6e6ef65fb9ef34ea8c90f4" ON "user" ("updatedAt") `); - await queryRunner.query(`CREATE INDEX "IDX_a27b942a0d6dcff90e3ee9b5e8" ON "user" ("usernameLower") `); - await queryRunner.query(`CREATE INDEX "IDX_fa99d777623947a5b05f394cae" ON "user" ("tags") `); - await queryRunner.query(`CREATE INDEX "IDX_3252a5df8d5bbd16b281f7799e" ON "user" ("host") `); - await queryRunner.query(`CREATE INDEX "IDX_be623adaa4c566baf5d29ce0c8" ON "user" ("uri") `); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_a854e557b1b14814750c7c7b0c" ON "user" ("token") `); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_5deb01ae162d1d70b80d064c27" ON "user" ("usernameLower", "host") `); - await queryRunner.query(`CREATE TABLE "app" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32), "secret" character varying(64) NOT NULL, "name" character varying(128) NOT NULL, "description" character varying(512) NOT NULL, "permission" character varying(64) array NOT NULL, "callbackUrl" character varying(512), CONSTRAINT "PK_9478629fc093d229df09e560aea" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE INDEX "IDX_048a757923ed8b157e9895da53" ON "app" ("createdAt") `); - await queryRunner.query(`CREATE INDEX "IDX_3f5b0899ef90527a3462d7c2cb" ON "app" ("userId") `); - await queryRunner.query(`CREATE INDEX "IDX_f49922d511d666848f250663c4" ON "app" ("secret") `); - await queryRunner.query(`CREATE TABLE "access_token" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "token" character varying(128) NOT NULL, "hash" character varying(128) NOT NULL, "userId" character varying(32) NOT NULL, "appId" character varying(32) NOT NULL, CONSTRAINT "PK_f20f028607b2603deabd8182d12" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE INDEX "IDX_70ba8f6af34bc924fc9e12adb8" ON "access_token" ("token") `); - await queryRunner.query(`CREATE INDEX "IDX_64c327441248bae40f7d92f34f" ON "access_token" ("hash") `); - await queryRunner.query(`CREATE INDEX "IDX_9949557d0e1b2c19e5344c171e" ON "access_token" ("userId") `); - await queryRunner.query(`CREATE TYPE "note_visibility_enum" AS ENUM('public', 'home', 'followers', 'specified')`); - await queryRunner.query(`CREATE TABLE "note" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "replyId" character varying(32), "renoteId" character varying(32), "text" text, "name" character varying(256), "cw" character varying(512), "appId" character varying(32), "userId" character varying(32) NOT NULL, "viaMobile" boolean NOT NULL DEFAULT false, "localOnly" boolean NOT NULL DEFAULT false, "renoteCount" smallint NOT NULL DEFAULT 0, "repliesCount" smallint NOT NULL DEFAULT 0, "reactions" jsonb NOT NULL DEFAULT '{}', "visibility" "note_visibility_enum" NOT NULL, "uri" character varying(512), "score" integer NOT NULL DEFAULT 0, "fileIds" character varying(32) array NOT NULL DEFAULT '{}'::varchar[], "attachedFileTypes" character varying(256) array NOT NULL DEFAULT '{}'::varchar[], "visibleUserIds" character varying(32) array NOT NULL DEFAULT '{}'::varchar[], "mentions" character varying(32) array NOT NULL DEFAULT '{}'::varchar[], "mentionedRemoteUsers" text NOT NULL DEFAULT '[]', "emojis" character varying(128) array NOT NULL DEFAULT '{}'::varchar[], "tags" character varying(128) array NOT NULL DEFAULT '{}'::varchar[], "hasPoll" boolean NOT NULL DEFAULT false, "geo" jsonb DEFAULT null, "userHost" character varying(128), "replyUserId" character varying(32), "replyUserHost" character varying(128), "renoteUserId" character varying(32), "renoteUserHost" character varying(128), CONSTRAINT "PK_96d0c172a4fba276b1bbed43058" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE INDEX "IDX_e7c0567f5261063592f022e9b5" ON "note" ("createdAt") `); - await queryRunner.query(`CREATE INDEX "IDX_17cb3553c700a4985dff5a30ff" ON "note" ("replyId") `); - await queryRunner.query(`CREATE INDEX "IDX_52ccc804d7c69037d558bac4c9" ON "note" ("renoteId") `); - await queryRunner.query(`CREATE INDEX "IDX_5b87d9d19127bd5d92026017a7" ON "note" ("userId") `); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_153536c67d05e9adb24e99fc2b" ON "note" ("uri") `); - await queryRunner.query(`CREATE INDEX "IDX_51c063b6a133a9cb87145450f5" ON "note" ("fileIds") `); - await queryRunner.query(`CREATE INDEX "IDX_25dfc71b0369b003a4cd434d0b" ON "note" ("attachedFileTypes") `); - await queryRunner.query(`CREATE INDEX "IDX_796a8c03959361f97dc2be1d5c" ON "note" ("visibleUserIds") `); - await queryRunner.query(`CREATE INDEX "IDX_54ebcb6d27222913b908d56fd8" ON "note" ("mentions") `); - await queryRunner.query(`CREATE INDEX "IDX_88937d94d7443d9a99a76fa5c0" ON "note" ("tags") `); - await queryRunner.query(`CREATE INDEX "IDX_7125a826ab192eb27e11d358a5" ON "note" ("userHost") `); - await queryRunner.query(`CREATE TABLE "poll_vote" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "noteId" character varying(32) NOT NULL, "choice" integer NOT NULL, CONSTRAINT "PK_fd002d371201c472490ba89c6a0" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE INDEX "IDX_0fb627e1c2f753262a74f0562d" ON "poll_vote" ("createdAt") `); - await queryRunner.query(`CREATE INDEX "IDX_66d2bd2ee31d14bcc23069a89f" ON "poll_vote" ("userId") `); - await queryRunner.query(`CREATE INDEX "IDX_aecfbd5ef60374918e63ee95fa" ON "poll_vote" ("noteId") `); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_50bd7164c5b78f1f4a42c4d21f" ON "poll_vote" ("userId", "noteId", "choice") `); - await queryRunner.query(`CREATE TABLE "note_reaction" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "noteId" character varying(32) NOT NULL, "reaction" character varying(128) NOT NULL, CONSTRAINT "PK_767ec729b108799b587a3fcc9cf" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE INDEX "IDX_01f4581f114e0ebd2bbb876f0b" ON "note_reaction" ("createdAt") `); - await queryRunner.query(`CREATE INDEX "IDX_13761f64257f40c5636d0ff95e" ON "note_reaction" ("userId") `); - await queryRunner.query(`CREATE INDEX "IDX_45145e4953780f3cd5656f0ea6" ON "note_reaction" ("noteId") `); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_ad0c221b25672daf2df320a817" ON "note_reaction" ("userId", "noteId") `); - await queryRunner.query(`CREATE TABLE "note_watching" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "noteId" character varying(32) NOT NULL, "noteUserId" character varying(32) NOT NULL, CONSTRAINT "PK_49286fdb23725945a74aa27d757" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE INDEX "IDX_318cdf42a9cfc11f479bd802bb" ON "note_watching" ("createdAt") `); - await queryRunner.query(`CREATE INDEX "IDX_b0134ec406e8d09a540f818288" ON "note_watching" ("userId") `); - await queryRunner.query(`CREATE INDEX "IDX_03e7028ab8388a3f5e3ce2a861" ON "note_watching" ("noteId") `); - await queryRunner.query(`CREATE INDEX "IDX_44499765eec6b5489d72c4253b" ON "note_watching" ("noteUserId") `); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_a42c93c69989ce1d09959df4cf" ON "note_watching" ("userId", "noteId") `); - await queryRunner.query(`CREATE TABLE "note_unread" ("id" character varying(32) NOT NULL, "userId" character varying(32) NOT NULL, "noteId" character varying(32) NOT NULL, "noteUserId" character varying(32) NOT NULL, "isSpecified" boolean NOT NULL, CONSTRAINT "PK_1904eda61a784f57e6e51fa9c1f" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE INDEX "IDX_56b0166d34ddae49d8ef7610bb" ON "note_unread" ("userId") `); - await queryRunner.query(`CREATE INDEX "IDX_e637cba4dc4410218c4251260e" ON "note_unread" ("noteId") `); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_d908433a4953cc13216cd9c274" ON "note_unread" ("userId", "noteId") `); - await queryRunner.query(`CREATE TABLE "notification" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "notifieeId" character varying(32) NOT NULL, "notifierId" character varying(32) NOT NULL, "type" character varying(32) NOT NULL, "isRead" boolean NOT NULL DEFAULT false, "noteId" character varying(32), "reaction" character varying(128), "choice" integer, CONSTRAINT "PK_705b6c7cdf9b2c2ff7ac7872cb7" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE INDEX "IDX_b11a5e627c41d4dc3170f1d370" ON "notification" ("createdAt") `); - await queryRunner.query(`CREATE INDEX "IDX_3c601b70a1066d2c8b517094cb" ON "notification" ("notifieeId") `); - await queryRunner.query(`CREATE TABLE "meta" ("id" character varying(32) NOT NULL, "name" character varying(128), "description" character varying(1024), "maintainerName" character varying(128), "maintainerEmail" character varying(128), "announcements" jsonb NOT NULL DEFAULT '[]', "disableRegistration" boolean NOT NULL DEFAULT false, "disableLocalTimeline" boolean NOT NULL DEFAULT false, "disableGlobalTimeline" boolean NOT NULL DEFAULT false, "enableEmojiReaction" boolean NOT NULL DEFAULT true, "useStarForReactionFallback" boolean NOT NULL DEFAULT false, "langs" character varying(64) array NOT NULL DEFAULT '{}'::varchar[], "hiddenTags" character varying(256) array NOT NULL DEFAULT '{}'::varchar[], "blockedHosts" character varying(256) array NOT NULL DEFAULT '{}'::varchar[], "mascotImageUrl" character varying(512) DEFAULT '/assets/ai.png', "bannerUrl" character varying(512), "errorImageUrl" character varying(512) DEFAULT 'https://xn--931a.moe/aiart/yubitun.png', "iconUrl" character varying(512), "cacheRemoteFiles" boolean NOT NULL DEFAULT true, "proxyAccount" character varying(128), "enableRecaptcha" boolean NOT NULL DEFAULT false, "recaptchaSiteKey" character varying(64), "recaptchaSecretKey" character varying(64), "localDriveCapacityMb" integer NOT NULL DEFAULT 1024, "remoteDriveCapacityMb" integer NOT NULL DEFAULT 32, "maxNoteTextLength" integer NOT NULL DEFAULT 500, "summalyProxy" character varying(128), "enableEmail" boolean NOT NULL DEFAULT false, "email" character varying(128), "smtpSecure" boolean NOT NULL DEFAULT false, "smtpHost" character varying(128), "smtpPort" integer, "smtpUser" character varying(128), "smtpPass" character varying(128), "enableServiceWorker" boolean NOT NULL DEFAULT false, "swPublicKey" character varying(128), "swPrivateKey" character varying(128), "enableTwitterIntegration" boolean NOT NULL DEFAULT false, "twitterConsumerKey" character varying(128), "twitterConsumerSecret" character varying(128), "enableGithubIntegration" boolean NOT NULL DEFAULT false, "githubClientId" character varying(128), "githubClientSecret" character varying(128), "enableDiscordIntegration" boolean NOT NULL DEFAULT false, "discordClientId" character varying(128), "discordClientSecret" character varying(128), CONSTRAINT "PK_c4c17a6c2bd7651338b60fc590b" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE TABLE "following" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "followeeId" character varying(32) NOT NULL, "followerId" character varying(32) NOT NULL, "followerHost" character varying(128), "followerInbox" character varying(512), "followerSharedInbox" character varying(512), "followeeHost" character varying(128), "followeeInbox" character varying(512), "followeeSharedInbox" character varying(512), CONSTRAINT "PK_c76c6e044bdf76ecf8bfb82a645" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE INDEX "IDX_582f8fab771a9040a12961f3e7" ON "following" ("createdAt") `); - await queryRunner.query(`CREATE INDEX "IDX_24e0042143a18157b234df186c" ON "following" ("followeeId") `); - await queryRunner.query(`CREATE INDEX "IDX_6516c5a6f3c015b4eed39978be" ON "following" ("followerId") `); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_307be5f1d1252e0388662acb96" ON "following" ("followerId", "followeeId") `); - await queryRunner.query(`CREATE TABLE "instance" ("id" character varying(32) NOT NULL, "caughtAt" TIMESTAMP WITH TIME ZONE NOT NULL, "host" character varying(128) NOT NULL, "system" character varying(64), "usersCount" integer NOT NULL DEFAULT 0, "notesCount" integer NOT NULL DEFAULT 0, "followingCount" integer NOT NULL DEFAULT 0, "followersCount" integer NOT NULL DEFAULT 0, "driveUsage" integer NOT NULL DEFAULT 0, "driveFiles" integer NOT NULL DEFAULT 0, "latestRequestSentAt" TIMESTAMP WITH TIME ZONE, "latestStatus" integer, "latestRequestReceivedAt" TIMESTAMP WITH TIME ZONE, "lastCommunicatedAt" TIMESTAMP WITH TIME ZONE NOT NULL, "isNotResponding" boolean NOT NULL DEFAULT false, "isMarkedAsClosed" boolean NOT NULL DEFAULT false, CONSTRAINT "PK_eaf60e4a0c399c9935413e06474" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE INDEX "IDX_2cd3b2a6b4cf0b910b260afe08" ON "instance" ("caughtAt") `); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_8d5afc98982185799b160e10eb" ON "instance" ("host") `); - await queryRunner.query(`CREATE TABLE "muting" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "muteeId" character varying(32) NOT NULL, "muterId" character varying(32) NOT NULL, CONSTRAINT "PK_2e92d06c8b5c602eeb27ca9ba48" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE INDEX "IDX_f86d57fbca33c7a4e6897490cc" ON "muting" ("createdAt") `); - await queryRunner.query(`CREATE INDEX "IDX_ec96b4fed9dae517e0dbbe0675" ON "muting" ("muteeId") `); - await queryRunner.query(`CREATE INDEX "IDX_93060675b4a79a577f31d260c6" ON "muting" ("muterId") `); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_1eb9d9824a630321a29fd3b290" ON "muting" ("muterId", "muteeId") `); - await queryRunner.query(`CREATE TABLE "sw_subscription" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "endpoint" character varying(512) NOT NULL, "auth" character varying(256) NOT NULL, "publickey" character varying(128) NOT NULL, CONSTRAINT "PK_e8f763631530051b95eb6279b91" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE INDEX "IDX_97754ca6f2baff9b4abb7f853d" ON "sw_subscription" ("userId") `); - await queryRunner.query(`CREATE TABLE "blocking" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "blockeeId" character varying(32) NOT NULL, "blockerId" character varying(32) NOT NULL, CONSTRAINT "PK_e5d9a541cc1965ee7e048ea09dd" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE INDEX "IDX_b9a354f7941c1e779f3b33aea6" ON "blocking" ("createdAt") `); - await queryRunner.query(`CREATE INDEX "IDX_2cd4a2743a99671308f5417759" ON "blocking" ("blockeeId") `); - await queryRunner.query(`CREATE INDEX "IDX_0627125f1a8a42c9a1929edb55" ON "blocking" ("blockerId") `); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_98a1bc5cb30dfd159de056549f" ON "blocking" ("blockerId", "blockeeId") `); - await queryRunner.query(`CREATE TABLE "user_list" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "name" character varying(128) NOT NULL, CONSTRAINT "PK_87bab75775fd9b1ff822b656402" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE INDEX "IDX_b7fcefbdd1c18dce86687531f9" ON "user_list" ("userId") `); - await queryRunner.query(`CREATE TABLE "user_list_joining" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "userListId" character varying(32) NOT NULL, CONSTRAINT "PK_11abb3768da1c5f8de101c9df45" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE INDEX "IDX_d844bfc6f3f523a05189076efa" ON "user_list_joining" ("userId") `); - await queryRunner.query(`CREATE INDEX "IDX_605472305f26818cc93d1baaa7" ON "user_list_joining" ("userListId") `); - await queryRunner.query(`CREATE TABLE "hashtag" ("id" character varying(32) NOT NULL, "name" character varying(128) NOT NULL, "mentionedUserIds" character varying(32) array NOT NULL, "mentionedUsersCount" integer NOT NULL DEFAULT 0, "mentionedLocalUserIds" character varying(32) array NOT NULL, "mentionedLocalUsersCount" integer NOT NULL DEFAULT 0, "mentionedRemoteUserIds" character varying(32) array NOT NULL, "mentionedRemoteUsersCount" integer NOT NULL DEFAULT 0, "attachedUserIds" character varying(32) array NOT NULL, "attachedUsersCount" integer NOT NULL DEFAULT 0, "attachedLocalUserIds" character varying(32) array NOT NULL, "attachedLocalUsersCount" integer NOT NULL DEFAULT 0, "attachedRemoteUserIds" character varying(32) array NOT NULL, "attachedRemoteUsersCount" integer NOT NULL DEFAULT 0, CONSTRAINT "PK_cb36eb8af8412bfa978f1165d78" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_347fec870eafea7b26c8a73bac" ON "hashtag" ("name") `); - await queryRunner.query(`CREATE INDEX "IDX_2710a55f826ee236ea1a62698f" ON "hashtag" ("mentionedUsersCount") `); - await queryRunner.query(`CREATE INDEX "IDX_0e206cec573f1edff4a3062923" ON "hashtag" ("mentionedLocalUsersCount") `); - await queryRunner.query(`CREATE INDEX "IDX_4c02d38a976c3ae132228c6fce" ON "hashtag" ("mentionedRemoteUsersCount") `); - await queryRunner.query(`CREATE INDEX "IDX_d57f9030cd3af7f63ffb1c267c" ON "hashtag" ("attachedUsersCount") `); - await queryRunner.query(`CREATE INDEX "IDX_0c44bf4f680964145f2a68a341" ON "hashtag" ("attachedLocalUsersCount") `); - await queryRunner.query(`CREATE INDEX "IDX_0b03cbcd7e6a7ce068efa8ecc2" ON "hashtag" ("attachedRemoteUsersCount") `); - await queryRunner.query(`CREATE TABLE "note_favorite" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "noteId" character varying(32) NOT NULL, CONSTRAINT "PK_af0da35a60b9fa4463a62082b36" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE INDEX "IDX_47f4b1892f5d6ba8efb3057d81" ON "note_favorite" ("userId") `); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_0f4fb9ad355f3effff221ef245" ON "note_favorite" ("userId", "noteId") `); - await queryRunner.query(`CREATE TABLE "abuse_user_report" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "reporterId" character varying(32) NOT NULL, "comment" character varying(512) NOT NULL, CONSTRAINT "PK_87873f5f5cc5c321a1306b2d18c" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE INDEX "IDX_db2098070b2b5a523c58181f74" ON "abuse_user_report" ("createdAt") `); - await queryRunner.query(`CREATE INDEX "IDX_d049123c413e68ca52abe73420" ON "abuse_user_report" ("userId") `); - await queryRunner.query(`CREATE INDEX "IDX_04cc96756f89d0b7f9473e8cdf" ON "abuse_user_report" ("reporterId") `); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_5cd442c3b2e74fdd99dae20243" ON "abuse_user_report" ("userId", "reporterId") `); - await queryRunner.query(`CREATE TABLE "registration_ticket" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "code" character varying(64) NOT NULL, CONSTRAINT "PK_f11696b6fafcf3662d4292734f8" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_0ff69e8dfa9fe31bb4a4660f59" ON "registration_ticket" ("code") `); - await queryRunner.query(`CREATE TABLE "messaging_message" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "recipientId" character varying(32) NOT NULL, "text" character varying(4096), "isRead" boolean NOT NULL DEFAULT false, "fileId" character varying(32), CONSTRAINT "PK_db398fd79dc95d0eb8c30456eaa" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE INDEX "IDX_e21cd3646e52ef9c94aaf17c2e" ON "messaging_message" ("createdAt") `); - await queryRunner.query(`CREATE INDEX "IDX_5377c307783fce2b6d352e1203" ON "messaging_message" ("userId") `); - await queryRunner.query(`CREATE INDEX "IDX_cac14a4e3944454a5ce7daa514" ON "messaging_message" ("recipientId") `); - await queryRunner.query(`CREATE TABLE "signin" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "ip" character varying(128) NOT NULL, "headers" jsonb NOT NULL, "success" boolean NOT NULL, CONSTRAINT "PK_9e96ddc025712616fc492b3b588" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE INDEX "IDX_2c308dbdc50d94dc625670055f" ON "signin" ("userId") `); - await queryRunner.query(`CREATE TABLE "auth_session" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "token" character varying(128) NOT NULL, "userId" character varying(32), "appId" character varying(32) NOT NULL, CONSTRAINT "PK_19354ed146424a728c1112a8cbf" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE INDEX "IDX_62cb09e1129f6ec024ef66e183" ON "auth_session" ("token") `); - await queryRunner.query(`CREATE TABLE "follow_request" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "followeeId" character varying(32) NOT NULL, "followerId" character varying(32) NOT NULL, "requestId" character varying(128), "followerHost" character varying(128), "followerInbox" character varying(512), "followerSharedInbox" character varying(512), "followeeHost" character varying(128), "followeeInbox" character varying(512), "followeeSharedInbox" character varying(512), CONSTRAINT "PK_53a9aa3725f7a3deb150b39dbfc" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE INDEX "IDX_12c01c0d1a79f77d9f6c15fadd" ON "follow_request" ("followeeId") `); - await queryRunner.query(`CREATE INDEX "IDX_a7fd92dd6dc519e6fb435dd108" ON "follow_request" ("followerId") `); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_d54a512b822fac7ed52800f6b4" ON "follow_request" ("followerId", "followeeId") `); - await queryRunner.query(`CREATE TABLE "emoji" ("id" character varying(32) NOT NULL, "updatedAt" TIMESTAMP WITH TIME ZONE, "name" character varying(128) NOT NULL, "host" character varying(128), "url" character varying(512) NOT NULL, "uri" character varying(512), "type" character varying(64), "aliases" character varying(128) array NOT NULL DEFAULT '{}'::varchar[], CONSTRAINT "PK_df74ce05e24999ee01ea0bc50a3" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE INDEX "IDX_b37dafc86e9af007e3295c2781" ON "emoji" ("name") `); - await queryRunner.query(`CREATE INDEX "IDX_5900e907bb46516ddf2871327c" ON "emoji" ("host") `); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_4f4d35e1256c84ae3d1f0eab10" ON "emoji" ("name", "host") `); - await queryRunner.query(`CREATE TABLE "reversi_game" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "startedAt" TIMESTAMP WITH TIME ZONE, "user1Id" character varying(32) NOT NULL, "user2Id" character varying(32) NOT NULL, "user1Accepted" boolean NOT NULL DEFAULT false, "user2Accepted" boolean NOT NULL DEFAULT false, "black" integer, "isStarted" boolean NOT NULL DEFAULT false, "isEnded" boolean NOT NULL DEFAULT false, "winnerId" character varying(32), "surrendered" character varying(32), "logs" jsonb NOT NULL DEFAULT '[]', "map" character varying(64) array NOT NULL, "bw" character varying(32) NOT NULL, "isLlotheo" boolean NOT NULL DEFAULT false, "canPutEverywhere" boolean NOT NULL DEFAULT false, "loopedBoard" boolean NOT NULL DEFAULT false, "form1" jsonb DEFAULT null, "form2" jsonb DEFAULT null, "crc32" character varying(32), CONSTRAINT "PK_76b30eeba71b1193ad7c5311c3f" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE INDEX "IDX_b46ec40746efceac604142be1c" ON "reversi_game" ("createdAt") `); - await queryRunner.query(`CREATE TABLE "reversi_matching" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "parentId" character varying(32) NOT NULL, "childId" character varying(32) NOT NULL, CONSTRAINT "PK_880bd0afbab232f21c8b9d146cf" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE INDEX "IDX_b604d92d6c7aec38627f6eaf16" ON "reversi_matching" ("createdAt") `); - await queryRunner.query(`CREATE INDEX "IDX_3b25402709dd9882048c2bbade" ON "reversi_matching" ("parentId") `); - await queryRunner.query(`CREATE INDEX "IDX_e247b23a3c9b45f89ec1299d06" ON "reversi_matching" ("childId") `); - await queryRunner.query(`CREATE TABLE "user_note_pining" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "noteId" character varying(32) NOT NULL, CONSTRAINT "PK_a6a2dad4ae000abce2ea9d9b103" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE INDEX "IDX_bfbc6f79ba4007b4ce5097f08d" ON "user_note_pining" ("userId") `); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_410cd649884b501c02d6e72738" ON "user_note_pining" ("userId", "noteId") `); - await queryRunner.query(`CREATE TYPE "poll_notevisibility_enum" AS ENUM('public', 'home', 'followers', 'specified')`); - await queryRunner.query(`CREATE TABLE "poll" ("noteId" character varying(32) NOT NULL, "expiresAt" TIMESTAMP WITH TIME ZONE, "multiple" boolean NOT NULL, "choices" character varying(128) array NOT NULL DEFAULT '{}'::varchar[], "votes" integer array NOT NULL, "noteVisibility" "poll_notevisibility_enum" NOT NULL, "userId" character varying(32) NOT NULL, "userHost" character varying(128), CONSTRAINT "REL_da851e06d0dfe2ef397d8b1bf1" UNIQUE ("noteId"), CONSTRAINT "PK_da851e06d0dfe2ef397d8b1bf1b" PRIMARY KEY ("noteId"))`); - await queryRunner.query(`CREATE INDEX "IDX_0610ebcfcfb4a18441a9bcdab2" ON "poll" ("userId") `); - await queryRunner.query(`CREATE INDEX "IDX_7fa20a12319c7f6dc3aed98c0a" ON "poll" ("userHost") `); - await queryRunner.query(`CREATE TABLE "user_keypair" ("userId" character varying(32) NOT NULL, "publicKey" character varying(4096) NOT NULL, "privateKey" character varying(4096) NOT NULL, CONSTRAINT "REL_f4853eb41ab722fe05f81cedeb" UNIQUE ("userId"), CONSTRAINT "PK_f4853eb41ab722fe05f81cedeb6" PRIMARY KEY ("userId"))`); - await queryRunner.query(`CREATE TABLE "user_publickey" ("userId" character varying(32) NOT NULL, "keyId" character varying(256) NOT NULL, "keyPem" character varying(4096) NOT NULL, CONSTRAINT "REL_10c146e4b39b443ede016f6736" UNIQUE ("userId"), CONSTRAINT "PK_10c146e4b39b443ede016f6736d" PRIMARY KEY ("userId"))`); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_171e64971c780ebd23fae140bb" ON "user_publickey" ("keyId") `); - await queryRunner.query(`CREATE TABLE "user_profile" ("userId" character varying(32) NOT NULL, "location" character varying(128), "birthday" character(10), "description" character varying(1024), "fields" jsonb NOT NULL DEFAULT '[]', "url" character varying(512), "email" character varying(128), "emailVerifyCode" character varying(128), "emailVerified" boolean NOT NULL DEFAULT false, "twoFactorTempSecret" character varying(128), "twoFactorSecret" character varying(128), "twoFactorEnabled" boolean NOT NULL DEFAULT false, "password" character varying(128), "clientData" jsonb NOT NULL DEFAULT '{}', "autoWatch" boolean NOT NULL DEFAULT false, "autoAcceptFollowed" boolean NOT NULL DEFAULT false, "alwaysMarkNsfw" boolean NOT NULL DEFAULT false, "carefulBot" boolean NOT NULL DEFAULT false, "twitter" boolean NOT NULL DEFAULT false, "twitterAccessToken" character varying(64) DEFAULT null, "twitterAccessTokenSecret" character varying(64) DEFAULT null, "twitterUserId" character varying(64) DEFAULT null, "twitterScreenName" character varying(64) DEFAULT null, "github" boolean NOT NULL DEFAULT false, "githubAccessToken" character varying(64) DEFAULT null, "githubId" integer DEFAULT null, "githubLogin" character varying(64) DEFAULT null, "discord" boolean NOT NULL DEFAULT false, "discordAccessToken" character varying(64) DEFAULT null, "discordRefreshToken" character varying(64) DEFAULT null, "discordExpiresDate" integer DEFAULT null, "discordId" character varying(64) DEFAULT null, "discordUsername" character varying(64) DEFAULT null, "discordDiscriminator" character varying(64) DEFAULT null, "userHost" character varying(128), CONSTRAINT "REL_51cb79b5555effaf7d69ba1cff" UNIQUE ("userId"), CONSTRAINT "PK_51cb79b5555effaf7d69ba1cff9" PRIMARY KEY ("userId"))`); - await queryRunner.query(`CREATE INDEX "IDX_dce530b98e454793dac5ec2f5a" ON "user_profile" ("userHost") `); - await queryRunner.query(`CREATE TYPE "__chart__active_users_span_enum" AS ENUM('hour', 'day')`); - await queryRunner.query(`CREATE TABLE "__chart__active_users" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128), "span" "__chart__active_users_span_enum" NOT NULL, "unique" jsonb NOT NULL DEFAULT '{}', "___local_count" bigint NOT NULL, "___remote_count" bigint NOT NULL, CONSTRAINT "PK_317237a9f733b970604a11e314f" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE TYPE "__chart__drive_span_enum" AS ENUM('hour', 'day')`); - await queryRunner.query(`CREATE TABLE "__chart__drive" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128), "span" "__chart__drive_span_enum" NOT NULL, "unique" jsonb NOT NULL DEFAULT '{}', "___local_totalCount" bigint NOT NULL, "___local_totalSize" bigint NOT NULL, "___local_incCount" bigint NOT NULL, "___local_incSize" bigint NOT NULL, "___local_decCount" bigint NOT NULL, "___local_decSize" bigint NOT NULL, "___remote_totalCount" bigint NOT NULL, "___remote_totalSize" bigint NOT NULL, "___remote_incCount" bigint NOT NULL, "___remote_incSize" bigint NOT NULL, "___remote_decCount" bigint NOT NULL, "___remote_decSize" bigint NOT NULL, CONSTRAINT "PK_f96bc548a765cd4b3b354221ce7" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE TYPE "__chart__federation_span_enum" AS ENUM('hour', 'day')`); - await queryRunner.query(`CREATE TABLE "__chart__federation" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128), "span" "__chart__federation_span_enum" NOT NULL, "unique" jsonb NOT NULL DEFAULT '{}', "___instance_total" bigint NOT NULL, "___instance_inc" bigint NOT NULL, "___instance_dec" bigint NOT NULL, CONSTRAINT "PK_b39dcd31a0fe1a7757e348e85fd" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE TYPE "__chart__hashtag_span_enum" AS ENUM('hour', 'day')`); - await queryRunner.query(`CREATE TABLE "__chart__hashtag" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128), "span" "__chart__hashtag_span_enum" NOT NULL, "unique" jsonb NOT NULL DEFAULT '{}', "___local_count" bigint NOT NULL, "___remote_count" bigint NOT NULL, CONSTRAINT "PK_c32f1ea2b44a5d2f7881e37f8f9" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE TYPE "__chart__instance_span_enum" AS ENUM('hour', 'day')`); - await queryRunner.query(`CREATE TABLE "__chart__instance" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128), "span" "__chart__instance_span_enum" NOT NULL, "unique" jsonb NOT NULL DEFAULT '{}', "___requests_failed" bigint NOT NULL, "___requests_succeeded" bigint NOT NULL, "___requests_received" bigint NOT NULL, "___notes_total" bigint NOT NULL, "___notes_inc" bigint NOT NULL, "___notes_dec" bigint NOT NULL, "___notes_diffs_normal" bigint NOT NULL, "___notes_diffs_reply" bigint NOT NULL, "___notes_diffs_renote" bigint NOT NULL, "___users_total" bigint NOT NULL, "___users_inc" bigint NOT NULL, "___users_dec" bigint NOT NULL, "___following_total" bigint NOT NULL, "___following_inc" bigint NOT NULL, "___following_dec" bigint NOT NULL, "___followers_total" bigint NOT NULL, "___followers_inc" bigint NOT NULL, "___followers_dec" bigint NOT NULL, "___drive_totalFiles" bigint NOT NULL, "___drive_totalUsage" bigint NOT NULL, "___drive_incFiles" bigint NOT NULL, "___drive_incUsage" bigint NOT NULL, "___drive_decFiles" bigint NOT NULL, "___drive_decUsage" bigint NOT NULL, CONSTRAINT "PK_1267c67c7c2d47b4903975f2c00" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE TYPE "__chart__network_span_enum" AS ENUM('hour', 'day')`); - await queryRunner.query(`CREATE TABLE "__chart__network" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128), "span" "__chart__network_span_enum" NOT NULL, "unique" jsonb NOT NULL DEFAULT '{}', "___incomingRequests" bigint NOT NULL, "___outgoingRequests" bigint NOT NULL, "___totalTime" bigint NOT NULL, "___incomingBytes" bigint NOT NULL, "___outgoingBytes" bigint NOT NULL, CONSTRAINT "PK_bc4290c2e27fad14ef0c1ca93f3" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE TYPE "__chart__notes_span_enum" AS ENUM('hour', 'day')`); - await queryRunner.query(`CREATE TABLE "__chart__notes" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128), "span" "__chart__notes_span_enum" NOT NULL, "unique" jsonb NOT NULL DEFAULT '{}', "___local_total" bigint NOT NULL, "___local_inc" bigint NOT NULL, "___local_dec" bigint NOT NULL, "___local_diffs_normal" bigint NOT NULL, "___local_diffs_reply" bigint NOT NULL, "___local_diffs_renote" bigint NOT NULL, "___remote_total" bigint NOT NULL, "___remote_inc" bigint NOT NULL, "___remote_dec" bigint NOT NULL, "___remote_diffs_normal" bigint NOT NULL, "___remote_diffs_reply" bigint NOT NULL, "___remote_diffs_renote" bigint NOT NULL, CONSTRAINT "PK_0aec823fa85c7f901bdb3863b14" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE TYPE "__chart__per_user_drive_span_enum" AS ENUM('hour', 'day')`); - await queryRunner.query(`CREATE TABLE "__chart__per_user_drive" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128), "span" "__chart__per_user_drive_span_enum" NOT NULL, "unique" jsonb NOT NULL DEFAULT '{}', "___totalCount" bigint NOT NULL, "___totalSize" bigint NOT NULL, "___incCount" bigint NOT NULL, "___incSize" bigint NOT NULL, "___decCount" bigint NOT NULL, "___decSize" bigint NOT NULL, CONSTRAINT "PK_d0ef23d24d666e1a44a0cd3d208" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE TYPE "__chart__per_user_following_span_enum" AS ENUM('hour', 'day')`); - await queryRunner.query(`CREATE TABLE "__chart__per_user_following" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128), "span" "__chart__per_user_following_span_enum" NOT NULL, "unique" jsonb NOT NULL DEFAULT '{}', "___local_followings_total" bigint NOT NULL, "___local_followings_inc" bigint NOT NULL, "___local_followings_dec" bigint NOT NULL, "___local_followers_total" bigint NOT NULL, "___local_followers_inc" bigint NOT NULL, "___local_followers_dec" bigint NOT NULL, "___remote_followings_total" bigint NOT NULL, "___remote_followings_inc" bigint NOT NULL, "___remote_followings_dec" bigint NOT NULL, "___remote_followers_total" bigint NOT NULL, "___remote_followers_inc" bigint NOT NULL, "___remote_followers_dec" bigint NOT NULL, CONSTRAINT "PK_85bb1b540363a29c2fec83bd907" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE TYPE "__chart__per_user_notes_span_enum" AS ENUM('hour', 'day')`); - await queryRunner.query(`CREATE TABLE "__chart__per_user_notes" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128), "span" "__chart__per_user_notes_span_enum" NOT NULL, "unique" jsonb NOT NULL DEFAULT '{}', "___total" bigint NOT NULL, "___inc" bigint NOT NULL, "___dec" bigint NOT NULL, "___diffs_normal" bigint NOT NULL, "___diffs_reply" bigint NOT NULL, "___diffs_renote" bigint NOT NULL, CONSTRAINT "PK_334acf6e915af2f29edc11b8e50" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE TYPE "__chart__per_user_reaction_span_enum" AS ENUM('hour', 'day')`); - await queryRunner.query(`CREATE TABLE "__chart__per_user_reaction" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128), "span" "__chart__per_user_reaction_span_enum" NOT NULL, "unique" jsonb NOT NULL DEFAULT '{}', "___local_count" bigint NOT NULL, "___remote_count" bigint NOT NULL, CONSTRAINT "PK_984f54dae441e65b633e8d27a7f" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE TYPE "__chart__test_grouped_span_enum" AS ENUM('hour', 'day')`); - await queryRunner.query(`CREATE TABLE "__chart__test_grouped" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128), "span" "__chart__test_grouped_span_enum" NOT NULL, "unique" jsonb NOT NULL DEFAULT '{}', "___foo_total" bigint NOT NULL, "___foo_inc" bigint NOT NULL, "___foo_dec" bigint NOT NULL, CONSTRAINT "PK_f4a2b175d308695af30d4293272" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE TYPE "__chart__test_unique_span_enum" AS ENUM('hour', 'day')`); - await queryRunner.query(`CREATE TABLE "__chart__test_unique" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128), "span" "__chart__test_unique_span_enum" NOT NULL, "unique" jsonb NOT NULL DEFAULT '{}', "___foo" bigint NOT NULL, CONSTRAINT "PK_409bac9c97cc612d8500012319d" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE TYPE "__chart__test_span_enum" AS ENUM('hour', 'day')`); - await queryRunner.query(`CREATE TABLE "__chart__test" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128), "span" "__chart__test_span_enum" NOT NULL, "unique" jsonb NOT NULL DEFAULT '{}', "___foo_total" bigint NOT NULL, "___foo_inc" bigint NOT NULL, "___foo_dec" bigint NOT NULL, CONSTRAINT "PK_b4bc31dffbd1b785276a3ecfc1e" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE TYPE "__chart__users_span_enum" AS ENUM('hour', 'day')`); - await queryRunner.query(`CREATE TABLE "__chart__users" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128), "span" "__chart__users_span_enum" NOT NULL, "unique" jsonb NOT NULL DEFAULT '{}', "___local_total" bigint NOT NULL, "___local_inc" bigint NOT NULL, "___local_dec" bigint NOT NULL, "___remote_total" bigint NOT NULL, "___remote_inc" bigint NOT NULL, "___remote_dec" bigint NOT NULL, CONSTRAINT "PK_4dfcf2c78d03524b9eb2c99d328" PRIMARY KEY ("id"))`); - await queryRunner.query(`ALTER TABLE "drive_folder" ADD CONSTRAINT "FK_f4fc06e49c0171c85f1c48060d2" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "drive_folder" ADD CONSTRAINT "FK_00ceffb0cdc238b3233294f08f2" FOREIGN KEY ("parentId") REFERENCES "drive_folder"("id") ON DELETE SET NULL ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "drive_file" ADD CONSTRAINT "FK_860fa6f6c7df5bb887249fba22e" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE SET NULL ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "drive_file" ADD CONSTRAINT "FK_bb90d1956dafc4068c28aa7560a" FOREIGN KEY ("folderId") REFERENCES "drive_folder"("id") ON DELETE SET NULL ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "user" ADD CONSTRAINT "FK_58f5c71eaab331645112cf8cfa5" FOREIGN KEY ("avatarId") REFERENCES "drive_file"("id") ON DELETE SET NULL ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "user" ADD CONSTRAINT "FK_afc64b53f8db3707ceb34eb28e2" FOREIGN KEY ("bannerId") REFERENCES "drive_file"("id") ON DELETE SET NULL ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "app" ADD CONSTRAINT "FK_3f5b0899ef90527a3462d7c2cb3" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE SET NULL ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "access_token" ADD CONSTRAINT "FK_9949557d0e1b2c19e5344c171e9" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "access_token" ADD CONSTRAINT "FK_a3ff16c90cc87a82a0b5959e560" FOREIGN KEY ("appId") REFERENCES "app"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "note" ADD CONSTRAINT "FK_17cb3553c700a4985dff5a30ff5" FOREIGN KEY ("replyId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "note" ADD CONSTRAINT "FK_52ccc804d7c69037d558bac4c96" FOREIGN KEY ("renoteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "note" ADD CONSTRAINT "FK_ec5c201576192ba8904c345c5cc" FOREIGN KEY ("appId") REFERENCES "app"("id") ON DELETE SET NULL ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "note" ADD CONSTRAINT "FK_5b87d9d19127bd5d92026017a7b" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "poll_vote" ADD CONSTRAINT "FK_66d2bd2ee31d14bcc23069a89f8" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "poll_vote" ADD CONSTRAINT "FK_aecfbd5ef60374918e63ee95fa7" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "note_reaction" ADD CONSTRAINT "FK_13761f64257f40c5636d0ff95ee" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "note_reaction" ADD CONSTRAINT "FK_45145e4953780f3cd5656f0ea6a" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "note_watching" ADD CONSTRAINT "FK_b0134ec406e8d09a540f8182888" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "note_watching" ADD CONSTRAINT "FK_03e7028ab8388a3f5e3ce2a8619" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "note_unread" ADD CONSTRAINT "FK_56b0166d34ddae49d8ef7610bb9" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "note_unread" ADD CONSTRAINT "FK_e637cba4dc4410218c4251260e4" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "notification" ADD CONSTRAINT "FK_3c601b70a1066d2c8b517094cb9" FOREIGN KEY ("notifieeId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "notification" ADD CONSTRAINT "FK_3b4e96eec8d36a8bbb9d02aa710" FOREIGN KEY ("notifierId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "notification" ADD CONSTRAINT "FK_769cb6b73a1efe22ddf733ac453" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "following" ADD CONSTRAINT "FK_24e0042143a18157b234df186c3" FOREIGN KEY ("followeeId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "following" ADD CONSTRAINT "FK_6516c5a6f3c015b4eed39978be5" FOREIGN KEY ("followerId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "muting" ADD CONSTRAINT "FK_ec96b4fed9dae517e0dbbe0675c" FOREIGN KEY ("muteeId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "muting" ADD CONSTRAINT "FK_93060675b4a79a577f31d260c67" FOREIGN KEY ("muterId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "sw_subscription" ADD CONSTRAINT "FK_97754ca6f2baff9b4abb7f853dd" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "blocking" ADD CONSTRAINT "FK_2cd4a2743a99671308f5417759e" FOREIGN KEY ("blockeeId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "blocking" ADD CONSTRAINT "FK_0627125f1a8a42c9a1929edb552" FOREIGN KEY ("blockerId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "user_list" ADD CONSTRAINT "FK_b7fcefbdd1c18dce86687531f99" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "user_list_joining" ADD CONSTRAINT "FK_d844bfc6f3f523a05189076efaa" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "user_list_joining" ADD CONSTRAINT "FK_605472305f26818cc93d1baaa74" FOREIGN KEY ("userListId") REFERENCES "user_list"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "note_favorite" ADD CONSTRAINT "FK_47f4b1892f5d6ba8efb3057d81a" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "note_favorite" ADD CONSTRAINT "FK_0e00498f180193423c992bc4370" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "abuse_user_report" ADD CONSTRAINT "FK_d049123c413e68ca52abe734203" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "abuse_user_report" ADD CONSTRAINT "FK_04cc96756f89d0b7f9473e8cdf3" FOREIGN KEY ("reporterId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "messaging_message" ADD CONSTRAINT "FK_5377c307783fce2b6d352e1203b" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "messaging_message" ADD CONSTRAINT "FK_cac14a4e3944454a5ce7daa5142" FOREIGN KEY ("recipientId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "messaging_message" ADD CONSTRAINT "FK_535def119223ac05ad3fa9ef64b" FOREIGN KEY ("fileId") REFERENCES "drive_file"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "signin" ADD CONSTRAINT "FK_2c308dbdc50d94dc625670055f7" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "auth_session" ADD CONSTRAINT "FK_c072b729d71697f959bde66ade0" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "auth_session" ADD CONSTRAINT "FK_dbe037d4bddd17b03a1dc778dee" FOREIGN KEY ("appId") REFERENCES "app"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "follow_request" ADD CONSTRAINT "FK_12c01c0d1a79f77d9f6c15fadd2" FOREIGN KEY ("followeeId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "follow_request" ADD CONSTRAINT "FK_a7fd92dd6dc519e6fb435dd108f" FOREIGN KEY ("followerId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "reversi_game" ADD CONSTRAINT "FK_f7467510c60a45ce5aca6292743" FOREIGN KEY ("user1Id") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "reversi_game" ADD CONSTRAINT "FK_6649a4e8c5d5cf32fb03b5da9f6" FOREIGN KEY ("user2Id") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "reversi_matching" ADD CONSTRAINT "FK_3b25402709dd9882048c2bbade0" FOREIGN KEY ("parentId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "reversi_matching" ADD CONSTRAINT "FK_e247b23a3c9b45f89ec1299d066" FOREIGN KEY ("childId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "user_note_pining" ADD CONSTRAINT "FK_bfbc6f79ba4007b4ce5097f08d6" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "user_note_pining" ADD CONSTRAINT "FK_68881008f7c3588ad7ecae471cf" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "poll" ADD CONSTRAINT "FK_da851e06d0dfe2ef397d8b1bf1b" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "user_keypair" ADD CONSTRAINT "FK_f4853eb41ab722fe05f81cedeb6" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "user_publickey" ADD CONSTRAINT "FK_10c146e4b39b443ede016f6736d" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "user_profile" ADD CONSTRAINT "FK_51cb79b5555effaf7d69ba1cff9" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user_profile" DROP CONSTRAINT "FK_51cb79b5555effaf7d69ba1cff9"`); - await queryRunner.query(`ALTER TABLE "user_publickey" DROP CONSTRAINT "FK_10c146e4b39b443ede016f6736d"`); - await queryRunner.query(`ALTER TABLE "user_keypair" DROP CONSTRAINT "FK_f4853eb41ab722fe05f81cedeb6"`); - await queryRunner.query(`ALTER TABLE "poll" DROP CONSTRAINT "FK_da851e06d0dfe2ef397d8b1bf1b"`); - await queryRunner.query(`ALTER TABLE "user_note_pining" DROP CONSTRAINT "FK_68881008f7c3588ad7ecae471cf"`); - await queryRunner.query(`ALTER TABLE "user_note_pining" DROP CONSTRAINT "FK_bfbc6f79ba4007b4ce5097f08d6"`); - await queryRunner.query(`ALTER TABLE "reversi_matching" DROP CONSTRAINT "FK_e247b23a3c9b45f89ec1299d066"`); - await queryRunner.query(`ALTER TABLE "reversi_matching" DROP CONSTRAINT "FK_3b25402709dd9882048c2bbade0"`); - await queryRunner.query(`ALTER TABLE "reversi_game" DROP CONSTRAINT "FK_6649a4e8c5d5cf32fb03b5da9f6"`); - await queryRunner.query(`ALTER TABLE "reversi_game" DROP CONSTRAINT "FK_f7467510c60a45ce5aca6292743"`); - await queryRunner.query(`ALTER TABLE "follow_request" DROP CONSTRAINT "FK_a7fd92dd6dc519e6fb435dd108f"`); - await queryRunner.query(`ALTER TABLE "follow_request" DROP CONSTRAINT "FK_12c01c0d1a79f77d9f6c15fadd2"`); - await queryRunner.query(`ALTER TABLE "auth_session" DROP CONSTRAINT "FK_dbe037d4bddd17b03a1dc778dee"`); - await queryRunner.query(`ALTER TABLE "auth_session" DROP CONSTRAINT "FK_c072b729d71697f959bde66ade0"`); - await queryRunner.query(`ALTER TABLE "signin" DROP CONSTRAINT "FK_2c308dbdc50d94dc625670055f7"`); - await queryRunner.query(`ALTER TABLE "messaging_message" DROP CONSTRAINT "FK_535def119223ac05ad3fa9ef64b"`); - await queryRunner.query(`ALTER TABLE "messaging_message" DROP CONSTRAINT "FK_cac14a4e3944454a5ce7daa5142"`); - await queryRunner.query(`ALTER TABLE "messaging_message" DROP CONSTRAINT "FK_5377c307783fce2b6d352e1203b"`); - await queryRunner.query(`ALTER TABLE "abuse_user_report" DROP CONSTRAINT "FK_04cc96756f89d0b7f9473e8cdf3"`); - await queryRunner.query(`ALTER TABLE "abuse_user_report" DROP CONSTRAINT "FK_d049123c413e68ca52abe734203"`); - await queryRunner.query(`ALTER TABLE "note_favorite" DROP CONSTRAINT "FK_0e00498f180193423c992bc4370"`); - await queryRunner.query(`ALTER TABLE "note_favorite" DROP CONSTRAINT "FK_47f4b1892f5d6ba8efb3057d81a"`); - await queryRunner.query(`ALTER TABLE "user_list_joining" DROP CONSTRAINT "FK_605472305f26818cc93d1baaa74"`); - await queryRunner.query(`ALTER TABLE "user_list_joining" DROP CONSTRAINT "FK_d844bfc6f3f523a05189076efaa"`); - await queryRunner.query(`ALTER TABLE "user_list" DROP CONSTRAINT "FK_b7fcefbdd1c18dce86687531f99"`); - await queryRunner.query(`ALTER TABLE "blocking" DROP CONSTRAINT "FK_0627125f1a8a42c9a1929edb552"`); - await queryRunner.query(`ALTER TABLE "blocking" DROP CONSTRAINT "FK_2cd4a2743a99671308f5417759e"`); - await queryRunner.query(`ALTER TABLE "sw_subscription" DROP CONSTRAINT "FK_97754ca6f2baff9b4abb7f853dd"`); - await queryRunner.query(`ALTER TABLE "muting" DROP CONSTRAINT "FK_93060675b4a79a577f31d260c67"`); - await queryRunner.query(`ALTER TABLE "muting" DROP CONSTRAINT "FK_ec96b4fed9dae517e0dbbe0675c"`); - await queryRunner.query(`ALTER TABLE "following" DROP CONSTRAINT "FK_6516c5a6f3c015b4eed39978be5"`); - await queryRunner.query(`ALTER TABLE "following" DROP CONSTRAINT "FK_24e0042143a18157b234df186c3"`); - await queryRunner.query(`ALTER TABLE "notification" DROP CONSTRAINT "FK_769cb6b73a1efe22ddf733ac453"`); - await queryRunner.query(`ALTER TABLE "notification" DROP CONSTRAINT "FK_3b4e96eec8d36a8bbb9d02aa710"`); - await queryRunner.query(`ALTER TABLE "notification" DROP CONSTRAINT "FK_3c601b70a1066d2c8b517094cb9"`); - await queryRunner.query(`ALTER TABLE "note_unread" DROP CONSTRAINT "FK_e637cba4dc4410218c4251260e4"`); - await queryRunner.query(`ALTER TABLE "note_unread" DROP CONSTRAINT "FK_56b0166d34ddae49d8ef7610bb9"`); - await queryRunner.query(`ALTER TABLE "note_watching" DROP CONSTRAINT "FK_03e7028ab8388a3f5e3ce2a8619"`); - await queryRunner.query(`ALTER TABLE "note_watching" DROP CONSTRAINT "FK_b0134ec406e8d09a540f8182888"`); - await queryRunner.query(`ALTER TABLE "note_reaction" DROP CONSTRAINT "FK_45145e4953780f3cd5656f0ea6a"`); - await queryRunner.query(`ALTER TABLE "note_reaction" DROP CONSTRAINT "FK_13761f64257f40c5636d0ff95ee"`); - await queryRunner.query(`ALTER TABLE "poll_vote" DROP CONSTRAINT "FK_aecfbd5ef60374918e63ee95fa7"`); - await queryRunner.query(`ALTER TABLE "poll_vote" DROP CONSTRAINT "FK_66d2bd2ee31d14bcc23069a89f8"`); - await queryRunner.query(`ALTER TABLE "note" DROP CONSTRAINT "FK_5b87d9d19127bd5d92026017a7b"`); - await queryRunner.query(`ALTER TABLE "note" DROP CONSTRAINT "FK_ec5c201576192ba8904c345c5cc"`); - await queryRunner.query(`ALTER TABLE "note" DROP CONSTRAINT "FK_52ccc804d7c69037d558bac4c96"`); - await queryRunner.query(`ALTER TABLE "note" DROP CONSTRAINT "FK_17cb3553c700a4985dff5a30ff5"`); - await queryRunner.query(`ALTER TABLE "access_token" DROP CONSTRAINT "FK_a3ff16c90cc87a82a0b5959e560"`); - await queryRunner.query(`ALTER TABLE "access_token" DROP CONSTRAINT "FK_9949557d0e1b2c19e5344c171e9"`); - await queryRunner.query(`ALTER TABLE "app" DROP CONSTRAINT "FK_3f5b0899ef90527a3462d7c2cb3"`); - await queryRunner.query(`ALTER TABLE "user" DROP CONSTRAINT "FK_afc64b53f8db3707ceb34eb28e2"`); - await queryRunner.query(`ALTER TABLE "user" DROP CONSTRAINT "FK_58f5c71eaab331645112cf8cfa5"`); - await queryRunner.query(`ALTER TABLE "drive_file" DROP CONSTRAINT "FK_bb90d1956dafc4068c28aa7560a"`); - await queryRunner.query(`ALTER TABLE "drive_file" DROP CONSTRAINT "FK_860fa6f6c7df5bb887249fba22e"`); - await queryRunner.query(`ALTER TABLE "drive_folder" DROP CONSTRAINT "FK_00ceffb0cdc238b3233294f08f2"`); - await queryRunner.query(`ALTER TABLE "drive_folder" DROP CONSTRAINT "FK_f4fc06e49c0171c85f1c48060d2"`); - await queryRunner.query(`DROP TABLE "__chart__users"`); - await queryRunner.query(`DROP TYPE "__chart__users_span_enum"`); - await queryRunner.query(`DROP TABLE "__chart__test"`); - await queryRunner.query(`DROP TYPE "__chart__test_span_enum"`); - await queryRunner.query(`DROP TABLE "__chart__test_unique"`); - await queryRunner.query(`DROP TYPE "__chart__test_unique_span_enum"`); - await queryRunner.query(`DROP TABLE "__chart__test_grouped"`); - await queryRunner.query(`DROP TYPE "__chart__test_grouped_span_enum"`); - await queryRunner.query(`DROP TABLE "__chart__per_user_reaction"`); - await queryRunner.query(`DROP TYPE "__chart__per_user_reaction_span_enum"`); - await queryRunner.query(`DROP TABLE "__chart__per_user_notes"`); - await queryRunner.query(`DROP TYPE "__chart__per_user_notes_span_enum"`); - await queryRunner.query(`DROP TABLE "__chart__per_user_following"`); - await queryRunner.query(`DROP TYPE "__chart__per_user_following_span_enum"`); - await queryRunner.query(`DROP TABLE "__chart__per_user_drive"`); - await queryRunner.query(`DROP TYPE "__chart__per_user_drive_span_enum"`); - await queryRunner.query(`DROP TABLE "__chart__notes"`); - await queryRunner.query(`DROP TYPE "__chart__notes_span_enum"`); - await queryRunner.query(`DROP TABLE "__chart__network"`); - await queryRunner.query(`DROP TYPE "__chart__network_span_enum"`); - await queryRunner.query(`DROP TABLE "__chart__instance"`); - await queryRunner.query(`DROP TYPE "__chart__instance_span_enum"`); - await queryRunner.query(`DROP TABLE "__chart__hashtag"`); - await queryRunner.query(`DROP TYPE "__chart__hashtag_span_enum"`); - await queryRunner.query(`DROP TABLE "__chart__federation"`); - await queryRunner.query(`DROP TYPE "__chart__federation_span_enum"`); - await queryRunner.query(`DROP TABLE "__chart__drive"`); - await queryRunner.query(`DROP TYPE "__chart__drive_span_enum"`); - await queryRunner.query(`DROP TABLE "__chart__active_users"`); - await queryRunner.query(`DROP TYPE "__chart__active_users_span_enum"`); - await queryRunner.query(`DROP INDEX "IDX_dce530b98e454793dac5ec2f5a"`); - await queryRunner.query(`DROP TABLE "user_profile"`); - await queryRunner.query(`DROP INDEX "IDX_171e64971c780ebd23fae140bb"`); - await queryRunner.query(`DROP TABLE "user_publickey"`); - await queryRunner.query(`DROP TABLE "user_keypair"`); - await queryRunner.query(`DROP INDEX "IDX_7fa20a12319c7f6dc3aed98c0a"`); - await queryRunner.query(`DROP INDEX "IDX_0610ebcfcfb4a18441a9bcdab2"`); - await queryRunner.query(`DROP TABLE "poll"`); - await queryRunner.query(`DROP TYPE "poll_notevisibility_enum"`); - await queryRunner.query(`DROP INDEX "IDX_410cd649884b501c02d6e72738"`); - await queryRunner.query(`DROP INDEX "IDX_bfbc6f79ba4007b4ce5097f08d"`); - await queryRunner.query(`DROP TABLE "user_note_pining"`); - await queryRunner.query(`DROP INDEX "IDX_e247b23a3c9b45f89ec1299d06"`); - await queryRunner.query(`DROP INDEX "IDX_3b25402709dd9882048c2bbade"`); - await queryRunner.query(`DROP INDEX "IDX_b604d92d6c7aec38627f6eaf16"`); - await queryRunner.query(`DROP TABLE "reversi_matching"`); - await queryRunner.query(`DROP INDEX "IDX_b46ec40746efceac604142be1c"`); - await queryRunner.query(`DROP TABLE "reversi_game"`); - await queryRunner.query(`DROP INDEX "IDX_4f4d35e1256c84ae3d1f0eab10"`); - await queryRunner.query(`DROP INDEX "IDX_5900e907bb46516ddf2871327c"`); - await queryRunner.query(`DROP INDEX "IDX_b37dafc86e9af007e3295c2781"`); - await queryRunner.query(`DROP TABLE "emoji"`); - await queryRunner.query(`DROP INDEX "IDX_d54a512b822fac7ed52800f6b4"`); - await queryRunner.query(`DROP INDEX "IDX_a7fd92dd6dc519e6fb435dd108"`); - await queryRunner.query(`DROP INDEX "IDX_12c01c0d1a79f77d9f6c15fadd"`); - await queryRunner.query(`DROP TABLE "follow_request"`); - await queryRunner.query(`DROP INDEX "IDX_62cb09e1129f6ec024ef66e183"`); - await queryRunner.query(`DROP TABLE "auth_session"`); - await queryRunner.query(`DROP INDEX "IDX_2c308dbdc50d94dc625670055f"`); - await queryRunner.query(`DROP TABLE "signin"`); - await queryRunner.query(`DROP INDEX "IDX_cac14a4e3944454a5ce7daa514"`); - await queryRunner.query(`DROP INDEX "IDX_5377c307783fce2b6d352e1203"`); - await queryRunner.query(`DROP INDEX "IDX_e21cd3646e52ef9c94aaf17c2e"`); - await queryRunner.query(`DROP TABLE "messaging_message"`); - await queryRunner.query(`DROP INDEX "IDX_0ff69e8dfa9fe31bb4a4660f59"`); - await queryRunner.query(`DROP TABLE "registration_ticket"`); - await queryRunner.query(`DROP INDEX "IDX_5cd442c3b2e74fdd99dae20243"`); - await queryRunner.query(`DROP INDEX "IDX_04cc96756f89d0b7f9473e8cdf"`); - await queryRunner.query(`DROP INDEX "IDX_d049123c413e68ca52abe73420"`); - await queryRunner.query(`DROP INDEX "IDX_db2098070b2b5a523c58181f74"`); - await queryRunner.query(`DROP TABLE "abuse_user_report"`); - await queryRunner.query(`DROP INDEX "IDX_0f4fb9ad355f3effff221ef245"`); - await queryRunner.query(`DROP INDEX "IDX_47f4b1892f5d6ba8efb3057d81"`); - await queryRunner.query(`DROP TABLE "note_favorite"`); - await queryRunner.query(`DROP INDEX "IDX_0b03cbcd7e6a7ce068efa8ecc2"`); - await queryRunner.query(`DROP INDEX "IDX_0c44bf4f680964145f2a68a341"`); - await queryRunner.query(`DROP INDEX "IDX_d57f9030cd3af7f63ffb1c267c"`); - await queryRunner.query(`DROP INDEX "IDX_4c02d38a976c3ae132228c6fce"`); - await queryRunner.query(`DROP INDEX "IDX_0e206cec573f1edff4a3062923"`); - await queryRunner.query(`DROP INDEX "IDX_2710a55f826ee236ea1a62698f"`); - await queryRunner.query(`DROP INDEX "IDX_347fec870eafea7b26c8a73bac"`); - await queryRunner.query(`DROP TABLE "hashtag"`); - await queryRunner.query(`DROP INDEX "IDX_605472305f26818cc93d1baaa7"`); - await queryRunner.query(`DROP INDEX "IDX_d844bfc6f3f523a05189076efa"`); - await queryRunner.query(`DROP TABLE "user_list_joining"`); - await queryRunner.query(`DROP INDEX "IDX_b7fcefbdd1c18dce86687531f9"`); - await queryRunner.query(`DROP TABLE "user_list"`); - await queryRunner.query(`DROP INDEX "IDX_98a1bc5cb30dfd159de056549f"`); - await queryRunner.query(`DROP INDEX "IDX_0627125f1a8a42c9a1929edb55"`); - await queryRunner.query(`DROP INDEX "IDX_2cd4a2743a99671308f5417759"`); - await queryRunner.query(`DROP INDEX "IDX_b9a354f7941c1e779f3b33aea6"`); - await queryRunner.query(`DROP TABLE "blocking"`); - await queryRunner.query(`DROP INDEX "IDX_97754ca6f2baff9b4abb7f853d"`); - await queryRunner.query(`DROP TABLE "sw_subscription"`); - await queryRunner.query(`DROP INDEX "IDX_1eb9d9824a630321a29fd3b290"`); - await queryRunner.query(`DROP INDEX "IDX_93060675b4a79a577f31d260c6"`); - await queryRunner.query(`DROP INDEX "IDX_ec96b4fed9dae517e0dbbe0675"`); - await queryRunner.query(`DROP INDEX "IDX_f86d57fbca33c7a4e6897490cc"`); - await queryRunner.query(`DROP TABLE "muting"`); - await queryRunner.query(`DROP INDEX "IDX_8d5afc98982185799b160e10eb"`); - await queryRunner.query(`DROP INDEX "IDX_2cd3b2a6b4cf0b910b260afe08"`); - await queryRunner.query(`DROP TABLE "instance"`); - await queryRunner.query(`DROP INDEX "IDX_307be5f1d1252e0388662acb96"`); - await queryRunner.query(`DROP INDEX "IDX_6516c5a6f3c015b4eed39978be"`); - await queryRunner.query(`DROP INDEX "IDX_24e0042143a18157b234df186c"`); - await queryRunner.query(`DROP INDEX "IDX_582f8fab771a9040a12961f3e7"`); - await queryRunner.query(`DROP TABLE "following"`); - await queryRunner.query(`DROP TABLE "meta"`); - await queryRunner.query(`DROP INDEX "IDX_3c601b70a1066d2c8b517094cb"`); - await queryRunner.query(`DROP INDEX "IDX_b11a5e627c41d4dc3170f1d370"`); - await queryRunner.query(`DROP TABLE "notification"`); - await queryRunner.query(`DROP INDEX "IDX_d908433a4953cc13216cd9c274"`); - await queryRunner.query(`DROP INDEX "IDX_e637cba4dc4410218c4251260e"`); - await queryRunner.query(`DROP INDEX "IDX_56b0166d34ddae49d8ef7610bb"`); - await queryRunner.query(`DROP TABLE "note_unread"`); - await queryRunner.query(`DROP INDEX "IDX_a42c93c69989ce1d09959df4cf"`); - await queryRunner.query(`DROP INDEX "IDX_44499765eec6b5489d72c4253b"`); - await queryRunner.query(`DROP INDEX "IDX_03e7028ab8388a3f5e3ce2a861"`); - await queryRunner.query(`DROP INDEX "IDX_b0134ec406e8d09a540f818288"`); - await queryRunner.query(`DROP INDEX "IDX_318cdf42a9cfc11f479bd802bb"`); - await queryRunner.query(`DROP TABLE "note_watching"`); - await queryRunner.query(`DROP INDEX "IDX_ad0c221b25672daf2df320a817"`); - await queryRunner.query(`DROP INDEX "IDX_45145e4953780f3cd5656f0ea6"`); - await queryRunner.query(`DROP INDEX "IDX_13761f64257f40c5636d0ff95e"`); - await queryRunner.query(`DROP INDEX "IDX_01f4581f114e0ebd2bbb876f0b"`); - await queryRunner.query(`DROP TABLE "note_reaction"`); - await queryRunner.query(`DROP INDEX "IDX_50bd7164c5b78f1f4a42c4d21f"`); - await queryRunner.query(`DROP INDEX "IDX_aecfbd5ef60374918e63ee95fa"`); - await queryRunner.query(`DROP INDEX "IDX_66d2bd2ee31d14bcc23069a89f"`); - await queryRunner.query(`DROP INDEX "IDX_0fb627e1c2f753262a74f0562d"`); - await queryRunner.query(`DROP TABLE "poll_vote"`); - await queryRunner.query(`DROP INDEX "IDX_7125a826ab192eb27e11d358a5"`); - await queryRunner.query(`DROP INDEX "IDX_88937d94d7443d9a99a76fa5c0"`); - await queryRunner.query(`DROP INDEX "IDX_54ebcb6d27222913b908d56fd8"`); - await queryRunner.query(`DROP INDEX "IDX_796a8c03959361f97dc2be1d5c"`); - await queryRunner.query(`DROP INDEX "IDX_25dfc71b0369b003a4cd434d0b"`); - await queryRunner.query(`DROP INDEX "IDX_51c063b6a133a9cb87145450f5"`); - await queryRunner.query(`DROP INDEX "IDX_153536c67d05e9adb24e99fc2b"`); - await queryRunner.query(`DROP INDEX "IDX_5b87d9d19127bd5d92026017a7"`); - await queryRunner.query(`DROP INDEX "IDX_52ccc804d7c69037d558bac4c9"`); - await queryRunner.query(`DROP INDEX "IDX_17cb3553c700a4985dff5a30ff"`); - await queryRunner.query(`DROP INDEX "IDX_e7c0567f5261063592f022e9b5"`); - await queryRunner.query(`DROP TABLE "note"`); - await queryRunner.query(`DROP TYPE "note_visibility_enum"`); - await queryRunner.query(`DROP INDEX "IDX_9949557d0e1b2c19e5344c171e"`); - await queryRunner.query(`DROP INDEX "IDX_64c327441248bae40f7d92f34f"`); - await queryRunner.query(`DROP INDEX "IDX_70ba8f6af34bc924fc9e12adb8"`); - await queryRunner.query(`DROP TABLE "access_token"`); - await queryRunner.query(`DROP INDEX "IDX_f49922d511d666848f250663c4"`); - await queryRunner.query(`DROP INDEX "IDX_3f5b0899ef90527a3462d7c2cb"`); - await queryRunner.query(`DROP INDEX "IDX_048a757923ed8b157e9895da53"`); - await queryRunner.query(`DROP TABLE "app"`); - await queryRunner.query(`DROP INDEX "IDX_5deb01ae162d1d70b80d064c27"`); - await queryRunner.query(`DROP INDEX "IDX_a854e557b1b14814750c7c7b0c"`); - await queryRunner.query(`DROP INDEX "IDX_be623adaa4c566baf5d29ce0c8"`); - await queryRunner.query(`DROP INDEX "IDX_3252a5df8d5bbd16b281f7799e"`); - await queryRunner.query(`DROP INDEX "IDX_fa99d777623947a5b05f394cae"`); - await queryRunner.query(`DROP INDEX "IDX_a27b942a0d6dcff90e3ee9b5e8"`); - await queryRunner.query(`DROP INDEX "IDX_80ca6e6ef65fb9ef34ea8c90f4"`); - await queryRunner.query(`DROP INDEX "IDX_e11e649824a45d8ed01d597fd9"`); - await queryRunner.query(`DROP TABLE "user"`); - await queryRunner.query(`DROP INDEX "IDX_bb90d1956dafc4068c28aa7560"`); - await queryRunner.query(`DROP INDEX "IDX_e5848eac4940934e23dbc17581"`); - await queryRunner.query(`DROP INDEX "IDX_c55b2b7c284d9fef98026fc88e"`); - await queryRunner.query(`DROP INDEX "IDX_e74022ce9a074b3866f70e0d27"`); - await queryRunner.query(`DROP INDEX "IDX_d85a184c2540d2deba33daf642"`); - await queryRunner.query(`DROP INDEX "IDX_a40b8df8c989d7db937ea27cf6"`); - await queryRunner.query(`DROP INDEX "IDX_37bb9a1b4585f8a3beb24c62d6"`); - await queryRunner.query(`DROP INDEX "IDX_92779627994ac79277f070c91e"`); - await queryRunner.query(`DROP INDEX "IDX_860fa6f6c7df5bb887249fba22"`); - await queryRunner.query(`DROP INDEX "IDX_c8dfad3b72196dd1d6b5db168a"`); - await queryRunner.query(`DROP TABLE "drive_file"`); - await queryRunner.query(`DROP INDEX "IDX_00ceffb0cdc238b3233294f08f"`); - await queryRunner.query(`DROP INDEX "IDX_f4fc06e49c0171c85f1c48060d"`); - await queryRunner.query(`DROP INDEX "IDX_02878d441ceae15ce060b73daf"`); - await queryRunner.query(`DROP TABLE "drive_folder"`); - await queryRunner.query(`DROP INDEX "IDX_584b536b49e53ac81beb39a177"`); - await queryRunner.query(`DROP INDEX "IDX_8cb40cfc8f3c28261e6f887b03"`); - await queryRunner.query(`DROP INDEX "IDX_8e4eb51a35d81b64dda28eed0a"`); - await queryRunner.query(`DROP TABLE "log"`); - await queryRunner.query(`DROP TYPE "log_level_enum"`); - } - -} diff --git a/migration/1556348509290-Pages.ts b/migration/1556348509290-Pages.ts deleted file mode 100644 index c44b4b1f7..000000000 --- a/migration/1556348509290-Pages.ts +++ /dev/null @@ -1,31 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class Pages1556348509290 implements MigrationInterface { - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE TYPE "page_visibility_enum" AS ENUM('public', 'followers', 'specified')`); - await queryRunner.query(`CREATE TABLE "page" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL, "title" character varying(256) NOT NULL, "name" character varying(256) NOT NULL, "summary" character varying(256), "alignCenter" boolean NOT NULL, "font" character varying(32) NOT NULL, "userId" character varying(32) NOT NULL, "eyeCatchingImageId" character varying(32), "content" jsonb NOT NULL DEFAULT '[]', "variables" jsonb NOT NULL DEFAULT '[]', "visibility" "page_visibility_enum" NOT NULL, "visibleUserIds" character varying(32) array NOT NULL DEFAULT '{}'::varchar[], CONSTRAINT "PK_742f4117e065c5b6ad21b37ba1f" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE INDEX "IDX_fbb4297c927a9b85e9cefa2eb1" ON "page" ("createdAt") `); - await queryRunner.query(`CREATE INDEX "IDX_af639b066dfbca78b01a920f8a" ON "page" ("updatedAt") `); - await queryRunner.query(`CREATE INDEX "IDX_b82c19c08afb292de4600d99e4" ON "page" ("name") `); - await queryRunner.query(`CREATE INDEX "IDX_ae1d917992dd0c9d9bbdad06c4" ON "page" ("userId") `); - await queryRunner.query(`CREATE INDEX "IDX_90148bbc2bf0854428786bfc15" ON "page" ("visibleUserIds") `); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_2133ef8317e4bdb839c0dcbf13" ON "page" ("userId", "name") `); - await queryRunner.query(`ALTER TABLE "page" ADD CONSTRAINT "FK_ae1d917992dd0c9d9bbdad06c4a" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "page" ADD CONSTRAINT "FK_3126dd7c502c9e4d7597ef7ef10" FOREIGN KEY ("eyeCatchingImageId") REFERENCES "drive_file"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "page" DROP CONSTRAINT "FK_3126dd7c502c9e4d7597ef7ef10"`); - await queryRunner.query(`ALTER TABLE "page" DROP CONSTRAINT "FK_ae1d917992dd0c9d9bbdad06c4a"`); - await queryRunner.query(`DROP INDEX "IDX_2133ef8317e4bdb839c0dcbf13"`); - await queryRunner.query(`DROP INDEX "IDX_90148bbc2bf0854428786bfc15"`); - await queryRunner.query(`DROP INDEX "IDX_ae1d917992dd0c9d9bbdad06c4"`); - await queryRunner.query(`DROP INDEX "IDX_b82c19c08afb292de4600d99e4"`); - await queryRunner.query(`DROP INDEX "IDX_af639b066dfbca78b01a920f8a"`); - await queryRunner.query(`DROP INDEX "IDX_fbb4297c927a9b85e9cefa2eb1"`); - await queryRunner.query(`DROP TABLE "page"`); - await queryRunner.query(`DROP TYPE "page_visibility_enum"`); - } - -} diff --git a/migration/1556746559567-UserProfile.ts b/migration/1556746559567-UserProfile.ts deleted file mode 100644 index 2dc7349cc..000000000 --- a/migration/1556746559567-UserProfile.ts +++ /dev/null @@ -1,16 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class UserProfile1556746559567 implements MigrationInterface { - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user_profile" ALTER COLUMN "githubId" TYPE VARCHAR(64) USING "githubId"::VARCHAR(64)`); - await queryRunner.query(`ALTER TABLE "user_profile" ALTER COLUMN "discordExpiresDate" TYPE VARCHAR(64) USING "discordExpiresDate"::VARCHAR(64)`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`UPDATE "user_profile" SET github = FALSE, discord = FALSE`); - await queryRunner.query(`ALTER TABLE "user_profile" ALTER COLUMN "githubId" TYPE INTEGER USING NULL`); - await queryRunner.query(`ALTER TABLE "user_profile" ALTER COLUMN "discordExpiresDate" TYPE INTEGER USING NULL`); - } - -} diff --git a/migration/1557476068003-PinnedUsers.ts b/migration/1557476068003-PinnedUsers.ts deleted file mode 100644 index 4e7222aaf..000000000 --- a/migration/1557476068003-PinnedUsers.ts +++ /dev/null @@ -1,13 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class PinnedUsers1557476068003 implements MigrationInterface { - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "meta" ADD "pinnedUsers" character varying(256) array NOT NULL DEFAULT '{}'::varchar[]`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "pinnedUsers"`); - } - -} diff --git a/migration/1557761316509-AddSomeUrls.ts b/migration/1557761316509-AddSomeUrls.ts deleted file mode 100644 index 926999de6..000000000 --- a/migration/1557761316509-AddSomeUrls.ts +++ /dev/null @@ -1,16 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class AddSomeUrls1557761316509 implements MigrationInterface { - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "meta" ADD "ToSUrl" character varying(512)`); - await queryRunner.query(`ALTER TABLE "meta" ADD "repositoryUrl" character varying(512) NOT NULL DEFAULT 'https://github.com/misskey-dev/misskey'`); - await queryRunner.query(`ALTER TABLE "meta" ADD "feedbackUrl" character varying(512) DEFAULT 'https://github.com/misskey-dev/misskey/issues/new'`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "feedbackUrl"`); - await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "repositoryUrl"`); - await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "ToSUrl"`); - } -} diff --git a/migration/1557932705754-ObjectStorageSetting.ts b/migration/1557932705754-ObjectStorageSetting.ts deleted file mode 100644 index dde6aa65f..000000000 --- a/migration/1557932705754-ObjectStorageSetting.ts +++ /dev/null @@ -1,31 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class ObjectStorageSetting1557932705754 implements MigrationInterface { - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "meta" ADD "useObjectStorage" boolean NOT NULL DEFAULT false`); - await queryRunner.query(`ALTER TABLE "meta" ADD "objectStorageBucket" character varying(512)`); - await queryRunner.query(`ALTER TABLE "meta" ADD "objectStoragePrefix" character varying(512)`); - await queryRunner.query(`ALTER TABLE "meta" ADD "objectStorageBaseUrl" character varying(512)`); - await queryRunner.query(`ALTER TABLE "meta" ADD "objectStorageEndpoint" character varying(512)`); - await queryRunner.query(`ALTER TABLE "meta" ADD "objectStorageRegion" character varying(512)`); - await queryRunner.query(`ALTER TABLE "meta" ADD "objectStorageAccessKey" character varying(512)`); - await queryRunner.query(`ALTER TABLE "meta" ADD "objectStorageSecretKey" character varying(512)`); - await queryRunner.query(`ALTER TABLE "meta" ADD "objectStoragePort" integer`); - await queryRunner.query(`ALTER TABLE "meta" ADD "objectStorageUseSSL" boolean NOT NULL DEFAULT true`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStorageUseSSL"`); - await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStoragePort"`); - await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStorageSecretKey"`); - await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStorageAccessKey"`); - await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStorageRegion"`); - await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStorageEndpoint"`); - await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStorageBaseUrl"`); - await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStoragePrefix"`); - await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStorageBucket"`); - await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "useObjectStorage"`); - } - -} diff --git a/migration/1558072954435-PageLike.ts b/migration/1558072954435-PageLike.ts deleted file mode 100644 index 93cdb8afe..000000000 --- a/migration/1558072954435-PageLike.ts +++ /dev/null @@ -1,23 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class PageLike1558072954435 implements MigrationInterface { - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE TABLE "page_like" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "pageId" character varying(32) NOT NULL, CONSTRAINT "PK_813f034843af992d3ae0f43c64c" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE INDEX "IDX_0e61efab7f88dbb79c9166dbb4" ON "page_like" ("userId") `); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_4ce6fb9c70529b4c8ac46c9bfa" ON "page_like" ("userId", "pageId") `); - await queryRunner.query(`ALTER TABLE "page" ADD "likedCount" integer NOT NULL DEFAULT 0`); - await queryRunner.query(`ALTER TABLE "page_like" ADD CONSTRAINT "FK_0e61efab7f88dbb79c9166dbb48" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "page_like" ADD CONSTRAINT "FK_cf8782626dced3176038176a847" FOREIGN KEY ("pageId") REFERENCES "page"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "page_like" DROP CONSTRAINT "FK_cf8782626dced3176038176a847"`); - await queryRunner.query(`ALTER TABLE "page_like" DROP CONSTRAINT "FK_0e61efab7f88dbb79c9166dbb48"`); - await queryRunner.query(`ALTER TABLE "page" DROP COLUMN "likedCount"`); - await queryRunner.query(`DROP INDEX "IDX_4ce6fb9c70529b4c8ac46c9bfa"`); - await queryRunner.query(`DROP INDEX "IDX_0e61efab7f88dbb79c9166dbb4"`); - await queryRunner.query(`DROP TABLE "page_like"`); - } - -} diff --git a/migration/1558103093633-UserGroup.ts b/migration/1558103093633-UserGroup.ts deleted file mode 100644 index 04783b8df..000000000 --- a/migration/1558103093633-UserGroup.ts +++ /dev/null @@ -1,41 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class UserGroup1558103093633 implements MigrationInterface { - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE TABLE "user_group" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "name" character varying(256) NOT NULL, "userId" character varying(32) NOT NULL, "isPrivate" boolean NOT NULL DEFAULT false, CONSTRAINT "PK_3c29fba6fe013ec8724378ce7c9" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE INDEX "IDX_20e30aa35180e317e133d75316" ON "user_group" ("createdAt") `); - await queryRunner.query(`CREATE INDEX "IDX_3d6b372788ab01be58853003c9" ON "user_group" ("userId") `); - await queryRunner.query(`CREATE TABLE "user_group_joining" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "userGroupId" character varying(32) NOT NULL, CONSTRAINT "PK_15f2425885253c5507e1599cfe7" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE INDEX "IDX_f3a1b4bd0c7cabba958a0c0b23" ON "user_group_joining" ("userId") `); - await queryRunner.query(`CREATE INDEX "IDX_67dc758bc0566985d1b3d39986" ON "user_group_joining" ("userGroupId") `); - await queryRunner.query(`ALTER TABLE "messaging_message" ADD "groupId" character varying(32)`); - await queryRunner.query(`ALTER TABLE "messaging_message" ADD "reads" character varying(32) array NOT NULL DEFAULT '{}'::varchar[]`); - await queryRunner.query(`ALTER TABLE "messaging_message" ALTER COLUMN "recipientId" DROP NOT NULL`); - await queryRunner.query(`COMMENT ON COLUMN "messaging_message"."recipientId" IS 'The recipient user ID.'`); - await queryRunner.query(`CREATE INDEX "IDX_2c4be03b446884f9e9c502135b" ON "messaging_message" ("groupId") `); - await queryRunner.query(`ALTER TABLE "messaging_message" ADD CONSTRAINT "FK_2c4be03b446884f9e9c502135be" FOREIGN KEY ("groupId") REFERENCES "user_group"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "user_group" ADD CONSTRAINT "FK_3d6b372788ab01be58853003c93" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "user_group_joining" ADD CONSTRAINT "FK_f3a1b4bd0c7cabba958a0c0b231" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "user_group_joining" ADD CONSTRAINT "FK_67dc758bc0566985d1b3d399865" FOREIGN KEY ("userGroupId") REFERENCES "user_group"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user_group_joining" DROP CONSTRAINT "FK_67dc758bc0566985d1b3d399865"`); - await queryRunner.query(`ALTER TABLE "user_group_joining" DROP CONSTRAINT "FK_f3a1b4bd0c7cabba958a0c0b231"`); - await queryRunner.query(`ALTER TABLE "user_group" DROP CONSTRAINT "FK_3d6b372788ab01be58853003c93"`); - await queryRunner.query(`ALTER TABLE "messaging_message" DROP CONSTRAINT "FK_2c4be03b446884f9e9c502135be"`); - await queryRunner.query(`DROP INDEX "IDX_2c4be03b446884f9e9c502135b"`); - await queryRunner.query(`COMMENT ON COLUMN "messaging_message"."recipientId" IS ''`); - await queryRunner.query(`ALTER TABLE "messaging_message" ALTER COLUMN "recipientId" SET NOT NULL`); - await queryRunner.query(`ALTER TABLE "messaging_message" DROP COLUMN "reads"`); - await queryRunner.query(`ALTER TABLE "messaging_message" DROP COLUMN "groupId"`); - await queryRunner.query(`DROP INDEX "IDX_67dc758bc0566985d1b3d39986"`); - await queryRunner.query(`DROP INDEX "IDX_f3a1b4bd0c7cabba958a0c0b23"`); - await queryRunner.query(`DROP TABLE "user_group_joining"`); - await queryRunner.query(`DROP INDEX "IDX_3d6b372788ab01be58853003c9"`); - await queryRunner.query(`DROP INDEX "IDX_20e30aa35180e317e133d75316"`); - await queryRunner.query(`DROP TABLE "user_group"`); - } - -} diff --git a/migration/1558257926829-UserGroupInvite.ts b/migration/1558257926829-UserGroupInvite.ts deleted file mode 100644 index a78e47922..000000000 --- a/migration/1558257926829-UserGroupInvite.ts +++ /dev/null @@ -1,25 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class UserGroupInvite1558257926829 implements MigrationInterface { - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE TABLE "user_group_invite" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "userGroupId" character varying(32) NOT NULL, CONSTRAINT "PK_3893884af0d3a5f4d01e7921a97" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE INDEX "IDX_1039988afa3bf991185b277fe0" ON "user_group_invite" ("userId") `); - await queryRunner.query(`CREATE INDEX "IDX_e10924607d058004304611a436" ON "user_group_invite" ("userGroupId") `); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_78787741f9010886796f2320a4" ON "user_group_invite" ("userId", "userGroupId") `); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_d9ecaed8c6dc43f3592c229282" ON "user_group_joining" ("userId", "userGroupId") `); - await queryRunner.query(`ALTER TABLE "user_group_invite" ADD CONSTRAINT "FK_1039988afa3bf991185b277fe03" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "user_group_invite" ADD CONSTRAINT "FK_e10924607d058004304611a436a" FOREIGN KEY ("userGroupId") REFERENCES "user_group"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user_group_invite" DROP CONSTRAINT "FK_e10924607d058004304611a436a"`); - await queryRunner.query(`ALTER TABLE "user_group_invite" DROP CONSTRAINT "FK_1039988afa3bf991185b277fe03"`); - await queryRunner.query(`DROP INDEX "IDX_d9ecaed8c6dc43f3592c229282"`); - await queryRunner.query(`DROP INDEX "IDX_78787741f9010886796f2320a4"`); - await queryRunner.query(`DROP INDEX "IDX_e10924607d058004304611a436"`); - await queryRunner.query(`DROP INDEX "IDX_1039988afa3bf991185b277fe0"`); - await queryRunner.query(`DROP TABLE "user_group_invite"`); - } - -} diff --git a/migration/1558266512381-UserListJoining.ts b/migration/1558266512381-UserListJoining.ts deleted file mode 100644 index f4a917045..000000000 --- a/migration/1558266512381-UserListJoining.ts +++ /dev/null @@ -1,13 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class UserListJoining1558266512381 implements MigrationInterface { - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_90f7da835e4c10aca6853621e1" ON "user_list_joining" ("userId", "userListId") `); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`DROP INDEX "IDX_90f7da835e4c10aca6853621e1"`); - } - -} diff --git a/migration/1561706992953-webauthn.ts b/migration/1561706992953-webauthn.ts deleted file mode 100644 index fc1f0c042..000000000 --- a/migration/1561706992953-webauthn.ts +++ /dev/null @@ -1,29 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class webauthn1561706992953 implements MigrationInterface { - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE TABLE "attestation_challenge" ("id" character varying(32) NOT NULL, "userId" character varying(32) NOT NULL, "challenge" character varying(64) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "registrationChallenge" boolean NOT NULL DEFAULT false, CONSTRAINT "PK_d0ba6786e093f1bcb497572a6b5" PRIMARY KEY ("id", "userId"))`); - await queryRunner.query(`CREATE INDEX "IDX_f1a461a618fa1755692d0e0d59" ON "attestation_challenge" ("userId") `); - await queryRunner.query(`CREATE INDEX "IDX_47efb914aed1f72dd39a306c7b" ON "attestation_challenge" ("challenge") `); - await queryRunner.query(`CREATE TABLE "user_security_key" ("id" character varying NOT NULL, "userId" character varying(32) NOT NULL, "publicKey" character varying NOT NULL, "lastUsed" TIMESTAMP WITH TIME ZONE NOT NULL, "name" character varying(30) NOT NULL, CONSTRAINT "PK_3e508571121ab39c5f85d10c166" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE INDEX "IDX_ff9ca3b5f3ee3d0681367a9b44" ON "user_security_key" ("userId") `); - await queryRunner.query(`CREATE INDEX "IDX_0d7718e562dcedd0aa5cf2c9f7" ON "user_security_key" ("publicKey") `); - await queryRunner.query(`ALTER TABLE "user_profile" ADD "securityKeysAvailable" boolean NOT NULL DEFAULT false`); - await queryRunner.query(`ALTER TABLE "attestation_challenge" ADD CONSTRAINT "FK_f1a461a618fa1755692d0e0d592" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "user_security_key" ADD CONSTRAINT "FK_ff9ca3b5f3ee3d0681367a9b447" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user_security_key" DROP CONSTRAINT "FK_ff9ca3b5f3ee3d0681367a9b447"`); - await queryRunner.query(`ALTER TABLE "attestation_challenge" DROP CONSTRAINT "FK_f1a461a618fa1755692d0e0d592"`); - await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "securityKeysAvailable"`); - await queryRunner.query(`DROP INDEX "IDX_0d7718e562dcedd0aa5cf2c9f7"`); - await queryRunner.query(`DROP INDEX "IDX_ff9ca3b5f3ee3d0681367a9b44"`); - await queryRunner.query(`DROP TABLE "user_security_key"`); - await queryRunner.query(`DROP INDEX "IDX_47efb914aed1f72dd39a306c7b"`); - await queryRunner.query(`DROP INDEX "IDX_f1a461a618fa1755692d0e0d59"`); - await queryRunner.query(`DROP TABLE "attestation_challenge"`); - } - -} diff --git a/migration/1561873850023-ChartIndexes.ts b/migration/1561873850023-ChartIndexes.ts deleted file mode 100644 index b870ad3b7..000000000 --- a/migration/1561873850023-ChartIndexes.ts +++ /dev/null @@ -1,201 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class ChartIndexes1561873850023 implements MigrationInterface { - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE INDEX "IDX_0ad37b7ef50f4ddc84363d7ccc" ON "__chart__active_users" ("date") `); - await queryRunner.query(`CREATE INDEX "IDX_15e91a03aeeac9dbccdf43fc06" ON "__chart__active_users" ("span") `); - await queryRunner.query(`CREATE INDEX "IDX_00ed5f86db1f7efafb1978bf21" ON "__chart__active_users" ("group") `); - await queryRunner.query(`CREATE INDEX "IDX_20f57cc8f142c131340ee16742" ON "__chart__active_users" ("span", "date") `); - await queryRunner.query(`CREATE INDEX "IDX_9a3ed15a30ab7e3a37702e6e08" ON "__chart__active_users" ("date", "group") `); - await queryRunner.query(`CREATE INDEX "IDX_c26e2c1cbb6e911e0554b27416" ON "__chart__active_users" ("span", "date", "group") `); - await queryRunner.query(`CREATE INDEX "IDX_13565815f618a1ff53886c5b28" ON "__chart__drive" ("date") `); - await queryRunner.query(`CREATE INDEX "IDX_3fa0d0f17ca72e3dc80999a032" ON "__chart__drive" ("span") `); - await queryRunner.query(`CREATE INDEX "IDX_7a170f67425e62a8fabb76c872" ON "__chart__drive" ("group") `); - await queryRunner.query(`CREATE INDEX "IDX_6e1df243476e20cbf86572ecc0" ON "__chart__drive" ("span", "date") `); - await queryRunner.query(`CREATE INDEX "IDX_3313d7288855ec105b5bbf6c21" ON "__chart__drive" ("date", "group") `); - await queryRunner.query(`CREATE INDEX "IDX_06690fc959f1c9fdaf21928222" ON "__chart__drive" ("span", "date", "group") `); - await queryRunner.query(`CREATE INDEX "IDX_36cb699c49580d4e6c2e6159f9" ON "__chart__federation" ("date") `); - await queryRunner.query(`CREATE INDEX "IDX_e447064455928cf627590ef527" ON "__chart__federation" ("span") `); - await queryRunner.query(`CREATE INDEX "IDX_76e87c7bfc5d925fcbba405d84" ON "__chart__federation" ("group") `); - await queryRunner.query(`CREATE INDEX "IDX_2d416e6af791a82e338c79d480" ON "__chart__federation" ("span", "date") `); - await queryRunner.query(`CREATE INDEX "IDX_dd907becf76104e4b656659e6b" ON "__chart__federation" ("date", "group") `); - await queryRunner.query(`CREATE INDEX "IDX_e9cd07672b37d8966cf3709283" ON "__chart__federation" ("span", "date", "group") `); - await queryRunner.query(`CREATE INDEX "IDX_07747a1038c05f532a718fe1de" ON "__chart__hashtag" ("date") `); - await queryRunner.query(`CREATE INDEX "IDX_fcc181fb8283009c61cc4083ef" ON "__chart__hashtag" ("span") `); - await queryRunner.query(`CREATE INDEX "IDX_99a7d2faaef84a6f728d714ad6" ON "__chart__hashtag" ("group") `); - await queryRunner.query(`CREATE INDEX "IDX_49975586f50ed7b800fdd88fbd" ON "__chart__hashtag" ("span", "date") `); - await queryRunner.query(`CREATE INDEX "IDX_25a97c02003338124b2b75fdbc" ON "__chart__hashtag" ("date", "group") `); - await queryRunner.query(`CREATE INDEX "IDX_6d6f156ceefc6bc5f273a0e370" ON "__chart__hashtag" ("span", "date", "group") `); - await queryRunner.query(`CREATE INDEX "IDX_6b8f34a1a64b06014b6fb66824" ON "__chart__instance" ("date") `); - await queryRunner.query(`CREATE INDEX "IDX_c12f0af4a66cdd30c2287ce8aa" ON "__chart__instance" ("span") `); - await queryRunner.query(`CREATE INDEX "IDX_da8a46ba84ca1d8bb5a29bfb63" ON "__chart__instance" ("group") `); - await queryRunner.query(`CREATE INDEX "IDX_d0a4f79af5a97b08f37b547197" ON "__chart__instance" ("span", "date") `); - await queryRunner.query(`CREATE INDEX "IDX_39ee857ab2f23493037c6b6631" ON "__chart__instance" ("date", "group") `); - await queryRunner.query(`CREATE INDEX "IDX_f5448d9633cff74208d850aabe" ON "__chart__instance" ("span", "date", "group") `); - await queryRunner.query(`CREATE INDEX "IDX_a1efd3e0048a5f2793a47360dc" ON "__chart__network" ("date") `); - await queryRunner.query(`CREATE INDEX "IDX_f8dd01baeded2ffa833e0a610a" ON "__chart__network" ("span") `); - await queryRunner.query(`CREATE INDEX "IDX_7b5da130992ec9df96712d4290" ON "__chart__network" ("group") `); - await queryRunner.query(`CREATE INDEX "IDX_08fac0eb3b11f04c200c0b40dd" ON "__chart__network" ("span", "date") `); - await queryRunner.query(`CREATE INDEX "IDX_0a905b992fecd2b5c3fb98759e" ON "__chart__network" ("date", "group") `); - await queryRunner.query(`CREATE INDEX "IDX_9ff6944f01acb756fdc92d7563" ON "__chart__network" ("span", "date", "group") `); - await queryRunner.query(`CREATE INDEX "IDX_42eb716a37d381cdf566192b2b" ON "__chart__notes" ("date") `); - await queryRunner.query(`CREATE INDEX "IDX_e69096589f11e3baa98ddd64d0" ON "__chart__notes" ("span") `); - await queryRunner.query(`CREATE INDEX "IDX_7036f2957151588b813185c794" ON "__chart__notes" ("group") `); - await queryRunner.query(`CREATE INDEX "IDX_0c9a159c5082cbeef3ca6706b5" ON "__chart__notes" ("span", "date") `); - await queryRunner.query(`CREATE INDEX "IDX_f09d543e3acb16c5976bdb31fa" ON "__chart__notes" ("date", "group") `); - await queryRunner.query(`CREATE INDEX "IDX_924fc196c80ca24bae01dd37e4" ON "__chart__notes" ("span", "date", "group") `); - await queryRunner.query(`CREATE INDEX "IDX_5f86db6492274e07c1a3cdf286" ON "__chart__per_user_drive" ("date") `); - await queryRunner.query(`CREATE INDEX "IDX_328f259961e60c4fa0bfcf55ca" ON "__chart__per_user_drive" ("span") `); - await queryRunner.query(`CREATE INDEX "IDX_e496ca8096d28f6b9b509264dc" ON "__chart__per_user_drive" ("group") `); - await queryRunner.query(`CREATE INDEX "IDX_42ea9381f0fda8dfe0fa1c8b53" ON "__chart__per_user_drive" ("span", "date") `); - await queryRunner.query(`CREATE INDEX "IDX_30bf67687f483ace115c5ca642" ON "__chart__per_user_drive" ("date", "group") `); - await queryRunner.query(`CREATE INDEX "IDX_f2aeafde2ae6fbad38e857631b" ON "__chart__per_user_drive" ("span", "date", "group") `); - await queryRunner.query(`CREATE INDEX "IDX_7af07790712aa3438ff6773f3b" ON "__chart__per_user_following" ("date") `); - await queryRunner.query(`CREATE INDEX "IDX_f92dd6d03f8d994f29987f6214" ON "__chart__per_user_following" ("span") `); - await queryRunner.query(`CREATE INDEX "IDX_4b3593098b6edc9c5afe36b18b" ON "__chart__per_user_following" ("group") `); - await queryRunner.query(`CREATE INDEX "IDX_57b5458d0d3d6d1e7f13d4e57f" ON "__chart__per_user_following" ("span", "date") `); - await queryRunner.query(`CREATE INDEX "IDX_b77d4dd9562c3a899d9a286fcd" ON "__chart__per_user_following" ("date", "group") `); - await queryRunner.query(`CREATE INDEX "IDX_4db3b84c7be0d3464714f3e0b1" ON "__chart__per_user_following" ("span", "date", "group") `); - await queryRunner.query(`CREATE INDEX "IDX_84234bd1abb873f07329681c83" ON "__chart__per_user_notes" ("date") `); - await queryRunner.query(`CREATE INDEX "IDX_8d2cbbc8114d90d19b44d626b6" ON "__chart__per_user_notes" ("span") `); - await queryRunner.query(`CREATE INDEX "IDX_55bf20f366979f2436de99206b" ON "__chart__per_user_notes" ("group") `); - await queryRunner.query(`CREATE INDEX "IDX_046feeb12e9ef5f783f409866a" ON "__chart__per_user_notes" ("span", "date") `); - await queryRunner.query(`CREATE INDEX "IDX_5048e9daccbbbc6d567bb142d3" ON "__chart__per_user_notes" ("date", "group") `); - await queryRunner.query(`CREATE INDEX "IDX_f68a5ab958f9f5fa17a32ac23b" ON "__chart__per_user_notes" ("span", "date", "group") `); - await queryRunner.query(`CREATE INDEX "IDX_f7bf4c62059764c2c2bb40fdab" ON "__chart__per_user_reaction" ("date") `); - await queryRunner.query(`CREATE INDEX "IDX_65633a106bce43fc7c5c30a5c7" ON "__chart__per_user_reaction" ("span") `); - await queryRunner.query(`CREATE INDEX "IDX_8cf3156fd7a6b15c43459c6e3b" ON "__chart__per_user_reaction" ("group") `); - await queryRunner.query(`CREATE INDEX "IDX_edeb73c09c3143a81bcb34d569" ON "__chart__per_user_reaction" ("span", "date") `); - await queryRunner.query(`CREATE INDEX "IDX_229a41ad465f9205f1f5703291" ON "__chart__per_user_reaction" ("date", "group") `); - await queryRunner.query(`CREATE INDEX "IDX_e316f01a6d24eb31db27f88262" ON "__chart__per_user_reaction" ("span", "date", "group") `); - await queryRunner.query(`CREATE INDEX "IDX_0c641990ecf47d2545df4edb75" ON "__chart__test_grouped" ("date") `); - await queryRunner.query(`CREATE INDEX "IDX_2be7ec6cebddc14dc11e206686" ON "__chart__test_grouped" ("span") `); - await queryRunner.query(`CREATE INDEX "IDX_234dff3c0b56a6150b95431ab9" ON "__chart__test_grouped" ("group") `); - await queryRunner.query(`CREATE INDEX "IDX_a5133470f4825902e170328ca5" ON "__chart__test_grouped" ("span", "date") `); - await queryRunner.query(`CREATE INDEX "IDX_b14489029e4b3aaf4bba5fb524" ON "__chart__test_grouped" ("date", "group") `); - await queryRunner.query(`CREATE INDEX "IDX_84e661abb7bd1e51b690d4b017" ON "__chart__test_grouped" ("span", "date", "group") `); - await queryRunner.query(`CREATE INDEX "IDX_437bab3c6061d90f6bb65fd2cc" ON "__chart__test_unique" ("date") `); - await queryRunner.query(`CREATE INDEX "IDX_5c73bf61da4f6e6f15bae88ed1" ON "__chart__test_unique" ("span") `); - await queryRunner.query(`CREATE INDEX "IDX_bbfa573a8181018851ed0b6357" ON "__chart__test_unique" ("group") `); - await queryRunner.query(`CREATE INDEX "IDX_d70c86baedc68326be11f9c0ce" ON "__chart__test_unique" ("span", "date") `); - await queryRunner.query(`CREATE INDEX "IDX_a0cd75442dd10d0643a17c4a49" ON "__chart__test_unique" ("date", "group") `); - await queryRunner.query(`CREATE INDEX "IDX_66e1e1ecd2f29e57778af35b59" ON "__chart__test_unique" ("span", "date", "group") `); - await queryRunner.query(`CREATE INDEX "IDX_b070a906db04b44c67c6c2144d" ON "__chart__test" ("date") `); - await queryRunner.query(`CREATE INDEX "IDX_92255988735563f0fe4aba1f05" ON "__chart__test" ("span") `); - await queryRunner.query(`CREATE INDEX "IDX_d41cce6aee1a50bfc062038f9b" ON "__chart__test" ("group") `); - await queryRunner.query(`CREATE INDEX "IDX_c5870993e25c3d5771f91f5003" ON "__chart__test" ("span", "date") `); - await queryRunner.query(`CREATE INDEX "IDX_a319e5dbf47e8a17497623beae" ON "__chart__test" ("date", "group") `); - await queryRunner.query(`CREATE INDEX "IDX_f170de677ea75ad4533de2723e" ON "__chart__test" ("span", "date", "group") `); - await queryRunner.query(`CREATE INDEX "IDX_845254b3eaf708ae8a6cac3026" ON "__chart__users" ("date") `); - await queryRunner.query(`CREATE INDEX "IDX_7c184198ecf66a8d3ecb253ab3" ON "__chart__users" ("span") `); - await queryRunner.query(`CREATE INDEX "IDX_ed9b95919c672a13008e9487ee" ON "__chart__users" ("group") `); - await queryRunner.query(`CREATE INDEX "IDX_f091abb24193d50c653c6b77fc" ON "__chart__users" ("span", "date") `); - await queryRunner.query(`CREATE INDEX "IDX_337e9599f278bd7537fe30876f" ON "__chart__users" ("date", "group") `); - await queryRunner.query(`CREATE INDEX "IDX_a770a57c70e668cc61590c9161" ON "__chart__users" ("span", "date", "group") `); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`DROP INDEX "IDX_a770a57c70e668cc61590c9161"`); - await queryRunner.query(`DROP INDEX "IDX_337e9599f278bd7537fe30876f"`); - await queryRunner.query(`DROP INDEX "IDX_f091abb24193d50c653c6b77fc"`); - await queryRunner.query(`DROP INDEX "IDX_ed9b95919c672a13008e9487ee"`); - await queryRunner.query(`DROP INDEX "IDX_7c184198ecf66a8d3ecb253ab3"`); - await queryRunner.query(`DROP INDEX "IDX_845254b3eaf708ae8a6cac3026"`); - await queryRunner.query(`DROP INDEX "IDX_f170de677ea75ad4533de2723e"`); - await queryRunner.query(`DROP INDEX "IDX_a319e5dbf47e8a17497623beae"`); - await queryRunner.query(`DROP INDEX "IDX_c5870993e25c3d5771f91f5003"`); - await queryRunner.query(`DROP INDEX "IDX_d41cce6aee1a50bfc062038f9b"`); - await queryRunner.query(`DROP INDEX "IDX_92255988735563f0fe4aba1f05"`); - await queryRunner.query(`DROP INDEX "IDX_b070a906db04b44c67c6c2144d"`); - await queryRunner.query(`DROP INDEX "IDX_66e1e1ecd2f29e57778af35b59"`); - await queryRunner.query(`DROP INDEX "IDX_a0cd75442dd10d0643a17c4a49"`); - await queryRunner.query(`DROP INDEX "IDX_d70c86baedc68326be11f9c0ce"`); - await queryRunner.query(`DROP INDEX "IDX_bbfa573a8181018851ed0b6357"`); - await queryRunner.query(`DROP INDEX "IDX_5c73bf61da4f6e6f15bae88ed1"`); - await queryRunner.query(`DROP INDEX "IDX_437bab3c6061d90f6bb65fd2cc"`); - await queryRunner.query(`DROP INDEX "IDX_84e661abb7bd1e51b690d4b017"`); - await queryRunner.query(`DROP INDEX "IDX_b14489029e4b3aaf4bba5fb524"`); - await queryRunner.query(`DROP INDEX "IDX_a5133470f4825902e170328ca5"`); - await queryRunner.query(`DROP INDEX "IDX_234dff3c0b56a6150b95431ab9"`); - await queryRunner.query(`DROP INDEX "IDX_2be7ec6cebddc14dc11e206686"`); - await queryRunner.query(`DROP INDEX "IDX_0c641990ecf47d2545df4edb75"`); - await queryRunner.query(`DROP INDEX "IDX_e316f01a6d24eb31db27f88262"`); - await queryRunner.query(`DROP INDEX "IDX_229a41ad465f9205f1f5703291"`); - await queryRunner.query(`DROP INDEX "IDX_edeb73c09c3143a81bcb34d569"`); - await queryRunner.query(`DROP INDEX "IDX_8cf3156fd7a6b15c43459c6e3b"`); - await queryRunner.query(`DROP INDEX "IDX_65633a106bce43fc7c5c30a5c7"`); - await queryRunner.query(`DROP INDEX "IDX_f7bf4c62059764c2c2bb40fdab"`); - await queryRunner.query(`DROP INDEX "IDX_f68a5ab958f9f5fa17a32ac23b"`); - await queryRunner.query(`DROP INDEX "IDX_5048e9daccbbbc6d567bb142d3"`); - await queryRunner.query(`DROP INDEX "IDX_046feeb12e9ef5f783f409866a"`); - await queryRunner.query(`DROP INDEX "IDX_55bf20f366979f2436de99206b"`); - await queryRunner.query(`DROP INDEX "IDX_8d2cbbc8114d90d19b44d626b6"`); - await queryRunner.query(`DROP INDEX "IDX_84234bd1abb873f07329681c83"`); - await queryRunner.query(`DROP INDEX "IDX_4db3b84c7be0d3464714f3e0b1"`); - await queryRunner.query(`DROP INDEX "IDX_b77d4dd9562c3a899d9a286fcd"`); - await queryRunner.query(`DROP INDEX "IDX_57b5458d0d3d6d1e7f13d4e57f"`); - await queryRunner.query(`DROP INDEX "IDX_4b3593098b6edc9c5afe36b18b"`); - await queryRunner.query(`DROP INDEX "IDX_f92dd6d03f8d994f29987f6214"`); - await queryRunner.query(`DROP INDEX "IDX_7af07790712aa3438ff6773f3b"`); - await queryRunner.query(`DROP INDEX "IDX_f2aeafde2ae6fbad38e857631b"`); - await queryRunner.query(`DROP INDEX "IDX_30bf67687f483ace115c5ca642"`); - await queryRunner.query(`DROP INDEX "IDX_42ea9381f0fda8dfe0fa1c8b53"`); - await queryRunner.query(`DROP INDEX "IDX_e496ca8096d28f6b9b509264dc"`); - await queryRunner.query(`DROP INDEX "IDX_328f259961e60c4fa0bfcf55ca"`); - await queryRunner.query(`DROP INDEX "IDX_5f86db6492274e07c1a3cdf286"`); - await queryRunner.query(`DROP INDEX "IDX_924fc196c80ca24bae01dd37e4"`); - await queryRunner.query(`DROP INDEX "IDX_f09d543e3acb16c5976bdb31fa"`); - await queryRunner.query(`DROP INDEX "IDX_0c9a159c5082cbeef3ca6706b5"`); - await queryRunner.query(`DROP INDEX "IDX_7036f2957151588b813185c794"`); - await queryRunner.query(`DROP INDEX "IDX_e69096589f11e3baa98ddd64d0"`); - await queryRunner.query(`DROP INDEX "IDX_42eb716a37d381cdf566192b2b"`); - await queryRunner.query(`DROP INDEX "IDX_9ff6944f01acb756fdc92d7563"`); - await queryRunner.query(`DROP INDEX "IDX_0a905b992fecd2b5c3fb98759e"`); - await queryRunner.query(`DROP INDEX "IDX_08fac0eb3b11f04c200c0b40dd"`); - await queryRunner.query(`DROP INDEX "IDX_7b5da130992ec9df96712d4290"`); - await queryRunner.query(`DROP INDEX "IDX_f8dd01baeded2ffa833e0a610a"`); - await queryRunner.query(`DROP INDEX "IDX_a1efd3e0048a5f2793a47360dc"`); - await queryRunner.query(`DROP INDEX "IDX_f5448d9633cff74208d850aabe"`); - await queryRunner.query(`DROP INDEX "IDX_39ee857ab2f23493037c6b6631"`); - await queryRunner.query(`DROP INDEX "IDX_d0a4f79af5a97b08f37b547197"`); - await queryRunner.query(`DROP INDEX "IDX_da8a46ba84ca1d8bb5a29bfb63"`); - await queryRunner.query(`DROP INDEX "IDX_c12f0af4a66cdd30c2287ce8aa"`); - await queryRunner.query(`DROP INDEX "IDX_6b8f34a1a64b06014b6fb66824"`); - await queryRunner.query(`DROP INDEX "IDX_6d6f156ceefc6bc5f273a0e370"`); - await queryRunner.query(`DROP INDEX "IDX_25a97c02003338124b2b75fdbc"`); - await queryRunner.query(`DROP INDEX "IDX_49975586f50ed7b800fdd88fbd"`); - await queryRunner.query(`DROP INDEX "IDX_99a7d2faaef84a6f728d714ad6"`); - await queryRunner.query(`DROP INDEX "IDX_fcc181fb8283009c61cc4083ef"`); - await queryRunner.query(`DROP INDEX "IDX_07747a1038c05f532a718fe1de"`); - await queryRunner.query(`DROP INDEX "IDX_e9cd07672b37d8966cf3709283"`); - await queryRunner.query(`DROP INDEX "IDX_dd907becf76104e4b656659e6b"`); - await queryRunner.query(`DROP INDEX "IDX_2d416e6af791a82e338c79d480"`); - await queryRunner.query(`DROP INDEX "IDX_76e87c7bfc5d925fcbba405d84"`); - await queryRunner.query(`DROP INDEX "IDX_e447064455928cf627590ef527"`); - await queryRunner.query(`DROP INDEX "IDX_36cb699c49580d4e6c2e6159f9"`); - await queryRunner.query(`DROP INDEX "IDX_06690fc959f1c9fdaf21928222"`); - await queryRunner.query(`DROP INDEX "IDX_3313d7288855ec105b5bbf6c21"`); - await queryRunner.query(`DROP INDEX "IDX_6e1df243476e20cbf86572ecc0"`); - await queryRunner.query(`DROP INDEX "IDX_7a170f67425e62a8fabb76c872"`); - await queryRunner.query(`DROP INDEX "IDX_3fa0d0f17ca72e3dc80999a032"`); - await queryRunner.query(`DROP INDEX "IDX_13565815f618a1ff53886c5b28"`); - await queryRunner.query(`DROP INDEX "IDX_c26e2c1cbb6e911e0554b27416"`); - await queryRunner.query(`DROP INDEX "IDX_9a3ed15a30ab7e3a37702e6e08"`); - await queryRunner.query(`DROP INDEX "IDX_20f57cc8f142c131340ee16742"`); - await queryRunner.query(`DROP INDEX "IDX_00ed5f86db1f7efafb1978bf21"`); - await queryRunner.query(`DROP INDEX "IDX_15e91a03aeeac9dbccdf43fc06"`); - await queryRunner.query(`DROP INDEX "IDX_0ad37b7ef50f4ddc84363d7ccc"`); - await queryRunner.query(`DROP INDEX "IDX_90148bbc2bf0854428786bfc15"`); - await queryRunner.query(`DROP INDEX "IDX_88937d94d7443d9a99a76fa5c0"`); - await queryRunner.query(`DROP INDEX "IDX_54ebcb6d27222913b908d56fd8"`); - await queryRunner.query(`DROP INDEX "IDX_796a8c03959361f97dc2be1d5c"`); - await queryRunner.query(`DROP INDEX "IDX_25dfc71b0369b003a4cd434d0b"`); - await queryRunner.query(`DROP INDEX "IDX_51c063b6a133a9cb87145450f5"`); - await queryRunner.query(`DROP INDEX "IDX_fa99d777623947a5b05f394cae"`); - await queryRunner.query(`DROP INDEX "IDX_315c779174fe8247ab324f036e"`); - await queryRunner.query(`DROP INDEX "IDX_c5d46cbfda48b1c33ed852e21b"`); - await queryRunner.query(`DROP INDEX "IDX_8cb40cfc8f3c28261e6f887b03"`); - } - -} diff --git a/migration/1562422242907-PasswordLessLogin.ts b/migration/1562422242907-PasswordLessLogin.ts deleted file mode 100644 index e789a3433..000000000 --- a/migration/1562422242907-PasswordLessLogin.ts +++ /dev/null @@ -1,13 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class PasswordLessLogin1562422242907 implements MigrationInterface { - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user_profile" ADD COLUMN "usePasswordLessLogin" boolean DEFAULT false NOT NULL`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "usePasswordLessLogin"`); - } - -} diff --git a/migration/1562444565093-PinnedPage.ts b/migration/1562444565093-PinnedPage.ts deleted file mode 100644 index 4bdee2274..000000000 --- a/migration/1562444565093-PinnedPage.ts +++ /dev/null @@ -1,17 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class PinnedPage1562444565093 implements MigrationInterface { - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user_profile" ADD "pinnedPageId" character varying(32)`); - await queryRunner.query(`ALTER TABLE "user_profile" ADD CONSTRAINT "UQ_6dc44f1ceb65b1e72bacef2ca27" UNIQUE ("pinnedPageId")`); - await queryRunner.query(`ALTER TABLE "user_profile" ADD CONSTRAINT "FK_6dc44f1ceb65b1e72bacef2ca27" FOREIGN KEY ("pinnedPageId") REFERENCES "page"("id") ON DELETE SET NULL ON UPDATE NO ACTION`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user_profile" DROP CONSTRAINT "FK_6dc44f1ceb65b1e72bacef2ca27"`); - await queryRunner.query(`ALTER TABLE "user_profile" DROP CONSTRAINT "UQ_6dc44f1ceb65b1e72bacef2ca27"`); - await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "pinnedPageId"`); - } - -} diff --git a/migration/1562448332510-PageTitleHideOption.ts b/migration/1562448332510-PageTitleHideOption.ts deleted file mode 100644 index acc9b7e26..000000000 --- a/migration/1562448332510-PageTitleHideOption.ts +++ /dev/null @@ -1,13 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class PageTitleHideOption1562448332510 implements MigrationInterface { - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "page" ADD "hideTitleWhenPinned" boolean NOT NULL DEFAULT false`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "page" DROP COLUMN "hideTitleWhenPinned"`); - } - -} diff --git a/migration/1562869971568-ModerationLog.ts b/migration/1562869971568-ModerationLog.ts deleted file mode 100644 index b37f38ee5..000000000 --- a/migration/1562869971568-ModerationLog.ts +++ /dev/null @@ -1,17 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class ModerationLog1562869971568 implements MigrationInterface { - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE TABLE "moderation_log" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "type" character varying(128) NOT NULL, "info" jsonb NOT NULL, CONSTRAINT "PK_d0adca6ecfd068db83e4526cc26" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE INDEX "IDX_a08ad074601d204e0f69da9a95" ON "moderation_log" ("userId") `); - await queryRunner.query(`ALTER TABLE "moderation_log" ADD CONSTRAINT "FK_a08ad074601d204e0f69da9a954" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "moderation_log" DROP CONSTRAINT "FK_a08ad074601d204e0f69da9a954"`); - await queryRunner.query(`DROP INDEX "IDX_a08ad074601d204e0f69da9a95"`); - await queryRunner.query(`DROP TABLE "moderation_log"`); - } - -} diff --git a/migration/1563757595828-UsedUsername.ts b/migration/1563757595828-UsedUsername.ts deleted file mode 100644 index a076fcc0c..000000000 --- a/migration/1563757595828-UsedUsername.ts +++ /dev/null @@ -1,13 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class UsedUsername1563757595828 implements MigrationInterface { - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE TABLE "used_username" ("username" character varying(128) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, CONSTRAINT "PK_78fd79d2d24c6ac2f4cc9a31a5d" PRIMARY KEY ("username"))`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`DROP TABLE "used_username"`); - } - -} diff --git a/migration/1565634203341-room.ts b/migration/1565634203341-room.ts deleted file mode 100644 index 783b375ff..000000000 --- a/migration/1565634203341-room.ts +++ /dev/null @@ -1,13 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class room1565634203341 implements MigrationInterface { - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user_profile" ADD "room" jsonb NOT NULL DEFAULT '{}'`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "room"`); - } - -} diff --git a/migration/1571220798684-CustomEmojiCategory.ts b/migration/1571220798684-CustomEmojiCategory.ts deleted file mode 100644 index 37f63fa3d..000000000 --- a/migration/1571220798684-CustomEmojiCategory.ts +++ /dev/null @@ -1,13 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class CustomEmojiCategory1571220798684 implements MigrationInterface { - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "emoji" ADD "category" character varying(128)`, undefined); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "emoji" DROP COLUMN "category"`, undefined); - } - -} diff --git a/migration/1572760203493-nodeinfo.ts b/migration/1572760203493-nodeinfo.ts deleted file mode 100644 index 88d8df723..000000000 --- a/migration/1572760203493-nodeinfo.ts +++ /dev/null @@ -1,29 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class nodeinfo1572760203493 implements MigrationInterface { - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "system"`, undefined); - await queryRunner.query(`ALTER TABLE "instance" ADD "softwareName" character varying(64) DEFAULT null`, undefined); - await queryRunner.query(`ALTER TABLE "instance" ADD "softwareVersion" character varying(64) DEFAULT null`, undefined); - await queryRunner.query(`ALTER TABLE "instance" ADD "openRegistrations" boolean DEFAULT null`, undefined); - await queryRunner.query(`ALTER TABLE "instance" ADD "name" character varying(256) DEFAULT null`, undefined); - await queryRunner.query(`ALTER TABLE "instance" ADD "description" character varying(4096) DEFAULT null`, undefined); - await queryRunner.query(`ALTER TABLE "instance" ADD "maintainerName" character varying(128) DEFAULT null`, undefined); - await queryRunner.query(`ALTER TABLE "instance" ADD "maintainerEmail" character varying(256) DEFAULT null`, undefined); - await queryRunner.query(`ALTER TABLE "instance" ADD "infoUpdatedAt" TIMESTAMP WITH TIME ZONE`, undefined); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "infoUpdatedAt"`, undefined); - await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "maintainerEmail"`, undefined); - await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "maintainerName"`, undefined); - await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "description"`, undefined); - await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "name"`, undefined); - await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "openRegistrations"`, undefined); - await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "softwareVersion"`, undefined); - await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "softwareName"`, undefined); - await queryRunner.query(`ALTER TABLE "instance" ADD "system" character varying(64)`, undefined); - } - -} diff --git a/migration/1576269851876-TalkFederationId.ts b/migration/1576269851876-TalkFederationId.ts deleted file mode 100644 index 57e86c8b0..000000000 --- a/migration/1576269851876-TalkFederationId.ts +++ /dev/null @@ -1,14 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class TalkFederationId1576269851876 implements MigrationInterface { - name = 'TalkFederationId1576269851876' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "messaging_message" ADD "uri" character varying(512)`, undefined); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "messaging_message" DROP COLUMN "uri"`, undefined); - } - -} diff --git a/migration/1576869585998-ProxyRemoteFiles.ts b/migration/1576869585998-ProxyRemoteFiles.ts deleted file mode 100644 index 1d15370bb..000000000 --- a/migration/1576869585998-ProxyRemoteFiles.ts +++ /dev/null @@ -1,14 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class ProxyRemoteFiles1576869585998 implements MigrationInterface { - name = 'ProxyRemoteFiles1576869585998' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "meta" ADD "proxyRemoteFiles" boolean NOT NULL DEFAULT false`, undefined); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "proxyRemoteFiles"`, undefined); - } - -} diff --git a/migration/1579267006611-v12.ts b/migration/1579267006611-v12.ts deleted file mode 100644 index 2c15283fa..000000000 --- a/migration/1579267006611-v12.ts +++ /dev/null @@ -1,34 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class v121579267006611 implements MigrationInterface { - name = 'v121579267006611' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE TABLE "announcement" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "text" character varying(8192) NOT NULL, "title" character varying(256) NOT NULL, "imageUrl" character varying(1024), CONSTRAINT "PK_e0ef0550174fd1099a308fd18a0" PRIMARY KEY ("id"))`, undefined); - await queryRunner.query(`CREATE INDEX "IDX_118ec703e596086fc4515acb39" ON "announcement" ("createdAt") `, undefined); - await queryRunner.query(`CREATE TABLE "announcement_read" ("id" character varying(32) NOT NULL, "userId" character varying(32) NOT NULL, "announcementId" character varying(32) NOT NULL, CONSTRAINT "PK_4b90ad1f42681d97b2683890c5e" PRIMARY KEY ("id"))`, undefined); - await queryRunner.query(`CREATE INDEX "IDX_8288151386172b8109f7239ab2" ON "announcement_read" ("userId") `, undefined); - await queryRunner.query(`CREATE INDEX "IDX_603a7b1e7aa0533c6c88e9bfaf" ON "announcement_read" ("announcementId") `, undefined); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_924fa71815cfa3941d003702a0" ON "announcement_read" ("userId", "announcementId") `, undefined); - await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "isVerified"`, undefined); - await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "announcements"`, undefined); - await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "enableEmojiReaction"`, undefined); - await queryRunner.query(`ALTER TABLE "announcement_read" ADD CONSTRAINT "FK_8288151386172b8109f7239ab28" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined); - await queryRunner.query(`ALTER TABLE "announcement_read" ADD CONSTRAINT "FK_603a7b1e7aa0533c6c88e9bfafe" FOREIGN KEY ("announcementId") REFERENCES "announcement"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "announcement_read" DROP CONSTRAINT "FK_603a7b1e7aa0533c6c88e9bfafe"`, undefined); - await queryRunner.query(`ALTER TABLE "announcement_read" DROP CONSTRAINT "FK_8288151386172b8109f7239ab28"`, undefined); - await queryRunner.query(`ALTER TABLE "meta" ADD "enableEmojiReaction" boolean NOT NULL DEFAULT true`, undefined); - await queryRunner.query(`ALTER TABLE "meta" ADD "announcements" jsonb NOT NULL DEFAULT '[]'`, undefined); - await queryRunner.query(`ALTER TABLE "user" ADD "isVerified" boolean NOT NULL DEFAULT false`, undefined); - await queryRunner.query(`DROP INDEX "IDX_924fa71815cfa3941d003702a0"`, undefined); - await queryRunner.query(`DROP INDEX "IDX_603a7b1e7aa0533c6c88e9bfaf"`, undefined); - await queryRunner.query(`DROP INDEX "IDX_8288151386172b8109f7239ab2"`, undefined); - await queryRunner.query(`DROP TABLE "announcement_read"`, undefined); - await queryRunner.query(`DROP INDEX "IDX_118ec703e596086fc4515acb39"`, undefined); - await queryRunner.query(`DROP TABLE "announcement"`, undefined); - } - -} diff --git a/migration/1579270193251-v12-2.ts b/migration/1579270193251-v12-2.ts deleted file mode 100644 index efad0cd56..000000000 --- a/migration/1579270193251-v12-2.ts +++ /dev/null @@ -1,14 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class v1221579270193251 implements MigrationInterface { - name = 'v1221579270193251' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "announcement_read" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`, undefined); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "announcement_read" DROP COLUMN "createdAt"`, undefined); - } - -} diff --git a/migration/1579282808087-v12-3.ts b/migration/1579282808087-v12-3.ts deleted file mode 100644 index a330caa97..000000000 --- a/migration/1579282808087-v12-3.ts +++ /dev/null @@ -1,14 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class v1231579282808087 implements MigrationInterface { - name = 'v1231579282808087' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "announcement" ADD "updatedAt" TIMESTAMP WITH TIME ZONE`, undefined); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "announcement" DROP COLUMN "updatedAt"`, undefined); - } - -} diff --git a/migration/1579544426412-v12-4.ts b/migration/1579544426412-v12-4.ts deleted file mode 100644 index d35b25d04..000000000 --- a/migration/1579544426412-v12-4.ts +++ /dev/null @@ -1,16 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class v1241579544426412 implements MigrationInterface { - name = 'v1241579544426412' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "notification" ADD "followRequestId" character varying(32)`, undefined); - await queryRunner.query(`ALTER TABLE "notification" ADD CONSTRAINT "FK_bd7fab507621e635b32cd31892c" FOREIGN KEY ("followRequestId") REFERENCES "follow_request"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "notification" DROP CONSTRAINT "FK_bd7fab507621e635b32cd31892c"`, undefined); - await queryRunner.query(`ALTER TABLE "notification" DROP COLUMN "followRequestId"`, undefined); - } - -} diff --git a/migration/1579977526288-v12-5.ts b/migration/1579977526288-v12-5.ts deleted file mode 100644 index 5f824a676..000000000 --- a/migration/1579977526288-v12-5.ts +++ /dev/null @@ -1,54 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class v1251579977526288 implements MigrationInterface { - name = 'v1251579977526288' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE TABLE "clip" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "name" character varying(128) NOT NULL, "isPublic" boolean NOT NULL DEFAULT false, CONSTRAINT "PK_f0685dac8d4dd056d7255670b75" PRIMARY KEY ("id"))`, undefined); - await queryRunner.query(`CREATE INDEX "IDX_2b5ec6c574d6802c94c80313fb" ON "clip" ("userId") `, undefined); - await queryRunner.query(`CREATE TABLE "clip_note" ("id" character varying(32) NOT NULL, "noteId" character varying(32) NOT NULL, "clipId" character varying(32) NOT NULL, CONSTRAINT "PK_e94cda2f40a99b57e032a1a738b" PRIMARY KEY ("id"))`, undefined); - await queryRunner.query(`CREATE INDEX "IDX_a012eaf5c87c65da1deb5fdbfa" ON "clip_note" ("noteId") `, undefined); - await queryRunner.query(`CREATE INDEX "IDX_ebe99317bbbe9968a0c6f579ad" ON "clip_note" ("clipId") `, undefined); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_6fc0ec357d55a18646262fdfff" ON "clip_note" ("noteId", "clipId") `, undefined); - await queryRunner.query(`CREATE TYPE "antenna_src_enum" AS ENUM('home', 'all', 'list')`, undefined); - await queryRunner.query(`CREATE TABLE "antenna" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "name" character varying(128) NOT NULL, "src" "antenna_src_enum" NOT NULL, "userListId" character varying(32), "keywords" jsonb NOT NULL DEFAULT '[]', "withFile" boolean NOT NULL, "expression" character varying(2048), "notify" boolean NOT NULL, "hasNewNote" boolean NOT NULL DEFAULT false, CONSTRAINT "PK_c170b99775e1dccca947c9f2d5f" PRIMARY KEY ("id"))`, undefined); - await queryRunner.query(`CREATE INDEX "IDX_6446c571a0e8d0f05f01c78909" ON "antenna" ("userId") `, undefined); - await queryRunner.query(`CREATE TABLE "antenna_note" ("id" character varying(32) NOT NULL, "noteId" character varying(32) NOT NULL, "antennaId" character varying(32) NOT NULL, CONSTRAINT "PK_fb28d94d0989a3872df19fd6ef8" PRIMARY KEY ("id"))`, undefined); - await queryRunner.query(`CREATE INDEX "IDX_bd0397be22147e17210940e125" ON "antenna_note" ("noteId") `, undefined); - await queryRunner.query(`CREATE INDEX "IDX_0d775946662d2575dfd2068a5f" ON "antenna_note" ("antennaId") `, undefined); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_335a0bf3f904406f9ef3dd51c2" ON "antenna_note" ("noteId", "antennaId") `, undefined); - await queryRunner.query(`ALTER TABLE "note" DROP COLUMN "geo"`, undefined); - await queryRunner.query(`ALTER TABLE "clip" ADD CONSTRAINT "FK_2b5ec6c574d6802c94c80313fb2" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined); - await queryRunner.query(`ALTER TABLE "clip_note" ADD CONSTRAINT "FK_a012eaf5c87c65da1deb5fdbfa3" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined); - await queryRunner.query(`ALTER TABLE "clip_note" ADD CONSTRAINT "FK_ebe99317bbbe9968a0c6f579adf" FOREIGN KEY ("clipId") REFERENCES "clip"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined); - await queryRunner.query(`ALTER TABLE "antenna" ADD CONSTRAINT "FK_6446c571a0e8d0f05f01c789096" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined); - await queryRunner.query(`ALTER TABLE "antenna" ADD CONSTRAINT "FK_709d7d32053d0dd7620f678eeb9" FOREIGN KEY ("userListId") REFERENCES "user_list"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined); - await queryRunner.query(`ALTER TABLE "antenna_note" ADD CONSTRAINT "FK_bd0397be22147e17210940e125b" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined); - await queryRunner.query(`ALTER TABLE "antenna_note" ADD CONSTRAINT "FK_0d775946662d2575dfd2068a5f5" FOREIGN KEY ("antennaId") REFERENCES "antenna"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "antenna_note" DROP CONSTRAINT "FK_0d775946662d2575dfd2068a5f5"`, undefined); - await queryRunner.query(`ALTER TABLE "antenna_note" DROP CONSTRAINT "FK_bd0397be22147e17210940e125b"`, undefined); - await queryRunner.query(`ALTER TABLE "antenna" DROP CONSTRAINT "FK_709d7d32053d0dd7620f678eeb9"`, undefined); - await queryRunner.query(`ALTER TABLE "antenna" DROP CONSTRAINT "FK_6446c571a0e8d0f05f01c789096"`, undefined); - await queryRunner.query(`ALTER TABLE "clip_note" DROP CONSTRAINT "FK_ebe99317bbbe9968a0c6f579adf"`, undefined); - await queryRunner.query(`ALTER TABLE "clip_note" DROP CONSTRAINT "FK_a012eaf5c87c65da1deb5fdbfa3"`, undefined); - await queryRunner.query(`ALTER TABLE "clip" DROP CONSTRAINT "FK_2b5ec6c574d6802c94c80313fb2"`, undefined); - await queryRunner.query(`ALTER TABLE "note" ADD "geo" jsonb`, undefined); - await queryRunner.query(`DROP INDEX "IDX_335a0bf3f904406f9ef3dd51c2"`, undefined); - await queryRunner.query(`DROP INDEX "IDX_0d775946662d2575dfd2068a5f"`, undefined); - await queryRunner.query(`DROP INDEX "IDX_bd0397be22147e17210940e125"`, undefined); - await queryRunner.query(`DROP TABLE "antenna_note"`, undefined); - await queryRunner.query(`DROP INDEX "IDX_6446c571a0e8d0f05f01c78909"`, undefined); - await queryRunner.query(`DROP TABLE "antenna"`, undefined); - await queryRunner.query(`DROP TYPE "antenna_src_enum"`, undefined); - await queryRunner.query(`DROP INDEX "IDX_6fc0ec357d55a18646262fdfff"`, undefined); - await queryRunner.query(`DROP INDEX "IDX_ebe99317bbbe9968a0c6f579ad"`, undefined); - await queryRunner.query(`DROP INDEX "IDX_a012eaf5c87c65da1deb5fdbfa"`, undefined); - await queryRunner.query(`DROP TABLE "clip_note"`, undefined); - await queryRunner.query(`DROP INDEX "IDX_2b5ec6c574d6802c94c80313fb"`, undefined); - await queryRunner.query(`DROP TABLE "clip"`, undefined); - } - -} diff --git a/migration/1579993013959-v12-6.ts b/migration/1579993013959-v12-6.ts deleted file mode 100644 index 4fa4623c3..000000000 --- a/migration/1579993013959-v12-6.ts +++ /dev/null @@ -1,18 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class v1261579993013959 implements MigrationInterface { - name = 'v1261579993013959' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "antenna" DROP COLUMN "hasNewNote"`, undefined); - await queryRunner.query(`ALTER TABLE "antenna_note" ADD "read" boolean NOT NULL DEFAULT false`, undefined); - await queryRunner.query(`CREATE INDEX "IDX_9937ea48d7ae97ffb4f3f063a4" ON "antenna_note" ("read") `, undefined); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`DROP INDEX "IDX_9937ea48d7ae97ffb4f3f063a4"`, undefined); - await queryRunner.query(`ALTER TABLE "antenna_note" DROP COLUMN "read"`, undefined); - await queryRunner.query(`ALTER TABLE "antenna" ADD "hasNewNote" boolean NOT NULL DEFAULT false`, undefined); - } - -} diff --git a/migration/1580069531114-v12-7.ts b/migration/1580069531114-v12-7.ts deleted file mode 100644 index 227e7cceb..000000000 --- a/migration/1580069531114-v12-7.ts +++ /dev/null @@ -1,24 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class v1271580069531114 implements MigrationInterface { - name = 'v1271580069531114' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "antenna" ADD "users" character varying(1024) array NOT NULL DEFAULT '{}'::varchar[]`, undefined); - await queryRunner.query(`ALTER TABLE "antenna" ADD "caseSensitive" boolean NOT NULL DEFAULT false`, undefined); - await queryRunner.query(`ALTER TYPE "public"."antenna_src_enum" RENAME TO "antenna_src_enum_old"`, undefined); - await queryRunner.query(`CREATE TYPE "antenna_src_enum" AS ENUM('home', 'all', 'users', 'list')`, undefined); - await queryRunner.query(`ALTER TABLE "antenna" ALTER COLUMN "src" TYPE "antenna_src_enum" USING "src"::"text"::"antenna_src_enum"`, undefined); - await queryRunner.query(`DROP TYPE "antenna_src_enum_old"`, undefined); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE TYPE "antenna_src_enum_old" AS ENUM('home', 'all', 'list')`, undefined); - await queryRunner.query(`ALTER TABLE "antenna" ALTER COLUMN "src" TYPE "antenna_src_enum_old" USING "src"::"text"::"antenna_src_enum_old"`, undefined); - await queryRunner.query(`DROP TYPE "antenna_src_enum"`, undefined); - await queryRunner.query(`ALTER TYPE "antenna_src_enum_old" RENAME TO "antenna_src_enum"`, undefined); - await queryRunner.query(`ALTER TABLE "antenna" DROP COLUMN "caseSensitive"`, undefined); - await queryRunner.query(`ALTER TABLE "antenna" DROP COLUMN "users"`, undefined); - } - -} diff --git a/migration/1580148575182-v12-8.ts b/migration/1580148575182-v12-8.ts deleted file mode 100644 index c63bdb4eb..000000000 --- a/migration/1580148575182-v12-8.ts +++ /dev/null @@ -1,16 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class v1281580148575182 implements MigrationInterface { - name = 'v1281580148575182' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "note" DROP CONSTRAINT "FK_ec5c201576192ba8904c345c5cc"`, undefined); - await queryRunner.query(`ALTER TABLE "note" DROP COLUMN "appId"`, undefined); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "note" ADD "appId" character varying(32)`, undefined); - await queryRunner.query(`ALTER TABLE "note" ADD CONSTRAINT "FK_ec5c201576192ba8904c345c5cc" FOREIGN KEY ("appId") REFERENCES "app"("id") ON DELETE SET NULL ON UPDATE NO ACTION`, undefined); - } - -} diff --git a/migration/1580154400017-v12-9.ts b/migration/1580154400017-v12-9.ts deleted file mode 100644 index de06d26e4..000000000 --- a/migration/1580154400017-v12-9.ts +++ /dev/null @@ -1,14 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class v1291580154400017 implements MigrationInterface { - name = 'v1291580154400017' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "antenna" ADD "withReplies" boolean NOT NULL DEFAULT false`, undefined); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "antenna" DROP COLUMN "withReplies"`, undefined); - } - -} diff --git a/migration/1580276619901-v12-10.ts b/migration/1580276619901-v12-10.ts deleted file mode 100644 index f48f42b4a..000000000 --- a/migration/1580276619901-v12-10.ts +++ /dev/null @@ -1,19 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class v12101580276619901 implements MigrationInterface { - name = 'v12101580276619901' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`TRUNCATE TABLE "notification"`, undefined); - await queryRunner.query(`ALTER TABLE "notification" DROP COLUMN "type"`, undefined); - await queryRunner.query(`CREATE TYPE "notification_type_enum" AS ENUM('follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'receiveFollowRequest', 'followRequestAccepted')`, undefined); - await queryRunner.query(`ALTER TABLE "notification" ADD "type" "notification_type_enum" NOT NULL`, undefined); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "notification" DROP COLUMN "type"`, undefined); - await queryRunner.query(`DROP TYPE "notification_type_enum"`, undefined); - await queryRunner.query(`ALTER TABLE "notification" ADD "type" character varying(32) NOT NULL`, undefined); - } - -} diff --git a/migration/1580331224276-v12-11.ts b/migration/1580331224276-v12-11.ts deleted file mode 100644 index 30794b80e..000000000 --- a/migration/1580331224276-v12-11.ts +++ /dev/null @@ -1,18 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class v12111580331224276 implements MigrationInterface { - name = 'v12111580331224276' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "isMarkedAsClosed"`, undefined); - await queryRunner.query(`ALTER TABLE "instance" ADD "isSuspended" boolean NOT NULL DEFAULT false`, undefined); - await queryRunner.query(`CREATE INDEX "IDX_34500da2e38ac393f7bb6b299c" ON "instance" ("isSuspended") `, undefined); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`DROP INDEX "IDX_34500da2e38ac393f7bb6b299c"`, undefined); - await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "isSuspended"`, undefined); - await queryRunner.query(`ALTER TABLE "instance" ADD "isMarkedAsClosed" boolean NOT NULL DEFAULT false`, undefined); - } - -} diff --git a/migration/1580508795118-v12-12.ts b/migration/1580508795118-v12-12.ts deleted file mode 100644 index 99791b051..000000000 --- a/migration/1580508795118-v12-12.ts +++ /dev/null @@ -1,46 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class v12121580508795118 implements MigrationInterface { - name = 'v12121580508795118' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "twitter"`, undefined); - await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "twitterAccessToken"`, undefined); - await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "twitterAccessTokenSecret"`, undefined); - await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "twitterUserId"`, undefined); - await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "twitterScreenName"`, undefined); - await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "github"`, undefined); - await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "githubAccessToken"`, undefined); - await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "githubId"`, undefined); - await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "githubLogin"`, undefined); - await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "discord"`, undefined); - await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "discordAccessToken"`, undefined); - await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "discordRefreshToken"`, undefined); - await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "discordExpiresDate"`, undefined); - await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "discordId"`, undefined); - await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "discordUsername"`, undefined); - await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "discordDiscriminator"`, undefined); - await queryRunner.query(`ALTER TABLE "user_profile" ADD "integrations" jsonb NOT NULL DEFAULT '{}'`, undefined); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "integrations"`, undefined); - await queryRunner.query(`ALTER TABLE "user_profile" ADD "discordDiscriminator" character varying(64) DEFAULT NULL`, undefined); - await queryRunner.query(`ALTER TABLE "user_profile" ADD "discordUsername" character varying(64) DEFAULT NULL`, undefined); - await queryRunner.query(`ALTER TABLE "user_profile" ADD "discordId" character varying(64) DEFAULT NULL`, undefined); - await queryRunner.query(`ALTER TABLE "user_profile" ADD "discordExpiresDate" character varying(64)`, undefined); - await queryRunner.query(`ALTER TABLE "user_profile" ADD "discordRefreshToken" character varying(64) DEFAULT NULL`, undefined); - await queryRunner.query(`ALTER TABLE "user_profile" ADD "discordAccessToken" character varying(64) DEFAULT NULL`, undefined); - await queryRunner.query(`ALTER TABLE "user_profile" ADD "discord" boolean NOT NULL DEFAULT false`, undefined); - await queryRunner.query(`ALTER TABLE "user_profile" ADD "githubLogin" character varying(64) DEFAULT NULL`, undefined); - await queryRunner.query(`ALTER TABLE "user_profile" ADD "githubId" character varying(64)`, undefined); - await queryRunner.query(`ALTER TABLE "user_profile" ADD "githubAccessToken" character varying(64) DEFAULT NULL`, undefined); - await queryRunner.query(`ALTER TABLE "user_profile" ADD "github" boolean NOT NULL DEFAULT false`, undefined); - await queryRunner.query(`ALTER TABLE "user_profile" ADD "twitterScreenName" character varying(64) DEFAULT NULL`, undefined); - await queryRunner.query(`ALTER TABLE "user_profile" ADD "twitterUserId" character varying(64) DEFAULT NULL`, undefined); - await queryRunner.query(`ALTER TABLE "user_profile" ADD "twitterAccessTokenSecret" character varying(64) DEFAULT NULL`, undefined); - await queryRunner.query(`ALTER TABLE "user_profile" ADD "twitterAccessToken" character varying(64) DEFAULT NULL`, undefined); - await queryRunner.query(`ALTER TABLE "user_profile" ADD "twitter" boolean NOT NULL DEFAULT false`, undefined); - } - -} diff --git a/migration/1580543501339-v12-13.ts b/migration/1580543501339-v12-13.ts deleted file mode 100644 index 7f5d8b803..000000000 --- a/migration/1580543501339-v12-13.ts +++ /dev/null @@ -1,14 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class v12131580543501339 implements MigrationInterface { - name = 'v12131580543501339' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE INDEX "IDX_NOTE_TAGS" ON "note" USING gin ("tags")`, undefined); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`DROP INDEX "IDX_NOTE_TAGS"`, undefined); - } - -} diff --git a/migration/1580864313253-v12-14.ts b/migration/1580864313253-v12-14.ts deleted file mode 100644 index 7bf38e5c6..000000000 --- a/migration/1580864313253-v12-14.ts +++ /dev/null @@ -1,20 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class v12141580864313253 implements MigrationInterface { - name = 'v12141580864313253' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "meta" RENAME COLUMN "proxyAccount" TO "proxyAccountId"`, undefined); - await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "proxyAccountId"`, undefined); - await queryRunner.query(`ALTER TABLE "meta" ADD "proxyAccountId" character varying(32)`, undefined); - await queryRunner.query(`ALTER TABLE "meta" ADD CONSTRAINT "FK_ab1bc0c1e209daa77b8e8d212ad" FOREIGN KEY ("proxyAccountId") REFERENCES "user"("id") ON DELETE SET NULL ON UPDATE NO ACTION`, undefined); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "meta" DROP CONSTRAINT "FK_ab1bc0c1e209daa77b8e8d212ad"`, undefined); - await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "proxyAccountId"`, undefined); - await queryRunner.query(`ALTER TABLE "meta" ADD "proxyAccountId" character varying(128)`, undefined); - await queryRunner.query(`ALTER TABLE "meta" RENAME COLUMN "proxyAccountId" TO "proxyAccount"`, undefined); - } - -} diff --git a/migration/1581526429287-user-group-invitation.ts b/migration/1581526429287-user-group-invitation.ts deleted file mode 100644 index 26ea54e0b..000000000 --- a/migration/1581526429287-user-group-invitation.ts +++ /dev/null @@ -1,38 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class userGroupInvitation1581526429287 implements MigrationInterface { - name = 'userGroupInvitation1581526429287' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE TABLE "user_group_invitation" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "userGroupId" character varying(32) NOT NULL, CONSTRAINT "PK_160c63ec02bf23f6a5c5e8140d6" PRIMARY KEY ("id"))`, undefined); - await queryRunner.query(`CREATE INDEX "IDX_bfbc6305547539369fe73eb144" ON "user_group_invitation" ("userId") `, undefined); - await queryRunner.query(`CREATE INDEX "IDX_5cc8c468090e129857e9fecce5" ON "user_group_invitation" ("userGroupId") `, undefined); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_e9793f65f504e5a31fbaedbf2f" ON "user_group_invitation" ("userId", "userGroupId") `, undefined); - await queryRunner.query(`ALTER TABLE "notification" ADD "userGroupInvitationId" character varying(32)`, undefined); - await queryRunner.query(`ALTER TYPE "public"."notification_type_enum" RENAME TO "notification_type_enum_old"`, undefined); - await queryRunner.query(`CREATE TYPE "notification_type_enum" AS ENUM('follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'receiveFollowRequest', 'followRequestAccepted', 'groupInvited')`, undefined); - await queryRunner.query(`ALTER TABLE "notification" ALTER COLUMN "type" TYPE "notification_type_enum" USING "type"::"text"::"notification_type_enum"`, undefined); - await queryRunner.query(`DROP TYPE "notification_type_enum_old"`, undefined); - await queryRunner.query(`COMMENT ON COLUMN "notification"."type" IS 'The type of the Notification.'`, undefined); - await queryRunner.query(`ALTER TABLE "user_group_invitation" ADD CONSTRAINT "FK_bfbc6305547539369fe73eb144a" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined); - await queryRunner.query(`ALTER TABLE "user_group_invitation" ADD CONSTRAINT "FK_5cc8c468090e129857e9fecce5a" FOREIGN KEY ("userGroupId") REFERENCES "user_group"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined); - await queryRunner.query(`ALTER TABLE "notification" ADD CONSTRAINT "FK_8fe87814e978053a53b1beb7e98" FOREIGN KEY ("userGroupInvitationId") REFERENCES "user_group_invitation"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "notification" DROP CONSTRAINT "FK_8fe87814e978053a53b1beb7e98"`, undefined); - await queryRunner.query(`ALTER TABLE "user_group_invitation" DROP CONSTRAINT "FK_5cc8c468090e129857e9fecce5a"`, undefined); - await queryRunner.query(`ALTER TABLE "user_group_invitation" DROP CONSTRAINT "FK_bfbc6305547539369fe73eb144a"`, undefined); - await queryRunner.query(`COMMENT ON COLUMN "notification"."type" IS ''`, undefined); - await queryRunner.query(`CREATE TYPE "notification_type_enum_old" AS ENUM('follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'receiveFollowRequest', 'followRequestAccepted')`, undefined); - await queryRunner.query(`ALTER TABLE "notification" ALTER COLUMN "type" TYPE "notification_type_enum_old" USING "type"::"text"::"notification_type_enum_old"`, undefined); - await queryRunner.query(`DROP TYPE "notification_type_enum"`, undefined); - await queryRunner.query(`ALTER TYPE "notification_type_enum_old" RENAME TO "notification_type_enum"`, undefined); - await queryRunner.query(`ALTER TABLE "notification" DROP COLUMN "userGroupInvitationId"`, undefined); - await queryRunner.query(`DROP INDEX "IDX_e9793f65f504e5a31fbaedbf2f"`, undefined); - await queryRunner.query(`DROP INDEX "IDX_5cc8c468090e129857e9fecce5"`, undefined); - await queryRunner.query(`DROP INDEX "IDX_bfbc6305547539369fe73eb144"`, undefined); - await queryRunner.query(`DROP TABLE "user_group_invitation"`, undefined); - } - -} diff --git a/migration/1581695816408-user-group-antenna.ts b/migration/1581695816408-user-group-antenna.ts deleted file mode 100644 index 15eb2fe11..000000000 --- a/migration/1581695816408-user-group-antenna.ts +++ /dev/null @@ -1,28 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class userGroupAntenna1581695816408 implements MigrationInterface { - name = 'userGroupAntenna1581695816408' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "antenna" ADD "userGroupJoiningId" character varying(32)`, undefined); - await queryRunner.query(`ALTER TYPE "public"."antenna_src_enum" RENAME TO "antenna_src_enum_old"`, undefined); - await queryRunner.query(`CREATE TYPE "antenna_src_enum" AS ENUM('home', 'all', 'users', 'list', 'group')`, undefined); - await queryRunner.query(`ALTER TABLE "antenna" ALTER COLUMN "src" TYPE "antenna_src_enum" USING "src"::"text"::"antenna_src_enum"`, undefined); - await queryRunner.query(`DROP TYPE "antenna_src_enum_old"`, undefined); - await queryRunner.query(`ALTER TABLE "antenna" DROP COLUMN "users"`, undefined); - await queryRunner.query(`ALTER TABLE "antenna" ADD "users" character varying(1024) array NOT NULL DEFAULT '{}'::varchar[]`, undefined); - await queryRunner.query(`ALTER TABLE "antenna" ADD CONSTRAINT "FK_ccbf5a8c0be4511133dcc50ddeb" FOREIGN KEY ("userGroupJoiningId") REFERENCES "user_group_joining"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "antenna" DROP CONSTRAINT "FK_ccbf5a8c0be4511133dcc50ddeb"`, undefined); - await queryRunner.query(`ALTER TABLE "antenna" DROP COLUMN "users"`, undefined); - await queryRunner.query(`ALTER TABLE "antenna" ADD "users" character varying array NOT NULL DEFAULT '{}'`, undefined); - await queryRunner.query(`CREATE TYPE "antenna_src_enum_old" AS ENUM('home', 'all', 'users', 'list')`, undefined); - await queryRunner.query(`ALTER TABLE "antenna" ALTER COLUMN "src" TYPE "antenna_src_enum_old" USING "src"::"text"::"antenna_src_enum_old"`, undefined); - await queryRunner.query(`DROP TYPE "antenna_src_enum"`, undefined); - await queryRunner.query(`ALTER TYPE "antenna_src_enum_old" RENAME TO "antenna_src_enum"`, undefined); - await queryRunner.query(`ALTER TABLE "antenna" DROP COLUMN "userGroupJoiningId"`, undefined); - } - -} diff --git a/migration/1581708415836-drive-user-folder-id-index.ts b/migration/1581708415836-drive-user-folder-id-index.ts deleted file mode 100644 index e7a7628ff..000000000 --- a/migration/1581708415836-drive-user-folder-id-index.ts +++ /dev/null @@ -1,14 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class driveUserFolderIdIndex1581708415836 implements MigrationInterface { - name = 'driveUserFolderIdIndex1581708415836' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE INDEX "IDX_55720b33a61a7c806a8215b825" ON "drive_file" ("userId", "folderId", "id") `, undefined); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`DROP INDEX "IDX_55720b33a61a7c806a8215b825"`, undefined); - } - -} diff --git a/migration/1581979837262-promo.ts b/migration/1581979837262-promo.ts deleted file mode 100644 index 2c4f25c4d..000000000 --- a/migration/1581979837262-promo.ts +++ /dev/null @@ -1,28 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class promo1581979837262 implements MigrationInterface { - name = 'promo1581979837262' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE TABLE "promo_note" ("noteId" character varying(32) NOT NULL, "expiresAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, CONSTRAINT "REL_e263909ca4fe5d57f8d4230dd5" UNIQUE ("noteId"), CONSTRAINT "PK_e263909ca4fe5d57f8d4230dd5c" PRIMARY KEY ("noteId"))`, undefined); - await queryRunner.query(`CREATE INDEX "IDX_83f0862e9bae44af52ced7099e" ON "promo_note" ("userId") `, undefined); - await queryRunner.query(`CREATE TABLE "promo_read" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "noteId" character varying(32) NOT NULL, CONSTRAINT "PK_61917c1541002422b703318b7c9" PRIMARY KEY ("id"))`, undefined); - await queryRunner.query(`CREATE INDEX "IDX_9657d55550c3d37bfafaf7d4b0" ON "promo_read" ("userId") `, undefined); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_2882b8a1a07c7d281a98b6db16" ON "promo_read" ("userId", "noteId") `, undefined); - await queryRunner.query(`ALTER TABLE "promo_note" ADD CONSTRAINT "FK_e263909ca4fe5d57f8d4230dd5c" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined); - await queryRunner.query(`ALTER TABLE "promo_read" ADD CONSTRAINT "FK_9657d55550c3d37bfafaf7d4b05" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined); - await queryRunner.query(`ALTER TABLE "promo_read" ADD CONSTRAINT "FK_a46a1a603ecee695d7db26da5f4" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "promo_read" DROP CONSTRAINT "FK_a46a1a603ecee695d7db26da5f4"`, undefined); - await queryRunner.query(`ALTER TABLE "promo_read" DROP CONSTRAINT "FK_9657d55550c3d37bfafaf7d4b05"`, undefined); - await queryRunner.query(`ALTER TABLE "promo_note" DROP CONSTRAINT "FK_e263909ca4fe5d57f8d4230dd5c"`, undefined); - await queryRunner.query(`DROP INDEX "IDX_2882b8a1a07c7d281a98b6db16"`, undefined); - await queryRunner.query(`DROP INDEX "IDX_9657d55550c3d37bfafaf7d4b0"`, undefined); - await queryRunner.query(`DROP TABLE "promo_read"`, undefined); - await queryRunner.query(`DROP INDEX "IDX_83f0862e9bae44af52ced7099e"`, undefined); - await queryRunner.query(`DROP TABLE "promo_note"`, undefined); - } - -} diff --git a/migration/1582019042083-featured-injecttion.ts b/migration/1582019042083-featured-injecttion.ts deleted file mode 100644 index 9c8498997..000000000 --- a/migration/1582019042083-featured-injecttion.ts +++ /dev/null @@ -1,14 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class featuredInjecttion1582019042083 implements MigrationInterface { - name = 'featuredInjecttion1582019042083' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user_profile" ADD "injectFeaturedNote" boolean NOT NULL DEFAULT true`, undefined); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "injectFeaturedNote"`, undefined); - } - -} diff --git a/migration/1582210532752-antenna-exclude.ts b/migration/1582210532752-antenna-exclude.ts deleted file mode 100644 index bff47a3ec..000000000 --- a/migration/1582210532752-antenna-exclude.ts +++ /dev/null @@ -1,14 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class antennaExclude1582210532752 implements MigrationInterface { - name = 'antennaExclude1582210532752' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "antenna" ADD "excludeKeywords" jsonb NOT NULL DEFAULT '[]'`, undefined); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "antenna" DROP COLUMN "excludeKeywords"`, undefined); - } - -} diff --git a/migration/1582875306439-note-reaction-length.ts b/migration/1582875306439-note-reaction-length.ts deleted file mode 100644 index b9af61eb0..000000000 --- a/migration/1582875306439-note-reaction-length.ts +++ /dev/null @@ -1,14 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class noteReactionLength1582875306439 implements MigrationInterface { - name = 'noteReactionLength1582875306439' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "note_reaction" ALTER COLUMN "reaction" TYPE character varying(130)`, undefined); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "note_reaction" ALTER COLUMN "reaction" TYPE character varying(128)`, undefined); - } - -} diff --git a/migration/1585361548360-miauth.ts b/migration/1585361548360-miauth.ts deleted file mode 100644 index 22d6c207f..000000000 --- a/migration/1585361548360-miauth.ts +++ /dev/null @@ -1,36 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class miauth1585361548360 implements MigrationInterface { - name = 'miauth1585361548360' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "access_token" ADD "lastUsedAt" TIMESTAMP WITH TIME ZONE DEFAULT null`, undefined); - await queryRunner.query(`ALTER TABLE "access_token" ADD "session" character varying(128) DEFAULT null`, undefined); - await queryRunner.query(`ALTER TABLE "access_token" ADD "name" character varying(128) DEFAULT null`, undefined); - await queryRunner.query(`ALTER TABLE "access_token" ADD "description" character varying(512) DEFAULT null`, undefined); - await queryRunner.query(`ALTER TABLE "access_token" ADD "iconUrl" character varying(512) DEFAULT null`, undefined); - await queryRunner.query(`ALTER TABLE "access_token" ADD "permission" character varying(64) array NOT NULL DEFAULT '{}'::varchar[]`, undefined); - await queryRunner.query(`ALTER TABLE "access_token" ADD "fetched" boolean NOT NULL DEFAULT false`, undefined); - await queryRunner.query(`ALTER TABLE "access_token" DROP CONSTRAINT "FK_a3ff16c90cc87a82a0b5959e560"`, undefined); - await queryRunner.query(`ALTER TABLE "access_token" ALTER COLUMN "appId" DROP NOT NULL`, undefined); - await queryRunner.query(`ALTER TABLE "access_token" ALTER COLUMN "appId" SET DEFAULT null`, undefined); - await queryRunner.query(`CREATE INDEX "IDX_bf3a053c07d9fb5d87317c56ee" ON "access_token" ("session") `, undefined); - await queryRunner.query(`ALTER TABLE "access_token" ADD CONSTRAINT "FK_a3ff16c90cc87a82a0b5959e560" FOREIGN KEY ("appId") REFERENCES "app"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "access_token" DROP CONSTRAINT "FK_a3ff16c90cc87a82a0b5959e560"`, undefined); - await queryRunner.query(`DROP INDEX "IDX_bf3a053c07d9fb5d87317c56ee"`, undefined); - await queryRunner.query(`ALTER TABLE "access_token" ALTER COLUMN "appId" DROP DEFAULT`, undefined); - await queryRunner.query(`ALTER TABLE "access_token" ALTER COLUMN "appId" SET NOT NULL`, undefined); - await queryRunner.query(`ALTER TABLE "access_token" ADD CONSTRAINT "FK_a3ff16c90cc87a82a0b5959e560" FOREIGN KEY ("appId") REFERENCES "app"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined); - await queryRunner.query(`ALTER TABLE "access_token" DROP COLUMN "fetched"`, undefined); - await queryRunner.query(`ALTER TABLE "access_token" DROP COLUMN "permission"`, undefined); - await queryRunner.query(`ALTER TABLE "access_token" DROP COLUMN "iconUrl"`, undefined); - await queryRunner.query(`ALTER TABLE "access_token" DROP COLUMN "description"`, undefined); - await queryRunner.query(`ALTER TABLE "access_token" DROP COLUMN "name"`, undefined); - await queryRunner.query(`ALTER TABLE "access_token" DROP COLUMN "session"`, undefined); - await queryRunner.query(`ALTER TABLE "access_token" DROP COLUMN "lastUsedAt"`, undefined); - } - -} diff --git a/migration/1585385921215-custom-notification.ts b/migration/1585385921215-custom-notification.ts deleted file mode 100644 index 24c29d53e..000000000 --- a/migration/1585385921215-custom-notification.ts +++ /dev/null @@ -1,48 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class customNotification1585385921215 implements MigrationInterface { - name = 'customNotification1585385921215' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "notification" ADD "customBody" character varying(2048)`, undefined); - await queryRunner.query(`ALTER TABLE "notification" ADD "customHeader" character varying(256)`, undefined); - await queryRunner.query(`ALTER TABLE "notification" ADD "customIcon" character varying(1024)`, undefined); - await queryRunner.query(`ALTER TABLE "notification" ADD "appAccessTokenId" character varying(32)`, undefined); - await queryRunner.query(`ALTER TABLE "notification" DROP CONSTRAINT "FK_3b4e96eec8d36a8bbb9d02aa710"`, undefined); - await queryRunner.query(`ALTER TABLE "notification" ALTER COLUMN "notifierId" DROP NOT NULL`, undefined); - await queryRunner.query(`COMMENT ON COLUMN "notification"."notifierId" IS 'The ID of sender user of the Notification.'`, undefined); - await queryRunner.query(`ALTER TYPE "public"."notification_type_enum" RENAME TO "notification_type_enum_old"`, undefined); - await queryRunner.query(`CREATE TYPE "notification_type_enum" AS ENUM('follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'receiveFollowRequest', 'followRequestAccepted', 'groupInvited', 'app')`, undefined); - await queryRunner.query(`ALTER TABLE "notification" ALTER COLUMN "type" TYPE "notification_type_enum" USING "type"::"text"::"notification_type_enum"`, undefined); - await queryRunner.query(`DROP TYPE "notification_type_enum_old"`, undefined); - await queryRunner.query(`COMMENT ON COLUMN "notification"."type" IS 'The type of the Notification.'`, undefined); - await queryRunner.query(`CREATE INDEX "IDX_3b4e96eec8d36a8bbb9d02aa71" ON "notification" ("notifierId") `, undefined); - await queryRunner.query(`CREATE INDEX "IDX_33f33cc8ef29d805a97ff4628b" ON "notification" ("type") `, undefined); - await queryRunner.query(`CREATE INDEX "IDX_080ab397c379af09b9d2169e5b" ON "notification" ("isRead") `, undefined); - await queryRunner.query(`CREATE INDEX "IDX_e22bf6bda77b6adc1fd9e75c8c" ON "notification" ("appAccessTokenId") `, undefined); - await queryRunner.query(`ALTER TABLE "notification" ADD CONSTRAINT "FK_3b4e96eec8d36a8bbb9d02aa710" FOREIGN KEY ("notifierId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined); - await queryRunner.query(`ALTER TABLE "notification" ADD CONSTRAINT "FK_e22bf6bda77b6adc1fd9e75c8c9" FOREIGN KEY ("appAccessTokenId") REFERENCES "access_token"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "notification" DROP CONSTRAINT "FK_e22bf6bda77b6adc1fd9e75c8c9"`, undefined); - await queryRunner.query(`ALTER TABLE "notification" DROP CONSTRAINT "FK_3b4e96eec8d36a8bbb9d02aa710"`, undefined); - await queryRunner.query(`DROP INDEX "IDX_e22bf6bda77b6adc1fd9e75c8c"`, undefined); - await queryRunner.query(`DROP INDEX "IDX_080ab397c379af09b9d2169e5b"`, undefined); - await queryRunner.query(`DROP INDEX "IDX_33f33cc8ef29d805a97ff4628b"`, undefined); - await queryRunner.query(`DROP INDEX "IDX_3b4e96eec8d36a8bbb9d02aa71"`, undefined); - await queryRunner.query(`COMMENT ON COLUMN "notification"."type" IS ''`, undefined); - await queryRunner.query(`CREATE TYPE "notification_type_enum_old" AS ENUM('follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'receiveFollowRequest', 'followRequestAccepted', 'groupInvited')`, undefined); - await queryRunner.query(`ALTER TABLE "notification" ALTER COLUMN "type" TYPE "notification_type_enum_old" USING "type"::"text"::"notification_type_enum_old"`, undefined); - await queryRunner.query(`DROP TYPE "notification_type_enum"`, undefined); - await queryRunner.query(`ALTER TYPE "notification_type_enum_old" RENAME TO "notification_type_enum"`, undefined); - await queryRunner.query(`COMMENT ON COLUMN "notification"."notifierId" IS ''`, undefined); - await queryRunner.query(`ALTER TABLE "notification" ALTER COLUMN "notifierId" SET NOT NULL`, undefined); - await queryRunner.query(`ALTER TABLE "notification" ADD CONSTRAINT "FK_3b4e96eec8d36a8bbb9d02aa710" FOREIGN KEY ("notifierId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined); - await queryRunner.query(`ALTER TABLE "notification" DROP COLUMN "appAccessTokenId"`, undefined); - await queryRunner.query(`ALTER TABLE "notification" DROP COLUMN "customIcon"`, undefined); - await queryRunner.query(`ALTER TABLE "notification" DROP COLUMN "customHeader"`, undefined); - await queryRunner.query(`ALTER TABLE "notification" DROP COLUMN "customBody"`, undefined); - } - -} diff --git a/migration/1585772678853-ap-url.ts b/migration/1585772678853-ap-url.ts deleted file mode 100644 index 622d09727..000000000 --- a/migration/1585772678853-ap-url.ts +++ /dev/null @@ -1,15 +0,0 @@ -/* tslint:disable:quotemark class-name indent */ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class apUrl1585772678853 implements MigrationInterface { - name = 'apUrl1585772678853' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "note" ADD "url" character varying(512)`, undefined); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "note" DROP COLUMN "url"`, undefined); - } - -} diff --git a/migration/1586624197029-AddObjectStorageUseProxy.ts b/migration/1586624197029-AddObjectStorageUseProxy.ts deleted file mode 100644 index deadf9483..000000000 --- a/migration/1586624197029-AddObjectStorageUseProxy.ts +++ /dev/null @@ -1,14 +0,0 @@ -import {MigrationInterface, QueryRunner} from 'typeorm'; - -export class AddObjectStorageUseProxy1586624197029 implements MigrationInterface { - name = 'AddObjectStorageUseProxy1586624197029' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "meta" ADD "objectStorageUseProxy" boolean NOT NULL DEFAULT true`, undefined); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStorageUseProxy"`, undefined); - } - -} diff --git a/migration/1586641139527-remote-reaction.ts b/migration/1586641139527-remote-reaction.ts deleted file mode 100644 index 5a7fb36e3..000000000 --- a/migration/1586641139527-remote-reaction.ts +++ /dev/null @@ -1,12 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class remoteReaction1586641139527 implements MigrationInterface { - name = 'remoteReaction1586641139527' - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "note_reaction" ALTER COLUMN "reaction" TYPE character varying(260)`, undefined); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "note_reaction" ALTER COLUMN "reaction" TYPE character varying(130)`, undefined); - } -} diff --git a/migration/1586708940386-pageAiScript.ts b/migration/1586708940386-pageAiScript.ts deleted file mode 100644 index fdd6e76b9..000000000 --- a/migration/1586708940386-pageAiScript.ts +++ /dev/null @@ -1,14 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class pageAiScript1586708940386 implements MigrationInterface { - name = 'pageAiScript1586708940386' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "page" ADD "script" character varying(16384) NOT NULL DEFAULT ''`, undefined); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "page" DROP COLUMN "script"`, undefined); - } - -} diff --git a/migration/1588044505511-hCaptcha.ts b/migration/1588044505511-hCaptcha.ts deleted file mode 100644 index a3f4e9367..000000000 --- a/migration/1588044505511-hCaptcha.ts +++ /dev/null @@ -1,18 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class hCaptcha1588044505511 implements MigrationInterface { - name = 'hCaptcha1588044505511' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "meta" ADD "enableHcaptcha" boolean NOT NULL DEFAULT false`, undefined); - await queryRunner.query(`ALTER TABLE "meta" ADD "hcaptchaSiteKey" character varying(64)`, undefined); - await queryRunner.query(`ALTER TABLE "meta" ADD "hcaptchaSecretKey" character varying(64)`, undefined); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "hcaptchaSecretKey"`, undefined); - await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "hcaptchaSiteKey"`, undefined); - await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "enableHcaptcha"`, undefined); - } - -} diff --git a/migration/1589023282116-pubRelay.ts b/migration/1589023282116-pubRelay.ts deleted file mode 100644 index 3b9d35991..000000000 --- a/migration/1589023282116-pubRelay.ts +++ /dev/null @@ -1,18 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class pubRelay1589023282116 implements MigrationInterface { - name = 'pubRelay1589023282116' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE TYPE "relay_status_enum" AS ENUM('requesting', 'accepted', 'rejected')`, undefined); - await queryRunner.query(`CREATE TABLE "relay" ("id" character varying(32) NOT NULL, "inbox" character varying(512) NOT NULL, "status" "relay_status_enum" NOT NULL, CONSTRAINT "PK_78ebc9cfddf4292633b7ba57aee" PRIMARY KEY ("id"))`, undefined); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_0d9a1738f2cf7f3b1c3334dfab" ON "relay" ("inbox") `, undefined); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`DROP INDEX "IDX_0d9a1738f2cf7f3b1c3334dfab"`, undefined); - await queryRunner.query(`DROP TABLE "relay"`, undefined); - await queryRunner.query(`DROP TYPE "relay_status_enum"`, undefined); - } - -} diff --git a/migration/1595075960584-blurhash.ts b/migration/1595075960584-blurhash.ts deleted file mode 100644 index 7c716ae17..000000000 --- a/migration/1595075960584-blurhash.ts +++ /dev/null @@ -1,14 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class blurhash1595075960584 implements MigrationInterface { - name = 'blurhash1595075960584' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "drive_file" ADD "blurhash" character varying(128)`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "drive_file" DROP COLUMN "blurhash"`); - } - -} diff --git a/migration/1595077605646-blurhash-for-avatar-banner.ts b/migration/1595077605646-blurhash-for-avatar-banner.ts deleted file mode 100644 index fcf161c35..000000000 --- a/migration/1595077605646-blurhash-for-avatar-banner.ts +++ /dev/null @@ -1,20 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class blurhashForAvatarBanner1595077605646 implements MigrationInterface { - name = 'blurhashForAvatarBanner1595077605646' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "avatarColor"`); - await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "bannerColor"`); - await queryRunner.query(`ALTER TABLE "user" ADD "avatarBlurhash" character varying(128)`); - await queryRunner.query(`ALTER TABLE "user" ADD "bannerBlurhash" character varying(128)`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "bannerBlurhash"`); - await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "avatarBlurhash"`); - await queryRunner.query(`ALTER TABLE "user" ADD "bannerColor" character varying(32)`); - await queryRunner.query(`ALTER TABLE "user" ADD "avatarColor" character varying(32)`); - } - -} diff --git a/migration/1595676934834-instance-icon-url.ts b/migration/1595676934834-instance-icon-url.ts deleted file mode 100644 index c75370f17..000000000 --- a/migration/1595676934834-instance-icon-url.ts +++ /dev/null @@ -1,14 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class instanceIconUrl1595676934834 implements MigrationInterface { - name = 'instanceIconUrl1595676934834' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "instance" ADD "iconUrl" character varying(256) DEFAULT null`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "iconUrl"`); - } - -} diff --git a/migration/1595771249699-word-mute.ts b/migration/1595771249699-word-mute.ts deleted file mode 100644 index 1a9114d92..000000000 --- a/migration/1595771249699-word-mute.ts +++ /dev/null @@ -1,30 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class wordMute1595771249699 implements MigrationInterface { - name = 'wordMute1595771249699' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE TABLE "muted_note" ("id" character varying(32) NOT NULL, "noteId" character varying(32) NOT NULL, "userId" character varying(32) NOT NULL, CONSTRAINT "PK_897e2eff1c0b9b64e55ca1418a4" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE INDEX "IDX_70ab9786313d78e4201d81cdb8" ON "muted_note" ("noteId") `); - await queryRunner.query(`CREATE INDEX "IDX_d8e07aa18c2d64e86201601aec" ON "muted_note" ("userId") `); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_a8c6bfd637d3f1d67a27c48e27" ON "muted_note" ("noteId", "userId") `); - await queryRunner.query(`ALTER TABLE "user_profile" ADD "enableWordMute" boolean NOT NULL DEFAULT false`); - await queryRunner.query(`ALTER TABLE "user_profile" ADD "mutedWords" jsonb NOT NULL DEFAULT '[]'`); - await queryRunner.query(`CREATE INDEX "IDX_3befe6f999c86aff06eb0257b4" ON "user_profile" ("enableWordMute") `); - await queryRunner.query(`ALTER TABLE "muted_note" ADD CONSTRAINT "FK_70ab9786313d78e4201d81cdb89" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "muted_note" ADD CONSTRAINT "FK_d8e07aa18c2d64e86201601aec1" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "muted_note" DROP CONSTRAINT "FK_d8e07aa18c2d64e86201601aec1"`); - await queryRunner.query(`ALTER TABLE "muted_note" DROP CONSTRAINT "FK_70ab9786313d78e4201d81cdb89"`); - await queryRunner.query(`DROP INDEX "IDX_3befe6f999c86aff06eb0257b4"`); - await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "mutedWords"`); - await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "enableWordMute"`); - await queryRunner.query(`DROP INDEX "IDX_a8c6bfd637d3f1d67a27c48e27"`); - await queryRunner.query(`DROP INDEX "IDX_d8e07aa18c2d64e86201601aec"`); - await queryRunner.query(`DROP INDEX "IDX_70ab9786313d78e4201d81cdb8"`); - await queryRunner.query(`DROP TABLE "muted_note"`); - } - -} diff --git a/migration/1595782306083-word-mute2.ts b/migration/1595782306083-word-mute2.ts deleted file mode 100644 index d68c12740..000000000 --- a/migration/1595782306083-word-mute2.ts +++ /dev/null @@ -1,18 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class wordMute21595782306083 implements MigrationInterface { - name = 'wordMute21595782306083' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE TYPE "muted_note_reason_enum" AS ENUM('word', 'manual', 'spam', 'other')`); - await queryRunner.query(`ALTER TABLE "muted_note" ADD "reason" "muted_note_reason_enum" NOT NULL`); - await queryRunner.query(`CREATE INDEX "IDX_636e977ff90b23676fb5624b25" ON "muted_note" ("reason") `); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`DROP INDEX "IDX_636e977ff90b23676fb5624b25"`); - await queryRunner.query(`ALTER TABLE "muted_note" DROP COLUMN "reason"`); - await queryRunner.query(`DROP TYPE "muted_note_reason_enum"`); - } - -} diff --git a/migration/1596548170836-channel.ts b/migration/1596548170836-channel.ts deleted file mode 100644 index 4e3ebb330..000000000 --- a/migration/1596548170836-channel.ts +++ /dev/null @@ -1,58 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class channel1596548170836 implements MigrationInterface { - name = 'channel1596548170836' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE TABLE "channel" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "lastNotedAt" TIMESTAMP WITH TIME ZONE, "userId" character varying(32) NOT NULL, "name" character varying(128) NOT NULL, "description" character varying(2048), "bannerId" character varying(32), "notesCount" integer NOT NULL DEFAULT 0, "usersCount" integer NOT NULL DEFAULT 0, CONSTRAINT "PK_590f33ee6ee7d76437acf362e39" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE INDEX "IDX_71cb7b435b7c0d4843317e7e16" ON "channel" ("createdAt") `); - await queryRunner.query(`CREATE INDEX "IDX_29ef80c6f13bcea998447fce43" ON "channel" ("lastNotedAt") `); - await queryRunner.query(`CREATE INDEX "IDX_823bae55bd81b3be6e05cff438" ON "channel" ("userId") `); - await queryRunner.query(`CREATE INDEX "IDX_0f58c11241e649d2a638a8de94" ON "channel" ("notesCount") `); - await queryRunner.query(`CREATE INDEX "IDX_094b86cd36bb805d1aa1e8cc9a" ON "channel" ("usersCount") `); - await queryRunner.query(`CREATE TABLE "channel_following" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "followeeId" character varying(32) NOT NULL, "followerId" character varying(32) NOT NULL, CONSTRAINT "PK_8b104be7f7415113f2a02cd5bdd" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE INDEX "IDX_11e71f2511589dcc8a4d3214f9" ON "channel_following" ("createdAt") `); - await queryRunner.query(`CREATE INDEX "IDX_0e43068c3f92cab197c3d3cd86" ON "channel_following" ("followeeId") `); - await queryRunner.query(`CREATE INDEX "IDX_6d8084ec9496e7334a4602707e" ON "channel_following" ("followerId") `); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_2e230dd45a10e671d781d99f3e" ON "channel_following" ("followerId", "followeeId") `); - await queryRunner.query(`CREATE TABLE "channel_note_pining" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "channelId" character varying(32) NOT NULL, "noteId" character varying(32) NOT NULL, CONSTRAINT "PK_44f7474496bcf2e4b741681146d" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE INDEX "IDX_8125f950afd3093acb10d2db8a" ON "channel_note_pining" ("channelId") `); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_f36fed37d6d4cdcc68c803cd9c" ON "channel_note_pining" ("channelId", "noteId") `); - await queryRunner.query(`ALTER TABLE "note" ADD "channelId" character varying(32) DEFAULT null`); - await queryRunner.query(`CREATE INDEX "IDX_f22169eb10657bded6d875ac8f" ON "note" ("channelId") `); - await queryRunner.query(`ALTER TABLE "channel" ADD CONSTRAINT "FK_823bae55bd81b3be6e05cff4383" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE SET NULL ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "channel" ADD CONSTRAINT "FK_999da2bcc7efadbfe0e92d3bc19" FOREIGN KEY ("bannerId") REFERENCES "drive_file"("id") ON DELETE SET NULL ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "note" ADD CONSTRAINT "FK_f22169eb10657bded6d875ac8f9" FOREIGN KEY ("channelId") REFERENCES "channel"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "channel_following" ADD CONSTRAINT "FK_0e43068c3f92cab197c3d3cd86e" FOREIGN KEY ("followeeId") REFERENCES "channel"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "channel_following" ADD CONSTRAINT "FK_6d8084ec9496e7334a4602707e1" FOREIGN KEY ("followerId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "channel_note_pining" ADD CONSTRAINT "FK_8125f950afd3093acb10d2db8a8" FOREIGN KEY ("channelId") REFERENCES "channel"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "channel_note_pining" ADD CONSTRAINT "FK_10b19ef67d297ea9de325cd4502" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "channel_note_pining" DROP CONSTRAINT "FK_10b19ef67d297ea9de325cd4502"`); - await queryRunner.query(`ALTER TABLE "channel_note_pining" DROP CONSTRAINT "FK_8125f950afd3093acb10d2db8a8"`); - await queryRunner.query(`ALTER TABLE "channel_following" DROP CONSTRAINT "FK_6d8084ec9496e7334a4602707e1"`); - await queryRunner.query(`ALTER TABLE "channel_following" DROP CONSTRAINT "FK_0e43068c3f92cab197c3d3cd86e"`); - await queryRunner.query(`ALTER TABLE "note" DROP CONSTRAINT "FK_f22169eb10657bded6d875ac8f9"`); - await queryRunner.query(`ALTER TABLE "channel" DROP CONSTRAINT "FK_999da2bcc7efadbfe0e92d3bc19"`); - await queryRunner.query(`ALTER TABLE "channel" DROP CONSTRAINT "FK_823bae55bd81b3be6e05cff4383"`); - await queryRunner.query(`DROP INDEX "IDX_f22169eb10657bded6d875ac8f"`); - await queryRunner.query(`ALTER TABLE "note" DROP COLUMN "channelId"`); - await queryRunner.query(`DROP INDEX "IDX_f36fed37d6d4cdcc68c803cd9c"`); - await queryRunner.query(`DROP INDEX "IDX_8125f950afd3093acb10d2db8a"`); - await queryRunner.query(`DROP TABLE "channel_note_pining"`); - await queryRunner.query(`DROP INDEX "IDX_2e230dd45a10e671d781d99f3e"`); - await queryRunner.query(`DROP INDEX "IDX_6d8084ec9496e7334a4602707e"`); - await queryRunner.query(`DROP INDEX "IDX_0e43068c3f92cab197c3d3cd86"`); - await queryRunner.query(`DROP INDEX "IDX_11e71f2511589dcc8a4d3214f9"`); - await queryRunner.query(`DROP TABLE "channel_following"`); - await queryRunner.query(`DROP INDEX "IDX_094b86cd36bb805d1aa1e8cc9a"`); - await queryRunner.query(`DROP INDEX "IDX_0f58c11241e649d2a638a8de94"`); - await queryRunner.query(`DROP INDEX "IDX_823bae55bd81b3be6e05cff438"`); - await queryRunner.query(`DROP INDEX "IDX_29ef80c6f13bcea998447fce43"`); - await queryRunner.query(`DROP INDEX "IDX_71cb7b435b7c0d4843317e7e16"`); - await queryRunner.query(`DROP TABLE "channel"`); - } - -} diff --git a/migration/1596786425167-channel2.ts b/migration/1596786425167-channel2.ts deleted file mode 100644 index 0233f7ab0..000000000 --- a/migration/1596786425167-channel2.ts +++ /dev/null @@ -1,14 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class channel21596786425167 implements MigrationInterface { - name = 'channel21596786425167' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "channel_following" ADD "readCursor" TIMESTAMP WITH TIME ZONE NOT NULL`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "channel_following" DROP COLUMN "readCursor"`); - } - -} diff --git a/migration/1597230137744-objectStorageSetPublicRead.ts b/migration/1597230137744-objectStorageSetPublicRead.ts deleted file mode 100644 index f040f2afd..000000000 --- a/migration/1597230137744-objectStorageSetPublicRead.ts +++ /dev/null @@ -1,14 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class objectStorageSetPublicRead1597230137744 implements MigrationInterface { - name = 'objectStorageSetPublicRead1597230137744' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "meta" ADD "objectStorageSetPublicRead" boolean NOT NULL DEFAULT false`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStorageSetPublicRead"`); - } - -} diff --git a/migration/1597236229720-IncludingNotificationTypes.ts b/migration/1597236229720-IncludingNotificationTypes.ts deleted file mode 100644 index be57824c0..000000000 --- a/migration/1597236229720-IncludingNotificationTypes.ts +++ /dev/null @@ -1,16 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class IncludingNotificationTypes1597236229720 implements MigrationInterface { - name = 'IncludingNotificationTypes1597236229720' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE TYPE "user_profile_includingnotificationtypes_enum" AS ENUM('follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'receiveFollowRequest', 'followRequestAccepted', 'groupInvited', 'app')`); - await queryRunner.query(`ALTER TABLE "user_profile" ADD "includingNotificationTypes" "user_profile_includingnotificationtypes_enum" array`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "includingNotificationTypes"`); - await queryRunner.query(`DROP TYPE "user_profile_includingnotificationtypes_enum"`); - } - -} diff --git a/migration/1597385880794-add-sensitive-index.ts b/migration/1597385880794-add-sensitive-index.ts deleted file mode 100644 index ff6251ac0..000000000 --- a/migration/1597385880794-add-sensitive-index.ts +++ /dev/null @@ -1,14 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class addSensitiveIndex1597385880794 implements MigrationInterface { - name = 'addSensitiveIndex1597385880794' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE INDEX "IDX_a7eba67f8b3fa27271e85d2e26" ON "drive_file" ("isSensitive") `); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`DROP INDEX "IDX_a7eba67f8b3fa27271e85d2e26"`); - } - -} diff --git a/migration/1597459042300-channel-unread.ts b/migration/1597459042300-channel-unread.ts deleted file mode 100644 index a0f862114..000000000 --- a/migration/1597459042300-channel-unread.ts +++ /dev/null @@ -1,27 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class channelUnread1597459042300 implements MigrationInterface { - name = 'channelUnread1597459042300' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`TRUNCATE TABLE "note_unread"`, undefined); - await queryRunner.query(`ALTER TABLE "channel_following" DROP COLUMN "readCursor"`); - await queryRunner.query(`ALTER TABLE "note_unread" ADD "isMentioned" boolean NOT NULL`); - await queryRunner.query(`ALTER TABLE "note_unread" ADD "noteChannelId" character varying(32)`); - await queryRunner.query(`CREATE INDEX "IDX_25b1dd384bec391b07b74b861c" ON "note_unread" ("isMentioned") `); - await queryRunner.query(`CREATE INDEX "IDX_89a29c9237b8c3b6b3cbb4cb30" ON "note_unread" ("isSpecified") `); - await queryRunner.query(`CREATE INDEX "IDX_29e8c1d579af54d4232939f994" ON "note_unread" ("noteUserId") `); - await queryRunner.query(`CREATE INDEX "IDX_6a57f051d82c6d4036c141e107" ON "note_unread" ("noteChannelId") `); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`DROP INDEX "IDX_6a57f051d82c6d4036c141e107"`); - await queryRunner.query(`DROP INDEX "IDX_29e8c1d579af54d4232939f994"`); - await queryRunner.query(`DROP INDEX "IDX_89a29c9237b8c3b6b3cbb4cb30"`); - await queryRunner.query(`DROP INDEX "IDX_25b1dd384bec391b07b74b861c"`); - await queryRunner.query(`ALTER TABLE "note_unread" DROP COLUMN "noteChannelId"`); - await queryRunner.query(`ALTER TABLE "note_unread" DROP COLUMN "isMentioned"`); - await queryRunner.query(`ALTER TABLE "channel_following" ADD "readCursor" TIMESTAMP WITH TIME ZONE NOT NULL`); - } - -} diff --git a/migration/1597893996136-ChannelNoteIdDescIndex.ts b/migration/1597893996136-ChannelNoteIdDescIndex.ts deleted file mode 100644 index 6cbd865fc..000000000 --- a/migration/1597893996136-ChannelNoteIdDescIndex.ts +++ /dev/null @@ -1,16 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class ChannelNoteIdDescIndex1597893996136 implements MigrationInterface { - name = 'ChannelNoteIdDescIndex1597893996136' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`DROP INDEX "IDX_f22169eb10657bded6d875ac8f"`); - await queryRunner.query(`CREATE INDEX "IDX_note_on_channelId_and_id_desc" ON "note" ("channelId", "id" desc)`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`DROP INDEX "IDX_note_on_channelId_and_id_desc"`); - await queryRunner.query(`CREATE INDEX "IDX_f22169eb10657bded6d875ac8f" ON "note" ("channelId") `); - } - -} diff --git a/migration/1600353287890-mutingNotificationTypes.ts b/migration/1600353287890-mutingNotificationTypes.ts deleted file mode 100644 index 914bad8e3..000000000 --- a/migration/1600353287890-mutingNotificationTypes.ts +++ /dev/null @@ -1,20 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class mutingNotificationTypes1600353287890 implements MigrationInterface { - name = 'mutingNotificationTypes1600353287890' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "includingNotificationTypes"`); - await queryRunner.query(`DROP TYPE "public"."user_profile_includingnotificationtypes_enum"`); - await queryRunner.query(`CREATE TYPE "user_profile_mutingnotificationtypes_enum" AS ENUM('follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'receiveFollowRequest', 'followRequestAccepted', 'groupInvited', 'app')`); - await queryRunner.query(`ALTER TABLE "user_profile" ADD "mutingNotificationTypes" "user_profile_mutingnotificationtypes_enum" array NOT NULL DEFAULT '{}'`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "mutingNotificationTypes"`); - await queryRunner.query(`DROP TYPE "user_profile_mutingnotificationtypes_enum"`); - await queryRunner.query(`CREATE TYPE "public"."user_profile_includingnotificationtypes_enum" AS ENUM('follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'receiveFollowRequest', 'followRequestAccepted', 'groupInvited', 'app')`); - await queryRunner.query(`ALTER TABLE "user_profile" ADD "includingNotificationTypes" "user_profile_includingnotificationtypes_enum" array`); - } - -} diff --git a/migration/1603094348345-refine-abuse-user-report.ts b/migration/1603094348345-refine-abuse-user-report.ts deleted file mode 100644 index ce74a88d4..000000000 --- a/migration/1603094348345-refine-abuse-user-report.ts +++ /dev/null @@ -1,32 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class refineAbuseUserReport1603094348345 implements MigrationInterface { - name = 'refineAbuseUserReport1603094348345' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "abuse_user_report" DROP CONSTRAINT "FK_d049123c413e68ca52abe734203"`); - await queryRunner.query(`DROP INDEX "IDX_d049123c413e68ca52abe73420"`); - await queryRunner.query(`DROP INDEX "IDX_5cd442c3b2e74fdd99dae20243"`); - await queryRunner.query(`ALTER TABLE "abuse_user_report" RENAME COLUMN "userId" TO "targetUserId"`); - await queryRunner.query(`ALTER TABLE "abuse_user_report" ADD "assigneeId" character varying(32)`); - await queryRunner.query(`ALTER TABLE "abuse_user_report" ADD "resolved" boolean NOT NULL DEFAULT false`); - await queryRunner.query(`ALTER TABLE "abuse_user_report" DROP COLUMN "comment"`); - await queryRunner.query(`ALTER TABLE "abuse_user_report" ADD "comment" character varying(2048) NOT NULL DEFAULT '{}'::varchar[]`); - await queryRunner.query(`CREATE INDEX "IDX_2b15aaf4a0dc5be3499af7ab6a" ON "abuse_user_report" ("resolved") `); - await queryRunner.query(`ALTER TABLE "abuse_user_report" ADD CONSTRAINT "FK_08b883dd5fdd6f9c4c1572b36de" FOREIGN KEY ("assigneeId") REFERENCES "user"("id") ON DELETE SET NULL ON UPDATE NO ACTION`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "abuse_user_report" DROP CONSTRAINT "FK_08b883dd5fdd6f9c4c1572b36de"`); - await queryRunner.query(`DROP INDEX "IDX_2b15aaf4a0dc5be3499af7ab6a"`); - await queryRunner.query(`ALTER TABLE "abuse_user_report" DROP COLUMN "comment"`); - await queryRunner.query(`ALTER TABLE "abuse_user_report" ADD "comment" character varying(512) NOT NULL DEFAULT '{}'::varchar[]`); - await queryRunner.query(`ALTER TABLE "abuse_user_report" DROP COLUMN "resolved"`); - await queryRunner.query(`ALTER TABLE "abuse_user_report" DROP COLUMN "assigneeId"`); - await queryRunner.query(`ALTER TABLE "abuse_user_report" RENAME COLUMN "targetUserId" TO "userId"`); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_5cd442c3b2e74fdd99dae20243" ON "abuse_user_report" ("userId", "reporterId") `); - await queryRunner.query(`CREATE INDEX "IDX_d049123c413e68ca52abe73420" ON "abuse_user_report" ("userId") `); - await queryRunner.query(`ALTER TABLE "abuse_user_report" ADD CONSTRAINT "FK_d049123c413e68ca52abe734203" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - } - -} diff --git a/migration/1603095701770-refine-abuse-user-report2.ts b/migration/1603095701770-refine-abuse-user-report2.ts deleted file mode 100644 index 18e0c05ac..000000000 --- a/migration/1603095701770-refine-abuse-user-report2.ts +++ /dev/null @@ -1,20 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class refineAbuseUserReport21603095701770 implements MigrationInterface { - name = 'refineAbuseUserReport21603095701770' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "abuse_user_report" ADD "targetUserHost" character varying(128)`); - await queryRunner.query(`ALTER TABLE "abuse_user_report" ADD "reporterHost" character varying(128)`); - await queryRunner.query(`CREATE INDEX "IDX_4ebbf7f93cdc10e8d1ef2fc6cd" ON "abuse_user_report" ("targetUserHost") `); - await queryRunner.query(`CREATE INDEX "IDX_f8d8b93740ad12c4ce8213a199" ON "abuse_user_report" ("reporterHost") `); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`DROP INDEX "IDX_f8d8b93740ad12c4ce8213a199"`); - await queryRunner.query(`DROP INDEX "IDX_4ebbf7f93cdc10e8d1ef2fc6cd"`); - await queryRunner.query(`ALTER TABLE "abuse_user_report" DROP COLUMN "reporterHost"`); - await queryRunner.query(`ALTER TABLE "abuse_user_report" DROP COLUMN "targetUserHost"`); - } - -} diff --git a/migration/1603776877564-instance-theme-color.ts b/migration/1603776877564-instance-theme-color.ts deleted file mode 100644 index 80c9d516f..000000000 --- a/migration/1603776877564-instance-theme-color.ts +++ /dev/null @@ -1,14 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class instanceThemeColor1603776877564 implements MigrationInterface { - name = 'instanceThemeColor1603776877564' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "instance" ADD "themeColor" character varying(64) DEFAULT null`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "themeColor"`); - } - -} diff --git a/migration/1603781553011-instance-favicon.ts b/migration/1603781553011-instance-favicon.ts deleted file mode 100644 index d748c43f5..000000000 --- a/migration/1603781553011-instance-favicon.ts +++ /dev/null @@ -1,14 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class instanceFavicon1603781553011 implements MigrationInterface { - name = 'instanceFavicon1603781553011' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "instance" ADD "faviconUrl" character varying(256) DEFAULT null`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "faviconUrl"`); - } - -} diff --git a/migration/1604821689616-delete-auto-watch.ts b/migration/1604821689616-delete-auto-watch.ts deleted file mode 100644 index e47a4cf1d..000000000 --- a/migration/1604821689616-delete-auto-watch.ts +++ /dev/null @@ -1,14 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class deleteAutoWatch1604821689616 implements MigrationInterface { - name = 'deleteAutoWatch1604821689616' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "autoWatch"`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user_profile" ADD "autoWatch" boolean NOT NULL DEFAULT false`); - } - -} diff --git a/migration/1605408848373-clip-description.ts b/migration/1605408848373-clip-description.ts deleted file mode 100644 index b352173e4..000000000 --- a/migration/1605408848373-clip-description.ts +++ /dev/null @@ -1,15 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class clipDescription1605408848373 implements MigrationInterface { - name = 'clipDescription1605408848373' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "clip" ADD "description" character varying(2048) DEFAULT null`); - } - - public async down(queryRunner: QueryRunner): Promise { - - await queryRunner.query(`ALTER TABLE "clip" DROP COLUMN "description"`); - } - -} diff --git a/migration/1605408971051-comments.ts b/migration/1605408971051-comments.ts deleted file mode 100644 index c69ae29a9..000000000 --- a/migration/1605408971051-comments.ts +++ /dev/null @@ -1,434 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class comments1605408971051 implements MigrationInterface { - name = 'comments1605408971051' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`COMMENT ON COLUMN "log"."createdAt" IS 'The created date of the Log.'`); - await queryRunner.query(`COMMENT ON COLUMN "drive_folder"."createdAt" IS 'The created date of the DriveFolder.'`); - await queryRunner.query(`COMMENT ON COLUMN "drive_folder"."name" IS 'The name of the DriveFolder.'`); - await queryRunner.query(`COMMENT ON COLUMN "drive_folder"."userId" IS 'The owner ID.'`); - await queryRunner.query(`COMMENT ON COLUMN "drive_folder"."parentId" IS 'The parent folder ID. If null, it means the DriveFolder is located in root.'`); - await queryRunner.query(`COMMENT ON COLUMN "drive_file"."createdAt" IS 'The created date of the DriveFile.'`); - await queryRunner.query(`COMMENT ON COLUMN "drive_file"."userId" IS 'The owner ID.'`); - await queryRunner.query(`COMMENT ON COLUMN "drive_file"."userHost" IS 'The host of owner. It will be null if the user in local.'`); - await queryRunner.query(`COMMENT ON COLUMN "drive_file"."md5" IS 'The MD5 hash of the DriveFile.'`); - await queryRunner.query(`COMMENT ON COLUMN "drive_file"."name" IS 'The file name of the DriveFile.'`); - await queryRunner.query(`COMMENT ON COLUMN "drive_file"."type" IS 'The content type (MIME) of the DriveFile.'`); - await queryRunner.query(`COMMENT ON COLUMN "drive_file"."size" IS 'The file size (bytes) of the DriveFile.'`); - await queryRunner.query(`COMMENT ON COLUMN "drive_file"."comment" IS 'The comment of the DriveFile.'`); - await queryRunner.query(`COMMENT ON COLUMN "drive_file"."blurhash" IS 'The BlurHash string.'`); - await queryRunner.query(`COMMENT ON COLUMN "drive_file"."properties" IS 'The any properties of the DriveFile. For example, it includes image width/height.'`); - await queryRunner.query(`COMMENT ON COLUMN "drive_file"."url" IS 'The URL of the DriveFile.'`); - await queryRunner.query(`COMMENT ON COLUMN "drive_file"."thumbnailUrl" IS 'The URL of the thumbnail of the DriveFile.'`); - await queryRunner.query(`COMMENT ON COLUMN "drive_file"."webpublicUrl" IS 'The URL of the webpublic of the DriveFile.'`); - await queryRunner.query(`COMMENT ON COLUMN "drive_file"."uri" IS 'The URI of the DriveFile. it will be null when the DriveFile is local.'`); - await queryRunner.query(`COMMENT ON COLUMN "drive_file"."folderId" IS 'The parent folder ID. If null, it means the DriveFile is located in root.'`); - await queryRunner.query(`COMMENT ON COLUMN "drive_file"."isSensitive" IS 'Whether the DriveFile is NSFW.'`); - await queryRunner.query(`COMMENT ON COLUMN "drive_file"."isLink" IS 'Whether the DriveFile is direct link to remote server.'`); - await queryRunner.query(`COMMENT ON COLUMN "user"."createdAt" IS 'The created date of the User.'`); - await queryRunner.query(`COMMENT ON COLUMN "user"."updatedAt" IS 'The updated date of the User.'`); - await queryRunner.query(`COMMENT ON COLUMN "user"."username" IS 'The username of the User.'`); - await queryRunner.query(`COMMENT ON COLUMN "user"."usernameLower" IS 'The username (lowercased) of the User.'`); - await queryRunner.query(`COMMENT ON COLUMN "user"."name" IS 'The name of the User.'`); - await queryRunner.query(`COMMENT ON COLUMN "user"."followersCount" IS 'The count of followers.'`); - await queryRunner.query(`COMMENT ON COLUMN "user"."followingCount" IS 'The count of following.'`); - await queryRunner.query(`COMMENT ON COLUMN "user"."notesCount" IS 'The count of notes.'`); - await queryRunner.query(`COMMENT ON COLUMN "user"."avatarId" IS 'The ID of avatar DriveFile.'`); - await queryRunner.query(`COMMENT ON COLUMN "user"."bannerId" IS 'The ID of banner DriveFile.'`); - await queryRunner.query(`COMMENT ON COLUMN "user"."isSuspended" IS 'Whether the User is suspended.'`); - await queryRunner.query(`COMMENT ON COLUMN "user"."isSilenced" IS 'Whether the User is silenced.'`); - await queryRunner.query(`COMMENT ON COLUMN "user"."isLocked" IS 'Whether the User is locked.'`); - await queryRunner.query(`COMMENT ON COLUMN "user"."isBot" IS 'Whether the User is a bot.'`); - await queryRunner.query(`COMMENT ON COLUMN "user"."isCat" IS 'Whether the User is a cat.'`); - await queryRunner.query(`COMMENT ON COLUMN "user"."isAdmin" IS 'Whether the User is the admin.'`); - await queryRunner.query(`COMMENT ON COLUMN "user"."isModerator" IS 'Whether the User is a moderator.'`); - await queryRunner.query(`COMMENT ON COLUMN "user"."host" IS 'The host of the User. It will be null if the origin of the user is local.'`); - await queryRunner.query(`COMMENT ON COLUMN "user"."inbox" IS 'The inbox URL of the User. It will be null if the origin of the user is local.'`); - await queryRunner.query(`COMMENT ON COLUMN "user"."sharedInbox" IS 'The sharedInbox URL of the User. It will be null if the origin of the user is local.'`); - await queryRunner.query(`COMMENT ON COLUMN "user"."featured" IS 'The featured URL of the User. It will be null if the origin of the user is local.'`); - await queryRunner.query(`COMMENT ON COLUMN "user"."uri" IS 'The URI of the User. It will be null if the origin of the user is local.'`); - await queryRunner.query(`COMMENT ON COLUMN "user"."token" IS 'The native access token of the User. It will be null if the origin of the user is local.'`); - await queryRunner.query(`COMMENT ON COLUMN "app"."createdAt" IS 'The created date of the App.'`); - await queryRunner.query(`COMMENT ON COLUMN "app"."userId" IS 'The owner ID.'`); - await queryRunner.query(`COMMENT ON COLUMN "app"."secret" IS 'The secret key of the App.'`); - await queryRunner.query(`COMMENT ON COLUMN "app"."name" IS 'The name of the App.'`); - await queryRunner.query(`COMMENT ON COLUMN "app"."description" IS 'The description of the App.'`); - await queryRunner.query(`COMMENT ON COLUMN "app"."permission" IS 'The permission of the App.'`); - await queryRunner.query(`COMMENT ON COLUMN "app"."callbackUrl" IS 'The callbackUrl of the App.'`); - await queryRunner.query(`COMMENT ON COLUMN "access_token"."createdAt" IS 'The created date of the AccessToken.'`); - await queryRunner.query(`COMMENT ON COLUMN "access_token"."lastUsedAt" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "access_token"."session" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "access_token"."appId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "access_token"."name" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "access_token"."description" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "access_token"."iconUrl" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "channel"."createdAt" IS 'The created date of the Channel.'`); - await queryRunner.query(`COMMENT ON COLUMN "channel"."userId" IS 'The owner ID.'`); - await queryRunner.query(`COMMENT ON COLUMN "channel"."name" IS 'The name of the Channel.'`); - await queryRunner.query(`COMMENT ON COLUMN "channel"."description" IS 'The description of the Channel.'`); - await queryRunner.query(`COMMENT ON COLUMN "channel"."bannerId" IS 'The ID of banner Channel.'`); - await queryRunner.query(`COMMENT ON COLUMN "channel"."notesCount" IS 'The count of notes.'`); - await queryRunner.query(`COMMENT ON COLUMN "channel"."usersCount" IS 'The count of users.'`); - await queryRunner.query(`COMMENT ON COLUMN "note"."createdAt" IS 'The created date of the Note.'`); - await queryRunner.query(`COMMENT ON COLUMN "note"."replyId" IS 'The ID of reply target.'`); - await queryRunner.query(`COMMENT ON COLUMN "note"."renoteId" IS 'The ID of renote target.'`); - await queryRunner.query(`COMMENT ON COLUMN "note"."userId" IS 'The ID of author.'`); - await queryRunner.query(`COMMENT ON COLUMN "note"."uri" IS 'The URI of a note. it will be null when the note is local.'`); - await queryRunner.query(`COMMENT ON COLUMN "note"."url" IS 'The human readable url of a note. it will be null when the note is local.'`); - await queryRunner.query(`COMMENT ON COLUMN "note"."channelId" IS 'The ID of source channel.'`); - await queryRunner.query(`COMMENT ON COLUMN "note"."userHost" IS '[Denormalized]'`); - await queryRunner.query(`COMMENT ON COLUMN "note"."replyUserId" IS '[Denormalized]'`); - await queryRunner.query(`COMMENT ON COLUMN "note"."replyUserHost" IS '[Denormalized]'`); - await queryRunner.query(`COMMENT ON COLUMN "note"."renoteUserId" IS '[Denormalized]'`); - await queryRunner.query(`COMMENT ON COLUMN "note"."renoteUserHost" IS '[Denormalized]'`); - await queryRunner.query(`COMMENT ON COLUMN "poll_vote"."createdAt" IS 'The created date of the PollVote.'`); - await queryRunner.query(`COMMENT ON COLUMN "note_reaction"."createdAt" IS 'The created date of the NoteReaction.'`); - await queryRunner.query(`COMMENT ON COLUMN "note_watching"."createdAt" IS 'The created date of the NoteWatching.'`); - await queryRunner.query(`COMMENT ON COLUMN "note_watching"."userId" IS 'The watcher ID.'`); - await queryRunner.query(`COMMENT ON COLUMN "note_watching"."noteId" IS 'The target Note ID.'`); - await queryRunner.query(`COMMENT ON COLUMN "note_watching"."noteUserId" IS '[Denormalized]'`); - await queryRunner.query(`COMMENT ON COLUMN "note_unread"."noteUserId" IS '[Denormalized]'`); - await queryRunner.query(`COMMENT ON COLUMN "note_unread"."noteChannelId" IS '[Denormalized]'`); - await queryRunner.query(`COMMENT ON COLUMN "follow_request"."createdAt" IS 'The created date of the FollowRequest.'`); - await queryRunner.query(`COMMENT ON COLUMN "follow_request"."followeeId" IS 'The followee user ID.'`); - await queryRunner.query(`COMMENT ON COLUMN "follow_request"."followerId" IS 'The follower user ID.'`); - await queryRunner.query(`COMMENT ON COLUMN "follow_request"."requestId" IS 'id of Follow Activity.'`); - await queryRunner.query(`COMMENT ON COLUMN "follow_request"."followerHost" IS '[Denormalized]'`); - await queryRunner.query(`COMMENT ON COLUMN "follow_request"."followerInbox" IS '[Denormalized]'`); - await queryRunner.query(`COMMENT ON COLUMN "follow_request"."followerSharedInbox" IS '[Denormalized]'`); - await queryRunner.query(`COMMENT ON COLUMN "follow_request"."followeeHost" IS '[Denormalized]'`); - await queryRunner.query(`COMMENT ON COLUMN "follow_request"."followeeInbox" IS '[Denormalized]'`); - await queryRunner.query(`COMMENT ON COLUMN "follow_request"."followeeSharedInbox" IS '[Denormalized]'`); - await queryRunner.query(`COMMENT ON COLUMN "user_group"."createdAt" IS 'The created date of the UserGroup.'`); - await queryRunner.query(`COMMENT ON COLUMN "user_group"."userId" IS 'The ID of owner.'`); - await queryRunner.query(`COMMENT ON COLUMN "user_group_invitation"."createdAt" IS 'The created date of the UserGroupInvitation.'`); - await queryRunner.query(`COMMENT ON COLUMN "user_group_invitation"."userId" IS 'The user ID.'`); - await queryRunner.query(`COMMENT ON COLUMN "user_group_invitation"."userGroupId" IS 'The group ID.'`); - await queryRunner.query(`COMMENT ON COLUMN "notification"."createdAt" IS 'The created date of the Notification.'`); - await queryRunner.query(`COMMENT ON COLUMN "notification"."notifieeId" IS 'The ID of recipient user of the Notification.'`); - await queryRunner.query(`COMMENT ON COLUMN "notification"."isRead" IS 'Whether the Notification is read.'`); - await queryRunner.query(`COMMENT ON COLUMN "meta"."localDriveCapacityMb" IS 'Drive capacity of a local user (MB)'`); - await queryRunner.query(`COMMENT ON COLUMN "meta"."remoteDriveCapacityMb" IS 'Drive capacity of a remote user (MB)'`); - await queryRunner.query(`COMMENT ON COLUMN "meta"."maxNoteTextLength" IS 'Max allowed note text length in characters'`); - await queryRunner.query(`COMMENT ON COLUMN "following"."createdAt" IS 'The created date of the Following.'`); - await queryRunner.query(`COMMENT ON COLUMN "following"."followeeId" IS 'The followee user ID.'`); - await queryRunner.query(`COMMENT ON COLUMN "following"."followerId" IS 'The follower user ID.'`); - await queryRunner.query(`COMMENT ON COLUMN "following"."followerHost" IS '[Denormalized]'`); - await queryRunner.query(`COMMENT ON COLUMN "following"."followerInbox" IS '[Denormalized]'`); - await queryRunner.query(`COMMENT ON COLUMN "following"."followerSharedInbox" IS '[Denormalized]'`); - await queryRunner.query(`COMMENT ON COLUMN "following"."followeeHost" IS '[Denormalized]'`); - await queryRunner.query(`COMMENT ON COLUMN "following"."followeeInbox" IS '[Denormalized]'`); - await queryRunner.query(`COMMENT ON COLUMN "following"."followeeSharedInbox" IS '[Denormalized]'`); - await queryRunner.query(`COMMENT ON COLUMN "instance"."caughtAt" IS 'The caught date of the Instance.'`); - await queryRunner.query(`COMMENT ON COLUMN "instance"."host" IS 'The host of the Instance.'`); - await queryRunner.query(`COMMENT ON COLUMN "instance"."usersCount" IS 'The count of the users of the Instance.'`); - await queryRunner.query(`COMMENT ON COLUMN "instance"."notesCount" IS 'The count of the notes of the Instance.'`); - await queryRunner.query(`COMMENT ON COLUMN "instance"."softwareName" IS 'The software of the Instance.'`); - await queryRunner.query(`COMMENT ON COLUMN "instance"."softwareVersion" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "instance"."openRegistrations" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "instance"."name" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "instance"."description" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "instance"."maintainerName" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "instance"."maintainerEmail" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "instance"."iconUrl" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "instance"."faviconUrl" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "instance"."themeColor" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "muting"."createdAt" IS 'The created date of the Muting.'`); - await queryRunner.query(`COMMENT ON COLUMN "muting"."muteeId" IS 'The mutee user ID.'`); - await queryRunner.query(`COMMENT ON COLUMN "muting"."muterId" IS 'The muter user ID.'`); - await queryRunner.query(`COMMENT ON COLUMN "blocking"."createdAt" IS 'The created date of the Blocking.'`); - await queryRunner.query(`COMMENT ON COLUMN "blocking"."blockeeId" IS 'The blockee user ID.'`); - await queryRunner.query(`COMMENT ON COLUMN "blocking"."blockerId" IS 'The blocker user ID.'`); - await queryRunner.query(`COMMENT ON COLUMN "user_list"."createdAt" IS 'The created date of the UserList.'`); - await queryRunner.query(`COMMENT ON COLUMN "user_list"."userId" IS 'The owner ID.'`); - await queryRunner.query(`COMMENT ON COLUMN "user_list"."name" IS 'The name of the UserList.'`); - await queryRunner.query(`COMMENT ON COLUMN "user_list_joining"."createdAt" IS 'The created date of the UserListJoining.'`); - await queryRunner.query(`COMMENT ON COLUMN "user_list_joining"."userId" IS 'The user ID.'`); - await queryRunner.query(`COMMENT ON COLUMN "user_list_joining"."userListId" IS 'The list ID.'`); - await queryRunner.query(`COMMENT ON COLUMN "user_group_joining"."createdAt" IS 'The created date of the UserGroupJoining.'`); - await queryRunner.query(`COMMENT ON COLUMN "user_group_joining"."userId" IS 'The user ID.'`); - await queryRunner.query(`COMMENT ON COLUMN "user_group_joining"."userGroupId" IS 'The group ID.'`); - await queryRunner.query(`COMMENT ON COLUMN "note_favorite"."createdAt" IS 'The created date of the NoteFavorite.'`); - await queryRunner.query(`COMMENT ON COLUMN "abuse_user_report"."createdAt" IS 'The created date of the AbuseUserReport.'`); - await queryRunner.query(`COMMENT ON COLUMN "abuse_user_report"."targetUserHost" IS '[Denormalized]'`); - await queryRunner.query(`COMMENT ON COLUMN "abuse_user_report"."reporterHost" IS '[Denormalized]'`); - await queryRunner.query(`COMMENT ON COLUMN "messaging_message"."createdAt" IS 'The created date of the MessagingMessage.'`); - await queryRunner.query(`COMMENT ON COLUMN "messaging_message"."userId" IS 'The sender user ID.'`); - await queryRunner.query(`COMMENT ON COLUMN "messaging_message"."groupId" IS 'The recipient group ID.'`); - await queryRunner.query(`COMMENT ON COLUMN "signin"."createdAt" IS 'The created date of the Signin.'`); - await queryRunner.query(`COMMENT ON COLUMN "auth_session"."createdAt" IS 'The created date of the AuthSession.'`); - await queryRunner.query(`COMMENT ON COLUMN "reversi_game"."createdAt" IS 'The created date of the ReversiGame.'`); - await queryRunner.query(`COMMENT ON COLUMN "reversi_game"."startedAt" IS 'The started date of the ReversiGame.'`); - await queryRunner.query(`COMMENT ON COLUMN "reversi_game"."form1" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "reversi_game"."form2" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "reversi_matching"."createdAt" IS 'The created date of the ReversiMatching.'`); - await queryRunner.query(`COMMENT ON COLUMN "user_note_pining"."createdAt" IS 'The created date of the UserNotePinings.'`); - await queryRunner.query(`COMMENT ON COLUMN "poll"."noteId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "poll"."noteVisibility" IS '[Denormalized]'`); - await queryRunner.query(`COMMENT ON COLUMN "poll"."userId" IS '[Denormalized]'`); - await queryRunner.query(`COMMENT ON COLUMN "poll"."userHost" IS '[Denormalized]'`); - await queryRunner.query(`COMMENT ON COLUMN "user_keypair"."userId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user_publickey"."userId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "page"."createdAt" IS 'The created date of the Page.'`); - await queryRunner.query(`COMMENT ON COLUMN "page"."updatedAt" IS 'The updated date of the Page.'`); - await queryRunner.query(`COMMENT ON COLUMN "page"."userId" IS 'The ID of author.'`); - await queryRunner.query(`COMMENT ON COLUMN "user_profile"."userId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user_profile"."location" IS 'The location of the User.'`); - await queryRunner.query(`COMMENT ON COLUMN "user_profile"."birthday" IS 'The birthday (YYYY-MM-DD) of the User.'`); - await queryRunner.query(`COMMENT ON COLUMN "user_profile"."description" IS 'The description (bio) of the User.'`); - await queryRunner.query(`COMMENT ON COLUMN "user_profile"."url" IS 'Remote URL of the user.'`); - await queryRunner.query(`COMMENT ON COLUMN "user_profile"."email" IS 'The email address of the User.'`); - await queryRunner.query(`COMMENT ON COLUMN "user_profile"."password" IS 'The password hash of the User. It will be null if the origin of the user is local.'`); - await queryRunner.query(`COMMENT ON COLUMN "user_profile"."clientData" IS 'The client-specific data of the User.'`); - await queryRunner.query(`COMMENT ON COLUMN "user_profile"."room" IS 'The room data of the User.'`); - await queryRunner.query(`COMMENT ON COLUMN "user_profile"."userHost" IS '[Denormalized]'`); - await queryRunner.query(`COMMENT ON COLUMN "user_security_key"."id" IS 'Variable-length id given to navigator.credentials.get()'`); - await queryRunner.query(`COMMENT ON COLUMN "user_security_key"."publicKey" IS 'Variable-length public key used to verify attestations (hex-encoded).'`); - await queryRunner.query(`COMMENT ON COLUMN "user_security_key"."lastUsed" IS 'The date of the last time the UserSecurityKey was successfully validated.'`); - await queryRunner.query(`COMMENT ON COLUMN "user_security_key"."name" IS 'User-defined name for this key'`); - await queryRunner.query(`COMMENT ON COLUMN "attestation_challenge"."challenge" IS 'Hex-encoded sha256 hash of the challenge.'`); - await queryRunner.query(`COMMENT ON COLUMN "attestation_challenge"."createdAt" IS 'The date challenge was created for expiry purposes.'`); - await queryRunner.query(`COMMENT ON COLUMN "attestation_challenge"."registrationChallenge" IS 'Indicates that the challenge is only for registration purposes if true to prevent the challenge for being used as authentication.'`); - await queryRunner.query(`COMMENT ON COLUMN "moderation_log"."createdAt" IS 'The created date of the ModerationLog.'`); - await queryRunner.query(`COMMENT ON COLUMN "announcement"."createdAt" IS 'The created date of the Announcement.'`); - await queryRunner.query(`COMMENT ON COLUMN "announcement"."updatedAt" IS 'The updated date of the Announcement.'`); - await queryRunner.query(`COMMENT ON COLUMN "announcement_read"."createdAt" IS 'The created date of the AnnouncementRead.'`); - await queryRunner.query(`COMMENT ON COLUMN "clip"."createdAt" IS 'The created date of the Clip.'`); - await queryRunner.query(`COMMENT ON COLUMN "clip"."userId" IS 'The owner ID.'`); - await queryRunner.query(`COMMENT ON COLUMN "clip"."name" IS 'The name of the Clip.'`); - await queryRunner.query(`COMMENT ON COLUMN "clip"."description" IS 'The description of the Clip.'`); - await queryRunner.query(`COMMENT ON COLUMN "clip_note"."noteId" IS 'The note ID.'`); - await queryRunner.query(`COMMENT ON COLUMN "clip_note"."clipId" IS 'The clip ID.'`); - await queryRunner.query(`COMMENT ON COLUMN "antenna"."createdAt" IS 'The created date of the Antenna.'`); - await queryRunner.query(`COMMENT ON COLUMN "antenna"."userId" IS 'The owner ID.'`); - await queryRunner.query(`COMMENT ON COLUMN "antenna"."name" IS 'The name of the Antenna.'`); - await queryRunner.query(`COMMENT ON COLUMN "antenna_note"."noteId" IS 'The note ID.'`); - await queryRunner.query(`COMMENT ON COLUMN "antenna_note"."antennaId" IS 'The antenna ID.'`); - await queryRunner.query(`COMMENT ON COLUMN "promo_note"."noteId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "promo_note"."userId" IS '[Denormalized]'`); - await queryRunner.query(`COMMENT ON COLUMN "promo_read"."createdAt" IS 'The created date of the PromoRead.'`); - await queryRunner.query(`COMMENT ON COLUMN "muted_note"."noteId" IS 'The note ID.'`); - await queryRunner.query(`COMMENT ON COLUMN "muted_note"."userId" IS 'The user ID.'`); - await queryRunner.query(`COMMENT ON COLUMN "muted_note"."reason" IS 'The reason of the MutedNote.'`); - await queryRunner.query(`COMMENT ON COLUMN "channel_following"."createdAt" IS 'The created date of the ChannelFollowing.'`); - await queryRunner.query(`COMMENT ON COLUMN "channel_following"."followeeId" IS 'The followee channel ID.'`); - await queryRunner.query(`COMMENT ON COLUMN "channel_following"."followerId" IS 'The follower user ID.'`); - await queryRunner.query(`COMMENT ON COLUMN "channel_note_pining"."createdAt" IS 'The created date of the ChannelNotePining.'`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`COMMENT ON COLUMN "channel_note_pining"."createdAt" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "channel_following"."followerId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "channel_following"."followeeId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "channel_following"."createdAt" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "muted_note"."reason" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "muted_note"."userId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "muted_note"."noteId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "promo_read"."createdAt" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "promo_note"."userId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "promo_note"."noteId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "antenna_note"."antennaId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "antenna_note"."noteId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "antenna"."name" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "antenna"."userId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "antenna"."createdAt" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "clip_note"."clipId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "clip_note"."noteId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "clip"."description" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "clip"."name" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "clip"."userId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "clip"."createdAt" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "announcement_read"."createdAt" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "announcement"."updatedAt" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "announcement"."createdAt" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "moderation_log"."createdAt" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "attestation_challenge"."registrationChallenge" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "attestation_challenge"."createdAt" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "attestation_challenge"."challenge" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user_security_key"."name" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user_security_key"."lastUsed" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user_security_key"."publicKey" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user_security_key"."id" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user_profile"."userHost" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user_profile"."room" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user_profile"."clientData" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user_profile"."password" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user_profile"."email" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user_profile"."url" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user_profile"."description" IS 'The description (bio) of the User.'`); - await queryRunner.query(`COMMENT ON COLUMN "user_profile"."birthday" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user_profile"."location" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user_profile"."userId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "page"."userId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "page"."updatedAt" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "page"."createdAt" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user_publickey"."userId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user_keypair"."userId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "poll"."userHost" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "poll"."userId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "poll"."noteVisibility" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "poll"."noteId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user_note_pining"."createdAt" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "reversi_matching"."createdAt" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "reversi_game"."form2" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "reversi_game"."form1" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "reversi_game"."startedAt" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "reversi_game"."createdAt" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "auth_session"."createdAt" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "signin"."createdAt" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "messaging_message"."groupId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "messaging_message"."userId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "messaging_message"."createdAt" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "abuse_user_report"."reporterHost" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "abuse_user_report"."targetUserHost" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "abuse_user_report"."createdAt" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "note_favorite"."createdAt" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user_group_joining"."userGroupId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user_group_joining"."userId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user_group_joining"."createdAt" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user_list_joining"."userListId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user_list_joining"."userId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user_list_joining"."createdAt" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user_list"."name" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user_list"."userId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user_list"."createdAt" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "blocking"."blockerId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "blocking"."blockeeId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "blocking"."createdAt" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "muting"."muterId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "muting"."muteeId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "muting"."createdAt" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "instance"."themeColor" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "instance"."faviconUrl" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "instance"."iconUrl" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "instance"."maintainerEmail" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "instance"."maintainerName" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "instance"."description" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "instance"."name" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "instance"."openRegistrations" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "instance"."softwareVersion" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "instance"."softwareName" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "instance"."notesCount" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "instance"."usersCount" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "instance"."host" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "instance"."caughtAt" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "following"."followeeSharedInbox" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "following"."followeeInbox" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "following"."followeeHost" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "following"."followerSharedInbox" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "following"."followerInbox" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "following"."followerHost" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "following"."followerId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "following"."followeeId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "following"."createdAt" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "meta"."maxNoteTextLength" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "meta"."remoteDriveCapacityMb" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "meta"."localDriveCapacityMb" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "notification"."isRead" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "notification"."notifieeId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "notification"."createdAt" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user_group_invitation"."userGroupId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user_group_invitation"."userId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user_group_invitation"."createdAt" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user_group"."userId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user_group"."createdAt" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "follow_request"."followeeSharedInbox" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "follow_request"."followeeInbox" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "follow_request"."followeeHost" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "follow_request"."followerSharedInbox" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "follow_request"."followerInbox" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "follow_request"."followerHost" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "follow_request"."requestId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "follow_request"."followerId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "follow_request"."followeeId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "follow_request"."createdAt" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "note_unread"."noteChannelId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "note_unread"."noteUserId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "note_watching"."noteUserId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "note_watching"."noteId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "note_watching"."userId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "note_watching"."createdAt" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "note_reaction"."createdAt" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "poll_vote"."createdAt" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "note"."renoteUserHost" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "note"."renoteUserId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "note"."replyUserHost" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "note"."replyUserId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "note"."userHost" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "note"."channelId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "note"."url" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "note"."uri" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "note"."userId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "note"."renoteId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "note"."replyId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "note"."createdAt" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "channel"."usersCount" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "channel"."notesCount" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "channel"."bannerId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "channel"."description" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "channel"."name" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "channel"."userId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "channel"."createdAt" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "access_token"."iconUrl" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "access_token"."description" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "access_token"."name" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "access_token"."appId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "access_token"."session" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "access_token"."lastUsedAt" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "access_token"."createdAt" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "app"."callbackUrl" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "app"."permission" IS 'The permission of the App.'`); - await queryRunner.query(`COMMENT ON COLUMN "app"."description" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "app"."name" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "app"."secret" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "app"."userId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "app"."createdAt" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user"."token" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user"."uri" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user"."featured" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user"."sharedInbox" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user"."inbox" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user"."host" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user"."isModerator" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user"."isAdmin" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user"."isCat" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user"."isBot" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user"."isLocked" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user"."isSilenced" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user"."isSuspended" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user"."bannerId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user"."avatarId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user"."notesCount" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user"."followingCount" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user"."followersCount" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user"."name" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user"."usernameLower" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user"."username" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user"."updatedAt" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user"."createdAt" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "drive_file"."isLink" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "drive_file"."isSensitive" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "drive_file"."folderId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "drive_file"."uri" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "drive_file"."webpublicUrl" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "drive_file"."thumbnailUrl" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "drive_file"."url" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "drive_file"."properties" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "drive_file"."blurhash" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "drive_file"."comment" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "drive_file"."size" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "drive_file"."type" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "drive_file"."name" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "drive_file"."md5" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "drive_file"."userHost" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "drive_file"."userId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "drive_file"."createdAt" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "drive_folder"."parentId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "drive_folder"."userId" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "drive_folder"."name" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "drive_folder"."createdAt" IS NULL`); - await queryRunner.query(`COMMENT ON COLUMN "log"."createdAt" IS NULL`); - } - -} diff --git a/migration/1605585339718-instance-pinned-pages.ts b/migration/1605585339718-instance-pinned-pages.ts deleted file mode 100644 index f59346130..000000000 --- a/migration/1605585339718-instance-pinned-pages.ts +++ /dev/null @@ -1,14 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class instancePinnedPages1605585339718 implements MigrationInterface { - name = 'instancePinnedPages1605585339718' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "meta" ADD "pinnedPages" character varying(512) array NOT NULL DEFAULT '{"/featured", "/channels", "/explore", "/pages", "/about-misskey"}'::varchar[]`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "pinnedPages"`); - } - -} diff --git a/migration/1605965516823-instance-images.ts b/migration/1605965516823-instance-images.ts deleted file mode 100644 index bf8d40856..000000000 --- a/migration/1605965516823-instance-images.ts +++ /dev/null @@ -1,16 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class instanceImages1605965516823 implements MigrationInterface { - name = 'instanceImages1605965516823' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "meta" ADD "backgroundImageUrl" character varying(512)`); - await queryRunner.query(`ALTER TABLE "meta" ADD "logoImageUrl" character varying(512)`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "logoImageUrl"`); - await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "backgroundImageUrl"`); - } - -} diff --git a/migration/1606191203881-no-crawle.ts b/migration/1606191203881-no-crawle.ts deleted file mode 100644 index accc8f8fe..000000000 --- a/migration/1606191203881-no-crawle.ts +++ /dev/null @@ -1,16 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class noCrawle1606191203881 implements MigrationInterface { - name = 'noCrawle1606191203881' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user_profile" ADD "noCrawle" boolean NOT NULL DEFAULT false`); - await queryRunner.query(`COMMENT ON COLUMN "user_profile"."noCrawle" IS 'Whether reject index by crawler.'`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`COMMENT ON COLUMN "user_profile"."noCrawle" IS 'Whether reject index by crawler.'`); - await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "noCrawle"`); - } - -} diff --git a/migration/1607151207216-instance-pinned-clip.ts b/migration/1607151207216-instance-pinned-clip.ts deleted file mode 100644 index 7e2c8b7de..000000000 --- a/migration/1607151207216-instance-pinned-clip.ts +++ /dev/null @@ -1,14 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class instancePinnedClip1607151207216 implements MigrationInterface { - name = 'instancePinnedClip1607151207216' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "meta" ADD "pinnedClipId" character varying(32)`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "pinnedClipId"`); - } - -} diff --git a/migration/1607353487793-isExplorable.ts b/migration/1607353487793-isExplorable.ts deleted file mode 100644 index 034f8c384..000000000 --- a/migration/1607353487793-isExplorable.ts +++ /dev/null @@ -1,18 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class isExplorable1607353487793 implements MigrationInterface { - name = 'isExplorable1607353487793' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user" ADD "isExplorable" boolean NOT NULL DEFAULT true`); - await queryRunner.query(`COMMENT ON COLUMN "user"."isExplorable" IS 'Whether the User is explorable.'`); - await queryRunner.query(`CREATE INDEX "IDX_d5a1b83c7cab66f167e6888188" ON "user" ("isExplorable") `); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`DROP INDEX "IDX_d5a1b83c7cab66f167e6888188"`); - await queryRunner.query(`COMMENT ON COLUMN "user"."isExplorable" IS 'Whether the User is explorable.'`); - await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "isExplorable"`); - } - -} diff --git a/migration/1610277136869-registry.ts b/migration/1610277136869-registry.ts deleted file mode 100644 index 46c8113c1..000000000 --- a/migration/1610277136869-registry.ts +++ /dev/null @@ -1,22 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class registry1610277136869 implements MigrationInterface { - name = 'registry1610277136869' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE TABLE "registry_item" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "key" character varying(1024) NOT NULL, "scope" character varying(1024) array NOT NULL DEFAULT '{}'::varchar[], "domain" character varying(512), CONSTRAINT "PK_64b3f7e6008b4d89b826cd3af95" PRIMARY KEY ("id")); COMMENT ON COLUMN "registry_item"."createdAt" IS 'The created date of the RegistryItem.'; COMMENT ON COLUMN "registry_item"."updatedAt" IS 'The updated date of the RegistryItem.'; COMMENT ON COLUMN "registry_item"."userId" IS 'The owner ID.'; COMMENT ON COLUMN "registry_item"."key" IS 'The key of the RegistryItem.'`); - await queryRunner.query(`CREATE INDEX "IDX_fb9d21ba0abb83223263df6bcb" ON "registry_item" ("userId") `); - await queryRunner.query(`CREATE INDEX "IDX_22baca135bb8a3ea1a83d13df3" ON "registry_item" ("scope") `); - await queryRunner.query(`CREATE INDEX "IDX_0a72bdfcdb97c0eca11fe7ecad" ON "registry_item" ("domain") `); - await queryRunner.query(`ALTER TABLE "registry_item" ADD CONSTRAINT "FK_fb9d21ba0abb83223263df6bcb3" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "registry_item" DROP CONSTRAINT "FK_fb9d21ba0abb83223263df6bcb3"`); - await queryRunner.query(`DROP INDEX "IDX_0a72bdfcdb97c0eca11fe7ecad"`); - await queryRunner.query(`DROP INDEX "IDX_22baca135bb8a3ea1a83d13df3"`); - await queryRunner.query(`DROP INDEX "IDX_fb9d21ba0abb83223263df6bcb"`); - await queryRunner.query(`DROP TABLE "registry_item"`); - } - -} diff --git a/migration/1610277585759-registry2.ts b/migration/1610277585759-registry2.ts deleted file mode 100644 index 2f2d80c48..000000000 --- a/migration/1610277585759-registry2.ts +++ /dev/null @@ -1,16 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class registry21610277585759 implements MigrationInterface { - name = 'registry21610277585759' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "registry_item" ADD "value" jsonb NOT NULL DEFAULT '{}'`); - await queryRunner.query(`COMMENT ON COLUMN "registry_item"."value" IS 'The value of the RegistryItem.'`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`COMMENT ON COLUMN "registry_item"."value" IS 'The value of the RegistryItem.'`); - await queryRunner.query(`ALTER TABLE "registry_item" DROP COLUMN "value"`); - } - -} diff --git a/migration/1610283021566-registry3.ts b/migration/1610283021566-registry3.ts deleted file mode 100644 index 61f235fb2..000000000 --- a/migration/1610283021566-registry3.ts +++ /dev/null @@ -1,14 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class registry31610283021566 implements MigrationInterface { - name = 'registry31610283021566' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "registry_item" ALTER COLUMN "value" DROP NOT NULL`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "registry_item" ALTER COLUMN "value" SET NOT NULL`); - } - -} diff --git a/migration/1611354329133-followersUri.ts b/migration/1611354329133-followersUri.ts deleted file mode 100644 index 5114418ae..000000000 --- a/migration/1611354329133-followersUri.ts +++ /dev/null @@ -1,16 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class followersUri1611354329133 implements MigrationInterface { - name = 'followersUri1611354329133' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user" ADD "followersUri" varchar(512) DEFAULT NULL`); - await queryRunner.query(`COMMENT ON COLUMN "user"."followersUri" IS 'The URI of the user Follower Collection. It will be null if the origin of the user is local.'`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`COMMENT ON COLUMN "user"."followersUri" IS 'The URI of the user Follower Collection. It will be null if the origin of the user is local.'`); - await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "followersUri"`); - } - -} diff --git a/migration/1611397665007-gallery.ts b/migration/1611397665007-gallery.ts deleted file mode 100644 index 1b64490fe..000000000 --- a/migration/1611397665007-gallery.ts +++ /dev/null @@ -1,40 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class gallery1611397665007 implements MigrationInterface { - name = 'gallery1611397665007' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE TABLE "gallery_post" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL, "title" character varying(256) NOT NULL, "description" character varying(2048), "userId" character varying(32) NOT NULL, "fileIds" character varying(32) array NOT NULL DEFAULT '{}'::varchar[], "isSensitive" boolean NOT NULL DEFAULT false, "likedCount" integer NOT NULL DEFAULT '0', "tags" character varying(128) array NOT NULL DEFAULT '{}'::varchar[], CONSTRAINT "PK_8e90d7b6015f2c4518881b14753" PRIMARY KEY ("id")); COMMENT ON COLUMN "gallery_post"."createdAt" IS 'The created date of the GalleryPost.'; COMMENT ON COLUMN "gallery_post"."updatedAt" IS 'The updated date of the GalleryPost.'; COMMENT ON COLUMN "gallery_post"."userId" IS 'The ID of author.'; COMMENT ON COLUMN "gallery_post"."isSensitive" IS 'Whether the post is sensitive.'`); - await queryRunner.query(`CREATE INDEX "IDX_8f1a239bd077c8864a20c62c2c" ON "gallery_post" ("createdAt") `); - await queryRunner.query(`CREATE INDEX "IDX_f631d37835adb04792e361807c" ON "gallery_post" ("updatedAt") `); - await queryRunner.query(`CREATE INDEX "IDX_985b836dddd8615e432d7043dd" ON "gallery_post" ("userId") `); - await queryRunner.query(`CREATE INDEX "IDX_3ca50563facd913c425e7a89ee" ON "gallery_post" ("fileIds") `); - await queryRunner.query(`CREATE INDEX "IDX_f2d744d9a14d0dfb8b96cb7fc5" ON "gallery_post" ("isSensitive") `); - await queryRunner.query(`CREATE INDEX "IDX_1a165c68a49d08f11caffbd206" ON "gallery_post" ("likedCount") `); - await queryRunner.query(`CREATE INDEX "IDX_05cca34b985d1b8edc1d1e28df" ON "gallery_post" ("tags") `); - await queryRunner.query(`CREATE TABLE "gallery_like" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "postId" character varying(32) NOT NULL, CONSTRAINT "PK_853ab02be39b8de45cd720cc15f" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE INDEX "IDX_8fd5215095473061855ceb948c" ON "gallery_like" ("userId") `); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_df1b5f4099e99fb0bc5eae53b6" ON "gallery_like" ("userId", "postId") `); - await queryRunner.query(`ALTER TABLE "gallery_post" ADD CONSTRAINT "FK_985b836dddd8615e432d7043ddb" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "gallery_like" ADD CONSTRAINT "FK_8fd5215095473061855ceb948cf" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "gallery_like" ADD CONSTRAINT "FK_b1cb568bfe569e47b7051699fc8" FOREIGN KEY ("postId") REFERENCES "gallery_post"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "gallery_like" DROP CONSTRAINT "FK_b1cb568bfe569e47b7051699fc8"`); - await queryRunner.query(`ALTER TABLE "gallery_like" DROP CONSTRAINT "FK_8fd5215095473061855ceb948cf"`); - await queryRunner.query(`ALTER TABLE "gallery_post" DROP CONSTRAINT "FK_985b836dddd8615e432d7043ddb"`); - await queryRunner.query(`DROP INDEX "IDX_df1b5f4099e99fb0bc5eae53b6"`); - await queryRunner.query(`DROP INDEX "IDX_8fd5215095473061855ceb948c"`); - await queryRunner.query(`DROP TABLE "gallery_like"`); - await queryRunner.query(`DROP INDEX "IDX_05cca34b985d1b8edc1d1e28df"`); - await queryRunner.query(`DROP INDEX "IDX_1a165c68a49d08f11caffbd206"`); - await queryRunner.query(`DROP INDEX "IDX_f2d744d9a14d0dfb8b96cb7fc5"`); - await queryRunner.query(`DROP INDEX "IDX_3ca50563facd913c425e7a89ee"`); - await queryRunner.query(`DROP INDEX "IDX_985b836dddd8615e432d7043dd"`); - await queryRunner.query(`DROP INDEX "IDX_f631d37835adb04792e361807c"`); - await queryRunner.query(`DROP INDEX "IDX_8f1a239bd077c8864a20c62c2c"`); - await queryRunner.query(`DROP TABLE "gallery_post"`); - } - -} diff --git a/migration/1611547387175-objectStorageS3ForcePathStyle.ts b/migration/1611547387175-objectStorageS3ForcePathStyle.ts deleted file mode 100644 index 1506a2900..000000000 --- a/migration/1611547387175-objectStorageS3ForcePathStyle.ts +++ /dev/null @@ -1,14 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class objectStorageS3ForcePathStyle1611547387175 implements MigrationInterface { - name = 'objectStorageS3ForcePathStyle1611547387175' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "meta" ADD "objectStorageS3ForcePathStyle" boolean NOT NULL DEFAULT true`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStorageS3ForcePathStyle"`); - } - -} diff --git a/migration/1612619156584-announcement-email.ts b/migration/1612619156584-announcement-email.ts deleted file mode 100644 index 0371daf8f..000000000 --- a/migration/1612619156584-announcement-email.ts +++ /dev/null @@ -1,14 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class announcementEmail1612619156584 implements MigrationInterface { - name = 'announcementEmail1612619156584' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user_profile" ADD "receiveAnnouncementEmail" boolean NOT NULL DEFAULT true`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "receiveAnnouncementEmail"`); - } - -} diff --git a/migration/1613155914446-emailNotificationTypes.ts b/migration/1613155914446-emailNotificationTypes.ts deleted file mode 100644 index d6908aecf..000000000 --- a/migration/1613155914446-emailNotificationTypes.ts +++ /dev/null @@ -1,14 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class emailNotificationTypes1613155914446 implements MigrationInterface { - name = 'emailNotificationTypes1613155914446' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user_profile" ADD "emailNotificationTypes" jsonb NOT NULL DEFAULT '["follow","receiveFollowRequest","groupInvited"]'`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "emailNotificationTypes"`); - } - -} diff --git a/migration/1613181457597-user-lang.ts b/migration/1613181457597-user-lang.ts deleted file mode 100644 index ac1fc88c9..000000000 --- a/migration/1613181457597-user-lang.ts +++ /dev/null @@ -1,14 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class userLang1613181457597 implements MigrationInterface { - name = 'userLang1613181457597' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user_profile" ADD "lang" character varying(32)`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "lang"`); - } - -} diff --git a/migration/1613503367223-use-bigint-for-driveUsage.ts b/migration/1613503367223-use-bigint-for-driveUsage.ts deleted file mode 100644 index d04e817ec..000000000 --- a/migration/1613503367223-use-bigint-for-driveUsage.ts +++ /dev/null @@ -1,15 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class useBigintForDriveUsage1613503367223 implements MigrationInterface { - name = 'useBigintForDriveUsage1613503367223' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "instance" ALTER COLUMN "driveUsage" TYPE bigint`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "driveUsage"`); - await queryRunner.query(`ALTER TABLE "instance" ADD "driveUsage" integer NOT NULL DEFAULT 0`); - } - -} diff --git a/migration/1615965918224-chart-v2.ts b/migration/1615965918224-chart-v2.ts deleted file mode 100644 index cacbd1945..000000000 --- a/migration/1615965918224-chart-v2.ts +++ /dev/null @@ -1,218 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class chartV21615965918224 implements MigrationInterface { - name = 'chartV21615965918224' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`DELETE FROM "__chart__active_users" WHERE "span" = 'day'`); - await queryRunner.query(`DELETE FROM "__chart__drive" WHERE "span" = 'day'`); - await queryRunner.query(`DELETE FROM "__chart__federation" WHERE "span" = 'day'`); - await queryRunner.query(`DELETE FROM "__chart__hashtag" WHERE "span" = 'day'`); - await queryRunner.query(`DELETE FROM "__chart__instance" WHERE "span" = 'day'`); - await queryRunner.query(`DELETE FROM "__chart__network" WHERE "span" = 'day'`); - await queryRunner.query(`DELETE FROM "__chart__notes" WHERE "span" = 'day'`); - await queryRunner.query(`DELETE FROM "__chart__per_user_drive" WHERE "span" = 'day'`); - await queryRunner.query(`DELETE FROM "__chart__per_user_following" WHERE "span" = 'day'`); - await queryRunner.query(`DELETE FROM "__chart__per_user_notes" WHERE "span" = 'day'`); - await queryRunner.query(`DELETE FROM "__chart__per_user_reaction" WHERE "span" = 'day'`); - await queryRunner.query(`DELETE FROM "__chart__test" WHERE "span" = 'day'`); - await queryRunner.query(`DELETE FROM "__chart__test_grouped" WHERE "span" = 'day'`); - await queryRunner.query(`DELETE FROM "__chart__test_unique" WHERE "span" = 'day'`); - await queryRunner.query(`DELETE FROM "__chart__users" WHERE "span" = 'day'`); - - await queryRunner.query(`DROP INDEX "IDX_15e91a03aeeac9dbccdf43fc06"`); - await queryRunner.query(`DROP INDEX "IDX_20f57cc8f142c131340ee16742"`); - await queryRunner.query(`DROP INDEX "IDX_c26e2c1cbb6e911e0554b27416"`); - await queryRunner.query(`DROP INDEX "IDX_3fa0d0f17ca72e3dc80999a032"`); - await queryRunner.query(`DROP INDEX "IDX_6e1df243476e20cbf86572ecc0"`); - await queryRunner.query(`DROP INDEX "IDX_06690fc959f1c9fdaf21928222"`); - await queryRunner.query(`DROP INDEX "IDX_e447064455928cf627590ef527"`); - await queryRunner.query(`DROP INDEX "IDX_2d416e6af791a82e338c79d480"`); - await queryRunner.query(`DROP INDEX "IDX_e9cd07672b37d8966cf3709283"`); - await queryRunner.query(`DROP INDEX "IDX_fcc181fb8283009c61cc4083ef"`); - await queryRunner.query(`DROP INDEX "IDX_49975586f50ed7b800fdd88fbd"`); - await queryRunner.query(`DROP INDEX "IDX_6d6f156ceefc6bc5f273a0e370"`); - await queryRunner.query(`DROP INDEX "IDX_c12f0af4a66cdd30c2287ce8aa"`); - await queryRunner.query(`DROP INDEX "IDX_d0a4f79af5a97b08f37b547197"`); - await queryRunner.query(`DROP INDEX "IDX_f5448d9633cff74208d850aabe"`); - await queryRunner.query(`DROP INDEX "IDX_f8dd01baeded2ffa833e0a610a"`); - await queryRunner.query(`DROP INDEX "IDX_08fac0eb3b11f04c200c0b40dd"`); - await queryRunner.query(`DROP INDEX "IDX_9ff6944f01acb756fdc92d7563"`); - await queryRunner.query(`DROP INDEX "IDX_e69096589f11e3baa98ddd64d0"`); - await queryRunner.query(`DROP INDEX "IDX_0c9a159c5082cbeef3ca6706b5"`); - await queryRunner.query(`DROP INDEX "IDX_924fc196c80ca24bae01dd37e4"`); - await queryRunner.query(`DROP INDEX "IDX_328f259961e60c4fa0bfcf55ca"`); - await queryRunner.query(`DROP INDEX "IDX_42ea9381f0fda8dfe0fa1c8b53"`); - await queryRunner.query(`DROP INDEX "IDX_f2aeafde2ae6fbad38e857631b"`); - await queryRunner.query(`DROP INDEX "IDX_f92dd6d03f8d994f29987f6214"`); - await queryRunner.query(`DROP INDEX "IDX_57b5458d0d3d6d1e7f13d4e57f"`); - await queryRunner.query(`DROP INDEX "IDX_4db3b84c7be0d3464714f3e0b1"`); - await queryRunner.query(`DROP INDEX "IDX_8d2cbbc8114d90d19b44d626b6"`); - await queryRunner.query(`DROP INDEX "IDX_046feeb12e9ef5f783f409866a"`); - await queryRunner.query(`DROP INDEX "IDX_f68a5ab958f9f5fa17a32ac23b"`); - await queryRunner.query(`DROP INDEX "IDX_65633a106bce43fc7c5c30a5c7"`); - await queryRunner.query(`DROP INDEX "IDX_edeb73c09c3143a81bcb34d569"`); - await queryRunner.query(`DROP INDEX "IDX_e316f01a6d24eb31db27f88262"`); - await queryRunner.query(`DROP INDEX "IDX_2be7ec6cebddc14dc11e206686"`); - await queryRunner.query(`DROP INDEX "IDX_a5133470f4825902e170328ca5"`); - await queryRunner.query(`DROP INDEX "IDX_84e661abb7bd1e51b690d4b017"`); - await queryRunner.query(`DROP INDEX "IDX_5c73bf61da4f6e6f15bae88ed1"`); - await queryRunner.query(`DROP INDEX "IDX_d70c86baedc68326be11f9c0ce"`); - await queryRunner.query(`DROP INDEX "IDX_66e1e1ecd2f29e57778af35b59"`); - await queryRunner.query(`DROP INDEX "IDX_92255988735563f0fe4aba1f05"`); - await queryRunner.query(`DROP INDEX "IDX_c5870993e25c3d5771f91f5003"`); - await queryRunner.query(`DROP INDEX "IDX_f170de677ea75ad4533de2723e"`); - await queryRunner.query(`DROP INDEX "IDX_7c184198ecf66a8d3ecb253ab3"`); - await queryRunner.query(`DROP INDEX "IDX_f091abb24193d50c653c6b77fc"`); - await queryRunner.query(`DROP INDEX "IDX_a770a57c70e668cc61590c9161"`); - await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "span"`); - await queryRunner.query(`DROP TYPE "public"."__chart__active_users_span_enum"`); - await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "unique"`); - await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "___local_count"`); - await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "___remote_count"`); - await queryRunner.query(`ALTER TABLE "__chart__drive" DROP COLUMN "span"`); - await queryRunner.query(`DROP TYPE "public"."__chart__drive_span_enum"`); - await queryRunner.query(`ALTER TABLE "__chart__drive" DROP COLUMN "unique"`); - await queryRunner.query(`ALTER TABLE "__chart__federation" DROP COLUMN "span"`); - await queryRunner.query(`DROP TYPE "public"."__chart__federation_span_enum"`); - await queryRunner.query(`ALTER TABLE "__chart__federation" DROP COLUMN "unique"`); - await queryRunner.query(`ALTER TABLE "__chart__hashtag" DROP COLUMN "span"`); - await queryRunner.query(`DROP TYPE "public"."__chart__hashtag_span_enum"`); - await queryRunner.query(`ALTER TABLE "__chart__hashtag" DROP COLUMN "unique"`); - await queryRunner.query(`ALTER TABLE "__chart__hashtag" DROP COLUMN "___local_count"`); - await queryRunner.query(`ALTER TABLE "__chart__hashtag" DROP COLUMN "___remote_count"`); - await queryRunner.query(`ALTER TABLE "__chart__instance" DROP COLUMN "span"`); - await queryRunner.query(`DROP TYPE "public"."__chart__instance_span_enum"`); - await queryRunner.query(`ALTER TABLE "__chart__instance" DROP COLUMN "unique"`); - await queryRunner.query(`ALTER TABLE "__chart__network" DROP COLUMN "span"`); - await queryRunner.query(`DROP TYPE "public"."__chart__network_span_enum"`); - await queryRunner.query(`ALTER TABLE "__chart__network" DROP COLUMN "unique"`); - await queryRunner.query(`ALTER TABLE "__chart__notes" DROP COLUMN "span"`); - await queryRunner.query(`DROP TYPE "public"."__chart__notes_span_enum"`); - await queryRunner.query(`ALTER TABLE "__chart__notes" DROP COLUMN "unique"`); - await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" DROP COLUMN "span"`); - await queryRunner.query(`DROP TYPE "public"."__chart__per_user_drive_span_enum"`); - await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" DROP COLUMN "unique"`); - await queryRunner.query(`ALTER TABLE "__chart__per_user_following" DROP COLUMN "span"`); - await queryRunner.query(`DROP TYPE "public"."__chart__per_user_following_span_enum"`); - await queryRunner.query(`ALTER TABLE "__chart__per_user_following" DROP COLUMN "unique"`); - await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" DROP COLUMN "span"`); - await queryRunner.query(`DROP TYPE "public"."__chart__per_user_notes_span_enum"`); - await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" DROP COLUMN "unique"`); - await queryRunner.query(`ALTER TABLE "__chart__per_user_reaction" DROP COLUMN "span"`); - await queryRunner.query(`DROP TYPE "public"."__chart__per_user_reaction_span_enum"`); - await queryRunner.query(`ALTER TABLE "__chart__per_user_reaction" DROP COLUMN "unique"`); - await queryRunner.query(`ALTER TABLE "__chart__test_grouped" DROP COLUMN "span"`); - await queryRunner.query(`DROP TYPE "public"."__chart__test_grouped_span_enum"`); - await queryRunner.query(`ALTER TABLE "__chart__test_grouped" DROP COLUMN "unique"`); - await queryRunner.query(`ALTER TABLE "__chart__test_unique" DROP COLUMN "span"`); - await queryRunner.query(`DROP TYPE "public"."__chart__test_unique_span_enum"`); - await queryRunner.query(`ALTER TABLE "__chart__test_unique" DROP COLUMN "unique"`); - await queryRunner.query(`ALTER TABLE "__chart__test_unique" DROP COLUMN "___foo"`); - await queryRunner.query(`ALTER TABLE "__chart__test" DROP COLUMN "span"`); - await queryRunner.query(`DROP TYPE "public"."__chart__test_span_enum"`); - await queryRunner.query(`ALTER TABLE "__chart__test" DROP COLUMN "unique"`); - await queryRunner.query(`ALTER TABLE "__chart__users" DROP COLUMN "span"`); - await queryRunner.query(`DROP TYPE "public"."__chart__users_span_enum"`); - await queryRunner.query(`ALTER TABLE "__chart__users" DROP COLUMN "unique"`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "__chart__users" ADD "unique" jsonb NOT NULL DEFAULT '{}'`); - await queryRunner.query(`CREATE TYPE "public"."__chart__users_span_enum" AS ENUM('hour', 'day')`); - await queryRunner.query(`ALTER TABLE "__chart__users" ADD "span" "__chart__users_span_enum" NOT NULL`); - await queryRunner.query(`ALTER TABLE "__chart__test" ADD "unique" jsonb NOT NULL DEFAULT '{}'`); - await queryRunner.query(`CREATE TYPE "public"."__chart__test_span_enum" AS ENUM('hour', 'day')`); - await queryRunner.query(`ALTER TABLE "__chart__test" ADD "span" "__chart__test_span_enum" NOT NULL`); - await queryRunner.query(`ALTER TABLE "__chart__test_unique" ADD "___foo" bigint NOT NULL`); - await queryRunner.query(`ALTER TABLE "__chart__test_unique" ADD "unique" jsonb NOT NULL DEFAULT '{}'`); - await queryRunner.query(`CREATE TYPE "public"."__chart__test_unique_span_enum" AS ENUM('hour', 'day')`); - await queryRunner.query(`ALTER TABLE "__chart__test_unique" ADD "span" "__chart__test_unique_span_enum" NOT NULL`); - await queryRunner.query(`ALTER TABLE "__chart__test_grouped" ADD "unique" jsonb NOT NULL DEFAULT '{}'`); - await queryRunner.query(`CREATE TYPE "public"."__chart__test_grouped_span_enum" AS ENUM('hour', 'day')`); - await queryRunner.query(`ALTER TABLE "__chart__test_grouped" ADD "span" "__chart__test_grouped_span_enum" NOT NULL`); - await queryRunner.query(`ALTER TABLE "__chart__per_user_reaction" ADD "unique" jsonb NOT NULL DEFAULT '{}'`); - await queryRunner.query(`CREATE TYPE "public"."__chart__per_user_reaction_span_enum" AS ENUM('hour', 'day')`); - await queryRunner.query(`ALTER TABLE "__chart__per_user_reaction" ADD "span" "__chart__per_user_reaction_span_enum" NOT NULL`); - await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ADD "unique" jsonb NOT NULL DEFAULT '{}'`); - await queryRunner.query(`CREATE TYPE "public"."__chart__per_user_notes_span_enum" AS ENUM('hour', 'day')`); - await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ADD "span" "__chart__per_user_notes_span_enum" NOT NULL`); - await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ADD "unique" jsonb NOT NULL DEFAULT '{}'`); - await queryRunner.query(`CREATE TYPE "public"."__chart__per_user_following_span_enum" AS ENUM('hour', 'day')`); - await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ADD "span" "__chart__per_user_following_span_enum" NOT NULL`); - await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ADD "unique" jsonb NOT NULL DEFAULT '{}'`); - await queryRunner.query(`CREATE TYPE "public"."__chart__per_user_drive_span_enum" AS ENUM('hour', 'day')`); - await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ADD "span" "__chart__per_user_drive_span_enum" NOT NULL`); - await queryRunner.query(`ALTER TABLE "__chart__notes" ADD "unique" jsonb NOT NULL DEFAULT '{}'`); - await queryRunner.query(`CREATE TYPE "public"."__chart__notes_span_enum" AS ENUM('hour', 'day')`); - await queryRunner.query(`ALTER TABLE "__chart__notes" ADD "span" "__chart__notes_span_enum" NOT NULL`); - await queryRunner.query(`ALTER TABLE "__chart__network" ADD "unique" jsonb NOT NULL DEFAULT '{}'`); - await queryRunner.query(`CREATE TYPE "public"."__chart__network_span_enum" AS ENUM('hour', 'day')`); - await queryRunner.query(`ALTER TABLE "__chart__network" ADD "span" "__chart__network_span_enum" NOT NULL`); - await queryRunner.query(`ALTER TABLE "__chart__instance" ADD "unique" jsonb NOT NULL DEFAULT '{}'`); - await queryRunner.query(`CREATE TYPE "public"."__chart__instance_span_enum" AS ENUM('hour', 'day')`); - await queryRunner.query(`ALTER TABLE "__chart__instance" ADD "span" "__chart__instance_span_enum" NOT NULL`); - await queryRunner.query(`ALTER TABLE "__chart__hashtag" ADD "___remote_count" bigint NOT NULL`); - await queryRunner.query(`ALTER TABLE "__chart__hashtag" ADD "___local_count" bigint NOT NULL`); - await queryRunner.query(`ALTER TABLE "__chart__hashtag" ADD "unique" jsonb NOT NULL DEFAULT '{}'`); - await queryRunner.query(`CREATE TYPE "public"."__chart__hashtag_span_enum" AS ENUM('hour', 'day')`); - await queryRunner.query(`ALTER TABLE "__chart__hashtag" ADD "span" "__chart__hashtag_span_enum" NOT NULL`); - await queryRunner.query(`ALTER TABLE "__chart__federation" ADD "unique" jsonb NOT NULL DEFAULT '{}'`); - await queryRunner.query(`CREATE TYPE "public"."__chart__federation_span_enum" AS ENUM('hour', 'day')`); - await queryRunner.query(`ALTER TABLE "__chart__federation" ADD "span" "__chart__federation_span_enum" NOT NULL`); - await queryRunner.query(`ALTER TABLE "__chart__drive" ADD "unique" jsonb NOT NULL DEFAULT '{}'`); - await queryRunner.query(`CREATE TYPE "public"."__chart__drive_span_enum" AS ENUM('hour', 'day')`); - await queryRunner.query(`ALTER TABLE "__chart__drive" ADD "span" "__chart__drive_span_enum" NOT NULL`); - await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "___remote_count" bigint NOT NULL`); - await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "___local_count" bigint NOT NULL`); - await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "unique" jsonb NOT NULL DEFAULT '{}'`); - await queryRunner.query(`CREATE TYPE "public"."__chart__active_users_span_enum" AS ENUM('hour', 'day')`); - await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "span" "__chart__active_users_span_enum" NOT NULL`); - await queryRunner.query(`CREATE INDEX "IDX_a770a57c70e668cc61590c9161" ON "__chart__users" ("date", "group", "span") `); - await queryRunner.query(`CREATE INDEX "IDX_f091abb24193d50c653c6b77fc" ON "__chart__users" ("date", "span") `); - await queryRunner.query(`CREATE INDEX "IDX_7c184198ecf66a8d3ecb253ab3" ON "__chart__users" ("span") `); - await queryRunner.query(`CREATE INDEX "IDX_f170de677ea75ad4533de2723e" ON "__chart__test" ("date", "group", "span") `); - await queryRunner.query(`CREATE INDEX "IDX_c5870993e25c3d5771f91f5003" ON "__chart__test" ("date", "span") `); - await queryRunner.query(`CREATE INDEX "IDX_92255988735563f0fe4aba1f05" ON "__chart__test" ("span") `); - await queryRunner.query(`CREATE INDEX "IDX_66e1e1ecd2f29e57778af35b59" ON "__chart__test_unique" ("date", "group", "span") `); - await queryRunner.query(`CREATE INDEX "IDX_d70c86baedc68326be11f9c0ce" ON "__chart__test_unique" ("date", "span") `); - await queryRunner.query(`CREATE INDEX "IDX_5c73bf61da4f6e6f15bae88ed1" ON "__chart__test_unique" ("span") `); - await queryRunner.query(`CREATE INDEX "IDX_84e661abb7bd1e51b690d4b017" ON "__chart__test_grouped" ("date", "group", "span") `); - await queryRunner.query(`CREATE INDEX "IDX_a5133470f4825902e170328ca5" ON "__chart__test_grouped" ("date", "span") `); - await queryRunner.query(`CREATE INDEX "IDX_2be7ec6cebddc14dc11e206686" ON "__chart__test_grouped" ("span") `); - await queryRunner.query(`CREATE INDEX "IDX_e316f01a6d24eb31db27f88262" ON "__chart__per_user_reaction" ("date", "group", "span") `); - await queryRunner.query(`CREATE INDEX "IDX_edeb73c09c3143a81bcb34d569" ON "__chart__per_user_reaction" ("date", "span") `); - await queryRunner.query(`CREATE INDEX "IDX_65633a106bce43fc7c5c30a5c7" ON "__chart__per_user_reaction" ("span") `); - await queryRunner.query(`CREATE INDEX "IDX_f68a5ab958f9f5fa17a32ac23b" ON "__chart__per_user_notes" ("date", "group", "span") `); - await queryRunner.query(`CREATE INDEX "IDX_046feeb12e9ef5f783f409866a" ON "__chart__per_user_notes" ("date", "span") `); - await queryRunner.query(`CREATE INDEX "IDX_8d2cbbc8114d90d19b44d626b6" ON "__chart__per_user_notes" ("span") `); - await queryRunner.query(`CREATE INDEX "IDX_4db3b84c7be0d3464714f3e0b1" ON "__chart__per_user_following" ("date", "group", "span") `); - await queryRunner.query(`CREATE INDEX "IDX_57b5458d0d3d6d1e7f13d4e57f" ON "__chart__per_user_following" ("date", "span") `); - await queryRunner.query(`CREATE INDEX "IDX_f92dd6d03f8d994f29987f6214" ON "__chart__per_user_following" ("span") `); - await queryRunner.query(`CREATE INDEX "IDX_f2aeafde2ae6fbad38e857631b" ON "__chart__per_user_drive" ("date", "group", "span") `); - await queryRunner.query(`CREATE INDEX "IDX_42ea9381f0fda8dfe0fa1c8b53" ON "__chart__per_user_drive" ("date", "span") `); - await queryRunner.query(`CREATE INDEX "IDX_328f259961e60c4fa0bfcf55ca" ON "__chart__per_user_drive" ("span") `); - await queryRunner.query(`CREATE INDEX "IDX_924fc196c80ca24bae01dd37e4" ON "__chart__notes" ("date", "group", "span") `); - await queryRunner.query(`CREATE INDEX "IDX_0c9a159c5082cbeef3ca6706b5" ON "__chart__notes" ("date", "span") `); - await queryRunner.query(`CREATE INDEX "IDX_e69096589f11e3baa98ddd64d0" ON "__chart__notes" ("span") `); - await queryRunner.query(`CREATE INDEX "IDX_9ff6944f01acb756fdc92d7563" ON "__chart__network" ("date", "group", "span") `); - await queryRunner.query(`CREATE INDEX "IDX_08fac0eb3b11f04c200c0b40dd" ON "__chart__network" ("date", "span") `); - await queryRunner.query(`CREATE INDEX "IDX_f8dd01baeded2ffa833e0a610a" ON "__chart__network" ("span") `); - await queryRunner.query(`CREATE INDEX "IDX_f5448d9633cff74208d850aabe" ON "__chart__instance" ("date", "group", "span") `); - await queryRunner.query(`CREATE INDEX "IDX_d0a4f79af5a97b08f37b547197" ON "__chart__instance" ("date", "span") `); - await queryRunner.query(`CREATE INDEX "IDX_c12f0af4a66cdd30c2287ce8aa" ON "__chart__instance" ("span") `); - await queryRunner.query(`CREATE INDEX "IDX_6d6f156ceefc6bc5f273a0e370" ON "__chart__hashtag" ("date", "group", "span") `); - await queryRunner.query(`CREATE INDEX "IDX_49975586f50ed7b800fdd88fbd" ON "__chart__hashtag" ("date", "span") `); - await queryRunner.query(`CREATE INDEX "IDX_fcc181fb8283009c61cc4083ef" ON "__chart__hashtag" ("span") `); - await queryRunner.query(`CREATE INDEX "IDX_e9cd07672b37d8966cf3709283" ON "__chart__federation" ("date", "group", "span") `); - await queryRunner.query(`CREATE INDEX "IDX_2d416e6af791a82e338c79d480" ON "__chart__federation" ("date", "span") `); - await queryRunner.query(`CREATE INDEX "IDX_e447064455928cf627590ef527" ON "__chart__federation" ("span") `); - await queryRunner.query(`CREATE INDEX "IDX_06690fc959f1c9fdaf21928222" ON "__chart__drive" ("date", "group", "span") `); - await queryRunner.query(`CREATE INDEX "IDX_6e1df243476e20cbf86572ecc0" ON "__chart__drive" ("date", "span") `); - await queryRunner.query(`CREATE INDEX "IDX_3fa0d0f17ca72e3dc80999a032" ON "__chart__drive" ("span") `); - await queryRunner.query(`CREATE INDEX "IDX_c26e2c1cbb6e911e0554b27416" ON "__chart__active_users" ("date", "group", "span") `); - await queryRunner.query(`CREATE INDEX "IDX_20f57cc8f142c131340ee16742" ON "__chart__active_users" ("date", "span") `); - await queryRunner.query(`CREATE INDEX "IDX_15e91a03aeeac9dbccdf43fc06" ON "__chart__active_users" ("span") `); - } - -} diff --git a/migration/1615966519402-chart-v2-2.ts b/migration/1615966519402-chart-v2-2.ts deleted file mode 100644 index a694f9542..000000000 --- a/migration/1615966519402-chart-v2-2.ts +++ /dev/null @@ -1,22 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class chartV221615966519402 implements MigrationInterface { - name = 'chartV221615966519402' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "___local_users" character varying array NOT NULL DEFAULT '{}'::varchar[]`); - await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "___remote_users" character varying array NOT NULL DEFAULT '{}'::varchar[]`); - await queryRunner.query(`ALTER TABLE "__chart__hashtag" ADD "___local_users" character varying array NOT NULL DEFAULT '{}'::varchar[]`); - await queryRunner.query(`ALTER TABLE "__chart__hashtag" ADD "___remote_users" character varying array NOT NULL DEFAULT '{}'::varchar[]`); - await queryRunner.query(`ALTER TABLE "__chart__test_unique" ADD "___foo" character varying array NOT NULL DEFAULT '{}'::varchar[]`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "__chart__test_unique" DROP COLUMN "___foo"`); - await queryRunner.query(`ALTER TABLE "__chart__hashtag" DROP COLUMN "___remote_users"`); - await queryRunner.query(`ALTER TABLE "__chart__hashtag" 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 "___local_users"`); - } - -} diff --git a/migration/1618637372000-user-last-active-date.ts b/migration/1618637372000-user-last-active-date.ts deleted file mode 100644 index a66c433a3..000000000 --- a/migration/1618637372000-user-last-active-date.ts +++ /dev/null @@ -1,16 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class userLastActiveDate1618637372000 implements MigrationInterface { - name = 'userLastActiveDate1618637372000' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user" ADD "lastActiveDate" TIMESTAMP WITH TIME ZONE DEFAULT NULL`); - await queryRunner.query(`CREATE INDEX "IDX_seoignmeoprigmkpodgrjmkpormg" ON "user" ("lastActiveDate") `); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`DROP INDEX "IDX_seoignmeoprigmkpodgrjmkpormg"`); - await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "lastActiveDate"`); - } - -} diff --git a/migration/1618639857000-user-hide-online-status.ts b/migration/1618639857000-user-hide-online-status.ts deleted file mode 100644 index d5d77f983..000000000 --- a/migration/1618639857000-user-hide-online-status.ts +++ /dev/null @@ -1,14 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class userHideOnlineStatus1618639857000 implements MigrationInterface { - name = 'userHideOnlineStatus1618639857000' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user" ADD "hideOnlineStatus" boolean NOT NULL DEFAULT false`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "hideOnlineStatus"`); - } - -} diff --git a/migration/1619942102890-password-reset.ts b/migration/1619942102890-password-reset.ts deleted file mode 100644 index 66854cb02..000000000 --- a/migration/1619942102890-password-reset.ts +++ /dev/null @@ -1,20 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class passwordReset1619942102890 implements MigrationInterface { - name = 'passwordReset1619942102890' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE TABLE "password_reset_request" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "token" character varying(256) NOT NULL, "userId" character varying(32) NOT NULL, CONSTRAINT "PK_fcf4b02eae1403a2edaf87fd074" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_0b575fa9a4cfe638a925949285" ON "password_reset_request" ("token") `); - await queryRunner.query(`CREATE INDEX "IDX_4bb7fd4a34492ae0e6cc8d30ac" ON "password_reset_request" ("userId") `); - await queryRunner.query(`ALTER TABLE "password_reset_request" ADD CONSTRAINT "FK_4bb7fd4a34492ae0e6cc8d30ac8" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "password_reset_request" DROP CONSTRAINT "FK_4bb7fd4a34492ae0e6cc8d30ac8"`); - await queryRunner.query(`DROP INDEX "IDX_4bb7fd4a34492ae0e6cc8d30ac"`); - await queryRunner.query(`DROP INDEX "IDX_0b575fa9a4cfe638a925949285"`); - await queryRunner.query(`DROP TABLE "password_reset_request"`); - } - -} diff --git a/migration/1620019354680-ad.ts b/migration/1620019354680-ad.ts deleted file mode 100644 index 27fb99f18..000000000 --- a/migration/1620019354680-ad.ts +++ /dev/null @@ -1,18 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class ad1620019354680 implements MigrationInterface { - name = 'ad1620019354680' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE TABLE "ad" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "expiresAt" TIMESTAMP WITH TIME ZONE NOT NULL, "place" character varying(32) NOT NULL, "priority" character varying(32) NOT NULL, "url" character varying(1024) NOT NULL, "imageUrl" character varying(1024) NOT NULL, "memo" character varying(8192) NOT NULL, CONSTRAINT "PK_0193d5ef09746e88e9ea92c634d" PRIMARY KEY ("id")); COMMENT ON COLUMN "ad"."createdAt" IS 'The created date of the Ad.'; COMMENT ON COLUMN "ad"."expiresAt" IS 'The expired date of the Ad.'`); - await queryRunner.query(`CREATE INDEX "IDX_1129c2ef687fc272df040bafaa" ON "ad" ("createdAt") `); - await queryRunner.query(`CREATE INDEX "IDX_2da24ce20ad209f1d9dc032457" ON "ad" ("expiresAt") `); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`DROP INDEX "IDX_2da24ce20ad209f1d9dc032457"`); - await queryRunner.query(`DROP INDEX "IDX_1129c2ef687fc272df040bafaa"`); - await queryRunner.query(`DROP TABLE "ad"`); - } - -} diff --git a/migration/1620364649428-ad2.ts b/migration/1620364649428-ad2.ts deleted file mode 100644 index a2d7f563c..000000000 --- a/migration/1620364649428-ad2.ts +++ /dev/null @@ -1,14 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class ad21620364649428 implements MigrationInterface { - name = 'ad21620364649428' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "ad" ADD "ratio" integer NOT NULL DEFAULT '1'`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "ad" DROP COLUMN "ratio"`); - } - -} diff --git a/migration/1621479946000-add-note-indexes.ts b/migration/1621479946000-add-note-indexes.ts deleted file mode 100644 index 53d49964a..000000000 --- a/migration/1621479946000-add-note-indexes.ts +++ /dev/null @@ -1,16 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class addNoteIndexes1621479946000 implements MigrationInterface { - name = 'addNoteIndexes1621479946000' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE INDEX "IDX_NOTE_MENTIONS" ON "note" USING gin ("mentions")`, undefined); - await queryRunner.query(`CREATE INDEX "IDX_NOTE_VISIBLE_USER_IDS" ON "note" USING gin ("visibleUserIds")`, undefined); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`DROP INDEX "IDX_NOTE_MENTIONS"`, undefined); - await queryRunner.query(`DROP INDEX "IDX_NOTE_VISIBLE_USER_IDS"`, undefined); - } - -} diff --git a/migration/1622679304522-user-profile-description-length.ts b/migration/1622679304522-user-profile-description-length.ts deleted file mode 100644 index 015d1e24b..000000000 --- a/migration/1622679304522-user-profile-description-length.ts +++ /dev/null @@ -1,13 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class userProfileDescriptionLength1622679304522 implements MigrationInterface { - name = 'userProfileDescriptionLength1622679304522'; - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user_profile" ALTER COLUMN "description" TYPE character varying(2048)`, undefined); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user_profile" ALTER COLUMN "description" TYPE character varying(1024)`, undefined); - } -} diff --git a/migration/1622681548499-log-message-length.ts b/migration/1622681548499-log-message-length.ts deleted file mode 100644 index ef8c33982..000000000 --- a/migration/1622681548499-log-message-length.ts +++ /dev/null @@ -1,12 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class logMessageLength1622681548499 implements MigrationInterface { - name = 'logMessageLength1622681548499'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "log" ALTER COLUMN "message" TYPE character varying(2048)`, undefined); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "log" ALTER COLUMN "message" TYPE character varying(1024)`, undefined); - } -} diff --git a/migration/1629004542760-chart-reindex.ts b/migration/1629004542760-chart-reindex.ts deleted file mode 100644 index c3d09f51b..000000000 --- a/migration/1629004542760-chart-reindex.ts +++ /dev/null @@ -1,182 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class chartReindex1629004542760 implements MigrationInterface { - name = 'chartReindex1629004542760' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`DELETE FROM "__chart__active_users" a USING "__chart__active_users" b WHERE a.id < b.id AND ((a.group IS NULL AND b.group IS NULL) OR a.group = b.group) AND a.date = b.date;`); - await queryRunner.query(`DELETE FROM "__chart__drive" a USING "__chart__drive" b WHERE a.id < b.id AND ((a.group IS NULL AND b.group IS NULL) OR a.group = b.group) AND a.date = b.date;`); - await queryRunner.query(`DELETE FROM "__chart__federation" a USING "__chart__federation" b WHERE a.id < b.id AND ((a.group IS NULL AND b.group IS NULL) OR a.group = b.group) AND a.date = b.date;`); - await queryRunner.query(`DELETE FROM "__chart__hashtag" a USING "__chart__hashtag" b WHERE a.id < b.id AND ((a.group IS NULL AND b.group IS NULL) OR a.group = b.group) AND a.date = b.date;`); - await queryRunner.query(`DELETE FROM "__chart__instance" a USING "__chart__instance" b WHERE a.id < b.id AND ((a.group IS NULL AND b.group IS NULL) OR a.group = b.group) AND a.date = b.date;`); - await queryRunner.query(`DELETE FROM "__chart__network" a USING "__chart__network" b WHERE a.id < b.id AND ((a.group IS NULL AND b.group IS NULL) OR a.group = b.group) AND a.date = b.date;`); - await queryRunner.query(`DELETE FROM "__chart__notes" a USING "__chart__notes" b WHERE a.id < b.id AND ((a.group IS NULL AND b.group IS NULL) OR a.group = b.group) AND a.date = b.date;`); - await queryRunner.query(`DELETE FROM "__chart__per_user_drive" a USING "__chart__per_user_drive" b WHERE a.id < b.id AND ((a.group IS NULL AND b.group IS NULL) OR a.group = b.group) AND a.date = b.date;`); - await queryRunner.query(`DELETE FROM "__chart__per_user_following" a USING "__chart__per_user_following" b WHERE a.id < b.id AND ((a.group IS NULL AND b.group IS NULL) OR a.group = b.group) AND a.date = b.date;`); - await queryRunner.query(`DELETE FROM "__chart__per_user_notes" a USING "__chart__per_user_notes" b WHERE a.id < b.id AND ((a.group IS NULL AND b.group IS NULL) OR a.group = b.group) AND a.date = b.date;`); - await queryRunner.query(`DELETE FROM "__chart__per_user_reaction" a USING "__chart__per_user_reaction" b WHERE a.id < b.id AND ((a.group IS NULL AND b.group IS NULL) OR a.group = b.group) AND a.date = b.date;`); - await queryRunner.query(`DELETE FROM "__chart__test_grouped" a USING "__chart__test_grouped" b WHERE a.id < b.id AND ((a.group IS NULL AND b.group IS NULL) OR a.group = b.group) AND a.date = b.date;`); - await queryRunner.query(`DELETE FROM "__chart__test_unique" a USING "__chart__test_unique" b WHERE a.id < b.id AND ((a.group IS NULL AND b.group IS NULL) OR a.group = b.group) AND a.date = b.date;`); - await queryRunner.query(`DELETE FROM "__chart__users" a USING "__chart__users" b WHERE a.id < b.id AND ((a.group IS NULL AND b.group IS NULL) OR a.group = b.group) AND a.date = b.date;`); - await queryRunner.query(`DROP INDEX "IDX_0ad37b7ef50f4ddc84363d7ccc"`); - await queryRunner.query(`DROP INDEX "IDX_00ed5f86db1f7efafb1978bf21"`); - await queryRunner.query(`DROP INDEX "IDX_9a3ed15a30ab7e3a37702e6e08"`); - await queryRunner.query(`DROP INDEX "IDX_13565815f618a1ff53886c5b28"`); - await queryRunner.query(`DROP INDEX "IDX_7a170f67425e62a8fabb76c872"`); - await queryRunner.query(`DROP INDEX "IDX_3313d7288855ec105b5bbf6c21"`); - await queryRunner.query(`DROP INDEX "IDX_36cb699c49580d4e6c2e6159f9"`); - await queryRunner.query(`DROP INDEX "IDX_76e87c7bfc5d925fcbba405d84"`); - await queryRunner.query(`DROP INDEX "IDX_dd907becf76104e4b656659e6b"`); - await queryRunner.query(`DROP INDEX "IDX_07747a1038c05f532a718fe1de"`); - await queryRunner.query(`DROP INDEX "IDX_99a7d2faaef84a6f728d714ad6"`); - await queryRunner.query(`DROP INDEX "IDX_25a97c02003338124b2b75fdbc"`); - await queryRunner.query(`DROP INDEX "IDX_6b8f34a1a64b06014b6fb66824"`); - await queryRunner.query(`DROP INDEX "IDX_da8a46ba84ca1d8bb5a29bfb63"`); - await queryRunner.query(`DROP INDEX "IDX_39ee857ab2f23493037c6b6631"`); - await queryRunner.query(`DROP INDEX "IDX_a1efd3e0048a5f2793a47360dc"`); - await queryRunner.query(`DROP INDEX "IDX_7b5da130992ec9df96712d4290"`); - await queryRunner.query(`DROP INDEX "IDX_0a905b992fecd2b5c3fb98759e"`); - await queryRunner.query(`DROP INDEX "IDX_42eb716a37d381cdf566192b2b"`); - await queryRunner.query(`DROP INDEX "IDX_7036f2957151588b813185c794"`); - await queryRunner.query(`DROP INDEX "IDX_f09d543e3acb16c5976bdb31fa"`); - await queryRunner.query(`DROP INDEX "IDX_5f86db6492274e07c1a3cdf286"`); - await queryRunner.query(`DROP INDEX "IDX_e496ca8096d28f6b9b509264dc"`); - await queryRunner.query(`DROP INDEX "IDX_30bf67687f483ace115c5ca642"`); - await queryRunner.query(`DROP INDEX "IDX_7af07790712aa3438ff6773f3b"`); - await queryRunner.query(`DROP INDEX "IDX_4b3593098b6edc9c5afe36b18b"`); - await queryRunner.query(`DROP INDEX "IDX_b77d4dd9562c3a899d9a286fcd"`); - await queryRunner.query(`DROP INDEX "IDX_84234bd1abb873f07329681c83"`); - await queryRunner.query(`DROP INDEX "IDX_55bf20f366979f2436de99206b"`); - await queryRunner.query(`DROP INDEX "IDX_5048e9daccbbbc6d567bb142d3"`); - await queryRunner.query(`DROP INDEX "IDX_f7bf4c62059764c2c2bb40fdab"`); - await queryRunner.query(`DROP INDEX "IDX_8cf3156fd7a6b15c43459c6e3b"`); - await queryRunner.query(`DROP INDEX "IDX_229a41ad465f9205f1f5703291"`); - await queryRunner.query(`DROP INDEX "IDX_0c641990ecf47d2545df4edb75"`); - await queryRunner.query(`DROP INDEX "IDX_234dff3c0b56a6150b95431ab9"`); - await queryRunner.query(`DROP INDEX "IDX_b14489029e4b3aaf4bba5fb524"`); - await queryRunner.query(`DROP INDEX "IDX_437bab3c6061d90f6bb65fd2cc"`); - await queryRunner.query(`DROP INDEX "IDX_bbfa573a8181018851ed0b6357"`); - await queryRunner.query(`DROP INDEX "IDX_a0cd75442dd10d0643a17c4a49"`); - await queryRunner.query(`DROP INDEX "IDX_b070a906db04b44c67c6c2144d"`); - await queryRunner.query(`DROP INDEX "IDX_d41cce6aee1a50bfc062038f9b"`); - await queryRunner.query(`DROP INDEX "IDX_a319e5dbf47e8a17497623beae"`); - await queryRunner.query(`DROP INDEX "IDX_845254b3eaf708ae8a6cac3026"`); - await queryRunner.query(`DROP INDEX "IDX_ed9b95919c672a13008e9487ee"`); - await queryRunner.query(`DROP INDEX "IDX_337e9599f278bd7537fe30876f"`); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_9a3ed15a30ab7e3a37702e6e08" ON "__chart__active_users" ("date", "group") `); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_60c5c6e7e538c09aa274ecd1cf" ON "__chart__active_users" ("date") WHERE "group" IS NULL`); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_3313d7288855ec105b5bbf6c21" ON "__chart__drive" ("date", "group") `); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_ceab80a6729f8e2e6f5b8a1a3d" ON "__chart__drive" ("date") WHERE "group" IS NULL`); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_dd907becf76104e4b656659e6b" ON "__chart__federation" ("date", "group") `); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_eddfed8fb40305a04c6f941050" ON "__chart__federation" ("date") WHERE "group" IS NULL`); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_25a97c02003338124b2b75fdbc" ON "__chart__hashtag" ("date", "group") `); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_53a3604b939e2b479eb2cfaac8" ON "__chart__hashtag" ("date") WHERE "group" IS NULL`); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_39ee857ab2f23493037c6b6631" ON "__chart__instance" ("date", "group") `); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_8111b817b9818c04d7eb8475b1" ON "__chart__instance" ("date") WHERE "group" IS NULL`); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_0a905b992fecd2b5c3fb98759e" ON "__chart__network" ("date", "group") `); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_2082327b2699ce924fa654afc5" ON "__chart__network" ("date") WHERE "group" IS NULL`); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_f09d543e3acb16c5976bdb31fa" ON "__chart__notes" ("date", "group") `); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_e60c358aaced5aab8900a4af31" ON "__chart__notes" ("date") WHERE "group" IS NULL`); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_30bf67687f483ace115c5ca642" ON "__chart__per_user_drive" ("date", "group") `); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_a9a806d466b314f253a1a611c4" ON "__chart__per_user_drive" ("date") WHERE "group" IS NULL`); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_b77d4dd9562c3a899d9a286fcd" ON "__chart__per_user_following" ("date", "group") `); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_dabbb38a51ab86ee3cab291326" ON "__chart__per_user_following" ("date") WHERE "group" IS NULL`); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_5048e9daccbbbc6d567bb142d3" ON "__chart__per_user_notes" ("date", "group") `); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_583a157ed0cf0ed1b5ec2a833f" ON "__chart__per_user_notes" ("date") WHERE "group" IS NULL`); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_229a41ad465f9205f1f5703291" ON "__chart__per_user_reaction" ("date", "group") `); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_3b7697a96f522d0478972e6d6f" ON "__chart__per_user_reaction" ("date") WHERE "group" IS NULL`); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_b14489029e4b3aaf4bba5fb524" ON "__chart__test_grouped" ("date", "group") `); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_da522b4008a9f5d7743b87ad55" ON "__chart__test_grouped" ("date") WHERE "group" IS NULL`); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_a0cd75442dd10d0643a17c4a49" ON "__chart__test_unique" ("date", "group") `); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_16effb2e888f6763673b579f80" ON "__chart__test_unique" ("date") WHERE "group" IS NULL`); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_a319e5dbf47e8a17497623beae" ON "__chart__test" ("date", "group") `); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_dab383a36f3c9db4a0c9b02cf3" ON "__chart__test" ("date") WHERE "group" IS NULL`); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_337e9599f278bd7537fe30876f" ON "__chart__users" ("date", "group") `); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_66feba81e1795d176d06c0b1e6" ON "__chart__users" ("date") WHERE "group" IS NULL`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`DROP INDEX "IDX_66feba81e1795d176d06c0b1e6"`); - await queryRunner.query(`DROP INDEX "IDX_337e9599f278bd7537fe30876f"`); - await queryRunner.query(`DROP INDEX "IDX_dab383a36f3c9db4a0c9b02cf3"`); - await queryRunner.query(`DROP INDEX "IDX_a319e5dbf47e8a17497623beae"`); - await queryRunner.query(`DROP INDEX "IDX_16effb2e888f6763673b579f80"`); - await queryRunner.query(`DROP INDEX "IDX_a0cd75442dd10d0643a17c4a49"`); - await queryRunner.query(`DROP INDEX "IDX_da522b4008a9f5d7743b87ad55"`); - await queryRunner.query(`DROP INDEX "IDX_b14489029e4b3aaf4bba5fb524"`); - await queryRunner.query(`DROP INDEX "IDX_3b7697a96f522d0478972e6d6f"`); - await queryRunner.query(`DROP INDEX "IDX_229a41ad465f9205f1f5703291"`); - await queryRunner.query(`DROP INDEX "IDX_583a157ed0cf0ed1b5ec2a833f"`); - await queryRunner.query(`DROP INDEX "IDX_5048e9daccbbbc6d567bb142d3"`); - await queryRunner.query(`DROP INDEX "IDX_dabbb38a51ab86ee3cab291326"`); - await queryRunner.query(`DROP INDEX "IDX_b77d4dd9562c3a899d9a286fcd"`); - await queryRunner.query(`DROP INDEX "IDX_a9a806d466b314f253a1a611c4"`); - await queryRunner.query(`DROP INDEX "IDX_30bf67687f483ace115c5ca642"`); - await queryRunner.query(`DROP INDEX "IDX_e60c358aaced5aab8900a4af31"`); - await queryRunner.query(`DROP INDEX "IDX_f09d543e3acb16c5976bdb31fa"`); - await queryRunner.query(`DROP INDEX "IDX_2082327b2699ce924fa654afc5"`); - await queryRunner.query(`DROP INDEX "IDX_0a905b992fecd2b5c3fb98759e"`); - await queryRunner.query(`DROP INDEX "IDX_8111b817b9818c04d7eb8475b1"`); - await queryRunner.query(`DROP INDEX "IDX_39ee857ab2f23493037c6b6631"`); - await queryRunner.query(`DROP INDEX "IDX_53a3604b939e2b479eb2cfaac8"`); - await queryRunner.query(`DROP INDEX "IDX_25a97c02003338124b2b75fdbc"`); - await queryRunner.query(`DROP INDEX "IDX_eddfed8fb40305a04c6f941050"`); - await queryRunner.query(`DROP INDEX "IDX_dd907becf76104e4b656659e6b"`); - await queryRunner.query(`DROP INDEX "IDX_ceab80a6729f8e2e6f5b8a1a3d"`); - await queryRunner.query(`DROP INDEX "IDX_3313d7288855ec105b5bbf6c21"`); - await queryRunner.query(`DROP INDEX "IDX_60c5c6e7e538c09aa274ecd1cf"`); - await queryRunner.query(`DROP INDEX "IDX_9a3ed15a30ab7e3a37702e6e08"`); - await queryRunner.query(`DROP INDEX "IDX_a9021cc2e1feb5f72d3db6e9f5"`); - await queryRunner.query(`DROP INDEX "IDX_f22169eb10657bded6d875ac8f"`); - await queryRunner.query(`DROP INDEX "IDX_c8cc87bd0f2f4487d17c651fbf"`); - await queryRunner.query(`DROP INDEX "IDX_754499f9b2642336433769518d"`); - await queryRunner.query(`DROP INDEX "IDX_315c779174fe8247ab324f036e"`); - await queryRunner.query(`DROP INDEX "IDX_c5d46cbfda48b1c33ed852e21b"`); - await queryRunner.query(`CREATE INDEX "IDX_337e9599f278bd7537fe30876f" ON "__chart__users" ("date", "group") `); - await queryRunner.query(`CREATE INDEX "IDX_ed9b95919c672a13008e9487ee" ON "__chart__users" ("group") `); - await queryRunner.query(`CREATE INDEX "IDX_845254b3eaf708ae8a6cac3026" ON "__chart__users" ("date") `); - await queryRunner.query(`CREATE INDEX "IDX_a319e5dbf47e8a17497623beae" ON "__chart__test" ("date", "group") `); - await queryRunner.query(`CREATE INDEX "IDX_d41cce6aee1a50bfc062038f9b" ON "__chart__test" ("group") `); - await queryRunner.query(`CREATE INDEX "IDX_b070a906db04b44c67c6c2144d" ON "__chart__test" ("date") `); - await queryRunner.query(`CREATE INDEX "IDX_a0cd75442dd10d0643a17c4a49" ON "__chart__test_unique" ("date", "group") `); - await queryRunner.query(`CREATE INDEX "IDX_bbfa573a8181018851ed0b6357" ON "__chart__test_unique" ("group") `); - await queryRunner.query(`CREATE INDEX "IDX_437bab3c6061d90f6bb65fd2cc" ON "__chart__test_unique" ("date") `); - await queryRunner.query(`CREATE INDEX "IDX_b14489029e4b3aaf4bba5fb524" ON "__chart__test_grouped" ("date", "group") `); - await queryRunner.query(`CREATE INDEX "IDX_234dff3c0b56a6150b95431ab9" ON "__chart__test_grouped" ("group") `); - await queryRunner.query(`CREATE INDEX "IDX_0c641990ecf47d2545df4edb75" ON "__chart__test_grouped" ("date") `); - await queryRunner.query(`CREATE INDEX "IDX_229a41ad465f9205f1f5703291" ON "__chart__per_user_reaction" ("date", "group") `); - await queryRunner.query(`CREATE INDEX "IDX_8cf3156fd7a6b15c43459c6e3b" ON "__chart__per_user_reaction" ("group") `); - await queryRunner.query(`CREATE INDEX "IDX_f7bf4c62059764c2c2bb40fdab" ON "__chart__per_user_reaction" ("date") `); - await queryRunner.query(`CREATE INDEX "IDX_5048e9daccbbbc6d567bb142d3" ON "__chart__per_user_notes" ("date", "group") `); - await queryRunner.query(`CREATE INDEX "IDX_55bf20f366979f2436de99206b" ON "__chart__per_user_notes" ("group") `); - await queryRunner.query(`CREATE INDEX "IDX_84234bd1abb873f07329681c83" ON "__chart__per_user_notes" ("date") `); - await queryRunner.query(`CREATE INDEX "IDX_b77d4dd9562c3a899d9a286fcd" ON "__chart__per_user_following" ("date", "group") `); - await queryRunner.query(`CREATE INDEX "IDX_4b3593098b6edc9c5afe36b18b" ON "__chart__per_user_following" ("group") `); - await queryRunner.query(`CREATE INDEX "IDX_7af07790712aa3438ff6773f3b" ON "__chart__per_user_following" ("date") `); - await queryRunner.query(`CREATE INDEX "IDX_30bf67687f483ace115c5ca642" ON "__chart__per_user_drive" ("date", "group") `); - await queryRunner.query(`CREATE INDEX "IDX_e496ca8096d28f6b9b509264dc" ON "__chart__per_user_drive" ("group") `); - await queryRunner.query(`CREATE INDEX "IDX_5f86db6492274e07c1a3cdf286" ON "__chart__per_user_drive" ("date") `); - await queryRunner.query(`CREATE INDEX "IDX_f09d543e3acb16c5976bdb31fa" ON "__chart__notes" ("date", "group") `); - await queryRunner.query(`CREATE INDEX "IDX_7036f2957151588b813185c794" ON "__chart__notes" ("group") `); - await queryRunner.query(`CREATE INDEX "IDX_42eb716a37d381cdf566192b2b" ON "__chart__notes" ("date") `); - await queryRunner.query(`CREATE INDEX "IDX_0a905b992fecd2b5c3fb98759e" ON "__chart__network" ("date", "group") `); - await queryRunner.query(`CREATE INDEX "IDX_7b5da130992ec9df96712d4290" ON "__chart__network" ("group") `); - await queryRunner.query(`CREATE INDEX "IDX_a1efd3e0048a5f2793a47360dc" ON "__chart__network" ("date") `); - await queryRunner.query(`CREATE INDEX "IDX_39ee857ab2f23493037c6b6631" ON "__chart__instance" ("date", "group") `); - await queryRunner.query(`CREATE INDEX "IDX_da8a46ba84ca1d8bb5a29bfb63" ON "__chart__instance" ("group") `); - await queryRunner.query(`CREATE INDEX "IDX_6b8f34a1a64b06014b6fb66824" ON "__chart__instance" ("date") `); - await queryRunner.query(`CREATE INDEX "IDX_25a97c02003338124b2b75fdbc" ON "__chart__hashtag" ("date", "group") `); - await queryRunner.query(`CREATE INDEX "IDX_99a7d2faaef84a6f728d714ad6" ON "__chart__hashtag" ("group") `); - await queryRunner.query(`CREATE INDEX "IDX_07747a1038c05f532a718fe1de" ON "__chart__hashtag" ("date") `); - await queryRunner.query(`CREATE INDEX "IDX_dd907becf76104e4b656659e6b" ON "__chart__federation" ("date", "group") `); - await queryRunner.query(`CREATE INDEX "IDX_76e87c7bfc5d925fcbba405d84" ON "__chart__federation" ("group") `); - await queryRunner.query(`CREATE INDEX "IDX_36cb699c49580d4e6c2e6159f9" ON "__chart__federation" ("date") `); - await queryRunner.query(`CREATE INDEX "IDX_3313d7288855ec105b5bbf6c21" ON "__chart__drive" ("date", "group") `); - await queryRunner.query(`CREATE INDEX "IDX_7a170f67425e62a8fabb76c872" ON "__chart__drive" ("group") `); - await queryRunner.query(`CREATE INDEX "IDX_13565815f618a1ff53886c5b28" ON "__chart__drive" ("date") `); - await queryRunner.query(`CREATE INDEX "IDX_9a3ed15a30ab7e3a37702e6e08" ON "__chart__active_users" ("date", "group") `); - await queryRunner.query(`CREATE INDEX "IDX_00ed5f86db1f7efafb1978bf21" ON "__chart__active_users" ("group") `); - await queryRunner.query(`CREATE INDEX "IDX_0ad37b7ef50f4ddc84363d7ccc" ON "__chart__active_users" ("date") `); - } - -} diff --git a/migration/1629024377804-deepl-integration.ts b/migration/1629024377804-deepl-integration.ts deleted file mode 100644 index 639f947c7..000000000 --- a/migration/1629024377804-deepl-integration.ts +++ /dev/null @@ -1,14 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class deeplIntegration1629024377804 implements MigrationInterface { - name = 'deeplIntegration1629024377804' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "meta" ADD "deeplAuthKey" character varying(128)`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "deeplAuthKey"`); - } - -} diff --git a/migration/1629288472000-fix-channel-userId.ts b/migration/1629288472000-fix-channel-userId.ts deleted file mode 100644 index cd8f81bb0..000000000 --- a/migration/1629288472000-fix-channel-userId.ts +++ /dev/null @@ -1,14 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class fixChannelUserId1629288472000 implements MigrationInterface { - name = 'fixChannelUserId1629288472000' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "channel" ALTER COLUMN "userId" DROP NOT NULL;`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "channel" ALTER COLUMN "userId" SET NOT NULL;`); - } - -} diff --git a/migration/1629512953000-user-is-deleted.ts b/migration/1629512953000-user-is-deleted.ts deleted file mode 100644 index 10b7d1d7b..000000000 --- a/migration/1629512953000-user-is-deleted.ts +++ /dev/null @@ -1,15 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class isUserDeleted1629512953000 implements MigrationInterface { - name = 'isUserDeleted1629512953000' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user" ADD "isDeleted" boolean NOT NULL DEFAULT false`); - await queryRunner.query(`COMMENT ON COLUMN "user"."isDeleted" IS 'Whether the User is deleted.'`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "isDeleted"`); - } - -} diff --git a/migration/1629778475000-deepl-integration2.ts b/migration/1629778475000-deepl-integration2.ts deleted file mode 100644 index 67e5ea02a..000000000 --- a/migration/1629778475000-deepl-integration2.ts +++ /dev/null @@ -1,14 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class deeplIntegration21629778475000 implements MigrationInterface { - name = 'deeplIntegration21629778475000' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "meta" ADD "deeplIsPro" boolean NOT NULL DEFAULT false`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "deeplIsPro"`); - } - -} diff --git a/migration/1633068642000-email-required-for-signup.ts b/migration/1633068642000-email-required-for-signup.ts deleted file mode 100644 index ab7be7a0d..000000000 --- a/migration/1633068642000-email-required-for-signup.ts +++ /dev/null @@ -1,14 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class emailRequiredForSignup1633068642000 implements MigrationInterface { - name = 'emailRequiredForSignup1633068642000' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "meta" ADD "emailRequiredForSignup" boolean NOT NULL DEFAULT false`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "emailRequiredForSignup"`); - } - -} diff --git a/migration/1633071909016-user-pending.ts b/migration/1633071909016-user-pending.ts deleted file mode 100644 index 28b556888..000000000 --- a/migration/1633071909016-user-pending.ts +++ /dev/null @@ -1,16 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class userPending1633071909016 implements MigrationInterface { - name = 'userPending1633071909016' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE TABLE "user_pending" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "code" character varying(128) NOT NULL, "username" character varying(128) NOT NULL, "email" character varying(128) NOT NULL, "password" character varying(128) NOT NULL, CONSTRAINT "PK_d4c84e013c98ec02d19b8fbbafa" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_4e5c4c99175638ec0761714ab0" ON "user_pending" ("code") `); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`DROP INDEX "IDX_4e5c4c99175638ec0761714ab0"`); - await queryRunner.query(`DROP TABLE "user_pending"`); - } - -} diff --git a/migration/1634486652000-user-public-reactions.ts b/migration/1634486652000-user-public-reactions.ts deleted file mode 100644 index da57a1326..000000000 --- a/migration/1634486652000-user-public-reactions.ts +++ /dev/null @@ -1,14 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class userPublicReactions1634486652000 implements MigrationInterface { - name = 'userPublicReactions1634486652000' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user_profile" ADD "publicReactions" boolean NOT NULL DEFAULT false`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "publicReactions"`); - } - -} diff --git a/migration/1634902659689-delete-log.ts b/migration/1634902659689-delete-log.ts deleted file mode 100644 index 5264d585c..000000000 --- a/migration/1634902659689-delete-log.ts +++ /dev/null @@ -1,13 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class deleteLog1634902659689 implements MigrationInterface { - name = 'deleteLog1634902659689' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`DROP TABLE "log"`); - } - - public async down(queryRunner: QueryRunner): Promise { - } - -} diff --git a/migration/1635500777168-note-thread-mute.ts b/migration/1635500777168-note-thread-mute.ts deleted file mode 100644 index aed10d18d..000000000 --- a/migration/1635500777168-note-thread-mute.ts +++ /dev/null @@ -1,26 +0,0 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; - -export class noteThreadMute1635500777168 implements MigrationInterface { - name = 'noteThreadMute1635500777168' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE TABLE "note_thread_muting" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "threadId" character varying(256) NOT NULL, CONSTRAINT "PK_ec5936d94d1a0369646d12a3a47" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE INDEX "IDX_29c11c7deb06615076f8c95b80" ON "note_thread_muting" ("userId") `); - await queryRunner.query(`CREATE INDEX "IDX_c426394644267453e76f036926" ON "note_thread_muting" ("threadId") `); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_ae7aab18a2641d3e5f25e0c4ea" ON "note_thread_muting" ("userId", "threadId") `); - await queryRunner.query(`ALTER TABLE "note" ADD "threadId" character varying(256)`); - await queryRunner.query(`CREATE INDEX "IDX_d4ebdef929896d6dc4a3c5bb48" ON "note" ("threadId") `); - await queryRunner.query(`ALTER TABLE "note_thread_muting" ADD CONSTRAINT "FK_29c11c7deb06615076f8c95b80a" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "note_thread_muting" DROP CONSTRAINT "FK_29c11c7deb06615076f8c95b80a"`); - await queryRunner.query(`DROP INDEX "public"."IDX_d4ebdef929896d6dc4a3c5bb48"`); - await queryRunner.query(`ALTER TABLE "note" DROP COLUMN "threadId"`); - await queryRunner.query(`DROP INDEX "public"."IDX_ae7aab18a2641d3e5f25e0c4ea"`); - await queryRunner.query(`DROP INDEX "public"."IDX_c426394644267453e76f036926"`); - await queryRunner.query(`DROP INDEX "public"."IDX_29c11c7deb06615076f8c95b80"`); - await queryRunner.query(`DROP TABLE "note_thread_muting"`); - } - -} diff --git a/ormconfig.js b/ormconfig.js deleted file mode 100644 index 8a0196947..000000000 --- a/ormconfig.js +++ /dev/null @@ -1,17 +0,0 @@ -const config = require('./built/config').default; -const entities = require('./built/db/postgre').entities; - -module.exports = { - type: 'postgres', - host: config.db.host, - port: config.db.port, - username: config.db.user, - password: config.db.pass, - database: config.db.db, - extra: config.db.extra, - entities: entities, - migrations: ['migration/*.ts'], - cli: { - migrationsDir: 'migration' - } -}; diff --git a/package.json b/package.json index 868722392..86f8a03cb 100644 --- a/package.json +++ b/package.json @@ -1,261 +1,50 @@ { "name": "misskey", - "version": "12.95.0", + "version": "12.96.0", "codename": "indigo", "repository": { "type": "git", "url": "https://github.com/misskey-dev/misskey.git" }, - "main": "./index.js", "private": true, "scripts": { - "start": "node --experimental-json-modules ./index.js", - "start:test": "cross-env NODE_ENV=test node --experimental-json-modules ./index.js", + "postinstall": "node ./scripts/install-packages.js", + "build": "node ./scripts/build.js", + "start": "cd packages/backend && node --experimental-json-modules ./built/index.js", + "start:test": "cd packages/backend && cross-env NODE_ENV=test node --experimental-json-modules ./built/index.js", "init": "npm run migrate", - "ormconfig": "node ./built/ormconfig.js", - "migrate": "ts-node ./node_modules/typeorm/cli.js migration:run", + "ormconfig": "node ./packages/backend/ormconfig.js", + "migrate": "cd packages/backend && npx typeorm migration:run", "migrateandstart": "npm run migrate && npm run start", - "build": "npm run build-webpack && npm run build-ts && npm run build-gulp", - "build-webpack": "webpack", - "build-ts": "tsc -p src/tsconfig.json || echo done. && tsc-alias -p src/tsconfig.json", - "build-gulp": "gulp build", + "gulp": "gulp build", "watch": "concurrently \"npm:watch-*\"", "watch-webpack": "webpack --watch", - "watch-ts": "tsc -w -p src/tsconfig.json && tsc-alias -w -p src/tsconfig.json", + "watch-ts": "tsc -w -p packages/tsconfig.json && tsc-alias -w -p packages/tsconfig.json", "watch-gulp": "gulp watch", - "clean": "gulp clean", - "cleanall": "gulp cleanall", - "lint": "tslint 'src/**/*.ts'", + "lint": "node ./scripts/lint.js", "cy:open": "cypress open", "cy:run": "cypress run", "e2e": "start-server-and-test start:test http://localhost:61812 cy:run", - "mocha": "cross-env TS_NODE_FILES=true TS_NODE_TRANSPILE_ONLY=true TS_NODE_PROJECT=\"./test/tsconfig.json\" mocha", + "mocha": "cd packages/backend && cross-env TS_NODE_FILES=true TS_NODE_TRANSPILE_ONLY=true TS_NODE_PROJECT=\"./test/tsconfig.json\" npx mocha", "test": "npm run mocha", - "format": "gulp format" - }, - "resolutions": { - "chokidar": "^3.3.1", - "lodash": "^4.17.21" + "format": "gulp format", + "clean": "node ./scripts/clean.js" }, "dependencies": { - "@discordapp/twemoji": "13.1.0", - "@elastic/elasticsearch": "7.11.0", - "@koa/cors": "3.1.0", - "@koa/multer": "3.0.0", - "@koa/router": "9.0.1", - "@sentry/browser": "5.29.2", - "@sentry/tracing": "5.29.2", - "@sinonjs/fake-timers": "7.1.2", - "@syuilo/aiscript": "0.11.1", - "@types/bcryptjs": "2.4.2", - "@types/bull": "3.15.5", - "@types/cbor": "6.0.0", - "@types/dateformat": "3.0.1", - "@types/escape-regexp": "0.0.0", - "@types/glob": "7.2.0", "@types/gulp": "4.0.9", "@types/gulp-rename": "2.0.1", - "@types/is-url": "1.2.30", - "@types/js-yaml": "4.0.4", - "@types/jsdom": "16.2.13", - "@types/jsonld": "1.5.6", - "@types/katex": "0.11.1", - "@types/koa": "2.13.4", - "@types/koa-bodyparser": "4.3.3", - "@types/koa-cors": "0.0.2", - "@types/koa-favicon": "2.0.21", - "@types/koa-logger": "3.1.2", - "@types/koa-mount": "4.0.1", - "@types/koa-send": "4.1.3", - "@types/koa-views": "7.0.0", - "@types/koa__cors": "3.0.3", - "@types/koa__multer": "2.0.4", - "@types/koa__router": "8.0.8", - "@types/markdown-it": "12.2.3", - "@types/matter-js": "0.17.6", - "@types/mocha": "8.2.3", - "@types/node": "16.11.4", - "@types/node-fetch": "2.5.12", - "@types/nodemailer": "6.4.4", - "@types/nprogress": "0.2.0", - "@types/oauth": "0.9.1", - "@types/parse5": "6.0.2", - "@types/parsimmon": "1.10.6", - "@types/portscanner": "2.1.1", - "@types/pug": "2.0.5", - "@types/punycode": "2.1.0", - "@types/qrcode": "1.4.1", - "@types/random-seed": "0.3.3", - "@types/ratelimiter": "3.4.2", - "@types/redis": "2.8.32", - "@types/rename": "1.0.4", - "@types/request-stats": "3.0.0", - "@types/rimraf": "3.0.2", - "@types/seedrandom": "2.4.28", - "@types/sharp": "0.29.2", - "@types/sinonjs__fake-timers": "6.0.4", - "@types/speakeasy": "2.0.6", - "@types/throttle-debounce": "2.1.0", - "@types/tinycolor2": "1.4.3", - "@types/tmp": "0.2.2", - "@types/uuid": "8.3.1", - "@types/web-push": "3.3.2", - "@types/webpack": "5.28.0", - "@types/webpack-stream": "3.2.12", - "@types/websocket": "1.0.4", - "@types/ws": "8.2.0", - "@typescript-eslint/parser": "5.1.0", - "@vue/compiler-sfc": "3.2.20", - "abort-controller": "3.0.0", - "autobind-decorator": "2.4.0", - "autosize": "4.0.4", - "autwh": "0.1.0", - "aws-sdk": "2.1013.0", - "bcryptjs": "2.4.3", - "blurhash": "1.1.4", - "broadcast-channel": "4.2.0", - "bull": "3.29.3", - "cacheable-lookup": "6.0.3", - "cafy": "15.2.1", - "cbor": "8.0.2", - "chalk": "4.1.2", - "chart.js": "3.6.0", - "chartjs-adapter-date-fns": "2.0.0", - "chartjs-plugin-zoom": "1.1.1", - "cli-highlight": "2.1.11", - "compare-versions": "3.6.0", - "concurrently": "6.3.0", - "content-disposition": "0.5.3", - "crc-32": "1.2.0", - "css-loader": "6.4.0", - "cssnano": "5.0.8", - "date-fns": "2.25.0", - "dateformat": "4.5.1", - "escape-regexp": "0.0.1", - "eslint": "8.1.0", - "eslint-plugin-vue": "7.20.0", - "eventemitter3": "4.0.7", - "feed": "4.2.2", - "file-type": "16.5.3", - "fluent-ffmpeg": "2.1.2", - "glob": "7.2.0", - "got": "11.8.2", + "execa": "5.1.1", "gulp": "4.0.2", "gulp-cssnano": "2.1.3", "gulp-rename": "2.0.0", "gulp-replace": "1.1.3", - "gulp-terser": "2.1.0", - "gulp-tslint": "8.1.4", - "hpagent": "0.1.2", - "http-signature": "1.3.5", - "idb-keyval": "5.1.3", - "insert-text-at-cursor": "0.3.0", - "ip-cidr": "3.0.4", - "is-svg": "4.3.1", - "js-yaml": "4.1.0", - "jsdom": "16.7.0", - "json5": "2.2.0", - "json5-loader": "4.0.1", - "jsonld": "5.2.0", - "jsrsasign": "8.0.20", - "katex": "0.13.18", - "koa": "2.13.4", - "koa-bodyparser": "4.3.0", - "koa-favicon": "2.1.0", - "koa-json-body": "5.3.0", - "koa-logger": "3.2.1", - "koa-mount": "4.0.0", - "koa-send": "5.0.1", - "koa-slow": "2.1.0", - "koa-views": "7.0.1", - "langmap": "0.0.16", - "markdown-it": "12.2.0", - "markdown-it-anchor": "7.1.0", - "matter-js": "0.17.1", - "mfm-js": "0.20.0", - "misskey-js": "0.0.8", - "mocha": "8.4.0", - "ms": "2.1.3", - "multer": "1.4.3", - "nested-property": "4.0.0", - "node-fetch": "2.6.1", - "nodemailer": "6.7.0", - "os-utils": "0.0.14", - "parse5": "6.0.1", - "pg": "8.7.1", - "photoswipe": "git://github.com/dimsemenov/photoswipe#v5-beta", - "portscanner": "2.2.0", - "postcss": "8.3.11", - "postcss-loader": "6.2.0", - "prismjs": "1.25.0", - "private-ip": "2.3.0", - "probe-image-size": "7.2.1", - "promise-limit": "2.7.0", - "pug": "3.0.2", - "punycode": "2.1.1", - "pureimage": "0.3.5", - "qrcode": "1.4.4", - "random-seed": "0.3.0", - "ratelimiter": "3.4.1", - "re2": "1.16.0", - "redis": "3.1.2", - "redis-lock": "0.1.4", - "reflect-metadata": "0.1.13", - "rename": "1.0.4", - "request-stats": "3.0.0", - "require-all": "3.0.0", - "rimraf": "3.0.2", - "rndstr": "1.0.0", - "s-age": "1.1.2", - "sass": "1.43.3", - "sass-loader": "12.2.0", - "seedrandom": "3.0.5", - "sharp": "0.29.2", - "speakeasy": "2.0.0", - "strict-event-emitter-types": "2.0.0", - "stringz": "2.1.0", - "style-loader": "3.3.1", - "summaly": "2.4.1", - "syslog-pro": "1.0.0", - "systeminformation": "5.9.8", - "syuilo-password-strength": "0.0.1", - "textarea-caret": "3.1.0", - "three": "0.117.1", - "throttle-debounce": "3.0.1", - "tinycolor2": "1.4.2", - "tmp": "0.2.1", - "ts-loader": "9.2.6", - "ts-node": "10.4.0", - "tsc-alias": "1.3.10", - "tsconfig-paths": "3.11.0", - "tslint": "6.1.3", - "tslint-sonarts": "1.9.0", - "twemoji-parser": "13.1.0", - "typeorm": "0.2.38", - "typescript": "4.4.4", - "ulid": "2.3.0", - "uuid": "8.3.2", - "v-debounce": "0.1.2", - "vanilla-tilt": "1.7.2", - "vue": "3.2.20", - "vue-loader": "16.7.0", - "vue-prism-editor": "2.0.0-alpha.2", - "vue-router": "4.0.5", - "vue-style-loader": "4.1.3", - "vue-svg-loader": "0.17.0-beta.2", - "vuedraggable": "4.0.1", - "web-push": "3.4.5", - "webpack": "5.59.1", - "webpack-cli": "4.9.1", - "websocket": "1.0.34", - "ws": "8.2.3", - "xev": "2.0.1" + "gulp-terser": "2.1.0" }, "devDependencies": { "@redocly/openapi-core": "1.0.0-beta.54", "@types/fluent-ffmpeg": "2.1.17", "cross-env": "7.0.3", - "cypress": "8.5.0", + "cypress": "9.0.0", "start-server-and-test": "1.14.0" } } diff --git a/packages/backend/.eslintignore b/packages/backend/.eslintignore new file mode 100644 index 000000000..790eb9014 --- /dev/null +++ b/packages/backend/.eslintignore @@ -0,0 +1,4 @@ +node_modules +/built +/.eslintrc.js +/@types/**/* diff --git a/packages/backend/.eslintrc.js b/packages/backend/.eslintrc.js new file mode 100644 index 000000000..5ce38b9cc --- /dev/null +++ b/packages/backend/.eslintrc.js @@ -0,0 +1,64 @@ +module.exports = { + root: true, + parser: '@typescript-eslint/parser', + parserOptions: { + tsconfigRootDir: __dirname, + project: ['./tsconfig.json'], + }, + plugins: [ + '@typescript-eslint', + 'import' + ], + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended', + 'plugin:import/recommended', + 'plugin:import/typescript' + ], + rules: { + 'indent': ['warn', 'tab', { + 'SwitchCase': 1, + 'MemberExpression': 'off', + 'flatTernaryExpressions': true, + 'ArrayExpression': 'first', + 'ObjectExpression': 'first', + }], + 'eol-last': ['error', 'always'], + 'semi': ['error', 'always'], + 'quotes': ['warn', 'single'], + 'comma-dangle': ['warn', 'always-multiline'], + 'keyword-spacing': ['error', { + 'before': true, + 'after': true, + }], + /* TODO: path aliasを使わないとwarnする + 'no-restricted-imports': ['warn', { + 'patterns': [ + ] + }], + */ + 'no-multi-spaces': ['error'], + 'no-var': ['error'], + 'prefer-arrow-callback': ['error'], + 'no-throw-literal': ['warn'], + 'no-param-reassign': ['warn'], + 'no-constant-condition': ['warn'], + 'no-empty-pattern': ['warn'], + 'no-async-promise-executor': ['off'], + 'no-useless-escape': ['off'], + 'no-multi-spaces': ['warn'], + 'no-control-regex': ['warn'], + 'no-empty': ['warn'], + 'no-inner-declarations': ['off'], + 'no-sparse-arrays': ['off'], + '@typescript-eslint/no-var-requires': ['warn'], + '@typescript-eslint/no-inferrable-types': ['warn'], + '@typescript-eslint/no-empty-function': ['off'], + '@typescript-eslint/no-non-null-assertion': ['off'], + '@typescript-eslint/no-misused-promises': ['error', { + 'checksVoidReturn': false, + }], + 'import/no-unresolved': ['off'], + 'import/no-default-export': ['warn'], + }, +}; diff --git a/.mocharc.json b/packages/backend/.mocharc.json similarity index 100% rename from .mocharc.json rename to packages/backend/.mocharc.json diff --git a/packages/backend/.npmrc b/packages/backend/.npmrc new file mode 100644 index 000000000..6b5f38e89 --- /dev/null +++ b/packages/backend/.npmrc @@ -0,0 +1,2 @@ +save-exact = true +package-lock = false diff --git a/packages/backend/.yarnrc b/packages/backend/.yarnrc new file mode 100644 index 000000000..788570fcd --- /dev/null +++ b/packages/backend/.yarnrc @@ -0,0 +1 @@ +network-timeout 600000 diff --git a/src/@types/hcaptcha.d.ts b/packages/backend/@types/hcaptcha.d.ts similarity index 100% rename from src/@types/hcaptcha.d.ts rename to packages/backend/@types/hcaptcha.d.ts diff --git a/src/@types/http-signature.d.ts b/packages/backend/@types/http-signature.d.ts similarity index 100% rename from src/@types/http-signature.d.ts rename to packages/backend/@types/http-signature.d.ts diff --git a/packages/backend/@types/jsrsasign.d.ts b/packages/backend/@types/jsrsasign.d.ts new file mode 100644 index 000000000..bb52f8f64 --- /dev/null +++ b/packages/backend/@types/jsrsasign.d.ts @@ -0,0 +1,800 @@ +// Attention: Partial Type Definition + +declare module 'jsrsasign' { + //// HELPER TYPES + + /** + * Attention: The value might be changed by the function. + */ + type Mutable = T; + + /** + * Deprecated: The function might be deleted in future release. + */ + type Deprecated = T; + + //// COMMON TYPES + + /** + * byte number + */ + type ByteNumber = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255; + + /** + * hexadecimal string /[0-9A-F]/ + */ + type HexString = string; + + /** + * binary string /[01]/ + */ + type BinString = string; + + /** + * base64 string /[A-Za-z0-9+/]=+/ + */ + type Base64String = string; + + /** + * base64 URL encoded string /[A-Za-z0-9_-]/ + */ + type Base64URLString = string; + + /** + * time value (ex. "151231235959Z") + */ + type TimeValue = string; + + /** + * OID string (ex. '1.2.3.4.567') + */ + type OID = string; + + /** + * OID name + */ + type OIDName = string; + + /** + * PEM formatted string + */ + type PEM = string; + + //// ASN1 TYPES + + class ASN1Object { + public isModified: boolean; + + public hTLV: ASN1TLV; + + public hT: ASN1T; + + public hL: ASN1L; + + public hV: ASN1V; + + public getLengthHexFromValue(): HexString; + + public getEncodedHex(): ASN1TLV; + + public getValueHex(): ASN1V; + + public getFreshValueHex(): ASN1V; + } + + class DERAbstractStructured extends ASN1Object { + constructor(params?: Partial>); + + public setByASN1ObjectArray(asn1ObjectArray: ASN1Object[]): void; + + public appendASN1Object(asn1Object: ASN1Object): void; + } + + class DERSequence extends DERAbstractStructured { + constructor(params?: Partial>); + + public getFreshValueHex(): ASN1V; + } + + //// ASN1HEX TYPES + + /** + * ASN.1 DER encoded data (hexadecimal string) + */ + type ASN1S = HexString; + + /** + * index of something + */ + type Idx = ASN1S extends { [idx: string]: unknown } ? string : ASN1S extends { [idx: number]: unknown } ? number : never; + + /** + * byte length of something + */ + type ByteLength = T['length']; + + /** + * ASN.1 L(length) (hexadecimal string) + */ + type ASN1L = HexString; + + /** + * ASN.1 T(tag) (hexadecimal string) + */ + type ASN1T = HexString; + + /** + * ASN.1 V(value) (hexadecimal string) + */ + type ASN1V = HexString; + + /** + * ASN.1 TLV (hexadecimal string) + */ + type ASN1TLV = HexString; + + /** + * ASN.1 object string + */ + type ASN1ObjectString = string; + + /** + * nth + */ + type Nth = number; + + /** + * ASN.1 DER encoded OID value (hexadecimal string) + */ + type ASN1OIDV = HexString; + + class ASN1HEX { + public static getLblen(s: ASN1S, idx: Idx): ByteLength; + + public static getL(s: ASN1S, idx: Idx): ASN1L; + + public static getVblen(s: ASN1S, idx: Idx): ByteLength; + + public static getVidx(s: ASN1S, idx: Idx): Idx; + + public static getV(s: ASN1S, idx: Idx): ASN1V; + + public static getTLV(s: ASN1S, idx: Idx): ASN1TLV; + + public static getNextSiblingIdx(s: ASN1S, idx: Idx): Idx; + + public static getChildIdx(h: ASN1S, pos: Idx): Idx[]; + + public static getNthChildIdx(h: ASN1S, idx: Idx, nth: Nth): Idx; + + public static getIdxbyList(h: ASN1S, currentIndex: Idx, nthList: Mutable, checkingTag?: string): Idx>; + + public static getTLVbyList(h: ASN1S, currentIndex: Idx, nthList: Mutable, checkingTag?: string): ASN1TLV; + + // eslint:disable-next-line:bool-param-default + public static getVbyList(h: ASN1S, currentIndex: Idx, nthList: Mutable, checkingTag?: string, removeUnusedbits?: boolean): ASN1V; + + public static hextooidstr(hex: ASN1OIDV): OID; + + public static dump(hexOrObj: ASN1S | ASN1Object, flags?: Record, idx?: Idx, indent?: string): string; + + public static isASN1HEX(hex: string): hex is HexString; + + public static oidname(oidDotOrHex: OID | ASN1OIDV): OIDName; + } + + //// BIG INTEGER TYPES (PARTIAL) + + class BigInteger { + constructor(a: null); + + constructor(a: number, b: SecureRandom); + + constructor(a: number, b: number, c: SecureRandom); + + constructor(a: unknown); + + constructor(a: string, b: number); + + public am(i: number, x: number, w: number, j: number, c: number, n: number): number; + + public DB: number; + + public DM: number; + + public DV: number; + + public FV: number; + + public F1: number; + + public F2: number; + + protected copyTo(r: Mutable): void; + + protected fromInt(x: number): void; + + protected fromString(s: string, b: number): void; + + protected clamp(): void; + + public toString(b: number): string; + + public negate(): BigInteger; + + public abs(): BigInteger; + + public compareTo(a: BigInteger): number; + + public bitLength(): number; + + protected dlShiftTo(n: number, r: Mutable): void; + + protected drShiftTo(n: number, r: Mutable): void; + + protected lShiftTo(n: number, r: Mutable): void; + + protected rShiftTo(n: number, r: Mutable): void; + + protected subTo(a: BigInteger, r: Mutable): void; + + protected multiplyTo(a: BigInteger, r: Mutable): void; + + protected squareTo(r: Mutable): void; + + protected divRemTo(m: BigInteger, q: Mutable, r: Mutable): void; + + public mod(a: BigInteger): BigInteger; + + protected invDigit(): number; + + protected isEven(): boolean; + + protected exp(e: number, z: Classic | Montgomery): BigInteger; + + public modPowInt(e: number, m: BigInteger): BigInteger; + + public static ZERO: BigInteger; + + public static ONE: BigInteger; + } + + class Classic { + constructor(m: BigInteger); + + public convert(x: BigInteger): BigInteger; + + public revert(x: BigInteger): BigInteger; + + public reduce(x: Mutable): void; + + public mulTo(x: BigInteger, r: Mutable): void; + + public sqrTo(x: BigInteger, y: BigInteger, r: Mutable): void; + } + + class Montgomery { + constructor(m: BigInteger); + + public convert(x: BigInteger): BigInteger; + + public revert(x: BigInteger): BigInteger; + + public reduce(x: Mutable): void; + + public mulTo(x: BigInteger, r: Mutable): void; + + public sqrTo(x: BigInteger, y: BigInteger, r: Mutable): void; + } + + //// KEYUTIL TYPES + + type DecryptAES = (dataHex: HexString, keyHex: HexString, ivHex: HexString) => HexString; + + type Decrypt3DES = (dataHex: HexString, keyHex: HexString, ivHex: HexString) => HexString; + + type DecryptDES = (dataHex: HexString, keyHex: HexString, ivHex: HexString) => HexString; + + type EncryptAES = (dataHex: HexString, keyHex: HexString, ivHex: HexString) => HexString; + + type Encrypt3DES = (dataHex: HexString, keyHex: HexString, ivHex: HexString) => HexString; + + type EncryptDES = (dataHex: HexString, keyHex: HexString, ivHex: HexString) => HexString; + + type AlgList = { + 'AES-256-CBC': { 'proc': DecryptAES; 'eproc': EncryptAES; keylen: 32; ivlen: 16; }; + 'AES-192-CBC': { 'proc': DecryptAES; 'eproc': EncryptAES; keylen: 24; ivlen: 16; }; + 'AES-128-CBC': { 'proc': DecryptAES; 'eproc': EncryptAES; keylen: 16; ivlen: 16; }; + 'DES-EDE3-CBC': { 'proc': Decrypt3DES; 'eproc': Encrypt3DES; keylen: 24; ivlen: 8; }; + 'DES-CBC': { 'proc': DecryptDES; 'eproc': EncryptDES; keylen: 8; ivlen: 8; }; + }; + + type AlgName = keyof AlgList; + + type PEMHeadAlgName = 'RSA' | 'EC' | 'DSA'; + + type GetKeyRSAParam = RSAKey | { + n: BigInteger; + e: number; + } | Record<'n' | 'e', HexString> | Record<'n' | 'e', HexString> & Record<'d' | 'p' | 'q' | 'dp' | 'dq' | 'co', HexString | null> | { + n: BigInteger; + e: number; + d: BigInteger; + } | { + kty: 'RSA'; + } & Record<'n' | 'e', Base64URLString> | { + kty: 'RSA'; + } & Record<'n' | 'e' | 'd' | 'p' | 'q' | 'dp' | 'dq' | 'qi', Base64URLString> | { + kty: 'RSA'; + } & Record<'n' | 'e' | 'd', Base64URLString>; + + type GetKeyECDSAParam = KJUR.crypto.ECDSA | { + curve: KJUR.crypto.CurveName; + xy: HexString; + } | { + curve: KJUR.crypto.CurveName; + d: HexString; + } | { + kty: 'EC'; + crv: KJUR.crypto.CurveName; + x: Base64URLString; + y: Base64URLString; + } | { + kty: 'EC'; + crv: KJUR.crypto.CurveName; + x: Base64URLString; + y: Base64URLString; + d: Base64URLString; + }; + + type GetKeyDSAParam = KJUR.crypto.DSA | Record<'p' | 'q' | 'g', BigInteger> & Record<'y', BigInteger | null> | Record<'p' | 'q' | 'g' | 'x', BigInteger> & Record<'y', BigInteger | null>; + + type GetKeyParam = GetKeyRSAParam | GetKeyECDSAParam | GetKeyDSAParam | string; + + class KEYUTIL { + public version: '1.0.0'; + + public parsePKCS5PEM(sPKCS5PEM: PEM): Partial> & (Record<'cipher' | 'ivsalt', string> | Record<'cipher' | 'ivsalt', undefined>); + + public getKeyAndUnusedIvByPasscodeAndIvsalt(algName: AlgName, passcode: string, ivsaltHex: HexString): Record<'keyhex' | 'ivhex', HexString>; + + public decryptKeyB64(privateKeyB64: Base64String, sharedKeyAlgName: AlgName, sharedKeyHex: HexString, ivsaltHex: HexString): Base64String; + + public getDecryptedKeyHex(sEncryptedPEM: PEM, passcode: string): HexString; + + public getEncryptedPKCS5PEMFromPrvKeyHex(pemHeadAlg: PEMHeadAlgName, hPrvKey: string, passcode: string, sharedKeyAlgName?: AlgName | null, ivsaltHex?: HexString | null): PEM; + + public parseHexOfEncryptedPKCS8(sHEX: HexString): { + ciphertext: ASN1V; + encryptionSchemeAlg: 'TripleDES'; + encryptionSchemeIV: ASN1V; + pbkdf2Salt: ASN1V; + pbkdf2Iter: number; + }; + + public getPBKDF2KeyHexFromParam(info: ReturnType, passcode: string): HexString; + + private _getPlainPKCS8HexFromEncryptedPKCS8PEM(pkcs8PEM: PEM, passcode: string): HexString; + + public getKeyFromEncryptedPKCS8PEM(prvKeyHex: HexString): ReturnType; + + public parsePlainPrivatePKCS8Hex(pkcs8PrvHex: HexString): { + algparam: ASN1V | null; + algoid: ASN1V; + keyidx: Idx; + }; + + public getKeyFromPlainPrivatePKCS8PEM(prvKeyHex: HexString): ReturnType; + + public getKeyFromPlainPrivatePKCS8Hex(prvKeyHex: HexString): RSAKey | KJUR.crypto.DSA | KJUR.crypto.ECDSA; + + private _getKeyFromPublicPKCS8Hex(h: HexString): RSAKey | KJUR.crypto.DSA | KJUR.crypto.ECDSA; + + public parsePublicRawRSAKeyHex(pubRawRSAHex: HexString): Record<'n' | 'e', ASN1V>; + + public parsePublicPKCS8Hex(pkcs8PubHex: HexString): { + algparam: ASN1V | Record<'p' | 'q' | 'g', ASN1V> | null; + algoid: ASN1V; + key: ASN1V; + }; + + public static getKey(param: GetKeyRSAParam): RSAKey; + + public static getKey(param: GetKeyECDSAParam): KJUR.crypto.ECDSA; + + public static getKey(param: GetKeyDSAParam): KJUR.crypto.DSA; + + public static getKey(param: string, passcode?: string, hextype?: string): RSAKey | KJUR.crypto.ECDSA | KJUR.crypto.DSA; + + public static generateKeypair(alg: 'RSA', keylen: number): Record<'prvKeyObj' | 'pubKeyObj', RSAKey>; + + public static generateKeypair(alg: 'EC', curve: KJUR.crypto.CurveName): Record<'prvKeyObj' | 'pubKeyObj', KJUR.crypto.ECDSA>; + + public static getPEM(keyObjOrHex: RSAKey | KJUR.crypto.ECDSA | KJUR.crypto.DSA, formatType?: 'PKCS1PRV' | 'PKCS5PRV' | 'PKCS8PRV', passwd?: string, encAlg?: 'DES-CBC' | 'DES-EDE3-CBC' | 'AES-128-CBC' | 'AES-192-CBC' | 'AES-256-CBC', hexType?: string, ivsaltHex?: HexString): object; // To Do + + public static getKeyFromCSRPEM(csrPEM: PEM): RSAKey | KJUR.crypto.ECDSA | KJUR.crypto.DSA; + + public static getKeyFromCSRHex(csrHex: HexString): RSAKey | KJUR.crypto.ECDSA | KJUR.crypto.DSA; + + public static parseCSRHex(csrHex: HexString): Record<'p8pubkeyhex', ASN1TLV>; + + public static getJWKFromKey(keyObj: RSAKey): { + kty: 'RSA'; + } & Record<'n' | 'e' | 'd' | 'p' | 'q' | 'dp' | 'dq' | 'qi', Base64URLString> | { + kty: 'RSA'; + } & Record<'n' | 'e', Base64URLString>; + + public static getJWKFromKey(keyObj: KJUR.crypto.ECDSA): { + kty: 'EC'; + crv: KJUR.crypto.CurveName; + x: Base64URLString; + y: Base64URLString; + d: Base64URLString; + } | { + kty: 'EC'; + crv: KJUR.crypto.CurveName; + x: Base64URLString; + y: Base64URLString; + }; + } + + //// KJUR NAMESPACE (PARTIAL) + + namespace KJUR { + namespace crypto { + type CurveName = 'secp128r1' | 'secp160k1' | 'secp160r1' | 'secp192k1' | 'secp192r1' | 'secp224r1' | 'secp256k1' | 'secp256r1' | 'secp384r1' | 'secp521r1'; + + class DSA { + public p: BigInteger | null; + + public q: BigInteger | null; + + public g: BigInteger | null; + + public y: BigInteger | null; + + public x: BigInteger | null; + + public type: 'DSA'; + + public isPrivate: boolean; + + public isPublic: boolean; + + public setPrivate(p: BigInteger, q: BigInteger, g: BigInteger, y: BigInteger | null, x: BigInteger): void; + + public setPrivateHex(hP: HexString, hQ: HexString, hG: HexString, hY: HexString | null, hX: HexString): void; + + public setPublic(p: BigInteger, q: BigInteger, g: BigInteger, y: BigInteger): void; + + public setPublicHex(hP: HexString, hQ: HexString, hG: HexString, hY: HexString): void; + + public signWithMessageHash(sHashHex: HexString): HexString; + + public verifyWithMessageHash(sHashHex: HexString, hSigVal: HexString): boolean; + + public parseASN1Signature(hSigVal: HexString): [BigInteger, BigInteger]; + + public readPKCS5PrvKeyHex(h: HexString): void; + + public readPKCS8PrvKeyHex(h: HexString): void; + + public readPKCS8PubKeyHex(h: HexString): void; + + public readCertPubKeyHex(h: HexString, nthPKI: number): void; + } + + class ECDSA { + constructor(params?: { + curve?: CurveName; + prv?: HexString; + pub?: HexString; + }); + + public p: BigInteger | null; + + public q: BigInteger | null; + + public g: BigInteger | null; + + public y: BigInteger | null; + + public x: BigInteger | null; + + public type: 'EC'; + + public isPrivate: boolean; + + public isPublic: boolean; + + public getBigRandom(limit: BigInteger): BigInteger; + + public setNamedCurve(curveName: CurveName): void; + + public setPrivateKeyHex(prvKeyHex: HexString): void; + + public setPublicKeyHex(pubKeyHex: HexString): void; + + public getPublicKeyXYHex(): Record<'x' | 'y', HexString>; + + public getShortNISTPCurveName(): 'P-256' | 'P-384' | null; + + public generateKeyPairHex(): Record<'ecprvhex' | 'ecpubhex', HexString>; + + public signWithMessageHash(hashHex: HexString): HexString; + + public signHex(hashHex: HexString, privHex: HexString): HexString; + + public verifyWithMessageHash(sHashHex: HexString, hSigVal: HexString): boolean; + + public parseASN1Signature(hSigVal: HexString): [BigInteger, BigInteger]; + + public readPKCS5PrvKeyHex(h: HexString): void; + + public readPKCS8PrvKeyHex(h: HexString): void; + + public readPKCS8PubKeyHex(h: HexString): void; + + public readCertPubKeyHex(h: HexString, nthPKI: number): void; + + public static parseSigHex(sigHex: HexString): Record<'r' | 's', BigInteger>; + + public static parseSigHexInHexRS(sigHex: HexString): Record<'r' | 's', ASN1V>; + + public static asn1SigToConcatSig(asn1Sig: HexString): HexString; + + public static concatSigToASN1Sig(concatSig: HexString): ASN1TLV; + + public static hexRSSigToASN1Sig(hR: HexString, hS: HexString): ASN1TLV; + + public static biRSSigToASN1Sig(biR: BigInteger, biS: BigInteger): ASN1TLV; + + public static getName(s: CurveName | HexString): 'secp256r1' | 'secp256k1' | 'secp384r1' | null; + } + + class Signature { + constructor(params?: ({ + alg: string; + prov?: string; + } | {}) & ({ + psssaltlen: number; + } | {}) & ({ + prvkeypem: PEM; + prvkeypas?: never; + } | {})); + + private _setAlgNames(): void; + + private _zeroPaddingOfSignature(hex: HexString, bitLength: number): HexString; + + public setAlgAndProvider(alg: string, prov: string): void; + + public init(key: GetKeyParam, pass?: string): void; + + public updateString(str: string): void; + + public updateHex(hex: HexString): void; + + public sign(): HexString; + + public signString(str: string): HexString; + + public signHex(hex: HexString): HexString; + + public verify(hSigVal: string): boolean | 0; + } + } + } + + //// RSAKEY TYPES + + class RSAKey { + public n: BigInteger | null; + + public e: number; + + public d: BigInteger | null; + + public p: BigInteger | null; + + public q: BigInteger | null; + + public dmp1: BigInteger | null; + + public dmq1: BigInteger | null; + + public coeff: BigInteger | null; + + public type: 'RSA'; + + public isPrivate?: boolean; + + public isPublic?: boolean; + + //// RSA PUBLIC + + protected doPublic(x: BigInteger): BigInteger; + + public setPublic(N: BigInteger, E: number): void; + + public setPublic(N: HexString, E: HexString): void; + + public encrypt(text: string): HexString | null; + + public encryptOAEP(text: string, hash?: string | ((s: string) => string), hashLen?: number): HexString | null; + + //// RSA PRIVATE + + protected doPrivate(x: BigInteger): BigInteger; + + public setPrivate(N: BigInteger, E: number, D: BigInteger): void; + + public setPrivate(N: HexString, E: HexString, D: HexString): void; + + public setPrivateEx(N: HexString, E: HexString, D?: HexString | null, P?: HexString | null, Q?: HexString | null, DP?: HexString | null, DQ?: HexString | null, C?: HexString | null): void; + + public generate(B: number, E: HexString): void; + + public decrypt(ctext: HexString): string; + + public decryptOAEP(ctext: HexString, hash?: string | ((s: string) => string), hashLen?: number): string | null; + + //// RSA PEM + + public getPosArrayOfChildrenFromHex(hPrivateKey: PEM): Idx[]; + + public getHexValueArrayOfChildrenFromHex(hPrivateKey: PEM): Idx[]; + + public readPrivateKeyFromPEMString(keyPEM: PEM): void; + + public readPKCS5PrvKeyHex(h: HexString): void; + + public readPKCS8PrvKeyHex(h: HexString): void; + + public readPKCS5PubKeyHex(h: HexString): void; + + public readPKCS8PubKeyHex(h: HexString): void; + + public readCertPubKeyHex(h: HexString, nthPKI: Nth): void; + + //// RSA SIGN + + public sign(s: string, hashAlg: string): HexString; + + public signWithMessageHash(sHashHex: HexString, hashAlg: string): HexString; + + public signPSS(s: string, hashAlg: string, sLen: number): HexString; + + public signWithMessageHashPSS(hHash: HexString, hashAlg: string, sLen: number): HexString; + + public verify(sMsg: string, hSig: HexString): boolean | 0; + + public verifyWithMessageHash(sHashHex: HexString, hSig: HexString): boolean | 0; + + public verifyPSS(sMsg: string, hSig: HexString, hashAlg: string, sLen: number): boolean; + + public verifyWithMessageHashPSS(hHash: HexString, hSig: HexString, hashAlg: string, sLen: number): boolean; + + public static SALT_LEN_HLEN: -1; + + public static SALT_LEN_MAX: -2; + + public static SALT_LEN_RECOVER: -2; + } + + /// RNG TYPES + class SecureRandom { + public nextBytes(ba: Mutable): void; + } + + //// X509 TYPES + + type ExtInfo = { + critical: boolean; + oid: OID; + vidx: Idx; + }; + + type ExtAIAInfo = Record<'ocsp' | 'caissuer', string>; + + type ExtCertificatePolicy = { + id: OIDName; + } & Partial<{ + cps: string; + } | { + unotice: string; + }>; + + class X509 { + public hex: HexString | null; + + public version: number; + + public foffset: number; + + public aExtInfo: null; + + public getVersion(): number; + + public getSerialNumberHex(): ASN1V; + + public getSignatureAlgorithmField(): OIDName; + + public getIssuerHex(): ASN1TLV; + + public getIssuerString(): HexString; + + public getSubjectHex(): ASN1TLV; + + public getSubjectString(): HexString; + + public getNotBefore(): TimeValue; + + public getNotAfter(): TimeValue; + + public getPublicKeyHex(): ASN1TLV; + + public getPublicKeyIdx(): Idx>; + + public getPublicKeyContentIdx(): Idx>; + + public getPublicKey(): RSAKey | KJUR.crypto.ECDSA | KJUR.crypto.DSA; + + public getSignatureAlgorithmName(): OIDName; + + public getSignatureValueHex(): ASN1V; + + public verifySignature(pubKey: GetKeyParam): boolean | 0; + + public parseExt(): void; + + public getExtInfo(oidOrName: OID | string): ExtInfo | undefined; + + public getExtBasicConstraints(): ExtInfo | {} | { + cA: true; + pathLen?: number; + }; + + public getExtKeyUsageBin(): BinString; + + public getExtKeyUsageString(): string; + + public getExtSubjectKeyIdentifier(): ASN1V | undefined; + + public getExtAuthorityKeyIdentifier(): { + kid: ASN1V; + } | undefined; + + public getExtExtKeyUsageName(): OIDName[] | undefined; + + public getExtSubjectAltName(): Deprecated; + + public getExtSubjectAltName2(): ['MAIL' | 'DNS' | 'DN' | 'URI' | 'IP', string][] | undefined; + + public getExtCRLDistributionPointsURI(): string[] | undefined; + + public getExtAIAInfo(): ExtAIAInfo | undefined; + + public getExtCertificatePolicies(): ExtCertificatePolicy[] | undefined; + + public readCertPEM(sCertPEM: PEM): void; + + public readCertHex(sCertHex: HexString): void; + + public getInfo(): string; + + public static hex2dn(hex: HexString, idx?: Idx): string; + + public static hex2rdn(hex: HexString, idx?: Idx): string; + + public static hex2attrTypeValue(hex: HexString, idx?: Idx): string; + + public static getPublicKeyFromCertPEM(sCertPEM: PEM): RSAKey | KJUR.crypto.ECDSA | KJUR.crypto.DSA; + + public static getPublicKeyInfoPropOfCertPEM(sCertPEM: PEM): { + algparam: ASN1V | null; + leyhex: ASN1V; + algoid: ASN1V; + }; + } +} diff --git a/src/@types/koa-json-body.d.ts b/packages/backend/@types/koa-json-body.d.ts similarity index 100% rename from src/@types/koa-json-body.d.ts rename to packages/backend/@types/koa-json-body.d.ts diff --git a/src/@types/koa-slow.d.ts b/packages/backend/@types/koa-slow.d.ts similarity index 100% rename from src/@types/koa-slow.d.ts rename to packages/backend/@types/koa-slow.d.ts diff --git a/src/@types/langmap.d.ts b/packages/backend/@types/langmap.d.ts similarity index 100% rename from src/@types/langmap.d.ts rename to packages/backend/@types/langmap.d.ts diff --git a/src/@types/os-utils.d.ts b/packages/backend/@types/os-utils.d.ts similarity index 100% rename from src/@types/os-utils.d.ts rename to packages/backend/@types/os-utils.d.ts diff --git a/src/@types/package.json.d.ts b/packages/backend/@types/package.json.d.ts similarity index 100% rename from src/@types/package.json.d.ts rename to packages/backend/@types/package.json.d.ts diff --git a/src/@types/probe-image-size.d.ts b/packages/backend/@types/probe-image-size.d.ts similarity index 100% rename from src/@types/probe-image-size.d.ts rename to packages/backend/@types/probe-image-size.d.ts diff --git a/assets/api-doc.png b/packages/backend/assets/api-doc.png similarity index 100% rename from assets/api-doc.png rename to packages/backend/assets/api-doc.png diff --git a/assets/apple-touch-icon.png b/packages/backend/assets/apple-touch-icon.png similarity index 100% rename from assets/apple-touch-icon.png rename to packages/backend/assets/apple-touch-icon.png diff --git a/assets/favicon.ico b/packages/backend/assets/favicon.ico similarity index 100% rename from assets/favicon.ico rename to packages/backend/assets/favicon.ico diff --git a/assets/favicon.png b/packages/backend/assets/favicon.png similarity index 100% rename from assets/favicon.png rename to packages/backend/assets/favicon.png diff --git a/assets/icons/192.png b/packages/backend/assets/icons/192.png similarity index 100% rename from assets/icons/192.png rename to packages/backend/assets/icons/192.png diff --git a/assets/icons/512.png b/packages/backend/assets/icons/512.png similarity index 100% rename from assets/icons/512.png rename to packages/backend/assets/icons/512.png diff --git a/assets/mi-white.png b/packages/backend/assets/mi-white.png similarity index 100% rename from assets/mi-white.png rename to packages/backend/assets/mi-white.png diff --git a/assets/redoc.html b/packages/backend/assets/redoc.html similarity index 100% rename from assets/redoc.html rename to packages/backend/assets/redoc.html diff --git a/assets/robots.txt b/packages/backend/assets/robots.txt similarity index 100% rename from assets/robots.txt rename to packages/backend/assets/robots.txt diff --git a/assets/user-unknown.png b/packages/backend/assets/user-unknown.png similarity index 100% rename from assets/user-unknown.png rename to packages/backend/assets/user-unknown.png diff --git a/jsconfig.json b/packages/backend/jsconfig.json similarity index 100% rename from jsconfig.json rename to packages/backend/jsconfig.json diff --git a/packages/backend/migration/1000000000000-Init.js b/packages/backend/migration/1000000000000-Init.js new file mode 100644 index 000000000..19b216600 --- /dev/null +++ b/packages/backend/migration/1000000000000-Init.js @@ -0,0 +1,483 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class Init1000000000000 { + async up(queryRunner) { + await queryRunner.query(`CREATE TYPE "log_level_enum" AS ENUM('error', 'warning', 'info', 'success', 'debug')`); + await queryRunner.query(`CREATE TABLE "log" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "domain" character varying(64) array NOT NULL DEFAULT '{}'::varchar[], "level" "log_level_enum" NOT NULL, "worker" character varying(8) NOT NULL, "machine" character varying(128) NOT NULL, "message" character varying(1024) NOT NULL, "data" jsonb NOT NULL DEFAULT '{}', CONSTRAINT "PK_350604cbdf991d5930d9e618fbd" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE INDEX "IDX_8e4eb51a35d81b64dda28eed0a" ON "log" ("createdAt") `); + await queryRunner.query(`CREATE INDEX "IDX_8cb40cfc8f3c28261e6f887b03" ON "log" ("domain") `); + await queryRunner.query(`CREATE INDEX "IDX_584b536b49e53ac81beb39a177" ON "log" ("level") `); + await queryRunner.query(`CREATE TABLE "drive_folder" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "name" character varying(128) NOT NULL, "userId" character varying(32), "parentId" character varying(32), CONSTRAINT "PK_7a0c089191f5ebdc214e0af808a" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE INDEX "IDX_02878d441ceae15ce060b73daf" ON "drive_folder" ("createdAt") `); + await queryRunner.query(`CREATE INDEX "IDX_f4fc06e49c0171c85f1c48060d" ON "drive_folder" ("userId") `); + await queryRunner.query(`CREATE INDEX "IDX_00ceffb0cdc238b3233294f08f" ON "drive_folder" ("parentId") `); + await queryRunner.query(`CREATE TABLE "drive_file" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32), "userHost" character varying(128), "md5" character varying(32) NOT NULL, "name" character varying(256) NOT NULL, "type" character varying(128) NOT NULL, "size" integer NOT NULL, "comment" character varying(512), "properties" jsonb NOT NULL DEFAULT '{}', "storedInternal" boolean NOT NULL, "url" character varying(512) NOT NULL, "thumbnailUrl" character varying(512), "webpublicUrl" character varying(512), "accessKey" character varying(256), "thumbnailAccessKey" character varying(256), "webpublicAccessKey" character varying(256), "uri" character varying(512), "src" character varying(512), "folderId" character varying(32), "isSensitive" boolean NOT NULL DEFAULT false, "isLink" boolean NOT NULL DEFAULT false, CONSTRAINT "PK_43ddaaaf18c9e68029b7cbb032e" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE INDEX "IDX_c8dfad3b72196dd1d6b5db168a" ON "drive_file" ("createdAt") `); + await queryRunner.query(`CREATE INDEX "IDX_860fa6f6c7df5bb887249fba22" ON "drive_file" ("userId") `); + await queryRunner.query(`CREATE INDEX "IDX_92779627994ac79277f070c91e" ON "drive_file" ("userHost") `); + await queryRunner.query(`CREATE INDEX "IDX_37bb9a1b4585f8a3beb24c62d6" ON "drive_file" ("md5") `); + await queryRunner.query(`CREATE INDEX "IDX_a40b8df8c989d7db937ea27cf6" ON "drive_file" ("type") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_d85a184c2540d2deba33daf642" ON "drive_file" ("accessKey") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_e74022ce9a074b3866f70e0d27" ON "drive_file" ("thumbnailAccessKey") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_c55b2b7c284d9fef98026fc88e" ON "drive_file" ("webpublicAccessKey") `); + await queryRunner.query(`CREATE INDEX "IDX_e5848eac4940934e23dbc17581" ON "drive_file" ("uri") `); + await queryRunner.query(`CREATE INDEX "IDX_bb90d1956dafc4068c28aa7560" ON "drive_file" ("folderId") `); + await queryRunner.query(`CREATE TABLE "user" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "updatedAt" TIMESTAMP WITH TIME ZONE, "lastFetchedAt" TIMESTAMP WITH TIME ZONE, "username" character varying(128) NOT NULL, "usernameLower" character varying(128) NOT NULL, "name" character varying(128), "followersCount" integer NOT NULL DEFAULT 0, "followingCount" integer NOT NULL DEFAULT 0, "notesCount" integer NOT NULL DEFAULT 0, "avatarId" character varying(32), "bannerId" character varying(32), "tags" character varying(128) array NOT NULL DEFAULT '{}'::varchar[], "avatarUrl" character varying(512), "bannerUrl" character varying(512), "avatarColor" character varying(32), "bannerColor" character varying(32), "isSuspended" boolean NOT NULL DEFAULT false, "isSilenced" boolean NOT NULL DEFAULT false, "isLocked" boolean NOT NULL DEFAULT false, "isBot" boolean NOT NULL DEFAULT false, "isCat" boolean NOT NULL DEFAULT false, "isAdmin" boolean NOT NULL DEFAULT false, "isModerator" boolean NOT NULL DEFAULT false, "isVerified" boolean NOT NULL DEFAULT false, "emojis" character varying(128) array NOT NULL DEFAULT '{}'::varchar[], "host" character varying(128), "inbox" character varying(512), "sharedInbox" character varying(512), "featured" character varying(512), "uri" character varying(512), "token" character(16), CONSTRAINT "UQ_a854e557b1b14814750c7c7b0c9" UNIQUE ("token"), CONSTRAINT "REL_58f5c71eaab331645112cf8cfa" UNIQUE ("avatarId"), CONSTRAINT "REL_afc64b53f8db3707ceb34eb28e" UNIQUE ("bannerId"), CONSTRAINT "PK_cace4a159ff9f2512dd42373760" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE INDEX "IDX_e11e649824a45d8ed01d597fd9" ON "user" ("createdAt") `); + await queryRunner.query(`CREATE INDEX "IDX_80ca6e6ef65fb9ef34ea8c90f4" ON "user" ("updatedAt") `); + await queryRunner.query(`CREATE INDEX "IDX_a27b942a0d6dcff90e3ee9b5e8" ON "user" ("usernameLower") `); + await queryRunner.query(`CREATE INDEX "IDX_fa99d777623947a5b05f394cae" ON "user" ("tags") `); + await queryRunner.query(`CREATE INDEX "IDX_3252a5df8d5bbd16b281f7799e" ON "user" ("host") `); + await queryRunner.query(`CREATE INDEX "IDX_be623adaa4c566baf5d29ce0c8" ON "user" ("uri") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_a854e557b1b14814750c7c7b0c" ON "user" ("token") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_5deb01ae162d1d70b80d064c27" ON "user" ("usernameLower", "host") `); + await queryRunner.query(`CREATE TABLE "app" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32), "secret" character varying(64) NOT NULL, "name" character varying(128) NOT NULL, "description" character varying(512) NOT NULL, "permission" character varying(64) array NOT NULL, "callbackUrl" character varying(512), CONSTRAINT "PK_9478629fc093d229df09e560aea" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE INDEX "IDX_048a757923ed8b157e9895da53" ON "app" ("createdAt") `); + await queryRunner.query(`CREATE INDEX "IDX_3f5b0899ef90527a3462d7c2cb" ON "app" ("userId") `); + await queryRunner.query(`CREATE INDEX "IDX_f49922d511d666848f250663c4" ON "app" ("secret") `); + await queryRunner.query(`CREATE TABLE "access_token" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "token" character varying(128) NOT NULL, "hash" character varying(128) NOT NULL, "userId" character varying(32) NOT NULL, "appId" character varying(32) NOT NULL, CONSTRAINT "PK_f20f028607b2603deabd8182d12" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE INDEX "IDX_70ba8f6af34bc924fc9e12adb8" ON "access_token" ("token") `); + await queryRunner.query(`CREATE INDEX "IDX_64c327441248bae40f7d92f34f" ON "access_token" ("hash") `); + await queryRunner.query(`CREATE INDEX "IDX_9949557d0e1b2c19e5344c171e" ON "access_token" ("userId") `); + await queryRunner.query(`CREATE TYPE "note_visibility_enum" AS ENUM('public', 'home', 'followers', 'specified')`); + await queryRunner.query(`CREATE TABLE "note" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "replyId" character varying(32), "renoteId" character varying(32), "text" text, "name" character varying(256), "cw" character varying(512), "appId" character varying(32), "userId" character varying(32) NOT NULL, "viaMobile" boolean NOT NULL DEFAULT false, "localOnly" boolean NOT NULL DEFAULT false, "renoteCount" smallint NOT NULL DEFAULT 0, "repliesCount" smallint NOT NULL DEFAULT 0, "reactions" jsonb NOT NULL DEFAULT '{}', "visibility" "note_visibility_enum" NOT NULL, "uri" character varying(512), "score" integer NOT NULL DEFAULT 0, "fileIds" character varying(32) array NOT NULL DEFAULT '{}'::varchar[], "attachedFileTypes" character varying(256) array NOT NULL DEFAULT '{}'::varchar[], "visibleUserIds" character varying(32) array NOT NULL DEFAULT '{}'::varchar[], "mentions" character varying(32) array NOT NULL DEFAULT '{}'::varchar[], "mentionedRemoteUsers" text NOT NULL DEFAULT '[]', "emojis" character varying(128) array NOT NULL DEFAULT '{}'::varchar[], "tags" character varying(128) array NOT NULL DEFAULT '{}'::varchar[], "hasPoll" boolean NOT NULL DEFAULT false, "geo" jsonb DEFAULT null, "userHost" character varying(128), "replyUserId" character varying(32), "replyUserHost" character varying(128), "renoteUserId" character varying(32), "renoteUserHost" character varying(128), CONSTRAINT "PK_96d0c172a4fba276b1bbed43058" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE INDEX "IDX_e7c0567f5261063592f022e9b5" ON "note" ("createdAt") `); + await queryRunner.query(`CREATE INDEX "IDX_17cb3553c700a4985dff5a30ff" ON "note" ("replyId") `); + await queryRunner.query(`CREATE INDEX "IDX_52ccc804d7c69037d558bac4c9" ON "note" ("renoteId") `); + await queryRunner.query(`CREATE INDEX "IDX_5b87d9d19127bd5d92026017a7" ON "note" ("userId") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_153536c67d05e9adb24e99fc2b" ON "note" ("uri") `); + await queryRunner.query(`CREATE INDEX "IDX_51c063b6a133a9cb87145450f5" ON "note" ("fileIds") `); + await queryRunner.query(`CREATE INDEX "IDX_25dfc71b0369b003a4cd434d0b" ON "note" ("attachedFileTypes") `); + await queryRunner.query(`CREATE INDEX "IDX_796a8c03959361f97dc2be1d5c" ON "note" ("visibleUserIds") `); + await queryRunner.query(`CREATE INDEX "IDX_54ebcb6d27222913b908d56fd8" ON "note" ("mentions") `); + await queryRunner.query(`CREATE INDEX "IDX_88937d94d7443d9a99a76fa5c0" ON "note" ("tags") `); + await queryRunner.query(`CREATE INDEX "IDX_7125a826ab192eb27e11d358a5" ON "note" ("userHost") `); + await queryRunner.query(`CREATE TABLE "poll_vote" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "noteId" character varying(32) NOT NULL, "choice" integer NOT NULL, CONSTRAINT "PK_fd002d371201c472490ba89c6a0" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE INDEX "IDX_0fb627e1c2f753262a74f0562d" ON "poll_vote" ("createdAt") `); + await queryRunner.query(`CREATE INDEX "IDX_66d2bd2ee31d14bcc23069a89f" ON "poll_vote" ("userId") `); + await queryRunner.query(`CREATE INDEX "IDX_aecfbd5ef60374918e63ee95fa" ON "poll_vote" ("noteId") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_50bd7164c5b78f1f4a42c4d21f" ON "poll_vote" ("userId", "noteId", "choice") `); + await queryRunner.query(`CREATE TABLE "note_reaction" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "noteId" character varying(32) NOT NULL, "reaction" character varying(128) NOT NULL, CONSTRAINT "PK_767ec729b108799b587a3fcc9cf" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE INDEX "IDX_01f4581f114e0ebd2bbb876f0b" ON "note_reaction" ("createdAt") `); + await queryRunner.query(`CREATE INDEX "IDX_13761f64257f40c5636d0ff95e" ON "note_reaction" ("userId") `); + await queryRunner.query(`CREATE INDEX "IDX_45145e4953780f3cd5656f0ea6" ON "note_reaction" ("noteId") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_ad0c221b25672daf2df320a817" ON "note_reaction" ("userId", "noteId") `); + await queryRunner.query(`CREATE TABLE "note_watching" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "noteId" character varying(32) NOT NULL, "noteUserId" character varying(32) NOT NULL, CONSTRAINT "PK_49286fdb23725945a74aa27d757" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE INDEX "IDX_318cdf42a9cfc11f479bd802bb" ON "note_watching" ("createdAt") `); + await queryRunner.query(`CREATE INDEX "IDX_b0134ec406e8d09a540f818288" ON "note_watching" ("userId") `); + await queryRunner.query(`CREATE INDEX "IDX_03e7028ab8388a3f5e3ce2a861" ON "note_watching" ("noteId") `); + await queryRunner.query(`CREATE INDEX "IDX_44499765eec6b5489d72c4253b" ON "note_watching" ("noteUserId") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_a42c93c69989ce1d09959df4cf" ON "note_watching" ("userId", "noteId") `); + await queryRunner.query(`CREATE TABLE "note_unread" ("id" character varying(32) NOT NULL, "userId" character varying(32) NOT NULL, "noteId" character varying(32) NOT NULL, "noteUserId" character varying(32) NOT NULL, "isSpecified" boolean NOT NULL, CONSTRAINT "PK_1904eda61a784f57e6e51fa9c1f" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE INDEX "IDX_56b0166d34ddae49d8ef7610bb" ON "note_unread" ("userId") `); + await queryRunner.query(`CREATE INDEX "IDX_e637cba4dc4410218c4251260e" ON "note_unread" ("noteId") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_d908433a4953cc13216cd9c274" ON "note_unread" ("userId", "noteId") `); + await queryRunner.query(`CREATE TABLE "notification" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "notifieeId" character varying(32) NOT NULL, "notifierId" character varying(32) NOT NULL, "type" character varying(32) NOT NULL, "isRead" boolean NOT NULL DEFAULT false, "noteId" character varying(32), "reaction" character varying(128), "choice" integer, CONSTRAINT "PK_705b6c7cdf9b2c2ff7ac7872cb7" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE INDEX "IDX_b11a5e627c41d4dc3170f1d370" ON "notification" ("createdAt") `); + await queryRunner.query(`CREATE INDEX "IDX_3c601b70a1066d2c8b517094cb" ON "notification" ("notifieeId") `); + await queryRunner.query(`CREATE TABLE "meta" ("id" character varying(32) NOT NULL, "name" character varying(128), "description" character varying(1024), "maintainerName" character varying(128), "maintainerEmail" character varying(128), "announcements" jsonb NOT NULL DEFAULT '[]', "disableRegistration" boolean NOT NULL DEFAULT false, "disableLocalTimeline" boolean NOT NULL DEFAULT false, "disableGlobalTimeline" boolean NOT NULL DEFAULT false, "enableEmojiReaction" boolean NOT NULL DEFAULT true, "useStarForReactionFallback" boolean NOT NULL DEFAULT false, "langs" character varying(64) array NOT NULL DEFAULT '{}'::varchar[], "hiddenTags" character varying(256) array NOT NULL DEFAULT '{}'::varchar[], "blockedHosts" character varying(256) array NOT NULL DEFAULT '{}'::varchar[], "mascotImageUrl" character varying(512) DEFAULT '/assets/ai.png', "bannerUrl" character varying(512), "errorImageUrl" character varying(512) DEFAULT 'https://xn--931a.moe/aiart/yubitun.png', "iconUrl" character varying(512), "cacheRemoteFiles" boolean NOT NULL DEFAULT true, "proxyAccount" character varying(128), "enableRecaptcha" boolean NOT NULL DEFAULT false, "recaptchaSiteKey" character varying(64), "recaptchaSecretKey" character varying(64), "localDriveCapacityMb" integer NOT NULL DEFAULT 1024, "remoteDriveCapacityMb" integer NOT NULL DEFAULT 32, "maxNoteTextLength" integer NOT NULL DEFAULT 500, "summalyProxy" character varying(128), "enableEmail" boolean NOT NULL DEFAULT false, "email" character varying(128), "smtpSecure" boolean NOT NULL DEFAULT false, "smtpHost" character varying(128), "smtpPort" integer, "smtpUser" character varying(128), "smtpPass" character varying(128), "enableServiceWorker" boolean NOT NULL DEFAULT false, "swPublicKey" character varying(128), "swPrivateKey" character varying(128), "enableTwitterIntegration" boolean NOT NULL DEFAULT false, "twitterConsumerKey" character varying(128), "twitterConsumerSecret" character varying(128), "enableGithubIntegration" boolean NOT NULL DEFAULT false, "githubClientId" character varying(128), "githubClientSecret" character varying(128), "enableDiscordIntegration" boolean NOT NULL DEFAULT false, "discordClientId" character varying(128), "discordClientSecret" character varying(128), CONSTRAINT "PK_c4c17a6c2bd7651338b60fc590b" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE TABLE "following" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "followeeId" character varying(32) NOT NULL, "followerId" character varying(32) NOT NULL, "followerHost" character varying(128), "followerInbox" character varying(512), "followerSharedInbox" character varying(512), "followeeHost" character varying(128), "followeeInbox" character varying(512), "followeeSharedInbox" character varying(512), CONSTRAINT "PK_c76c6e044bdf76ecf8bfb82a645" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE INDEX "IDX_582f8fab771a9040a12961f3e7" ON "following" ("createdAt") `); + await queryRunner.query(`CREATE INDEX "IDX_24e0042143a18157b234df186c" ON "following" ("followeeId") `); + await queryRunner.query(`CREATE INDEX "IDX_6516c5a6f3c015b4eed39978be" ON "following" ("followerId") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_307be5f1d1252e0388662acb96" ON "following" ("followerId", "followeeId") `); + await queryRunner.query(`CREATE TABLE "instance" ("id" character varying(32) NOT NULL, "caughtAt" TIMESTAMP WITH TIME ZONE NOT NULL, "host" character varying(128) NOT NULL, "system" character varying(64), "usersCount" integer NOT NULL DEFAULT 0, "notesCount" integer NOT NULL DEFAULT 0, "followingCount" integer NOT NULL DEFAULT 0, "followersCount" integer NOT NULL DEFAULT 0, "driveUsage" integer NOT NULL DEFAULT 0, "driveFiles" integer NOT NULL DEFAULT 0, "latestRequestSentAt" TIMESTAMP WITH TIME ZONE, "latestStatus" integer, "latestRequestReceivedAt" TIMESTAMP WITH TIME ZONE, "lastCommunicatedAt" TIMESTAMP WITH TIME ZONE NOT NULL, "isNotResponding" boolean NOT NULL DEFAULT false, "isMarkedAsClosed" boolean NOT NULL DEFAULT false, CONSTRAINT "PK_eaf60e4a0c399c9935413e06474" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE INDEX "IDX_2cd3b2a6b4cf0b910b260afe08" ON "instance" ("caughtAt") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_8d5afc98982185799b160e10eb" ON "instance" ("host") `); + await queryRunner.query(`CREATE TABLE "muting" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "muteeId" character varying(32) NOT NULL, "muterId" character varying(32) NOT NULL, CONSTRAINT "PK_2e92d06c8b5c602eeb27ca9ba48" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE INDEX "IDX_f86d57fbca33c7a4e6897490cc" ON "muting" ("createdAt") `); + await queryRunner.query(`CREATE INDEX "IDX_ec96b4fed9dae517e0dbbe0675" ON "muting" ("muteeId") `); + await queryRunner.query(`CREATE INDEX "IDX_93060675b4a79a577f31d260c6" ON "muting" ("muterId") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_1eb9d9824a630321a29fd3b290" ON "muting" ("muterId", "muteeId") `); + await queryRunner.query(`CREATE TABLE "sw_subscription" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "endpoint" character varying(512) NOT NULL, "auth" character varying(256) NOT NULL, "publickey" character varying(128) NOT NULL, CONSTRAINT "PK_e8f763631530051b95eb6279b91" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE INDEX "IDX_97754ca6f2baff9b4abb7f853d" ON "sw_subscription" ("userId") `); + await queryRunner.query(`CREATE TABLE "blocking" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "blockeeId" character varying(32) NOT NULL, "blockerId" character varying(32) NOT NULL, CONSTRAINT "PK_e5d9a541cc1965ee7e048ea09dd" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE INDEX "IDX_b9a354f7941c1e779f3b33aea6" ON "blocking" ("createdAt") `); + await queryRunner.query(`CREATE INDEX "IDX_2cd4a2743a99671308f5417759" ON "blocking" ("blockeeId") `); + await queryRunner.query(`CREATE INDEX "IDX_0627125f1a8a42c9a1929edb55" ON "blocking" ("blockerId") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_98a1bc5cb30dfd159de056549f" ON "blocking" ("blockerId", "blockeeId") `); + await queryRunner.query(`CREATE TABLE "user_list" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "name" character varying(128) NOT NULL, CONSTRAINT "PK_87bab75775fd9b1ff822b656402" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE INDEX "IDX_b7fcefbdd1c18dce86687531f9" ON "user_list" ("userId") `); + await queryRunner.query(`CREATE TABLE "user_list_joining" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "userListId" character varying(32) NOT NULL, CONSTRAINT "PK_11abb3768da1c5f8de101c9df45" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE INDEX "IDX_d844bfc6f3f523a05189076efa" ON "user_list_joining" ("userId") `); + await queryRunner.query(`CREATE INDEX "IDX_605472305f26818cc93d1baaa7" ON "user_list_joining" ("userListId") `); + await queryRunner.query(`CREATE TABLE "hashtag" ("id" character varying(32) NOT NULL, "name" character varying(128) NOT NULL, "mentionedUserIds" character varying(32) array NOT NULL, "mentionedUsersCount" integer NOT NULL DEFAULT 0, "mentionedLocalUserIds" character varying(32) array NOT NULL, "mentionedLocalUsersCount" integer NOT NULL DEFAULT 0, "mentionedRemoteUserIds" character varying(32) array NOT NULL, "mentionedRemoteUsersCount" integer NOT NULL DEFAULT 0, "attachedUserIds" character varying(32) array NOT NULL, "attachedUsersCount" integer NOT NULL DEFAULT 0, "attachedLocalUserIds" character varying(32) array NOT NULL, "attachedLocalUsersCount" integer NOT NULL DEFAULT 0, "attachedRemoteUserIds" character varying(32) array NOT NULL, "attachedRemoteUsersCount" integer NOT NULL DEFAULT 0, CONSTRAINT "PK_cb36eb8af8412bfa978f1165d78" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_347fec870eafea7b26c8a73bac" ON "hashtag" ("name") `); + await queryRunner.query(`CREATE INDEX "IDX_2710a55f826ee236ea1a62698f" ON "hashtag" ("mentionedUsersCount") `); + await queryRunner.query(`CREATE INDEX "IDX_0e206cec573f1edff4a3062923" ON "hashtag" ("mentionedLocalUsersCount") `); + await queryRunner.query(`CREATE INDEX "IDX_4c02d38a976c3ae132228c6fce" ON "hashtag" ("mentionedRemoteUsersCount") `); + await queryRunner.query(`CREATE INDEX "IDX_d57f9030cd3af7f63ffb1c267c" ON "hashtag" ("attachedUsersCount") `); + await queryRunner.query(`CREATE INDEX "IDX_0c44bf4f680964145f2a68a341" ON "hashtag" ("attachedLocalUsersCount") `); + await queryRunner.query(`CREATE INDEX "IDX_0b03cbcd7e6a7ce068efa8ecc2" ON "hashtag" ("attachedRemoteUsersCount") `); + await queryRunner.query(`CREATE TABLE "note_favorite" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "noteId" character varying(32) NOT NULL, CONSTRAINT "PK_af0da35a60b9fa4463a62082b36" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE INDEX "IDX_47f4b1892f5d6ba8efb3057d81" ON "note_favorite" ("userId") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_0f4fb9ad355f3effff221ef245" ON "note_favorite" ("userId", "noteId") `); + await queryRunner.query(`CREATE TABLE "abuse_user_report" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "reporterId" character varying(32) NOT NULL, "comment" character varying(512) NOT NULL, CONSTRAINT "PK_87873f5f5cc5c321a1306b2d18c" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE INDEX "IDX_db2098070b2b5a523c58181f74" ON "abuse_user_report" ("createdAt") `); + await queryRunner.query(`CREATE INDEX "IDX_d049123c413e68ca52abe73420" ON "abuse_user_report" ("userId") `); + await queryRunner.query(`CREATE INDEX "IDX_04cc96756f89d0b7f9473e8cdf" ON "abuse_user_report" ("reporterId") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_5cd442c3b2e74fdd99dae20243" ON "abuse_user_report" ("userId", "reporterId") `); + await queryRunner.query(`CREATE TABLE "registration_ticket" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "code" character varying(64) NOT NULL, CONSTRAINT "PK_f11696b6fafcf3662d4292734f8" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_0ff69e8dfa9fe31bb4a4660f59" ON "registration_ticket" ("code") `); + await queryRunner.query(`CREATE TABLE "messaging_message" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "recipientId" character varying(32) NOT NULL, "text" character varying(4096), "isRead" boolean NOT NULL DEFAULT false, "fileId" character varying(32), CONSTRAINT "PK_db398fd79dc95d0eb8c30456eaa" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE INDEX "IDX_e21cd3646e52ef9c94aaf17c2e" ON "messaging_message" ("createdAt") `); + await queryRunner.query(`CREATE INDEX "IDX_5377c307783fce2b6d352e1203" ON "messaging_message" ("userId") `); + await queryRunner.query(`CREATE INDEX "IDX_cac14a4e3944454a5ce7daa514" ON "messaging_message" ("recipientId") `); + await queryRunner.query(`CREATE TABLE "signin" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "ip" character varying(128) NOT NULL, "headers" jsonb NOT NULL, "success" boolean NOT NULL, CONSTRAINT "PK_9e96ddc025712616fc492b3b588" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE INDEX "IDX_2c308dbdc50d94dc625670055f" ON "signin" ("userId") `); + await queryRunner.query(`CREATE TABLE "auth_session" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "token" character varying(128) NOT NULL, "userId" character varying(32), "appId" character varying(32) NOT NULL, CONSTRAINT "PK_19354ed146424a728c1112a8cbf" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE INDEX "IDX_62cb09e1129f6ec024ef66e183" ON "auth_session" ("token") `); + await queryRunner.query(`CREATE TABLE "follow_request" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "followeeId" character varying(32) NOT NULL, "followerId" character varying(32) NOT NULL, "requestId" character varying(128), "followerHost" character varying(128), "followerInbox" character varying(512), "followerSharedInbox" character varying(512), "followeeHost" character varying(128), "followeeInbox" character varying(512), "followeeSharedInbox" character varying(512), CONSTRAINT "PK_53a9aa3725f7a3deb150b39dbfc" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE INDEX "IDX_12c01c0d1a79f77d9f6c15fadd" ON "follow_request" ("followeeId") `); + await queryRunner.query(`CREATE INDEX "IDX_a7fd92dd6dc519e6fb435dd108" ON "follow_request" ("followerId") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_d54a512b822fac7ed52800f6b4" ON "follow_request" ("followerId", "followeeId") `); + await queryRunner.query(`CREATE TABLE "emoji" ("id" character varying(32) NOT NULL, "updatedAt" TIMESTAMP WITH TIME ZONE, "name" character varying(128) NOT NULL, "host" character varying(128), "url" character varying(512) NOT NULL, "uri" character varying(512), "type" character varying(64), "aliases" character varying(128) array NOT NULL DEFAULT '{}'::varchar[], CONSTRAINT "PK_df74ce05e24999ee01ea0bc50a3" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE INDEX "IDX_b37dafc86e9af007e3295c2781" ON "emoji" ("name") `); + await queryRunner.query(`CREATE INDEX "IDX_5900e907bb46516ddf2871327c" ON "emoji" ("host") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_4f4d35e1256c84ae3d1f0eab10" ON "emoji" ("name", "host") `); + await queryRunner.query(`CREATE TABLE "reversi_game" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "startedAt" TIMESTAMP WITH TIME ZONE, "user1Id" character varying(32) NOT NULL, "user2Id" character varying(32) NOT NULL, "user1Accepted" boolean NOT NULL DEFAULT false, "user2Accepted" boolean NOT NULL DEFAULT false, "black" integer, "isStarted" boolean NOT NULL DEFAULT false, "isEnded" boolean NOT NULL DEFAULT false, "winnerId" character varying(32), "surrendered" character varying(32), "logs" jsonb NOT NULL DEFAULT '[]', "map" character varying(64) array NOT NULL, "bw" character varying(32) NOT NULL, "isLlotheo" boolean NOT NULL DEFAULT false, "canPutEverywhere" boolean NOT NULL DEFAULT false, "loopedBoard" boolean NOT NULL DEFAULT false, "form1" jsonb DEFAULT null, "form2" jsonb DEFAULT null, "crc32" character varying(32), CONSTRAINT "PK_76b30eeba71b1193ad7c5311c3f" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE INDEX "IDX_b46ec40746efceac604142be1c" ON "reversi_game" ("createdAt") `); + await queryRunner.query(`CREATE TABLE "reversi_matching" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "parentId" character varying(32) NOT NULL, "childId" character varying(32) NOT NULL, CONSTRAINT "PK_880bd0afbab232f21c8b9d146cf" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE INDEX "IDX_b604d92d6c7aec38627f6eaf16" ON "reversi_matching" ("createdAt") `); + await queryRunner.query(`CREATE INDEX "IDX_3b25402709dd9882048c2bbade" ON "reversi_matching" ("parentId") `); + await queryRunner.query(`CREATE INDEX "IDX_e247b23a3c9b45f89ec1299d06" ON "reversi_matching" ("childId") `); + await queryRunner.query(`CREATE TABLE "user_note_pining" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "noteId" character varying(32) NOT NULL, CONSTRAINT "PK_a6a2dad4ae000abce2ea9d9b103" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE INDEX "IDX_bfbc6f79ba4007b4ce5097f08d" ON "user_note_pining" ("userId") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_410cd649884b501c02d6e72738" ON "user_note_pining" ("userId", "noteId") `); + await queryRunner.query(`CREATE TYPE "poll_notevisibility_enum" AS ENUM('public', 'home', 'followers', 'specified')`); + await queryRunner.query(`CREATE TABLE "poll" ("noteId" character varying(32) NOT NULL, "expiresAt" TIMESTAMP WITH TIME ZONE, "multiple" boolean NOT NULL, "choices" character varying(128) array NOT NULL DEFAULT '{}'::varchar[], "votes" integer array NOT NULL, "noteVisibility" "poll_notevisibility_enum" NOT NULL, "userId" character varying(32) NOT NULL, "userHost" character varying(128), CONSTRAINT "REL_da851e06d0dfe2ef397d8b1bf1" UNIQUE ("noteId"), CONSTRAINT "PK_da851e06d0dfe2ef397d8b1bf1b" PRIMARY KEY ("noteId"))`); + await queryRunner.query(`CREATE INDEX "IDX_0610ebcfcfb4a18441a9bcdab2" ON "poll" ("userId") `); + await queryRunner.query(`CREATE INDEX "IDX_7fa20a12319c7f6dc3aed98c0a" ON "poll" ("userHost") `); + await queryRunner.query(`CREATE TABLE "user_keypair" ("userId" character varying(32) NOT NULL, "publicKey" character varying(4096) NOT NULL, "privateKey" character varying(4096) NOT NULL, CONSTRAINT "REL_f4853eb41ab722fe05f81cedeb" UNIQUE ("userId"), CONSTRAINT "PK_f4853eb41ab722fe05f81cedeb6" PRIMARY KEY ("userId"))`); + await queryRunner.query(`CREATE TABLE "user_publickey" ("userId" character varying(32) NOT NULL, "keyId" character varying(256) NOT NULL, "keyPem" character varying(4096) NOT NULL, CONSTRAINT "REL_10c146e4b39b443ede016f6736" UNIQUE ("userId"), CONSTRAINT "PK_10c146e4b39b443ede016f6736d" PRIMARY KEY ("userId"))`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_171e64971c780ebd23fae140bb" ON "user_publickey" ("keyId") `); + await queryRunner.query(`CREATE TABLE "user_profile" ("userId" character varying(32) NOT NULL, "location" character varying(128), "birthday" character(10), "description" character varying(1024), "fields" jsonb NOT NULL DEFAULT '[]', "url" character varying(512), "email" character varying(128), "emailVerifyCode" character varying(128), "emailVerified" boolean NOT NULL DEFAULT false, "twoFactorTempSecret" character varying(128), "twoFactorSecret" character varying(128), "twoFactorEnabled" boolean NOT NULL DEFAULT false, "password" character varying(128), "clientData" jsonb NOT NULL DEFAULT '{}', "autoWatch" boolean NOT NULL DEFAULT false, "autoAcceptFollowed" boolean NOT NULL DEFAULT false, "alwaysMarkNsfw" boolean NOT NULL DEFAULT false, "carefulBot" boolean NOT NULL DEFAULT false, "twitter" boolean NOT NULL DEFAULT false, "twitterAccessToken" character varying(64) DEFAULT null, "twitterAccessTokenSecret" character varying(64) DEFAULT null, "twitterUserId" character varying(64) DEFAULT null, "twitterScreenName" character varying(64) DEFAULT null, "github" boolean NOT NULL DEFAULT false, "githubAccessToken" character varying(64) DEFAULT null, "githubId" integer DEFAULT null, "githubLogin" character varying(64) DEFAULT null, "discord" boolean NOT NULL DEFAULT false, "discordAccessToken" character varying(64) DEFAULT null, "discordRefreshToken" character varying(64) DEFAULT null, "discordExpiresDate" integer DEFAULT null, "discordId" character varying(64) DEFAULT null, "discordUsername" character varying(64) DEFAULT null, "discordDiscriminator" character varying(64) DEFAULT null, "userHost" character varying(128), CONSTRAINT "REL_51cb79b5555effaf7d69ba1cff" UNIQUE ("userId"), CONSTRAINT "PK_51cb79b5555effaf7d69ba1cff9" PRIMARY KEY ("userId"))`); + await queryRunner.query(`CREATE INDEX "IDX_dce530b98e454793dac5ec2f5a" ON "user_profile" ("userHost") `); + await queryRunner.query(`CREATE TYPE "__chart__active_users_span_enum" AS ENUM('hour', 'day')`); + await queryRunner.query(`CREATE TABLE "__chart__active_users" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128), "span" "__chart__active_users_span_enum" NOT NULL, "unique" jsonb NOT NULL DEFAULT '{}', "___local_count" bigint NOT NULL, "___remote_count" bigint NOT NULL, CONSTRAINT "PK_317237a9f733b970604a11e314f" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE TYPE "__chart__drive_span_enum" AS ENUM('hour', 'day')`); + await queryRunner.query(`CREATE TABLE "__chart__drive" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128), "span" "__chart__drive_span_enum" NOT NULL, "unique" jsonb NOT NULL DEFAULT '{}', "___local_totalCount" bigint NOT NULL, "___local_totalSize" bigint NOT NULL, "___local_incCount" bigint NOT NULL, "___local_incSize" bigint NOT NULL, "___local_decCount" bigint NOT NULL, "___local_decSize" bigint NOT NULL, "___remote_totalCount" bigint NOT NULL, "___remote_totalSize" bigint NOT NULL, "___remote_incCount" bigint NOT NULL, "___remote_incSize" bigint NOT NULL, "___remote_decCount" bigint NOT NULL, "___remote_decSize" bigint NOT NULL, CONSTRAINT "PK_f96bc548a765cd4b3b354221ce7" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE TYPE "__chart__federation_span_enum" AS ENUM('hour', 'day')`); + await queryRunner.query(`CREATE TABLE "__chart__federation" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128), "span" "__chart__federation_span_enum" NOT NULL, "unique" jsonb NOT NULL DEFAULT '{}', "___instance_total" bigint NOT NULL, "___instance_inc" bigint NOT NULL, "___instance_dec" bigint NOT NULL, CONSTRAINT "PK_b39dcd31a0fe1a7757e348e85fd" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE TYPE "__chart__hashtag_span_enum" AS ENUM('hour', 'day')`); + await queryRunner.query(`CREATE TABLE "__chart__hashtag" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128), "span" "__chart__hashtag_span_enum" NOT NULL, "unique" jsonb NOT NULL DEFAULT '{}', "___local_count" bigint NOT NULL, "___remote_count" bigint NOT NULL, CONSTRAINT "PK_c32f1ea2b44a5d2f7881e37f8f9" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE TYPE "__chart__instance_span_enum" AS ENUM('hour', 'day')`); + await queryRunner.query(`CREATE TABLE "__chart__instance" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128), "span" "__chart__instance_span_enum" NOT NULL, "unique" jsonb NOT NULL DEFAULT '{}', "___requests_failed" bigint NOT NULL, "___requests_succeeded" bigint NOT NULL, "___requests_received" bigint NOT NULL, "___notes_total" bigint NOT NULL, "___notes_inc" bigint NOT NULL, "___notes_dec" bigint NOT NULL, "___notes_diffs_normal" bigint NOT NULL, "___notes_diffs_reply" bigint NOT NULL, "___notes_diffs_renote" bigint NOT NULL, "___users_total" bigint NOT NULL, "___users_inc" bigint NOT NULL, "___users_dec" bigint NOT NULL, "___following_total" bigint NOT NULL, "___following_inc" bigint NOT NULL, "___following_dec" bigint NOT NULL, "___followers_total" bigint NOT NULL, "___followers_inc" bigint NOT NULL, "___followers_dec" bigint NOT NULL, "___drive_totalFiles" bigint NOT NULL, "___drive_totalUsage" bigint NOT NULL, "___drive_incFiles" bigint NOT NULL, "___drive_incUsage" bigint NOT NULL, "___drive_decFiles" bigint NOT NULL, "___drive_decUsage" bigint NOT NULL, CONSTRAINT "PK_1267c67c7c2d47b4903975f2c00" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE TYPE "__chart__network_span_enum" AS ENUM('hour', 'day')`); + await queryRunner.query(`CREATE TABLE "__chart__network" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128), "span" "__chart__network_span_enum" NOT NULL, "unique" jsonb NOT NULL DEFAULT '{}', "___incomingRequests" bigint NOT NULL, "___outgoingRequests" bigint NOT NULL, "___totalTime" bigint NOT NULL, "___incomingBytes" bigint NOT NULL, "___outgoingBytes" bigint NOT NULL, CONSTRAINT "PK_bc4290c2e27fad14ef0c1ca93f3" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE TYPE "__chart__notes_span_enum" AS ENUM('hour', 'day')`); + await queryRunner.query(`CREATE TABLE "__chart__notes" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128), "span" "__chart__notes_span_enum" NOT NULL, "unique" jsonb NOT NULL DEFAULT '{}', "___local_total" bigint NOT NULL, "___local_inc" bigint NOT NULL, "___local_dec" bigint NOT NULL, "___local_diffs_normal" bigint NOT NULL, "___local_diffs_reply" bigint NOT NULL, "___local_diffs_renote" bigint NOT NULL, "___remote_total" bigint NOT NULL, "___remote_inc" bigint NOT NULL, "___remote_dec" bigint NOT NULL, "___remote_diffs_normal" bigint NOT NULL, "___remote_diffs_reply" bigint NOT NULL, "___remote_diffs_renote" bigint NOT NULL, CONSTRAINT "PK_0aec823fa85c7f901bdb3863b14" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE TYPE "__chart__per_user_drive_span_enum" AS ENUM('hour', 'day')`); + await queryRunner.query(`CREATE TABLE "__chart__per_user_drive" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128), "span" "__chart__per_user_drive_span_enum" NOT NULL, "unique" jsonb NOT NULL DEFAULT '{}', "___totalCount" bigint NOT NULL, "___totalSize" bigint NOT NULL, "___incCount" bigint NOT NULL, "___incSize" bigint NOT NULL, "___decCount" bigint NOT NULL, "___decSize" bigint NOT NULL, CONSTRAINT "PK_d0ef23d24d666e1a44a0cd3d208" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE TYPE "__chart__per_user_following_span_enum" AS ENUM('hour', 'day')`); + await queryRunner.query(`CREATE TABLE "__chart__per_user_following" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128), "span" "__chart__per_user_following_span_enum" NOT NULL, "unique" jsonb NOT NULL DEFAULT '{}', "___local_followings_total" bigint NOT NULL, "___local_followings_inc" bigint NOT NULL, "___local_followings_dec" bigint NOT NULL, "___local_followers_total" bigint NOT NULL, "___local_followers_inc" bigint NOT NULL, "___local_followers_dec" bigint NOT NULL, "___remote_followings_total" bigint NOT NULL, "___remote_followings_inc" bigint NOT NULL, "___remote_followings_dec" bigint NOT NULL, "___remote_followers_total" bigint NOT NULL, "___remote_followers_inc" bigint NOT NULL, "___remote_followers_dec" bigint NOT NULL, CONSTRAINT "PK_85bb1b540363a29c2fec83bd907" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE TYPE "__chart__per_user_notes_span_enum" AS ENUM('hour', 'day')`); + await queryRunner.query(`CREATE TABLE "__chart__per_user_notes" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128), "span" "__chart__per_user_notes_span_enum" NOT NULL, "unique" jsonb NOT NULL DEFAULT '{}', "___total" bigint NOT NULL, "___inc" bigint NOT NULL, "___dec" bigint NOT NULL, "___diffs_normal" bigint NOT NULL, "___diffs_reply" bigint NOT NULL, "___diffs_renote" bigint NOT NULL, CONSTRAINT "PK_334acf6e915af2f29edc11b8e50" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE TYPE "__chart__per_user_reaction_span_enum" AS ENUM('hour', 'day')`); + await queryRunner.query(`CREATE TABLE "__chart__per_user_reaction" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128), "span" "__chart__per_user_reaction_span_enum" NOT NULL, "unique" jsonb NOT NULL DEFAULT '{}', "___local_count" bigint NOT NULL, "___remote_count" bigint NOT NULL, CONSTRAINT "PK_984f54dae441e65b633e8d27a7f" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE TYPE "__chart__test_grouped_span_enum" AS ENUM('hour', 'day')`); + await queryRunner.query(`CREATE TABLE "__chart__test_grouped" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128), "span" "__chart__test_grouped_span_enum" NOT NULL, "unique" jsonb NOT NULL DEFAULT '{}', "___foo_total" bigint NOT NULL, "___foo_inc" bigint NOT NULL, "___foo_dec" bigint NOT NULL, CONSTRAINT "PK_f4a2b175d308695af30d4293272" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE TYPE "__chart__test_unique_span_enum" AS ENUM('hour', 'day')`); + await queryRunner.query(`CREATE TABLE "__chart__test_unique" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128), "span" "__chart__test_unique_span_enum" NOT NULL, "unique" jsonb NOT NULL DEFAULT '{}', "___foo" bigint NOT NULL, CONSTRAINT "PK_409bac9c97cc612d8500012319d" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE TYPE "__chart__test_span_enum" AS ENUM('hour', 'day')`); + await queryRunner.query(`CREATE TABLE "__chart__test" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128), "span" "__chart__test_span_enum" NOT NULL, "unique" jsonb NOT NULL DEFAULT '{}', "___foo_total" bigint NOT NULL, "___foo_inc" bigint NOT NULL, "___foo_dec" bigint NOT NULL, CONSTRAINT "PK_b4bc31dffbd1b785276a3ecfc1e" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE TYPE "__chart__users_span_enum" AS ENUM('hour', 'day')`); + await queryRunner.query(`CREATE TABLE "__chart__users" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128), "span" "__chart__users_span_enum" NOT NULL, "unique" jsonb NOT NULL DEFAULT '{}', "___local_total" bigint NOT NULL, "___local_inc" bigint NOT NULL, "___local_dec" bigint NOT NULL, "___remote_total" bigint NOT NULL, "___remote_inc" bigint NOT NULL, "___remote_dec" bigint NOT NULL, CONSTRAINT "PK_4dfcf2c78d03524b9eb2c99d328" PRIMARY KEY ("id"))`); + await queryRunner.query(`ALTER TABLE "drive_folder" ADD CONSTRAINT "FK_f4fc06e49c0171c85f1c48060d2" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "drive_folder" ADD CONSTRAINT "FK_00ceffb0cdc238b3233294f08f2" FOREIGN KEY ("parentId") REFERENCES "drive_folder"("id") ON DELETE SET NULL ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "drive_file" ADD CONSTRAINT "FK_860fa6f6c7df5bb887249fba22e" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE SET NULL ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "drive_file" ADD CONSTRAINT "FK_bb90d1956dafc4068c28aa7560a" FOREIGN KEY ("folderId") REFERENCES "drive_folder"("id") ON DELETE SET NULL ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "user" ADD CONSTRAINT "FK_58f5c71eaab331645112cf8cfa5" FOREIGN KEY ("avatarId") REFERENCES "drive_file"("id") ON DELETE SET NULL ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "user" ADD CONSTRAINT "FK_afc64b53f8db3707ceb34eb28e2" FOREIGN KEY ("bannerId") REFERENCES "drive_file"("id") ON DELETE SET NULL ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "app" ADD CONSTRAINT "FK_3f5b0899ef90527a3462d7c2cb3" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE SET NULL ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "access_token" ADD CONSTRAINT "FK_9949557d0e1b2c19e5344c171e9" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "access_token" ADD CONSTRAINT "FK_a3ff16c90cc87a82a0b5959e560" FOREIGN KEY ("appId") REFERENCES "app"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "note" ADD CONSTRAINT "FK_17cb3553c700a4985dff5a30ff5" FOREIGN KEY ("replyId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "note" ADD CONSTRAINT "FK_52ccc804d7c69037d558bac4c96" FOREIGN KEY ("renoteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "note" ADD CONSTRAINT "FK_ec5c201576192ba8904c345c5cc" FOREIGN KEY ("appId") REFERENCES "app"("id") ON DELETE SET NULL ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "note" ADD CONSTRAINT "FK_5b87d9d19127bd5d92026017a7b" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "poll_vote" ADD CONSTRAINT "FK_66d2bd2ee31d14bcc23069a89f8" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "poll_vote" ADD CONSTRAINT "FK_aecfbd5ef60374918e63ee95fa7" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "note_reaction" ADD CONSTRAINT "FK_13761f64257f40c5636d0ff95ee" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "note_reaction" ADD CONSTRAINT "FK_45145e4953780f3cd5656f0ea6a" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "note_watching" ADD CONSTRAINT "FK_b0134ec406e8d09a540f8182888" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "note_watching" ADD CONSTRAINT "FK_03e7028ab8388a3f5e3ce2a8619" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "note_unread" ADD CONSTRAINT "FK_56b0166d34ddae49d8ef7610bb9" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "note_unread" ADD CONSTRAINT "FK_e637cba4dc4410218c4251260e4" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "notification" ADD CONSTRAINT "FK_3c601b70a1066d2c8b517094cb9" FOREIGN KEY ("notifieeId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "notification" ADD CONSTRAINT "FK_3b4e96eec8d36a8bbb9d02aa710" FOREIGN KEY ("notifierId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "notification" ADD CONSTRAINT "FK_769cb6b73a1efe22ddf733ac453" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "following" ADD CONSTRAINT "FK_24e0042143a18157b234df186c3" FOREIGN KEY ("followeeId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "following" ADD CONSTRAINT "FK_6516c5a6f3c015b4eed39978be5" FOREIGN KEY ("followerId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "muting" ADD CONSTRAINT "FK_ec96b4fed9dae517e0dbbe0675c" FOREIGN KEY ("muteeId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "muting" ADD CONSTRAINT "FK_93060675b4a79a577f31d260c67" FOREIGN KEY ("muterId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "sw_subscription" ADD CONSTRAINT "FK_97754ca6f2baff9b4abb7f853dd" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "blocking" ADD CONSTRAINT "FK_2cd4a2743a99671308f5417759e" FOREIGN KEY ("blockeeId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "blocking" ADD CONSTRAINT "FK_0627125f1a8a42c9a1929edb552" FOREIGN KEY ("blockerId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "user_list" ADD CONSTRAINT "FK_b7fcefbdd1c18dce86687531f99" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "user_list_joining" ADD CONSTRAINT "FK_d844bfc6f3f523a05189076efaa" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "user_list_joining" ADD CONSTRAINT "FK_605472305f26818cc93d1baaa74" FOREIGN KEY ("userListId") REFERENCES "user_list"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "note_favorite" ADD CONSTRAINT "FK_47f4b1892f5d6ba8efb3057d81a" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "note_favorite" ADD CONSTRAINT "FK_0e00498f180193423c992bc4370" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "abuse_user_report" ADD CONSTRAINT "FK_d049123c413e68ca52abe734203" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "abuse_user_report" ADD CONSTRAINT "FK_04cc96756f89d0b7f9473e8cdf3" FOREIGN KEY ("reporterId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "messaging_message" ADD CONSTRAINT "FK_5377c307783fce2b6d352e1203b" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "messaging_message" ADD CONSTRAINT "FK_cac14a4e3944454a5ce7daa5142" FOREIGN KEY ("recipientId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "messaging_message" ADD CONSTRAINT "FK_535def119223ac05ad3fa9ef64b" FOREIGN KEY ("fileId") REFERENCES "drive_file"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "signin" ADD CONSTRAINT "FK_2c308dbdc50d94dc625670055f7" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "auth_session" ADD CONSTRAINT "FK_c072b729d71697f959bde66ade0" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "auth_session" ADD CONSTRAINT "FK_dbe037d4bddd17b03a1dc778dee" FOREIGN KEY ("appId") REFERENCES "app"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "follow_request" ADD CONSTRAINT "FK_12c01c0d1a79f77d9f6c15fadd2" FOREIGN KEY ("followeeId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "follow_request" ADD CONSTRAINT "FK_a7fd92dd6dc519e6fb435dd108f" FOREIGN KEY ("followerId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "reversi_game" ADD CONSTRAINT "FK_f7467510c60a45ce5aca6292743" FOREIGN KEY ("user1Id") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "reversi_game" ADD CONSTRAINT "FK_6649a4e8c5d5cf32fb03b5da9f6" FOREIGN KEY ("user2Id") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "reversi_matching" ADD CONSTRAINT "FK_3b25402709dd9882048c2bbade0" FOREIGN KEY ("parentId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "reversi_matching" ADD CONSTRAINT "FK_e247b23a3c9b45f89ec1299d066" FOREIGN KEY ("childId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "user_note_pining" ADD CONSTRAINT "FK_bfbc6f79ba4007b4ce5097f08d6" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "user_note_pining" ADD CONSTRAINT "FK_68881008f7c3588ad7ecae471cf" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "poll" ADD CONSTRAINT "FK_da851e06d0dfe2ef397d8b1bf1b" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "user_keypair" ADD CONSTRAINT "FK_f4853eb41ab722fe05f81cedeb6" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "user_publickey" ADD CONSTRAINT "FK_10c146e4b39b443ede016f6736d" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "user_profile" ADD CONSTRAINT "FK_51cb79b5555effaf7d69ba1cff9" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "user_profile" DROP CONSTRAINT "FK_51cb79b5555effaf7d69ba1cff9"`); + await queryRunner.query(`ALTER TABLE "user_publickey" DROP CONSTRAINT "FK_10c146e4b39b443ede016f6736d"`); + await queryRunner.query(`ALTER TABLE "user_keypair" DROP CONSTRAINT "FK_f4853eb41ab722fe05f81cedeb6"`); + await queryRunner.query(`ALTER TABLE "poll" DROP CONSTRAINT "FK_da851e06d0dfe2ef397d8b1bf1b"`); + await queryRunner.query(`ALTER TABLE "user_note_pining" DROP CONSTRAINT "FK_68881008f7c3588ad7ecae471cf"`); + await queryRunner.query(`ALTER TABLE "user_note_pining" DROP CONSTRAINT "FK_bfbc6f79ba4007b4ce5097f08d6"`); + await queryRunner.query(`ALTER TABLE "reversi_matching" DROP CONSTRAINT "FK_e247b23a3c9b45f89ec1299d066"`); + await queryRunner.query(`ALTER TABLE "reversi_matching" DROP CONSTRAINT "FK_3b25402709dd9882048c2bbade0"`); + await queryRunner.query(`ALTER TABLE "reversi_game" DROP CONSTRAINT "FK_6649a4e8c5d5cf32fb03b5da9f6"`); + await queryRunner.query(`ALTER TABLE "reversi_game" DROP CONSTRAINT "FK_f7467510c60a45ce5aca6292743"`); + await queryRunner.query(`ALTER TABLE "follow_request" DROP CONSTRAINT "FK_a7fd92dd6dc519e6fb435dd108f"`); + await queryRunner.query(`ALTER TABLE "follow_request" DROP CONSTRAINT "FK_12c01c0d1a79f77d9f6c15fadd2"`); + await queryRunner.query(`ALTER TABLE "auth_session" DROP CONSTRAINT "FK_dbe037d4bddd17b03a1dc778dee"`); + await queryRunner.query(`ALTER TABLE "auth_session" DROP CONSTRAINT "FK_c072b729d71697f959bde66ade0"`); + await queryRunner.query(`ALTER TABLE "signin" DROP CONSTRAINT "FK_2c308dbdc50d94dc625670055f7"`); + await queryRunner.query(`ALTER TABLE "messaging_message" DROP CONSTRAINT "FK_535def119223ac05ad3fa9ef64b"`); + await queryRunner.query(`ALTER TABLE "messaging_message" DROP CONSTRAINT "FK_cac14a4e3944454a5ce7daa5142"`); + await queryRunner.query(`ALTER TABLE "messaging_message" DROP CONSTRAINT "FK_5377c307783fce2b6d352e1203b"`); + await queryRunner.query(`ALTER TABLE "abuse_user_report" DROP CONSTRAINT "FK_04cc96756f89d0b7f9473e8cdf3"`); + await queryRunner.query(`ALTER TABLE "abuse_user_report" DROP CONSTRAINT "FK_d049123c413e68ca52abe734203"`); + await queryRunner.query(`ALTER TABLE "note_favorite" DROP CONSTRAINT "FK_0e00498f180193423c992bc4370"`); + await queryRunner.query(`ALTER TABLE "note_favorite" DROP CONSTRAINT "FK_47f4b1892f5d6ba8efb3057d81a"`); + await queryRunner.query(`ALTER TABLE "user_list_joining" DROP CONSTRAINT "FK_605472305f26818cc93d1baaa74"`); + await queryRunner.query(`ALTER TABLE "user_list_joining" DROP CONSTRAINT "FK_d844bfc6f3f523a05189076efaa"`); + await queryRunner.query(`ALTER TABLE "user_list" DROP CONSTRAINT "FK_b7fcefbdd1c18dce86687531f99"`); + await queryRunner.query(`ALTER TABLE "blocking" DROP CONSTRAINT "FK_0627125f1a8a42c9a1929edb552"`); + await queryRunner.query(`ALTER TABLE "blocking" DROP CONSTRAINT "FK_2cd4a2743a99671308f5417759e"`); + await queryRunner.query(`ALTER TABLE "sw_subscription" DROP CONSTRAINT "FK_97754ca6f2baff9b4abb7f853dd"`); + await queryRunner.query(`ALTER TABLE "muting" DROP CONSTRAINT "FK_93060675b4a79a577f31d260c67"`); + await queryRunner.query(`ALTER TABLE "muting" DROP CONSTRAINT "FK_ec96b4fed9dae517e0dbbe0675c"`); + await queryRunner.query(`ALTER TABLE "following" DROP CONSTRAINT "FK_6516c5a6f3c015b4eed39978be5"`); + await queryRunner.query(`ALTER TABLE "following" DROP CONSTRAINT "FK_24e0042143a18157b234df186c3"`); + await queryRunner.query(`ALTER TABLE "notification" DROP CONSTRAINT "FK_769cb6b73a1efe22ddf733ac453"`); + await queryRunner.query(`ALTER TABLE "notification" DROP CONSTRAINT "FK_3b4e96eec8d36a8bbb9d02aa710"`); + await queryRunner.query(`ALTER TABLE "notification" DROP CONSTRAINT "FK_3c601b70a1066d2c8b517094cb9"`); + await queryRunner.query(`ALTER TABLE "note_unread" DROP CONSTRAINT "FK_e637cba4dc4410218c4251260e4"`); + await queryRunner.query(`ALTER TABLE "note_unread" DROP CONSTRAINT "FK_56b0166d34ddae49d8ef7610bb9"`); + await queryRunner.query(`ALTER TABLE "note_watching" DROP CONSTRAINT "FK_03e7028ab8388a3f5e3ce2a8619"`); + await queryRunner.query(`ALTER TABLE "note_watching" DROP CONSTRAINT "FK_b0134ec406e8d09a540f8182888"`); + await queryRunner.query(`ALTER TABLE "note_reaction" DROP CONSTRAINT "FK_45145e4953780f3cd5656f0ea6a"`); + await queryRunner.query(`ALTER TABLE "note_reaction" DROP CONSTRAINT "FK_13761f64257f40c5636d0ff95ee"`); + await queryRunner.query(`ALTER TABLE "poll_vote" DROP CONSTRAINT "FK_aecfbd5ef60374918e63ee95fa7"`); + await queryRunner.query(`ALTER TABLE "poll_vote" DROP CONSTRAINT "FK_66d2bd2ee31d14bcc23069a89f8"`); + await queryRunner.query(`ALTER TABLE "note" DROP CONSTRAINT "FK_5b87d9d19127bd5d92026017a7b"`); + await queryRunner.query(`ALTER TABLE "note" DROP CONSTRAINT "FK_ec5c201576192ba8904c345c5cc"`); + await queryRunner.query(`ALTER TABLE "note" DROP CONSTRAINT "FK_52ccc804d7c69037d558bac4c96"`); + await queryRunner.query(`ALTER TABLE "note" DROP CONSTRAINT "FK_17cb3553c700a4985dff5a30ff5"`); + await queryRunner.query(`ALTER TABLE "access_token" DROP CONSTRAINT "FK_a3ff16c90cc87a82a0b5959e560"`); + await queryRunner.query(`ALTER TABLE "access_token" DROP CONSTRAINT "FK_9949557d0e1b2c19e5344c171e9"`); + await queryRunner.query(`ALTER TABLE "app" DROP CONSTRAINT "FK_3f5b0899ef90527a3462d7c2cb3"`); + await queryRunner.query(`ALTER TABLE "user" DROP CONSTRAINT "FK_afc64b53f8db3707ceb34eb28e2"`); + await queryRunner.query(`ALTER TABLE "user" DROP CONSTRAINT "FK_58f5c71eaab331645112cf8cfa5"`); + await queryRunner.query(`ALTER TABLE "drive_file" DROP CONSTRAINT "FK_bb90d1956dafc4068c28aa7560a"`); + await queryRunner.query(`ALTER TABLE "drive_file" DROP CONSTRAINT "FK_860fa6f6c7df5bb887249fba22e"`); + await queryRunner.query(`ALTER TABLE "drive_folder" DROP CONSTRAINT "FK_00ceffb0cdc238b3233294f08f2"`); + await queryRunner.query(`ALTER TABLE "drive_folder" DROP CONSTRAINT "FK_f4fc06e49c0171c85f1c48060d2"`); + await queryRunner.query(`DROP TABLE "__chart__users"`); + await queryRunner.query(`DROP TYPE "__chart__users_span_enum"`); + await queryRunner.query(`DROP TABLE "__chart__test"`); + await queryRunner.query(`DROP TYPE "__chart__test_span_enum"`); + await queryRunner.query(`DROP TABLE "__chart__test_unique"`); + await queryRunner.query(`DROP TYPE "__chart__test_unique_span_enum"`); + await queryRunner.query(`DROP TABLE "__chart__test_grouped"`); + await queryRunner.query(`DROP TYPE "__chart__test_grouped_span_enum"`); + await queryRunner.query(`DROP TABLE "__chart__per_user_reaction"`); + await queryRunner.query(`DROP TYPE "__chart__per_user_reaction_span_enum"`); + await queryRunner.query(`DROP TABLE "__chart__per_user_notes"`); + await queryRunner.query(`DROP TYPE "__chart__per_user_notes_span_enum"`); + await queryRunner.query(`DROP TABLE "__chart__per_user_following"`); + await queryRunner.query(`DROP TYPE "__chart__per_user_following_span_enum"`); + await queryRunner.query(`DROP TABLE "__chart__per_user_drive"`); + await queryRunner.query(`DROP TYPE "__chart__per_user_drive_span_enum"`); + await queryRunner.query(`DROP TABLE "__chart__notes"`); + await queryRunner.query(`DROP TYPE "__chart__notes_span_enum"`); + await queryRunner.query(`DROP TABLE "__chart__network"`); + await queryRunner.query(`DROP TYPE "__chart__network_span_enum"`); + await queryRunner.query(`DROP TABLE "__chart__instance"`); + await queryRunner.query(`DROP TYPE "__chart__instance_span_enum"`); + await queryRunner.query(`DROP TABLE "__chart__hashtag"`); + await queryRunner.query(`DROP TYPE "__chart__hashtag_span_enum"`); + await queryRunner.query(`DROP TABLE "__chart__federation"`); + await queryRunner.query(`DROP TYPE "__chart__federation_span_enum"`); + await queryRunner.query(`DROP TABLE "__chart__drive"`); + await queryRunner.query(`DROP TYPE "__chart__drive_span_enum"`); + await queryRunner.query(`DROP TABLE "__chart__active_users"`); + await queryRunner.query(`DROP TYPE "__chart__active_users_span_enum"`); + await queryRunner.query(`DROP INDEX "IDX_dce530b98e454793dac5ec2f5a"`); + await queryRunner.query(`DROP TABLE "user_profile"`); + await queryRunner.query(`DROP INDEX "IDX_171e64971c780ebd23fae140bb"`); + await queryRunner.query(`DROP TABLE "user_publickey"`); + await queryRunner.query(`DROP TABLE "user_keypair"`); + await queryRunner.query(`DROP INDEX "IDX_7fa20a12319c7f6dc3aed98c0a"`); + await queryRunner.query(`DROP INDEX "IDX_0610ebcfcfb4a18441a9bcdab2"`); + await queryRunner.query(`DROP TABLE "poll"`); + await queryRunner.query(`DROP TYPE "poll_notevisibility_enum"`); + await queryRunner.query(`DROP INDEX "IDX_410cd649884b501c02d6e72738"`); + await queryRunner.query(`DROP INDEX "IDX_bfbc6f79ba4007b4ce5097f08d"`); + await queryRunner.query(`DROP TABLE "user_note_pining"`); + await queryRunner.query(`DROP INDEX "IDX_e247b23a3c9b45f89ec1299d06"`); + await queryRunner.query(`DROP INDEX "IDX_3b25402709dd9882048c2bbade"`); + await queryRunner.query(`DROP INDEX "IDX_b604d92d6c7aec38627f6eaf16"`); + await queryRunner.query(`DROP TABLE "reversi_matching"`); + await queryRunner.query(`DROP INDEX "IDX_b46ec40746efceac604142be1c"`); + await queryRunner.query(`DROP TABLE "reversi_game"`); + await queryRunner.query(`DROP INDEX "IDX_4f4d35e1256c84ae3d1f0eab10"`); + await queryRunner.query(`DROP INDEX "IDX_5900e907bb46516ddf2871327c"`); + await queryRunner.query(`DROP INDEX "IDX_b37dafc86e9af007e3295c2781"`); + await queryRunner.query(`DROP TABLE "emoji"`); + await queryRunner.query(`DROP INDEX "IDX_d54a512b822fac7ed52800f6b4"`); + await queryRunner.query(`DROP INDEX "IDX_a7fd92dd6dc519e6fb435dd108"`); + await queryRunner.query(`DROP INDEX "IDX_12c01c0d1a79f77d9f6c15fadd"`); + await queryRunner.query(`DROP TABLE "follow_request"`); + await queryRunner.query(`DROP INDEX "IDX_62cb09e1129f6ec024ef66e183"`); + await queryRunner.query(`DROP TABLE "auth_session"`); + await queryRunner.query(`DROP INDEX "IDX_2c308dbdc50d94dc625670055f"`); + await queryRunner.query(`DROP TABLE "signin"`); + await queryRunner.query(`DROP INDEX "IDX_cac14a4e3944454a5ce7daa514"`); + await queryRunner.query(`DROP INDEX "IDX_5377c307783fce2b6d352e1203"`); + await queryRunner.query(`DROP INDEX "IDX_e21cd3646e52ef9c94aaf17c2e"`); + await queryRunner.query(`DROP TABLE "messaging_message"`); + await queryRunner.query(`DROP INDEX "IDX_0ff69e8dfa9fe31bb4a4660f59"`); + await queryRunner.query(`DROP TABLE "registration_ticket"`); + await queryRunner.query(`DROP INDEX "IDX_5cd442c3b2e74fdd99dae20243"`); + await queryRunner.query(`DROP INDEX "IDX_04cc96756f89d0b7f9473e8cdf"`); + await queryRunner.query(`DROP INDEX "IDX_d049123c413e68ca52abe73420"`); + await queryRunner.query(`DROP INDEX "IDX_db2098070b2b5a523c58181f74"`); + await queryRunner.query(`DROP TABLE "abuse_user_report"`); + await queryRunner.query(`DROP INDEX "IDX_0f4fb9ad355f3effff221ef245"`); + await queryRunner.query(`DROP INDEX "IDX_47f4b1892f5d6ba8efb3057d81"`); + await queryRunner.query(`DROP TABLE "note_favorite"`); + await queryRunner.query(`DROP INDEX "IDX_0b03cbcd7e6a7ce068efa8ecc2"`); + await queryRunner.query(`DROP INDEX "IDX_0c44bf4f680964145f2a68a341"`); + await queryRunner.query(`DROP INDEX "IDX_d57f9030cd3af7f63ffb1c267c"`); + await queryRunner.query(`DROP INDEX "IDX_4c02d38a976c3ae132228c6fce"`); + await queryRunner.query(`DROP INDEX "IDX_0e206cec573f1edff4a3062923"`); + await queryRunner.query(`DROP INDEX "IDX_2710a55f826ee236ea1a62698f"`); + await queryRunner.query(`DROP INDEX "IDX_347fec870eafea7b26c8a73bac"`); + await queryRunner.query(`DROP TABLE "hashtag"`); + await queryRunner.query(`DROP INDEX "IDX_605472305f26818cc93d1baaa7"`); + await queryRunner.query(`DROP INDEX "IDX_d844bfc6f3f523a05189076efa"`); + await queryRunner.query(`DROP TABLE "user_list_joining"`); + await queryRunner.query(`DROP INDEX "IDX_b7fcefbdd1c18dce86687531f9"`); + await queryRunner.query(`DROP TABLE "user_list"`); + await queryRunner.query(`DROP INDEX "IDX_98a1bc5cb30dfd159de056549f"`); + await queryRunner.query(`DROP INDEX "IDX_0627125f1a8a42c9a1929edb55"`); + await queryRunner.query(`DROP INDEX "IDX_2cd4a2743a99671308f5417759"`); + await queryRunner.query(`DROP INDEX "IDX_b9a354f7941c1e779f3b33aea6"`); + await queryRunner.query(`DROP TABLE "blocking"`); + await queryRunner.query(`DROP INDEX "IDX_97754ca6f2baff9b4abb7f853d"`); + await queryRunner.query(`DROP TABLE "sw_subscription"`); + await queryRunner.query(`DROP INDEX "IDX_1eb9d9824a630321a29fd3b290"`); + await queryRunner.query(`DROP INDEX "IDX_93060675b4a79a577f31d260c6"`); + await queryRunner.query(`DROP INDEX "IDX_ec96b4fed9dae517e0dbbe0675"`); + await queryRunner.query(`DROP INDEX "IDX_f86d57fbca33c7a4e6897490cc"`); + await queryRunner.query(`DROP TABLE "muting"`); + await queryRunner.query(`DROP INDEX "IDX_8d5afc98982185799b160e10eb"`); + await queryRunner.query(`DROP INDEX "IDX_2cd3b2a6b4cf0b910b260afe08"`); + await queryRunner.query(`DROP TABLE "instance"`); + await queryRunner.query(`DROP INDEX "IDX_307be5f1d1252e0388662acb96"`); + await queryRunner.query(`DROP INDEX "IDX_6516c5a6f3c015b4eed39978be"`); + await queryRunner.query(`DROP INDEX "IDX_24e0042143a18157b234df186c"`); + await queryRunner.query(`DROP INDEX "IDX_582f8fab771a9040a12961f3e7"`); + await queryRunner.query(`DROP TABLE "following"`); + await queryRunner.query(`DROP TABLE "meta"`); + await queryRunner.query(`DROP INDEX "IDX_3c601b70a1066d2c8b517094cb"`); + await queryRunner.query(`DROP INDEX "IDX_b11a5e627c41d4dc3170f1d370"`); + await queryRunner.query(`DROP TABLE "notification"`); + await queryRunner.query(`DROP INDEX "IDX_d908433a4953cc13216cd9c274"`); + await queryRunner.query(`DROP INDEX "IDX_e637cba4dc4410218c4251260e"`); + await queryRunner.query(`DROP INDEX "IDX_56b0166d34ddae49d8ef7610bb"`); + await queryRunner.query(`DROP TABLE "note_unread"`); + await queryRunner.query(`DROP INDEX "IDX_a42c93c69989ce1d09959df4cf"`); + await queryRunner.query(`DROP INDEX "IDX_44499765eec6b5489d72c4253b"`); + await queryRunner.query(`DROP INDEX "IDX_03e7028ab8388a3f5e3ce2a861"`); + await queryRunner.query(`DROP INDEX "IDX_b0134ec406e8d09a540f818288"`); + await queryRunner.query(`DROP INDEX "IDX_318cdf42a9cfc11f479bd802bb"`); + await queryRunner.query(`DROP TABLE "note_watching"`); + await queryRunner.query(`DROP INDEX "IDX_ad0c221b25672daf2df320a817"`); + await queryRunner.query(`DROP INDEX "IDX_45145e4953780f3cd5656f0ea6"`); + await queryRunner.query(`DROP INDEX "IDX_13761f64257f40c5636d0ff95e"`); + await queryRunner.query(`DROP INDEX "IDX_01f4581f114e0ebd2bbb876f0b"`); + await queryRunner.query(`DROP TABLE "note_reaction"`); + await queryRunner.query(`DROP INDEX "IDX_50bd7164c5b78f1f4a42c4d21f"`); + await queryRunner.query(`DROP INDEX "IDX_aecfbd5ef60374918e63ee95fa"`); + await queryRunner.query(`DROP INDEX "IDX_66d2bd2ee31d14bcc23069a89f"`); + await queryRunner.query(`DROP INDEX "IDX_0fb627e1c2f753262a74f0562d"`); + await queryRunner.query(`DROP TABLE "poll_vote"`); + await queryRunner.query(`DROP INDEX "IDX_7125a826ab192eb27e11d358a5"`); + await queryRunner.query(`DROP INDEX "IDX_88937d94d7443d9a99a76fa5c0"`); + await queryRunner.query(`DROP INDEX "IDX_54ebcb6d27222913b908d56fd8"`); + await queryRunner.query(`DROP INDEX "IDX_796a8c03959361f97dc2be1d5c"`); + await queryRunner.query(`DROP INDEX "IDX_25dfc71b0369b003a4cd434d0b"`); + await queryRunner.query(`DROP INDEX "IDX_51c063b6a133a9cb87145450f5"`); + await queryRunner.query(`DROP INDEX "IDX_153536c67d05e9adb24e99fc2b"`); + await queryRunner.query(`DROP INDEX "IDX_5b87d9d19127bd5d92026017a7"`); + await queryRunner.query(`DROP INDEX "IDX_52ccc804d7c69037d558bac4c9"`); + await queryRunner.query(`DROP INDEX "IDX_17cb3553c700a4985dff5a30ff"`); + await queryRunner.query(`DROP INDEX "IDX_e7c0567f5261063592f022e9b5"`); + await queryRunner.query(`DROP TABLE "note"`); + await queryRunner.query(`DROP TYPE "note_visibility_enum"`); + await queryRunner.query(`DROP INDEX "IDX_9949557d0e1b2c19e5344c171e"`); + await queryRunner.query(`DROP INDEX "IDX_64c327441248bae40f7d92f34f"`); + await queryRunner.query(`DROP INDEX "IDX_70ba8f6af34bc924fc9e12adb8"`); + await queryRunner.query(`DROP TABLE "access_token"`); + await queryRunner.query(`DROP INDEX "IDX_f49922d511d666848f250663c4"`); + await queryRunner.query(`DROP INDEX "IDX_3f5b0899ef90527a3462d7c2cb"`); + await queryRunner.query(`DROP INDEX "IDX_048a757923ed8b157e9895da53"`); + await queryRunner.query(`DROP TABLE "app"`); + await queryRunner.query(`DROP INDEX "IDX_5deb01ae162d1d70b80d064c27"`); + await queryRunner.query(`DROP INDEX "IDX_a854e557b1b14814750c7c7b0c"`); + await queryRunner.query(`DROP INDEX "IDX_be623adaa4c566baf5d29ce0c8"`); + await queryRunner.query(`DROP INDEX "IDX_3252a5df8d5bbd16b281f7799e"`); + await queryRunner.query(`DROP INDEX "IDX_fa99d777623947a5b05f394cae"`); + await queryRunner.query(`DROP INDEX "IDX_a27b942a0d6dcff90e3ee9b5e8"`); + await queryRunner.query(`DROP INDEX "IDX_80ca6e6ef65fb9ef34ea8c90f4"`); + await queryRunner.query(`DROP INDEX "IDX_e11e649824a45d8ed01d597fd9"`); + await queryRunner.query(`DROP TABLE "user"`); + await queryRunner.query(`DROP INDEX "IDX_bb90d1956dafc4068c28aa7560"`); + await queryRunner.query(`DROP INDEX "IDX_e5848eac4940934e23dbc17581"`); + await queryRunner.query(`DROP INDEX "IDX_c55b2b7c284d9fef98026fc88e"`); + await queryRunner.query(`DROP INDEX "IDX_e74022ce9a074b3866f70e0d27"`); + await queryRunner.query(`DROP INDEX "IDX_d85a184c2540d2deba33daf642"`); + await queryRunner.query(`DROP INDEX "IDX_a40b8df8c989d7db937ea27cf6"`); + await queryRunner.query(`DROP INDEX "IDX_37bb9a1b4585f8a3beb24c62d6"`); + await queryRunner.query(`DROP INDEX "IDX_92779627994ac79277f070c91e"`); + await queryRunner.query(`DROP INDEX "IDX_860fa6f6c7df5bb887249fba22"`); + await queryRunner.query(`DROP INDEX "IDX_c8dfad3b72196dd1d6b5db168a"`); + await queryRunner.query(`DROP TABLE "drive_file"`); + await queryRunner.query(`DROP INDEX "IDX_00ceffb0cdc238b3233294f08f"`); + await queryRunner.query(`DROP INDEX "IDX_f4fc06e49c0171c85f1c48060d"`); + await queryRunner.query(`DROP INDEX "IDX_02878d441ceae15ce060b73daf"`); + await queryRunner.query(`DROP TABLE "drive_folder"`); + await queryRunner.query(`DROP INDEX "IDX_584b536b49e53ac81beb39a177"`); + await queryRunner.query(`DROP INDEX "IDX_8cb40cfc8f3c28261e6f887b03"`); + await queryRunner.query(`DROP INDEX "IDX_8e4eb51a35d81b64dda28eed0a"`); + await queryRunner.query(`DROP TABLE "log"`); + await queryRunner.query(`DROP TYPE "log_level_enum"`); + } +} +exports.Init1000000000000 = Init1000000000000; diff --git a/packages/backend/migration/1556348509290-Pages.js b/packages/backend/migration/1556348509290-Pages.js new file mode 100644 index 000000000..d69d17258 --- /dev/null +++ b/packages/backend/migration/1556348509290-Pages.js @@ -0,0 +1,29 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class Pages1556348509290 { + async up(queryRunner) { + await queryRunner.query(`CREATE TYPE "page_visibility_enum" AS ENUM('public', 'followers', 'specified')`); + await queryRunner.query(`CREATE TABLE "page" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL, "title" character varying(256) NOT NULL, "name" character varying(256) NOT NULL, "summary" character varying(256), "alignCenter" boolean NOT NULL, "font" character varying(32) NOT NULL, "userId" character varying(32) NOT NULL, "eyeCatchingImageId" character varying(32), "content" jsonb NOT NULL DEFAULT '[]', "variables" jsonb NOT NULL DEFAULT '[]', "visibility" "page_visibility_enum" NOT NULL, "visibleUserIds" character varying(32) array NOT NULL DEFAULT '{}'::varchar[], CONSTRAINT "PK_742f4117e065c5b6ad21b37ba1f" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE INDEX "IDX_fbb4297c927a9b85e9cefa2eb1" ON "page" ("createdAt") `); + await queryRunner.query(`CREATE INDEX "IDX_af639b066dfbca78b01a920f8a" ON "page" ("updatedAt") `); + await queryRunner.query(`CREATE INDEX "IDX_b82c19c08afb292de4600d99e4" ON "page" ("name") `); + await queryRunner.query(`CREATE INDEX "IDX_ae1d917992dd0c9d9bbdad06c4" ON "page" ("userId") `); + await queryRunner.query(`CREATE INDEX "IDX_90148bbc2bf0854428786bfc15" ON "page" ("visibleUserIds") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_2133ef8317e4bdb839c0dcbf13" ON "page" ("userId", "name") `); + await queryRunner.query(`ALTER TABLE "page" ADD CONSTRAINT "FK_ae1d917992dd0c9d9bbdad06c4a" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "page" ADD CONSTRAINT "FK_3126dd7c502c9e4d7597ef7ef10" FOREIGN KEY ("eyeCatchingImageId") REFERENCES "drive_file"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "page" DROP CONSTRAINT "FK_3126dd7c502c9e4d7597ef7ef10"`); + await queryRunner.query(`ALTER TABLE "page" DROP CONSTRAINT "FK_ae1d917992dd0c9d9bbdad06c4a"`); + await queryRunner.query(`DROP INDEX "IDX_2133ef8317e4bdb839c0dcbf13"`); + await queryRunner.query(`DROP INDEX "IDX_90148bbc2bf0854428786bfc15"`); + await queryRunner.query(`DROP INDEX "IDX_ae1d917992dd0c9d9bbdad06c4"`); + await queryRunner.query(`DROP INDEX "IDX_b82c19c08afb292de4600d99e4"`); + await queryRunner.query(`DROP INDEX "IDX_af639b066dfbca78b01a920f8a"`); + await queryRunner.query(`DROP INDEX "IDX_fbb4297c927a9b85e9cefa2eb1"`); + await queryRunner.query(`DROP TABLE "page"`); + await queryRunner.query(`DROP TYPE "page_visibility_enum"`); + } +} +exports.Pages1556348509290 = Pages1556348509290; diff --git a/packages/backend/migration/1556746559567-UserProfile.js b/packages/backend/migration/1556746559567-UserProfile.js new file mode 100644 index 000000000..3a082b882 --- /dev/null +++ b/packages/backend/migration/1556746559567-UserProfile.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class UserProfile1556746559567 { + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "user_profile" ALTER COLUMN "githubId" TYPE VARCHAR(64) USING "githubId"::VARCHAR(64)`); + await queryRunner.query(`ALTER TABLE "user_profile" ALTER COLUMN "discordExpiresDate" TYPE VARCHAR(64) USING "discordExpiresDate"::VARCHAR(64)`); + } + async down(queryRunner) { + await queryRunner.query(`UPDATE "user_profile" SET github = FALSE, discord = FALSE`); + await queryRunner.query(`ALTER TABLE "user_profile" ALTER COLUMN "githubId" TYPE INTEGER USING NULL`); + await queryRunner.query(`ALTER TABLE "user_profile" ALTER COLUMN "discordExpiresDate" TYPE INTEGER USING NULL`); + } +} +exports.UserProfile1556746559567 = UserProfile1556746559567; diff --git a/packages/backend/migration/1557476068003-PinnedUsers.js b/packages/backend/migration/1557476068003-PinnedUsers.js new file mode 100644 index 000000000..c5e7fe748 --- /dev/null +++ b/packages/backend/migration/1557476068003-PinnedUsers.js @@ -0,0 +1,11 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class PinnedUsers1557476068003 { + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" ADD "pinnedUsers" character varying(256) array NOT NULL DEFAULT '{}'::varchar[]`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "pinnedUsers"`); + } +} +exports.PinnedUsers1557476068003 = PinnedUsers1557476068003; diff --git a/packages/backend/migration/1557761316509-AddSomeUrls.js b/packages/backend/migration/1557761316509-AddSomeUrls.js new file mode 100644 index 000000000..f6a7b409c --- /dev/null +++ b/packages/backend/migration/1557761316509-AddSomeUrls.js @@ -0,0 +1,15 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class AddSomeUrls1557761316509 { + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" ADD "ToSUrl" character varying(512)`); + await queryRunner.query(`ALTER TABLE "meta" ADD "repositoryUrl" character varying(512) NOT NULL DEFAULT 'https://github.com/misskey-dev/misskey'`); + await queryRunner.query(`ALTER TABLE "meta" ADD "feedbackUrl" character varying(512) DEFAULT 'https://github.com/misskey-dev/misskey/issues/new'`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "feedbackUrl"`); + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "repositoryUrl"`); + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "ToSUrl"`); + } +} +exports.AddSomeUrls1557761316509 = AddSomeUrls1557761316509; diff --git a/packages/backend/migration/1557932705754-ObjectStorageSetting.js b/packages/backend/migration/1557932705754-ObjectStorageSetting.js new file mode 100644 index 000000000..d798ac5ca --- /dev/null +++ b/packages/backend/migration/1557932705754-ObjectStorageSetting.js @@ -0,0 +1,29 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class ObjectStorageSetting1557932705754 { + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" ADD "useObjectStorage" boolean NOT NULL DEFAULT false`); + await queryRunner.query(`ALTER TABLE "meta" ADD "objectStorageBucket" character varying(512)`); + await queryRunner.query(`ALTER TABLE "meta" ADD "objectStoragePrefix" character varying(512)`); + await queryRunner.query(`ALTER TABLE "meta" ADD "objectStorageBaseUrl" character varying(512)`); + await queryRunner.query(`ALTER TABLE "meta" ADD "objectStorageEndpoint" character varying(512)`); + await queryRunner.query(`ALTER TABLE "meta" ADD "objectStorageRegion" character varying(512)`); + await queryRunner.query(`ALTER TABLE "meta" ADD "objectStorageAccessKey" character varying(512)`); + await queryRunner.query(`ALTER TABLE "meta" ADD "objectStorageSecretKey" character varying(512)`); + await queryRunner.query(`ALTER TABLE "meta" ADD "objectStoragePort" integer`); + await queryRunner.query(`ALTER TABLE "meta" ADD "objectStorageUseSSL" boolean NOT NULL DEFAULT true`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStorageUseSSL"`); + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStoragePort"`); + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStorageSecretKey"`); + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStorageAccessKey"`); + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStorageRegion"`); + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStorageEndpoint"`); + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStorageBaseUrl"`); + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStoragePrefix"`); + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStorageBucket"`); + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "useObjectStorage"`); + } +} +exports.ObjectStorageSetting1557932705754 = ObjectStorageSetting1557932705754; diff --git a/packages/backend/migration/1558072954435-PageLike.js b/packages/backend/migration/1558072954435-PageLike.js new file mode 100644 index 000000000..703843497 --- /dev/null +++ b/packages/backend/migration/1558072954435-PageLike.js @@ -0,0 +1,21 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class PageLike1558072954435 { + async up(queryRunner) { + await queryRunner.query(`CREATE TABLE "page_like" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "pageId" character varying(32) NOT NULL, CONSTRAINT "PK_813f034843af992d3ae0f43c64c" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE INDEX "IDX_0e61efab7f88dbb79c9166dbb4" ON "page_like" ("userId") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_4ce6fb9c70529b4c8ac46c9bfa" ON "page_like" ("userId", "pageId") `); + await queryRunner.query(`ALTER TABLE "page" ADD "likedCount" integer NOT NULL DEFAULT 0`); + await queryRunner.query(`ALTER TABLE "page_like" ADD CONSTRAINT "FK_0e61efab7f88dbb79c9166dbb48" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "page_like" ADD CONSTRAINT "FK_cf8782626dced3176038176a847" FOREIGN KEY ("pageId") REFERENCES "page"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "page_like" DROP CONSTRAINT "FK_cf8782626dced3176038176a847"`); + await queryRunner.query(`ALTER TABLE "page_like" DROP CONSTRAINT "FK_0e61efab7f88dbb79c9166dbb48"`); + await queryRunner.query(`ALTER TABLE "page" DROP COLUMN "likedCount"`); + await queryRunner.query(`DROP INDEX "IDX_4ce6fb9c70529b4c8ac46c9bfa"`); + await queryRunner.query(`DROP INDEX "IDX_0e61efab7f88dbb79c9166dbb4"`); + await queryRunner.query(`DROP TABLE "page_like"`); + } +} +exports.PageLike1558072954435 = PageLike1558072954435; diff --git a/packages/backend/migration/1558103093633-UserGroup.js b/packages/backend/migration/1558103093633-UserGroup.js new file mode 100644 index 000000000..9c1e51128 --- /dev/null +++ b/packages/backend/migration/1558103093633-UserGroup.js @@ -0,0 +1,39 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class UserGroup1558103093633 { + async up(queryRunner) { + await queryRunner.query(`CREATE TABLE "user_group" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "name" character varying(256) NOT NULL, "userId" character varying(32) NOT NULL, "isPrivate" boolean NOT NULL DEFAULT false, CONSTRAINT "PK_3c29fba6fe013ec8724378ce7c9" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE INDEX "IDX_20e30aa35180e317e133d75316" ON "user_group" ("createdAt") `); + await queryRunner.query(`CREATE INDEX "IDX_3d6b372788ab01be58853003c9" ON "user_group" ("userId") `); + await queryRunner.query(`CREATE TABLE "user_group_joining" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "userGroupId" character varying(32) NOT NULL, CONSTRAINT "PK_15f2425885253c5507e1599cfe7" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE INDEX "IDX_f3a1b4bd0c7cabba958a0c0b23" ON "user_group_joining" ("userId") `); + await queryRunner.query(`CREATE INDEX "IDX_67dc758bc0566985d1b3d39986" ON "user_group_joining" ("userGroupId") `); + await queryRunner.query(`ALTER TABLE "messaging_message" ADD "groupId" character varying(32)`); + await queryRunner.query(`ALTER TABLE "messaging_message" ADD "reads" character varying(32) array NOT NULL DEFAULT '{}'::varchar[]`); + await queryRunner.query(`ALTER TABLE "messaging_message" ALTER COLUMN "recipientId" DROP NOT NULL`); + await queryRunner.query(`COMMENT ON COLUMN "messaging_message"."recipientId" IS 'The recipient user ID.'`); + await queryRunner.query(`CREATE INDEX "IDX_2c4be03b446884f9e9c502135b" ON "messaging_message" ("groupId") `); + await queryRunner.query(`ALTER TABLE "messaging_message" ADD CONSTRAINT "FK_2c4be03b446884f9e9c502135be" FOREIGN KEY ("groupId") REFERENCES "user_group"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "user_group" ADD CONSTRAINT "FK_3d6b372788ab01be58853003c93" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "user_group_joining" ADD CONSTRAINT "FK_f3a1b4bd0c7cabba958a0c0b231" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "user_group_joining" ADD CONSTRAINT "FK_67dc758bc0566985d1b3d399865" FOREIGN KEY ("userGroupId") REFERENCES "user_group"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "user_group_joining" DROP CONSTRAINT "FK_67dc758bc0566985d1b3d399865"`); + await queryRunner.query(`ALTER TABLE "user_group_joining" DROP CONSTRAINT "FK_f3a1b4bd0c7cabba958a0c0b231"`); + await queryRunner.query(`ALTER TABLE "user_group" DROP CONSTRAINT "FK_3d6b372788ab01be58853003c93"`); + await queryRunner.query(`ALTER TABLE "messaging_message" DROP CONSTRAINT "FK_2c4be03b446884f9e9c502135be"`); + await queryRunner.query(`DROP INDEX "IDX_2c4be03b446884f9e9c502135b"`); + await queryRunner.query(`COMMENT ON COLUMN "messaging_message"."recipientId" IS ''`); + await queryRunner.query(`ALTER TABLE "messaging_message" ALTER COLUMN "recipientId" SET NOT NULL`); + await queryRunner.query(`ALTER TABLE "messaging_message" DROP COLUMN "reads"`); + await queryRunner.query(`ALTER TABLE "messaging_message" DROP COLUMN "groupId"`); + await queryRunner.query(`DROP INDEX "IDX_67dc758bc0566985d1b3d39986"`); + await queryRunner.query(`DROP INDEX "IDX_f3a1b4bd0c7cabba958a0c0b23"`); + await queryRunner.query(`DROP TABLE "user_group_joining"`); + await queryRunner.query(`DROP INDEX "IDX_3d6b372788ab01be58853003c9"`); + await queryRunner.query(`DROP INDEX "IDX_20e30aa35180e317e133d75316"`); + await queryRunner.query(`DROP TABLE "user_group"`); + } +} +exports.UserGroup1558103093633 = UserGroup1558103093633; diff --git a/packages/backend/migration/1558257926829-UserGroupInvite.js b/packages/backend/migration/1558257926829-UserGroupInvite.js new file mode 100644 index 000000000..e8a575e74 --- /dev/null +++ b/packages/backend/migration/1558257926829-UserGroupInvite.js @@ -0,0 +1,23 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class UserGroupInvite1558257926829 { + async up(queryRunner) { + await queryRunner.query(`CREATE TABLE "user_group_invite" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "userGroupId" character varying(32) NOT NULL, CONSTRAINT "PK_3893884af0d3a5f4d01e7921a97" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE INDEX "IDX_1039988afa3bf991185b277fe0" ON "user_group_invite" ("userId") `); + await queryRunner.query(`CREATE INDEX "IDX_e10924607d058004304611a436" ON "user_group_invite" ("userGroupId") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_78787741f9010886796f2320a4" ON "user_group_invite" ("userId", "userGroupId") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_d9ecaed8c6dc43f3592c229282" ON "user_group_joining" ("userId", "userGroupId") `); + await queryRunner.query(`ALTER TABLE "user_group_invite" ADD CONSTRAINT "FK_1039988afa3bf991185b277fe03" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "user_group_invite" ADD CONSTRAINT "FK_e10924607d058004304611a436a" FOREIGN KEY ("userGroupId") REFERENCES "user_group"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "user_group_invite" DROP CONSTRAINT "FK_e10924607d058004304611a436a"`); + await queryRunner.query(`ALTER TABLE "user_group_invite" DROP CONSTRAINT "FK_1039988afa3bf991185b277fe03"`); + await queryRunner.query(`DROP INDEX "IDX_d9ecaed8c6dc43f3592c229282"`); + await queryRunner.query(`DROP INDEX "IDX_78787741f9010886796f2320a4"`); + await queryRunner.query(`DROP INDEX "IDX_e10924607d058004304611a436"`); + await queryRunner.query(`DROP INDEX "IDX_1039988afa3bf991185b277fe0"`); + await queryRunner.query(`DROP TABLE "user_group_invite"`); + } +} +exports.UserGroupInvite1558257926829 = UserGroupInvite1558257926829; diff --git a/packages/backend/migration/1558266512381-UserListJoining.js b/packages/backend/migration/1558266512381-UserListJoining.js new file mode 100644 index 000000000..b31f7bd3d --- /dev/null +++ b/packages/backend/migration/1558266512381-UserListJoining.js @@ -0,0 +1,11 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class UserListJoining1558266512381 { + async up(queryRunner) { + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_90f7da835e4c10aca6853621e1" ON "user_list_joining" ("userId", "userListId") `); + } + async down(queryRunner) { + await queryRunner.query(`DROP INDEX "IDX_90f7da835e4c10aca6853621e1"`); + } +} +exports.UserListJoining1558266512381 = UserListJoining1558266512381; diff --git a/packages/backend/migration/1561706992953-webauthn.js b/packages/backend/migration/1561706992953-webauthn.js new file mode 100644 index 000000000..f05054f55 --- /dev/null +++ b/packages/backend/migration/1561706992953-webauthn.js @@ -0,0 +1,27 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class webauthn1561706992953 { + async up(queryRunner) { + await queryRunner.query(`CREATE TABLE "attestation_challenge" ("id" character varying(32) NOT NULL, "userId" character varying(32) NOT NULL, "challenge" character varying(64) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "registrationChallenge" boolean NOT NULL DEFAULT false, CONSTRAINT "PK_d0ba6786e093f1bcb497572a6b5" PRIMARY KEY ("id", "userId"))`); + await queryRunner.query(`CREATE INDEX "IDX_f1a461a618fa1755692d0e0d59" ON "attestation_challenge" ("userId") `); + await queryRunner.query(`CREATE INDEX "IDX_47efb914aed1f72dd39a306c7b" ON "attestation_challenge" ("challenge") `); + await queryRunner.query(`CREATE TABLE "user_security_key" ("id" character varying NOT NULL, "userId" character varying(32) NOT NULL, "publicKey" character varying NOT NULL, "lastUsed" TIMESTAMP WITH TIME ZONE NOT NULL, "name" character varying(30) NOT NULL, CONSTRAINT "PK_3e508571121ab39c5f85d10c166" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE INDEX "IDX_ff9ca3b5f3ee3d0681367a9b44" ON "user_security_key" ("userId") `); + await queryRunner.query(`CREATE INDEX "IDX_0d7718e562dcedd0aa5cf2c9f7" ON "user_security_key" ("publicKey") `); + await queryRunner.query(`ALTER TABLE "user_profile" ADD "securityKeysAvailable" boolean NOT NULL DEFAULT false`); + await queryRunner.query(`ALTER TABLE "attestation_challenge" ADD CONSTRAINT "FK_f1a461a618fa1755692d0e0d592" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "user_security_key" ADD CONSTRAINT "FK_ff9ca3b5f3ee3d0681367a9b447" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "user_security_key" DROP CONSTRAINT "FK_ff9ca3b5f3ee3d0681367a9b447"`); + await queryRunner.query(`ALTER TABLE "attestation_challenge" DROP CONSTRAINT "FK_f1a461a618fa1755692d0e0d592"`); + await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "securityKeysAvailable"`); + await queryRunner.query(`DROP INDEX "IDX_0d7718e562dcedd0aa5cf2c9f7"`); + await queryRunner.query(`DROP INDEX "IDX_ff9ca3b5f3ee3d0681367a9b44"`); + await queryRunner.query(`DROP TABLE "user_security_key"`); + await queryRunner.query(`DROP INDEX "IDX_47efb914aed1f72dd39a306c7b"`); + await queryRunner.query(`DROP INDEX "IDX_f1a461a618fa1755692d0e0d59"`); + await queryRunner.query(`DROP TABLE "attestation_challenge"`); + } +} +exports.webauthn1561706992953 = webauthn1561706992953; diff --git a/packages/backend/migration/1561873850023-ChartIndexes.js b/packages/backend/migration/1561873850023-ChartIndexes.js new file mode 100644 index 000000000..559cb70cb --- /dev/null +++ b/packages/backend/migration/1561873850023-ChartIndexes.js @@ -0,0 +1,199 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class ChartIndexes1561873850023 { + async up(queryRunner) { + await queryRunner.query(`CREATE INDEX "IDX_0ad37b7ef50f4ddc84363d7ccc" ON "__chart__active_users" ("date") `); + await queryRunner.query(`CREATE INDEX "IDX_15e91a03aeeac9dbccdf43fc06" ON "__chart__active_users" ("span") `); + await queryRunner.query(`CREATE INDEX "IDX_00ed5f86db1f7efafb1978bf21" ON "__chart__active_users" ("group") `); + await queryRunner.query(`CREATE INDEX "IDX_20f57cc8f142c131340ee16742" ON "__chart__active_users" ("span", "date") `); + await queryRunner.query(`CREATE INDEX "IDX_9a3ed15a30ab7e3a37702e6e08" ON "__chart__active_users" ("date", "group") `); + await queryRunner.query(`CREATE INDEX "IDX_c26e2c1cbb6e911e0554b27416" ON "__chart__active_users" ("span", "date", "group") `); + await queryRunner.query(`CREATE INDEX "IDX_13565815f618a1ff53886c5b28" ON "__chart__drive" ("date") `); + await queryRunner.query(`CREATE INDEX "IDX_3fa0d0f17ca72e3dc80999a032" ON "__chart__drive" ("span") `); + await queryRunner.query(`CREATE INDEX "IDX_7a170f67425e62a8fabb76c872" ON "__chart__drive" ("group") `); + await queryRunner.query(`CREATE INDEX "IDX_6e1df243476e20cbf86572ecc0" ON "__chart__drive" ("span", "date") `); + await queryRunner.query(`CREATE INDEX "IDX_3313d7288855ec105b5bbf6c21" ON "__chart__drive" ("date", "group") `); + await queryRunner.query(`CREATE INDEX "IDX_06690fc959f1c9fdaf21928222" ON "__chart__drive" ("span", "date", "group") `); + await queryRunner.query(`CREATE INDEX "IDX_36cb699c49580d4e6c2e6159f9" ON "__chart__federation" ("date") `); + await queryRunner.query(`CREATE INDEX "IDX_e447064455928cf627590ef527" ON "__chart__federation" ("span") `); + await queryRunner.query(`CREATE INDEX "IDX_76e87c7bfc5d925fcbba405d84" ON "__chart__federation" ("group") `); + await queryRunner.query(`CREATE INDEX "IDX_2d416e6af791a82e338c79d480" ON "__chart__federation" ("span", "date") `); + await queryRunner.query(`CREATE INDEX "IDX_dd907becf76104e4b656659e6b" ON "__chart__federation" ("date", "group") `); + await queryRunner.query(`CREATE INDEX "IDX_e9cd07672b37d8966cf3709283" ON "__chart__federation" ("span", "date", "group") `); + await queryRunner.query(`CREATE INDEX "IDX_07747a1038c05f532a718fe1de" ON "__chart__hashtag" ("date") `); + await queryRunner.query(`CREATE INDEX "IDX_fcc181fb8283009c61cc4083ef" ON "__chart__hashtag" ("span") `); + await queryRunner.query(`CREATE INDEX "IDX_99a7d2faaef84a6f728d714ad6" ON "__chart__hashtag" ("group") `); + await queryRunner.query(`CREATE INDEX "IDX_49975586f50ed7b800fdd88fbd" ON "__chart__hashtag" ("span", "date") `); + await queryRunner.query(`CREATE INDEX "IDX_25a97c02003338124b2b75fdbc" ON "__chart__hashtag" ("date", "group") `); + await queryRunner.query(`CREATE INDEX "IDX_6d6f156ceefc6bc5f273a0e370" ON "__chart__hashtag" ("span", "date", "group") `); + await queryRunner.query(`CREATE INDEX "IDX_6b8f34a1a64b06014b6fb66824" ON "__chart__instance" ("date") `); + await queryRunner.query(`CREATE INDEX "IDX_c12f0af4a66cdd30c2287ce8aa" ON "__chart__instance" ("span") `); + await queryRunner.query(`CREATE INDEX "IDX_da8a46ba84ca1d8bb5a29bfb63" ON "__chart__instance" ("group") `); + await queryRunner.query(`CREATE INDEX "IDX_d0a4f79af5a97b08f37b547197" ON "__chart__instance" ("span", "date") `); + await queryRunner.query(`CREATE INDEX "IDX_39ee857ab2f23493037c6b6631" ON "__chart__instance" ("date", "group") `); + await queryRunner.query(`CREATE INDEX "IDX_f5448d9633cff74208d850aabe" ON "__chart__instance" ("span", "date", "group") `); + await queryRunner.query(`CREATE INDEX "IDX_a1efd3e0048a5f2793a47360dc" ON "__chart__network" ("date") `); + await queryRunner.query(`CREATE INDEX "IDX_f8dd01baeded2ffa833e0a610a" ON "__chart__network" ("span") `); + await queryRunner.query(`CREATE INDEX "IDX_7b5da130992ec9df96712d4290" ON "__chart__network" ("group") `); + await queryRunner.query(`CREATE INDEX "IDX_08fac0eb3b11f04c200c0b40dd" ON "__chart__network" ("span", "date") `); + await queryRunner.query(`CREATE INDEX "IDX_0a905b992fecd2b5c3fb98759e" ON "__chart__network" ("date", "group") `); + await queryRunner.query(`CREATE INDEX "IDX_9ff6944f01acb756fdc92d7563" ON "__chart__network" ("span", "date", "group") `); + await queryRunner.query(`CREATE INDEX "IDX_42eb716a37d381cdf566192b2b" ON "__chart__notes" ("date") `); + await queryRunner.query(`CREATE INDEX "IDX_e69096589f11e3baa98ddd64d0" ON "__chart__notes" ("span") `); + await queryRunner.query(`CREATE INDEX "IDX_7036f2957151588b813185c794" ON "__chart__notes" ("group") `); + await queryRunner.query(`CREATE INDEX "IDX_0c9a159c5082cbeef3ca6706b5" ON "__chart__notes" ("span", "date") `); + await queryRunner.query(`CREATE INDEX "IDX_f09d543e3acb16c5976bdb31fa" ON "__chart__notes" ("date", "group") `); + await queryRunner.query(`CREATE INDEX "IDX_924fc196c80ca24bae01dd37e4" ON "__chart__notes" ("span", "date", "group") `); + await queryRunner.query(`CREATE INDEX "IDX_5f86db6492274e07c1a3cdf286" ON "__chart__per_user_drive" ("date") `); + await queryRunner.query(`CREATE INDEX "IDX_328f259961e60c4fa0bfcf55ca" ON "__chart__per_user_drive" ("span") `); + await queryRunner.query(`CREATE INDEX "IDX_e496ca8096d28f6b9b509264dc" ON "__chart__per_user_drive" ("group") `); + await queryRunner.query(`CREATE INDEX "IDX_42ea9381f0fda8dfe0fa1c8b53" ON "__chart__per_user_drive" ("span", "date") `); + await queryRunner.query(`CREATE INDEX "IDX_30bf67687f483ace115c5ca642" ON "__chart__per_user_drive" ("date", "group") `); + await queryRunner.query(`CREATE INDEX "IDX_f2aeafde2ae6fbad38e857631b" ON "__chart__per_user_drive" ("span", "date", "group") `); + await queryRunner.query(`CREATE INDEX "IDX_7af07790712aa3438ff6773f3b" ON "__chart__per_user_following" ("date") `); + await queryRunner.query(`CREATE INDEX "IDX_f92dd6d03f8d994f29987f6214" ON "__chart__per_user_following" ("span") `); + await queryRunner.query(`CREATE INDEX "IDX_4b3593098b6edc9c5afe36b18b" ON "__chart__per_user_following" ("group") `); + await queryRunner.query(`CREATE INDEX "IDX_57b5458d0d3d6d1e7f13d4e57f" ON "__chart__per_user_following" ("span", "date") `); + await queryRunner.query(`CREATE INDEX "IDX_b77d4dd9562c3a899d9a286fcd" ON "__chart__per_user_following" ("date", "group") `); + await queryRunner.query(`CREATE INDEX "IDX_4db3b84c7be0d3464714f3e0b1" ON "__chart__per_user_following" ("span", "date", "group") `); + await queryRunner.query(`CREATE INDEX "IDX_84234bd1abb873f07329681c83" ON "__chart__per_user_notes" ("date") `); + await queryRunner.query(`CREATE INDEX "IDX_8d2cbbc8114d90d19b44d626b6" ON "__chart__per_user_notes" ("span") `); + await queryRunner.query(`CREATE INDEX "IDX_55bf20f366979f2436de99206b" ON "__chart__per_user_notes" ("group") `); + await queryRunner.query(`CREATE INDEX "IDX_046feeb12e9ef5f783f409866a" ON "__chart__per_user_notes" ("span", "date") `); + await queryRunner.query(`CREATE INDEX "IDX_5048e9daccbbbc6d567bb142d3" ON "__chart__per_user_notes" ("date", "group") `); + await queryRunner.query(`CREATE INDEX "IDX_f68a5ab958f9f5fa17a32ac23b" ON "__chart__per_user_notes" ("span", "date", "group") `); + await queryRunner.query(`CREATE INDEX "IDX_f7bf4c62059764c2c2bb40fdab" ON "__chart__per_user_reaction" ("date") `); + await queryRunner.query(`CREATE INDEX "IDX_65633a106bce43fc7c5c30a5c7" ON "__chart__per_user_reaction" ("span") `); + await queryRunner.query(`CREATE INDEX "IDX_8cf3156fd7a6b15c43459c6e3b" ON "__chart__per_user_reaction" ("group") `); + await queryRunner.query(`CREATE INDEX "IDX_edeb73c09c3143a81bcb34d569" ON "__chart__per_user_reaction" ("span", "date") `); + await queryRunner.query(`CREATE INDEX "IDX_229a41ad465f9205f1f5703291" ON "__chart__per_user_reaction" ("date", "group") `); + await queryRunner.query(`CREATE INDEX "IDX_e316f01a6d24eb31db27f88262" ON "__chart__per_user_reaction" ("span", "date", "group") `); + await queryRunner.query(`CREATE INDEX "IDX_0c641990ecf47d2545df4edb75" ON "__chart__test_grouped" ("date") `); + await queryRunner.query(`CREATE INDEX "IDX_2be7ec6cebddc14dc11e206686" ON "__chart__test_grouped" ("span") `); + await queryRunner.query(`CREATE INDEX "IDX_234dff3c0b56a6150b95431ab9" ON "__chart__test_grouped" ("group") `); + await queryRunner.query(`CREATE INDEX "IDX_a5133470f4825902e170328ca5" ON "__chart__test_grouped" ("span", "date") `); + await queryRunner.query(`CREATE INDEX "IDX_b14489029e4b3aaf4bba5fb524" ON "__chart__test_grouped" ("date", "group") `); + await queryRunner.query(`CREATE INDEX "IDX_84e661abb7bd1e51b690d4b017" ON "__chart__test_grouped" ("span", "date", "group") `); + await queryRunner.query(`CREATE INDEX "IDX_437bab3c6061d90f6bb65fd2cc" ON "__chart__test_unique" ("date") `); + await queryRunner.query(`CREATE INDEX "IDX_5c73bf61da4f6e6f15bae88ed1" ON "__chart__test_unique" ("span") `); + await queryRunner.query(`CREATE INDEX "IDX_bbfa573a8181018851ed0b6357" ON "__chart__test_unique" ("group") `); + await queryRunner.query(`CREATE INDEX "IDX_d70c86baedc68326be11f9c0ce" ON "__chart__test_unique" ("span", "date") `); + await queryRunner.query(`CREATE INDEX "IDX_a0cd75442dd10d0643a17c4a49" ON "__chart__test_unique" ("date", "group") `); + await queryRunner.query(`CREATE INDEX "IDX_66e1e1ecd2f29e57778af35b59" ON "__chart__test_unique" ("span", "date", "group") `); + await queryRunner.query(`CREATE INDEX "IDX_b070a906db04b44c67c6c2144d" ON "__chart__test" ("date") `); + await queryRunner.query(`CREATE INDEX "IDX_92255988735563f0fe4aba1f05" ON "__chart__test" ("span") `); + await queryRunner.query(`CREATE INDEX "IDX_d41cce6aee1a50bfc062038f9b" ON "__chart__test" ("group") `); + await queryRunner.query(`CREATE INDEX "IDX_c5870993e25c3d5771f91f5003" ON "__chart__test" ("span", "date") `); + await queryRunner.query(`CREATE INDEX "IDX_a319e5dbf47e8a17497623beae" ON "__chart__test" ("date", "group") `); + await queryRunner.query(`CREATE INDEX "IDX_f170de677ea75ad4533de2723e" ON "__chart__test" ("span", "date", "group") `); + await queryRunner.query(`CREATE INDEX "IDX_845254b3eaf708ae8a6cac3026" ON "__chart__users" ("date") `); + await queryRunner.query(`CREATE INDEX "IDX_7c184198ecf66a8d3ecb253ab3" ON "__chart__users" ("span") `); + await queryRunner.query(`CREATE INDEX "IDX_ed9b95919c672a13008e9487ee" ON "__chart__users" ("group") `); + await queryRunner.query(`CREATE INDEX "IDX_f091abb24193d50c653c6b77fc" ON "__chart__users" ("span", "date") `); + await queryRunner.query(`CREATE INDEX "IDX_337e9599f278bd7537fe30876f" ON "__chart__users" ("date", "group") `); + await queryRunner.query(`CREATE INDEX "IDX_a770a57c70e668cc61590c9161" ON "__chart__users" ("span", "date", "group") `); + } + async down(queryRunner) { + await queryRunner.query(`DROP INDEX "IDX_a770a57c70e668cc61590c9161"`); + await queryRunner.query(`DROP INDEX "IDX_337e9599f278bd7537fe30876f"`); + await queryRunner.query(`DROP INDEX "IDX_f091abb24193d50c653c6b77fc"`); + await queryRunner.query(`DROP INDEX "IDX_ed9b95919c672a13008e9487ee"`); + await queryRunner.query(`DROP INDEX "IDX_7c184198ecf66a8d3ecb253ab3"`); + await queryRunner.query(`DROP INDEX "IDX_845254b3eaf708ae8a6cac3026"`); + await queryRunner.query(`DROP INDEX "IDX_f170de677ea75ad4533de2723e"`); + await queryRunner.query(`DROP INDEX "IDX_a319e5dbf47e8a17497623beae"`); + await queryRunner.query(`DROP INDEX "IDX_c5870993e25c3d5771f91f5003"`); + await queryRunner.query(`DROP INDEX "IDX_d41cce6aee1a50bfc062038f9b"`); + await queryRunner.query(`DROP INDEX "IDX_92255988735563f0fe4aba1f05"`); + await queryRunner.query(`DROP INDEX "IDX_b070a906db04b44c67c6c2144d"`); + await queryRunner.query(`DROP INDEX "IDX_66e1e1ecd2f29e57778af35b59"`); + await queryRunner.query(`DROP INDEX "IDX_a0cd75442dd10d0643a17c4a49"`); + await queryRunner.query(`DROP INDEX "IDX_d70c86baedc68326be11f9c0ce"`); + await queryRunner.query(`DROP INDEX "IDX_bbfa573a8181018851ed0b6357"`); + await queryRunner.query(`DROP INDEX "IDX_5c73bf61da4f6e6f15bae88ed1"`); + await queryRunner.query(`DROP INDEX "IDX_437bab3c6061d90f6bb65fd2cc"`); + await queryRunner.query(`DROP INDEX "IDX_84e661abb7bd1e51b690d4b017"`); + await queryRunner.query(`DROP INDEX "IDX_b14489029e4b3aaf4bba5fb524"`); + await queryRunner.query(`DROP INDEX "IDX_a5133470f4825902e170328ca5"`); + await queryRunner.query(`DROP INDEX "IDX_234dff3c0b56a6150b95431ab9"`); + await queryRunner.query(`DROP INDEX "IDX_2be7ec6cebddc14dc11e206686"`); + await queryRunner.query(`DROP INDEX "IDX_0c641990ecf47d2545df4edb75"`); + await queryRunner.query(`DROP INDEX "IDX_e316f01a6d24eb31db27f88262"`); + await queryRunner.query(`DROP INDEX "IDX_229a41ad465f9205f1f5703291"`); + await queryRunner.query(`DROP INDEX "IDX_edeb73c09c3143a81bcb34d569"`); + await queryRunner.query(`DROP INDEX "IDX_8cf3156fd7a6b15c43459c6e3b"`); + await queryRunner.query(`DROP INDEX "IDX_65633a106bce43fc7c5c30a5c7"`); + await queryRunner.query(`DROP INDEX "IDX_f7bf4c62059764c2c2bb40fdab"`); + await queryRunner.query(`DROP INDEX "IDX_f68a5ab958f9f5fa17a32ac23b"`); + await queryRunner.query(`DROP INDEX "IDX_5048e9daccbbbc6d567bb142d3"`); + await queryRunner.query(`DROP INDEX "IDX_046feeb12e9ef5f783f409866a"`); + await queryRunner.query(`DROP INDEX "IDX_55bf20f366979f2436de99206b"`); + await queryRunner.query(`DROP INDEX "IDX_8d2cbbc8114d90d19b44d626b6"`); + await queryRunner.query(`DROP INDEX "IDX_84234bd1abb873f07329681c83"`); + await queryRunner.query(`DROP INDEX "IDX_4db3b84c7be0d3464714f3e0b1"`); + await queryRunner.query(`DROP INDEX "IDX_b77d4dd9562c3a899d9a286fcd"`); + await queryRunner.query(`DROP INDEX "IDX_57b5458d0d3d6d1e7f13d4e57f"`); + await queryRunner.query(`DROP INDEX "IDX_4b3593098b6edc9c5afe36b18b"`); + await queryRunner.query(`DROP INDEX "IDX_f92dd6d03f8d994f29987f6214"`); + await queryRunner.query(`DROP INDEX "IDX_7af07790712aa3438ff6773f3b"`); + await queryRunner.query(`DROP INDEX "IDX_f2aeafde2ae6fbad38e857631b"`); + await queryRunner.query(`DROP INDEX "IDX_30bf67687f483ace115c5ca642"`); + await queryRunner.query(`DROP INDEX "IDX_42ea9381f0fda8dfe0fa1c8b53"`); + await queryRunner.query(`DROP INDEX "IDX_e496ca8096d28f6b9b509264dc"`); + await queryRunner.query(`DROP INDEX "IDX_328f259961e60c4fa0bfcf55ca"`); + await queryRunner.query(`DROP INDEX "IDX_5f86db6492274e07c1a3cdf286"`); + await queryRunner.query(`DROP INDEX "IDX_924fc196c80ca24bae01dd37e4"`); + await queryRunner.query(`DROP INDEX "IDX_f09d543e3acb16c5976bdb31fa"`); + await queryRunner.query(`DROP INDEX "IDX_0c9a159c5082cbeef3ca6706b5"`); + await queryRunner.query(`DROP INDEX "IDX_7036f2957151588b813185c794"`); + await queryRunner.query(`DROP INDEX "IDX_e69096589f11e3baa98ddd64d0"`); + await queryRunner.query(`DROP INDEX "IDX_42eb716a37d381cdf566192b2b"`); + await queryRunner.query(`DROP INDEX "IDX_9ff6944f01acb756fdc92d7563"`); + await queryRunner.query(`DROP INDEX "IDX_0a905b992fecd2b5c3fb98759e"`); + await queryRunner.query(`DROP INDEX "IDX_08fac0eb3b11f04c200c0b40dd"`); + await queryRunner.query(`DROP INDEX "IDX_7b5da130992ec9df96712d4290"`); + await queryRunner.query(`DROP INDEX "IDX_f8dd01baeded2ffa833e0a610a"`); + await queryRunner.query(`DROP INDEX "IDX_a1efd3e0048a5f2793a47360dc"`); + await queryRunner.query(`DROP INDEX "IDX_f5448d9633cff74208d850aabe"`); + await queryRunner.query(`DROP INDEX "IDX_39ee857ab2f23493037c6b6631"`); + await queryRunner.query(`DROP INDEX "IDX_d0a4f79af5a97b08f37b547197"`); + await queryRunner.query(`DROP INDEX "IDX_da8a46ba84ca1d8bb5a29bfb63"`); + await queryRunner.query(`DROP INDEX "IDX_c12f0af4a66cdd30c2287ce8aa"`); + await queryRunner.query(`DROP INDEX "IDX_6b8f34a1a64b06014b6fb66824"`); + await queryRunner.query(`DROP INDEX "IDX_6d6f156ceefc6bc5f273a0e370"`); + await queryRunner.query(`DROP INDEX "IDX_25a97c02003338124b2b75fdbc"`); + await queryRunner.query(`DROP INDEX "IDX_49975586f50ed7b800fdd88fbd"`); + await queryRunner.query(`DROP INDEX "IDX_99a7d2faaef84a6f728d714ad6"`); + await queryRunner.query(`DROP INDEX "IDX_fcc181fb8283009c61cc4083ef"`); + await queryRunner.query(`DROP INDEX "IDX_07747a1038c05f532a718fe1de"`); + await queryRunner.query(`DROP INDEX "IDX_e9cd07672b37d8966cf3709283"`); + await queryRunner.query(`DROP INDEX "IDX_dd907becf76104e4b656659e6b"`); + await queryRunner.query(`DROP INDEX "IDX_2d416e6af791a82e338c79d480"`); + await queryRunner.query(`DROP INDEX "IDX_76e87c7bfc5d925fcbba405d84"`); + await queryRunner.query(`DROP INDEX "IDX_e447064455928cf627590ef527"`); + await queryRunner.query(`DROP INDEX "IDX_36cb699c49580d4e6c2e6159f9"`); + await queryRunner.query(`DROP INDEX "IDX_06690fc959f1c9fdaf21928222"`); + await queryRunner.query(`DROP INDEX "IDX_3313d7288855ec105b5bbf6c21"`); + await queryRunner.query(`DROP INDEX "IDX_6e1df243476e20cbf86572ecc0"`); + await queryRunner.query(`DROP INDEX "IDX_7a170f67425e62a8fabb76c872"`); + await queryRunner.query(`DROP INDEX "IDX_3fa0d0f17ca72e3dc80999a032"`); + await queryRunner.query(`DROP INDEX "IDX_13565815f618a1ff53886c5b28"`); + await queryRunner.query(`DROP INDEX "IDX_c26e2c1cbb6e911e0554b27416"`); + await queryRunner.query(`DROP INDEX "IDX_9a3ed15a30ab7e3a37702e6e08"`); + await queryRunner.query(`DROP INDEX "IDX_20f57cc8f142c131340ee16742"`); + await queryRunner.query(`DROP INDEX "IDX_00ed5f86db1f7efafb1978bf21"`); + await queryRunner.query(`DROP INDEX "IDX_15e91a03aeeac9dbccdf43fc06"`); + await queryRunner.query(`DROP INDEX "IDX_0ad37b7ef50f4ddc84363d7ccc"`); + await queryRunner.query(`DROP INDEX "IDX_90148bbc2bf0854428786bfc15"`); + await queryRunner.query(`DROP INDEX "IDX_88937d94d7443d9a99a76fa5c0"`); + await queryRunner.query(`DROP INDEX "IDX_54ebcb6d27222913b908d56fd8"`); + await queryRunner.query(`DROP INDEX "IDX_796a8c03959361f97dc2be1d5c"`); + await queryRunner.query(`DROP INDEX "IDX_25dfc71b0369b003a4cd434d0b"`); + await queryRunner.query(`DROP INDEX "IDX_51c063b6a133a9cb87145450f5"`); + await queryRunner.query(`DROP INDEX "IDX_fa99d777623947a5b05f394cae"`); + await queryRunner.query(`DROP INDEX "IDX_315c779174fe8247ab324f036e"`); + await queryRunner.query(`DROP INDEX "IDX_c5d46cbfda48b1c33ed852e21b"`); + await queryRunner.query(`DROP INDEX "IDX_8cb40cfc8f3c28261e6f887b03"`); + } +} +exports.ChartIndexes1561873850023 = ChartIndexes1561873850023; diff --git a/packages/backend/migration/1562422242907-PasswordLessLogin.js b/packages/backend/migration/1562422242907-PasswordLessLogin.js new file mode 100644 index 000000000..bed879ade --- /dev/null +++ b/packages/backend/migration/1562422242907-PasswordLessLogin.js @@ -0,0 +1,11 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class PasswordLessLogin1562422242907 { + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "user_profile" ADD COLUMN "usePasswordLessLogin" boolean DEFAULT false NOT NULL`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "usePasswordLessLogin"`); + } +} +exports.PasswordLessLogin1562422242907 = PasswordLessLogin1562422242907; diff --git a/packages/backend/migration/1562444565093-PinnedPage.js b/packages/backend/migration/1562444565093-PinnedPage.js new file mode 100644 index 000000000..f0aac3a4b --- /dev/null +++ b/packages/backend/migration/1562444565093-PinnedPage.js @@ -0,0 +1,15 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class PinnedPage1562444565093 { + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "user_profile" ADD "pinnedPageId" character varying(32)`); + await queryRunner.query(`ALTER TABLE "user_profile" ADD CONSTRAINT "UQ_6dc44f1ceb65b1e72bacef2ca27" UNIQUE ("pinnedPageId")`); + await queryRunner.query(`ALTER TABLE "user_profile" ADD CONSTRAINT "FK_6dc44f1ceb65b1e72bacef2ca27" FOREIGN KEY ("pinnedPageId") REFERENCES "page"("id") ON DELETE SET NULL ON UPDATE NO ACTION`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "user_profile" DROP CONSTRAINT "FK_6dc44f1ceb65b1e72bacef2ca27"`); + await queryRunner.query(`ALTER TABLE "user_profile" DROP CONSTRAINT "UQ_6dc44f1ceb65b1e72bacef2ca27"`); + await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "pinnedPageId"`); + } +} +exports.PinnedPage1562444565093 = PinnedPage1562444565093; diff --git a/packages/backend/migration/1562448332510-PageTitleHideOption.js b/packages/backend/migration/1562448332510-PageTitleHideOption.js new file mode 100644 index 000000000..238b74226 --- /dev/null +++ b/packages/backend/migration/1562448332510-PageTitleHideOption.js @@ -0,0 +1,11 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class PageTitleHideOption1562448332510 { + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "page" ADD "hideTitleWhenPinned" boolean NOT NULL DEFAULT false`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "page" DROP COLUMN "hideTitleWhenPinned"`); + } +} +exports.PageTitleHideOption1562448332510 = PageTitleHideOption1562448332510; diff --git a/packages/backend/migration/1562869971568-ModerationLog.js b/packages/backend/migration/1562869971568-ModerationLog.js new file mode 100644 index 000000000..c8953c513 --- /dev/null +++ b/packages/backend/migration/1562869971568-ModerationLog.js @@ -0,0 +1,15 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class ModerationLog1562869971568 { + async up(queryRunner) { + await queryRunner.query(`CREATE TABLE "moderation_log" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "type" character varying(128) NOT NULL, "info" jsonb NOT NULL, CONSTRAINT "PK_d0adca6ecfd068db83e4526cc26" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE INDEX "IDX_a08ad074601d204e0f69da9a95" ON "moderation_log" ("userId") `); + await queryRunner.query(`ALTER TABLE "moderation_log" ADD CONSTRAINT "FK_a08ad074601d204e0f69da9a954" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "moderation_log" DROP CONSTRAINT "FK_a08ad074601d204e0f69da9a954"`); + await queryRunner.query(`DROP INDEX "IDX_a08ad074601d204e0f69da9a95"`); + await queryRunner.query(`DROP TABLE "moderation_log"`); + } +} +exports.ModerationLog1562869971568 = ModerationLog1562869971568; diff --git a/packages/backend/migration/1563757595828-UsedUsername.js b/packages/backend/migration/1563757595828-UsedUsername.js new file mode 100644 index 000000000..0e59fdd45 --- /dev/null +++ b/packages/backend/migration/1563757595828-UsedUsername.js @@ -0,0 +1,11 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class UsedUsername1563757595828 { + async up(queryRunner) { + await queryRunner.query(`CREATE TABLE "used_username" ("username" character varying(128) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, CONSTRAINT "PK_78fd79d2d24c6ac2f4cc9a31a5d" PRIMARY KEY ("username"))`); + } + async down(queryRunner) { + await queryRunner.query(`DROP TABLE "used_username"`); + } +} +exports.UsedUsername1563757595828 = UsedUsername1563757595828; diff --git a/packages/backend/migration/1565634203341-room.js b/packages/backend/migration/1565634203341-room.js new file mode 100644 index 000000000..49ca5ea50 --- /dev/null +++ b/packages/backend/migration/1565634203341-room.js @@ -0,0 +1,11 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class room1565634203341 { + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "user_profile" ADD "room" jsonb NOT NULL DEFAULT '{}'`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "room"`); + } +} +exports.room1565634203341 = room1565634203341; diff --git a/packages/backend/migration/1571220798684-CustomEmojiCategory.js b/packages/backend/migration/1571220798684-CustomEmojiCategory.js new file mode 100644 index 000000000..c67c437de --- /dev/null +++ b/packages/backend/migration/1571220798684-CustomEmojiCategory.js @@ -0,0 +1,11 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class CustomEmojiCategory1571220798684 { + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "emoji" ADD "category" character varying(128)`, undefined); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "emoji" DROP COLUMN "category"`, undefined); + } +} +exports.CustomEmojiCategory1571220798684 = CustomEmojiCategory1571220798684; diff --git a/packages/backend/migration/1572760203493-nodeinfo.js b/packages/backend/migration/1572760203493-nodeinfo.js new file mode 100644 index 000000000..a3ca5d718 --- /dev/null +++ b/packages/backend/migration/1572760203493-nodeinfo.js @@ -0,0 +1,27 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class nodeinfo1572760203493 { + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "system"`, undefined); + await queryRunner.query(`ALTER TABLE "instance" ADD "softwareName" character varying(64) DEFAULT null`, undefined); + await queryRunner.query(`ALTER TABLE "instance" ADD "softwareVersion" character varying(64) DEFAULT null`, undefined); + await queryRunner.query(`ALTER TABLE "instance" ADD "openRegistrations" boolean DEFAULT null`, undefined); + await queryRunner.query(`ALTER TABLE "instance" ADD "name" character varying(256) DEFAULT null`, undefined); + await queryRunner.query(`ALTER TABLE "instance" ADD "description" character varying(4096) DEFAULT null`, undefined); + await queryRunner.query(`ALTER TABLE "instance" ADD "maintainerName" character varying(128) DEFAULT null`, undefined); + await queryRunner.query(`ALTER TABLE "instance" ADD "maintainerEmail" character varying(256) DEFAULT null`, undefined); + await queryRunner.query(`ALTER TABLE "instance" ADD "infoUpdatedAt" TIMESTAMP WITH TIME ZONE`, undefined); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "infoUpdatedAt"`, undefined); + await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "maintainerEmail"`, undefined); + await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "maintainerName"`, undefined); + await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "description"`, undefined); + await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "name"`, undefined); + await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "openRegistrations"`, undefined); + await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "softwareVersion"`, undefined); + await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "softwareName"`, undefined); + await queryRunner.query(`ALTER TABLE "instance" ADD "system" character varying(64)`, undefined); + } +} +exports.nodeinfo1572760203493 = nodeinfo1572760203493; diff --git a/packages/backend/migration/1576269851876-TalkFederationId.js b/packages/backend/migration/1576269851876-TalkFederationId.js new file mode 100644 index 000000000..63a8f8a9a --- /dev/null +++ b/packages/backend/migration/1576269851876-TalkFederationId.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class TalkFederationId1576269851876 { + constructor() { + this.name = 'TalkFederationId1576269851876'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "messaging_message" ADD "uri" character varying(512)`, undefined); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "messaging_message" DROP COLUMN "uri"`, undefined); + } +} +exports.TalkFederationId1576269851876 = TalkFederationId1576269851876; diff --git a/packages/backend/migration/1576869585998-ProxyRemoteFiles.js b/packages/backend/migration/1576869585998-ProxyRemoteFiles.js new file mode 100644 index 000000000..867ae3d6e --- /dev/null +++ b/packages/backend/migration/1576869585998-ProxyRemoteFiles.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class ProxyRemoteFiles1576869585998 { + constructor() { + this.name = 'ProxyRemoteFiles1576869585998'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" ADD "proxyRemoteFiles" boolean NOT NULL DEFAULT false`, undefined); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "proxyRemoteFiles"`, undefined); + } +} +exports.ProxyRemoteFiles1576869585998 = ProxyRemoteFiles1576869585998; diff --git a/packages/backend/migration/1579267006611-v12.js b/packages/backend/migration/1579267006611-v12.js new file mode 100644 index 000000000..ccc524773 --- /dev/null +++ b/packages/backend/migration/1579267006611-v12.js @@ -0,0 +1,34 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class v121579267006611 { + constructor() { + this.name = 'v121579267006611'; + } + async up(queryRunner) { + await queryRunner.query(`CREATE TABLE "announcement" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "text" character varying(8192) NOT NULL, "title" character varying(256) NOT NULL, "imageUrl" character varying(1024), CONSTRAINT "PK_e0ef0550174fd1099a308fd18a0" PRIMARY KEY ("id"))`, undefined); + await queryRunner.query(`CREATE INDEX "IDX_118ec703e596086fc4515acb39" ON "announcement" ("createdAt") `, undefined); + await queryRunner.query(`CREATE TABLE "announcement_read" ("id" character varying(32) NOT NULL, "userId" character varying(32) NOT NULL, "announcementId" character varying(32) NOT NULL, CONSTRAINT "PK_4b90ad1f42681d97b2683890c5e" PRIMARY KEY ("id"))`, undefined); + await queryRunner.query(`CREATE INDEX "IDX_8288151386172b8109f7239ab2" ON "announcement_read" ("userId") `, undefined); + await queryRunner.query(`CREATE INDEX "IDX_603a7b1e7aa0533c6c88e9bfaf" ON "announcement_read" ("announcementId") `, undefined); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_924fa71815cfa3941d003702a0" ON "announcement_read" ("userId", "announcementId") `, undefined); + await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "isVerified"`, undefined); + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "announcements"`, undefined); + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "enableEmojiReaction"`, undefined); + await queryRunner.query(`ALTER TABLE "announcement_read" ADD CONSTRAINT "FK_8288151386172b8109f7239ab28" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined); + await queryRunner.query(`ALTER TABLE "announcement_read" ADD CONSTRAINT "FK_603a7b1e7aa0533c6c88e9bfafe" FOREIGN KEY ("announcementId") REFERENCES "announcement"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "announcement_read" DROP CONSTRAINT "FK_603a7b1e7aa0533c6c88e9bfafe"`, undefined); + await queryRunner.query(`ALTER TABLE "announcement_read" DROP CONSTRAINT "FK_8288151386172b8109f7239ab28"`, undefined); + await queryRunner.query(`ALTER TABLE "meta" ADD "enableEmojiReaction" boolean NOT NULL DEFAULT true`, undefined); + await queryRunner.query(`ALTER TABLE "meta" ADD "announcements" jsonb NOT NULL DEFAULT '[]'`, undefined); + await queryRunner.query(`ALTER TABLE "user" ADD "isVerified" boolean NOT NULL DEFAULT false`, undefined); + await queryRunner.query(`DROP INDEX "IDX_924fa71815cfa3941d003702a0"`, undefined); + await queryRunner.query(`DROP INDEX "IDX_603a7b1e7aa0533c6c88e9bfaf"`, undefined); + await queryRunner.query(`DROP INDEX "IDX_8288151386172b8109f7239ab2"`, undefined); + await queryRunner.query(`DROP TABLE "announcement_read"`, undefined); + await queryRunner.query(`DROP INDEX "IDX_118ec703e596086fc4515acb39"`, undefined); + await queryRunner.query(`DROP TABLE "announcement"`, undefined); + } +} +exports.v121579267006611 = v121579267006611; diff --git a/packages/backend/migration/1579270193251-v12-2.js b/packages/backend/migration/1579270193251-v12-2.js new file mode 100644 index 000000000..7f67645aa --- /dev/null +++ b/packages/backend/migration/1579270193251-v12-2.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class v1221579270193251 { + constructor() { + this.name = 'v1221579270193251'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "announcement_read" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`, undefined); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "announcement_read" DROP COLUMN "createdAt"`, undefined); + } +} +exports.v1221579270193251 = v1221579270193251; diff --git a/packages/backend/migration/1579282808087-v12-3.js b/packages/backend/migration/1579282808087-v12-3.js new file mode 100644 index 000000000..80fa234a5 --- /dev/null +++ b/packages/backend/migration/1579282808087-v12-3.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class v1231579282808087 { + constructor() { + this.name = 'v1231579282808087'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "announcement" ADD "updatedAt" TIMESTAMP WITH TIME ZONE`, undefined); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "announcement" DROP COLUMN "updatedAt"`, undefined); + } +} +exports.v1231579282808087 = v1231579282808087; diff --git a/packages/backend/migration/1579544426412-v12-4.js b/packages/backend/migration/1579544426412-v12-4.js new file mode 100644 index 000000000..ef2b804f5 --- /dev/null +++ b/packages/backend/migration/1579544426412-v12-4.js @@ -0,0 +1,16 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class v1241579544426412 { + constructor() { + this.name = 'v1241579544426412'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "notification" ADD "followRequestId" character varying(32)`, undefined); + await queryRunner.query(`ALTER TABLE "notification" ADD CONSTRAINT "FK_bd7fab507621e635b32cd31892c" FOREIGN KEY ("followRequestId") REFERENCES "follow_request"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "notification" DROP CONSTRAINT "FK_bd7fab507621e635b32cd31892c"`, undefined); + await queryRunner.query(`ALTER TABLE "notification" DROP COLUMN "followRequestId"`, undefined); + } +} +exports.v1241579544426412 = v1241579544426412; diff --git a/packages/backend/migration/1579977526288-v12-5.js b/packages/backend/migration/1579977526288-v12-5.js new file mode 100644 index 000000000..1d2ed0966 --- /dev/null +++ b/packages/backend/migration/1579977526288-v12-5.js @@ -0,0 +1,54 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class v1251579977526288 { + constructor() { + this.name = 'v1251579977526288'; + } + async up(queryRunner) { + await queryRunner.query(`CREATE TABLE "clip" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "name" character varying(128) NOT NULL, "isPublic" boolean NOT NULL DEFAULT false, CONSTRAINT "PK_f0685dac8d4dd056d7255670b75" PRIMARY KEY ("id"))`, undefined); + await queryRunner.query(`CREATE INDEX "IDX_2b5ec6c574d6802c94c80313fb" ON "clip" ("userId") `, undefined); + await queryRunner.query(`CREATE TABLE "clip_note" ("id" character varying(32) NOT NULL, "noteId" character varying(32) NOT NULL, "clipId" character varying(32) NOT NULL, CONSTRAINT "PK_e94cda2f40a99b57e032a1a738b" PRIMARY KEY ("id"))`, undefined); + await queryRunner.query(`CREATE INDEX "IDX_a012eaf5c87c65da1deb5fdbfa" ON "clip_note" ("noteId") `, undefined); + await queryRunner.query(`CREATE INDEX "IDX_ebe99317bbbe9968a0c6f579ad" ON "clip_note" ("clipId") `, undefined); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_6fc0ec357d55a18646262fdfff" ON "clip_note" ("noteId", "clipId") `, undefined); + await queryRunner.query(`CREATE TYPE "antenna_src_enum" AS ENUM('home', 'all', 'list')`, undefined); + await queryRunner.query(`CREATE TABLE "antenna" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "name" character varying(128) NOT NULL, "src" "antenna_src_enum" NOT NULL, "userListId" character varying(32), "keywords" jsonb NOT NULL DEFAULT '[]', "withFile" boolean NOT NULL, "expression" character varying(2048), "notify" boolean NOT NULL, "hasNewNote" boolean NOT NULL DEFAULT false, CONSTRAINT "PK_c170b99775e1dccca947c9f2d5f" PRIMARY KEY ("id"))`, undefined); + await queryRunner.query(`CREATE INDEX "IDX_6446c571a0e8d0f05f01c78909" ON "antenna" ("userId") `, undefined); + await queryRunner.query(`CREATE TABLE "antenna_note" ("id" character varying(32) NOT NULL, "noteId" character varying(32) NOT NULL, "antennaId" character varying(32) NOT NULL, CONSTRAINT "PK_fb28d94d0989a3872df19fd6ef8" PRIMARY KEY ("id"))`, undefined); + await queryRunner.query(`CREATE INDEX "IDX_bd0397be22147e17210940e125" ON "antenna_note" ("noteId") `, undefined); + await queryRunner.query(`CREATE INDEX "IDX_0d775946662d2575dfd2068a5f" ON "antenna_note" ("antennaId") `, undefined); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_335a0bf3f904406f9ef3dd51c2" ON "antenna_note" ("noteId", "antennaId") `, undefined); + await queryRunner.query(`ALTER TABLE "note" DROP COLUMN "geo"`, undefined); + await queryRunner.query(`ALTER TABLE "clip" ADD CONSTRAINT "FK_2b5ec6c574d6802c94c80313fb2" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined); + await queryRunner.query(`ALTER TABLE "clip_note" ADD CONSTRAINT "FK_a012eaf5c87c65da1deb5fdbfa3" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined); + await queryRunner.query(`ALTER TABLE "clip_note" ADD CONSTRAINT "FK_ebe99317bbbe9968a0c6f579adf" FOREIGN KEY ("clipId") REFERENCES "clip"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined); + await queryRunner.query(`ALTER TABLE "antenna" ADD CONSTRAINT "FK_6446c571a0e8d0f05f01c789096" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined); + await queryRunner.query(`ALTER TABLE "antenna" ADD CONSTRAINT "FK_709d7d32053d0dd7620f678eeb9" FOREIGN KEY ("userListId") REFERENCES "user_list"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined); + await queryRunner.query(`ALTER TABLE "antenna_note" ADD CONSTRAINT "FK_bd0397be22147e17210940e125b" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined); + await queryRunner.query(`ALTER TABLE "antenna_note" ADD CONSTRAINT "FK_0d775946662d2575dfd2068a5f5" FOREIGN KEY ("antennaId") REFERENCES "antenna"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "antenna_note" DROP CONSTRAINT "FK_0d775946662d2575dfd2068a5f5"`, undefined); + await queryRunner.query(`ALTER TABLE "antenna_note" DROP CONSTRAINT "FK_bd0397be22147e17210940e125b"`, undefined); + await queryRunner.query(`ALTER TABLE "antenna" DROP CONSTRAINT "FK_709d7d32053d0dd7620f678eeb9"`, undefined); + await queryRunner.query(`ALTER TABLE "antenna" DROP CONSTRAINT "FK_6446c571a0e8d0f05f01c789096"`, undefined); + await queryRunner.query(`ALTER TABLE "clip_note" DROP CONSTRAINT "FK_ebe99317bbbe9968a0c6f579adf"`, undefined); + await queryRunner.query(`ALTER TABLE "clip_note" DROP CONSTRAINT "FK_a012eaf5c87c65da1deb5fdbfa3"`, undefined); + await queryRunner.query(`ALTER TABLE "clip" DROP CONSTRAINT "FK_2b5ec6c574d6802c94c80313fb2"`, undefined); + await queryRunner.query(`ALTER TABLE "note" ADD "geo" jsonb`, undefined); + await queryRunner.query(`DROP INDEX "IDX_335a0bf3f904406f9ef3dd51c2"`, undefined); + await queryRunner.query(`DROP INDEX "IDX_0d775946662d2575dfd2068a5f"`, undefined); + await queryRunner.query(`DROP INDEX "IDX_bd0397be22147e17210940e125"`, undefined); + await queryRunner.query(`DROP TABLE "antenna_note"`, undefined); + await queryRunner.query(`DROP INDEX "IDX_6446c571a0e8d0f05f01c78909"`, undefined); + await queryRunner.query(`DROP TABLE "antenna"`, undefined); + await queryRunner.query(`DROP TYPE "antenna_src_enum"`, undefined); + await queryRunner.query(`DROP INDEX "IDX_6fc0ec357d55a18646262fdfff"`, undefined); + await queryRunner.query(`DROP INDEX "IDX_ebe99317bbbe9968a0c6f579ad"`, undefined); + await queryRunner.query(`DROP INDEX "IDX_a012eaf5c87c65da1deb5fdbfa"`, undefined); + await queryRunner.query(`DROP TABLE "clip_note"`, undefined); + await queryRunner.query(`DROP INDEX "IDX_2b5ec6c574d6802c94c80313fb"`, undefined); + await queryRunner.query(`DROP TABLE "clip"`, undefined); + } +} +exports.v1251579977526288 = v1251579977526288; diff --git a/packages/backend/migration/1579993013959-v12-6.js b/packages/backend/migration/1579993013959-v12-6.js new file mode 100644 index 000000000..e6c3a40a3 --- /dev/null +++ b/packages/backend/migration/1579993013959-v12-6.js @@ -0,0 +1,18 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class v1261579993013959 { + constructor() { + this.name = 'v1261579993013959'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "antenna" DROP COLUMN "hasNewNote"`, undefined); + await queryRunner.query(`ALTER TABLE "antenna_note" ADD "read" boolean NOT NULL DEFAULT false`, undefined); + await queryRunner.query(`CREATE INDEX "IDX_9937ea48d7ae97ffb4f3f063a4" ON "antenna_note" ("read") `, undefined); + } + async down(queryRunner) { + await queryRunner.query(`DROP INDEX "IDX_9937ea48d7ae97ffb4f3f063a4"`, undefined); + await queryRunner.query(`ALTER TABLE "antenna_note" DROP COLUMN "read"`, undefined); + await queryRunner.query(`ALTER TABLE "antenna" ADD "hasNewNote" boolean NOT NULL DEFAULT false`, undefined); + } +} +exports.v1261579993013959 = v1261579993013959; diff --git a/packages/backend/migration/1580069531114-v12-7.js b/packages/backend/migration/1580069531114-v12-7.js new file mode 100644 index 000000000..7915603b8 --- /dev/null +++ b/packages/backend/migration/1580069531114-v12-7.js @@ -0,0 +1,24 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class v1271580069531114 { + constructor() { + this.name = 'v1271580069531114'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "antenna" ADD "users" character varying(1024) array NOT NULL DEFAULT '{}'::varchar[]`, undefined); + await queryRunner.query(`ALTER TABLE "antenna" ADD "caseSensitive" boolean NOT NULL DEFAULT false`, undefined); + await queryRunner.query(`ALTER TYPE "public"."antenna_src_enum" RENAME TO "antenna_src_enum_old"`, undefined); + await queryRunner.query(`CREATE TYPE "antenna_src_enum" AS ENUM('home', 'all', 'users', 'list')`, undefined); + await queryRunner.query(`ALTER TABLE "antenna" ALTER COLUMN "src" TYPE "antenna_src_enum" USING "src"::"text"::"antenna_src_enum"`, undefined); + await queryRunner.query(`DROP TYPE "antenna_src_enum_old"`, undefined); + } + async down(queryRunner) { + await queryRunner.query(`CREATE TYPE "antenna_src_enum_old" AS ENUM('home', 'all', 'list')`, undefined); + await queryRunner.query(`ALTER TABLE "antenna" ALTER COLUMN "src" TYPE "antenna_src_enum_old" USING "src"::"text"::"antenna_src_enum_old"`, undefined); + await queryRunner.query(`DROP TYPE "antenna_src_enum"`, undefined); + await queryRunner.query(`ALTER TYPE "antenna_src_enum_old" RENAME TO "antenna_src_enum"`, undefined); + await queryRunner.query(`ALTER TABLE "antenna" DROP COLUMN "caseSensitive"`, undefined); + await queryRunner.query(`ALTER TABLE "antenna" DROP COLUMN "users"`, undefined); + } +} +exports.v1271580069531114 = v1271580069531114; diff --git a/packages/backend/migration/1580148575182-v12-8.js b/packages/backend/migration/1580148575182-v12-8.js new file mode 100644 index 000000000..43fbc70e4 --- /dev/null +++ b/packages/backend/migration/1580148575182-v12-8.js @@ -0,0 +1,16 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class v1281580148575182 { + constructor() { + this.name = 'v1281580148575182'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "note" DROP CONSTRAINT "FK_ec5c201576192ba8904c345c5cc"`, undefined); + await queryRunner.query(`ALTER TABLE "note" DROP COLUMN "appId"`, undefined); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "note" ADD "appId" character varying(32)`, undefined); + await queryRunner.query(`ALTER TABLE "note" ADD CONSTRAINT "FK_ec5c201576192ba8904c345c5cc" FOREIGN KEY ("appId") REFERENCES "app"("id") ON DELETE SET NULL ON UPDATE NO ACTION`, undefined); + } +} +exports.v1281580148575182 = v1281580148575182; diff --git a/packages/backend/migration/1580154400017-v12-9.js b/packages/backend/migration/1580154400017-v12-9.js new file mode 100644 index 000000000..f47611868 --- /dev/null +++ b/packages/backend/migration/1580154400017-v12-9.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class v1291580154400017 { + constructor() { + this.name = 'v1291580154400017'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "antenna" ADD "withReplies" boolean NOT NULL DEFAULT false`, undefined); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "antenna" DROP COLUMN "withReplies"`, undefined); + } +} +exports.v1291580154400017 = v1291580154400017; diff --git a/packages/backend/migration/1580276619901-v12-10.js b/packages/backend/migration/1580276619901-v12-10.js new file mode 100644 index 000000000..301d0ceb9 --- /dev/null +++ b/packages/backend/migration/1580276619901-v12-10.js @@ -0,0 +1,19 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class v12101580276619901 { + constructor() { + this.name = 'v12101580276619901'; + } + async up(queryRunner) { + await queryRunner.query(`TRUNCATE TABLE "notification"`, undefined); + await queryRunner.query(`ALTER TABLE "notification" DROP COLUMN "type"`, undefined); + await queryRunner.query(`CREATE TYPE "notification_type_enum" AS ENUM('follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'receiveFollowRequest', 'followRequestAccepted')`, undefined); + await queryRunner.query(`ALTER TABLE "notification" ADD "type" "notification_type_enum" NOT NULL`, undefined); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "notification" DROP COLUMN "type"`, undefined); + await queryRunner.query(`DROP TYPE "notification_type_enum"`, undefined); + await queryRunner.query(`ALTER TABLE "notification" ADD "type" character varying(32) NOT NULL`, undefined); + } +} +exports.v12101580276619901 = v12101580276619901; diff --git a/packages/backend/migration/1580331224276-v12-11.js b/packages/backend/migration/1580331224276-v12-11.js new file mode 100644 index 000000000..fb5124baa --- /dev/null +++ b/packages/backend/migration/1580331224276-v12-11.js @@ -0,0 +1,18 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class v12111580331224276 { + constructor() { + this.name = 'v12111580331224276'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "isMarkedAsClosed"`, undefined); + await queryRunner.query(`ALTER TABLE "instance" ADD "isSuspended" boolean NOT NULL DEFAULT false`, undefined); + await queryRunner.query(`CREATE INDEX "IDX_34500da2e38ac393f7bb6b299c" ON "instance" ("isSuspended") `, undefined); + } + async down(queryRunner) { + await queryRunner.query(`DROP INDEX "IDX_34500da2e38ac393f7bb6b299c"`, undefined); + await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "isSuspended"`, undefined); + await queryRunner.query(`ALTER TABLE "instance" ADD "isMarkedAsClosed" boolean NOT NULL DEFAULT false`, undefined); + } +} +exports.v12111580331224276 = v12111580331224276; diff --git a/packages/backend/migration/1580508795118-v12-12.js b/packages/backend/migration/1580508795118-v12-12.js new file mode 100644 index 000000000..eb70ba3ce --- /dev/null +++ b/packages/backend/migration/1580508795118-v12-12.js @@ -0,0 +1,46 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class v12121580508795118 { + constructor() { + this.name = 'v12121580508795118'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "twitter"`, undefined); + await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "twitterAccessToken"`, undefined); + await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "twitterAccessTokenSecret"`, undefined); + await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "twitterUserId"`, undefined); + await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "twitterScreenName"`, undefined); + await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "github"`, undefined); + await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "githubAccessToken"`, undefined); + await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "githubId"`, undefined); + await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "githubLogin"`, undefined); + await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "discord"`, undefined); + await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "discordAccessToken"`, undefined); + await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "discordRefreshToken"`, undefined); + await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "discordExpiresDate"`, undefined); + await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "discordId"`, undefined); + await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "discordUsername"`, undefined); + await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "discordDiscriminator"`, undefined); + await queryRunner.query(`ALTER TABLE "user_profile" ADD "integrations" jsonb NOT NULL DEFAULT '{}'`, undefined); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "integrations"`, undefined); + await queryRunner.query(`ALTER TABLE "user_profile" ADD "discordDiscriminator" character varying(64) DEFAULT NULL`, undefined); + await queryRunner.query(`ALTER TABLE "user_profile" ADD "discordUsername" character varying(64) DEFAULT NULL`, undefined); + await queryRunner.query(`ALTER TABLE "user_profile" ADD "discordId" character varying(64) DEFAULT NULL`, undefined); + await queryRunner.query(`ALTER TABLE "user_profile" ADD "discordExpiresDate" character varying(64)`, undefined); + await queryRunner.query(`ALTER TABLE "user_profile" ADD "discordRefreshToken" character varying(64) DEFAULT NULL`, undefined); + await queryRunner.query(`ALTER TABLE "user_profile" ADD "discordAccessToken" character varying(64) DEFAULT NULL`, undefined); + await queryRunner.query(`ALTER TABLE "user_profile" ADD "discord" boolean NOT NULL DEFAULT false`, undefined); + await queryRunner.query(`ALTER TABLE "user_profile" ADD "githubLogin" character varying(64) DEFAULT NULL`, undefined); + await queryRunner.query(`ALTER TABLE "user_profile" ADD "githubId" character varying(64)`, undefined); + await queryRunner.query(`ALTER TABLE "user_profile" ADD "githubAccessToken" character varying(64) DEFAULT NULL`, undefined); + await queryRunner.query(`ALTER TABLE "user_profile" ADD "github" boolean NOT NULL DEFAULT false`, undefined); + await queryRunner.query(`ALTER TABLE "user_profile" ADD "twitterScreenName" character varying(64) DEFAULT NULL`, undefined); + await queryRunner.query(`ALTER TABLE "user_profile" ADD "twitterUserId" character varying(64) DEFAULT NULL`, undefined); + await queryRunner.query(`ALTER TABLE "user_profile" ADD "twitterAccessTokenSecret" character varying(64) DEFAULT NULL`, undefined); + await queryRunner.query(`ALTER TABLE "user_profile" ADD "twitterAccessToken" character varying(64) DEFAULT NULL`, undefined); + await queryRunner.query(`ALTER TABLE "user_profile" ADD "twitter" boolean NOT NULL DEFAULT false`, undefined); + } +} +exports.v12121580508795118 = v12121580508795118; diff --git a/packages/backend/migration/1580543501339-v12-13.js b/packages/backend/migration/1580543501339-v12-13.js new file mode 100644 index 000000000..7dae7178b --- /dev/null +++ b/packages/backend/migration/1580543501339-v12-13.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class v12131580543501339 { + constructor() { + this.name = 'v12131580543501339'; + } + async up(queryRunner) { + await queryRunner.query(`CREATE INDEX "IDX_NOTE_TAGS" ON "note" USING gin ("tags")`, undefined); + } + async down(queryRunner) { + await queryRunner.query(`DROP INDEX "IDX_NOTE_TAGS"`, undefined); + } +} +exports.v12131580543501339 = v12131580543501339; diff --git a/packages/backend/migration/1580864313253-v12-14.js b/packages/backend/migration/1580864313253-v12-14.js new file mode 100644 index 000000000..b1939c51b --- /dev/null +++ b/packages/backend/migration/1580864313253-v12-14.js @@ -0,0 +1,20 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class v12141580864313253 { + constructor() { + this.name = 'v12141580864313253'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" RENAME COLUMN "proxyAccount" TO "proxyAccountId"`, undefined); + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "proxyAccountId"`, undefined); + await queryRunner.query(`ALTER TABLE "meta" ADD "proxyAccountId" character varying(32)`, undefined); + await queryRunner.query(`ALTER TABLE "meta" ADD CONSTRAINT "FK_ab1bc0c1e209daa77b8e8d212ad" FOREIGN KEY ("proxyAccountId") REFERENCES "user"("id") ON DELETE SET NULL ON UPDATE NO ACTION`, undefined); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" DROP CONSTRAINT "FK_ab1bc0c1e209daa77b8e8d212ad"`, undefined); + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "proxyAccountId"`, undefined); + await queryRunner.query(`ALTER TABLE "meta" ADD "proxyAccountId" character varying(128)`, undefined); + await queryRunner.query(`ALTER TABLE "meta" RENAME COLUMN "proxyAccountId" TO "proxyAccount"`, undefined); + } +} +exports.v12141580864313253 = v12141580864313253; diff --git a/packages/backend/migration/1581526429287-user-group-invitation.js b/packages/backend/migration/1581526429287-user-group-invitation.js new file mode 100644 index 000000000..80946c94a --- /dev/null +++ b/packages/backend/migration/1581526429287-user-group-invitation.js @@ -0,0 +1,38 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class userGroupInvitation1581526429287 { + constructor() { + this.name = 'userGroupInvitation1581526429287'; + } + async up(queryRunner) { + await queryRunner.query(`CREATE TABLE "user_group_invitation" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "userGroupId" character varying(32) NOT NULL, CONSTRAINT "PK_160c63ec02bf23f6a5c5e8140d6" PRIMARY KEY ("id"))`, undefined); + await queryRunner.query(`CREATE INDEX "IDX_bfbc6305547539369fe73eb144" ON "user_group_invitation" ("userId") `, undefined); + await queryRunner.query(`CREATE INDEX "IDX_5cc8c468090e129857e9fecce5" ON "user_group_invitation" ("userGroupId") `, undefined); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_e9793f65f504e5a31fbaedbf2f" ON "user_group_invitation" ("userId", "userGroupId") `, undefined); + await queryRunner.query(`ALTER TABLE "notification" ADD "userGroupInvitationId" character varying(32)`, undefined); + await queryRunner.query(`ALTER TYPE "public"."notification_type_enum" RENAME TO "notification_type_enum_old"`, undefined); + await queryRunner.query(`CREATE TYPE "notification_type_enum" AS ENUM('follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'receiveFollowRequest', 'followRequestAccepted', 'groupInvited')`, undefined); + await queryRunner.query(`ALTER TABLE "notification" ALTER COLUMN "type" TYPE "notification_type_enum" USING "type"::"text"::"notification_type_enum"`, undefined); + await queryRunner.query(`DROP TYPE "notification_type_enum_old"`, undefined); + await queryRunner.query(`COMMENT ON COLUMN "notification"."type" IS 'The type of the Notification.'`, undefined); + await queryRunner.query(`ALTER TABLE "user_group_invitation" ADD CONSTRAINT "FK_bfbc6305547539369fe73eb144a" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined); + await queryRunner.query(`ALTER TABLE "user_group_invitation" ADD CONSTRAINT "FK_5cc8c468090e129857e9fecce5a" FOREIGN KEY ("userGroupId") REFERENCES "user_group"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined); + await queryRunner.query(`ALTER TABLE "notification" ADD CONSTRAINT "FK_8fe87814e978053a53b1beb7e98" FOREIGN KEY ("userGroupInvitationId") REFERENCES "user_group_invitation"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "notification" DROP CONSTRAINT "FK_8fe87814e978053a53b1beb7e98"`, undefined); + await queryRunner.query(`ALTER TABLE "user_group_invitation" DROP CONSTRAINT "FK_5cc8c468090e129857e9fecce5a"`, undefined); + await queryRunner.query(`ALTER TABLE "user_group_invitation" DROP CONSTRAINT "FK_bfbc6305547539369fe73eb144a"`, undefined); + await queryRunner.query(`COMMENT ON COLUMN "notification"."type" IS ''`, undefined); + await queryRunner.query(`CREATE TYPE "notification_type_enum_old" AS ENUM('follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'receiveFollowRequest', 'followRequestAccepted')`, undefined); + await queryRunner.query(`ALTER TABLE "notification" ALTER COLUMN "type" TYPE "notification_type_enum_old" USING "type"::"text"::"notification_type_enum_old"`, undefined); + await queryRunner.query(`DROP TYPE "notification_type_enum"`, undefined); + await queryRunner.query(`ALTER TYPE "notification_type_enum_old" RENAME TO "notification_type_enum"`, undefined); + await queryRunner.query(`ALTER TABLE "notification" DROP COLUMN "userGroupInvitationId"`, undefined); + await queryRunner.query(`DROP INDEX "IDX_e9793f65f504e5a31fbaedbf2f"`, undefined); + await queryRunner.query(`DROP INDEX "IDX_5cc8c468090e129857e9fecce5"`, undefined); + await queryRunner.query(`DROP INDEX "IDX_bfbc6305547539369fe73eb144"`, undefined); + await queryRunner.query(`DROP TABLE "user_group_invitation"`, undefined); + } +} +exports.userGroupInvitation1581526429287 = userGroupInvitation1581526429287; diff --git a/packages/backend/migration/1581695816408-user-group-antenna.js b/packages/backend/migration/1581695816408-user-group-antenna.js new file mode 100644 index 000000000..307b5b057 --- /dev/null +++ b/packages/backend/migration/1581695816408-user-group-antenna.js @@ -0,0 +1,28 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class userGroupAntenna1581695816408 { + constructor() { + this.name = 'userGroupAntenna1581695816408'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "antenna" ADD "userGroupJoiningId" character varying(32)`, undefined); + await queryRunner.query(`ALTER TYPE "public"."antenna_src_enum" RENAME TO "antenna_src_enum_old"`, undefined); + await queryRunner.query(`CREATE TYPE "antenna_src_enum" AS ENUM('home', 'all', 'users', 'list', 'group')`, undefined); + await queryRunner.query(`ALTER TABLE "antenna" ALTER COLUMN "src" TYPE "antenna_src_enum" USING "src"::"text"::"antenna_src_enum"`, undefined); + await queryRunner.query(`DROP TYPE "antenna_src_enum_old"`, undefined); + await queryRunner.query(`ALTER TABLE "antenna" DROP COLUMN "users"`, undefined); + await queryRunner.query(`ALTER TABLE "antenna" ADD "users" character varying(1024) array NOT NULL DEFAULT '{}'::varchar[]`, undefined); + await queryRunner.query(`ALTER TABLE "antenna" ADD CONSTRAINT "FK_ccbf5a8c0be4511133dcc50ddeb" FOREIGN KEY ("userGroupJoiningId") REFERENCES "user_group_joining"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "antenna" DROP CONSTRAINT "FK_ccbf5a8c0be4511133dcc50ddeb"`, undefined); + await queryRunner.query(`ALTER TABLE "antenna" DROP COLUMN "users"`, undefined); + await queryRunner.query(`ALTER TABLE "antenna" ADD "users" character varying array NOT NULL DEFAULT '{}'`, undefined); + await queryRunner.query(`CREATE TYPE "antenna_src_enum_old" AS ENUM('home', 'all', 'users', 'list')`, undefined); + await queryRunner.query(`ALTER TABLE "antenna" ALTER COLUMN "src" TYPE "antenna_src_enum_old" USING "src"::"text"::"antenna_src_enum_old"`, undefined); + await queryRunner.query(`DROP TYPE "antenna_src_enum"`, undefined); + await queryRunner.query(`ALTER TYPE "antenna_src_enum_old" RENAME TO "antenna_src_enum"`, undefined); + await queryRunner.query(`ALTER TABLE "antenna" DROP COLUMN "userGroupJoiningId"`, undefined); + } +} +exports.userGroupAntenna1581695816408 = userGroupAntenna1581695816408; diff --git a/packages/backend/migration/1581708415836-drive-user-folder-id-index.js b/packages/backend/migration/1581708415836-drive-user-folder-id-index.js new file mode 100644 index 000000000..8029ef139 --- /dev/null +++ b/packages/backend/migration/1581708415836-drive-user-folder-id-index.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class driveUserFolderIdIndex1581708415836 { + constructor() { + this.name = 'driveUserFolderIdIndex1581708415836'; + } + async up(queryRunner) { + await queryRunner.query(`CREATE INDEX "IDX_55720b33a61a7c806a8215b825" ON "drive_file" ("userId", "folderId", "id") `, undefined); + } + async down(queryRunner) { + await queryRunner.query(`DROP INDEX "IDX_55720b33a61a7c806a8215b825"`, undefined); + } +} +exports.driveUserFolderIdIndex1581708415836 = driveUserFolderIdIndex1581708415836; diff --git a/packages/backend/migration/1581979837262-promo.js b/packages/backend/migration/1581979837262-promo.js new file mode 100644 index 000000000..d2c5bac17 --- /dev/null +++ b/packages/backend/migration/1581979837262-promo.js @@ -0,0 +1,28 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class promo1581979837262 { + constructor() { + this.name = 'promo1581979837262'; + } + async up(queryRunner) { + await queryRunner.query(`CREATE TABLE "promo_note" ("noteId" character varying(32) NOT NULL, "expiresAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, CONSTRAINT "REL_e263909ca4fe5d57f8d4230dd5" UNIQUE ("noteId"), CONSTRAINT "PK_e263909ca4fe5d57f8d4230dd5c" PRIMARY KEY ("noteId"))`, undefined); + await queryRunner.query(`CREATE INDEX "IDX_83f0862e9bae44af52ced7099e" ON "promo_note" ("userId") `, undefined); + await queryRunner.query(`CREATE TABLE "promo_read" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "noteId" character varying(32) NOT NULL, CONSTRAINT "PK_61917c1541002422b703318b7c9" PRIMARY KEY ("id"))`, undefined); + await queryRunner.query(`CREATE INDEX "IDX_9657d55550c3d37bfafaf7d4b0" ON "promo_read" ("userId") `, undefined); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_2882b8a1a07c7d281a98b6db16" ON "promo_read" ("userId", "noteId") `, undefined); + await queryRunner.query(`ALTER TABLE "promo_note" ADD CONSTRAINT "FK_e263909ca4fe5d57f8d4230dd5c" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined); + await queryRunner.query(`ALTER TABLE "promo_read" ADD CONSTRAINT "FK_9657d55550c3d37bfafaf7d4b05" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined); + await queryRunner.query(`ALTER TABLE "promo_read" ADD CONSTRAINT "FK_a46a1a603ecee695d7db26da5f4" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "promo_read" DROP CONSTRAINT "FK_a46a1a603ecee695d7db26da5f4"`, undefined); + await queryRunner.query(`ALTER TABLE "promo_read" DROP CONSTRAINT "FK_9657d55550c3d37bfafaf7d4b05"`, undefined); + await queryRunner.query(`ALTER TABLE "promo_note" DROP CONSTRAINT "FK_e263909ca4fe5d57f8d4230dd5c"`, undefined); + await queryRunner.query(`DROP INDEX "IDX_2882b8a1a07c7d281a98b6db16"`, undefined); + await queryRunner.query(`DROP INDEX "IDX_9657d55550c3d37bfafaf7d4b0"`, undefined); + await queryRunner.query(`DROP TABLE "promo_read"`, undefined); + await queryRunner.query(`DROP INDEX "IDX_83f0862e9bae44af52ced7099e"`, undefined); + await queryRunner.query(`DROP TABLE "promo_note"`, undefined); + } +} +exports.promo1581979837262 = promo1581979837262; diff --git a/packages/backend/migration/1582019042083-featured-injecttion.js b/packages/backend/migration/1582019042083-featured-injecttion.js new file mode 100644 index 000000000..9779e2a08 --- /dev/null +++ b/packages/backend/migration/1582019042083-featured-injecttion.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class featuredInjecttion1582019042083 { + constructor() { + this.name = 'featuredInjecttion1582019042083'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "user_profile" ADD "injectFeaturedNote" boolean NOT NULL DEFAULT true`, undefined); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "injectFeaturedNote"`, undefined); + } +} +exports.featuredInjecttion1582019042083 = featuredInjecttion1582019042083; diff --git a/packages/backend/migration/1582210532752-antenna-exclude.js b/packages/backend/migration/1582210532752-antenna-exclude.js new file mode 100644 index 000000000..cc095b4b5 --- /dev/null +++ b/packages/backend/migration/1582210532752-antenna-exclude.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class antennaExclude1582210532752 { + constructor() { + this.name = 'antennaExclude1582210532752'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "antenna" ADD "excludeKeywords" jsonb NOT NULL DEFAULT '[]'`, undefined); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "antenna" DROP COLUMN "excludeKeywords"`, undefined); + } +} +exports.antennaExclude1582210532752 = antennaExclude1582210532752; diff --git a/packages/backend/migration/1582875306439-note-reaction-length.js b/packages/backend/migration/1582875306439-note-reaction-length.js new file mode 100644 index 000000000..bdee1ef14 --- /dev/null +++ b/packages/backend/migration/1582875306439-note-reaction-length.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class noteReactionLength1582875306439 { + constructor() { + this.name = 'noteReactionLength1582875306439'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "note_reaction" ALTER COLUMN "reaction" TYPE character varying(130)`, undefined); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "note_reaction" ALTER COLUMN "reaction" TYPE character varying(128)`, undefined); + } +} +exports.noteReactionLength1582875306439 = noteReactionLength1582875306439; diff --git a/packages/backend/migration/1585361548360-miauth.js b/packages/backend/migration/1585361548360-miauth.js new file mode 100644 index 000000000..c1a695dd2 --- /dev/null +++ b/packages/backend/migration/1585361548360-miauth.js @@ -0,0 +1,36 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class miauth1585361548360 { + constructor() { + this.name = 'miauth1585361548360'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "access_token" ADD "lastUsedAt" TIMESTAMP WITH TIME ZONE DEFAULT null`, undefined); + await queryRunner.query(`ALTER TABLE "access_token" ADD "session" character varying(128) DEFAULT null`, undefined); + await queryRunner.query(`ALTER TABLE "access_token" ADD "name" character varying(128) DEFAULT null`, undefined); + await queryRunner.query(`ALTER TABLE "access_token" ADD "description" character varying(512) DEFAULT null`, undefined); + await queryRunner.query(`ALTER TABLE "access_token" ADD "iconUrl" character varying(512) DEFAULT null`, undefined); + await queryRunner.query(`ALTER TABLE "access_token" ADD "permission" character varying(64) array NOT NULL DEFAULT '{}'::varchar[]`, undefined); + await queryRunner.query(`ALTER TABLE "access_token" ADD "fetched" boolean NOT NULL DEFAULT false`, undefined); + await queryRunner.query(`ALTER TABLE "access_token" DROP CONSTRAINT "FK_a3ff16c90cc87a82a0b5959e560"`, undefined); + await queryRunner.query(`ALTER TABLE "access_token" ALTER COLUMN "appId" DROP NOT NULL`, undefined); + await queryRunner.query(`ALTER TABLE "access_token" ALTER COLUMN "appId" SET DEFAULT null`, undefined); + await queryRunner.query(`CREATE INDEX "IDX_bf3a053c07d9fb5d87317c56ee" ON "access_token" ("session") `, undefined); + await queryRunner.query(`ALTER TABLE "access_token" ADD CONSTRAINT "FK_a3ff16c90cc87a82a0b5959e560" FOREIGN KEY ("appId") REFERENCES "app"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "access_token" DROP CONSTRAINT "FK_a3ff16c90cc87a82a0b5959e560"`, undefined); + await queryRunner.query(`DROP INDEX "IDX_bf3a053c07d9fb5d87317c56ee"`, undefined); + await queryRunner.query(`ALTER TABLE "access_token" ALTER COLUMN "appId" DROP DEFAULT`, undefined); + await queryRunner.query(`ALTER TABLE "access_token" ALTER COLUMN "appId" SET NOT NULL`, undefined); + await queryRunner.query(`ALTER TABLE "access_token" ADD CONSTRAINT "FK_a3ff16c90cc87a82a0b5959e560" FOREIGN KEY ("appId") REFERENCES "app"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined); + await queryRunner.query(`ALTER TABLE "access_token" DROP COLUMN "fetched"`, undefined); + await queryRunner.query(`ALTER TABLE "access_token" DROP COLUMN "permission"`, undefined); + await queryRunner.query(`ALTER TABLE "access_token" DROP COLUMN "iconUrl"`, undefined); + await queryRunner.query(`ALTER TABLE "access_token" DROP COLUMN "description"`, undefined); + await queryRunner.query(`ALTER TABLE "access_token" DROP COLUMN "name"`, undefined); + await queryRunner.query(`ALTER TABLE "access_token" DROP COLUMN "session"`, undefined); + await queryRunner.query(`ALTER TABLE "access_token" DROP COLUMN "lastUsedAt"`, undefined); + } +} +exports.miauth1585361548360 = miauth1585361548360; diff --git a/packages/backend/migration/1585385921215-custom-notification.js b/packages/backend/migration/1585385921215-custom-notification.js new file mode 100644 index 000000000..7f94c741a --- /dev/null +++ b/packages/backend/migration/1585385921215-custom-notification.js @@ -0,0 +1,48 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class customNotification1585385921215 { + constructor() { + this.name = 'customNotification1585385921215'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "notification" ADD "customBody" character varying(2048)`, undefined); + await queryRunner.query(`ALTER TABLE "notification" ADD "customHeader" character varying(256)`, undefined); + await queryRunner.query(`ALTER TABLE "notification" ADD "customIcon" character varying(1024)`, undefined); + await queryRunner.query(`ALTER TABLE "notification" ADD "appAccessTokenId" character varying(32)`, undefined); + await queryRunner.query(`ALTER TABLE "notification" DROP CONSTRAINT "FK_3b4e96eec8d36a8bbb9d02aa710"`, undefined); + await queryRunner.query(`ALTER TABLE "notification" ALTER COLUMN "notifierId" DROP NOT NULL`, undefined); + await queryRunner.query(`COMMENT ON COLUMN "notification"."notifierId" IS 'The ID of sender user of the Notification.'`, undefined); + await queryRunner.query(`ALTER TYPE "public"."notification_type_enum" RENAME TO "notification_type_enum_old"`, undefined); + await queryRunner.query(`CREATE TYPE "notification_type_enum" AS ENUM('follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'receiveFollowRequest', 'followRequestAccepted', 'groupInvited', 'app')`, undefined); + await queryRunner.query(`ALTER TABLE "notification" ALTER COLUMN "type" TYPE "notification_type_enum" USING "type"::"text"::"notification_type_enum"`, undefined); + await queryRunner.query(`DROP TYPE "notification_type_enum_old"`, undefined); + await queryRunner.query(`COMMENT ON COLUMN "notification"."type" IS 'The type of the Notification.'`, undefined); + await queryRunner.query(`CREATE INDEX "IDX_3b4e96eec8d36a8bbb9d02aa71" ON "notification" ("notifierId") `, undefined); + await queryRunner.query(`CREATE INDEX "IDX_33f33cc8ef29d805a97ff4628b" ON "notification" ("type") `, undefined); + await queryRunner.query(`CREATE INDEX "IDX_080ab397c379af09b9d2169e5b" ON "notification" ("isRead") `, undefined); + await queryRunner.query(`CREATE INDEX "IDX_e22bf6bda77b6adc1fd9e75c8c" ON "notification" ("appAccessTokenId") `, undefined); + await queryRunner.query(`ALTER TABLE "notification" ADD CONSTRAINT "FK_3b4e96eec8d36a8bbb9d02aa710" FOREIGN KEY ("notifierId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined); + await queryRunner.query(`ALTER TABLE "notification" ADD CONSTRAINT "FK_e22bf6bda77b6adc1fd9e75c8c9" FOREIGN KEY ("appAccessTokenId") REFERENCES "access_token"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "notification" DROP CONSTRAINT "FK_e22bf6bda77b6adc1fd9e75c8c9"`, undefined); + await queryRunner.query(`ALTER TABLE "notification" DROP CONSTRAINT "FK_3b4e96eec8d36a8bbb9d02aa710"`, undefined); + await queryRunner.query(`DROP INDEX "IDX_e22bf6bda77b6adc1fd9e75c8c"`, undefined); + await queryRunner.query(`DROP INDEX "IDX_080ab397c379af09b9d2169e5b"`, undefined); + await queryRunner.query(`DROP INDEX "IDX_33f33cc8ef29d805a97ff4628b"`, undefined); + await queryRunner.query(`DROP INDEX "IDX_3b4e96eec8d36a8bbb9d02aa71"`, undefined); + await queryRunner.query(`COMMENT ON COLUMN "notification"."type" IS ''`, undefined); + await queryRunner.query(`CREATE TYPE "notification_type_enum_old" AS ENUM('follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'receiveFollowRequest', 'followRequestAccepted', 'groupInvited')`, undefined); + await queryRunner.query(`ALTER TABLE "notification" ALTER COLUMN "type" TYPE "notification_type_enum_old" USING "type"::"text"::"notification_type_enum_old"`, undefined); + await queryRunner.query(`DROP TYPE "notification_type_enum"`, undefined); + await queryRunner.query(`ALTER TYPE "notification_type_enum_old" RENAME TO "notification_type_enum"`, undefined); + await queryRunner.query(`COMMENT ON COLUMN "notification"."notifierId" IS ''`, undefined); + await queryRunner.query(`ALTER TABLE "notification" ALTER COLUMN "notifierId" SET NOT NULL`, undefined); + await queryRunner.query(`ALTER TABLE "notification" ADD CONSTRAINT "FK_3b4e96eec8d36a8bbb9d02aa710" FOREIGN KEY ("notifierId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined); + await queryRunner.query(`ALTER TABLE "notification" DROP COLUMN "appAccessTokenId"`, undefined); + await queryRunner.query(`ALTER TABLE "notification" DROP COLUMN "customIcon"`, undefined); + await queryRunner.query(`ALTER TABLE "notification" DROP COLUMN "customHeader"`, undefined); + await queryRunner.query(`ALTER TABLE "notification" DROP COLUMN "customBody"`, undefined); + } +} +exports.customNotification1585385921215 = customNotification1585385921215; diff --git a/packages/backend/migration/1585772678853-ap-url.js b/packages/backend/migration/1585772678853-ap-url.js new file mode 100644 index 000000000..f7c1f87b8 --- /dev/null +++ b/packages/backend/migration/1585772678853-ap-url.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class apUrl1585772678853 { + constructor() { + this.name = 'apUrl1585772678853'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "note" ADD "url" character varying(512)`, undefined); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "note" DROP COLUMN "url"`, undefined); + } +} +exports.apUrl1585772678853 = apUrl1585772678853; diff --git a/packages/backend/migration/1586624197029-AddObjectStorageUseProxy.js b/packages/backend/migration/1586624197029-AddObjectStorageUseProxy.js new file mode 100644 index 000000000..9fcef0c90 --- /dev/null +++ b/packages/backend/migration/1586624197029-AddObjectStorageUseProxy.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class AddObjectStorageUseProxy1586624197029 { + constructor() { + this.name = 'AddObjectStorageUseProxy1586624197029'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" ADD "objectStorageUseProxy" boolean NOT NULL DEFAULT true`, undefined); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStorageUseProxy"`, undefined); + } +} +exports.AddObjectStorageUseProxy1586624197029 = AddObjectStorageUseProxy1586624197029; diff --git a/packages/backend/migration/1586641139527-remote-reaction.js b/packages/backend/migration/1586641139527-remote-reaction.js new file mode 100644 index 000000000..a9d362474 --- /dev/null +++ b/packages/backend/migration/1586641139527-remote-reaction.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class remoteReaction1586641139527 { + constructor() { + this.name = 'remoteReaction1586641139527'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "note_reaction" ALTER COLUMN "reaction" TYPE character varying(260)`, undefined); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "note_reaction" ALTER COLUMN "reaction" TYPE character varying(130)`, undefined); + } +} +exports.remoteReaction1586641139527 = remoteReaction1586641139527; diff --git a/packages/backend/migration/1586708940386-pageAiScript.js b/packages/backend/migration/1586708940386-pageAiScript.js new file mode 100644 index 000000000..089ff6e27 --- /dev/null +++ b/packages/backend/migration/1586708940386-pageAiScript.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class pageAiScript1586708940386 { + constructor() { + this.name = 'pageAiScript1586708940386'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "page" ADD "script" character varying(16384) NOT NULL DEFAULT ''`, undefined); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "page" DROP COLUMN "script"`, undefined); + } +} +exports.pageAiScript1586708940386 = pageAiScript1586708940386; diff --git a/packages/backend/migration/1588044505511-hCaptcha.js b/packages/backend/migration/1588044505511-hCaptcha.js new file mode 100644 index 000000000..9b2524afb --- /dev/null +++ b/packages/backend/migration/1588044505511-hCaptcha.js @@ -0,0 +1,18 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class hCaptcha1588044505511 { + constructor() { + this.name = 'hCaptcha1588044505511'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" ADD "enableHcaptcha" boolean NOT NULL DEFAULT false`, undefined); + await queryRunner.query(`ALTER TABLE "meta" ADD "hcaptchaSiteKey" character varying(64)`, undefined); + await queryRunner.query(`ALTER TABLE "meta" ADD "hcaptchaSecretKey" character varying(64)`, undefined); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "hcaptchaSecretKey"`, undefined); + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "hcaptchaSiteKey"`, undefined); + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "enableHcaptcha"`, undefined); + } +} +exports.hCaptcha1588044505511 = hCaptcha1588044505511; diff --git a/packages/backend/migration/1589023282116-pubRelay.js b/packages/backend/migration/1589023282116-pubRelay.js new file mode 100644 index 000000000..f03384a51 --- /dev/null +++ b/packages/backend/migration/1589023282116-pubRelay.js @@ -0,0 +1,18 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class pubRelay1589023282116 { + constructor() { + this.name = 'pubRelay1589023282116'; + } + async up(queryRunner) { + await queryRunner.query(`CREATE TYPE "relay_status_enum" AS ENUM('requesting', 'accepted', 'rejected')`, undefined); + await queryRunner.query(`CREATE TABLE "relay" ("id" character varying(32) NOT NULL, "inbox" character varying(512) NOT NULL, "status" "relay_status_enum" NOT NULL, CONSTRAINT "PK_78ebc9cfddf4292633b7ba57aee" PRIMARY KEY ("id"))`, undefined); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_0d9a1738f2cf7f3b1c3334dfab" ON "relay" ("inbox") `, undefined); + } + async down(queryRunner) { + await queryRunner.query(`DROP INDEX "IDX_0d9a1738f2cf7f3b1c3334dfab"`, undefined); + await queryRunner.query(`DROP TABLE "relay"`, undefined); + await queryRunner.query(`DROP TYPE "relay_status_enum"`, undefined); + } +} +exports.pubRelay1589023282116 = pubRelay1589023282116; diff --git a/packages/backend/migration/1595075960584-blurhash.js b/packages/backend/migration/1595075960584-blurhash.js new file mode 100644 index 000000000..3bd9c46f1 --- /dev/null +++ b/packages/backend/migration/1595075960584-blurhash.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class blurhash1595075960584 { + constructor() { + this.name = 'blurhash1595075960584'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "drive_file" ADD "blurhash" character varying(128)`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "drive_file" DROP COLUMN "blurhash"`); + } +} +exports.blurhash1595075960584 = blurhash1595075960584; diff --git a/packages/backend/migration/1595077605646-blurhash-for-avatar-banner.js b/packages/backend/migration/1595077605646-blurhash-for-avatar-banner.js new file mode 100644 index 000000000..c2a9c9756 --- /dev/null +++ b/packages/backend/migration/1595077605646-blurhash-for-avatar-banner.js @@ -0,0 +1,20 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class blurhashForAvatarBanner1595077605646 { + constructor() { + this.name = 'blurhashForAvatarBanner1595077605646'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "avatarColor"`); + await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "bannerColor"`); + await queryRunner.query(`ALTER TABLE "user" ADD "avatarBlurhash" character varying(128)`); + await queryRunner.query(`ALTER TABLE "user" ADD "bannerBlurhash" character varying(128)`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "bannerBlurhash"`); + await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "avatarBlurhash"`); + await queryRunner.query(`ALTER TABLE "user" ADD "bannerColor" character varying(32)`); + await queryRunner.query(`ALTER TABLE "user" ADD "avatarColor" character varying(32)`); + } +} +exports.blurhashForAvatarBanner1595077605646 = blurhashForAvatarBanner1595077605646; diff --git a/packages/backend/migration/1595676934834-instance-icon-url.js b/packages/backend/migration/1595676934834-instance-icon-url.js new file mode 100644 index 000000000..21ae26c55 --- /dev/null +++ b/packages/backend/migration/1595676934834-instance-icon-url.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class instanceIconUrl1595676934834 { + constructor() { + this.name = 'instanceIconUrl1595676934834'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "instance" ADD "iconUrl" character varying(256) DEFAULT null`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "iconUrl"`); + } +} +exports.instanceIconUrl1595676934834 = instanceIconUrl1595676934834; diff --git a/packages/backend/migration/1595771249699-word-mute.js b/packages/backend/migration/1595771249699-word-mute.js new file mode 100644 index 000000000..0dd3a5556 --- /dev/null +++ b/packages/backend/migration/1595771249699-word-mute.js @@ -0,0 +1,30 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class wordMute1595771249699 { + constructor() { + this.name = 'wordMute1595771249699'; + } + async up(queryRunner) { + await queryRunner.query(`CREATE TABLE "muted_note" ("id" character varying(32) NOT NULL, "noteId" character varying(32) NOT NULL, "userId" character varying(32) NOT NULL, CONSTRAINT "PK_897e2eff1c0b9b64e55ca1418a4" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE INDEX "IDX_70ab9786313d78e4201d81cdb8" ON "muted_note" ("noteId") `); + await queryRunner.query(`CREATE INDEX "IDX_d8e07aa18c2d64e86201601aec" ON "muted_note" ("userId") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_a8c6bfd637d3f1d67a27c48e27" ON "muted_note" ("noteId", "userId") `); + await queryRunner.query(`ALTER TABLE "user_profile" ADD "enableWordMute" boolean NOT NULL DEFAULT false`); + await queryRunner.query(`ALTER TABLE "user_profile" ADD "mutedWords" jsonb NOT NULL DEFAULT '[]'`); + await queryRunner.query(`CREATE INDEX "IDX_3befe6f999c86aff06eb0257b4" ON "user_profile" ("enableWordMute") `); + await queryRunner.query(`ALTER TABLE "muted_note" ADD CONSTRAINT "FK_70ab9786313d78e4201d81cdb89" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "muted_note" ADD CONSTRAINT "FK_d8e07aa18c2d64e86201601aec1" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "muted_note" DROP CONSTRAINT "FK_d8e07aa18c2d64e86201601aec1"`); + await queryRunner.query(`ALTER TABLE "muted_note" DROP CONSTRAINT "FK_70ab9786313d78e4201d81cdb89"`); + await queryRunner.query(`DROP INDEX "IDX_3befe6f999c86aff06eb0257b4"`); + await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "mutedWords"`); + await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "enableWordMute"`); + await queryRunner.query(`DROP INDEX "IDX_a8c6bfd637d3f1d67a27c48e27"`); + await queryRunner.query(`DROP INDEX "IDX_d8e07aa18c2d64e86201601aec"`); + await queryRunner.query(`DROP INDEX "IDX_70ab9786313d78e4201d81cdb8"`); + await queryRunner.query(`DROP TABLE "muted_note"`); + } +} +exports.wordMute1595771249699 = wordMute1595771249699; diff --git a/packages/backend/migration/1595782306083-word-mute2.js b/packages/backend/migration/1595782306083-word-mute2.js new file mode 100644 index 000000000..29c707e95 --- /dev/null +++ b/packages/backend/migration/1595782306083-word-mute2.js @@ -0,0 +1,18 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class wordMute21595782306083 { + constructor() { + this.name = 'wordMute21595782306083'; + } + async up(queryRunner) { + await queryRunner.query(`CREATE TYPE "muted_note_reason_enum" AS ENUM('word', 'manual', 'spam', 'other')`); + await queryRunner.query(`ALTER TABLE "muted_note" ADD "reason" "muted_note_reason_enum" NOT NULL`); + await queryRunner.query(`CREATE INDEX "IDX_636e977ff90b23676fb5624b25" ON "muted_note" ("reason") `); + } + async down(queryRunner) { + await queryRunner.query(`DROP INDEX "IDX_636e977ff90b23676fb5624b25"`); + await queryRunner.query(`ALTER TABLE "muted_note" DROP COLUMN "reason"`); + await queryRunner.query(`DROP TYPE "muted_note_reason_enum"`); + } +} +exports.wordMute21595782306083 = wordMute21595782306083; diff --git a/packages/backend/migration/1596548170836-channel.js b/packages/backend/migration/1596548170836-channel.js new file mode 100644 index 000000000..bce812d5e --- /dev/null +++ b/packages/backend/migration/1596548170836-channel.js @@ -0,0 +1,58 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class channel1596548170836 { + constructor() { + this.name = 'channel1596548170836'; + } + async up(queryRunner) { + await queryRunner.query(`CREATE TABLE "channel" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "lastNotedAt" TIMESTAMP WITH TIME ZONE, "userId" character varying(32) NOT NULL, "name" character varying(128) NOT NULL, "description" character varying(2048), "bannerId" character varying(32), "notesCount" integer NOT NULL DEFAULT 0, "usersCount" integer NOT NULL DEFAULT 0, CONSTRAINT "PK_590f33ee6ee7d76437acf362e39" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE INDEX "IDX_71cb7b435b7c0d4843317e7e16" ON "channel" ("createdAt") `); + await queryRunner.query(`CREATE INDEX "IDX_29ef80c6f13bcea998447fce43" ON "channel" ("lastNotedAt") `); + await queryRunner.query(`CREATE INDEX "IDX_823bae55bd81b3be6e05cff438" ON "channel" ("userId") `); + await queryRunner.query(`CREATE INDEX "IDX_0f58c11241e649d2a638a8de94" ON "channel" ("notesCount") `); + await queryRunner.query(`CREATE INDEX "IDX_094b86cd36bb805d1aa1e8cc9a" ON "channel" ("usersCount") `); + await queryRunner.query(`CREATE TABLE "channel_following" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "followeeId" character varying(32) NOT NULL, "followerId" character varying(32) NOT NULL, CONSTRAINT "PK_8b104be7f7415113f2a02cd5bdd" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE INDEX "IDX_11e71f2511589dcc8a4d3214f9" ON "channel_following" ("createdAt") `); + await queryRunner.query(`CREATE INDEX "IDX_0e43068c3f92cab197c3d3cd86" ON "channel_following" ("followeeId") `); + await queryRunner.query(`CREATE INDEX "IDX_6d8084ec9496e7334a4602707e" ON "channel_following" ("followerId") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_2e230dd45a10e671d781d99f3e" ON "channel_following" ("followerId", "followeeId") `); + await queryRunner.query(`CREATE TABLE "channel_note_pining" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "channelId" character varying(32) NOT NULL, "noteId" character varying(32) NOT NULL, CONSTRAINT "PK_44f7474496bcf2e4b741681146d" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE INDEX "IDX_8125f950afd3093acb10d2db8a" ON "channel_note_pining" ("channelId") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_f36fed37d6d4cdcc68c803cd9c" ON "channel_note_pining" ("channelId", "noteId") `); + await queryRunner.query(`ALTER TABLE "note" ADD "channelId" character varying(32) DEFAULT null`); + await queryRunner.query(`CREATE INDEX "IDX_f22169eb10657bded6d875ac8f" ON "note" ("channelId") `); + await queryRunner.query(`ALTER TABLE "channel" ADD CONSTRAINT "FK_823bae55bd81b3be6e05cff4383" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE SET NULL ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "channel" ADD CONSTRAINT "FK_999da2bcc7efadbfe0e92d3bc19" FOREIGN KEY ("bannerId") REFERENCES "drive_file"("id") ON DELETE SET NULL ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "note" ADD CONSTRAINT "FK_f22169eb10657bded6d875ac8f9" FOREIGN KEY ("channelId") REFERENCES "channel"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "channel_following" ADD CONSTRAINT "FK_0e43068c3f92cab197c3d3cd86e" FOREIGN KEY ("followeeId") REFERENCES "channel"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "channel_following" ADD CONSTRAINT "FK_6d8084ec9496e7334a4602707e1" FOREIGN KEY ("followerId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "channel_note_pining" ADD CONSTRAINT "FK_8125f950afd3093acb10d2db8a8" FOREIGN KEY ("channelId") REFERENCES "channel"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "channel_note_pining" ADD CONSTRAINT "FK_10b19ef67d297ea9de325cd4502" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "channel_note_pining" DROP CONSTRAINT "FK_10b19ef67d297ea9de325cd4502"`); + await queryRunner.query(`ALTER TABLE "channel_note_pining" DROP CONSTRAINT "FK_8125f950afd3093acb10d2db8a8"`); + await queryRunner.query(`ALTER TABLE "channel_following" DROP CONSTRAINT "FK_6d8084ec9496e7334a4602707e1"`); + await queryRunner.query(`ALTER TABLE "channel_following" DROP CONSTRAINT "FK_0e43068c3f92cab197c3d3cd86e"`); + await queryRunner.query(`ALTER TABLE "note" DROP CONSTRAINT "FK_f22169eb10657bded6d875ac8f9"`); + await queryRunner.query(`ALTER TABLE "channel" DROP CONSTRAINT "FK_999da2bcc7efadbfe0e92d3bc19"`); + await queryRunner.query(`ALTER TABLE "channel" DROP CONSTRAINT "FK_823bae55bd81b3be6e05cff4383"`); + await queryRunner.query(`DROP INDEX "IDX_f22169eb10657bded6d875ac8f"`); + await queryRunner.query(`ALTER TABLE "note" DROP COLUMN "channelId"`); + await queryRunner.query(`DROP INDEX "IDX_f36fed37d6d4cdcc68c803cd9c"`); + await queryRunner.query(`DROP INDEX "IDX_8125f950afd3093acb10d2db8a"`); + await queryRunner.query(`DROP TABLE "channel_note_pining"`); + await queryRunner.query(`DROP INDEX "IDX_2e230dd45a10e671d781d99f3e"`); + await queryRunner.query(`DROP INDEX "IDX_6d8084ec9496e7334a4602707e"`); + await queryRunner.query(`DROP INDEX "IDX_0e43068c3f92cab197c3d3cd86"`); + await queryRunner.query(`DROP INDEX "IDX_11e71f2511589dcc8a4d3214f9"`); + await queryRunner.query(`DROP TABLE "channel_following"`); + await queryRunner.query(`DROP INDEX "IDX_094b86cd36bb805d1aa1e8cc9a"`); + await queryRunner.query(`DROP INDEX "IDX_0f58c11241e649d2a638a8de94"`); + await queryRunner.query(`DROP INDEX "IDX_823bae55bd81b3be6e05cff438"`); + await queryRunner.query(`DROP INDEX "IDX_29ef80c6f13bcea998447fce43"`); + await queryRunner.query(`DROP INDEX "IDX_71cb7b435b7c0d4843317e7e16"`); + await queryRunner.query(`DROP TABLE "channel"`); + } +} +exports.channel1596548170836 = channel1596548170836; diff --git a/packages/backend/migration/1596786425167-channel2.js b/packages/backend/migration/1596786425167-channel2.js new file mode 100644 index 000000000..160c73b06 --- /dev/null +++ b/packages/backend/migration/1596786425167-channel2.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class channel21596786425167 { + constructor() { + this.name = 'channel21596786425167'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "channel_following" ADD "readCursor" TIMESTAMP WITH TIME ZONE NOT NULL`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "channel_following" DROP COLUMN "readCursor"`); + } +} +exports.channel21596786425167 = channel21596786425167; diff --git a/packages/backend/migration/1597230137744-objectStorageSetPublicRead.js b/packages/backend/migration/1597230137744-objectStorageSetPublicRead.js new file mode 100644 index 000000000..d208c425e --- /dev/null +++ b/packages/backend/migration/1597230137744-objectStorageSetPublicRead.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class objectStorageSetPublicRead1597230137744 { + constructor() { + this.name = 'objectStorageSetPublicRead1597230137744'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" ADD "objectStorageSetPublicRead" boolean NOT NULL DEFAULT false`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStorageSetPublicRead"`); + } +} +exports.objectStorageSetPublicRead1597230137744 = objectStorageSetPublicRead1597230137744; diff --git a/packages/backend/migration/1597236229720-IncludingNotificationTypes.js b/packages/backend/migration/1597236229720-IncludingNotificationTypes.js new file mode 100644 index 000000000..0efbf2fe5 --- /dev/null +++ b/packages/backend/migration/1597236229720-IncludingNotificationTypes.js @@ -0,0 +1,16 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class IncludingNotificationTypes1597236229720 { + constructor() { + this.name = 'IncludingNotificationTypes1597236229720'; + } + async up(queryRunner) { + await queryRunner.query(`CREATE TYPE "user_profile_includingnotificationtypes_enum" AS ENUM('follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'receiveFollowRequest', 'followRequestAccepted', 'groupInvited', 'app')`); + await queryRunner.query(`ALTER TABLE "user_profile" ADD "includingNotificationTypes" "user_profile_includingnotificationtypes_enum" array`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "includingNotificationTypes"`); + await queryRunner.query(`DROP TYPE "user_profile_includingnotificationtypes_enum"`); + } +} +exports.IncludingNotificationTypes1597236229720 = IncludingNotificationTypes1597236229720; diff --git a/packages/backend/migration/1597385880794-add-sensitive-index.js b/packages/backend/migration/1597385880794-add-sensitive-index.js new file mode 100644 index 000000000..69fd394b0 --- /dev/null +++ b/packages/backend/migration/1597385880794-add-sensitive-index.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class addSensitiveIndex1597385880794 { + constructor() { + this.name = 'addSensitiveIndex1597385880794'; + } + async up(queryRunner) { + await queryRunner.query(`CREATE INDEX "IDX_a7eba67f8b3fa27271e85d2e26" ON "drive_file" ("isSensitive") `); + } + async down(queryRunner) { + await queryRunner.query(`DROP INDEX "IDX_a7eba67f8b3fa27271e85d2e26"`); + } +} +exports.addSensitiveIndex1597385880794 = addSensitiveIndex1597385880794; diff --git a/packages/backend/migration/1597459042300-channel-unread.js b/packages/backend/migration/1597459042300-channel-unread.js new file mode 100644 index 000000000..629aa6009 --- /dev/null +++ b/packages/backend/migration/1597459042300-channel-unread.js @@ -0,0 +1,27 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class channelUnread1597459042300 { + constructor() { + this.name = 'channelUnread1597459042300'; + } + async up(queryRunner) { + await queryRunner.query(`TRUNCATE TABLE "note_unread"`, undefined); + await queryRunner.query(`ALTER TABLE "channel_following" DROP COLUMN "readCursor"`); + await queryRunner.query(`ALTER TABLE "note_unread" ADD "isMentioned" boolean NOT NULL`); + await queryRunner.query(`ALTER TABLE "note_unread" ADD "noteChannelId" character varying(32)`); + await queryRunner.query(`CREATE INDEX "IDX_25b1dd384bec391b07b74b861c" ON "note_unread" ("isMentioned") `); + await queryRunner.query(`CREATE INDEX "IDX_89a29c9237b8c3b6b3cbb4cb30" ON "note_unread" ("isSpecified") `); + await queryRunner.query(`CREATE INDEX "IDX_29e8c1d579af54d4232939f994" ON "note_unread" ("noteUserId") `); + await queryRunner.query(`CREATE INDEX "IDX_6a57f051d82c6d4036c141e107" ON "note_unread" ("noteChannelId") `); + } + async down(queryRunner) { + await queryRunner.query(`DROP INDEX "IDX_6a57f051d82c6d4036c141e107"`); + await queryRunner.query(`DROP INDEX "IDX_29e8c1d579af54d4232939f994"`); + await queryRunner.query(`DROP INDEX "IDX_89a29c9237b8c3b6b3cbb4cb30"`); + await queryRunner.query(`DROP INDEX "IDX_25b1dd384bec391b07b74b861c"`); + await queryRunner.query(`ALTER TABLE "note_unread" DROP COLUMN "noteChannelId"`); + await queryRunner.query(`ALTER TABLE "note_unread" DROP COLUMN "isMentioned"`); + await queryRunner.query(`ALTER TABLE "channel_following" ADD "readCursor" TIMESTAMP WITH TIME ZONE NOT NULL`); + } +} +exports.channelUnread1597459042300 = channelUnread1597459042300; diff --git a/packages/backend/migration/1597893996136-ChannelNoteIdDescIndex.js b/packages/backend/migration/1597893996136-ChannelNoteIdDescIndex.js new file mode 100644 index 000000000..770ac1887 --- /dev/null +++ b/packages/backend/migration/1597893996136-ChannelNoteIdDescIndex.js @@ -0,0 +1,16 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class ChannelNoteIdDescIndex1597893996136 { + constructor() { + this.name = 'ChannelNoteIdDescIndex1597893996136'; + } + async up(queryRunner) { + await queryRunner.query(`DROP INDEX "IDX_f22169eb10657bded6d875ac8f"`); + await queryRunner.query(`CREATE INDEX "IDX_note_on_channelId_and_id_desc" ON "note" ("channelId", "id" desc)`); + } + async down(queryRunner) { + await queryRunner.query(`DROP INDEX "IDX_note_on_channelId_and_id_desc"`); + await queryRunner.query(`CREATE INDEX "IDX_f22169eb10657bded6d875ac8f" ON "note" ("channelId") `); + } +} +exports.ChannelNoteIdDescIndex1597893996136 = ChannelNoteIdDescIndex1597893996136; diff --git a/packages/backend/migration/1600353287890-mutingNotificationTypes.js b/packages/backend/migration/1600353287890-mutingNotificationTypes.js new file mode 100644 index 000000000..d39a6f2e4 --- /dev/null +++ b/packages/backend/migration/1600353287890-mutingNotificationTypes.js @@ -0,0 +1,20 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class mutingNotificationTypes1600353287890 { + constructor() { + this.name = 'mutingNotificationTypes1600353287890'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "includingNotificationTypes"`); + await queryRunner.query(`DROP TYPE "public"."user_profile_includingnotificationtypes_enum"`); + await queryRunner.query(`CREATE TYPE "user_profile_mutingnotificationtypes_enum" AS ENUM('follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'receiveFollowRequest', 'followRequestAccepted', 'groupInvited', 'app')`); + await queryRunner.query(`ALTER TABLE "user_profile" ADD "mutingNotificationTypes" "user_profile_mutingnotificationtypes_enum" array NOT NULL DEFAULT '{}'`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "mutingNotificationTypes"`); + await queryRunner.query(`DROP TYPE "user_profile_mutingnotificationtypes_enum"`); + await queryRunner.query(`CREATE TYPE "public"."user_profile_includingnotificationtypes_enum" AS ENUM('follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'receiveFollowRequest', 'followRequestAccepted', 'groupInvited', 'app')`); + await queryRunner.query(`ALTER TABLE "user_profile" ADD "includingNotificationTypes" "user_profile_includingnotificationtypes_enum" array`); + } +} +exports.mutingNotificationTypes1600353287890 = mutingNotificationTypes1600353287890; diff --git a/packages/backend/migration/1603094348345-refine-abuse-user-report.js b/packages/backend/migration/1603094348345-refine-abuse-user-report.js new file mode 100644 index 000000000..b01a5d80a --- /dev/null +++ b/packages/backend/migration/1603094348345-refine-abuse-user-report.js @@ -0,0 +1,32 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class refineAbuseUserReport1603094348345 { + constructor() { + this.name = 'refineAbuseUserReport1603094348345'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "abuse_user_report" DROP CONSTRAINT "FK_d049123c413e68ca52abe734203"`); + await queryRunner.query(`DROP INDEX "IDX_d049123c413e68ca52abe73420"`); + await queryRunner.query(`DROP INDEX "IDX_5cd442c3b2e74fdd99dae20243"`); + await queryRunner.query(`ALTER TABLE "abuse_user_report" RENAME COLUMN "userId" TO "targetUserId"`); + await queryRunner.query(`ALTER TABLE "abuse_user_report" ADD "assigneeId" character varying(32)`); + await queryRunner.query(`ALTER TABLE "abuse_user_report" ADD "resolved" boolean NOT NULL DEFAULT false`); + await queryRunner.query(`ALTER TABLE "abuse_user_report" DROP COLUMN "comment"`); + await queryRunner.query(`ALTER TABLE "abuse_user_report" ADD "comment" character varying(2048) NOT NULL DEFAULT '{}'::varchar[]`); + await queryRunner.query(`CREATE INDEX "IDX_2b15aaf4a0dc5be3499af7ab6a" ON "abuse_user_report" ("resolved") `); + await queryRunner.query(`ALTER TABLE "abuse_user_report" ADD CONSTRAINT "FK_08b883dd5fdd6f9c4c1572b36de" FOREIGN KEY ("assigneeId") REFERENCES "user"("id") ON DELETE SET NULL ON UPDATE NO ACTION`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "abuse_user_report" DROP CONSTRAINT "FK_08b883dd5fdd6f9c4c1572b36de"`); + await queryRunner.query(`DROP INDEX "IDX_2b15aaf4a0dc5be3499af7ab6a"`); + await queryRunner.query(`ALTER TABLE "abuse_user_report" DROP COLUMN "comment"`); + await queryRunner.query(`ALTER TABLE "abuse_user_report" ADD "comment" character varying(512) NOT NULL DEFAULT '{}'::varchar[]`); + await queryRunner.query(`ALTER TABLE "abuse_user_report" DROP COLUMN "resolved"`); + await queryRunner.query(`ALTER TABLE "abuse_user_report" DROP COLUMN "assigneeId"`); + await queryRunner.query(`ALTER TABLE "abuse_user_report" RENAME COLUMN "targetUserId" TO "userId"`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_5cd442c3b2e74fdd99dae20243" ON "abuse_user_report" ("userId", "reporterId") `); + await queryRunner.query(`CREATE INDEX "IDX_d049123c413e68ca52abe73420" ON "abuse_user_report" ("userId") `); + await queryRunner.query(`ALTER TABLE "abuse_user_report" ADD CONSTRAINT "FK_d049123c413e68ca52abe734203" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + } +} +exports.refineAbuseUserReport1603094348345 = refineAbuseUserReport1603094348345; diff --git a/packages/backend/migration/1603095701770-refine-abuse-user-report2.js b/packages/backend/migration/1603095701770-refine-abuse-user-report2.js new file mode 100644 index 000000000..32b4e0bd2 --- /dev/null +++ b/packages/backend/migration/1603095701770-refine-abuse-user-report2.js @@ -0,0 +1,20 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class refineAbuseUserReport21603095701770 { + constructor() { + this.name = 'refineAbuseUserReport21603095701770'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "abuse_user_report" ADD "targetUserHost" character varying(128)`); + await queryRunner.query(`ALTER TABLE "abuse_user_report" ADD "reporterHost" character varying(128)`); + await queryRunner.query(`CREATE INDEX "IDX_4ebbf7f93cdc10e8d1ef2fc6cd" ON "abuse_user_report" ("targetUserHost") `); + await queryRunner.query(`CREATE INDEX "IDX_f8d8b93740ad12c4ce8213a199" ON "abuse_user_report" ("reporterHost") `); + } + async down(queryRunner) { + await queryRunner.query(`DROP INDEX "IDX_f8d8b93740ad12c4ce8213a199"`); + await queryRunner.query(`DROP INDEX "IDX_4ebbf7f93cdc10e8d1ef2fc6cd"`); + await queryRunner.query(`ALTER TABLE "abuse_user_report" DROP COLUMN "reporterHost"`); + await queryRunner.query(`ALTER TABLE "abuse_user_report" DROP COLUMN "targetUserHost"`); + } +} +exports.refineAbuseUserReport21603095701770 = refineAbuseUserReport21603095701770; diff --git a/packages/backend/migration/1603776877564-instance-theme-color.js b/packages/backend/migration/1603776877564-instance-theme-color.js new file mode 100644 index 000000000..315305f53 --- /dev/null +++ b/packages/backend/migration/1603776877564-instance-theme-color.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class instanceThemeColor1603776877564 { + constructor() { + this.name = 'instanceThemeColor1603776877564'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "instance" ADD "themeColor" character varying(64) DEFAULT null`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "themeColor"`); + } +} +exports.instanceThemeColor1603776877564 = instanceThemeColor1603776877564; diff --git a/packages/backend/migration/1603781553011-instance-favicon.js b/packages/backend/migration/1603781553011-instance-favicon.js new file mode 100644 index 000000000..451989f91 --- /dev/null +++ b/packages/backend/migration/1603781553011-instance-favicon.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class instanceFavicon1603781553011 { + constructor() { + this.name = 'instanceFavicon1603781553011'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "instance" ADD "faviconUrl" character varying(256) DEFAULT null`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "faviconUrl"`); + } +} +exports.instanceFavicon1603781553011 = instanceFavicon1603781553011; diff --git a/packages/backend/migration/1604821689616-delete-auto-watch.js b/packages/backend/migration/1604821689616-delete-auto-watch.js new file mode 100644 index 000000000..9d972dd3f --- /dev/null +++ b/packages/backend/migration/1604821689616-delete-auto-watch.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class deleteAutoWatch1604821689616 { + constructor() { + this.name = 'deleteAutoWatch1604821689616'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "autoWatch"`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "user_profile" ADD "autoWatch" boolean NOT NULL DEFAULT false`); + } +} +exports.deleteAutoWatch1604821689616 = deleteAutoWatch1604821689616; diff --git a/packages/backend/migration/1605408848373-clip-description.js b/packages/backend/migration/1605408848373-clip-description.js new file mode 100644 index 000000000..acbe2b0c8 --- /dev/null +++ b/packages/backend/migration/1605408848373-clip-description.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class clipDescription1605408848373 { + constructor() { + this.name = 'clipDescription1605408848373'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "clip" ADD "description" character varying(2048) DEFAULT null`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "clip" DROP COLUMN "description"`); + } +} +exports.clipDescription1605408848373 = clipDescription1605408848373; diff --git a/packages/backend/migration/1605408971051-comments.js b/packages/backend/migration/1605408971051-comments.js new file mode 100644 index 000000000..6e5dacbb6 --- /dev/null +++ b/packages/backend/migration/1605408971051-comments.js @@ -0,0 +1,434 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class comments1605408971051 { + constructor() { + this.name = 'comments1605408971051'; + } + async up(queryRunner) { + await queryRunner.query(`COMMENT ON COLUMN "log"."createdAt" IS 'The created date of the Log.'`); + await queryRunner.query(`COMMENT ON COLUMN "drive_folder"."createdAt" IS 'The created date of the DriveFolder.'`); + await queryRunner.query(`COMMENT ON COLUMN "drive_folder"."name" IS 'The name of the DriveFolder.'`); + await queryRunner.query(`COMMENT ON COLUMN "drive_folder"."userId" IS 'The owner ID.'`); + await queryRunner.query(`COMMENT ON COLUMN "drive_folder"."parentId" IS 'The parent folder ID. If null, it means the DriveFolder is located in root.'`); + await queryRunner.query(`COMMENT ON COLUMN "drive_file"."createdAt" IS 'The created date of the DriveFile.'`); + await queryRunner.query(`COMMENT ON COLUMN "drive_file"."userId" IS 'The owner ID.'`); + await queryRunner.query(`COMMENT ON COLUMN "drive_file"."userHost" IS 'The host of owner. It will be null if the user in local.'`); + await queryRunner.query(`COMMENT ON COLUMN "drive_file"."md5" IS 'The MD5 hash of the DriveFile.'`); + await queryRunner.query(`COMMENT ON COLUMN "drive_file"."name" IS 'The file name of the DriveFile.'`); + await queryRunner.query(`COMMENT ON COLUMN "drive_file"."type" IS 'The content type (MIME) of the DriveFile.'`); + await queryRunner.query(`COMMENT ON COLUMN "drive_file"."size" IS 'The file size (bytes) of the DriveFile.'`); + await queryRunner.query(`COMMENT ON COLUMN "drive_file"."comment" IS 'The comment of the DriveFile.'`); + await queryRunner.query(`COMMENT ON COLUMN "drive_file"."blurhash" IS 'The BlurHash string.'`); + await queryRunner.query(`COMMENT ON COLUMN "drive_file"."properties" IS 'The any properties of the DriveFile. For example, it includes image width/height.'`); + await queryRunner.query(`COMMENT ON COLUMN "drive_file"."url" IS 'The URL of the DriveFile.'`); + await queryRunner.query(`COMMENT ON COLUMN "drive_file"."thumbnailUrl" IS 'The URL of the thumbnail of the DriveFile.'`); + await queryRunner.query(`COMMENT ON COLUMN "drive_file"."webpublicUrl" IS 'The URL of the webpublic of the DriveFile.'`); + await queryRunner.query(`COMMENT ON COLUMN "drive_file"."uri" IS 'The URI of the DriveFile. it will be null when the DriveFile is local.'`); + await queryRunner.query(`COMMENT ON COLUMN "drive_file"."folderId" IS 'The parent folder ID. If null, it means the DriveFile is located in root.'`); + await queryRunner.query(`COMMENT ON COLUMN "drive_file"."isSensitive" IS 'Whether the DriveFile is NSFW.'`); + await queryRunner.query(`COMMENT ON COLUMN "drive_file"."isLink" IS 'Whether the DriveFile is direct link to remote server.'`); + await queryRunner.query(`COMMENT ON COLUMN "user"."createdAt" IS 'The created date of the User.'`); + await queryRunner.query(`COMMENT ON COLUMN "user"."updatedAt" IS 'The updated date of the User.'`); + await queryRunner.query(`COMMENT ON COLUMN "user"."username" IS 'The username of the User.'`); + await queryRunner.query(`COMMENT ON COLUMN "user"."usernameLower" IS 'The username (lowercased) of the User.'`); + await queryRunner.query(`COMMENT ON COLUMN "user"."name" IS 'The name of the User.'`); + await queryRunner.query(`COMMENT ON COLUMN "user"."followersCount" IS 'The count of followers.'`); + await queryRunner.query(`COMMENT ON COLUMN "user"."followingCount" IS 'The count of following.'`); + await queryRunner.query(`COMMENT ON COLUMN "user"."notesCount" IS 'The count of notes.'`); + await queryRunner.query(`COMMENT ON COLUMN "user"."avatarId" IS 'The ID of avatar DriveFile.'`); + await queryRunner.query(`COMMENT ON COLUMN "user"."bannerId" IS 'The ID of banner DriveFile.'`); + await queryRunner.query(`COMMENT ON COLUMN "user"."isSuspended" IS 'Whether the User is suspended.'`); + await queryRunner.query(`COMMENT ON COLUMN "user"."isSilenced" IS 'Whether the User is silenced.'`); + await queryRunner.query(`COMMENT ON COLUMN "user"."isLocked" IS 'Whether the User is locked.'`); + await queryRunner.query(`COMMENT ON COLUMN "user"."isBot" IS 'Whether the User is a bot.'`); + await queryRunner.query(`COMMENT ON COLUMN "user"."isCat" IS 'Whether the User is a cat.'`); + await queryRunner.query(`COMMENT ON COLUMN "user"."isAdmin" IS 'Whether the User is the admin.'`); + await queryRunner.query(`COMMENT ON COLUMN "user"."isModerator" IS 'Whether the User is a moderator.'`); + await queryRunner.query(`COMMENT ON COLUMN "user"."host" IS 'The host of the User. It will be null if the origin of the user is local.'`); + await queryRunner.query(`COMMENT ON COLUMN "user"."inbox" IS 'The inbox URL of the User. It will be null if the origin of the user is local.'`); + await queryRunner.query(`COMMENT ON COLUMN "user"."sharedInbox" IS 'The sharedInbox URL of the User. It will be null if the origin of the user is local.'`); + await queryRunner.query(`COMMENT ON COLUMN "user"."featured" IS 'The featured URL of the User. It will be null if the origin of the user is local.'`); + await queryRunner.query(`COMMENT ON COLUMN "user"."uri" IS 'The URI of the User. It will be null if the origin of the user is local.'`); + await queryRunner.query(`COMMENT ON COLUMN "user"."token" IS 'The native access token of the User. It will be null if the origin of the user is local.'`); + await queryRunner.query(`COMMENT ON COLUMN "app"."createdAt" IS 'The created date of the App.'`); + await queryRunner.query(`COMMENT ON COLUMN "app"."userId" IS 'The owner ID.'`); + await queryRunner.query(`COMMENT ON COLUMN "app"."secret" IS 'The secret key of the App.'`); + await queryRunner.query(`COMMENT ON COLUMN "app"."name" IS 'The name of the App.'`); + await queryRunner.query(`COMMENT ON COLUMN "app"."description" IS 'The description of the App.'`); + await queryRunner.query(`COMMENT ON COLUMN "app"."permission" IS 'The permission of the App.'`); + await queryRunner.query(`COMMENT ON COLUMN "app"."callbackUrl" IS 'The callbackUrl of the App.'`); + await queryRunner.query(`COMMENT ON COLUMN "access_token"."createdAt" IS 'The created date of the AccessToken.'`); + await queryRunner.query(`COMMENT ON COLUMN "access_token"."lastUsedAt" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "access_token"."session" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "access_token"."appId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "access_token"."name" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "access_token"."description" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "access_token"."iconUrl" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "channel"."createdAt" IS 'The created date of the Channel.'`); + await queryRunner.query(`COMMENT ON COLUMN "channel"."userId" IS 'The owner ID.'`); + await queryRunner.query(`COMMENT ON COLUMN "channel"."name" IS 'The name of the Channel.'`); + await queryRunner.query(`COMMENT ON COLUMN "channel"."description" IS 'The description of the Channel.'`); + await queryRunner.query(`COMMENT ON COLUMN "channel"."bannerId" IS 'The ID of banner Channel.'`); + await queryRunner.query(`COMMENT ON COLUMN "channel"."notesCount" IS 'The count of notes.'`); + await queryRunner.query(`COMMENT ON COLUMN "channel"."usersCount" IS 'The count of users.'`); + await queryRunner.query(`COMMENT ON COLUMN "note"."createdAt" IS 'The created date of the Note.'`); + await queryRunner.query(`COMMENT ON COLUMN "note"."replyId" IS 'The ID of reply target.'`); + await queryRunner.query(`COMMENT ON COLUMN "note"."renoteId" IS 'The ID of renote target.'`); + await queryRunner.query(`COMMENT ON COLUMN "note"."userId" IS 'The ID of author.'`); + await queryRunner.query(`COMMENT ON COLUMN "note"."uri" IS 'The URI of a note. it will be null when the note is local.'`); + await queryRunner.query(`COMMENT ON COLUMN "note"."url" IS 'The human readable url of a note. it will be null when the note is local.'`); + await queryRunner.query(`COMMENT ON COLUMN "note"."channelId" IS 'The ID of source channel.'`); + await queryRunner.query(`COMMENT ON COLUMN "note"."userHost" IS '[Denormalized]'`); + await queryRunner.query(`COMMENT ON COLUMN "note"."replyUserId" IS '[Denormalized]'`); + await queryRunner.query(`COMMENT ON COLUMN "note"."replyUserHost" IS '[Denormalized]'`); + await queryRunner.query(`COMMENT ON COLUMN "note"."renoteUserId" IS '[Denormalized]'`); + await queryRunner.query(`COMMENT ON COLUMN "note"."renoteUserHost" IS '[Denormalized]'`); + await queryRunner.query(`COMMENT ON COLUMN "poll_vote"."createdAt" IS 'The created date of the PollVote.'`); + await queryRunner.query(`COMMENT ON COLUMN "note_reaction"."createdAt" IS 'The created date of the NoteReaction.'`); + await queryRunner.query(`COMMENT ON COLUMN "note_watching"."createdAt" IS 'The created date of the NoteWatching.'`); + await queryRunner.query(`COMMENT ON COLUMN "note_watching"."userId" IS 'The watcher ID.'`); + await queryRunner.query(`COMMENT ON COLUMN "note_watching"."noteId" IS 'The target Note ID.'`); + await queryRunner.query(`COMMENT ON COLUMN "note_watching"."noteUserId" IS '[Denormalized]'`); + await queryRunner.query(`COMMENT ON COLUMN "note_unread"."noteUserId" IS '[Denormalized]'`); + await queryRunner.query(`COMMENT ON COLUMN "note_unread"."noteChannelId" IS '[Denormalized]'`); + await queryRunner.query(`COMMENT ON COLUMN "follow_request"."createdAt" IS 'The created date of the FollowRequest.'`); + await queryRunner.query(`COMMENT ON COLUMN "follow_request"."followeeId" IS 'The followee user ID.'`); + await queryRunner.query(`COMMENT ON COLUMN "follow_request"."followerId" IS 'The follower user ID.'`); + await queryRunner.query(`COMMENT ON COLUMN "follow_request"."requestId" IS 'id of Follow Activity.'`); + await queryRunner.query(`COMMENT ON COLUMN "follow_request"."followerHost" IS '[Denormalized]'`); + await queryRunner.query(`COMMENT ON COLUMN "follow_request"."followerInbox" IS '[Denormalized]'`); + await queryRunner.query(`COMMENT ON COLUMN "follow_request"."followerSharedInbox" IS '[Denormalized]'`); + await queryRunner.query(`COMMENT ON COLUMN "follow_request"."followeeHost" IS '[Denormalized]'`); + await queryRunner.query(`COMMENT ON COLUMN "follow_request"."followeeInbox" IS '[Denormalized]'`); + await queryRunner.query(`COMMENT ON COLUMN "follow_request"."followeeSharedInbox" IS '[Denormalized]'`); + await queryRunner.query(`COMMENT ON COLUMN "user_group"."createdAt" IS 'The created date of the UserGroup.'`); + await queryRunner.query(`COMMENT ON COLUMN "user_group"."userId" IS 'The ID of owner.'`); + await queryRunner.query(`COMMENT ON COLUMN "user_group_invitation"."createdAt" IS 'The created date of the UserGroupInvitation.'`); + await queryRunner.query(`COMMENT ON COLUMN "user_group_invitation"."userId" IS 'The user ID.'`); + await queryRunner.query(`COMMENT ON COLUMN "user_group_invitation"."userGroupId" IS 'The group ID.'`); + await queryRunner.query(`COMMENT ON COLUMN "notification"."createdAt" IS 'The created date of the Notification.'`); + await queryRunner.query(`COMMENT ON COLUMN "notification"."notifieeId" IS 'The ID of recipient user of the Notification.'`); + await queryRunner.query(`COMMENT ON COLUMN "notification"."isRead" IS 'Whether the Notification is read.'`); + await queryRunner.query(`COMMENT ON COLUMN "meta"."localDriveCapacityMb" IS 'Drive capacity of a local user (MB)'`); + await queryRunner.query(`COMMENT ON COLUMN "meta"."remoteDriveCapacityMb" IS 'Drive capacity of a remote user (MB)'`); + await queryRunner.query(`COMMENT ON COLUMN "meta"."maxNoteTextLength" IS 'Max allowed note text length in characters'`); + await queryRunner.query(`COMMENT ON COLUMN "following"."createdAt" IS 'The created date of the Following.'`); + await queryRunner.query(`COMMENT ON COLUMN "following"."followeeId" IS 'The followee user ID.'`); + await queryRunner.query(`COMMENT ON COLUMN "following"."followerId" IS 'The follower user ID.'`); + await queryRunner.query(`COMMENT ON COLUMN "following"."followerHost" IS '[Denormalized]'`); + await queryRunner.query(`COMMENT ON COLUMN "following"."followerInbox" IS '[Denormalized]'`); + await queryRunner.query(`COMMENT ON COLUMN "following"."followerSharedInbox" IS '[Denormalized]'`); + await queryRunner.query(`COMMENT ON COLUMN "following"."followeeHost" IS '[Denormalized]'`); + await queryRunner.query(`COMMENT ON COLUMN "following"."followeeInbox" IS '[Denormalized]'`); + await queryRunner.query(`COMMENT ON COLUMN "following"."followeeSharedInbox" IS '[Denormalized]'`); + await queryRunner.query(`COMMENT ON COLUMN "instance"."caughtAt" IS 'The caught date of the Instance.'`); + await queryRunner.query(`COMMENT ON COLUMN "instance"."host" IS 'The host of the Instance.'`); + await queryRunner.query(`COMMENT ON COLUMN "instance"."usersCount" IS 'The count of the users of the Instance.'`); + await queryRunner.query(`COMMENT ON COLUMN "instance"."notesCount" IS 'The count of the notes of the Instance.'`); + await queryRunner.query(`COMMENT ON COLUMN "instance"."softwareName" IS 'The software of the Instance.'`); + await queryRunner.query(`COMMENT ON COLUMN "instance"."softwareVersion" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "instance"."openRegistrations" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "instance"."name" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "instance"."description" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "instance"."maintainerName" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "instance"."maintainerEmail" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "instance"."iconUrl" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "instance"."faviconUrl" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "instance"."themeColor" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "muting"."createdAt" IS 'The created date of the Muting.'`); + await queryRunner.query(`COMMENT ON COLUMN "muting"."muteeId" IS 'The mutee user ID.'`); + await queryRunner.query(`COMMENT ON COLUMN "muting"."muterId" IS 'The muter user ID.'`); + await queryRunner.query(`COMMENT ON COLUMN "blocking"."createdAt" IS 'The created date of the Blocking.'`); + await queryRunner.query(`COMMENT ON COLUMN "blocking"."blockeeId" IS 'The blockee user ID.'`); + await queryRunner.query(`COMMENT ON COLUMN "blocking"."blockerId" IS 'The blocker user ID.'`); + await queryRunner.query(`COMMENT ON COLUMN "user_list"."createdAt" IS 'The created date of the UserList.'`); + await queryRunner.query(`COMMENT ON COLUMN "user_list"."userId" IS 'The owner ID.'`); + await queryRunner.query(`COMMENT ON COLUMN "user_list"."name" IS 'The name of the UserList.'`); + await queryRunner.query(`COMMENT ON COLUMN "user_list_joining"."createdAt" IS 'The created date of the UserListJoining.'`); + await queryRunner.query(`COMMENT ON COLUMN "user_list_joining"."userId" IS 'The user ID.'`); + await queryRunner.query(`COMMENT ON COLUMN "user_list_joining"."userListId" IS 'The list ID.'`); + await queryRunner.query(`COMMENT ON COLUMN "user_group_joining"."createdAt" IS 'The created date of the UserGroupJoining.'`); + await queryRunner.query(`COMMENT ON COLUMN "user_group_joining"."userId" IS 'The user ID.'`); + await queryRunner.query(`COMMENT ON COLUMN "user_group_joining"."userGroupId" IS 'The group ID.'`); + await queryRunner.query(`COMMENT ON COLUMN "note_favorite"."createdAt" IS 'The created date of the NoteFavorite.'`); + await queryRunner.query(`COMMENT ON COLUMN "abuse_user_report"."createdAt" IS 'The created date of the AbuseUserReport.'`); + await queryRunner.query(`COMMENT ON COLUMN "abuse_user_report"."targetUserHost" IS '[Denormalized]'`); + await queryRunner.query(`COMMENT ON COLUMN "abuse_user_report"."reporterHost" IS '[Denormalized]'`); + await queryRunner.query(`COMMENT ON COLUMN "messaging_message"."createdAt" IS 'The created date of the MessagingMessage.'`); + await queryRunner.query(`COMMENT ON COLUMN "messaging_message"."userId" IS 'The sender user ID.'`); + await queryRunner.query(`COMMENT ON COLUMN "messaging_message"."groupId" IS 'The recipient group ID.'`); + await queryRunner.query(`COMMENT ON COLUMN "signin"."createdAt" IS 'The created date of the Signin.'`); + await queryRunner.query(`COMMENT ON COLUMN "auth_session"."createdAt" IS 'The created date of the AuthSession.'`); + await queryRunner.query(`COMMENT ON COLUMN "reversi_game"."createdAt" IS 'The created date of the ReversiGame.'`); + await queryRunner.query(`COMMENT ON COLUMN "reversi_game"."startedAt" IS 'The started date of the ReversiGame.'`); + await queryRunner.query(`COMMENT ON COLUMN "reversi_game"."form1" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "reversi_game"."form2" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "reversi_matching"."createdAt" IS 'The created date of the ReversiMatching.'`); + await queryRunner.query(`COMMENT ON COLUMN "user_note_pining"."createdAt" IS 'The created date of the UserNotePinings.'`); + await queryRunner.query(`COMMENT ON COLUMN "poll"."noteId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "poll"."noteVisibility" IS '[Denormalized]'`); + await queryRunner.query(`COMMENT ON COLUMN "poll"."userId" IS '[Denormalized]'`); + await queryRunner.query(`COMMENT ON COLUMN "poll"."userHost" IS '[Denormalized]'`); + await queryRunner.query(`COMMENT ON COLUMN "user_keypair"."userId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user_publickey"."userId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "page"."createdAt" IS 'The created date of the Page.'`); + await queryRunner.query(`COMMENT ON COLUMN "page"."updatedAt" IS 'The updated date of the Page.'`); + await queryRunner.query(`COMMENT ON COLUMN "page"."userId" IS 'The ID of author.'`); + await queryRunner.query(`COMMENT ON COLUMN "user_profile"."userId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user_profile"."location" IS 'The location of the User.'`); + await queryRunner.query(`COMMENT ON COLUMN "user_profile"."birthday" IS 'The birthday (YYYY-MM-DD) of the User.'`); + await queryRunner.query(`COMMENT ON COLUMN "user_profile"."description" IS 'The description (bio) of the User.'`); + await queryRunner.query(`COMMENT ON COLUMN "user_profile"."url" IS 'Remote URL of the user.'`); + await queryRunner.query(`COMMENT ON COLUMN "user_profile"."email" IS 'The email address of the User.'`); + await queryRunner.query(`COMMENT ON COLUMN "user_profile"."password" IS 'The password hash of the User. It will be null if the origin of the user is local.'`); + await queryRunner.query(`COMMENT ON COLUMN "user_profile"."clientData" IS 'The client-specific data of the User.'`); + await queryRunner.query(`COMMENT ON COLUMN "user_profile"."room" IS 'The room data of the User.'`); + await queryRunner.query(`COMMENT ON COLUMN "user_profile"."userHost" IS '[Denormalized]'`); + await queryRunner.query(`COMMENT ON COLUMN "user_security_key"."id" IS 'Variable-length id given to navigator.credentials.get()'`); + await queryRunner.query(`COMMENT ON COLUMN "user_security_key"."publicKey" IS 'Variable-length public key used to verify attestations (hex-encoded).'`); + await queryRunner.query(`COMMENT ON COLUMN "user_security_key"."lastUsed" IS 'The date of the last time the UserSecurityKey was successfully validated.'`); + await queryRunner.query(`COMMENT ON COLUMN "user_security_key"."name" IS 'User-defined name for this key'`); + await queryRunner.query(`COMMENT ON COLUMN "attestation_challenge"."challenge" IS 'Hex-encoded sha256 hash of the challenge.'`); + await queryRunner.query(`COMMENT ON COLUMN "attestation_challenge"."createdAt" IS 'The date challenge was created for expiry purposes.'`); + await queryRunner.query(`COMMENT ON COLUMN "attestation_challenge"."registrationChallenge" IS 'Indicates that the challenge is only for registration purposes if true to prevent the challenge for being used as authentication.'`); + await queryRunner.query(`COMMENT ON COLUMN "moderation_log"."createdAt" IS 'The created date of the ModerationLog.'`); + await queryRunner.query(`COMMENT ON COLUMN "announcement"."createdAt" IS 'The created date of the Announcement.'`); + await queryRunner.query(`COMMENT ON COLUMN "announcement"."updatedAt" IS 'The updated date of the Announcement.'`); + await queryRunner.query(`COMMENT ON COLUMN "announcement_read"."createdAt" IS 'The created date of the AnnouncementRead.'`); + await queryRunner.query(`COMMENT ON COLUMN "clip"."createdAt" IS 'The created date of the Clip.'`); + await queryRunner.query(`COMMENT ON COLUMN "clip"."userId" IS 'The owner ID.'`); + await queryRunner.query(`COMMENT ON COLUMN "clip"."name" IS 'The name of the Clip.'`); + await queryRunner.query(`COMMENT ON COLUMN "clip"."description" IS 'The description of the Clip.'`); + await queryRunner.query(`COMMENT ON COLUMN "clip_note"."noteId" IS 'The note ID.'`); + await queryRunner.query(`COMMENT ON COLUMN "clip_note"."clipId" IS 'The clip ID.'`); + await queryRunner.query(`COMMENT ON COLUMN "antenna"."createdAt" IS 'The created date of the Antenna.'`); + await queryRunner.query(`COMMENT ON COLUMN "antenna"."userId" IS 'The owner ID.'`); + await queryRunner.query(`COMMENT ON COLUMN "antenna"."name" IS 'The name of the Antenna.'`); + await queryRunner.query(`COMMENT ON COLUMN "antenna_note"."noteId" IS 'The note ID.'`); + await queryRunner.query(`COMMENT ON COLUMN "antenna_note"."antennaId" IS 'The antenna ID.'`); + await queryRunner.query(`COMMENT ON COLUMN "promo_note"."noteId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "promo_note"."userId" IS '[Denormalized]'`); + await queryRunner.query(`COMMENT ON COLUMN "promo_read"."createdAt" IS 'The created date of the PromoRead.'`); + await queryRunner.query(`COMMENT ON COLUMN "muted_note"."noteId" IS 'The note ID.'`); + await queryRunner.query(`COMMENT ON COLUMN "muted_note"."userId" IS 'The user ID.'`); + await queryRunner.query(`COMMENT ON COLUMN "muted_note"."reason" IS 'The reason of the MutedNote.'`); + await queryRunner.query(`COMMENT ON COLUMN "channel_following"."createdAt" IS 'The created date of the ChannelFollowing.'`); + await queryRunner.query(`COMMENT ON COLUMN "channel_following"."followeeId" IS 'The followee channel ID.'`); + await queryRunner.query(`COMMENT ON COLUMN "channel_following"."followerId" IS 'The follower user ID.'`); + await queryRunner.query(`COMMENT ON COLUMN "channel_note_pining"."createdAt" IS 'The created date of the ChannelNotePining.'`); + } + async down(queryRunner) { + await queryRunner.query(`COMMENT ON COLUMN "channel_note_pining"."createdAt" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "channel_following"."followerId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "channel_following"."followeeId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "channel_following"."createdAt" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "muted_note"."reason" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "muted_note"."userId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "muted_note"."noteId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "promo_read"."createdAt" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "promo_note"."userId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "promo_note"."noteId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "antenna_note"."antennaId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "antenna_note"."noteId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "antenna"."name" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "antenna"."userId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "antenna"."createdAt" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "clip_note"."clipId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "clip_note"."noteId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "clip"."description" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "clip"."name" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "clip"."userId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "clip"."createdAt" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "announcement_read"."createdAt" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "announcement"."updatedAt" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "announcement"."createdAt" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "moderation_log"."createdAt" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "attestation_challenge"."registrationChallenge" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "attestation_challenge"."createdAt" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "attestation_challenge"."challenge" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user_security_key"."name" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user_security_key"."lastUsed" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user_security_key"."publicKey" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user_security_key"."id" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user_profile"."userHost" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user_profile"."room" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user_profile"."clientData" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user_profile"."password" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user_profile"."email" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user_profile"."url" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user_profile"."description" IS 'The description (bio) of the User.'`); + await queryRunner.query(`COMMENT ON COLUMN "user_profile"."birthday" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user_profile"."location" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user_profile"."userId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "page"."userId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "page"."updatedAt" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "page"."createdAt" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user_publickey"."userId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user_keypair"."userId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "poll"."userHost" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "poll"."userId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "poll"."noteVisibility" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "poll"."noteId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user_note_pining"."createdAt" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "reversi_matching"."createdAt" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "reversi_game"."form2" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "reversi_game"."form1" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "reversi_game"."startedAt" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "reversi_game"."createdAt" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "auth_session"."createdAt" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "signin"."createdAt" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "messaging_message"."groupId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "messaging_message"."userId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "messaging_message"."createdAt" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "abuse_user_report"."reporterHost" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "abuse_user_report"."targetUserHost" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "abuse_user_report"."createdAt" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "note_favorite"."createdAt" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user_group_joining"."userGroupId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user_group_joining"."userId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user_group_joining"."createdAt" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user_list_joining"."userListId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user_list_joining"."userId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user_list_joining"."createdAt" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user_list"."name" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user_list"."userId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user_list"."createdAt" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "blocking"."blockerId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "blocking"."blockeeId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "blocking"."createdAt" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "muting"."muterId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "muting"."muteeId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "muting"."createdAt" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "instance"."themeColor" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "instance"."faviconUrl" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "instance"."iconUrl" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "instance"."maintainerEmail" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "instance"."maintainerName" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "instance"."description" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "instance"."name" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "instance"."openRegistrations" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "instance"."softwareVersion" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "instance"."softwareName" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "instance"."notesCount" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "instance"."usersCount" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "instance"."host" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "instance"."caughtAt" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "following"."followeeSharedInbox" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "following"."followeeInbox" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "following"."followeeHost" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "following"."followerSharedInbox" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "following"."followerInbox" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "following"."followerHost" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "following"."followerId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "following"."followeeId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "following"."createdAt" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "meta"."maxNoteTextLength" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "meta"."remoteDriveCapacityMb" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "meta"."localDriveCapacityMb" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "notification"."isRead" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "notification"."notifieeId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "notification"."createdAt" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user_group_invitation"."userGroupId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user_group_invitation"."userId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user_group_invitation"."createdAt" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user_group"."userId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user_group"."createdAt" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "follow_request"."followeeSharedInbox" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "follow_request"."followeeInbox" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "follow_request"."followeeHost" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "follow_request"."followerSharedInbox" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "follow_request"."followerInbox" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "follow_request"."followerHost" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "follow_request"."requestId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "follow_request"."followerId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "follow_request"."followeeId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "follow_request"."createdAt" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "note_unread"."noteChannelId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "note_unread"."noteUserId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "note_watching"."noteUserId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "note_watching"."noteId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "note_watching"."userId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "note_watching"."createdAt" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "note_reaction"."createdAt" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "poll_vote"."createdAt" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "note"."renoteUserHost" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "note"."renoteUserId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "note"."replyUserHost" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "note"."replyUserId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "note"."userHost" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "note"."channelId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "note"."url" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "note"."uri" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "note"."userId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "note"."renoteId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "note"."replyId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "note"."createdAt" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "channel"."usersCount" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "channel"."notesCount" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "channel"."bannerId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "channel"."description" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "channel"."name" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "channel"."userId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "channel"."createdAt" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "access_token"."iconUrl" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "access_token"."description" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "access_token"."name" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "access_token"."appId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "access_token"."session" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "access_token"."lastUsedAt" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "access_token"."createdAt" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "app"."callbackUrl" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "app"."permission" IS 'The permission of the App.'`); + await queryRunner.query(`COMMENT ON COLUMN "app"."description" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "app"."name" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "app"."secret" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "app"."userId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "app"."createdAt" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user"."token" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user"."uri" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user"."featured" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user"."sharedInbox" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user"."inbox" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user"."host" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user"."isModerator" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user"."isAdmin" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user"."isCat" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user"."isBot" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user"."isLocked" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user"."isSilenced" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user"."isSuspended" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user"."bannerId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user"."avatarId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user"."notesCount" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user"."followingCount" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user"."followersCount" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user"."name" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user"."usernameLower" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user"."username" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user"."updatedAt" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user"."createdAt" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "drive_file"."isLink" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "drive_file"."isSensitive" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "drive_file"."folderId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "drive_file"."uri" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "drive_file"."webpublicUrl" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "drive_file"."thumbnailUrl" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "drive_file"."url" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "drive_file"."properties" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "drive_file"."blurhash" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "drive_file"."comment" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "drive_file"."size" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "drive_file"."type" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "drive_file"."name" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "drive_file"."md5" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "drive_file"."userHost" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "drive_file"."userId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "drive_file"."createdAt" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "drive_folder"."parentId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "drive_folder"."userId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "drive_folder"."name" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "drive_folder"."createdAt" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "log"."createdAt" IS NULL`); + } +} +exports.comments1605408971051 = comments1605408971051; diff --git a/packages/backend/migration/1605585339718-instance-pinned-pages.js b/packages/backend/migration/1605585339718-instance-pinned-pages.js new file mode 100644 index 000000000..8d2357276 --- /dev/null +++ b/packages/backend/migration/1605585339718-instance-pinned-pages.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class instancePinnedPages1605585339718 { + constructor() { + this.name = 'instancePinnedPages1605585339718'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" ADD "pinnedPages" character varying(512) array NOT NULL DEFAULT '{"/featured", "/channels", "/explore", "/pages", "/about-misskey"}'::varchar[]`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "pinnedPages"`); + } +} +exports.instancePinnedPages1605585339718 = instancePinnedPages1605585339718; diff --git a/packages/backend/migration/1605965516823-instance-images.js b/packages/backend/migration/1605965516823-instance-images.js new file mode 100644 index 000000000..f078428ba --- /dev/null +++ b/packages/backend/migration/1605965516823-instance-images.js @@ -0,0 +1,16 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class instanceImages1605965516823 { + constructor() { + this.name = 'instanceImages1605965516823'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" ADD "backgroundImageUrl" character varying(512)`); + await queryRunner.query(`ALTER TABLE "meta" ADD "logoImageUrl" character varying(512)`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "logoImageUrl"`); + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "backgroundImageUrl"`); + } +} +exports.instanceImages1605965516823 = instanceImages1605965516823; diff --git a/packages/backend/migration/1606191203881-no-crawle.js b/packages/backend/migration/1606191203881-no-crawle.js new file mode 100644 index 000000000..2c5fdaed2 --- /dev/null +++ b/packages/backend/migration/1606191203881-no-crawle.js @@ -0,0 +1,16 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class noCrawle1606191203881 { + constructor() { + this.name = 'noCrawle1606191203881'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "user_profile" ADD "noCrawle" boolean NOT NULL DEFAULT false`); + await queryRunner.query(`COMMENT ON COLUMN "user_profile"."noCrawle" IS 'Whether reject index by crawler.'`); + } + async down(queryRunner) { + await queryRunner.query(`COMMENT ON COLUMN "user_profile"."noCrawle" IS 'Whether reject index by crawler.'`); + await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "noCrawle"`); + } +} +exports.noCrawle1606191203881 = noCrawle1606191203881; diff --git a/packages/backend/migration/1607151207216-instance-pinned-clip.js b/packages/backend/migration/1607151207216-instance-pinned-clip.js new file mode 100644 index 000000000..3bd479296 --- /dev/null +++ b/packages/backend/migration/1607151207216-instance-pinned-clip.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class instancePinnedClip1607151207216 { + constructor() { + this.name = 'instancePinnedClip1607151207216'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" ADD "pinnedClipId" character varying(32)`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "pinnedClipId"`); + } +} +exports.instancePinnedClip1607151207216 = instancePinnedClip1607151207216; diff --git a/packages/backend/migration/1607353487793-isExplorable.js b/packages/backend/migration/1607353487793-isExplorable.js new file mode 100644 index 000000000..3ddd0cb32 --- /dev/null +++ b/packages/backend/migration/1607353487793-isExplorable.js @@ -0,0 +1,18 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class isExplorable1607353487793 { + constructor() { + this.name = 'isExplorable1607353487793'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "user" ADD "isExplorable" boolean NOT NULL DEFAULT true`); + await queryRunner.query(`COMMENT ON COLUMN "user"."isExplorable" IS 'Whether the User is explorable.'`); + await queryRunner.query(`CREATE INDEX "IDX_d5a1b83c7cab66f167e6888188" ON "user" ("isExplorable") `); + } + async down(queryRunner) { + await queryRunner.query(`DROP INDEX "IDX_d5a1b83c7cab66f167e6888188"`); + await queryRunner.query(`COMMENT ON COLUMN "user"."isExplorable" IS 'Whether the User is explorable.'`); + await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "isExplorable"`); + } +} +exports.isExplorable1607353487793 = isExplorable1607353487793; diff --git a/packages/backend/migration/1610277136869-registry.js b/packages/backend/migration/1610277136869-registry.js new file mode 100644 index 000000000..a7b5af84b --- /dev/null +++ b/packages/backend/migration/1610277136869-registry.js @@ -0,0 +1,22 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class registry1610277136869 { + constructor() { + this.name = 'registry1610277136869'; + } + async up(queryRunner) { + await queryRunner.query(`CREATE TABLE "registry_item" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "key" character varying(1024) NOT NULL, "scope" character varying(1024) array NOT NULL DEFAULT '{}'::varchar[], "domain" character varying(512), CONSTRAINT "PK_64b3f7e6008b4d89b826cd3af95" PRIMARY KEY ("id")); COMMENT ON COLUMN "registry_item"."createdAt" IS 'The created date of the RegistryItem.'; COMMENT ON COLUMN "registry_item"."updatedAt" IS 'The updated date of the RegistryItem.'; COMMENT ON COLUMN "registry_item"."userId" IS 'The owner ID.'; COMMENT ON COLUMN "registry_item"."key" IS 'The key of the RegistryItem.'`); + await queryRunner.query(`CREATE INDEX "IDX_fb9d21ba0abb83223263df6bcb" ON "registry_item" ("userId") `); + await queryRunner.query(`CREATE INDEX "IDX_22baca135bb8a3ea1a83d13df3" ON "registry_item" ("scope") `); + await queryRunner.query(`CREATE INDEX "IDX_0a72bdfcdb97c0eca11fe7ecad" ON "registry_item" ("domain") `); + await queryRunner.query(`ALTER TABLE "registry_item" ADD CONSTRAINT "FK_fb9d21ba0abb83223263df6bcb3" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "registry_item" DROP CONSTRAINT "FK_fb9d21ba0abb83223263df6bcb3"`); + await queryRunner.query(`DROP INDEX "IDX_0a72bdfcdb97c0eca11fe7ecad"`); + await queryRunner.query(`DROP INDEX "IDX_22baca135bb8a3ea1a83d13df3"`); + await queryRunner.query(`DROP INDEX "IDX_fb9d21ba0abb83223263df6bcb"`); + await queryRunner.query(`DROP TABLE "registry_item"`); + } +} +exports.registry1610277136869 = registry1610277136869; diff --git a/packages/backend/migration/1610277585759-registry2.js b/packages/backend/migration/1610277585759-registry2.js new file mode 100644 index 000000000..aa1417e18 --- /dev/null +++ b/packages/backend/migration/1610277585759-registry2.js @@ -0,0 +1,16 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class registry21610277585759 { + constructor() { + this.name = 'registry21610277585759'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "registry_item" ADD "value" jsonb NOT NULL DEFAULT '{}'`); + await queryRunner.query(`COMMENT ON COLUMN "registry_item"."value" IS 'The value of the RegistryItem.'`); + } + async down(queryRunner) { + await queryRunner.query(`COMMENT ON COLUMN "registry_item"."value" IS 'The value of the RegistryItem.'`); + await queryRunner.query(`ALTER TABLE "registry_item" DROP COLUMN "value"`); + } +} +exports.registry21610277585759 = registry21610277585759; diff --git a/packages/backend/migration/1610283021566-registry3.js b/packages/backend/migration/1610283021566-registry3.js new file mode 100644 index 000000000..7089cee1f --- /dev/null +++ b/packages/backend/migration/1610283021566-registry3.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class registry31610283021566 { + constructor() { + this.name = 'registry31610283021566'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "registry_item" ALTER COLUMN "value" DROP NOT NULL`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "registry_item" ALTER COLUMN "value" SET NOT NULL`); + } +} +exports.registry31610283021566 = registry31610283021566; diff --git a/packages/backend/migration/1611354329133-followersUri.js b/packages/backend/migration/1611354329133-followersUri.js new file mode 100644 index 000000000..e944da73a --- /dev/null +++ b/packages/backend/migration/1611354329133-followersUri.js @@ -0,0 +1,16 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class followersUri1611354329133 { + constructor() { + this.name = 'followersUri1611354329133'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "user" ADD "followersUri" varchar(512) DEFAULT NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user"."followersUri" IS 'The URI of the user Follower Collection. It will be null if the origin of the user is local.'`); + } + async down(queryRunner) { + await queryRunner.query(`COMMENT ON COLUMN "user"."followersUri" IS 'The URI of the user Follower Collection. It will be null if the origin of the user is local.'`); + await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "followersUri"`); + } +} +exports.followersUri1611354329133 = followersUri1611354329133; diff --git a/packages/backend/migration/1611397665007-gallery.js b/packages/backend/migration/1611397665007-gallery.js new file mode 100644 index 000000000..9cf73cbcf --- /dev/null +++ b/packages/backend/migration/1611397665007-gallery.js @@ -0,0 +1,40 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class gallery1611397665007 { + constructor() { + this.name = 'gallery1611397665007'; + } + async up(queryRunner) { + await queryRunner.query(`CREATE TABLE "gallery_post" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL, "title" character varying(256) NOT NULL, "description" character varying(2048), "userId" character varying(32) NOT NULL, "fileIds" character varying(32) array NOT NULL DEFAULT '{}'::varchar[], "isSensitive" boolean NOT NULL DEFAULT false, "likedCount" integer NOT NULL DEFAULT '0', "tags" character varying(128) array NOT NULL DEFAULT '{}'::varchar[], CONSTRAINT "PK_8e90d7b6015f2c4518881b14753" PRIMARY KEY ("id")); COMMENT ON COLUMN "gallery_post"."createdAt" IS 'The created date of the GalleryPost.'; COMMENT ON COLUMN "gallery_post"."updatedAt" IS 'The updated date of the GalleryPost.'; COMMENT ON COLUMN "gallery_post"."userId" IS 'The ID of author.'; COMMENT ON COLUMN "gallery_post"."isSensitive" IS 'Whether the post is sensitive.'`); + await queryRunner.query(`CREATE INDEX "IDX_8f1a239bd077c8864a20c62c2c" ON "gallery_post" ("createdAt") `); + await queryRunner.query(`CREATE INDEX "IDX_f631d37835adb04792e361807c" ON "gallery_post" ("updatedAt") `); + await queryRunner.query(`CREATE INDEX "IDX_985b836dddd8615e432d7043dd" ON "gallery_post" ("userId") `); + await queryRunner.query(`CREATE INDEX "IDX_3ca50563facd913c425e7a89ee" ON "gallery_post" ("fileIds") `); + await queryRunner.query(`CREATE INDEX "IDX_f2d744d9a14d0dfb8b96cb7fc5" ON "gallery_post" ("isSensitive") `); + await queryRunner.query(`CREATE INDEX "IDX_1a165c68a49d08f11caffbd206" ON "gallery_post" ("likedCount") `); + await queryRunner.query(`CREATE INDEX "IDX_05cca34b985d1b8edc1d1e28df" ON "gallery_post" ("tags") `); + await queryRunner.query(`CREATE TABLE "gallery_like" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "postId" character varying(32) NOT NULL, CONSTRAINT "PK_853ab02be39b8de45cd720cc15f" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE INDEX "IDX_8fd5215095473061855ceb948c" ON "gallery_like" ("userId") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_df1b5f4099e99fb0bc5eae53b6" ON "gallery_like" ("userId", "postId") `); + await queryRunner.query(`ALTER TABLE "gallery_post" ADD CONSTRAINT "FK_985b836dddd8615e432d7043ddb" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "gallery_like" ADD CONSTRAINT "FK_8fd5215095473061855ceb948cf" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "gallery_like" ADD CONSTRAINT "FK_b1cb568bfe569e47b7051699fc8" FOREIGN KEY ("postId") REFERENCES "gallery_post"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "gallery_like" DROP CONSTRAINT "FK_b1cb568bfe569e47b7051699fc8"`); + await queryRunner.query(`ALTER TABLE "gallery_like" DROP CONSTRAINT "FK_8fd5215095473061855ceb948cf"`); + await queryRunner.query(`ALTER TABLE "gallery_post" DROP CONSTRAINT "FK_985b836dddd8615e432d7043ddb"`); + await queryRunner.query(`DROP INDEX "IDX_df1b5f4099e99fb0bc5eae53b6"`); + await queryRunner.query(`DROP INDEX "IDX_8fd5215095473061855ceb948c"`); + await queryRunner.query(`DROP TABLE "gallery_like"`); + await queryRunner.query(`DROP INDEX "IDX_05cca34b985d1b8edc1d1e28df"`); + await queryRunner.query(`DROP INDEX "IDX_1a165c68a49d08f11caffbd206"`); + await queryRunner.query(`DROP INDEX "IDX_f2d744d9a14d0dfb8b96cb7fc5"`); + await queryRunner.query(`DROP INDEX "IDX_3ca50563facd913c425e7a89ee"`); + await queryRunner.query(`DROP INDEX "IDX_985b836dddd8615e432d7043dd"`); + await queryRunner.query(`DROP INDEX "IDX_f631d37835adb04792e361807c"`); + await queryRunner.query(`DROP INDEX "IDX_8f1a239bd077c8864a20c62c2c"`); + await queryRunner.query(`DROP TABLE "gallery_post"`); + } +} +exports.gallery1611397665007 = gallery1611397665007; diff --git a/packages/backend/migration/1611547387175-objectStorageS3ForcePathStyle.js b/packages/backend/migration/1611547387175-objectStorageS3ForcePathStyle.js new file mode 100644 index 000000000..50a618994 --- /dev/null +++ b/packages/backend/migration/1611547387175-objectStorageS3ForcePathStyle.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class objectStorageS3ForcePathStyle1611547387175 { + constructor() { + this.name = 'objectStorageS3ForcePathStyle1611547387175'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" ADD "objectStorageS3ForcePathStyle" boolean NOT NULL DEFAULT true`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStorageS3ForcePathStyle"`); + } +} +exports.objectStorageS3ForcePathStyle1611547387175 = objectStorageS3ForcePathStyle1611547387175; diff --git a/packages/backend/migration/1612619156584-announcement-email.js b/packages/backend/migration/1612619156584-announcement-email.js new file mode 100644 index 000000000..bbd04679b --- /dev/null +++ b/packages/backend/migration/1612619156584-announcement-email.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class announcementEmail1612619156584 { + constructor() { + this.name = 'announcementEmail1612619156584'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "user_profile" ADD "receiveAnnouncementEmail" boolean NOT NULL DEFAULT true`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "receiveAnnouncementEmail"`); + } +} +exports.announcementEmail1612619156584 = announcementEmail1612619156584; diff --git a/packages/backend/migration/1613155914446-emailNotificationTypes.js b/packages/backend/migration/1613155914446-emailNotificationTypes.js new file mode 100644 index 000000000..30fa4924b --- /dev/null +++ b/packages/backend/migration/1613155914446-emailNotificationTypes.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class emailNotificationTypes1613155914446 { + constructor() { + this.name = 'emailNotificationTypes1613155914446'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "user_profile" ADD "emailNotificationTypes" jsonb NOT NULL DEFAULT '["follow","receiveFollowRequest","groupInvited"]'`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "emailNotificationTypes"`); + } +} +exports.emailNotificationTypes1613155914446 = emailNotificationTypes1613155914446; diff --git a/packages/backend/migration/1613181457597-user-lang.js b/packages/backend/migration/1613181457597-user-lang.js new file mode 100644 index 000000000..f6be7cdab --- /dev/null +++ b/packages/backend/migration/1613181457597-user-lang.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class userLang1613181457597 { + constructor() { + this.name = 'userLang1613181457597'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "user_profile" ADD "lang" character varying(32)`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "lang"`); + } +} +exports.userLang1613181457597 = userLang1613181457597; diff --git a/packages/backend/migration/1613503367223-use-bigint-for-driveUsage.js b/packages/backend/migration/1613503367223-use-bigint-for-driveUsage.js new file mode 100644 index 000000000..91956ad78 --- /dev/null +++ b/packages/backend/migration/1613503367223-use-bigint-for-driveUsage.js @@ -0,0 +1,15 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class useBigintForDriveUsage1613503367223 { + constructor() { + this.name = 'useBigintForDriveUsage1613503367223'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "instance" ALTER COLUMN "driveUsage" TYPE bigint`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "driveUsage"`); + await queryRunner.query(`ALTER TABLE "instance" ADD "driveUsage" integer NOT NULL DEFAULT 0`); + } +} +exports.useBigintForDriveUsage1613503367223 = useBigintForDriveUsage1613503367223; diff --git a/packages/backend/migration/1615965918224-chart-v2.js b/packages/backend/migration/1615965918224-chart-v2.js new file mode 100644 index 000000000..95f44879b --- /dev/null +++ b/packages/backend/migration/1615965918224-chart-v2.js @@ -0,0 +1,217 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class chartV21615965918224 { + constructor() { + this.name = 'chartV21615965918224'; + } + async up(queryRunner) { + await queryRunner.query(`DELETE FROM "__chart__active_users" WHERE "span" = 'day'`); + await queryRunner.query(`DELETE FROM "__chart__drive" WHERE "span" = 'day'`); + await queryRunner.query(`DELETE FROM "__chart__federation" WHERE "span" = 'day'`); + await queryRunner.query(`DELETE FROM "__chart__hashtag" WHERE "span" = 'day'`); + await queryRunner.query(`DELETE FROM "__chart__instance" WHERE "span" = 'day'`); + await queryRunner.query(`DELETE FROM "__chart__network" WHERE "span" = 'day'`); + await queryRunner.query(`DELETE FROM "__chart__notes" WHERE "span" = 'day'`); + await queryRunner.query(`DELETE FROM "__chart__per_user_drive" WHERE "span" = 'day'`); + await queryRunner.query(`DELETE FROM "__chart__per_user_following" WHERE "span" = 'day'`); + await queryRunner.query(`DELETE FROM "__chart__per_user_notes" WHERE "span" = 'day'`); + await queryRunner.query(`DELETE FROM "__chart__per_user_reaction" WHERE "span" = 'day'`); + await queryRunner.query(`DELETE FROM "__chart__test" WHERE "span" = 'day'`); + await queryRunner.query(`DELETE FROM "__chart__test_grouped" WHERE "span" = 'day'`); + await queryRunner.query(`DELETE FROM "__chart__test_unique" WHERE "span" = 'day'`); + await queryRunner.query(`DELETE FROM "__chart__users" WHERE "span" = 'day'`); + await queryRunner.query(`DROP INDEX "IDX_15e91a03aeeac9dbccdf43fc06"`); + await queryRunner.query(`DROP INDEX "IDX_20f57cc8f142c131340ee16742"`); + await queryRunner.query(`DROP INDEX "IDX_c26e2c1cbb6e911e0554b27416"`); + await queryRunner.query(`DROP INDEX "IDX_3fa0d0f17ca72e3dc80999a032"`); + await queryRunner.query(`DROP INDEX "IDX_6e1df243476e20cbf86572ecc0"`); + await queryRunner.query(`DROP INDEX "IDX_06690fc959f1c9fdaf21928222"`); + await queryRunner.query(`DROP INDEX "IDX_e447064455928cf627590ef527"`); + await queryRunner.query(`DROP INDEX "IDX_2d416e6af791a82e338c79d480"`); + await queryRunner.query(`DROP INDEX "IDX_e9cd07672b37d8966cf3709283"`); + await queryRunner.query(`DROP INDEX "IDX_fcc181fb8283009c61cc4083ef"`); + await queryRunner.query(`DROP INDEX "IDX_49975586f50ed7b800fdd88fbd"`); + await queryRunner.query(`DROP INDEX "IDX_6d6f156ceefc6bc5f273a0e370"`); + await queryRunner.query(`DROP INDEX "IDX_c12f0af4a66cdd30c2287ce8aa"`); + await queryRunner.query(`DROP INDEX "IDX_d0a4f79af5a97b08f37b547197"`); + await queryRunner.query(`DROP INDEX "IDX_f5448d9633cff74208d850aabe"`); + await queryRunner.query(`DROP INDEX "IDX_f8dd01baeded2ffa833e0a610a"`); + await queryRunner.query(`DROP INDEX "IDX_08fac0eb3b11f04c200c0b40dd"`); + await queryRunner.query(`DROP INDEX "IDX_9ff6944f01acb756fdc92d7563"`); + await queryRunner.query(`DROP INDEX "IDX_e69096589f11e3baa98ddd64d0"`); + await queryRunner.query(`DROP INDEX "IDX_0c9a159c5082cbeef3ca6706b5"`); + await queryRunner.query(`DROP INDEX "IDX_924fc196c80ca24bae01dd37e4"`); + await queryRunner.query(`DROP INDEX "IDX_328f259961e60c4fa0bfcf55ca"`); + await queryRunner.query(`DROP INDEX "IDX_42ea9381f0fda8dfe0fa1c8b53"`); + await queryRunner.query(`DROP INDEX "IDX_f2aeafde2ae6fbad38e857631b"`); + await queryRunner.query(`DROP INDEX "IDX_f92dd6d03f8d994f29987f6214"`); + await queryRunner.query(`DROP INDEX "IDX_57b5458d0d3d6d1e7f13d4e57f"`); + await queryRunner.query(`DROP INDEX "IDX_4db3b84c7be0d3464714f3e0b1"`); + await queryRunner.query(`DROP INDEX "IDX_8d2cbbc8114d90d19b44d626b6"`); + await queryRunner.query(`DROP INDEX "IDX_046feeb12e9ef5f783f409866a"`); + await queryRunner.query(`DROP INDEX "IDX_f68a5ab958f9f5fa17a32ac23b"`); + await queryRunner.query(`DROP INDEX "IDX_65633a106bce43fc7c5c30a5c7"`); + await queryRunner.query(`DROP INDEX "IDX_edeb73c09c3143a81bcb34d569"`); + await queryRunner.query(`DROP INDEX "IDX_e316f01a6d24eb31db27f88262"`); + await queryRunner.query(`DROP INDEX "IDX_2be7ec6cebddc14dc11e206686"`); + await queryRunner.query(`DROP INDEX "IDX_a5133470f4825902e170328ca5"`); + await queryRunner.query(`DROP INDEX "IDX_84e661abb7bd1e51b690d4b017"`); + await queryRunner.query(`DROP INDEX "IDX_5c73bf61da4f6e6f15bae88ed1"`); + await queryRunner.query(`DROP INDEX "IDX_d70c86baedc68326be11f9c0ce"`); + await queryRunner.query(`DROP INDEX "IDX_66e1e1ecd2f29e57778af35b59"`); + await queryRunner.query(`DROP INDEX "IDX_92255988735563f0fe4aba1f05"`); + await queryRunner.query(`DROP INDEX "IDX_c5870993e25c3d5771f91f5003"`); + await queryRunner.query(`DROP INDEX "IDX_f170de677ea75ad4533de2723e"`); + await queryRunner.query(`DROP INDEX "IDX_7c184198ecf66a8d3ecb253ab3"`); + await queryRunner.query(`DROP INDEX "IDX_f091abb24193d50c653c6b77fc"`); + await queryRunner.query(`DROP INDEX "IDX_a770a57c70e668cc61590c9161"`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "span"`); + await queryRunner.query(`DROP TYPE "public"."__chart__active_users_span_enum"`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "unique"`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "___local_count"`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" DROP COLUMN "___remote_count"`); + await queryRunner.query(`ALTER TABLE "__chart__drive" DROP COLUMN "span"`); + await queryRunner.query(`DROP TYPE "public"."__chart__drive_span_enum"`); + await queryRunner.query(`ALTER TABLE "__chart__drive" DROP COLUMN "unique"`); + await queryRunner.query(`ALTER TABLE "__chart__federation" DROP COLUMN "span"`); + await queryRunner.query(`DROP TYPE "public"."__chart__federation_span_enum"`); + await queryRunner.query(`ALTER TABLE "__chart__federation" DROP COLUMN "unique"`); + await queryRunner.query(`ALTER TABLE "__chart__hashtag" DROP COLUMN "span"`); + await queryRunner.query(`DROP TYPE "public"."__chart__hashtag_span_enum"`); + await queryRunner.query(`ALTER TABLE "__chart__hashtag" DROP COLUMN "unique"`); + await queryRunner.query(`ALTER TABLE "__chart__hashtag" DROP COLUMN "___local_count"`); + await queryRunner.query(`ALTER TABLE "__chart__hashtag" DROP COLUMN "___remote_count"`); + await queryRunner.query(`ALTER TABLE "__chart__instance" DROP COLUMN "span"`); + await queryRunner.query(`DROP TYPE "public"."__chart__instance_span_enum"`); + await queryRunner.query(`ALTER TABLE "__chart__instance" DROP COLUMN "unique"`); + await queryRunner.query(`ALTER TABLE "__chart__network" DROP COLUMN "span"`); + await queryRunner.query(`DROP TYPE "public"."__chart__network_span_enum"`); + await queryRunner.query(`ALTER TABLE "__chart__network" DROP COLUMN "unique"`); + await queryRunner.query(`ALTER TABLE "__chart__notes" DROP COLUMN "span"`); + await queryRunner.query(`DROP TYPE "public"."__chart__notes_span_enum"`); + await queryRunner.query(`ALTER TABLE "__chart__notes" DROP COLUMN "unique"`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" DROP COLUMN "span"`); + await queryRunner.query(`DROP TYPE "public"."__chart__per_user_drive_span_enum"`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" DROP COLUMN "unique"`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" DROP COLUMN "span"`); + await queryRunner.query(`DROP TYPE "public"."__chart__per_user_following_span_enum"`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" DROP COLUMN "unique"`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" DROP COLUMN "span"`); + await queryRunner.query(`DROP TYPE "public"."__chart__per_user_notes_span_enum"`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" DROP COLUMN "unique"`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_reaction" DROP COLUMN "span"`); + await queryRunner.query(`DROP TYPE "public"."__chart__per_user_reaction_span_enum"`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_reaction" DROP COLUMN "unique"`); + await queryRunner.query(`ALTER TABLE "__chart__test_grouped" DROP COLUMN "span"`); + await queryRunner.query(`DROP TYPE "public"."__chart__test_grouped_span_enum"`); + await queryRunner.query(`ALTER TABLE "__chart__test_grouped" DROP COLUMN "unique"`); + await queryRunner.query(`ALTER TABLE "__chart__test_unique" DROP COLUMN "span"`); + await queryRunner.query(`DROP TYPE "public"."__chart__test_unique_span_enum"`); + await queryRunner.query(`ALTER TABLE "__chart__test_unique" DROP COLUMN "unique"`); + await queryRunner.query(`ALTER TABLE "__chart__test_unique" DROP COLUMN "___foo"`); + await queryRunner.query(`ALTER TABLE "__chart__test" DROP COLUMN "span"`); + await queryRunner.query(`DROP TYPE "public"."__chart__test_span_enum"`); + await queryRunner.query(`ALTER TABLE "__chart__test" DROP COLUMN "unique"`); + await queryRunner.query(`ALTER TABLE "__chart__users" DROP COLUMN "span"`); + await queryRunner.query(`DROP TYPE "public"."__chart__users_span_enum"`); + await queryRunner.query(`ALTER TABLE "__chart__users" DROP COLUMN "unique"`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "__chart__users" ADD "unique" jsonb NOT NULL DEFAULT '{}'`); + await queryRunner.query(`CREATE TYPE "public"."__chart__users_span_enum" AS ENUM('hour', 'day')`); + await queryRunner.query(`ALTER TABLE "__chart__users" ADD "span" "__chart__users_span_enum" NOT NULL`); + await queryRunner.query(`ALTER TABLE "__chart__test" ADD "unique" jsonb NOT NULL DEFAULT '{}'`); + await queryRunner.query(`CREATE TYPE "public"."__chart__test_span_enum" AS ENUM('hour', 'day')`); + await queryRunner.query(`ALTER TABLE "__chart__test" ADD "span" "__chart__test_span_enum" NOT NULL`); + await queryRunner.query(`ALTER TABLE "__chart__test_unique" ADD "___foo" bigint NOT NULL`); + await queryRunner.query(`ALTER TABLE "__chart__test_unique" ADD "unique" jsonb NOT NULL DEFAULT '{}'`); + await queryRunner.query(`CREATE TYPE "public"."__chart__test_unique_span_enum" AS ENUM('hour', 'day')`); + await queryRunner.query(`ALTER TABLE "__chart__test_unique" ADD "span" "__chart__test_unique_span_enum" NOT NULL`); + await queryRunner.query(`ALTER TABLE "__chart__test_grouped" ADD "unique" jsonb NOT NULL DEFAULT '{}'`); + await queryRunner.query(`CREATE TYPE "public"."__chart__test_grouped_span_enum" AS ENUM('hour', 'day')`); + await queryRunner.query(`ALTER TABLE "__chart__test_grouped" ADD "span" "__chart__test_grouped_span_enum" NOT NULL`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_reaction" ADD "unique" jsonb NOT NULL DEFAULT '{}'`); + await queryRunner.query(`CREATE TYPE "public"."__chart__per_user_reaction_span_enum" AS ENUM('hour', 'day')`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_reaction" ADD "span" "__chart__per_user_reaction_span_enum" NOT NULL`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ADD "unique" jsonb NOT NULL DEFAULT '{}'`); + await queryRunner.query(`CREATE TYPE "public"."__chart__per_user_notes_span_enum" AS ENUM('hour', 'day')`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_notes" ADD "span" "__chart__per_user_notes_span_enum" NOT NULL`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ADD "unique" jsonb NOT NULL DEFAULT '{}'`); + await queryRunner.query(`CREATE TYPE "public"."__chart__per_user_following_span_enum" AS ENUM('hour', 'day')`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_following" ADD "span" "__chart__per_user_following_span_enum" NOT NULL`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ADD "unique" jsonb NOT NULL DEFAULT '{}'`); + await queryRunner.query(`CREATE TYPE "public"."__chart__per_user_drive_span_enum" AS ENUM('hour', 'day')`); + await queryRunner.query(`ALTER TABLE "__chart__per_user_drive" ADD "span" "__chart__per_user_drive_span_enum" NOT NULL`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ADD "unique" jsonb NOT NULL DEFAULT '{}'`); + await queryRunner.query(`CREATE TYPE "public"."__chart__notes_span_enum" AS ENUM('hour', 'day')`); + await queryRunner.query(`ALTER TABLE "__chart__notes" ADD "span" "__chart__notes_span_enum" NOT NULL`); + await queryRunner.query(`ALTER TABLE "__chart__network" ADD "unique" jsonb NOT NULL DEFAULT '{}'`); + await queryRunner.query(`CREATE TYPE "public"."__chart__network_span_enum" AS ENUM('hour', 'day')`); + await queryRunner.query(`ALTER TABLE "__chart__network" ADD "span" "__chart__network_span_enum" NOT NULL`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ADD "unique" jsonb NOT NULL DEFAULT '{}'`); + await queryRunner.query(`CREATE TYPE "public"."__chart__instance_span_enum" AS ENUM('hour', 'day')`); + await queryRunner.query(`ALTER TABLE "__chart__instance" ADD "span" "__chart__instance_span_enum" NOT NULL`); + await queryRunner.query(`ALTER TABLE "__chart__hashtag" ADD "___remote_count" bigint NOT NULL`); + await queryRunner.query(`ALTER TABLE "__chart__hashtag" ADD "___local_count" bigint NOT NULL`); + await queryRunner.query(`ALTER TABLE "__chart__hashtag" ADD "unique" jsonb NOT NULL DEFAULT '{}'`); + await queryRunner.query(`CREATE TYPE "public"."__chart__hashtag_span_enum" AS ENUM('hour', 'day')`); + await queryRunner.query(`ALTER TABLE "__chart__hashtag" ADD "span" "__chart__hashtag_span_enum" NOT NULL`); + await queryRunner.query(`ALTER TABLE "__chart__federation" ADD "unique" jsonb NOT NULL DEFAULT '{}'`); + await queryRunner.query(`CREATE TYPE "public"."__chart__federation_span_enum" AS ENUM('hour', 'day')`); + await queryRunner.query(`ALTER TABLE "__chart__federation" ADD "span" "__chart__federation_span_enum" NOT NULL`); + await queryRunner.query(`ALTER TABLE "__chart__drive" ADD "unique" jsonb NOT NULL DEFAULT '{}'`); + await queryRunner.query(`CREATE TYPE "public"."__chart__drive_span_enum" AS ENUM('hour', 'day')`); + await queryRunner.query(`ALTER TABLE "__chart__drive" ADD "span" "__chart__drive_span_enum" NOT NULL`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "___remote_count" bigint NOT NULL`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "___local_count" bigint NOT NULL`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "unique" jsonb NOT NULL DEFAULT '{}'`); + await queryRunner.query(`CREATE TYPE "public"."__chart__active_users_span_enum" AS ENUM('hour', 'day')`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "span" "__chart__active_users_span_enum" NOT NULL`); + await queryRunner.query(`CREATE INDEX "IDX_a770a57c70e668cc61590c9161" ON "__chart__users" ("date", "group", "span") `); + await queryRunner.query(`CREATE INDEX "IDX_f091abb24193d50c653c6b77fc" ON "__chart__users" ("date", "span") `); + await queryRunner.query(`CREATE INDEX "IDX_7c184198ecf66a8d3ecb253ab3" ON "__chart__users" ("span") `); + await queryRunner.query(`CREATE INDEX "IDX_f170de677ea75ad4533de2723e" ON "__chart__test" ("date", "group", "span") `); + await queryRunner.query(`CREATE INDEX "IDX_c5870993e25c3d5771f91f5003" ON "__chart__test" ("date", "span") `); + await queryRunner.query(`CREATE INDEX "IDX_92255988735563f0fe4aba1f05" ON "__chart__test" ("span") `); + await queryRunner.query(`CREATE INDEX "IDX_66e1e1ecd2f29e57778af35b59" ON "__chart__test_unique" ("date", "group", "span") `); + await queryRunner.query(`CREATE INDEX "IDX_d70c86baedc68326be11f9c0ce" ON "__chart__test_unique" ("date", "span") `); + await queryRunner.query(`CREATE INDEX "IDX_5c73bf61da4f6e6f15bae88ed1" ON "__chart__test_unique" ("span") `); + await queryRunner.query(`CREATE INDEX "IDX_84e661abb7bd1e51b690d4b017" ON "__chart__test_grouped" ("date", "group", "span") `); + await queryRunner.query(`CREATE INDEX "IDX_a5133470f4825902e170328ca5" ON "__chart__test_grouped" ("date", "span") `); + await queryRunner.query(`CREATE INDEX "IDX_2be7ec6cebddc14dc11e206686" ON "__chart__test_grouped" ("span") `); + await queryRunner.query(`CREATE INDEX "IDX_e316f01a6d24eb31db27f88262" ON "__chart__per_user_reaction" ("date", "group", "span") `); + await queryRunner.query(`CREATE INDEX "IDX_edeb73c09c3143a81bcb34d569" ON "__chart__per_user_reaction" ("date", "span") `); + await queryRunner.query(`CREATE INDEX "IDX_65633a106bce43fc7c5c30a5c7" ON "__chart__per_user_reaction" ("span") `); + await queryRunner.query(`CREATE INDEX "IDX_f68a5ab958f9f5fa17a32ac23b" ON "__chart__per_user_notes" ("date", "group", "span") `); + await queryRunner.query(`CREATE INDEX "IDX_046feeb12e9ef5f783f409866a" ON "__chart__per_user_notes" ("date", "span") `); + await queryRunner.query(`CREATE INDEX "IDX_8d2cbbc8114d90d19b44d626b6" ON "__chart__per_user_notes" ("span") `); + await queryRunner.query(`CREATE INDEX "IDX_4db3b84c7be0d3464714f3e0b1" ON "__chart__per_user_following" ("date", "group", "span") `); + await queryRunner.query(`CREATE INDEX "IDX_57b5458d0d3d6d1e7f13d4e57f" ON "__chart__per_user_following" ("date", "span") `); + await queryRunner.query(`CREATE INDEX "IDX_f92dd6d03f8d994f29987f6214" ON "__chart__per_user_following" ("span") `); + await queryRunner.query(`CREATE INDEX "IDX_f2aeafde2ae6fbad38e857631b" ON "__chart__per_user_drive" ("date", "group", "span") `); + await queryRunner.query(`CREATE INDEX "IDX_42ea9381f0fda8dfe0fa1c8b53" ON "__chart__per_user_drive" ("date", "span") `); + await queryRunner.query(`CREATE INDEX "IDX_328f259961e60c4fa0bfcf55ca" ON "__chart__per_user_drive" ("span") `); + await queryRunner.query(`CREATE INDEX "IDX_924fc196c80ca24bae01dd37e4" ON "__chart__notes" ("date", "group", "span") `); + await queryRunner.query(`CREATE INDEX "IDX_0c9a159c5082cbeef3ca6706b5" ON "__chart__notes" ("date", "span") `); + await queryRunner.query(`CREATE INDEX "IDX_e69096589f11e3baa98ddd64d0" ON "__chart__notes" ("span") `); + await queryRunner.query(`CREATE INDEX "IDX_9ff6944f01acb756fdc92d7563" ON "__chart__network" ("date", "group", "span") `); + await queryRunner.query(`CREATE INDEX "IDX_08fac0eb3b11f04c200c0b40dd" ON "__chart__network" ("date", "span") `); + await queryRunner.query(`CREATE INDEX "IDX_f8dd01baeded2ffa833e0a610a" ON "__chart__network" ("span") `); + await queryRunner.query(`CREATE INDEX "IDX_f5448d9633cff74208d850aabe" ON "__chart__instance" ("date", "group", "span") `); + await queryRunner.query(`CREATE INDEX "IDX_d0a4f79af5a97b08f37b547197" ON "__chart__instance" ("date", "span") `); + await queryRunner.query(`CREATE INDEX "IDX_c12f0af4a66cdd30c2287ce8aa" ON "__chart__instance" ("span") `); + await queryRunner.query(`CREATE INDEX "IDX_6d6f156ceefc6bc5f273a0e370" ON "__chart__hashtag" ("date", "group", "span") `); + await queryRunner.query(`CREATE INDEX "IDX_49975586f50ed7b800fdd88fbd" ON "__chart__hashtag" ("date", "span") `); + await queryRunner.query(`CREATE INDEX "IDX_fcc181fb8283009c61cc4083ef" ON "__chart__hashtag" ("span") `); + await queryRunner.query(`CREATE INDEX "IDX_e9cd07672b37d8966cf3709283" ON "__chart__federation" ("date", "group", "span") `); + await queryRunner.query(`CREATE INDEX "IDX_2d416e6af791a82e338c79d480" ON "__chart__federation" ("date", "span") `); + await queryRunner.query(`CREATE INDEX "IDX_e447064455928cf627590ef527" ON "__chart__federation" ("span") `); + await queryRunner.query(`CREATE INDEX "IDX_06690fc959f1c9fdaf21928222" ON "__chart__drive" ("date", "group", "span") `); + await queryRunner.query(`CREATE INDEX "IDX_6e1df243476e20cbf86572ecc0" ON "__chart__drive" ("date", "span") `); + await queryRunner.query(`CREATE INDEX "IDX_3fa0d0f17ca72e3dc80999a032" ON "__chart__drive" ("span") `); + await queryRunner.query(`CREATE INDEX "IDX_c26e2c1cbb6e911e0554b27416" ON "__chart__active_users" ("date", "group", "span") `); + await queryRunner.query(`CREATE INDEX "IDX_20f57cc8f142c131340ee16742" ON "__chart__active_users" ("date", "span") `); + await queryRunner.query(`CREATE INDEX "IDX_15e91a03aeeac9dbccdf43fc06" ON "__chart__active_users" ("span") `); + } +} +exports.chartV21615965918224 = chartV21615965918224; diff --git a/packages/backend/migration/1615966519402-chart-v2-2.js b/packages/backend/migration/1615966519402-chart-v2-2.js new file mode 100644 index 000000000..85a83df1a --- /dev/null +++ b/packages/backend/migration/1615966519402-chart-v2-2.js @@ -0,0 +1,22 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class chartV221615966519402 { + constructor() { + this.name = 'chartV221615966519402'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "___local_users" character varying array NOT NULL DEFAULT '{}'::varchar[]`); + await queryRunner.query(`ALTER TABLE "__chart__active_users" ADD "___remote_users" character varying array NOT NULL DEFAULT '{}'::varchar[]`); + await queryRunner.query(`ALTER TABLE "__chart__hashtag" ADD "___local_users" character varying array NOT NULL DEFAULT '{}'::varchar[]`); + await queryRunner.query(`ALTER TABLE "__chart__hashtag" ADD "___remote_users" character varying array NOT NULL DEFAULT '{}'::varchar[]`); + await queryRunner.query(`ALTER TABLE "__chart__test_unique" ADD "___foo" character varying array NOT NULL DEFAULT '{}'::varchar[]`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "__chart__test_unique" DROP COLUMN "___foo"`); + await queryRunner.query(`ALTER TABLE "__chart__hashtag" DROP COLUMN "___remote_users"`); + await queryRunner.query(`ALTER TABLE "__chart__hashtag" 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 "___local_users"`); + } +} +exports.chartV221615966519402 = chartV221615966519402; diff --git a/packages/backend/migration/1618637372000-user-last-active-date.js b/packages/backend/migration/1618637372000-user-last-active-date.js new file mode 100644 index 000000000..03fc011e4 --- /dev/null +++ b/packages/backend/migration/1618637372000-user-last-active-date.js @@ -0,0 +1,16 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class userLastActiveDate1618637372000 { + constructor() { + this.name = 'userLastActiveDate1618637372000'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "user" ADD "lastActiveDate" TIMESTAMP WITH TIME ZONE DEFAULT NULL`); + await queryRunner.query(`CREATE INDEX "IDX_seoignmeoprigmkpodgrjmkpormg" ON "user" ("lastActiveDate") `); + } + async down(queryRunner) { + await queryRunner.query(`DROP INDEX "IDX_seoignmeoprigmkpodgrjmkpormg"`); + await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "lastActiveDate"`); + } +} +exports.userLastActiveDate1618637372000 = userLastActiveDate1618637372000; diff --git a/packages/backend/migration/1618639857000-user-hide-online-status.js b/packages/backend/migration/1618639857000-user-hide-online-status.js new file mode 100644 index 000000000..0b1e34100 --- /dev/null +++ b/packages/backend/migration/1618639857000-user-hide-online-status.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class userHideOnlineStatus1618639857000 { + constructor() { + this.name = 'userHideOnlineStatus1618639857000'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "user" ADD "hideOnlineStatus" boolean NOT NULL DEFAULT false`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "hideOnlineStatus"`); + } +} +exports.userHideOnlineStatus1618639857000 = userHideOnlineStatus1618639857000; diff --git a/packages/backend/migration/1619942102890-password-reset.js b/packages/backend/migration/1619942102890-password-reset.js new file mode 100644 index 000000000..9505be4b8 --- /dev/null +++ b/packages/backend/migration/1619942102890-password-reset.js @@ -0,0 +1,20 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class passwordReset1619942102890 { + constructor() { + this.name = 'passwordReset1619942102890'; + } + async up(queryRunner) { + await queryRunner.query(`CREATE TABLE "password_reset_request" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "token" character varying(256) NOT NULL, "userId" character varying(32) NOT NULL, CONSTRAINT "PK_fcf4b02eae1403a2edaf87fd074" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_0b575fa9a4cfe638a925949285" ON "password_reset_request" ("token") `); + await queryRunner.query(`CREATE INDEX "IDX_4bb7fd4a34492ae0e6cc8d30ac" ON "password_reset_request" ("userId") `); + await queryRunner.query(`ALTER TABLE "password_reset_request" ADD CONSTRAINT "FK_4bb7fd4a34492ae0e6cc8d30ac8" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "password_reset_request" DROP CONSTRAINT "FK_4bb7fd4a34492ae0e6cc8d30ac8"`); + await queryRunner.query(`DROP INDEX "IDX_4bb7fd4a34492ae0e6cc8d30ac"`); + await queryRunner.query(`DROP INDEX "IDX_0b575fa9a4cfe638a925949285"`); + await queryRunner.query(`DROP TABLE "password_reset_request"`); + } +} +exports.passwordReset1619942102890 = passwordReset1619942102890; diff --git a/packages/backend/migration/1620019354680-ad.js b/packages/backend/migration/1620019354680-ad.js new file mode 100644 index 000000000..655629bc3 --- /dev/null +++ b/packages/backend/migration/1620019354680-ad.js @@ -0,0 +1,18 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class ad1620019354680 { + constructor() { + this.name = 'ad1620019354680'; + } + async up(queryRunner) { + await queryRunner.query(`CREATE TABLE "ad" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "expiresAt" TIMESTAMP WITH TIME ZONE NOT NULL, "place" character varying(32) NOT NULL, "priority" character varying(32) NOT NULL, "url" character varying(1024) NOT NULL, "imageUrl" character varying(1024) NOT NULL, "memo" character varying(8192) NOT NULL, CONSTRAINT "PK_0193d5ef09746e88e9ea92c634d" PRIMARY KEY ("id")); COMMENT ON COLUMN "ad"."createdAt" IS 'The created date of the Ad.'; COMMENT ON COLUMN "ad"."expiresAt" IS 'The expired date of the Ad.'`); + await queryRunner.query(`CREATE INDEX "IDX_1129c2ef687fc272df040bafaa" ON "ad" ("createdAt") `); + await queryRunner.query(`CREATE INDEX "IDX_2da24ce20ad209f1d9dc032457" ON "ad" ("expiresAt") `); + } + async down(queryRunner) { + await queryRunner.query(`DROP INDEX "IDX_2da24ce20ad209f1d9dc032457"`); + await queryRunner.query(`DROP INDEX "IDX_1129c2ef687fc272df040bafaa"`); + await queryRunner.query(`DROP TABLE "ad"`); + } +} +exports.ad1620019354680 = ad1620019354680; diff --git a/packages/backend/migration/1620364649428-ad2.js b/packages/backend/migration/1620364649428-ad2.js new file mode 100644 index 000000000..7f2213f6a --- /dev/null +++ b/packages/backend/migration/1620364649428-ad2.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class ad21620364649428 { + constructor() { + this.name = 'ad21620364649428'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "ad" ADD "ratio" integer NOT NULL DEFAULT '1'`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "ad" DROP COLUMN "ratio"`); + } +} +exports.ad21620364649428 = ad21620364649428; diff --git a/packages/backend/migration/1621479946000-add-note-indexes.js b/packages/backend/migration/1621479946000-add-note-indexes.js new file mode 100644 index 000000000..1bf9827f6 --- /dev/null +++ b/packages/backend/migration/1621479946000-add-note-indexes.js @@ -0,0 +1,16 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class addNoteIndexes1621479946000 { + constructor() { + this.name = 'addNoteIndexes1621479946000'; + } + async up(queryRunner) { + await queryRunner.query(`CREATE INDEX "IDX_NOTE_MENTIONS" ON "note" USING gin ("mentions")`, undefined); + await queryRunner.query(`CREATE INDEX "IDX_NOTE_VISIBLE_USER_IDS" ON "note" USING gin ("visibleUserIds")`, undefined); + } + async down(queryRunner) { + await queryRunner.query(`DROP INDEX "IDX_NOTE_MENTIONS"`, undefined); + await queryRunner.query(`DROP INDEX "IDX_NOTE_VISIBLE_USER_IDS"`, undefined); + } +} +exports.addNoteIndexes1621479946000 = addNoteIndexes1621479946000; diff --git a/packages/backend/migration/1622679304522-user-profile-description-length.js b/packages/backend/migration/1622679304522-user-profile-description-length.js new file mode 100644 index 000000000..237870d6c --- /dev/null +++ b/packages/backend/migration/1622679304522-user-profile-description-length.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class userProfileDescriptionLength1622679304522 { + constructor() { + this.name = 'userProfileDescriptionLength1622679304522'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "user_profile" ALTER COLUMN "description" TYPE character varying(2048)`, undefined); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "user_profile" ALTER COLUMN "description" TYPE character varying(1024)`, undefined); + } +} +exports.userProfileDescriptionLength1622679304522 = userProfileDescriptionLength1622679304522; diff --git a/packages/backend/migration/1622681548499-log-message-length.js b/packages/backend/migration/1622681548499-log-message-length.js new file mode 100644 index 000000000..cb2ad288b --- /dev/null +++ b/packages/backend/migration/1622681548499-log-message-length.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class logMessageLength1622681548499 { + constructor() { + this.name = 'logMessageLength1622681548499'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "log" ALTER COLUMN "message" TYPE character varying(2048)`, undefined); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "log" ALTER COLUMN "message" TYPE character varying(1024)`, undefined); + } +} +exports.logMessageLength1622681548499 = logMessageLength1622681548499; diff --git a/packages/backend/migration/1629004542760-chart-reindex.js b/packages/backend/migration/1629004542760-chart-reindex.js new file mode 100644 index 000000000..927ea312e --- /dev/null +++ b/packages/backend/migration/1629004542760-chart-reindex.js @@ -0,0 +1,182 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class chartReindex1629004542760 { + constructor() { + this.name = 'chartReindex1629004542760'; + } + async up(queryRunner) { + await queryRunner.query(`DELETE FROM "__chart__active_users" a USING "__chart__active_users" b WHERE a.id < b.id AND ((a.group IS NULL AND b.group IS NULL) OR a.group = b.group) AND a.date = b.date;`); + await queryRunner.query(`DELETE FROM "__chart__drive" a USING "__chart__drive" b WHERE a.id < b.id AND ((a.group IS NULL AND b.group IS NULL) OR a.group = b.group) AND a.date = b.date;`); + await queryRunner.query(`DELETE FROM "__chart__federation" a USING "__chart__federation" b WHERE a.id < b.id AND ((a.group IS NULL AND b.group IS NULL) OR a.group = b.group) AND a.date = b.date;`); + await queryRunner.query(`DELETE FROM "__chart__hashtag" a USING "__chart__hashtag" b WHERE a.id < b.id AND ((a.group IS NULL AND b.group IS NULL) OR a.group = b.group) AND a.date = b.date;`); + await queryRunner.query(`DELETE FROM "__chart__instance" a USING "__chart__instance" b WHERE a.id < b.id AND ((a.group IS NULL AND b.group IS NULL) OR a.group = b.group) AND a.date = b.date;`); + await queryRunner.query(`DELETE FROM "__chart__network" a USING "__chart__network" b WHERE a.id < b.id AND ((a.group IS NULL AND b.group IS NULL) OR a.group = b.group) AND a.date = b.date;`); + await queryRunner.query(`DELETE FROM "__chart__notes" a USING "__chart__notes" b WHERE a.id < b.id AND ((a.group IS NULL AND b.group IS NULL) OR a.group = b.group) AND a.date = b.date;`); + await queryRunner.query(`DELETE FROM "__chart__per_user_drive" a USING "__chart__per_user_drive" b WHERE a.id < b.id AND ((a.group IS NULL AND b.group IS NULL) OR a.group = b.group) AND a.date = b.date;`); + await queryRunner.query(`DELETE FROM "__chart__per_user_following" a USING "__chart__per_user_following" b WHERE a.id < b.id AND ((a.group IS NULL AND b.group IS NULL) OR a.group = b.group) AND a.date = b.date;`); + await queryRunner.query(`DELETE FROM "__chart__per_user_notes" a USING "__chart__per_user_notes" b WHERE a.id < b.id AND ((a.group IS NULL AND b.group IS NULL) OR a.group = b.group) AND a.date = b.date;`); + await queryRunner.query(`DELETE FROM "__chart__per_user_reaction" a USING "__chart__per_user_reaction" b WHERE a.id < b.id AND ((a.group IS NULL AND b.group IS NULL) OR a.group = b.group) AND a.date = b.date;`); + await queryRunner.query(`DELETE FROM "__chart__test_grouped" a USING "__chart__test_grouped" b WHERE a.id < b.id AND ((a.group IS NULL AND b.group IS NULL) OR a.group = b.group) AND a.date = b.date;`); + await queryRunner.query(`DELETE FROM "__chart__test_unique" a USING "__chart__test_unique" b WHERE a.id < b.id AND ((a.group IS NULL AND b.group IS NULL) OR a.group = b.group) AND a.date = b.date;`); + await queryRunner.query(`DELETE FROM "__chart__users" a USING "__chart__users" b WHERE a.id < b.id AND ((a.group IS NULL AND b.group IS NULL) OR a.group = b.group) AND a.date = b.date;`); + await queryRunner.query(`DROP INDEX "IDX_0ad37b7ef50f4ddc84363d7ccc"`); + await queryRunner.query(`DROP INDEX "IDX_00ed5f86db1f7efafb1978bf21"`); + await queryRunner.query(`DROP INDEX "IDX_9a3ed15a30ab7e3a37702e6e08"`); + await queryRunner.query(`DROP INDEX "IDX_13565815f618a1ff53886c5b28"`); + await queryRunner.query(`DROP INDEX "IDX_7a170f67425e62a8fabb76c872"`); + await queryRunner.query(`DROP INDEX "IDX_3313d7288855ec105b5bbf6c21"`); + await queryRunner.query(`DROP INDEX "IDX_36cb699c49580d4e6c2e6159f9"`); + await queryRunner.query(`DROP INDEX "IDX_76e87c7bfc5d925fcbba405d84"`); + await queryRunner.query(`DROP INDEX "IDX_dd907becf76104e4b656659e6b"`); + await queryRunner.query(`DROP INDEX "IDX_07747a1038c05f532a718fe1de"`); + await queryRunner.query(`DROP INDEX "IDX_99a7d2faaef84a6f728d714ad6"`); + await queryRunner.query(`DROP INDEX "IDX_25a97c02003338124b2b75fdbc"`); + await queryRunner.query(`DROP INDEX "IDX_6b8f34a1a64b06014b6fb66824"`); + await queryRunner.query(`DROP INDEX "IDX_da8a46ba84ca1d8bb5a29bfb63"`); + await queryRunner.query(`DROP INDEX "IDX_39ee857ab2f23493037c6b6631"`); + await queryRunner.query(`DROP INDEX "IDX_a1efd3e0048a5f2793a47360dc"`); + await queryRunner.query(`DROP INDEX "IDX_7b5da130992ec9df96712d4290"`); + await queryRunner.query(`DROP INDEX "IDX_0a905b992fecd2b5c3fb98759e"`); + await queryRunner.query(`DROP INDEX "IDX_42eb716a37d381cdf566192b2b"`); + await queryRunner.query(`DROP INDEX "IDX_7036f2957151588b813185c794"`); + await queryRunner.query(`DROP INDEX "IDX_f09d543e3acb16c5976bdb31fa"`); + await queryRunner.query(`DROP INDEX "IDX_5f86db6492274e07c1a3cdf286"`); + await queryRunner.query(`DROP INDEX "IDX_e496ca8096d28f6b9b509264dc"`); + await queryRunner.query(`DROP INDEX "IDX_30bf67687f483ace115c5ca642"`); + await queryRunner.query(`DROP INDEX "IDX_7af07790712aa3438ff6773f3b"`); + await queryRunner.query(`DROP INDEX "IDX_4b3593098b6edc9c5afe36b18b"`); + await queryRunner.query(`DROP INDEX "IDX_b77d4dd9562c3a899d9a286fcd"`); + await queryRunner.query(`DROP INDEX "IDX_84234bd1abb873f07329681c83"`); + await queryRunner.query(`DROP INDEX "IDX_55bf20f366979f2436de99206b"`); + await queryRunner.query(`DROP INDEX "IDX_5048e9daccbbbc6d567bb142d3"`); + await queryRunner.query(`DROP INDEX "IDX_f7bf4c62059764c2c2bb40fdab"`); + await queryRunner.query(`DROP INDEX "IDX_8cf3156fd7a6b15c43459c6e3b"`); + await queryRunner.query(`DROP INDEX "IDX_229a41ad465f9205f1f5703291"`); + await queryRunner.query(`DROP INDEX "IDX_0c641990ecf47d2545df4edb75"`); + await queryRunner.query(`DROP INDEX "IDX_234dff3c0b56a6150b95431ab9"`); + await queryRunner.query(`DROP INDEX "IDX_b14489029e4b3aaf4bba5fb524"`); + await queryRunner.query(`DROP INDEX "IDX_437bab3c6061d90f6bb65fd2cc"`); + await queryRunner.query(`DROP INDEX "IDX_bbfa573a8181018851ed0b6357"`); + await queryRunner.query(`DROP INDEX "IDX_a0cd75442dd10d0643a17c4a49"`); + await queryRunner.query(`DROP INDEX "IDX_b070a906db04b44c67c6c2144d"`); + await queryRunner.query(`DROP INDEX "IDX_d41cce6aee1a50bfc062038f9b"`); + await queryRunner.query(`DROP INDEX "IDX_a319e5dbf47e8a17497623beae"`); + await queryRunner.query(`DROP INDEX "IDX_845254b3eaf708ae8a6cac3026"`); + await queryRunner.query(`DROP INDEX "IDX_ed9b95919c672a13008e9487ee"`); + await queryRunner.query(`DROP INDEX "IDX_337e9599f278bd7537fe30876f"`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_9a3ed15a30ab7e3a37702e6e08" ON "__chart__active_users" ("date", "group") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_60c5c6e7e538c09aa274ecd1cf" ON "__chart__active_users" ("date") WHERE "group" IS NULL`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_3313d7288855ec105b5bbf6c21" ON "__chart__drive" ("date", "group") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_ceab80a6729f8e2e6f5b8a1a3d" ON "__chart__drive" ("date") WHERE "group" IS NULL`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_dd907becf76104e4b656659e6b" ON "__chart__federation" ("date", "group") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_eddfed8fb40305a04c6f941050" ON "__chart__federation" ("date") WHERE "group" IS NULL`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_25a97c02003338124b2b75fdbc" ON "__chart__hashtag" ("date", "group") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_53a3604b939e2b479eb2cfaac8" ON "__chart__hashtag" ("date") WHERE "group" IS NULL`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_39ee857ab2f23493037c6b6631" ON "__chart__instance" ("date", "group") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_8111b817b9818c04d7eb8475b1" ON "__chart__instance" ("date") WHERE "group" IS NULL`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_0a905b992fecd2b5c3fb98759e" ON "__chart__network" ("date", "group") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_2082327b2699ce924fa654afc5" ON "__chart__network" ("date") WHERE "group" IS NULL`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_f09d543e3acb16c5976bdb31fa" ON "__chart__notes" ("date", "group") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_e60c358aaced5aab8900a4af31" ON "__chart__notes" ("date") WHERE "group" IS NULL`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_30bf67687f483ace115c5ca642" ON "__chart__per_user_drive" ("date", "group") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_a9a806d466b314f253a1a611c4" ON "__chart__per_user_drive" ("date") WHERE "group" IS NULL`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_b77d4dd9562c3a899d9a286fcd" ON "__chart__per_user_following" ("date", "group") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_dabbb38a51ab86ee3cab291326" ON "__chart__per_user_following" ("date") WHERE "group" IS NULL`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_5048e9daccbbbc6d567bb142d3" ON "__chart__per_user_notes" ("date", "group") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_583a157ed0cf0ed1b5ec2a833f" ON "__chart__per_user_notes" ("date") WHERE "group" IS NULL`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_229a41ad465f9205f1f5703291" ON "__chart__per_user_reaction" ("date", "group") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_3b7697a96f522d0478972e6d6f" ON "__chart__per_user_reaction" ("date") WHERE "group" IS NULL`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_b14489029e4b3aaf4bba5fb524" ON "__chart__test_grouped" ("date", "group") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_da522b4008a9f5d7743b87ad55" ON "__chart__test_grouped" ("date") WHERE "group" IS NULL`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_a0cd75442dd10d0643a17c4a49" ON "__chart__test_unique" ("date", "group") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_16effb2e888f6763673b579f80" ON "__chart__test_unique" ("date") WHERE "group" IS NULL`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_a319e5dbf47e8a17497623beae" ON "__chart__test" ("date", "group") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_dab383a36f3c9db4a0c9b02cf3" ON "__chart__test" ("date") WHERE "group" IS NULL`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_337e9599f278bd7537fe30876f" ON "__chart__users" ("date", "group") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_66feba81e1795d176d06c0b1e6" ON "__chart__users" ("date") WHERE "group" IS NULL`); + } + async down(queryRunner) { + await queryRunner.query(`DROP INDEX "IDX_66feba81e1795d176d06c0b1e6"`); + await queryRunner.query(`DROP INDEX "IDX_337e9599f278bd7537fe30876f"`); + await queryRunner.query(`DROP INDEX "IDX_dab383a36f3c9db4a0c9b02cf3"`); + await queryRunner.query(`DROP INDEX "IDX_a319e5dbf47e8a17497623beae"`); + await queryRunner.query(`DROP INDEX "IDX_16effb2e888f6763673b579f80"`); + await queryRunner.query(`DROP INDEX "IDX_a0cd75442dd10d0643a17c4a49"`); + await queryRunner.query(`DROP INDEX "IDX_da522b4008a9f5d7743b87ad55"`); + await queryRunner.query(`DROP INDEX "IDX_b14489029e4b3aaf4bba5fb524"`); + await queryRunner.query(`DROP INDEX "IDX_3b7697a96f522d0478972e6d6f"`); + await queryRunner.query(`DROP INDEX "IDX_229a41ad465f9205f1f5703291"`); + await queryRunner.query(`DROP INDEX "IDX_583a157ed0cf0ed1b5ec2a833f"`); + await queryRunner.query(`DROP INDEX "IDX_5048e9daccbbbc6d567bb142d3"`); + await queryRunner.query(`DROP INDEX "IDX_dabbb38a51ab86ee3cab291326"`); + await queryRunner.query(`DROP INDEX "IDX_b77d4dd9562c3a899d9a286fcd"`); + await queryRunner.query(`DROP INDEX "IDX_a9a806d466b314f253a1a611c4"`); + await queryRunner.query(`DROP INDEX "IDX_30bf67687f483ace115c5ca642"`); + await queryRunner.query(`DROP INDEX "IDX_e60c358aaced5aab8900a4af31"`); + await queryRunner.query(`DROP INDEX "IDX_f09d543e3acb16c5976bdb31fa"`); + await queryRunner.query(`DROP INDEX "IDX_2082327b2699ce924fa654afc5"`); + await queryRunner.query(`DROP INDEX "IDX_0a905b992fecd2b5c3fb98759e"`); + await queryRunner.query(`DROP INDEX "IDX_8111b817b9818c04d7eb8475b1"`); + await queryRunner.query(`DROP INDEX "IDX_39ee857ab2f23493037c6b6631"`); + await queryRunner.query(`DROP INDEX "IDX_53a3604b939e2b479eb2cfaac8"`); + await queryRunner.query(`DROP INDEX "IDX_25a97c02003338124b2b75fdbc"`); + await queryRunner.query(`DROP INDEX "IDX_eddfed8fb40305a04c6f941050"`); + await queryRunner.query(`DROP INDEX "IDX_dd907becf76104e4b656659e6b"`); + await queryRunner.query(`DROP INDEX "IDX_ceab80a6729f8e2e6f5b8a1a3d"`); + await queryRunner.query(`DROP INDEX "IDX_3313d7288855ec105b5bbf6c21"`); + await queryRunner.query(`DROP INDEX "IDX_60c5c6e7e538c09aa274ecd1cf"`); + await queryRunner.query(`DROP INDEX "IDX_9a3ed15a30ab7e3a37702e6e08"`); + await queryRunner.query(`DROP INDEX "IDX_a9021cc2e1feb5f72d3db6e9f5"`); + await queryRunner.query(`DROP INDEX "IDX_f22169eb10657bded6d875ac8f"`); + await queryRunner.query(`DROP INDEX "IDX_c8cc87bd0f2f4487d17c651fbf"`); + await queryRunner.query(`DROP INDEX "IDX_754499f9b2642336433769518d"`); + await queryRunner.query(`DROP INDEX "IDX_315c779174fe8247ab324f036e"`); + await queryRunner.query(`DROP INDEX "IDX_c5d46cbfda48b1c33ed852e21b"`); + await queryRunner.query(`CREATE INDEX "IDX_337e9599f278bd7537fe30876f" ON "__chart__users" ("date", "group") `); + await queryRunner.query(`CREATE INDEX "IDX_ed9b95919c672a13008e9487ee" ON "__chart__users" ("group") `); + await queryRunner.query(`CREATE INDEX "IDX_845254b3eaf708ae8a6cac3026" ON "__chart__users" ("date") `); + await queryRunner.query(`CREATE INDEX "IDX_a319e5dbf47e8a17497623beae" ON "__chart__test" ("date", "group") `); + await queryRunner.query(`CREATE INDEX "IDX_d41cce6aee1a50bfc062038f9b" ON "__chart__test" ("group") `); + await queryRunner.query(`CREATE INDEX "IDX_b070a906db04b44c67c6c2144d" ON "__chart__test" ("date") `); + await queryRunner.query(`CREATE INDEX "IDX_a0cd75442dd10d0643a17c4a49" ON "__chart__test_unique" ("date", "group") `); + await queryRunner.query(`CREATE INDEX "IDX_bbfa573a8181018851ed0b6357" ON "__chart__test_unique" ("group") `); + await queryRunner.query(`CREATE INDEX "IDX_437bab3c6061d90f6bb65fd2cc" ON "__chart__test_unique" ("date") `); + await queryRunner.query(`CREATE INDEX "IDX_b14489029e4b3aaf4bba5fb524" ON "__chart__test_grouped" ("date", "group") `); + await queryRunner.query(`CREATE INDEX "IDX_234dff3c0b56a6150b95431ab9" ON "__chart__test_grouped" ("group") `); + await queryRunner.query(`CREATE INDEX "IDX_0c641990ecf47d2545df4edb75" ON "__chart__test_grouped" ("date") `); + await queryRunner.query(`CREATE INDEX "IDX_229a41ad465f9205f1f5703291" ON "__chart__per_user_reaction" ("date", "group") `); + await queryRunner.query(`CREATE INDEX "IDX_8cf3156fd7a6b15c43459c6e3b" ON "__chart__per_user_reaction" ("group") `); + await queryRunner.query(`CREATE INDEX "IDX_f7bf4c62059764c2c2bb40fdab" ON "__chart__per_user_reaction" ("date") `); + await queryRunner.query(`CREATE INDEX "IDX_5048e9daccbbbc6d567bb142d3" ON "__chart__per_user_notes" ("date", "group") `); + await queryRunner.query(`CREATE INDEX "IDX_55bf20f366979f2436de99206b" ON "__chart__per_user_notes" ("group") `); + await queryRunner.query(`CREATE INDEX "IDX_84234bd1abb873f07329681c83" ON "__chart__per_user_notes" ("date") `); + await queryRunner.query(`CREATE INDEX "IDX_b77d4dd9562c3a899d9a286fcd" ON "__chart__per_user_following" ("date", "group") `); + await queryRunner.query(`CREATE INDEX "IDX_4b3593098b6edc9c5afe36b18b" ON "__chart__per_user_following" ("group") `); + await queryRunner.query(`CREATE INDEX "IDX_7af07790712aa3438ff6773f3b" ON "__chart__per_user_following" ("date") `); + await queryRunner.query(`CREATE INDEX "IDX_30bf67687f483ace115c5ca642" ON "__chart__per_user_drive" ("date", "group") `); + await queryRunner.query(`CREATE INDEX "IDX_e496ca8096d28f6b9b509264dc" ON "__chart__per_user_drive" ("group") `); + await queryRunner.query(`CREATE INDEX "IDX_5f86db6492274e07c1a3cdf286" ON "__chart__per_user_drive" ("date") `); + await queryRunner.query(`CREATE INDEX "IDX_f09d543e3acb16c5976bdb31fa" ON "__chart__notes" ("date", "group") `); + await queryRunner.query(`CREATE INDEX "IDX_7036f2957151588b813185c794" ON "__chart__notes" ("group") `); + await queryRunner.query(`CREATE INDEX "IDX_42eb716a37d381cdf566192b2b" ON "__chart__notes" ("date") `); + await queryRunner.query(`CREATE INDEX "IDX_0a905b992fecd2b5c3fb98759e" ON "__chart__network" ("date", "group") `); + await queryRunner.query(`CREATE INDEX "IDX_7b5da130992ec9df96712d4290" ON "__chart__network" ("group") `); + await queryRunner.query(`CREATE INDEX "IDX_a1efd3e0048a5f2793a47360dc" ON "__chart__network" ("date") `); + await queryRunner.query(`CREATE INDEX "IDX_39ee857ab2f23493037c6b6631" ON "__chart__instance" ("date", "group") `); + await queryRunner.query(`CREATE INDEX "IDX_da8a46ba84ca1d8bb5a29bfb63" ON "__chart__instance" ("group") `); + await queryRunner.query(`CREATE INDEX "IDX_6b8f34a1a64b06014b6fb66824" ON "__chart__instance" ("date") `); + await queryRunner.query(`CREATE INDEX "IDX_25a97c02003338124b2b75fdbc" ON "__chart__hashtag" ("date", "group") `); + await queryRunner.query(`CREATE INDEX "IDX_99a7d2faaef84a6f728d714ad6" ON "__chart__hashtag" ("group") `); + await queryRunner.query(`CREATE INDEX "IDX_07747a1038c05f532a718fe1de" ON "__chart__hashtag" ("date") `); + await queryRunner.query(`CREATE INDEX "IDX_dd907becf76104e4b656659e6b" ON "__chart__federation" ("date", "group") `); + await queryRunner.query(`CREATE INDEX "IDX_76e87c7bfc5d925fcbba405d84" ON "__chart__federation" ("group") `); + await queryRunner.query(`CREATE INDEX "IDX_36cb699c49580d4e6c2e6159f9" ON "__chart__federation" ("date") `); + await queryRunner.query(`CREATE INDEX "IDX_3313d7288855ec105b5bbf6c21" ON "__chart__drive" ("date", "group") `); + await queryRunner.query(`CREATE INDEX "IDX_7a170f67425e62a8fabb76c872" ON "__chart__drive" ("group") `); + await queryRunner.query(`CREATE INDEX "IDX_13565815f618a1ff53886c5b28" ON "__chart__drive" ("date") `); + await queryRunner.query(`CREATE INDEX "IDX_9a3ed15a30ab7e3a37702e6e08" ON "__chart__active_users" ("date", "group") `); + await queryRunner.query(`CREATE INDEX "IDX_00ed5f86db1f7efafb1978bf21" ON "__chart__active_users" ("group") `); + await queryRunner.query(`CREATE INDEX "IDX_0ad37b7ef50f4ddc84363d7ccc" ON "__chart__active_users" ("date") `); + } +} +exports.chartReindex1629004542760 = chartReindex1629004542760; diff --git a/packages/backend/migration/1629024377804-deepl-integration.js b/packages/backend/migration/1629024377804-deepl-integration.js new file mode 100644 index 000000000..a2bd3b188 --- /dev/null +++ b/packages/backend/migration/1629024377804-deepl-integration.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class deeplIntegration1629024377804 { + constructor() { + this.name = 'deeplIntegration1629024377804'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" ADD "deeplAuthKey" character varying(128)`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "deeplAuthKey"`); + } +} +exports.deeplIntegration1629024377804 = deeplIntegration1629024377804; diff --git a/packages/backend/migration/1629288472000-fix-channel-userId.js b/packages/backend/migration/1629288472000-fix-channel-userId.js new file mode 100644 index 000000000..d0e8baa06 --- /dev/null +++ b/packages/backend/migration/1629288472000-fix-channel-userId.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class fixChannelUserId1629288472000 { + constructor() { + this.name = 'fixChannelUserId1629288472000'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "channel" ALTER COLUMN "userId" DROP NOT NULL;`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "channel" ALTER COLUMN "userId" SET NOT NULL;`); + } +} +exports.fixChannelUserId1629288472000 = fixChannelUserId1629288472000; diff --git a/packages/backend/migration/1629512953000-user-is-deleted.js b/packages/backend/migration/1629512953000-user-is-deleted.js new file mode 100644 index 000000000..008390719 --- /dev/null +++ b/packages/backend/migration/1629512953000-user-is-deleted.js @@ -0,0 +1,15 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class isUserDeleted1629512953000 { + constructor() { + this.name = 'isUserDeleted1629512953000'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "user" ADD "isDeleted" boolean NOT NULL DEFAULT false`); + await queryRunner.query(`COMMENT ON COLUMN "user"."isDeleted" IS 'Whether the User is deleted.'`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "isDeleted"`); + } +} +exports.isUserDeleted1629512953000 = isUserDeleted1629512953000; diff --git a/packages/backend/migration/1629778475000-deepl-integration2.js b/packages/backend/migration/1629778475000-deepl-integration2.js new file mode 100644 index 000000000..50365f4bb --- /dev/null +++ b/packages/backend/migration/1629778475000-deepl-integration2.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class deeplIntegration21629778475000 { + constructor() { + this.name = 'deeplIntegration21629778475000'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" ADD "deeplIsPro" boolean NOT NULL DEFAULT false`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "deeplIsPro"`); + } +} +exports.deeplIntegration21629778475000 = deeplIntegration21629778475000; diff --git a/packages/backend/migration/1633068642000-email-required-for-signup.js b/packages/backend/migration/1633068642000-email-required-for-signup.js new file mode 100644 index 000000000..9793cac00 --- /dev/null +++ b/packages/backend/migration/1633068642000-email-required-for-signup.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class emailRequiredForSignup1633068642000 { + constructor() { + this.name = 'emailRequiredForSignup1633068642000'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" ADD "emailRequiredForSignup" boolean NOT NULL DEFAULT false`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "emailRequiredForSignup"`); + } +} +exports.emailRequiredForSignup1633068642000 = emailRequiredForSignup1633068642000; diff --git a/packages/backend/migration/1633071909016-user-pending.js b/packages/backend/migration/1633071909016-user-pending.js new file mode 100644 index 000000000..92a513994 --- /dev/null +++ b/packages/backend/migration/1633071909016-user-pending.js @@ -0,0 +1,16 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class userPending1633071909016 { + constructor() { + this.name = 'userPending1633071909016'; + } + async up(queryRunner) { + await queryRunner.query(`CREATE TABLE "user_pending" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "code" character varying(128) NOT NULL, "username" character varying(128) NOT NULL, "email" character varying(128) NOT NULL, "password" character varying(128) NOT NULL, CONSTRAINT "PK_d4c84e013c98ec02d19b8fbbafa" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_4e5c4c99175638ec0761714ab0" ON "user_pending" ("code") `); + } + async down(queryRunner) { + await queryRunner.query(`DROP INDEX "IDX_4e5c4c99175638ec0761714ab0"`); + await queryRunner.query(`DROP TABLE "user_pending"`); + } +} +exports.userPending1633071909016 = userPending1633071909016; diff --git a/packages/backend/migration/1634486652000-user-public-reactions.js b/packages/backend/migration/1634486652000-user-public-reactions.js new file mode 100644 index 000000000..1447abe6a --- /dev/null +++ b/packages/backend/migration/1634486652000-user-public-reactions.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class userPublicReactions1634486652000 { + constructor() { + this.name = 'userPublicReactions1634486652000'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "user_profile" ADD "publicReactions" boolean NOT NULL DEFAULT false`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "publicReactions"`); + } +} +exports.userPublicReactions1634486652000 = userPublicReactions1634486652000; diff --git a/packages/backend/migration/1634902659689-delete-log.js b/packages/backend/migration/1634902659689-delete-log.js new file mode 100644 index 000000000..b2162519f --- /dev/null +++ b/packages/backend/migration/1634902659689-delete-log.js @@ -0,0 +1,13 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class deleteLog1634902659689 { + constructor() { + this.name = 'deleteLog1634902659689'; + } + async up(queryRunner) { + await queryRunner.query(`DROP TABLE "log"`); + } + async down(queryRunner) { + } +} +exports.deleteLog1634902659689 = deleteLog1634902659689; diff --git a/packages/backend/migration/1635500777168-note-thread-mute.js b/packages/backend/migration/1635500777168-note-thread-mute.js new file mode 100644 index 000000000..1e0195274 --- /dev/null +++ b/packages/backend/migration/1635500777168-note-thread-mute.js @@ -0,0 +1,26 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class noteThreadMute1635500777168 { + constructor() { + this.name = 'noteThreadMute1635500777168'; + } + async up(queryRunner) { + await queryRunner.query(`CREATE TABLE "note_thread_muting" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "threadId" character varying(256) NOT NULL, CONSTRAINT "PK_ec5936d94d1a0369646d12a3a47" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE INDEX "IDX_29c11c7deb06615076f8c95b80" ON "note_thread_muting" ("userId") `); + await queryRunner.query(`CREATE INDEX "IDX_c426394644267453e76f036926" ON "note_thread_muting" ("threadId") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_ae7aab18a2641d3e5f25e0c4ea" ON "note_thread_muting" ("userId", "threadId") `); + await queryRunner.query(`ALTER TABLE "note" ADD "threadId" character varying(256)`); + await queryRunner.query(`CREATE INDEX "IDX_d4ebdef929896d6dc4a3c5bb48" ON "note" ("threadId") `); + await queryRunner.query(`ALTER TABLE "note_thread_muting" ADD CONSTRAINT "FK_29c11c7deb06615076f8c95b80a" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "note_thread_muting" DROP CONSTRAINT "FK_29c11c7deb06615076f8c95b80a"`); + await queryRunner.query(`DROP INDEX "public"."IDX_d4ebdef929896d6dc4a3c5bb48"`); + await queryRunner.query(`ALTER TABLE "note" DROP COLUMN "threadId"`); + await queryRunner.query(`DROP INDEX "public"."IDX_ae7aab18a2641d3e5f25e0c4ea"`); + await queryRunner.query(`DROP INDEX "public"."IDX_c426394644267453e76f036926"`); + await queryRunner.query(`DROP INDEX "public"."IDX_29c11c7deb06615076f8c95b80"`); + await queryRunner.query(`DROP TABLE "note_thread_muting"`); + } +} +exports.noteThreadMute1635500777168 = noteThreadMute1635500777168; diff --git a/packages/backend/migration/1636197624383-ff-visibility.js b/packages/backend/migration/1636197624383-ff-visibility.js new file mode 100644 index 000000000..9e8d5a3dc --- /dev/null +++ b/packages/backend/migration/1636197624383-ff-visibility.js @@ -0,0 +1,16 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class ffVisibility1636197624383 { + constructor() { + this.name = 'ffVisibility1636197624383'; + } + async up(queryRunner) { + await queryRunner.query(`CREATE TYPE "public"."user_profile_ffvisibility_enum" AS ENUM('public', 'followers', 'private')`); + await queryRunner.query(`ALTER TABLE "user_profile" ADD "ffVisibility" "public"."user_profile_ffvisibility_enum" NOT NULL DEFAULT 'public'`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "ffVisibility"`); + await queryRunner.query(`DROP TYPE "public"."user_profile_ffvisibility_enum"`); + } +} +exports.ffVisibility1636197624383 = ffVisibility1636197624383; diff --git a/packages/backend/migration/1636697408073-remove-via-mobile.js b/packages/backend/migration/1636697408073-remove-via-mobile.js new file mode 100644 index 000000000..bb5157cf1 --- /dev/null +++ b/packages/backend/migration/1636697408073-remove-via-mobile.js @@ -0,0 +1,13 @@ +const { MigrationInterface, QueryRunner } = require("typeorm"); + +module.exports = class removeViaMobile1636697408073 { + name = 'removeViaMobile1636697408073' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "note" DROP COLUMN "viaMobile"`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "note" ADD "viaMobile" boolean NOT NULL DEFAULT false`); + } +} diff --git a/packages/backend/ormconfig.js b/packages/backend/ormconfig.js new file mode 100644 index 000000000..524181cb8 --- /dev/null +++ b/packages/backend/ormconfig.js @@ -0,0 +1,17 @@ +const config = require('./built/config').default; +const entities = require('./built/db/postgre').entities; + +module.exports = { + type: 'postgres', + host: config.db.host, + port: config.db.port, + username: config.db.user, + password: config.db.pass, + database: config.db.db, + extra: config.db.extra, + entities: entities, + migrations: ['migration/*.js'], + cli: { + migrationsDir: 'migration' + } +}; diff --git a/packages/backend/package.json b/packages/backend/package.json new file mode 100644 index 000000000..6c41245e6 --- /dev/null +++ b/packages/backend/package.json @@ -0,0 +1,199 @@ +{ + "main": "./index.js", + "private": true, + "scripts": { + "init": "npm run migrate", + "build": "tsc -p tsconfig.json || echo done. && tsc-alias -p tsconfig.json", + "watch": "tsc -w -p tsconfig.json && tsc-alias -w -p tsconfig.json", + "lint": "eslint --quiet src/**/*.ts", + "mocha": "cross-env TS_NODE_FILES=true TS_NODE_TRANSPILE_ONLY=true TS_NODE_PROJECT=\"./test/tsconfig.json\" mocha", + "test": "npm run mocha" + }, + "resolutions": { + "chokidar": "^3.3.1", + "lodash": "^4.17.21" + }, + "dependencies": { + "@discordapp/twemoji": "13.1.0", + "@elastic/elasticsearch": "7.11.0", + "@koa/cors": "3.1.0", + "@koa/multer": "3.0.0", + "@koa/router": "9.0.1", + "@sinonjs/fake-timers": "7.1.2", + "@syuilo/aiscript": "0.11.1", + "@types/bcryptjs": "2.4.2", + "@types/bull": "3.15.5", + "@types/cbor": "6.0.0", + "@types/dateformat": "3.0.1", + "@types/escape-regexp": "0.0.0", + "@types/glob": "7.2.0", + "@types/is-url": "1.2.30", + "@types/js-yaml": "4.0.4", + "@types/jsdom": "16.2.13", + "@types/jsonld": "1.5.6", + "@types/koa": "2.13.4", + "@types/koa-bodyparser": "4.3.3", + "@types/koa-cors": "0.0.2", + "@types/koa-favicon": "2.0.21", + "@types/koa-logger": "3.1.2", + "@types/koa-mount": "4.0.1", + "@types/koa-send": "4.1.3", + "@types/koa-views": "7.0.0", + "@types/koa__cors": "3.0.3", + "@types/koa__multer": "2.0.4", + "@types/koa__router": "8.0.8", + "@types/mocha": "8.2.3", + "@types/node": "16.11.7", + "@types/node-fetch": "2.5.12", + "@types/nodemailer": "6.4.4", + "@types/nprogress": "0.2.0", + "@types/oauth": "0.9.1", + "@types/parse5": "6.0.2", + "@types/parsimmon": "1.10.6", + "@types/portscanner": "2.1.1", + "@types/pug": "2.0.5", + "@types/punycode": "2.1.0", + "@types/qrcode": "1.4.1", + "@types/random-seed": "0.3.3", + "@types/ratelimiter": "3.4.2", + "@types/redis": "2.8.32", + "@types/rename": "1.0.4", + "@types/request-stats": "3.0.0", + "@types/sanitize-html": "2.5.0", + "@types/seedrandom": "2.4.28", + "@types/sharp": "0.29.3", + "@types/sinonjs__fake-timers": "6.0.4", + "@types/speakeasy": "2.0.6", + "@types/throttle-debounce": "2.1.0", + "@types/tinycolor2": "1.4.3", + "@types/tmp": "0.2.2", + "@types/uuid": "8.3.1", + "@types/web-push": "3.3.2", + "@types/webpack": "5.28.0", + "@types/webpack-stream": "3.2.12", + "@types/websocket": "1.0.4", + "@types/ws": "8.2.0", + "@typescript-eslint/eslint-plugin": "5.3.1", + "@typescript-eslint/parser": "5.1.0", + "abort-controller": "3.0.0", + "autobind-decorator": "2.4.0", + "autosize": "4.0.4", + "autwh": "0.1.0", + "aws-sdk": "2.1013.0", + "bcryptjs": "2.4.3", + "blurhash": "1.1.4", + "broadcast-channel": "4.5.0", + "bull": "4.1.0", + "cacheable-lookup": "6.0.4", + "cafy": "15.2.1", + "cbor": "8.1.0", + "chalk": "4.1.2", + "chart.js": "3.6.0", + "chartjs-adapter-date-fns": "2.0.0", + "chartjs-plugin-zoom": "1.1.1", + "cli-highlight": "2.1.11", + "compare-versions": "3.6.0", + "concurrently": "6.3.0", + "content-disposition": "0.5.3", + "crc-32": "1.2.0", + "css-loader": "6.5.1", + "cssnano": "5.0.10", + "date-fns": "2.25.0", + "dateformat": "4.5.1", + "deep-email-validator": "0.1.18", + "escape-regexp": "0.0.1", + "eslint": "8.2.0", + "eslint-plugin-import": "2.25.3", + "eslint-plugin-vue": "8.0.3", + "eventemitter3": "4.0.7", + "feed": "4.2.2", + "file-type": "16.5.3", + "fluent-ffmpeg": "2.1.2", + "glob": "7.2.0", + "got": "11.8.2", + "hpagent": "0.1.2", + "http-signature": "1.3.5", + "idb-keyval": "5.1.3", + "insert-text-at-cursor": "0.3.0", + "ip-cidr": "3.0.4", + "is-svg": "4.3.1", + "js-yaml": "4.1.0", + "jsdom": "16.7.0", + "json5": "2.2.0", + "json5-loader": "4.0.1", + "jsonld": "5.2.0", + "jsrsasign": "8.0.20", + "koa": "2.13.4", + "koa-bodyparser": "4.3.0", + "koa-favicon": "2.1.0", + "koa-json-body": "5.3.0", + "koa-logger": "3.2.1", + "koa-mount": "4.0.0", + "koa-send": "5.0.1", + "koa-slow": "2.1.0", + "koa-views": "7.0.2", + "langmap": "0.0.16", + "mfm-js": "0.20.0", + "misskey-js": "0.0.8", + "mocha": "8.4.0", + "ms": "3.0.0-canary.1", + "multer": "1.4.3", + "nested-property": "4.0.0", + "node-fetch": "2.6.1", + "nodemailer": "6.7.0", + "os-utils": "0.0.14", + "parse5": "6.0.1", + "pg": "8.7.1", + "portscanner": "2.2.0", + "prismjs": "1.25.0", + "private-ip": "2.3.3", + "probe-image-size": "7.2.1", + "promise-limit": "2.7.0", + "pug": "3.0.2", + "punycode": "2.1.1", + "pureimage": "0.3.5", + "qrcode": "1.4.4", + "random-seed": "0.3.0", + "ratelimiter": "3.4.1", + "re2": "1.16.0", + "redis": "3.1.2", + "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.5.3", + "seedrandom": "3.0.5", + "sharp": "0.29.2", + "speakeasy": "2.0.0", + "strict-event-emitter-types": "2.0.0", + "stringz": "2.1.0", + "style-loader": "3.3.1", + "summaly": "2.4.1", + "syslog-pro": "1.0.0", + "systeminformation": "5.9.9", + "throttle-debounce": "3.0.1", + "tinycolor2": "1.4.2", + "tmp": "0.2.1", + "ts-loader": "9.2.6", + "ts-node": "10.4.0", + "tsc-alias": "1.3.10", + "tsconfig-paths": "3.11.0", + "twemoji-parser": "13.1.0", + "typeorm": "0.2.39", + "typescript": "4.4.4", + "ulid": "2.3.0", + "uuid": "8.3.2", + "web-push": "3.4.5", + "websocket": "1.0.34", + "ws": "8.2.3", + "xev": "2.0.1" + }, + "devDependencies": { + "@redocly/openapi-core": "1.0.0-beta.54", + "@types/fluent-ffmpeg": "2.1.17", + "cross-env": "7.0.3" + } +} diff --git a/packages/backend/src/boot/index.ts b/packages/backend/src/boot/index.ts new file mode 100644 index 000000000..1723c32dd --- /dev/null +++ b/packages/backend/src/boot/index.ts @@ -0,0 +1,79 @@ +import * as cluster from 'cluster'; +import * as chalk from 'chalk'; +import Xev from 'xev'; + +import Logger from '@/services/logger'; +import { envOption } from '../env'; + +// for typeorm +import 'reflect-metadata'; +import { masterMain } from './master'; +import { workerMain } from './worker'; + +const logger = new Logger('core', 'cyan'); +const clusterLogger = logger.createSubLogger('cluster', 'orange', false); +const ev = new Xev(); + +/** + * Init process + */ +export default async function() { + process.title = `Misskey (${cluster.isPrimary ? 'master' : 'worker'})`; + + if (cluster.isPrimary || envOption.disableClustering) { + await masterMain(); + + if (cluster.isPrimary) { + ev.mount(); + } + } + + if (cluster.isWorker || envOption.disableClustering) { + await workerMain(); + } + + // ユニットテスト時にMisskeyが子プロセスで起動された時のため + // それ以外のときは process.send は使えないので弾く + if (process.send) { + process.send('ok'); + } +} + +//#region Events + +// Listen new workers +cluster.on('fork', worker => { + clusterLogger.debug(`Process forked: [${worker.id}]`); +}); + +// Listen online workers +cluster.on('online', worker => { + clusterLogger.debug(`Process is now online: [${worker.id}]`); +}); + +// Listen for dying workers +cluster.on('exit', worker => { + // Replace the dead worker, + // we're not sentimental + clusterLogger.error(chalk.red(`[${worker.id}] died :(`)); + cluster.fork(); +}); + +// Display detail of unhandled promise rejection +if (!envOption.quiet) { + process.on('unhandledRejection', console.dir); +} + +// Display detail of uncaught exception +process.on('uncaughtException', err => { + try { + logger.error(err); + } catch { } +}); + +// Dying away... +process.on('exit', code => { + logger.info(`The process is going to exit with code ${code}`); +}); + +//#endregion diff --git a/packages/backend/src/boot/master.ts b/packages/backend/src/boot/master.ts new file mode 100644 index 000000000..eeb7017cb --- /dev/null +++ b/packages/backend/src/boot/master.ts @@ -0,0 +1,194 @@ +import * as fs from 'fs'; +import { fileURLToPath } from 'url'; +import { dirname } from 'path'; +import * as os from 'os'; +import * as cluster from 'cluster'; +import * as chalk from 'chalk'; +import * as portscanner from 'portscanner'; +import { getConnection } from 'typeorm'; + +import Logger from '@/services/logger'; +import loadConfig from '@/config/load'; +import { Config } from '@/config/types'; +import { lessThan } from '@/prelude/array'; +import { envOption } from '../env'; +import { showMachineInfo } from '@/misc/show-machine-info'; +import { initDb } from '../db/postgre'; + +//const _filename = fileURLToPath(import.meta.url); +const _filename = __filename; +const _dirname = dirname(_filename); + +const meta = JSON.parse(fs.readFileSync(`${_dirname}/../../../../built/meta.json`, 'utf-8')); + +const logger = new Logger('core', 'cyan'); +const bootLogger = logger.createSubLogger('boot', 'magenta', false); + +function greet() { + if (!envOption.quiet) { + //#region Misskey logo + const v = `v${meta.version}`; + console.log(' _____ _ _ '); + console.log(' | |_|___ ___| |_ ___ _ _ '); + console.log(' | | | | |_ -|_ -| \'_| -_| | |'); + console.log(' |_|_|_|_|___|___|_,_|___|_ |'); + console.log(' ' + chalk.gray(v) + (' |___|\n'.substr(v.length))); + //#endregion + + console.log(' Misskey is an open-source decentralized microblogging platform.'); + console.log(chalk.keyword('orange')(' If you like Misskey, please donate to support development. https://www.patreon.com/syuilo')); + + console.log(''); + console.log(chalk`--- ${os.hostname()} {gray (PID: ${process.pid.toString()})} ---`); + } + + bootLogger.info('Welcome to Misskey!'); + bootLogger.info(`Misskey v${meta.version}`, null, true); +} + +function isRoot() { + // maybe process.getuid will be undefined under not POSIX environment (e.g. Windows) + return process.getuid != null && process.getuid() === 0; +} + +/** + * Init master process + */ +export async function masterMain() { + let config!: Config; + + // initialize app + try { + greet(); + showEnvironment(); + await showMachineInfo(bootLogger); + showNodejsVersion(); + config = loadConfigBoot(); + await connectDb(); + await validatePort(config); + } catch (e) { + bootLogger.error('Fatal error occurred during initialization', null, true); + process.exit(1); + } + + bootLogger.succ('Misskey initialized'); + + if (!envOption.disableClustering) { + await spawnWorkers(config.clusterLimit); + } + + bootLogger.succ(`Now listening on port ${config.port} on ${config.url}`, null, true); + + if (!envOption.noDaemons) { + require('../daemons/server-stats').default(); + require('../daemons/queue-stats').default(); + require('../daemons/janitor').default(); + } +} + +const runningNodejsVersion = process.version.slice(1).split('.').map(x => parseInt(x, 10)); +const requiredNodejsVersion = [11, 7, 0]; +const satisfyNodejsVersion = !lessThan(runningNodejsVersion, requiredNodejsVersion); + +function showEnvironment(): void { + const env = process.env.NODE_ENV; + const logger = bootLogger.createSubLogger('env'); + logger.info(typeof env === 'undefined' ? 'NODE_ENV is not set' : `NODE_ENV: ${env}`); + + if (env !== 'production') { + logger.warn('The environment is not in production mode.'); + logger.warn('DO NOT USE FOR PRODUCTION PURPOSE!', null, true); + } + + logger.info(`You ${isRoot() ? '' : 'do not '}have root privileges`); +} + +function showNodejsVersion(): void { + const nodejsLogger = bootLogger.createSubLogger('nodejs'); + + nodejsLogger.info(`Version ${runningNodejsVersion.join('.')}`); + + if (!satisfyNodejsVersion) { + nodejsLogger.error(`Node.js version is less than ${requiredNodejsVersion.join('.')}. Please upgrade it.`, null, true); + process.exit(1); + } +} + +function loadConfigBoot(): Config { + const configLogger = bootLogger.createSubLogger('config'); + let config; + + try { + config = loadConfig(); + } catch (exception) { + if (typeof exception === 'string') { + configLogger.error(exception); + process.exit(1); + } + if (exception.code === 'ENOENT') { + configLogger.error('Configuration file not found', null, true); + process.exit(1); + } + throw exception; + } + + configLogger.succ('Loaded'); + + return config; +} + +async function connectDb(): Promise { + const dbLogger = bootLogger.createSubLogger('db'); + + // Try to connect to DB + try { + dbLogger.info('Connecting...'); + await initDb(); + const v = await getConnection().query('SHOW server_version').then(x => x[0].server_version); + dbLogger.succ(`Connected: v${v}`); + } catch (e) { + dbLogger.error('Cannot connect', null, true); + dbLogger.error(e); + process.exit(1); + } +} + +async function validatePort(config: Config): Promise { + const isWellKnownPort = (port: number) => port < 1024; + + async function isPortAvailable(port: number): Promise { + return await portscanner.checkPortStatus(port, '127.0.0.1') === 'closed'; + } + + if (config.port == null || Number.isNaN(config.port)) { + bootLogger.error('The port is not configured. Please configure port.', null, true); + process.exit(1); + } + + if (process.platform === 'linux' && isWellKnownPort(config.port) && !isRoot()) { + bootLogger.error('You need root privileges to listen on well-known port on Linux', null, true); + process.exit(1); + } + + if (!await isPortAvailable(config.port)) { + bootLogger.error(`Port ${config.port} is already in use`, null, true); + process.exit(1); + } +} + +async function spawnWorkers(limit: number = 1) { + const workers = Math.min(limit, os.cpus().length); + bootLogger.info(`Starting ${workers} worker${workers === 1 ? '' : 's'}...`); + await Promise.all([...Array(workers)].map(spawnWorker)); + bootLogger.succ('All workers started'); +} + +function spawnWorker(): Promise { + return new Promise(res => { + const worker = cluster.fork(); + worker.on('message', message => { + if (message !== 'ready') return; + res(); + }); + }); +} diff --git a/src/boot/worker.ts b/packages/backend/src/boot/worker.ts similarity index 100% rename from src/boot/worker.ts rename to packages/backend/src/boot/worker.ts diff --git a/src/config/index.ts b/packages/backend/src/config/index.ts similarity index 100% rename from src/config/index.ts rename to packages/backend/src/config/index.ts diff --git a/packages/backend/src/config/load.ts b/packages/backend/src/config/load.ts new file mode 100644 index 000000000..1b5457cdb --- /dev/null +++ b/packages/backend/src/config/load.ts @@ -0,0 +1,61 @@ +/** + * Config loader + */ + +import * as fs from 'fs'; +import { fileURLToPath } from 'url'; +import { dirname } from 'path'; +import * as yaml from 'js-yaml'; +import { Source, Mixin } from './types'; + +//const _filename = fileURLToPath(import.meta.url); +const _filename = __filename; +const _dirname = dirname(_filename); + +/** + * Path of configuration directory + */ +const dir = `${_dirname}/../../../../.config`; + +/** + * Path of configuration file + */ +const path = process.env.NODE_ENV === 'test' + ? `${dir}/test.yml` + : `${dir}/default.yml`; + +export default function load() { + const meta = JSON.parse(fs.readFileSync(`${_dirname}/../../../../built/meta.json`, 'utf-8')); + const config = yaml.load(fs.readFileSync(path, 'utf-8')) as Source; + + const mixin = {} as Mixin; + + const url = tryCreateUrl(config.url); + + config.url = url.origin; + + config.port = config.port || parseInt(process.env.PORT || '', 10); + + mixin.version = meta.version; + mixin.host = url.host; + mixin.hostname = url.hostname; + mixin.scheme = url.protocol.replace(/:$/, ''); + mixin.wsScheme = mixin.scheme.replace('http', 'ws'); + mixin.wsUrl = `${mixin.wsScheme}://${mixin.host}`; + mixin.apiUrl = `${mixin.scheme}://${mixin.host}/api`; + mixin.authUrl = `${mixin.scheme}://${mixin.host}/auth`; + mixin.driveUrl = `${mixin.scheme}://${mixin.host}/files`; + mixin.userAgent = `Misskey/${meta.version} (${config.url})`; + + if (!config.redis.prefix) config.redis.prefix = mixin.host; + + return Object.assign(config, mixin); +} + +function tryCreateUrl(url: string) { + try { + return new URL(url); + } catch (e) { + throw `url="${url}" is not a valid URL.`; + } +} diff --git a/src/config/types.ts b/packages/backend/src/config/types.ts similarity index 100% rename from src/config/types.ts rename to packages/backend/src/config/types.ts diff --git a/src/const.ts b/packages/backend/src/const.ts similarity index 100% rename from src/const.ts rename to packages/backend/src/const.ts diff --git a/src/daemons/janitor.ts b/packages/backend/src/daemons/janitor.ts similarity index 100% rename from src/daemons/janitor.ts rename to packages/backend/src/daemons/janitor.ts diff --git a/src/daemons/queue-stats.ts b/packages/backend/src/daemons/queue-stats.ts similarity index 100% rename from src/daemons/queue-stats.ts rename to packages/backend/src/daemons/queue-stats.ts diff --git a/src/daemons/server-stats.ts b/packages/backend/src/daemons/server-stats.ts similarity index 100% rename from src/daemons/server-stats.ts rename to packages/backend/src/daemons/server-stats.ts diff --git a/src/db/elasticsearch.ts b/packages/backend/src/db/elasticsearch.ts similarity index 100% rename from src/db/elasticsearch.ts rename to packages/backend/src/db/elasticsearch.ts diff --git a/src/db/logger.ts b/packages/backend/src/db/logger.ts similarity index 100% rename from src/db/logger.ts rename to packages/backend/src/db/logger.ts diff --git a/packages/backend/src/db/postgre.ts b/packages/backend/src/db/postgre.ts new file mode 100644 index 000000000..efbacf3d1 --- /dev/null +++ b/packages/backend/src/db/postgre.ts @@ -0,0 +1,241 @@ +// https://github.com/typeorm/typeorm/issues/2400 +const types = require('pg').types; +types.setTypeParser(20, Number); + +import { createConnection, Logger, getConnection } from 'typeorm'; +import config from '@/config/index'; +import { entities as charts } from '@/services/chart/entities'; +import { dbLogger } from './logger'; +import * as highlight from 'cli-highlight'; + +import { User } from '@/models/entities/user'; +import { DriveFile } from '@/models/entities/drive-file'; +import { DriveFolder } from '@/models/entities/drive-folder'; +import { AccessToken } from '@/models/entities/access-token'; +import { App } from '@/models/entities/app'; +import { PollVote } from '@/models/entities/poll-vote'; +import { Note } from '@/models/entities/note'; +import { NoteReaction } from '@/models/entities/note-reaction'; +import { NoteWatching } from '@/models/entities/note-watching'; +import { NoteThreadMuting } from '@/models/entities/note-thread-muting'; +import { NoteUnread } from '@/models/entities/note-unread'; +import { Notification } from '@/models/entities/notification'; +import { Meta } from '@/models/entities/meta'; +import { Following } from '@/models/entities/following'; +import { Instance } from '@/models/entities/instance'; +import { Muting } from '@/models/entities/muting'; +import { SwSubscription } from '@/models/entities/sw-subscription'; +import { Blocking } from '@/models/entities/blocking'; +import { UserList } from '@/models/entities/user-list'; +import { UserListJoining } from '@/models/entities/user-list-joining'; +import { UserGroup } from '@/models/entities/user-group'; +import { UserGroupJoining } from '@/models/entities/user-group-joining'; +import { UserGroupInvitation } from '@/models/entities/user-group-invitation'; +import { Hashtag } from '@/models/entities/hashtag'; +import { NoteFavorite } from '@/models/entities/note-favorite'; +import { AbuseUserReport } from '@/models/entities/abuse-user-report'; +import { RegistrationTicket } from '@/models/entities/registration-tickets'; +import { MessagingMessage } from '@/models/entities/messaging-message'; +import { Signin } from '@/models/entities/signin'; +import { AuthSession } from '@/models/entities/auth-session'; +import { FollowRequest } from '@/models/entities/follow-request'; +import { Emoji } from '@/models/entities/emoji'; +import { ReversiGame } from '@/models/entities/games/reversi/game'; +import { ReversiMatching } from '@/models/entities/games/reversi/matching'; +import { UserNotePining } from '@/models/entities/user-note-pining'; +import { Poll } from '@/models/entities/poll'; +import { UserKeypair } from '@/models/entities/user-keypair'; +import { UserPublickey } from '@/models/entities/user-publickey'; +import { UserProfile } from '@/models/entities/user-profile'; +import { UserSecurityKey } from '@/models/entities/user-security-key'; +import { AttestationChallenge } from '@/models/entities/attestation-challenge'; +import { Page } from '@/models/entities/page'; +import { PageLike } from '@/models/entities/page-like'; +import { GalleryPost } from '@/models/entities/gallery-post'; +import { GalleryLike } from '@/models/entities/gallery-like'; +import { ModerationLog } from '@/models/entities/moderation-log'; +import { UsedUsername } from '@/models/entities/used-username'; +import { Announcement } from '@/models/entities/announcement'; +import { AnnouncementRead } from '@/models/entities/announcement-read'; +import { Clip } from '@/models/entities/clip'; +import { ClipNote } from '@/models/entities/clip-note'; +import { Antenna } from '@/models/entities/antenna'; +import { AntennaNote } from '@/models/entities/antenna-note'; +import { PromoNote } from '@/models/entities/promo-note'; +import { PromoRead } from '@/models/entities/promo-read'; +import { envOption } from '../env'; +import { Relay } from '@/models/entities/relay'; +import { MutedNote } from '@/models/entities/muted-note'; +import { Channel } from '@/models/entities/channel'; +import { ChannelFollowing } from '@/models/entities/channel-following'; +import { ChannelNotePining } from '@/models/entities/channel-note-pining'; +import { RegistryItem } from '@/models/entities/registry-item'; +import { Ad } from '@/models/entities/ad'; +import { PasswordResetRequest } from '@/models/entities/password-reset-request'; +import { UserPending } from '@/models/entities/user-pending'; + +const sqlLogger = dbLogger.createSubLogger('sql', 'white', false); + +class MyCustomLogger implements Logger { + private highlight(sql: string) { + return highlight.highlight(sql, { + language: 'sql', ignoreIllegals: true, + }); + } + + public logQuery(query: string, parameters?: any[]) { + if (envOption.verbose) { + sqlLogger.info(this.highlight(query)); + } + } + + public logQueryError(error: string, query: string, parameters?: any[]) { + sqlLogger.error(this.highlight(query)); + } + + public logQuerySlow(time: number, query: string, parameters?: any[]) { + sqlLogger.warn(this.highlight(query)); + } + + public logSchemaBuild(message: string) { + sqlLogger.info(message); + } + + public log(message: string) { + sqlLogger.info(message); + } + + public logMigration(message: string) { + sqlLogger.info(message); + } +} + +export const entities = [ + Announcement, + AnnouncementRead, + Meta, + Instance, + App, + AuthSession, + AccessToken, + User, + UserProfile, + UserKeypair, + UserPublickey, + UserList, + UserListJoining, + UserGroup, + UserGroupJoining, + UserGroupInvitation, + UserNotePining, + UserSecurityKey, + UsedUsername, + AttestationChallenge, + Following, + FollowRequest, + Muting, + Blocking, + Note, + NoteFavorite, + NoteReaction, + NoteWatching, + NoteThreadMuting, + NoteUnread, + Page, + PageLike, + GalleryPost, + GalleryLike, + DriveFile, + DriveFolder, + Poll, + PollVote, + Notification, + Emoji, + Hashtag, + SwSubscription, + AbuseUserReport, + RegistrationTicket, + MessagingMessage, + Signin, + ModerationLog, + Clip, + ClipNote, + Antenna, + AntennaNote, + PromoNote, + PromoRead, + ReversiGame, + ReversiMatching, + Relay, + MutedNote, + Channel, + ChannelFollowing, + ChannelNotePining, + RegistryItem, + Ad, + PasswordResetRequest, + UserPending, + ...charts as any +]; + +export function initDb(justBorrow = false, sync = false, forceRecreate = false) { + if (!forceRecreate) { + try { + const conn = getConnection(); + return Promise.resolve(conn); + } catch (e) {} + } + + const log = process.env.NODE_ENV != 'production'; + + return createConnection({ + type: 'postgres', + host: config.db.host, + port: config.db.port, + username: config.db.user, + password: config.db.pass, + database: config.db.db, + extra: config.db.extra, + synchronize: process.env.NODE_ENV === 'test' || sync, + dropSchema: process.env.NODE_ENV === 'test' && !justBorrow, + cache: !config.db.disableCache ? { + type: 'redis', + options: { + host: config.redis.host, + port: config.redis.port, + password: config.redis.pass, + prefix: `${config.redis.prefix}:query:`, + db: config.redis.db || 0 + } + } : false, + logging: log, + logger: log ? new MyCustomLogger() : undefined, + entities: entities + }); +} + +export async function resetDb() { + const reset = async () => { + const conn = await getConnection(); + const tables = await conn.query(`SELECT relname AS "table" + FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace) + WHERE nspname NOT IN ('pg_catalog', 'information_schema') + AND C.relkind = 'r' + AND nspname !~ '^pg_toast';`); + await Promise.all(tables.map(t => t.table).map(x => conn.query(`DELETE FROM "${x}" CASCADE`))); + }; + + for (let i = 1; i <= 3; i++) { + try { + await reset(); + } catch (e) { + if (i === 3) { + throw e; + } else { + await new Promise(resolve => setTimeout(resolve, 1000)); + continue; + } + } + break; + } +} diff --git a/src/db/redis.ts b/packages/backend/src/db/redis.ts similarity index 100% rename from src/db/redis.ts rename to packages/backend/src/db/redis.ts diff --git a/src/env.ts b/packages/backend/src/env.ts similarity index 100% rename from src/env.ts rename to packages/backend/src/env.ts diff --git a/src/games/reversi/core.ts b/packages/backend/src/games/reversi/core.ts similarity index 100% rename from src/games/reversi/core.ts rename to packages/backend/src/games/reversi/core.ts diff --git a/src/games/reversi/maps.ts b/packages/backend/src/games/reversi/maps.ts similarity index 100% rename from src/games/reversi/maps.ts rename to packages/backend/src/games/reversi/maps.ts diff --git a/src/games/reversi/package.json b/packages/backend/src/games/reversi/package.json similarity index 100% rename from src/games/reversi/package.json rename to packages/backend/src/games/reversi/package.json diff --git a/src/games/reversi/tsconfig.json b/packages/backend/src/games/reversi/tsconfig.json similarity index 100% rename from src/games/reversi/tsconfig.json rename to packages/backend/src/games/reversi/tsconfig.json diff --git a/src/global.d.ts b/packages/backend/src/global.d.ts similarity index 100% rename from src/global.d.ts rename to packages/backend/src/global.d.ts diff --git a/packages/backend/src/index.ts b/packages/backend/src/index.ts new file mode 100644 index 000000000..5e4e377ab --- /dev/null +++ b/packages/backend/src/index.ts @@ -0,0 +1,11 @@ +/** + * Misskey Entry Point! + */ + +Error.stackTraceLimit = Infinity; + +require('events').EventEmitter.defaultMaxListeners = 128; + +import boot from './boot/index'; + +boot(); diff --git a/packages/backend/src/mfm/from-html.ts b/packages/backend/src/mfm/from-html.ts new file mode 100644 index 000000000..43e16d80c --- /dev/null +++ b/packages/backend/src/mfm/from-html.ts @@ -0,0 +1,210 @@ +import * as parse5 from 'parse5'; +import treeAdapter = require('parse5/lib/tree-adapters/default'); +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; + + const dom = parse5.parseFragment(html); + + let text = ''; + + for (const n of dom.childNodes) { + analyze(n); + } + + return text.trim(); + + function getText(node: parse5.Node): string { + if (treeAdapter.isTextNode(node)) return node.value; + if (!treeAdapter.isElementNode(node)) return ''; + if (node.nodeName === 'br') return '\n'; + + if (node.childNodes) { + return node.childNodes.map(n => getText(n)).join(''); + } + + return ''; + } + + function appendChildren(childNodes: parse5.ChildNode[]): void { + if (childNodes) { + for (const n of childNodes) { + analyze(n); + } + } + } + + function analyze(node: parse5.Node) { + if (treeAdapter.isTextNode(node)) { + text += node.value; + return; + } + + // Skip comment or document type node + if (!treeAdapter.isElementNode(node)) return; + + switch (node.nodeName) { + case 'br': { + text += '\n'; + break; + } + + case 'a': + { + const txt = getText(node); + const rel = node.attrs.find(x => x.name === 'rel'); + const href = node.attrs.find(x => x.name === 'href'); + + // ハッシュタグ + if (hashtagNames && href && hashtagNames.map(x => x.toLowerCase()).includes(txt.toLowerCase())) { + text += txt; + // メンション + } else if (txt.startsWith('@') && !(rel && rel.value.match(/^me /))) { + const part = txt.split('@'); + + if (part.length === 2 && href) { + //#region ホスト名部分が省略されているので復元する + const acct = `${txt}@${(new URL(href.value)).hostname}`; + text += acct; + //#endregion + } else if (part.length === 3) { + text += txt; + } + // その他 + } else { + const generateLink = () => { + if (!href && !txt) { + return ''; + } + if (!href) { + return txt; + } + if (!txt || txt === href.value) { // #6383: Missing text node + if (href.value.match(urlRegexFull)) { + return href.value; + } else { + return `<${href.value}>`; + } + } + if (href.value.match(urlRegex) && !href.value.match(urlRegexFull)) { + return `[${txt}](<${href.value}>)`; // #6846 + } else { + return `[${txt}](${href.value})`; + } + }; + + text += generateLink(); + } + break; + } + + case 'h1': + { + text += '【'; + appendChildren(node.childNodes); + text += '】\n'; + break; + } + + case 'b': + case 'strong': + { + text += '**'; + appendChildren(node.childNodes); + text += '**'; + break; + } + + case 'small': + { + text += ''; + appendChildren(node.childNodes); + text += ''; + break; + } + + case 's': + case 'del': + { + text += '~~'; + appendChildren(node.childNodes); + text += '~~'; + break; + } + + case 'i': + case 'em': + { + text += ''; + appendChildren(node.childNodes); + text += ''; + break; + } + + // block code (
)
+			case 'pre': {
+				if (node.childNodes.length === 1 && node.childNodes[0].nodeName === 'code') {
+					text += '\n```\n';
+					text += getText(node.childNodes[0]);
+					text += '\n```\n';
+				} else {
+					appendChildren(node.childNodes);
+				}
+				break;
+			}
+
+			// inline code ()
+			case 'code': {
+				text += '`';
+				appendChildren(node.childNodes);
+				text += '`';
+				break;
+			}
+
+			case 'blockquote': {
+				const t = getText(node);
+				if (t) {
+					text += '> ';
+					text += t.split('\n').join(`\n> `);
+				}
+				break;
+			}
+
+			case 'p':
+			case 'h2':
+			case 'h3':
+			case 'h4':
+			case 'h5':
+			case 'h6':
+			{
+				text += '\n\n';
+				appendChildren(node.childNodes);
+				break;
+			}
+
+			// other block elements
+			case 'div':
+			case 'header':
+			case 'footer':
+			case 'article':
+			case 'li':
+			case 'dt':
+			case 'dd':
+			{
+				text += '\n';
+				appendChildren(node.childNodes);
+				break;
+			}
+
+			default:	// includes inline elements
+			{
+				appendChildren(node.childNodes);
+				break;
+			}
+		}
+	}
+}
diff --git a/packages/backend/src/mfm/to-html.ts b/packages/backend/src/mfm/to-html.ts
new file mode 100644
index 000000000..343c76fb3
--- /dev/null
+++ b/packages/backend/src/mfm/to-html.ts
@@ -0,0 +1,153 @@
+import { JSDOM } from 'jsdom';
+import * as mfm from 'mfm-js';
+import config from '@/config/index';
+import { intersperse } from '@/prelude/array';
+import { IMentionedRemoteUsers } from '@/models/entities/note';
+
+export function toHtml(nodes: mfm.MfmNode[] | null, mentionedRemoteUsers: IMentionedRemoteUsers = []) {
+	if (nodes == null) {
+		return null;
+	}
+
+	const { window } = new JSDOM('');
+
+	const doc = window.document;
+
+	function appendChildren(children: mfm.MfmNode[], targetElement: any): void {
+		if (children) {
+			for (const child of children.map(x => (handlers as any)[x.type](x))) targetElement.appendChild(child);
+		}
+	}
+
+	const handlers: { [K in mfm.MfmNode['type']]: (node: mfm.NodeType) => any } = {
+		bold(node) {
+			const el = doc.createElement('b');
+			appendChildren(node.children, el);
+			return el;
+		},
+
+		small(node) {
+			const el = doc.createElement('small');
+			appendChildren(node.children, el);
+			return el;
+		},
+
+		strike(node) {
+			const el = doc.createElement('del');
+			appendChildren(node.children, el);
+			return el;
+		},
+
+		italic(node) {
+			const el = doc.createElement('i');
+			appendChildren(node.children, el);
+			return el;
+		},
+
+		fn(node) {
+			const el = doc.createElement('i');
+			appendChildren(node.children, el);
+			return el;
+		},
+
+		blockCode(node) {
+			const pre = doc.createElement('pre');
+			const inner = doc.createElement('code');
+			inner.textContent = node.props.code;
+			pre.appendChild(inner);
+			return pre;
+		},
+
+		center(node) {
+			const el = doc.createElement('div');
+			appendChildren(node.children, el);
+			return el;
+		},
+
+		emojiCode(node) {
+			return doc.createTextNode(`\u200B:${node.props.name}:\u200B`);
+		},
+
+		unicodeEmoji(node) {
+			return doc.createTextNode(node.props.emoji);
+		},
+
+		hashtag(node) {
+			const a = doc.createElement('a');
+			a.href = `${config.url}/tags/${node.props.hashtag}`;
+			a.textContent = `#${node.props.hashtag}`;
+			a.setAttribute('rel', 'tag');
+			return a;
+		},
+
+		inlineCode(node) {
+			const el = doc.createElement('code');
+			el.textContent = node.props.code;
+			return el;
+		},
+
+		mathInline(node) {
+			const el = doc.createElement('code');
+			el.textContent = node.props.formula;
+			return el;
+		},
+
+		mathBlock(node) {
+			const el = doc.createElement('code');
+			el.textContent = node.props.formula;
+			return el;
+		},
+
+		link(node) {
+			const a = doc.createElement('a');
+			a.href = node.props.url;
+			appendChildren(node.children, a);
+			return a;
+		},
+
+		mention(node) {
+			const a = doc.createElement('a');
+			const { username, host, acct } = node.props;
+			const remoteUserInfo = mentionedRemoteUsers.find(remoteUser => remoteUser.username === username && remoteUser.host === host);
+			a.href = remoteUserInfo ? (remoteUserInfo.url ? remoteUserInfo.url : remoteUserInfo.uri) : `${config.url}/${acct}`;
+			a.className = 'u-url mention';
+			a.textContent = acct;
+			return a;
+		},
+
+		quote(node) {
+			const el = doc.createElement('blockquote');
+			appendChildren(node.children, el);
+			return el;
+		},
+
+		text(node) {
+			const el = doc.createElement('span');
+			const nodes = node.props.text.split(/\r\n|\r|\n/).map(x => doc.createTextNode(x));
+
+			for (const x of intersperse('br', nodes)) {
+				el.appendChild(x === 'br' ? doc.createElement('br') : x);
+			}
+
+			return el;
+		},
+
+		url(node) {
+			const a = doc.createElement('a');
+			a.href = node.props.url;
+			a.textContent = node.props.url;
+			return a;
+		},
+
+		search(node) {
+			const a = doc.createElement('a');
+			a.href = `https://www.google.com/search?q=${node.props.query}`;
+			a.textContent = node.props.content;
+			return a;
+		}
+	};
+
+	appendChildren(nodes, doc.body);
+
+	return `

${doc.body.innerHTML}

`; +} diff --git a/src/misc/antenna-cache.ts b/packages/backend/src/misc/antenna-cache.ts similarity index 100% rename from src/misc/antenna-cache.ts rename to packages/backend/src/misc/antenna-cache.ts diff --git a/src/misc/api-permissions.ts b/packages/backend/src/misc/api-permissions.ts similarity index 100% rename from src/misc/api-permissions.ts rename to packages/backend/src/misc/api-permissions.ts diff --git a/src/misc/app-lock.ts b/packages/backend/src/misc/app-lock.ts similarity index 100% rename from src/misc/app-lock.ts rename to packages/backend/src/misc/app-lock.ts diff --git a/src/misc/before-shutdown.ts b/packages/backend/src/misc/before-shutdown.ts similarity index 100% rename from src/misc/before-shutdown.ts rename to packages/backend/src/misc/before-shutdown.ts diff --git a/src/misc/cache.ts b/packages/backend/src/misc/cache.ts similarity index 100% rename from src/misc/cache.ts rename to packages/backend/src/misc/cache.ts diff --git a/packages/backend/src/misc/cafy-id.ts b/packages/backend/src/misc/cafy-id.ts new file mode 100644 index 000000000..dd81c5c4c --- /dev/null +++ b/packages/backend/src/misc/cafy-id.ts @@ -0,0 +1,33 @@ +import { Context } from 'cafy'; + +// eslint-disable-next-line @typescript-eslint/ban-types +export class ID extends Context { + public readonly name = 'ID'; + + constructor(optional = false, nullable = false) { + super(optional, nullable); + + this.push((v: any) => { + if (typeof v !== 'string') { + return new Error('must-be-an-id'); + } + return true; + }); + } + + public getType() { + return super.getType('String'); + } + + public makeOptional(): ID { + return new ID(true, false); + } + + public makeNullable(): ID { + return new ID(false, true); + } + + public makeOptionalNullable(): ID { + return new ID(true, true); + } +} diff --git a/src/misc/captcha.ts b/packages/backend/src/misc/captcha.ts similarity index 100% rename from src/misc/captcha.ts rename to packages/backend/src/misc/captcha.ts diff --git a/packages/backend/src/misc/check-hit-antenna.ts b/packages/backend/src/misc/check-hit-antenna.ts new file mode 100644 index 000000000..e70b7429c --- /dev/null +++ b/packages/backend/src/misc/check-hit-antenna.ts @@ -0,0 +1,90 @@ +import { Antenna } from '@/models/entities/antenna'; +import { Note } from '@/models/entities/note'; +import { User } from '@/models/entities/user'; +import { UserListJoinings, UserGroupJoinings } from '@/models/index'; +import { getFullApAccount } from './convert-host'; +import * as Acct from 'misskey-js/built/acct'; +import { Packed } from './schema'; + +/** + * noteUserFollowers / antennaUserFollowing はどちらか一方が指定されていればよい + */ +export async function checkHitAntenna(antenna: Antenna, note: (Note | Packed<'Note'>), noteUser: { username: string; host: string | null; }, noteUserFollowers?: User['id'][], antennaUserFollowing?: User['id'][]): Promise { + if (note.visibility === 'specified') return false; + + if (note.visibility === 'followers') { + if (noteUserFollowers && !noteUserFollowers.includes(antenna.userId)) return false; + if (antennaUserFollowing && !antennaUserFollowing.includes(note.userId)) return false; + } + + if (!antenna.withReplies && note.replyId != null) return false; + + if (antenna.src === 'home') { + if (noteUserFollowers && !noteUserFollowers.includes(antenna.userId)) return false; + if (antennaUserFollowing && !antennaUserFollowing.includes(note.userId)) return false; + } else if (antenna.src === 'list') { + const listUsers = (await UserListJoinings.find({ + userListId: antenna.userListId! + })).map(x => x.userId); + + if (!listUsers.includes(note.userId)) return false; + } else if (antenna.src === 'group') { + const joining = await UserGroupJoinings.findOneOrFail(antenna.userGroupJoiningId!); + + const groupUsers = (await UserGroupJoinings.find({ + userGroupId: joining.userGroupId + })).map(x => x.userId); + + if (!groupUsers.includes(note.userId)) return false; + } else if (antenna.src === 'users') { + const accts = antenna.users.map(x => { + const { username, host } = Acct.parse(x); + return getFullApAccount(username, host).toLowerCase(); + }); + if (!accts.includes(getFullApAccount(noteUser.username, noteUser.host).toLowerCase())) return false; + } + + const keywords = antenna.keywords + // Clean up + .map(xs => xs.filter(x => x !== '')) + .filter(xs => xs.length > 0); + + if (keywords.length > 0) { + if (note.text == null) return false; + + const matched = keywords.some(and => + and.every(keyword => + antenna.caseSensitive + ? note.text!.includes(keyword) + : note.text!.toLowerCase().includes(keyword.toLowerCase()) + )); + + if (!matched) return false; + } + + const excludeKeywords = antenna.excludeKeywords + // Clean up + .map(xs => xs.filter(x => x !== '')) + .filter(xs => xs.length > 0); + + if (excludeKeywords.length > 0) { + if (note.text == null) return false; + + const matched = excludeKeywords.some(and => + and.every(keyword => + antenna.caseSensitive + ? note.text!.includes(keyword) + : note.text!.toLowerCase().includes(keyword.toLowerCase()) + )); + + if (matched) return false; + } + + if (antenna.withFile) { + if (note.fileIds && note.fileIds.length === 0) return false; + } + + // TODO: eval expression + + return true; +} diff --git a/src/misc/check-word-mute.ts b/packages/backend/src/misc/check-word-mute.ts similarity index 100% rename from src/misc/check-word-mute.ts rename to packages/backend/src/misc/check-word-mute.ts diff --git a/src/misc/content-disposition.ts b/packages/backend/src/misc/content-disposition.ts similarity index 100% rename from src/misc/content-disposition.ts rename to packages/backend/src/misc/content-disposition.ts diff --git a/src/misc/convert-host.ts b/packages/backend/src/misc/convert-host.ts similarity index 100% rename from src/misc/convert-host.ts rename to packages/backend/src/misc/convert-host.ts diff --git a/src/misc/count-same-renotes.ts b/packages/backend/src/misc/count-same-renotes.ts similarity index 100% rename from src/misc/count-same-renotes.ts rename to packages/backend/src/misc/count-same-renotes.ts diff --git a/src/misc/create-temp.ts b/packages/backend/src/misc/create-temp.ts similarity index 100% rename from src/misc/create-temp.ts rename to packages/backend/src/misc/create-temp.ts diff --git a/src/misc/detect-url-mime.ts b/packages/backend/src/misc/detect-url-mime.ts similarity index 100% rename from src/misc/detect-url-mime.ts rename to packages/backend/src/misc/detect-url-mime.ts diff --git a/src/misc/download-text-file.ts b/packages/backend/src/misc/download-text-file.ts similarity index 100% rename from src/misc/download-text-file.ts rename to packages/backend/src/misc/download-text-file.ts diff --git a/src/misc/download-url.ts b/packages/backend/src/misc/download-url.ts similarity index 100% rename from src/misc/download-url.ts rename to packages/backend/src/misc/download-url.ts diff --git a/src/misc/emoji-regex.ts b/packages/backend/src/misc/emoji-regex.ts similarity index 100% rename from src/misc/emoji-regex.ts rename to packages/backend/src/misc/emoji-regex.ts diff --git a/src/misc/extract-custom-emojis-from-mfm.ts b/packages/backend/src/misc/extract-custom-emojis-from-mfm.ts similarity index 100% rename from src/misc/extract-custom-emojis-from-mfm.ts rename to packages/backend/src/misc/extract-custom-emojis-from-mfm.ts diff --git a/src/misc/extract-hashtags.ts b/packages/backend/src/misc/extract-hashtags.ts similarity index 100% rename from src/misc/extract-hashtags.ts rename to packages/backend/src/misc/extract-hashtags.ts diff --git a/src/misc/extract-mentions.ts b/packages/backend/src/misc/extract-mentions.ts similarity index 100% rename from src/misc/extract-mentions.ts rename to packages/backend/src/misc/extract-mentions.ts diff --git a/src/misc/fetch-meta.ts b/packages/backend/src/misc/fetch-meta.ts similarity index 100% rename from src/misc/fetch-meta.ts rename to packages/backend/src/misc/fetch-meta.ts diff --git a/src/misc/fetch-proxy-account.ts b/packages/backend/src/misc/fetch-proxy-account.ts similarity index 100% rename from src/misc/fetch-proxy-account.ts rename to packages/backend/src/misc/fetch-proxy-account.ts diff --git a/src/misc/fetch.ts b/packages/backend/src/misc/fetch.ts similarity index 100% rename from src/misc/fetch.ts rename to packages/backend/src/misc/fetch.ts diff --git a/packages/backend/src/misc/gen-avatar.ts b/packages/backend/src/misc/gen-avatar.ts new file mode 100644 index 000000000..8838ec8d1 --- /dev/null +++ b/packages/backend/src/misc/gen-avatar.ts @@ -0,0 +1,90 @@ +/** + * Random avatar generator + */ + +import * as p from 'pureimage'; +import * as gen from 'random-seed'; +import { WriteStream } from 'fs'; + +const size = 256; // px +const n = 5; // resolution +const margin = (size / n); +const colors = [ + '#e57373', + '#F06292', + '#BA68C8', + '#9575CD', + '#7986CB', + '#64B5F6', + '#4FC3F7', + '#4DD0E1', + '#4DB6AC', + '#81C784', + '#8BC34A', + '#AFB42B', + '#F57F17', + '#FF5722', + '#795548', + '#455A64', +]; +const bg = '#e9e9e9'; + +const actualSize = size - (margin * 2); +const cellSize = actualSize / n; +const sideN = Math.floor(n / 2); + +/** + * Generate buffer of random avatar by seed + */ +export function genAvatar(seed: string, stream: WriteStream): Promise { + const rand = gen.create(seed); + const canvas = p.make(size, size); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = bg; + ctx.beginPath(); + ctx.fillRect(0, 0, size, size); + + ctx.fillStyle = colors[rand(colors.length)]; + + // side bitmap (filled by false) + const side: boolean[][] = new Array(sideN); + for (let i = 0; i < side.length; i++) { + side[i] = new Array(n).fill(false); + } + + // 1*n (filled by false) + const center: boolean[] = new Array(n).fill(false); + + // eslint:disable-next-line:prefer-for-of + for (let x = 0; x < side.length; x++) { + for (let y = 0; y < side[x].length; y++) { + side[x][y] = rand(3) === 0; + } + } + + for (let i = 0; i < center.length; i++) { + center[i] = rand(3) === 0; + } + + // Draw + for (let x = 0; x < n; x++) { + for (let y = 0; y < n; y++) { + const isXCenter = x === ((n - 1) / 2); + if (isXCenter && !center[y]) continue; + + const isLeftSide = x < ((n - 1) / 2); + if (isLeftSide && !side[x][y]) continue; + + const isRightSide = x > ((n - 1) / 2); + if (isRightSide && !side[sideN - (x - sideN)][y]) continue; + + const actualX = margin + (cellSize * x); + const actualY = margin + (cellSize * y); + ctx.beginPath(); + ctx.fillRect(actualX, actualY, cellSize, cellSize); + } + } + + return p.encodePNGToStream(canvas, stream); +} diff --git a/src/misc/gen-id.ts b/packages/backend/src/misc/gen-id.ts similarity index 100% rename from src/misc/gen-id.ts rename to packages/backend/src/misc/gen-id.ts diff --git a/src/misc/gen-key-pair.ts b/packages/backend/src/misc/gen-key-pair.ts similarity index 100% rename from src/misc/gen-key-pair.ts rename to packages/backend/src/misc/gen-key-pair.ts diff --git a/src/misc/get-file-info.ts b/packages/backend/src/misc/get-file-info.ts similarity index 100% rename from src/misc/get-file-info.ts rename to packages/backend/src/misc/get-file-info.ts diff --git a/packages/backend/src/misc/get-note-summary.ts b/packages/backend/src/misc/get-note-summary.ts new file mode 100644 index 000000000..d7273d1c5 --- /dev/null +++ b/packages/backend/src/misc/get-note-summary.ts @@ -0,0 +1,54 @@ +import { Packed } from './schema'; + +/** + * 投稿を表す文字列を取得します。 + * @param {*} note (packされた)投稿 + */ +export const getNoteSummary = (note: Packed<'Note'>): string => { + if (note.deletedAt) { + return `(❌⛔)`; + } + + if (note.isHidden) { + return `(⛔)`; + } + + let summary = ''; + + // 本文 + if (note.cw != null) { + summary += note.cw; + } else { + summary += note.text ? note.text : ''; + } + + // ファイルが添付されているとき + if ((note.files || []).length != 0) { + summary += ` (📎${note.files!.length})`; + } + + // 投票が添付されているとき + if (note.poll) { + summary += ` (📊)`; + } + + // 返信のとき + if (note.replyId) { + if (note.reply) { + summary += `\n\nRE: ${getNoteSummary(note.reply)}`; + } else { + summary += '\n\nRE: ...'; + } + } + + // Renoteのとき + if (note.renoteId) { + if (note.renote) { + summary += `\n\nRN: ${getNoteSummary(note.renote)}`; + } else { + summary += '\n\nRN: ...'; + } + } + + return summary.trim(); +}; diff --git a/src/misc/get-reaction-emoji.ts b/packages/backend/src/misc/get-reaction-emoji.ts similarity index 100% rename from src/misc/get-reaction-emoji.ts rename to packages/backend/src/misc/get-reaction-emoji.ts diff --git a/src/misc/hard-limits.ts b/packages/backend/src/misc/hard-limits.ts similarity index 100% rename from src/misc/hard-limits.ts rename to packages/backend/src/misc/hard-limits.ts diff --git a/src/misc/i18n.ts b/packages/backend/src/misc/i18n.ts similarity index 100% rename from src/misc/i18n.ts rename to packages/backend/src/misc/i18n.ts diff --git a/src/misc/id/aid.ts b/packages/backend/src/misc/id/aid.ts similarity index 100% rename from src/misc/id/aid.ts rename to packages/backend/src/misc/id/aid.ts diff --git a/src/misc/id/meid.ts b/packages/backend/src/misc/id/meid.ts similarity index 100% rename from src/misc/id/meid.ts rename to packages/backend/src/misc/id/meid.ts diff --git a/src/misc/id/meidg.ts b/packages/backend/src/misc/id/meidg.ts similarity index 100% rename from src/misc/id/meidg.ts rename to packages/backend/src/misc/id/meidg.ts diff --git a/src/misc/id/object-id.ts b/packages/backend/src/misc/id/object-id.ts similarity index 100% rename from src/misc/id/object-id.ts rename to packages/backend/src/misc/id/object-id.ts diff --git a/src/misc/identifiable-error.ts b/packages/backend/src/misc/identifiable-error.ts similarity index 100% rename from src/misc/identifiable-error.ts rename to packages/backend/src/misc/identifiable-error.ts diff --git a/src/misc/is-blocker-user-related.ts b/packages/backend/src/misc/is-blocker-user-related.ts similarity index 100% rename from src/misc/is-blocker-user-related.ts rename to packages/backend/src/misc/is-blocker-user-related.ts diff --git a/src/misc/is-duplicate-key-value-error.ts b/packages/backend/src/misc/is-duplicate-key-value-error.ts similarity index 100% rename from src/misc/is-duplicate-key-value-error.ts rename to packages/backend/src/misc/is-duplicate-key-value-error.ts diff --git a/src/misc/is-muted-user-related.ts b/packages/backend/src/misc/is-muted-user-related.ts similarity index 100% rename from src/misc/is-muted-user-related.ts rename to packages/backend/src/misc/is-muted-user-related.ts diff --git a/src/misc/is-quote.ts b/packages/backend/src/misc/is-quote.ts similarity index 100% rename from src/misc/is-quote.ts rename to packages/backend/src/misc/is-quote.ts diff --git a/src/misc/keypair-store.ts b/packages/backend/src/misc/keypair-store.ts similarity index 100% rename from src/misc/keypair-store.ts rename to packages/backend/src/misc/keypair-store.ts diff --git a/src/misc/normalize-for-search.ts b/packages/backend/src/misc/normalize-for-search.ts similarity index 100% rename from src/misc/normalize-for-search.ts rename to packages/backend/src/misc/normalize-for-search.ts diff --git a/src/misc/nyaize.ts b/packages/backend/src/misc/nyaize.ts similarity index 100% rename from src/misc/nyaize.ts rename to packages/backend/src/misc/nyaize.ts diff --git a/src/misc/populate-emojis.ts b/packages/backend/src/misc/populate-emojis.ts similarity index 100% rename from src/misc/populate-emojis.ts rename to packages/backend/src/misc/populate-emojis.ts diff --git a/src/misc/reaction-lib.ts b/packages/backend/src/misc/reaction-lib.ts similarity index 100% rename from src/misc/reaction-lib.ts rename to packages/backend/src/misc/reaction-lib.ts diff --git a/src/misc/safe-for-sql.ts b/packages/backend/src/misc/safe-for-sql.ts similarity index 100% rename from src/misc/safe-for-sql.ts rename to packages/backend/src/misc/safe-for-sql.ts diff --git a/src/misc/schema.ts b/packages/backend/src/misc/schema.ts similarity index 100% rename from src/misc/schema.ts rename to packages/backend/src/misc/schema.ts diff --git a/src/misc/secure-rndstr.ts b/packages/backend/src/misc/secure-rndstr.ts similarity index 100% rename from src/misc/secure-rndstr.ts rename to packages/backend/src/misc/secure-rndstr.ts diff --git a/src/misc/show-machine-info.ts b/packages/backend/src/misc/show-machine-info.ts similarity index 100% rename from src/misc/show-machine-info.ts rename to packages/backend/src/misc/show-machine-info.ts diff --git a/src/misc/simple-schema.ts b/packages/backend/src/misc/simple-schema.ts similarity index 100% rename from src/misc/simple-schema.ts rename to packages/backend/src/misc/simple-schema.ts diff --git a/src/misc/truncate.ts b/packages/backend/src/misc/truncate.ts similarity index 100% rename from src/misc/truncate.ts rename to packages/backend/src/misc/truncate.ts diff --git a/src/models/entities/abuse-user-report.ts b/packages/backend/src/models/entities/abuse-user-report.ts similarity index 100% rename from src/models/entities/abuse-user-report.ts rename to packages/backend/src/models/entities/abuse-user-report.ts diff --git a/src/models/entities/access-token.ts b/packages/backend/src/models/entities/access-token.ts similarity index 100% rename from src/models/entities/access-token.ts rename to packages/backend/src/models/entities/access-token.ts diff --git a/src/models/entities/ad.ts b/packages/backend/src/models/entities/ad.ts similarity index 100% rename from src/models/entities/ad.ts rename to packages/backend/src/models/entities/ad.ts diff --git a/src/models/entities/announcement-read.ts b/packages/backend/src/models/entities/announcement-read.ts similarity index 100% rename from src/models/entities/announcement-read.ts rename to packages/backend/src/models/entities/announcement-read.ts diff --git a/src/models/entities/announcement.ts b/packages/backend/src/models/entities/announcement.ts similarity index 100% rename from src/models/entities/announcement.ts rename to packages/backend/src/models/entities/announcement.ts diff --git a/src/models/entities/antenna-note.ts b/packages/backend/src/models/entities/antenna-note.ts similarity index 100% rename from src/models/entities/antenna-note.ts rename to packages/backend/src/models/entities/antenna-note.ts diff --git a/src/models/entities/antenna.ts b/packages/backend/src/models/entities/antenna.ts similarity index 100% rename from src/models/entities/antenna.ts rename to packages/backend/src/models/entities/antenna.ts diff --git a/src/models/entities/app.ts b/packages/backend/src/models/entities/app.ts similarity index 100% rename from src/models/entities/app.ts rename to packages/backend/src/models/entities/app.ts diff --git a/src/models/entities/attestation-challenge.ts b/packages/backend/src/models/entities/attestation-challenge.ts similarity index 100% rename from src/models/entities/attestation-challenge.ts rename to packages/backend/src/models/entities/attestation-challenge.ts diff --git a/src/models/entities/auth-session.ts b/packages/backend/src/models/entities/auth-session.ts similarity index 100% rename from src/models/entities/auth-session.ts rename to packages/backend/src/models/entities/auth-session.ts diff --git a/src/models/entities/blocking.ts b/packages/backend/src/models/entities/blocking.ts similarity index 100% rename from src/models/entities/blocking.ts rename to packages/backend/src/models/entities/blocking.ts diff --git a/src/models/entities/channel-following.ts b/packages/backend/src/models/entities/channel-following.ts similarity index 100% rename from src/models/entities/channel-following.ts rename to packages/backend/src/models/entities/channel-following.ts diff --git a/src/models/entities/channel-note-pining.ts b/packages/backend/src/models/entities/channel-note-pining.ts similarity index 100% rename from src/models/entities/channel-note-pining.ts rename to packages/backend/src/models/entities/channel-note-pining.ts diff --git a/src/models/entities/channel.ts b/packages/backend/src/models/entities/channel.ts similarity index 100% rename from src/models/entities/channel.ts rename to packages/backend/src/models/entities/channel.ts diff --git a/src/models/entities/clip-note.ts b/packages/backend/src/models/entities/clip-note.ts similarity index 100% rename from src/models/entities/clip-note.ts rename to packages/backend/src/models/entities/clip-note.ts diff --git a/src/models/entities/clip.ts b/packages/backend/src/models/entities/clip.ts similarity index 100% rename from src/models/entities/clip.ts rename to packages/backend/src/models/entities/clip.ts diff --git a/src/models/entities/drive-file.ts b/packages/backend/src/models/entities/drive-file.ts similarity index 100% rename from src/models/entities/drive-file.ts rename to packages/backend/src/models/entities/drive-file.ts diff --git a/src/models/entities/drive-folder.ts b/packages/backend/src/models/entities/drive-folder.ts similarity index 100% rename from src/models/entities/drive-folder.ts rename to packages/backend/src/models/entities/drive-folder.ts diff --git a/src/models/entities/emoji.ts b/packages/backend/src/models/entities/emoji.ts similarity index 100% rename from src/models/entities/emoji.ts rename to packages/backend/src/models/entities/emoji.ts diff --git a/src/models/entities/follow-request.ts b/packages/backend/src/models/entities/follow-request.ts similarity index 100% rename from src/models/entities/follow-request.ts rename to packages/backend/src/models/entities/follow-request.ts diff --git a/src/models/entities/following.ts b/packages/backend/src/models/entities/following.ts similarity index 100% rename from src/models/entities/following.ts rename to packages/backend/src/models/entities/following.ts diff --git a/src/models/entities/gallery-like.ts b/packages/backend/src/models/entities/gallery-like.ts similarity index 100% rename from src/models/entities/gallery-like.ts rename to packages/backend/src/models/entities/gallery-like.ts diff --git a/src/models/entities/gallery-post.ts b/packages/backend/src/models/entities/gallery-post.ts similarity index 100% rename from src/models/entities/gallery-post.ts rename to packages/backend/src/models/entities/gallery-post.ts diff --git a/src/models/entities/games/reversi/game.ts b/packages/backend/src/models/entities/games/reversi/game.ts similarity index 100% rename from src/models/entities/games/reversi/game.ts rename to packages/backend/src/models/entities/games/reversi/game.ts diff --git a/src/models/entities/games/reversi/matching.ts b/packages/backend/src/models/entities/games/reversi/matching.ts similarity index 100% rename from src/models/entities/games/reversi/matching.ts rename to packages/backend/src/models/entities/games/reversi/matching.ts diff --git a/src/models/entities/hashtag.ts b/packages/backend/src/models/entities/hashtag.ts similarity index 100% rename from src/models/entities/hashtag.ts rename to packages/backend/src/models/entities/hashtag.ts diff --git a/src/models/entities/instance.ts b/packages/backend/src/models/entities/instance.ts similarity index 100% rename from src/models/entities/instance.ts rename to packages/backend/src/models/entities/instance.ts diff --git a/src/models/entities/messaging-message.ts b/packages/backend/src/models/entities/messaging-message.ts similarity index 100% rename from src/models/entities/messaging-message.ts rename to packages/backend/src/models/entities/messaging-message.ts diff --git a/src/models/entities/meta.ts b/packages/backend/src/models/entities/meta.ts similarity index 100% rename from src/models/entities/meta.ts rename to packages/backend/src/models/entities/meta.ts diff --git a/src/models/entities/moderation-log.ts b/packages/backend/src/models/entities/moderation-log.ts similarity index 100% rename from src/models/entities/moderation-log.ts rename to packages/backend/src/models/entities/moderation-log.ts diff --git a/src/models/entities/muted-note.ts b/packages/backend/src/models/entities/muted-note.ts similarity index 100% rename from src/models/entities/muted-note.ts rename to packages/backend/src/models/entities/muted-note.ts diff --git a/src/models/entities/muting.ts b/packages/backend/src/models/entities/muting.ts similarity index 100% rename from src/models/entities/muting.ts rename to packages/backend/src/models/entities/muting.ts diff --git a/src/models/entities/note-favorite.ts b/packages/backend/src/models/entities/note-favorite.ts similarity index 100% rename from src/models/entities/note-favorite.ts rename to packages/backend/src/models/entities/note-favorite.ts diff --git a/src/models/entities/note-reaction.ts b/packages/backend/src/models/entities/note-reaction.ts similarity index 100% rename from src/models/entities/note-reaction.ts rename to packages/backend/src/models/entities/note-reaction.ts diff --git a/src/models/entities/note-thread-muting.ts b/packages/backend/src/models/entities/note-thread-muting.ts similarity index 100% rename from src/models/entities/note-thread-muting.ts rename to packages/backend/src/models/entities/note-thread-muting.ts diff --git a/src/models/entities/note-unread.ts b/packages/backend/src/models/entities/note-unread.ts similarity index 100% rename from src/models/entities/note-unread.ts rename to packages/backend/src/models/entities/note-unread.ts diff --git a/src/models/entities/note-watching.ts b/packages/backend/src/models/entities/note-watching.ts similarity index 100% rename from src/models/entities/note-watching.ts rename to packages/backend/src/models/entities/note-watching.ts diff --git a/packages/backend/src/models/entities/note.ts b/packages/backend/src/models/entities/note.ts new file mode 100644 index 000000000..9dee25ea2 --- /dev/null +++ b/packages/backend/src/models/entities/note.ts @@ -0,0 +1,242 @@ +import { Entity, Index, JoinColumn, Column, PrimaryColumn, ManyToOne } from 'typeorm'; +import { User } from './user'; +import { DriveFile } from './drive-file'; +import { id } from '../id'; +import { noteVisibilities } from '../../types'; +import { Channel } from './channel'; + +@Entity() +@Index('IDX_NOTE_TAGS', { synchronize: false }) +@Index('IDX_NOTE_MENTIONS', { synchronize: false }) +@Index('IDX_NOTE_VISIBLE_USER_IDS', { synchronize: false }) +export class Note { + @PrimaryColumn(id()) + public id: string; + + @Index() + @Column('timestamp with time zone', { + comment: 'The created date of the Note.' + }) + public createdAt: Date; + + @Index() + @Column({ + ...id(), + nullable: true, + comment: 'The ID of reply target.' + }) + public replyId: Note['id'] | null; + + @ManyToOne(type => Note, { + onDelete: 'CASCADE' + }) + @JoinColumn() + public reply: Note | null; + + @Index() + @Column({ + ...id(), + nullable: true, + comment: 'The ID of renote target.' + }) + public renoteId: Note['id'] | null; + + @ManyToOne(type => Note, { + onDelete: 'CASCADE' + }) + @JoinColumn() + public renote: Note | null; + + @Index() + @Column('varchar', { + length: 256, nullable: true + }) + public threadId: string | null; + + @Column('varchar', { + length: 8192, nullable: true + }) + public text: string | null; + + @Column('varchar', { + length: 256, nullable: true + }) + public name: string | null; + + @Column('varchar', { + length: 512, nullable: true + }) + public cw: string | null; + + @Index() + @Column({ + ...id(), + comment: 'The ID of author.' + }) + public userId: User['id']; + + @ManyToOne(type => User, { + onDelete: 'CASCADE' + }) + @JoinColumn() + public user: User | null; + + @Column('boolean', { + default: false + }) + public localOnly: boolean; + + @Column('smallint', { + default: 0 + }) + public renoteCount: number; + + @Column('smallint', { + default: 0 + }) + public repliesCount: number; + + @Column('jsonb', { + default: {} + }) + public reactions: Record; + + /** + * public ... 公開 + * home ... ホームタイムライン(ユーザーページのタイムライン含む)のみに流す + * followers ... フォロワーのみ + * specified ... visibleUserIds で指定したユーザーのみ + */ + @Column('enum', { enum: noteVisibilities }) + public visibility: typeof noteVisibilities[number]; + + @Index({ unique: true }) + @Column('varchar', { + length: 512, nullable: true, + comment: 'The URI of a note. it will be null when the note is local.' + }) + public uri: string | null; + + @Column('varchar', { + length: 512, nullable: true, + comment: 'The human readable url of a note. it will be null when the note is local.' + }) + public url: string | null; + + @Column('integer', { + default: 0, select: false + }) + public score: number; + + @Index() + @Column({ + ...id(), + array: true, default: '{}' + }) + public fileIds: DriveFile['id'][]; + + @Index() + @Column('varchar', { + length: 256, array: true, default: '{}' + }) + public attachedFileTypes: string[]; + + @Index() + @Column({ + ...id(), + array: true, default: '{}' + }) + public visibleUserIds: User['id'][]; + + @Index() + @Column({ + ...id(), + array: true, default: '{}' + }) + public mentions: User['id'][]; + + @Column('text', { + default: '[]' + }) + public mentionedRemoteUsers: string; + + @Column('varchar', { + length: 128, array: true, default: '{}' + }) + public emojis: string[]; + + @Index() + @Column('varchar', { + length: 128, array: true, default: '{}' + }) + public tags: string[]; + + @Column('boolean', { + default: false + }) + public hasPoll: boolean; + + @Index() + @Column({ + ...id(), + nullable: true, default: null, + comment: 'The ID of source channel.' + }) + public channelId: Channel['id'] | null; + + @ManyToOne(type => Channel, { + onDelete: 'CASCADE' + }) + @JoinColumn() + public channel: Channel | null; + + //#region Denormalized fields + @Index() + @Column('varchar', { + length: 128, nullable: true, + comment: '[Denormalized]' + }) + public userHost: string | null; + + @Column({ + ...id(), + nullable: true, + comment: '[Denormalized]' + }) + public replyUserId: User['id'] | null; + + @Column('varchar', { + length: 128, nullable: true, + comment: '[Denormalized]' + }) + public replyUserHost: string | null; + + @Column({ + ...id(), + nullable: true, + comment: '[Denormalized]' + }) + public renoteUserId: User['id'] | null; + + @Column('varchar', { + length: 128, nullable: true, + comment: '[Denormalized]' + }) + public renoteUserHost: string | null; + //#endregion + + constructor(data: Partial) { + if (data == null) return; + + for (const [k, v] of Object.entries(data)) { + (this as any)[k] = v; + } + } +} + +export type IMentionedRemoteUsers = { + uri: string; + url?: string; + username: string; + host: string; +}[]; diff --git a/src/models/entities/notification.ts b/packages/backend/src/models/entities/notification.ts similarity index 100% rename from src/models/entities/notification.ts rename to packages/backend/src/models/entities/notification.ts diff --git a/src/models/entities/page-like.ts b/packages/backend/src/models/entities/page-like.ts similarity index 100% rename from src/models/entities/page-like.ts rename to packages/backend/src/models/entities/page-like.ts diff --git a/src/models/entities/page.ts b/packages/backend/src/models/entities/page.ts similarity index 100% rename from src/models/entities/page.ts rename to packages/backend/src/models/entities/page.ts diff --git a/src/models/entities/password-reset-request.ts b/packages/backend/src/models/entities/password-reset-request.ts similarity index 100% rename from src/models/entities/password-reset-request.ts rename to packages/backend/src/models/entities/password-reset-request.ts diff --git a/src/models/entities/poll-vote.ts b/packages/backend/src/models/entities/poll-vote.ts similarity index 100% rename from src/models/entities/poll-vote.ts rename to packages/backend/src/models/entities/poll-vote.ts diff --git a/src/models/entities/poll.ts b/packages/backend/src/models/entities/poll.ts similarity index 100% rename from src/models/entities/poll.ts rename to packages/backend/src/models/entities/poll.ts diff --git a/src/models/entities/promo-note.ts b/packages/backend/src/models/entities/promo-note.ts similarity index 100% rename from src/models/entities/promo-note.ts rename to packages/backend/src/models/entities/promo-note.ts diff --git a/src/models/entities/promo-read.ts b/packages/backend/src/models/entities/promo-read.ts similarity index 100% rename from src/models/entities/promo-read.ts rename to packages/backend/src/models/entities/promo-read.ts diff --git a/src/models/entities/registration-tickets.ts b/packages/backend/src/models/entities/registration-tickets.ts similarity index 100% rename from src/models/entities/registration-tickets.ts rename to packages/backend/src/models/entities/registration-tickets.ts diff --git a/src/models/entities/registry-item.ts b/packages/backend/src/models/entities/registry-item.ts similarity index 100% rename from src/models/entities/registry-item.ts rename to packages/backend/src/models/entities/registry-item.ts diff --git a/src/models/entities/relay.ts b/packages/backend/src/models/entities/relay.ts similarity index 100% rename from src/models/entities/relay.ts rename to packages/backend/src/models/entities/relay.ts diff --git a/src/models/entities/signin.ts b/packages/backend/src/models/entities/signin.ts similarity index 100% rename from src/models/entities/signin.ts rename to packages/backend/src/models/entities/signin.ts diff --git a/src/models/entities/sw-subscription.ts b/packages/backend/src/models/entities/sw-subscription.ts similarity index 100% rename from src/models/entities/sw-subscription.ts rename to packages/backend/src/models/entities/sw-subscription.ts diff --git a/src/models/entities/used-username.ts b/packages/backend/src/models/entities/used-username.ts similarity index 100% rename from src/models/entities/used-username.ts rename to packages/backend/src/models/entities/used-username.ts diff --git a/src/models/entities/user-group-invitation.ts b/packages/backend/src/models/entities/user-group-invitation.ts similarity index 100% rename from src/models/entities/user-group-invitation.ts rename to packages/backend/src/models/entities/user-group-invitation.ts diff --git a/src/models/entities/user-group-joining.ts b/packages/backend/src/models/entities/user-group-joining.ts similarity index 100% rename from src/models/entities/user-group-joining.ts rename to packages/backend/src/models/entities/user-group-joining.ts diff --git a/src/models/entities/user-group.ts b/packages/backend/src/models/entities/user-group.ts similarity index 100% rename from src/models/entities/user-group.ts rename to packages/backend/src/models/entities/user-group.ts diff --git a/src/models/entities/user-keypair.ts b/packages/backend/src/models/entities/user-keypair.ts similarity index 100% rename from src/models/entities/user-keypair.ts rename to packages/backend/src/models/entities/user-keypair.ts diff --git a/src/models/entities/user-list-joining.ts b/packages/backend/src/models/entities/user-list-joining.ts similarity index 100% rename from src/models/entities/user-list-joining.ts rename to packages/backend/src/models/entities/user-list-joining.ts diff --git a/src/models/entities/user-list.ts b/packages/backend/src/models/entities/user-list.ts similarity index 100% rename from src/models/entities/user-list.ts rename to packages/backend/src/models/entities/user-list.ts diff --git a/src/models/entities/user-note-pining.ts b/packages/backend/src/models/entities/user-note-pining.ts similarity index 100% rename from src/models/entities/user-note-pining.ts rename to packages/backend/src/models/entities/user-note-pining.ts diff --git a/src/models/entities/user-pending.ts b/packages/backend/src/models/entities/user-pending.ts similarity index 100% rename from src/models/entities/user-pending.ts rename to packages/backend/src/models/entities/user-pending.ts diff --git a/packages/backend/src/models/entities/user-profile.ts b/packages/backend/src/models/entities/user-profile.ts new file mode 100644 index 000000000..8a8cacfd5 --- /dev/null +++ b/packages/backend/src/models/entities/user-profile.ts @@ -0,0 +1,215 @@ +import { Entity, Column, Index, OneToOne, JoinColumn, PrimaryColumn } from 'typeorm'; +import { id } from '../id'; +import { User } from './user'; +import { Page } from './page'; +import { ffVisibility, notificationTypes } from '@/types'; + +// TODO: このテーブルで管理している情報すべてレジストリで管理するようにしても良いかも +// ただ、「emailVerified が true なユーザーを find する」のようなクエリは書けなくなるからウーン +@Entity() +export class UserProfile { + @PrimaryColumn(id()) + public userId: User['id']; + + @OneToOne(type => User, { + onDelete: 'CASCADE' + }) + @JoinColumn() + public user: User | null; + + @Column('varchar', { + length: 128, nullable: true, + comment: 'The location of the User.' + }) + public location: string | null; + + @Column('char', { + length: 10, nullable: true, + comment: 'The birthday (YYYY-MM-DD) of the User.' + }) + public birthday: string | null; + + @Column('varchar', { + length: 2048, nullable: true, + comment: 'The description (bio) of the User.' + }) + public description: string | null; + + @Column('jsonb', { + default: [], + }) + public fields: { + name: string; + value: string; + }[]; + + @Column('varchar', { + length: 32, nullable: true, + }) + public lang: string | null; + + @Column('varchar', { + length: 512, nullable: true, + comment: 'Remote URL of the user.' + }) + public url: string | null; + + @Column('varchar', { + length: 128, nullable: true, + comment: 'The email address of the User.' + }) + public email: string | null; + + @Column('varchar', { + length: 128, nullable: true, + }) + public emailVerifyCode: string | null; + + @Column('boolean', { + default: false, + }) + public emailVerified: boolean; + + @Column('jsonb', { + default: ['follow', 'receiveFollowRequest', 'groupInvited'] + }) + public emailNotificationTypes: string[]; + + @Column('boolean', { + default: false, + }) + public publicReactions: boolean; + + @Column('enum', { + enum: ffVisibility, + default: 'public', + }) + public ffVisibility: typeof ffVisibility[number]; + + @Column('varchar', { + length: 128, nullable: true, + }) + public twoFactorTempSecret: string | null; + + @Column('varchar', { + length: 128, nullable: true, + }) + public twoFactorSecret: string | null; + + @Column('boolean', { + default: false, + }) + public twoFactorEnabled: boolean; + + @Column('boolean', { + default: false, + }) + public securityKeysAvailable: boolean; + + @Column('boolean', { + default: false, + }) + public usePasswordLessLogin: boolean; + + @Column('varchar', { + length: 128, nullable: true, + comment: 'The password hash of the User. It will be null if the origin of the user is local.' + }) + public password: string | null; + + // TODO: そのうち消す + @Column('jsonb', { + default: {}, + comment: 'The client-specific data of the User.' + }) + public clientData: Record; + + @Column('jsonb', { + default: {}, + comment: 'The room data of the User.' + }) + public room: Record; + + @Column('boolean', { + default: false, + }) + public autoAcceptFollowed: boolean; + + @Column('boolean', { + default: false, + comment: 'Whether reject index by crawler.' + }) + public noCrawle: boolean; + + @Column('boolean', { + default: false, + }) + public alwaysMarkNsfw: boolean; + + @Column('boolean', { + default: false, + }) + public carefulBot: boolean; + + @Column('boolean', { + default: true, + }) + public injectFeaturedNote: boolean; + + @Column('boolean', { + default: true, + }) + public receiveAnnouncementEmail: boolean; + + @Column({ + ...id(), + nullable: true + }) + public pinnedPageId: Page['id'] | null; + + @OneToOne(type => Page, { + onDelete: 'SET NULL' + }) + @JoinColumn() + public pinnedPage: Page | null; + + @Column('jsonb', { + default: {} + }) + public integrations: Record; + + @Index() + @Column('boolean', { + default: false, select: false, + }) + public enableWordMute: boolean; + + @Column('jsonb', { + default: [] + }) + public mutedWords: string[][]; + + @Column('enum', { + enum: notificationTypes, + array: true, + default: [], + }) + public mutingNotificationTypes: typeof notificationTypes[number][]; + + //#region Denormalized fields + @Index() + @Column('varchar', { + length: 128, nullable: true, + comment: '[Denormalized]' + }) + public userHost: string | null; + //#endregion + + constructor(data: Partial) { + if (data == null) return; + + for (const [k, v] of Object.entries(data)) { + (this as any)[k] = v; + } + } +} diff --git a/src/models/entities/user-publickey.ts b/packages/backend/src/models/entities/user-publickey.ts similarity index 100% rename from src/models/entities/user-publickey.ts rename to packages/backend/src/models/entities/user-publickey.ts diff --git a/src/models/entities/user-security-key.ts b/packages/backend/src/models/entities/user-security-key.ts similarity index 100% rename from src/models/entities/user-security-key.ts rename to packages/backend/src/models/entities/user-security-key.ts diff --git a/src/models/entities/user.ts b/packages/backend/src/models/entities/user.ts similarity index 100% rename from src/models/entities/user.ts rename to packages/backend/src/models/entities/user.ts diff --git a/src/models/id.ts b/packages/backend/src/models/id.ts similarity index 100% rename from src/models/id.ts rename to packages/backend/src/models/id.ts diff --git a/src/models/index.ts b/packages/backend/src/models/index.ts similarity index 100% rename from src/models/index.ts rename to packages/backend/src/models/index.ts diff --git a/src/models/repositories/abuse-user-report.ts b/packages/backend/src/models/repositories/abuse-user-report.ts similarity index 100% rename from src/models/repositories/abuse-user-report.ts rename to packages/backend/src/models/repositories/abuse-user-report.ts diff --git a/src/models/repositories/antenna.ts b/packages/backend/src/models/repositories/antenna.ts similarity index 100% rename from src/models/repositories/antenna.ts rename to packages/backend/src/models/repositories/antenna.ts diff --git a/src/models/repositories/app.ts b/packages/backend/src/models/repositories/app.ts similarity index 100% rename from src/models/repositories/app.ts rename to packages/backend/src/models/repositories/app.ts diff --git a/src/models/repositories/auth-session.ts b/packages/backend/src/models/repositories/auth-session.ts similarity index 100% rename from src/models/repositories/auth-session.ts rename to packages/backend/src/models/repositories/auth-session.ts diff --git a/src/models/repositories/blocking.ts b/packages/backend/src/models/repositories/blocking.ts similarity index 100% rename from src/models/repositories/blocking.ts rename to packages/backend/src/models/repositories/blocking.ts diff --git a/src/models/repositories/channel.ts b/packages/backend/src/models/repositories/channel.ts similarity index 100% rename from src/models/repositories/channel.ts rename to packages/backend/src/models/repositories/channel.ts diff --git a/src/models/repositories/clip.ts b/packages/backend/src/models/repositories/clip.ts similarity index 100% rename from src/models/repositories/clip.ts rename to packages/backend/src/models/repositories/clip.ts diff --git a/src/models/repositories/drive-file.ts b/packages/backend/src/models/repositories/drive-file.ts similarity index 100% rename from src/models/repositories/drive-file.ts rename to packages/backend/src/models/repositories/drive-file.ts diff --git a/src/models/repositories/drive-folder.ts b/packages/backend/src/models/repositories/drive-folder.ts similarity index 100% rename from src/models/repositories/drive-folder.ts rename to packages/backend/src/models/repositories/drive-folder.ts diff --git a/src/models/repositories/emoji.ts b/packages/backend/src/models/repositories/emoji.ts similarity index 100% rename from src/models/repositories/emoji.ts rename to packages/backend/src/models/repositories/emoji.ts diff --git a/src/models/repositories/federation-instance.ts b/packages/backend/src/models/repositories/federation-instance.ts similarity index 100% rename from src/models/repositories/federation-instance.ts rename to packages/backend/src/models/repositories/federation-instance.ts diff --git a/src/models/repositories/follow-request.ts b/packages/backend/src/models/repositories/follow-request.ts similarity index 100% rename from src/models/repositories/follow-request.ts rename to packages/backend/src/models/repositories/follow-request.ts diff --git a/src/models/repositories/following.ts b/packages/backend/src/models/repositories/following.ts similarity index 100% rename from src/models/repositories/following.ts rename to packages/backend/src/models/repositories/following.ts diff --git a/src/models/repositories/gallery-like.ts b/packages/backend/src/models/repositories/gallery-like.ts similarity index 100% rename from src/models/repositories/gallery-like.ts rename to packages/backend/src/models/repositories/gallery-like.ts diff --git a/src/models/repositories/gallery-post.ts b/packages/backend/src/models/repositories/gallery-post.ts similarity index 100% rename from src/models/repositories/gallery-post.ts rename to packages/backend/src/models/repositories/gallery-post.ts diff --git a/src/models/repositories/games/reversi/game.ts b/packages/backend/src/models/repositories/games/reversi/game.ts similarity index 100% rename from src/models/repositories/games/reversi/game.ts rename to packages/backend/src/models/repositories/games/reversi/game.ts diff --git a/src/models/repositories/games/reversi/matching.ts b/packages/backend/src/models/repositories/games/reversi/matching.ts similarity index 100% rename from src/models/repositories/games/reversi/matching.ts rename to packages/backend/src/models/repositories/games/reversi/matching.ts diff --git a/src/models/repositories/hashtag.ts b/packages/backend/src/models/repositories/hashtag.ts similarity index 100% rename from src/models/repositories/hashtag.ts rename to packages/backend/src/models/repositories/hashtag.ts diff --git a/src/models/repositories/messaging-message.ts b/packages/backend/src/models/repositories/messaging-message.ts similarity index 100% rename from src/models/repositories/messaging-message.ts rename to packages/backend/src/models/repositories/messaging-message.ts diff --git a/src/models/repositories/moderation-logs.ts b/packages/backend/src/models/repositories/moderation-logs.ts similarity index 100% rename from src/models/repositories/moderation-logs.ts rename to packages/backend/src/models/repositories/moderation-logs.ts diff --git a/src/models/repositories/muting.ts b/packages/backend/src/models/repositories/muting.ts similarity index 100% rename from src/models/repositories/muting.ts rename to packages/backend/src/models/repositories/muting.ts diff --git a/src/models/repositories/note-favorite.ts b/packages/backend/src/models/repositories/note-favorite.ts similarity index 100% rename from src/models/repositories/note-favorite.ts rename to packages/backend/src/models/repositories/note-favorite.ts diff --git a/src/models/repositories/note-reaction.ts b/packages/backend/src/models/repositories/note-reaction.ts similarity index 100% rename from src/models/repositories/note-reaction.ts rename to packages/backend/src/models/repositories/note-reaction.ts diff --git a/packages/backend/src/models/repositories/note.ts b/packages/backend/src/models/repositories/note.ts new file mode 100644 index 000000000..c076cb31e --- /dev/null +++ b/packages/backend/src/models/repositories/note.ts @@ -0,0 +1,507 @@ +import { EntityRepository, Repository, In } from 'typeorm'; +import * as mfm from 'mfm-js'; +import { Note } from '@/models/entities/note'; +import { User } from '@/models/entities/user'; +import { Users, PollVotes, DriveFiles, NoteReactions, Followings, Polls, Channels } from '../index'; +import { Packed } from '@/misc/schema'; +import { nyaize } from '@/misc/nyaize'; +import { awaitAll } from '@/prelude/await-all'; +import { convertLegacyReaction, convertLegacyReactions, decodeReaction } from '@/misc/reaction-lib'; +import { NoteReaction } from '@/models/entities/note-reaction'; +import { aggregateNoteEmojis, populateEmojis, prefetchEmojis } from '@/misc/populate-emojis'; + +@EntityRepository(Note) +export class NoteRepository extends Repository { + public validateCw(x: string) { + return x.trim().length <= 100; + } + + public async isVisibleForMe(note: Note, meId: User['id'] | null): Promise { + // visibility が specified かつ自分が指定されていなかったら非表示 + if (note.visibility === 'specified') { + if (meId == null) { + return false; + } else if (meId === note.userId) { + return true; + } else { + // 指定されているかどうか + const specified = note.visibleUserIds.some((id: any) => meId === id); + + if (specified) { + return true; + } else { + return false; + } + } + } + + // visibility が followers かつ自分が投稿者のフォロワーでなかったら非表示 + if (note.visibility === 'followers') { + if (meId == null) { + return false; + } else if (meId === note.userId) { + return true; + } else if (note.reply && (meId === note.reply.userId)) { + // 自分の投稿に対するリプライ + return true; + } else if (note.mentions && note.mentions.some(id => meId === id)) { + // 自分へのメンション + return true; + } else { + // フォロワーかどうか + const following = await Followings.findOne({ + followeeId: note.userId, + followerId: meId + }); + + if (following == null) { + return false; + } else { + return true; + } + } + } + + return true; + } + + private async hideNote(packedNote: Packed<'Note'>, meId: User['id'] | null) { + // TODO: isVisibleForMe を使うようにしても良さそう(型違うけど) + let hide = false; + + // visibility が specified かつ自分が指定されていなかったら非表示 + if (packedNote.visibility === 'specified') { + if (meId == null) { + hide = true; + } else if (meId === packedNote.userId) { + hide = false; + } else { + // 指定されているかどうか + const specified = packedNote.visibleUserIds!.some((id: any) => meId === id); + + if (specified) { + hide = false; + } else { + hide = true; + } + } + } + + // visibility が followers かつ自分が投稿者のフォロワーでなかったら非表示 + if (packedNote.visibility === 'followers') { + if (meId == null) { + hide = true; + } else if (meId === packedNote.userId) { + hide = false; + } else if (packedNote.reply && (meId === packedNote.reply.userId)) { + // 自分の投稿に対するリプライ + hide = false; + } else if (packedNote.mentions && packedNote.mentions.some(id => meId === id)) { + // 自分へのメンション + hide = false; + } else { + // フォロワーかどうか + const following = await Followings.findOne({ + followeeId: packedNote.userId, + followerId: meId + }); + + if (following == null) { + hide = true; + } else { + hide = false; + } + } + } + + if (hide) { + packedNote.visibleUserIds = undefined; + packedNote.fileIds = []; + packedNote.files = []; + packedNote.text = null; + packedNote.poll = undefined; + packedNote.cw = null; + packedNote.isHidden = true; + } + } + + public async pack( + src: Note['id'] | Note, + me?: { id: User['id'] } | null | undefined, + options?: { + detail?: boolean; + skipHide?: boolean; + _hint_?: { + myReactions: Map; + }; + } + ): Promise> { + const opts = Object.assign({ + detail: true, + skipHide: false + }, options); + + const meId = me ? me.id : null; + const note = typeof src === 'object' ? src : await this.findOneOrFail(src); + const host = note.userHost; + + async function populatePoll() { + const poll = await Polls.findOneOrFail(note.id); + const choices = poll.choices.map(c => ({ + text: c, + votes: poll.votes[poll.choices.indexOf(c)], + isVoted: false + })); + + if (poll.multiple) { + const votes = await PollVotes.find({ + userId: meId!, + noteId: note.id + }); + + const myChoices = votes.map(v => v.choice); + for (const myChoice of myChoices) { + choices[myChoice].isVoted = true; + } + } else { + const vote = await PollVotes.findOne({ + userId: meId!, + noteId: note.id + }); + + if (vote) { + choices[vote.choice].isVoted = true; + } + } + + return { + multiple: poll.multiple, + expiresAt: poll.expiresAt, + choices + }; + } + + async function populateMyReaction() { + if (options?._hint_?.myReactions) { + const reaction = options._hint_.myReactions.get(note.id); + if (reaction) { + return convertLegacyReaction(reaction.reaction); + } else if (reaction === null) { + return undefined; + } + // 実装上抜けがあるだけかもしれないので、「ヒントに含まれてなかったら(=undefinedなら)return」のようにはしない + } + + const reaction = await NoteReactions.findOne({ + userId: meId!, + noteId: note.id, + }); + + if (reaction) { + return convertLegacyReaction(reaction.reaction); + } + + return undefined; + } + + let text = note.text; + + if (note.name && (note.url || note.uri)) { + text = `【${note.name}】\n${(note.text || '').trim()}\n\n${note.url || note.uri}`; + } + + const channel = note.channelId + ? note.channel + ? note.channel + : await Channels.findOne(note.channelId) + : null; + + const reactionEmojiNames = Object.keys(note.reactions).filter(x => x?.startsWith(':')).map(x => decodeReaction(x).reaction).map(x => x.replace(/:/g, '')); + + const packed = await awaitAll({ + id: note.id, + createdAt: note.createdAt.toISOString(), + userId: note.userId, + user: Users.pack(note.user || note.userId, me, { + detail: false, + }), + text: text, + cw: note.cw, + visibility: note.visibility, + localOnly: note.localOnly || undefined, + visibleUserIds: note.visibility === 'specified' ? note.visibleUserIds : undefined, + renoteCount: note.renoteCount, + repliesCount: note.repliesCount, + reactions: convertLegacyReactions(note.reactions), + tags: note.tags.length > 0 ? note.tags : undefined, + emojis: populateEmojis(note.emojis.concat(reactionEmojiNames), host), + fileIds: note.fileIds, + files: DriveFiles.packMany(note.fileIds), + replyId: note.replyId, + renoteId: note.renoteId, + channelId: note.channelId || undefined, + channel: channel ? { + id: channel.id, + name: channel.name, + } : undefined, + mentions: note.mentions.length > 0 ? note.mentions : undefined, + uri: note.uri || undefined, + url: note.url || undefined, + + ...(opts.detail ? { + reply: note.replyId ? this.pack(note.reply || note.replyId, me, { + detail: false, + _hint_: options?._hint_ + }) : undefined, + + renote: note.renoteId ? this.pack(note.renote || note.renoteId, me, { + detail: true, + _hint_: options?._hint_ + }) : undefined, + + poll: note.hasPoll ? populatePoll() : undefined, + + ...(meId ? { + myReaction: populateMyReaction() + } : {}) + } : {}) + }); + + if (packed.user.isCat && packed.text) { + const tokens = packed.text ? mfm.parse(packed.text) : []; + mfm.inspect(tokens, node => { + if (node.type === 'text') { + // TODO: quoteなtextはskip + node.props.text = nyaize(node.props.text); + } + }); + packed.text = mfm.toString(tokens); + } + + if (!opts.skipHide) { + await this.hideNote(packed, meId); + } + + return packed; + } + + public async packMany( + notes: Note[], + me?: { id: User['id'] } | null | undefined, + options?: { + detail?: boolean; + skipHide?: boolean; + } + ) { + if (notes.length === 0) return []; + + const meId = me ? me.id : null; + const myReactionsMap = new Map(); + if (meId) { + const renoteIds = notes.filter(n => n.renoteId != null).map(n => n.renoteId!); + const targets = [...notes.map(n => n.id), ...renoteIds]; + const myReactions = await NoteReactions.find({ + userId: meId, + noteId: In(targets), + }); + + for (const target of targets) { + myReactionsMap.set(target, myReactions.find(reaction => reaction.noteId === target) || null); + } + } + + await prefetchEmojis(aggregateNoteEmojis(notes)); + + return await Promise.all(notes.map(n => this.pack(n, me, { + ...options, + _hint_: { + myReactions: myReactionsMap + } + }))); + } +} + +export const packedNoteSchema = { + type: 'object' as const, + optional: false as const, nullable: false as const, + properties: { + id: { + type: 'string' as const, + optional: false as const, nullable: false as const, + format: 'id', + example: 'xxxxxxxxxx', + }, + createdAt: { + type: 'string' as const, + optional: false as const, nullable: false as const, + format: 'date-time', + }, + text: { + type: 'string' as const, + optional: false as const, nullable: true as const, + }, + cw: { + type: 'string' as const, + optional: true as const, nullable: true as const, + }, + userId: { + type: 'string' as const, + optional: false as const, nullable: false as const, + format: 'id', + }, + user: { + type: 'object' as const, + ref: 'User' as const, + optional: false as const, nullable: false as const, + }, + replyId: { + type: 'string' as const, + optional: true as const, nullable: true as const, + format: 'id', + example: 'xxxxxxxxxx', + }, + renoteId: { + type: 'string' as const, + optional: true as const, nullable: true as const, + format: 'id', + example: 'xxxxxxxxxx', + }, + reply: { + type: 'object' as const, + optional: true as const, nullable: true as const, + ref: 'Note' as const, + }, + renote: { + type: 'object' as const, + optional: true as const, nullable: true as const, + ref: 'Note' as const, + }, + isHidden: { + type: 'boolean' as const, + optional: true as const, nullable: false as const, + }, + visibility: { + type: 'string' as const, + optional: false as const, nullable: false as const, + }, + mentions: { + type: 'array' as const, + optional: true as const, nullable: false as const, + items: { + type: 'string' as const, + optional: false as const, nullable: false as const, + format: 'id' + } + }, + visibleUserIds: { + type: 'array' as const, + optional: true as const, nullable: false as const, + items: { + type: 'string' as const, + optional: false as const, nullable: false as const, + format: 'id' + } + }, + fileIds: { + type: 'array' as const, + optional: true as const, nullable: false as const, + items: { + type: 'string' as const, + optional: false as const, nullable: false as const, + format: 'id' + } + }, + files: { + type: 'array' as const, + optional: true as const, nullable: false as const, + items: { + type: 'object' as const, + optional: false as const, nullable: false as const, + ref: 'DriveFile' as const, + } + }, + tags: { + type: 'array' as const, + optional: true as const, nullable: false as const, + items: { + type: 'string' as const, + optional: false as const, nullable: false as const, + } + }, + poll: { + type: 'object' as const, + optional: true as const, nullable: true as const, + }, + channelId: { + type: 'string' as const, + optional: true as const, nullable: true as const, + format: 'id', + example: 'xxxxxxxxxx', + }, + channel: { + type: 'object' as const, + optional: true as const, nullable: true as const, + items: { + type: 'object' as const, + optional: false as const, nullable: false as const, + properties: { + id: { + type: 'string' as const, + optional: false as const, nullable: false as const, + }, + name: { + type: 'string' as const, + optional: false as const, nullable: true as const, + }, + }, + }, + }, + localOnly: { + type: 'boolean' as const, + optional: true as const, nullable: false as const, + }, + emojis: { + type: 'array' as const, + optional: false as const, nullable: false as const, + items: { + type: 'object' as const, + optional: false as const, nullable: false as const, + properties: { + name: { + type: 'string' as const, + optional: false as const, nullable: false as const, + }, + url: { + type: 'string' as const, + optional: false as const, nullable: true as const, + }, + }, + }, + }, + reactions: { + type: 'object' as const, + optional: false as const, nullable: false as const, + }, + renoteCount: { + type: 'number' as const, + optional: false as const, nullable: false as const, + }, + repliesCount: { + type: 'number' as const, + optional: false as const, nullable: false as const, + }, + uri: { + type: 'string' as const, + optional: true as const, nullable: false as const, + }, + url: { + type: 'string' as const, + optional: true as const, nullable: false as const, + }, + + myReaction: { + type: 'object' as const, + optional: true as const, nullable: true as const, + }, + }, +}; diff --git a/src/models/repositories/notification.ts b/packages/backend/src/models/repositories/notification.ts similarity index 100% rename from src/models/repositories/notification.ts rename to packages/backend/src/models/repositories/notification.ts diff --git a/src/models/repositories/page-like.ts b/packages/backend/src/models/repositories/page-like.ts similarity index 100% rename from src/models/repositories/page-like.ts rename to packages/backend/src/models/repositories/page-like.ts diff --git a/src/models/repositories/page.ts b/packages/backend/src/models/repositories/page.ts similarity index 100% rename from src/models/repositories/page.ts rename to packages/backend/src/models/repositories/page.ts diff --git a/src/models/repositories/queue.ts b/packages/backend/src/models/repositories/queue.ts similarity index 100% rename from src/models/repositories/queue.ts rename to packages/backend/src/models/repositories/queue.ts diff --git a/src/models/repositories/relay.ts b/packages/backend/src/models/repositories/relay.ts similarity index 100% rename from src/models/repositories/relay.ts rename to packages/backend/src/models/repositories/relay.ts diff --git a/src/models/repositories/signin.ts b/packages/backend/src/models/repositories/signin.ts similarity index 100% rename from src/models/repositories/signin.ts rename to packages/backend/src/models/repositories/signin.ts diff --git a/src/models/repositories/user-group-invitation.ts b/packages/backend/src/models/repositories/user-group-invitation.ts similarity index 100% rename from src/models/repositories/user-group-invitation.ts rename to packages/backend/src/models/repositories/user-group-invitation.ts diff --git a/src/models/repositories/user-group.ts b/packages/backend/src/models/repositories/user-group.ts similarity index 100% rename from src/models/repositories/user-group.ts rename to packages/backend/src/models/repositories/user-group.ts diff --git a/src/models/repositories/user-list.ts b/packages/backend/src/models/repositories/user-list.ts similarity index 100% rename from src/models/repositories/user-list.ts rename to packages/backend/src/models/repositories/user-list.ts diff --git a/packages/backend/src/models/repositories/user.ts b/packages/backend/src/models/repositories/user.ts new file mode 100644 index 000000000..fc0860970 --- /dev/null +++ b/packages/backend/src/models/repositories/user.ts @@ -0,0 +1,659 @@ +import $ from 'cafy'; +import { EntityRepository, Repository, In, Not } from 'typeorm'; +import { User, ILocalUser, IRemoteUser } from '@/models/entities/user'; +import { Notes, NoteUnreads, FollowRequests, Notifications, MessagingMessages, UserNotePinings, Followings, Blockings, Mutings, UserProfiles, UserSecurityKeys, UserGroupJoinings, Pages, Announcements, AnnouncementReads, Antennas, AntennaNotes, ChannelFollowings, Instances } from '../index'; +import config from '@/config/index'; +import { Packed } from '@/misc/schema'; +import { awaitAll } from '@/prelude/await-all'; +import { populateEmojis } from '@/misc/populate-emojis'; +import { getAntennas } from '@/misc/antenna-cache'; +import { USER_ACTIVE_THRESHOLD, USER_ONLINE_THRESHOLD } from '@/const'; + +@EntityRepository(User) +export class UserRepository extends Repository { + public async getRelation(me: User['id'], target: User['id']) { + const [following1, following2, followReq1, followReq2, toBlocking, fromBlocked, mute] = await Promise.all([ + Followings.findOne({ + followerId: me, + followeeId: target + }), + Followings.findOne({ + followerId: target, + followeeId: me + }), + FollowRequests.findOne({ + followerId: me, + followeeId: target + }), + FollowRequests.findOne({ + followerId: target, + followeeId: me + }), + Blockings.findOne({ + blockerId: me, + blockeeId: target + }), + Blockings.findOne({ + blockerId: target, + blockeeId: me + }), + Mutings.findOne({ + muterId: me, + muteeId: target + }) + ]); + + return { + id: target, + isFollowing: following1 != null, + hasPendingFollowRequestFromYou: followReq1 != null, + hasPendingFollowRequestToYou: followReq2 != null, + isFollowed: following2 != null, + isBlocking: toBlocking != null, + isBlocked: fromBlocked != null, + isMuted: mute != null + }; + } + + public async getHasUnreadMessagingMessage(userId: User['id']): Promise { + const mute = await Mutings.find({ + muterId: userId + }); + + const joinings = await UserGroupJoinings.find({ userId: userId }); + + const groupQs = Promise.all(joinings.map(j => MessagingMessages.createQueryBuilder('message') + .where(`message.groupId = :groupId`, { groupId: j.userGroupId }) + .andWhere('message.userId != :userId', { userId: userId }) + .andWhere('NOT (:userId = ANY(message.reads))', { userId: userId }) + .andWhere('message.createdAt > :joinedAt', { joinedAt: j.createdAt }) // 自分が加入する前の会話については、未読扱いしない + .getOne().then(x => x != null))); + + const [withUser, withGroups] = await Promise.all([ + MessagingMessages.count({ + where: { + recipientId: userId, + isRead: false, + ...(mute.length > 0 ? { userId: Not(In(mute.map(x => x.muteeId))) } : {}), + }, + take: 1 + }).then(count => count > 0), + groupQs + ]); + + return withUser || withGroups.some(x => x); + } + + public async getHasUnreadAnnouncement(userId: User['id']): Promise { + const reads = await AnnouncementReads.find({ + userId: userId + }); + + const count = await Announcements.count(reads.length > 0 ? { + id: Not(In(reads.map(read => read.announcementId))) + } : {}); + + return count > 0; + } + + public async getHasUnreadAntenna(userId: User['id']): Promise { + const myAntennas = (await getAntennas()).filter(a => a.userId === userId); + + const unread = myAntennas.length > 0 ? await AntennaNotes.findOne({ + antennaId: In(myAntennas.map(x => x.id)), + read: false + }) : null; + + return unread != null; + } + + public async getHasUnreadChannel(userId: User['id']): Promise { + const channels = await ChannelFollowings.find({ followerId: userId }); + + const unread = channels.length > 0 ? await NoteUnreads.findOne({ + userId: userId, + noteChannelId: In(channels.map(x => x.followeeId)), + }) : null; + + return unread != null; + } + + public async getHasUnreadNotification(userId: User['id']): Promise { + const mute = await Mutings.find({ + muterId: userId + }); + const mutedUserIds = mute.map(m => m.muteeId); + + const count = await Notifications.count({ + where: { + notifieeId: userId, + ...(mutedUserIds.length > 0 ? { notifierId: Not(In(mutedUserIds)) } : {}), + isRead: false + }, + take: 1 + }); + + return count > 0; + } + + public async getHasPendingReceivedFollowRequest(userId: User['id']): Promise { + const count = await FollowRequests.count({ + followeeId: userId + }); + + return count > 0; + } + + public getOnlineStatus(user: User): string { + if (user.hideOnlineStatus) return 'unknown'; + if (user.lastActiveDate == null) return 'unknown'; + const elapsed = Date.now() - user.lastActiveDate.getTime(); + return ( + elapsed < USER_ONLINE_THRESHOLD ? 'online' : + elapsed < USER_ACTIVE_THRESHOLD ? 'active' : + 'offline' + ); + } + + public getAvatarUrl(user: User): string { + if (user.avatarUrl) { + return user.avatarUrl; + } else { + return `${config.url}/random-avatar/${user.id}`; + } + } + + public async pack( + src: User['id'] | User, + me?: { id: User['id'] } | null | undefined, + options?: { + detail?: boolean, + includeSecrets?: boolean, + } + ): Promise> { + const opts = Object.assign({ + detail: false, + includeSecrets: false + }, options); + + const user = typeof src === 'object' ? src : await this.findOneOrFail(src); + const meId = me ? me.id : null; + + const relation = meId && (meId !== user.id) && opts.detail ? await this.getRelation(meId, user.id) : null; + const pins = opts.detail ? await UserNotePinings.createQueryBuilder('pin') + .where('pin.userId = :userId', { userId: user.id }) + .innerJoinAndSelect('pin.note', 'note') + .orderBy('pin.id', 'DESC') + .getMany() : []; + const profile = opts.detail ? await UserProfiles.findOneOrFail(user.id) : null; + + const followingCount = profile == null ? null : + (profile.ffVisibility === 'public') || (meId === user.id) ? user.followingCount : + (profile.ffVisibility === 'followers') && (relation!.isFollowing) ? user.followingCount : + null; + + const followersCount = profile == null ? null : + (profile.ffVisibility === 'public') || (meId === user.id) ? user.followersCount : + (profile.ffVisibility === 'followers') && (relation!.isFollowing) ? user.followersCount : + null; + + const falsy = opts.detail ? false : undefined; + + const packed = { + id: user.id, + name: user.name, + username: user.username, + host: user.host, + avatarUrl: this.getAvatarUrl(user), + avatarBlurhash: user.avatarBlurhash, + avatarColor: null, // 後方互換性のため + isAdmin: user.isAdmin || falsy, + isModerator: user.isModerator || falsy, + isBot: user.isBot || falsy, + isCat: user.isCat || falsy, + instance: user.host ? Instances.findOne({ host: user.host }).then(instance => instance ? { + name: instance.name, + softwareName: instance.softwareName, + softwareVersion: instance.softwareVersion, + iconUrl: instance.iconUrl, + faviconUrl: instance.faviconUrl, + themeColor: instance.themeColor, + } : undefined) : undefined, + emojis: populateEmojis(user.emojis, user.host), + onlineStatus: this.getOnlineStatus(user), + + ...(opts.detail ? { + url: profile!.url, + uri: user.uri, + createdAt: user.createdAt.toISOString(), + updatedAt: user.updatedAt ? user.updatedAt.toISOString() : null, + lastFetchedAt: user.lastFetchedAt?.toISOString(), + bannerUrl: user.bannerUrl, + bannerBlurhash: user.bannerBlurhash, + bannerColor: null, // 後方互換性のため + isLocked: user.isLocked, + isModerator: user.isModerator || falsy, + isSilenced: user.isSilenced || falsy, + isSuspended: user.isSuspended || falsy, + description: profile!.description, + location: profile!.location, + birthday: profile!.birthday, + lang: profile!.lang, + fields: profile!.fields, + followersCount: followersCount || 0, + followingCount: followingCount || 0, + notesCount: user.notesCount, + pinnedNoteIds: pins.map(pin => pin.noteId), + pinnedNotes: Notes.packMany(pins.map(pin => pin.note!), me, { + detail: true + }), + pinnedPageId: profile!.pinnedPageId, + pinnedPage: profile!.pinnedPageId ? Pages.pack(profile!.pinnedPageId, me) : null, + publicReactions: profile!.publicReactions, + ffVisibility: profile!.ffVisibility, + twoFactorEnabled: profile!.twoFactorEnabled, + usePasswordLessLogin: profile!.usePasswordLessLogin, + securityKeys: profile!.twoFactorEnabled + ? UserSecurityKeys.count({ + userId: user.id + }).then(result => result >= 1) + : false, + } : {}), + + ...(opts.detail && meId === user.id ? { + avatarId: user.avatarId, + bannerId: user.bannerId, + injectFeaturedNote: profile!.injectFeaturedNote, + receiveAnnouncementEmail: profile!.receiveAnnouncementEmail, + alwaysMarkNsfw: profile!.alwaysMarkNsfw, + carefulBot: profile!.carefulBot, + autoAcceptFollowed: profile!.autoAcceptFollowed, + noCrawle: profile!.noCrawle, + isExplorable: user.isExplorable, + isDeleted: user.isDeleted, + hideOnlineStatus: user.hideOnlineStatus, + hasUnreadSpecifiedNotes: NoteUnreads.count({ + where: { userId: user.id, isSpecified: true }, + take: 1 + }).then(count => count > 0), + hasUnreadMentions: NoteUnreads.count({ + where: { userId: user.id, isMentioned: true }, + take: 1 + }).then(count => count > 0), + hasUnreadAnnouncement: this.getHasUnreadAnnouncement(user.id), + hasUnreadAntenna: this.getHasUnreadAntenna(user.id), + hasUnreadChannel: this.getHasUnreadChannel(user.id), + hasUnreadMessagingMessage: this.getHasUnreadMessagingMessage(user.id), + hasUnreadNotification: this.getHasUnreadNotification(user.id), + hasPendingReceivedFollowRequest: this.getHasPendingReceivedFollowRequest(user.id), + integrations: profile!.integrations, + mutedWords: profile!.mutedWords, + mutingNotificationTypes: profile!.mutingNotificationTypes, + emailNotificationTypes: profile!.emailNotificationTypes, + } : {}), + + ...(opts.includeSecrets ? { + email: profile!.email, + emailVerified: profile!.emailVerified, + securityKeysList: profile!.twoFactorEnabled + ? UserSecurityKeys.find({ + where: { + userId: user.id + }, + select: ['id', 'name', 'lastUsed'] + }) + : [] + } : {}), + + ...(relation ? { + isFollowing: relation.isFollowing, + isFollowed: relation.isFollowed, + hasPendingFollowRequestFromYou: relation.hasPendingFollowRequestFromYou, + hasPendingFollowRequestToYou: relation.hasPendingFollowRequestToYou, + isBlocking: relation.isBlocking, + isBlocked: relation.isBlocked, + isMuted: relation.isMuted, + } : {}) + }; + + return await awaitAll(packed); + } + + public packMany( + users: (User['id'] | User)[], + me?: { id: User['id'] } | null | undefined, + options?: { + detail?: boolean, + includeSecrets?: boolean, + } + ) { + return Promise.all(users.map(u => this.pack(u, me, options))); + } + + public isLocalUser(user: User): user is ILocalUser; + public isLocalUser(user: T): user is T & { host: null; }; + public isLocalUser(user: User | { host: User['host'] }): boolean { + return user.host == null; + } + + public isRemoteUser(user: User): user is IRemoteUser; + public isRemoteUser(user: T): user is T & { host: string; }; + public isRemoteUser(user: User | { host: User['host'] }): boolean { + return !this.isLocalUser(user); + } + + //#region Validators + public validateLocalUsername = $.str.match(/^\w{1,20}$/); + public validatePassword = $.str.min(1); + public validateName = $.str.min(1).max(50); + public validateDescription = $.str.min(1).max(500); + public validateLocation = $.str.min(1).max(50); + public validateBirthday = $.str.match(/^([0-9]{4})-([0-9]{2})-([0-9]{2})$/); + //#endregion +} + +export const packedUserSchema = { + type: 'object' as const, + nullable: false as const, optional: false as const, + properties: { + id: { + type: 'string' as const, + nullable: false as const, optional: false as const, + format: 'id', + example: 'xxxxxxxxxx', + }, + name: { + type: 'string' as const, + nullable: true as const, optional: false as const, + example: '藍' + }, + username: { + type: 'string' as const, + nullable: false as const, optional: false as const, + example: 'ai' + }, + host: { + type: 'string' as const, + nullable: true as const, optional: false as const, + example: 'misskey.example.com' + }, + avatarUrl: { + type: 'string' as const, + format: 'url', + nullable: true as const, optional: false as const, + }, + avatarBlurhash: { + type: 'any' as const, + nullable: true as const, optional: false as const, + }, + avatarColor: { + type: 'any' as const, + nullable: true as const, optional: false as const, + default: null + }, + isAdmin: { + type: 'boolean' as const, + nullable: false as const, optional: true as const, + default: false + }, + isModerator: { + type: 'boolean' as const, + nullable: false as const, optional: true as const, + default: false + }, + isBot: { + type: 'boolean' as const, + nullable: false as const, optional: true as const, + }, + isCat: { + type: 'boolean' as const, + nullable: false as const, optional: true as const, + }, + emojis: { + type: 'array' as const, + nullable: false as const, optional: false as const, + items: { + type: 'object' as const, + nullable: false as const, optional: false as const, + properties: { + name: { + type: 'string' as const, + nullable: false as const, optional: false as const + }, + url: { + type: 'string' as const, + nullable: false as const, optional: false as const, + format: 'url' + }, + } + } + }, + url: { + type: 'string' as const, + format: 'url', + nullable: true as const, optional: true as const, + }, + createdAt: { + type: 'string' as const, + nullable: false as const, optional: true as const, + format: 'date-time', + }, + updatedAt: { + type: 'string' as const, + nullable: true as const, optional: true as const, + format: 'date-time', + }, + bannerUrl: { + type: 'string' as const, + format: 'url', + nullable: true as const, optional: true as const, + }, + bannerBlurhash: { + type: 'any' as const, + nullable: true as const, optional: true as const, + }, + bannerColor: { + type: 'any' as const, + nullable: true as const, optional: true as const, + default: null + }, + isLocked: { + type: 'boolean' as const, + nullable: false as const, optional: true as const, + }, + isSuspended: { + type: 'boolean' as const, + nullable: false as const, optional: true as const, + example: false + }, + description: { + type: 'string' as const, + nullable: true as const, optional: true as const, + example: 'Hi masters, I am Ai!' + }, + location: { + type: 'string' as const, + nullable: true as const, optional: true as const, + }, + birthday: { + type: 'string' as const, + nullable: true as const, optional: true as const, + example: '2018-03-12' + }, + fields: { + type: 'array' as const, + nullable: false as const, optional: true as const, + items: { + type: 'object' as const, + nullable: false as const, optional: false as const, + properties: { + name: { + type: 'string' as const, + nullable: false as const, optional: false as const + }, + value: { + type: 'string' as const, + nullable: false as const, optional: false as const + } + }, + maxLength: 4 + } + }, + followersCount: { + type: 'number' as const, + nullable: false as const, optional: true as const, + }, + followingCount: { + type: 'number' as const, + nullable: false as const, optional: true as const, + }, + notesCount: { + type: 'number' as const, + nullable: false as const, optional: true as const, + }, + pinnedNoteIds: { + type: 'array' as const, + nullable: false as const, optional: true as const, + items: { + type: 'string' as const, + nullable: false as const, optional: false as const, + format: 'id', + } + }, + pinnedNotes: { + type: 'array' as const, + nullable: false as const, optional: true as const, + items: { + type: 'object' as const, + nullable: false as const, optional: false as const, + ref: 'Note' as const, + } + }, + pinnedPageId: { + type: 'string' as const, + nullable: true as const, optional: true as const + }, + pinnedPage: { + type: 'object' as const, + nullable: true as const, optional: true as const, + ref: 'Page' as const, + }, + twoFactorEnabled: { + type: 'boolean' as const, + nullable: false as const, optional: true as const, + default: false + }, + usePasswordLessLogin: { + type: 'boolean' as const, + nullable: false as const, optional: true as const, + default: false + }, + securityKeys: { + type: 'boolean' as const, + nullable: false as const, optional: true as const, + default: false + }, + avatarId: { + type: 'string' as const, + nullable: true as const, optional: true as const, + format: 'id' + }, + bannerId: { + type: 'string' as const, + nullable: true as const, optional: true as const, + format: 'id' + }, + autoWatch: { + type: 'boolean' as const, + nullable: false as const, optional: true as const + }, + injectFeaturedNote: { + type: 'boolean' as const, + nullable: false as const, optional: true as const + }, + alwaysMarkNsfw: { + type: 'boolean' as const, + nullable: false as const, optional: true as const + }, + carefulBot: { + type: 'boolean' as const, + nullable: false as const, optional: true as const + }, + autoAcceptFollowed: { + type: 'boolean' as const, + nullable: false as const, optional: true as const + }, + hasUnreadSpecifiedNotes: { + type: 'boolean' as const, + nullable: false as const, optional: true as const, + }, + hasUnreadMentions: { + type: 'boolean' as const, + nullable: false as const, optional: true as const, + }, + hasUnreadAnnouncement: { + type: 'boolean' as const, + nullable: false as const, optional: true as const, + }, + hasUnreadAntenna: { + type: 'boolean' as const, + nullable: false as const, optional: true as const, + }, + hasUnreadChannel: { + type: 'boolean' as const, + nullable: false as const, optional: true as const, + }, + hasUnreadMessagingMessage: { + type: 'boolean' as const, + nullable: false as const, optional: true as const, + }, + hasUnreadNotification: { + type: 'boolean' as const, + nullable: false as const, optional: true as const, + }, + hasPendingReceivedFollowRequest: { + type: 'boolean' as const, + nullable: false as const, optional: true as const, + }, + integrations: { + type: 'object' as const, + nullable: false as const, optional: true as const + }, + mutedWords: { + type: 'array' as const, + nullable: false as const, optional: true as const + }, + mutingNotificationTypes: { + type: 'array' as const, + nullable: false as const, optional: true as const + }, + isFollowing: { + type: 'boolean' as const, + optional: true as const, nullable: false as const + }, + hasPendingFollowRequestFromYou: { + type: 'boolean' as const, + optional: true as const, nullable: false as const + }, + hasPendingFollowRequestToYou: { + type: 'boolean' as const, + optional: true as const, nullable: false as const + }, + isFollowed: { + type: 'boolean' as const, + optional: true as const, nullable: false as const + }, + isBlocking: { + type: 'boolean' as const, + optional: true as const, nullable: false as const + }, + isBlocked: { + type: 'boolean' as const, + optional: true as const, nullable: false as const + }, + isMuted: { + type: 'boolean' as const, + optional: true as const, nullable: false as const + } + }, +}; diff --git a/src/prelude/README.md b/packages/backend/src/prelude/README.md similarity index 100% rename from src/prelude/README.md rename to packages/backend/src/prelude/README.md diff --git a/packages/backend/src/prelude/array.ts b/packages/backend/src/prelude/array.ts new file mode 100644 index 000000000..1e9e62b89 --- /dev/null +++ b/packages/backend/src/prelude/array.ts @@ -0,0 +1,138 @@ +import { EndoRelation, Predicate } from './relation'; + +/** + * Count the number of elements that satisfy the predicate + */ + +export function countIf(f: Predicate, xs: T[]): number { + return xs.filter(f).length; +} + +/** + * Count the number of elements that is equal to the element + */ +export function count(a: T, xs: T[]): number { + return countIf(x => x === a, xs); +} + +/** + * Concatenate an array of arrays + */ +export function concat(xss: T[][]): T[] { + return ([] as T[]).concat(...xss); +} + +/** + * Intersperse the element between the elements of the array + * @param sep The element to be interspersed + */ +export function intersperse(sep: T, xs: T[]): T[] { + return concat(xs.map(x => [sep, x])).slice(1); +} + +/** + * Returns the array of elements that is not equal to the element + */ +export function erase(a: T, xs: T[]): T[] { + return xs.filter(x => x !== a); +} + +/** + * Finds the array of all elements in the first array not contained in the second array. + * The order of result values are determined by the first array. + */ +export function difference(xs: T[], ys: T[]): T[] { + return xs.filter(x => !ys.includes(x)); +} + +/** + * Remove all but the first element from every group of equivalent elements + */ +export function unique(xs: T[]): T[] { + return [...new Set(xs)]; +} + +export function sum(xs: number[]): number { + return xs.reduce((a, b) => a + b, 0); +} + +export function maximum(xs: number[]): number { + return Math.max(...xs); +} + +/** + * Splits an array based on the equivalence relation. + * The concatenation of the result is equal to the argument. + */ +export function groupBy(f: EndoRelation, xs: T[]): T[][] { + const groups = [] as T[][]; + for (const x of xs) { + if (groups.length !== 0 && f(groups[groups.length - 1][0], x)) { + groups[groups.length - 1].push(x); + } else { + groups.push([x]); + } + } + return groups; +} + +/** + * Splits an array based on the equivalence relation induced by the function. + * The concatenation of the result is equal to the argument. + */ +export function groupOn(f: (x: T) => S, xs: T[]): T[][] { + return groupBy((a, b) => f(a) === f(b), xs); +} + +export function groupByX(collections: T[], keySelector: (x: T) => string) { + return collections.reduce((obj: Record, item: T) => { + const key = keySelector(item); + if (!Object.prototype.hasOwnProperty.call(obj, key)) { + obj[key] = []; + } + + obj[key].push(item); + + return obj; + }, {}); +} + +/** + * Compare two arrays by lexicographical order + */ +export function lessThan(xs: number[], ys: number[]): boolean { + for (let i = 0; i < Math.min(xs.length, ys.length); i++) { + if (xs[i] < ys[i]) return true; + if (xs[i] > ys[i]) return false; + } + return xs.length < ys.length; +} + +/** + * Returns the longest prefix of elements that satisfy the predicate + */ +export function takeWhile(f: Predicate, xs: T[]): T[] { + const ys = []; + for (const x of xs) { + if (f(x)) { + ys.push(x); + } else { + break; + } + } + return ys; +} + +export function cumulativeSum(xs: number[]): number[] { + const ys = Array.from(xs); // deep copy + for (let i = 1; i < ys.length; i++) ys[i] += ys[i - 1]; + return ys; +} + +export function toArray(x: T | T[] | undefined): T[] { + return Array.isArray(x) ? x : x != null ? [x] : []; +} + +export function toSingle(x: T | T[] | undefined): T | undefined { + return Array.isArray(x) ? x[0] : x; +} diff --git a/src/prelude/await-all.ts b/packages/backend/src/prelude/await-all.ts similarity index 100% rename from src/prelude/await-all.ts rename to packages/backend/src/prelude/await-all.ts diff --git a/src/prelude/math.ts b/packages/backend/src/prelude/math.ts similarity index 100% rename from src/prelude/math.ts rename to packages/backend/src/prelude/math.ts diff --git a/src/prelude/maybe.ts b/packages/backend/src/prelude/maybe.ts similarity index 100% rename from src/prelude/maybe.ts rename to packages/backend/src/prelude/maybe.ts diff --git a/src/prelude/relation.ts b/packages/backend/src/prelude/relation.ts similarity index 100% rename from src/prelude/relation.ts rename to packages/backend/src/prelude/relation.ts diff --git a/src/prelude/string.ts b/packages/backend/src/prelude/string.ts similarity index 100% rename from src/prelude/string.ts rename to packages/backend/src/prelude/string.ts diff --git a/src/prelude/symbol.ts b/packages/backend/src/prelude/symbol.ts similarity index 100% rename from src/prelude/symbol.ts rename to packages/backend/src/prelude/symbol.ts diff --git a/src/prelude/time.ts b/packages/backend/src/prelude/time.ts similarity index 100% rename from src/prelude/time.ts rename to packages/backend/src/prelude/time.ts diff --git a/packages/backend/src/prelude/url.ts b/packages/backend/src/prelude/url.ts new file mode 100644 index 000000000..a4f2f7f5a --- /dev/null +++ b/packages/backend/src/prelude/url.ts @@ -0,0 +1,13 @@ +export function query(obj: Record): string { + const params = Object.entries(obj) + .filter(([, v]) => Array.isArray(v) ? v.length : v !== undefined) + .reduce((a, [k, v]) => (a[k] = v, a), {} as Record); + + return Object.entries(params) + .map((e) => `${e[0]}=${encodeURIComponent(e[1])}`) + .join('&'); +} + +export function appendQuery(url: string, query: string): string { + return `${url}${/\?/.test(url) ? url.endsWith('?') ? '' : '&' : '?'}${query}`; +} diff --git a/src/prelude/xml.ts b/packages/backend/src/prelude/xml.ts similarity index 100% rename from src/prelude/xml.ts rename to packages/backend/src/prelude/xml.ts diff --git a/src/queue/get-job-info.ts b/packages/backend/src/queue/get-job-info.ts similarity index 100% rename from src/queue/get-job-info.ts rename to packages/backend/src/queue/get-job-info.ts diff --git a/src/queue/index.ts b/packages/backend/src/queue/index.ts similarity index 100% rename from src/queue/index.ts rename to packages/backend/src/queue/index.ts diff --git a/src/queue/initialize.ts b/packages/backend/src/queue/initialize.ts similarity index 100% rename from src/queue/initialize.ts rename to packages/backend/src/queue/initialize.ts diff --git a/src/queue/logger.ts b/packages/backend/src/queue/logger.ts similarity index 100% rename from src/queue/logger.ts rename to packages/backend/src/queue/logger.ts diff --git a/src/queue/processors/db/delete-account.ts b/packages/backend/src/queue/processors/db/delete-account.ts similarity index 100% rename from src/queue/processors/db/delete-account.ts rename to packages/backend/src/queue/processors/db/delete-account.ts diff --git a/src/queue/processors/db/delete-drive-files.ts b/packages/backend/src/queue/processors/db/delete-drive-files.ts similarity index 100% rename from src/queue/processors/db/delete-drive-files.ts rename to packages/backend/src/queue/processors/db/delete-drive-files.ts diff --git a/src/queue/processors/db/export-blocking.ts b/packages/backend/src/queue/processors/db/export-blocking.ts similarity index 100% rename from src/queue/processors/db/export-blocking.ts rename to packages/backend/src/queue/processors/db/export-blocking.ts diff --git a/src/queue/processors/db/export-following.ts b/packages/backend/src/queue/processors/db/export-following.ts similarity index 100% rename from src/queue/processors/db/export-following.ts rename to packages/backend/src/queue/processors/db/export-following.ts diff --git a/src/queue/processors/db/export-mute.ts b/packages/backend/src/queue/processors/db/export-mute.ts similarity index 100% rename from src/queue/processors/db/export-mute.ts rename to packages/backend/src/queue/processors/db/export-mute.ts diff --git a/packages/backend/src/queue/processors/db/export-notes.ts b/packages/backend/src/queue/processors/db/export-notes.ts new file mode 100644 index 000000000..761f4d827 --- /dev/null +++ b/packages/backend/src/queue/processors/db/export-notes.ts @@ -0,0 +1,132 @@ +import * as Bull from 'bull'; +import * as tmp from 'tmp'; +import * as fs from 'fs'; + +import { queueLogger } from '../../logger'; +import addFile from '@/services/drive/add-file'; +import * as dateFormat from 'dateformat'; +import { Users, Notes, Polls } from '@/models/index'; +import { MoreThan } from 'typeorm'; +import { Note } from '@/models/entities/note'; +import { Poll } from '@/models/entities/poll'; +import { DbUserJobData } from '@/queue/types'; + +const logger = queueLogger.createSubLogger('export-notes'); + +export async function exportNotes(job: Bull.Job, done: any): Promise { + logger.info(`Exporting notes of ${job.data.user.id} ...`); + + const user = await Users.findOne(job.data.user.id); + if (user == null) { + done(); + return; + } + + // Create temp file + const [path, cleanup] = await new Promise<[string, any]>((res, rej) => { + tmp.file((e, path, fd, cleanup) => { + if (e) return rej(e); + res([path, cleanup]); + }); + }); + + logger.info(`Temp file is ${path}`); + + const stream = fs.createWriteStream(path, { flags: 'a' }); + + await new Promise((res, rej) => { + stream.write('[', err => { + if (err) { + logger.error(err); + rej(err); + } else { + res(); + } + }); + }); + + let exportedNotesCount = 0; + let cursor: Note['id'] | null = null; + + while (true) { + const notes = await Notes.find({ + where: { + userId: user.id, + ...(cursor ? { id: MoreThan(cursor) } : {}), + }, + take: 100, + order: { + id: 1, + }, + }); + + if (notes.length === 0) { + job.progress(100); + break; + } + + cursor = notes[notes.length - 1].id; + + for (const note of notes) { + let poll: Poll | undefined; + if (note.hasPoll) { + poll = await Polls.findOneOrFail({ noteId: note.id }); + } + const content = JSON.stringify(serialize(note, poll)); + await new Promise((res, rej) => { + stream.write(exportedNotesCount === 0 ? content : ',\n' + content, err => { + if (err) { + logger.error(err); + rej(err); + } else { + res(); + } + }); + }); + exportedNotesCount++; + } + + const total = await Notes.count({ + userId: user.id, + }); + + job.progress(exportedNotesCount / total); + } + + await new Promise((res, rej) => { + stream.write(']', err => { + if (err) { + logger.error(err); + rej(err); + } else { + res(); + } + }); + }); + + stream.end(); + logger.succ(`Exported to: ${path}`); + + const fileName = 'notes-' + dateFormat(new Date(), 'yyyy-mm-dd-HH-MM-ss') + '.json'; + const driveFile = await addFile(user, path, fileName, null, null, true); + + logger.succ(`Exported to: ${driveFile.id}`); + cleanup(); + done(); +} + +function serialize(note: Note, poll: Poll | null = null): Record { + return { + id: note.id, + text: note.text, + createdAt: note.createdAt, + fileIds: note.fileIds, + replyId: note.replyId, + renoteId: note.renoteId, + poll: poll, + cw: note.cw, + visibility: note.visibility, + visibleUserIds: note.visibleUserIds, + localOnly: note.localOnly, + }; +} diff --git a/src/queue/processors/db/export-user-lists.ts b/packages/backend/src/queue/processors/db/export-user-lists.ts similarity index 100% rename from src/queue/processors/db/export-user-lists.ts rename to packages/backend/src/queue/processors/db/export-user-lists.ts diff --git a/packages/backend/src/queue/processors/db/import-blocking.ts b/packages/backend/src/queue/processors/db/import-blocking.ts new file mode 100644 index 000000000..2e7710703 --- /dev/null +++ b/packages/backend/src/queue/processors/db/import-blocking.ts @@ -0,0 +1,74 @@ +import * as Bull from 'bull'; + +import { queueLogger } from '../../logger'; +import * as Acct from 'misskey-js/built/acct'; +import { resolveUser } from '@/remote/resolve-user'; +import { downloadTextFile } from '@/misc/download-text-file'; +import { isSelfHost, toPuny } from '@/misc/convert-host'; +import { Users, DriveFiles, Blockings } from '@/models/index'; +import { DbUserImportJobData } from '@/queue/types'; +import block from '@/services/blocking/create'; + +const logger = queueLogger.createSubLogger('import-blocking'); + +export async function importBlocking(job: Bull.Job, done: any): Promise { + logger.info(`Importing blocking of ${job.data.user.id} ...`); + + const user = await Users.findOne(job.data.user.id); + if (user == null) { + done(); + return; + } + + const file = await DriveFiles.findOne({ + id: job.data.fileId + }); + if (file == null) { + done(); + return; + } + + const csv = await downloadTextFile(file.url); + + let linenum = 0; + + for (const line of csv.trim().split('\n')) { + linenum++; + + try { + const acct = line.split(',')[0].trim(); + const { username, host } = Acct.parse(acct); + + let target = isSelfHost(host!) ? await Users.findOne({ + host: null, + usernameLower: username.toLowerCase() + }) : await Users.findOne({ + host: toPuny(host!), + usernameLower: username.toLowerCase() + }); + + if (host == null && target == null) continue; + + if (target == null) { + target = await resolveUser(username, host); + } + + if (target == null) { + throw `cannot resolve user: @${username}@${host}`; + } + + // skip myself + if (target.id === job.data.user.id) continue; + + logger.info(`Block[${linenum}] ${target.id} ...`); + + await block(user, target); + } catch (e) { + logger.warn(`Error in line:${linenum} ${e}`); + } + } + + logger.succ('Imported'); + done(); +} + diff --git a/packages/backend/src/queue/processors/db/import-following.ts b/packages/backend/src/queue/processors/db/import-following.ts new file mode 100644 index 000000000..2bd079e4b --- /dev/null +++ b/packages/backend/src/queue/processors/db/import-following.ts @@ -0,0 +1,73 @@ +import * as Bull from 'bull'; + +import { queueLogger } from '../../logger'; +import follow from '@/services/following/create'; +import * as Acct from 'misskey-js/built/acct'; +import { resolveUser } from '@/remote/resolve-user'; +import { downloadTextFile } from '@/misc/download-text-file'; +import { isSelfHost, toPuny } from '@/misc/convert-host'; +import { Users, DriveFiles } from '@/models/index'; +import { DbUserImportJobData } from '@/queue/types'; + +const logger = queueLogger.createSubLogger('import-following'); + +export async function importFollowing(job: Bull.Job, done: any): Promise { + logger.info(`Importing following of ${job.data.user.id} ...`); + + const user = await Users.findOne(job.data.user.id); + if (user == null) { + done(); + return; + } + + const file = await DriveFiles.findOne({ + id: job.data.fileId + }); + if (file == null) { + done(); + return; + } + + const csv = await downloadTextFile(file.url); + + let linenum = 0; + + for (const line of csv.trim().split('\n')) { + linenum++; + + try { + const acct = line.split(',')[0].trim(); + const { username, host } = Acct.parse(acct); + + let target = isSelfHost(host!) ? await Users.findOne({ + host: null, + usernameLower: username.toLowerCase() + }) : await Users.findOne({ + host: toPuny(host!), + usernameLower: username.toLowerCase() + }); + + if (host == null && target == null) continue; + + if (target == null) { + target = await resolveUser(username, host); + } + + if (target == null) { + throw `cannot resolve user: @${username}@${host}`; + } + + // skip myself + if (target.id === job.data.user.id) continue; + + logger.info(`Follow[${linenum}] ${target.id} ...`); + + follow(user, target); + } catch (e) { + logger.warn(`Error in line:${linenum} ${e}`); + } + } + + logger.succ('Imported'); + done(); +} diff --git a/packages/backend/src/queue/processors/db/import-muting.ts b/packages/backend/src/queue/processors/db/import-muting.ts new file mode 100644 index 000000000..806098062 --- /dev/null +++ b/packages/backend/src/queue/processors/db/import-muting.ts @@ -0,0 +1,83 @@ +import * as Bull from 'bull'; + +import { queueLogger } from '../../logger'; +import * as Acct from 'misskey-js/built/acct'; +import { resolveUser } from '@/remote/resolve-user'; +import { downloadTextFile } from '@/misc/download-text-file'; +import { isSelfHost, toPuny } from '@/misc/convert-host'; +import { Users, DriveFiles, Mutings } from '@/models/index'; +import { DbUserImportJobData } from '@/queue/types'; +import { User } from '@/models/entities/user'; +import { genId } from '@/misc/gen-id'; + +const logger = queueLogger.createSubLogger('import-muting'); + +export async function importMuting(job: Bull.Job, done: any): Promise { + logger.info(`Importing muting of ${job.data.user.id} ...`); + + const user = await Users.findOne(job.data.user.id); + if (user == null) { + done(); + return; + } + + const file = await DriveFiles.findOne({ + id: job.data.fileId + }); + if (file == null) { + done(); + return; + } + + const csv = await downloadTextFile(file.url); + + let linenum = 0; + + for (const line of csv.trim().split('\n')) { + linenum++; + + try { + const acct = line.split(',')[0].trim(); + const { username, host } = Acct.parse(acct); + + let target = isSelfHost(host!) ? await Users.findOne({ + host: null, + usernameLower: username.toLowerCase() + }) : await Users.findOne({ + host: toPuny(host!), + usernameLower: username.toLowerCase() + }); + + if (host == null && target == null) continue; + + if (target == null) { + target = await resolveUser(username, host); + } + + if (target == null) { + throw `cannot resolve user: @${username}@${host}`; + } + + // skip myself + if (target.id === job.data.user.id) continue; + + logger.info(`Mute[${linenum}] ${target.id} ...`); + + await mute(user, target); + } catch (e) { + logger.warn(`Error in line:${linenum} ${e}`); + } + } + + logger.succ('Imported'); + done(); +} + +async function mute(user: User, target: User) { + await Mutings.insert({ + id: genId(), + createdAt: new Date(), + muterId: user.id, + muteeId: target.id, + }); +} diff --git a/packages/backend/src/queue/processors/db/import-user-lists.ts b/packages/backend/src/queue/processors/db/import-user-lists.ts new file mode 100644 index 000000000..46b728b38 --- /dev/null +++ b/packages/backend/src/queue/processors/db/import-user-lists.ts @@ -0,0 +1,80 @@ +import * as Bull from 'bull'; + +import { queueLogger } from '../../logger'; +import * as Acct from 'misskey-js/built/acct'; +import { resolveUser } from '@/remote/resolve-user'; +import { pushUserToUserList } from '@/services/user-list/push'; +import { downloadTextFile } from '@/misc/download-text-file'; +import { isSelfHost, toPuny } from '@/misc/convert-host'; +import { DriveFiles, Users, UserLists, UserListJoinings } from '@/models/index'; +import { genId } from '@/misc/gen-id'; +import { DbUserImportJobData } from '@/queue/types'; + +const logger = queueLogger.createSubLogger('import-user-lists'); + +export async function importUserLists(job: Bull.Job, done: any): Promise { + logger.info(`Importing user lists of ${job.data.user.id} ...`); + + const user = await Users.findOne(job.data.user.id); + if (user == null) { + done(); + return; + } + + const file = await DriveFiles.findOne({ + id: job.data.fileId + }); + if (file == null) { + done(); + return; + } + + const csv = await downloadTextFile(file.url); + + let linenum = 0; + + for (const line of csv.trim().split('\n')) { + linenum++; + + try { + const listName = line.split(',')[0].trim(); + const { username, host } = Acct.parse(line.split(',')[1].trim()); + + let list = await UserLists.findOne({ + userId: user.id, + name: listName + }); + + if (list == null) { + list = await UserLists.save({ + id: genId(), + createdAt: new Date(), + userId: user.id, + name: listName, + userIds: [] + }); + } + + let target = isSelfHost(host!) ? await Users.findOne({ + host: null, + usernameLower: username.toLowerCase() + }) : await Users.findOne({ + host: toPuny(host!), + usernameLower: username.toLowerCase() + }); + + if (target == null) { + target = await resolveUser(username, host); + } + + if (await UserListJoinings.findOne({ userListId: list.id, userId: target.id }) != null) continue; + + pushUserToUserList(target, list); + } catch (e) { + logger.warn(`Error in line:${linenum} ${e}`); + } + } + + logger.succ('Imported'); + done(); +} diff --git a/src/queue/processors/db/index.ts b/packages/backend/src/queue/processors/db/index.ts similarity index 100% rename from src/queue/processors/db/index.ts rename to packages/backend/src/queue/processors/db/index.ts diff --git a/src/queue/processors/deliver.ts b/packages/backend/src/queue/processors/deliver.ts similarity index 100% rename from src/queue/processors/deliver.ts rename to packages/backend/src/queue/processors/deliver.ts diff --git a/src/queue/processors/inbox.ts b/packages/backend/src/queue/processors/inbox.ts similarity index 100% rename from src/queue/processors/inbox.ts rename to packages/backend/src/queue/processors/inbox.ts diff --git a/packages/backend/src/queue/processors/object-storage/clean-remote-files.ts b/packages/backend/src/queue/processors/object-storage/clean-remote-files.ts new file mode 100644 index 000000000..a094c39d5 --- /dev/null +++ b/packages/backend/src/queue/processors/object-storage/clean-remote-files.ts @@ -0,0 +1,50 @@ +import * as Bull from 'bull'; + +import { queueLogger } from '../../logger'; +import { deleteFileSync } from '@/services/drive/delete-file'; +import { DriveFiles } from '@/models/index'; +import { MoreThan, Not, IsNull } from 'typeorm'; + +const logger = queueLogger.createSubLogger('clean-remote-files'); + +export default async function cleanRemoteFiles(job: Bull.Job>, done: any): Promise { + logger.info(`Deleting cached remote files...`); + + let deletedCount = 0; + let cursor: any = null; + + while (true) { + const files = await DriveFiles.find({ + where: { + userHost: Not(IsNull()), + isLink: false, + ...(cursor ? { id: MoreThan(cursor) } : {}) + }, + take: 8, + order: { + id: 1 + } + }); + + if (files.length === 0) { + job.progress(100); + break; + } + + cursor = files[files.length - 1].id; + + await Promise.all(files.map(file => deleteFileSync(file, true))); + + deletedCount += 8; + + const total = await DriveFiles.count({ + userHost: Not(IsNull()), + isLink: false, + }); + + job.progress(deletedCount / total); + } + + logger.succ(`All cahced remote files has been deleted.`); + done(); +} diff --git a/src/queue/processors/object-storage/delete-file.ts b/packages/backend/src/queue/processors/object-storage/delete-file.ts similarity index 100% rename from src/queue/processors/object-storage/delete-file.ts rename to packages/backend/src/queue/processors/object-storage/delete-file.ts diff --git a/src/queue/processors/object-storage/index.ts b/packages/backend/src/queue/processors/object-storage/index.ts similarity index 100% rename from src/queue/processors/object-storage/index.ts rename to packages/backend/src/queue/processors/object-storage/index.ts diff --git a/packages/backend/src/queue/processors/system/index.ts b/packages/backend/src/queue/processors/system/index.ts new file mode 100644 index 000000000..8460ea0a9 --- /dev/null +++ b/packages/backend/src/queue/processors/system/index.ts @@ -0,0 +1,12 @@ +import * as Bull from 'bull'; +import { resyncCharts } from './resync-charts'; + +const jobs = { + resyncCharts, +} as Record> | Bull.ProcessPromiseFunction>>; + +export default function(dbQueue: Bull.Queue>) { + for (const [k, v] of Object.entries(jobs)) { + dbQueue.process(k, v); + } +} diff --git a/packages/backend/src/queue/processors/system/resync-charts.ts b/packages/backend/src/queue/processors/system/resync-charts.ts new file mode 100644 index 000000000..78a70bb98 --- /dev/null +++ b/packages/backend/src/queue/processors/system/resync-charts.ts @@ -0,0 +1,21 @@ +import * as Bull from 'bull'; + +import { queueLogger } from '../../logger'; +import { driveChart, notesChart, usersChart } from '@/services/chart/index'; + +const logger = queueLogger.createSubLogger('resync-charts'); + +export async function resyncCharts(job: Bull.Job>, done: any): Promise { + logger.info(`Resync charts...`); + + // TODO: ユーザーごとのチャートも更新する + // TODO: インスタンスごとのチャートも更新する + await Promise.all([ + driveChart.resync(), + notesChart.resync(), + usersChart.resync(), + ]); + + logger.succ(`All charts successfully resynced.`); + done(); +} diff --git a/packages/backend/src/queue/queues.ts b/packages/backend/src/queue/queues.ts new file mode 100644 index 000000000..b1d790fcb --- /dev/null +++ b/packages/backend/src/queue/queues.ts @@ -0,0 +1,9 @@ +import config from '@/config/index'; +import { initialize as initializeQueue } from './initialize'; +import { DeliverJobData, InboxJobData, DbJobData, ObjectStorageJobData } from './types'; + +export const systemQueue = initializeQueue>('system'); +export const deliverQueue = initializeQueue('deliver', config.deliverJobPerSec || 128); +export const inboxQueue = initializeQueue('inbox', config.inboxJobPerSec || 16); +export const dbQueue = initializeQueue('db'); +export const objectStorageQueue = initializeQueue('objectStorage'); diff --git a/packages/backend/src/queue/types.ts b/packages/backend/src/queue/types.ts new file mode 100644 index 000000000..c8c714715 --- /dev/null +++ b/packages/backend/src/queue/types.ts @@ -0,0 +1,44 @@ +import { DriveFile } from '@/models/entities/drive-file'; +import { User } from '@/models/entities/user'; +import { IActivity } from '@/remote/activitypub/type'; +import * as httpSignature from 'http-signature'; + +export type DeliverJobData = { + /** Actor */ + user: ThinUser; + /** Activity */ + content: unknown; + /** inbox URL to deliver */ + to: string; +}; + +export type InboxJobData = { + activity: IActivity; + signature: httpSignature.IParsedSignature; +}; + +export type DbJobData = DbUserJobData | DbUserImportJobData | DbUserDeleteJobData; + +export type DbUserJobData = { + user: ThinUser; +}; + +export type DbUserDeleteJobData = { + user: ThinUser; + soft?: boolean; +}; + +export type DbUserImportJobData = { + user: ThinUser; + fileId: DriveFile['id']; +}; + +export type ObjectStorageJobData = ObjectStorageFileJobData | Record; + +export type ObjectStorageFileJobData = { + key: string; +}; + +export type ThinUser = { + id: User['id']; +}; diff --git a/src/remote/activitypub/ap-request.ts b/packages/backend/src/remote/activitypub/ap-request.ts similarity index 100% rename from src/remote/activitypub/ap-request.ts rename to packages/backend/src/remote/activitypub/ap-request.ts diff --git a/src/remote/activitypub/audience.ts b/packages/backend/src/remote/activitypub/audience.ts similarity index 100% rename from src/remote/activitypub/audience.ts rename to packages/backend/src/remote/activitypub/audience.ts diff --git a/src/remote/activitypub/db-resolver.ts b/packages/backend/src/remote/activitypub/db-resolver.ts similarity index 100% rename from src/remote/activitypub/db-resolver.ts rename to packages/backend/src/remote/activitypub/db-resolver.ts diff --git a/src/remote/activitypub/deliver-manager.ts b/packages/backend/src/remote/activitypub/deliver-manager.ts similarity index 100% rename from src/remote/activitypub/deliver-manager.ts rename to packages/backend/src/remote/activitypub/deliver-manager.ts diff --git a/src/remote/activitypub/kernel/accept/follow.ts b/packages/backend/src/remote/activitypub/kernel/accept/follow.ts similarity index 100% rename from src/remote/activitypub/kernel/accept/follow.ts rename to packages/backend/src/remote/activitypub/kernel/accept/follow.ts diff --git a/src/remote/activitypub/kernel/accept/index.ts b/packages/backend/src/remote/activitypub/kernel/accept/index.ts similarity index 100% rename from src/remote/activitypub/kernel/accept/index.ts rename to packages/backend/src/remote/activitypub/kernel/accept/index.ts diff --git a/src/remote/activitypub/kernel/add/index.ts b/packages/backend/src/remote/activitypub/kernel/add/index.ts similarity index 100% rename from src/remote/activitypub/kernel/add/index.ts rename to packages/backend/src/remote/activitypub/kernel/add/index.ts diff --git a/src/remote/activitypub/kernel/announce/index.ts b/packages/backend/src/remote/activitypub/kernel/announce/index.ts similarity index 100% rename from src/remote/activitypub/kernel/announce/index.ts rename to packages/backend/src/remote/activitypub/kernel/announce/index.ts diff --git a/src/remote/activitypub/kernel/announce/note.ts b/packages/backend/src/remote/activitypub/kernel/announce/note.ts similarity index 100% rename from src/remote/activitypub/kernel/announce/note.ts rename to packages/backend/src/remote/activitypub/kernel/announce/note.ts diff --git a/src/remote/activitypub/kernel/block/index.ts b/packages/backend/src/remote/activitypub/kernel/block/index.ts similarity index 100% rename from src/remote/activitypub/kernel/block/index.ts rename to packages/backend/src/remote/activitypub/kernel/block/index.ts diff --git a/src/remote/activitypub/kernel/create/index.ts b/packages/backend/src/remote/activitypub/kernel/create/index.ts similarity index 100% rename from src/remote/activitypub/kernel/create/index.ts rename to packages/backend/src/remote/activitypub/kernel/create/index.ts diff --git a/src/remote/activitypub/kernel/create/note.ts b/packages/backend/src/remote/activitypub/kernel/create/note.ts similarity index 100% rename from src/remote/activitypub/kernel/create/note.ts rename to packages/backend/src/remote/activitypub/kernel/create/note.ts diff --git a/src/remote/activitypub/kernel/delete/actor.ts b/packages/backend/src/remote/activitypub/kernel/delete/actor.ts similarity index 100% rename from src/remote/activitypub/kernel/delete/actor.ts rename to packages/backend/src/remote/activitypub/kernel/delete/actor.ts diff --git a/src/remote/activitypub/kernel/delete/index.ts b/packages/backend/src/remote/activitypub/kernel/delete/index.ts similarity index 100% rename from src/remote/activitypub/kernel/delete/index.ts rename to packages/backend/src/remote/activitypub/kernel/delete/index.ts diff --git a/src/remote/activitypub/kernel/delete/note.ts b/packages/backend/src/remote/activitypub/kernel/delete/note.ts similarity index 100% rename from src/remote/activitypub/kernel/delete/note.ts rename to packages/backend/src/remote/activitypub/kernel/delete/note.ts diff --git a/src/remote/activitypub/kernel/flag/index.ts b/packages/backend/src/remote/activitypub/kernel/flag/index.ts similarity index 100% rename from src/remote/activitypub/kernel/flag/index.ts rename to packages/backend/src/remote/activitypub/kernel/flag/index.ts diff --git a/src/remote/activitypub/kernel/follow.ts b/packages/backend/src/remote/activitypub/kernel/follow.ts similarity index 100% rename from src/remote/activitypub/kernel/follow.ts rename to packages/backend/src/remote/activitypub/kernel/follow.ts diff --git a/src/remote/activitypub/kernel/index.ts b/packages/backend/src/remote/activitypub/kernel/index.ts similarity index 100% rename from src/remote/activitypub/kernel/index.ts rename to packages/backend/src/remote/activitypub/kernel/index.ts diff --git a/src/remote/activitypub/kernel/like.ts b/packages/backend/src/remote/activitypub/kernel/like.ts similarity index 100% rename from src/remote/activitypub/kernel/like.ts rename to packages/backend/src/remote/activitypub/kernel/like.ts diff --git a/src/remote/activitypub/kernel/move/index.ts b/packages/backend/src/remote/activitypub/kernel/move/index.ts similarity index 100% rename from src/remote/activitypub/kernel/move/index.ts rename to packages/backend/src/remote/activitypub/kernel/move/index.ts diff --git a/src/remote/activitypub/kernel/read.ts b/packages/backend/src/remote/activitypub/kernel/read.ts similarity index 100% rename from src/remote/activitypub/kernel/read.ts rename to packages/backend/src/remote/activitypub/kernel/read.ts diff --git a/src/remote/activitypub/kernel/reject/follow.ts b/packages/backend/src/remote/activitypub/kernel/reject/follow.ts similarity index 100% rename from src/remote/activitypub/kernel/reject/follow.ts rename to packages/backend/src/remote/activitypub/kernel/reject/follow.ts diff --git a/src/remote/activitypub/kernel/reject/index.ts b/packages/backend/src/remote/activitypub/kernel/reject/index.ts similarity index 100% rename from src/remote/activitypub/kernel/reject/index.ts rename to packages/backend/src/remote/activitypub/kernel/reject/index.ts diff --git a/src/remote/activitypub/kernel/remove/index.ts b/packages/backend/src/remote/activitypub/kernel/remove/index.ts similarity index 100% rename from src/remote/activitypub/kernel/remove/index.ts rename to packages/backend/src/remote/activitypub/kernel/remove/index.ts diff --git a/src/remote/activitypub/kernel/undo/announce.ts b/packages/backend/src/remote/activitypub/kernel/undo/announce.ts similarity index 100% rename from src/remote/activitypub/kernel/undo/announce.ts rename to packages/backend/src/remote/activitypub/kernel/undo/announce.ts diff --git a/src/remote/activitypub/kernel/undo/block.ts b/packages/backend/src/remote/activitypub/kernel/undo/block.ts similarity index 100% rename from src/remote/activitypub/kernel/undo/block.ts rename to packages/backend/src/remote/activitypub/kernel/undo/block.ts diff --git a/src/remote/activitypub/kernel/undo/follow.ts b/packages/backend/src/remote/activitypub/kernel/undo/follow.ts similarity index 100% rename from src/remote/activitypub/kernel/undo/follow.ts rename to packages/backend/src/remote/activitypub/kernel/undo/follow.ts diff --git a/src/remote/activitypub/kernel/undo/index.ts b/packages/backend/src/remote/activitypub/kernel/undo/index.ts similarity index 100% rename from src/remote/activitypub/kernel/undo/index.ts rename to packages/backend/src/remote/activitypub/kernel/undo/index.ts diff --git a/src/remote/activitypub/kernel/undo/like.ts b/packages/backend/src/remote/activitypub/kernel/undo/like.ts similarity index 100% rename from src/remote/activitypub/kernel/undo/like.ts rename to packages/backend/src/remote/activitypub/kernel/undo/like.ts diff --git a/src/remote/activitypub/kernel/update/index.ts b/packages/backend/src/remote/activitypub/kernel/update/index.ts similarity index 100% rename from src/remote/activitypub/kernel/update/index.ts rename to packages/backend/src/remote/activitypub/kernel/update/index.ts diff --git a/src/remote/activitypub/logger.ts b/packages/backend/src/remote/activitypub/logger.ts similarity index 100% rename from src/remote/activitypub/logger.ts rename to packages/backend/src/remote/activitypub/logger.ts diff --git a/packages/backend/src/remote/activitypub/misc/contexts.ts b/packages/backend/src/remote/activitypub/misc/contexts.ts new file mode 100644 index 000000000..64d9da647 --- /dev/null +++ b/packages/backend/src/remote/activitypub/misc/contexts.ts @@ -0,0 +1,526 @@ +/* eslint:disable:quotemark indent */ +const id_v1 = { + "@context": { + "id": "@id", + "type": "@type", + + "cred": "https://w3id.org/credentials#", + "dc": "http://purl.org/dc/terms/", + "identity": "https://w3id.org/identity#", + "perm": "https://w3id.org/permissions#", + "ps": "https://w3id.org/payswarm#", + "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#", + "rdfs": "http://www.w3.org/2000/01/rdf-schema#", + "sec": "https://w3id.org/security#", + "schema": "http://schema.org/", + "xsd": "http://www.w3.org/2001/XMLSchema#", + + "Group": "https://www.w3.org/ns/activitystreams#Group", + + "claim": {"@id": "cred:claim", "@type": "@id"}, + "credential": {"@id": "cred:credential", "@type": "@id"}, + "issued": {"@id": "cred:issued", "@type": "xsd:dateTime"}, + "issuer": {"@id": "cred:issuer", "@type": "@id"}, + "recipient": {"@id": "cred:recipient", "@type": "@id"}, + "Credential": "cred:Credential", + "CryptographicKeyCredential": "cred:CryptographicKeyCredential", + + "about": {"@id": "schema:about", "@type": "@id"}, + "address": {"@id": "schema:address", "@type": "@id"}, + "addressCountry": "schema:addressCountry", + "addressLocality": "schema:addressLocality", + "addressRegion": "schema:addressRegion", + "comment": "rdfs:comment", + "created": {"@id": "dc:created", "@type": "xsd:dateTime"}, + "creator": {"@id": "dc:creator", "@type": "@id"}, + "description": "schema:description", + "email": "schema:email", + "familyName": "schema:familyName", + "givenName": "schema:givenName", + "image": {"@id": "schema:image", "@type": "@id"}, + "label": "rdfs:label", + "name": "schema:name", + "postalCode": "schema:postalCode", + "streetAddress": "schema:streetAddress", + "title": "dc:title", + "url": {"@id": "schema:url", "@type": "@id"}, + "Person": "schema:Person", + "PostalAddress": "schema:PostalAddress", + "Organization": "schema:Organization", + + "identityService": {"@id": "identity:identityService", "@type": "@id"}, + "idp": {"@id": "identity:idp", "@type": "@id"}, + "Identity": "identity:Identity", + + "paymentProcessor": "ps:processor", + "preferences": {"@id": "ps:preferences", "@type": "@vocab"}, + + "cipherAlgorithm": "sec:cipherAlgorithm", + "cipherData": "sec:cipherData", + "cipherKey": "sec:cipherKey", + "digestAlgorithm": "sec:digestAlgorithm", + "digestValue": "sec:digestValue", + "domain": "sec:domain", + "expires": {"@id": "sec:expiration", "@type": "xsd:dateTime"}, + "initializationVector": "sec:initializationVector", + "member": {"@id": "schema:member", "@type": "@id"}, + "memberOf": {"@id": "schema:memberOf", "@type": "@id"}, + "nonce": "sec:nonce", + "normalizationAlgorithm": "sec:normalizationAlgorithm", + "owner": {"@id": "sec:owner", "@type": "@id"}, + "password": "sec:password", + "privateKey": {"@id": "sec:privateKey", "@type": "@id"}, + "privateKeyPem": "sec:privateKeyPem", + "publicKey": {"@id": "sec:publicKey", "@type": "@id"}, + "publicKeyPem": "sec:publicKeyPem", + "publicKeyService": {"@id": "sec:publicKeyService", "@type": "@id"}, + "revoked": {"@id": "sec:revoked", "@type": "xsd:dateTime"}, + "signature": "sec:signature", + "signatureAlgorithm": "sec:signatureAlgorithm", + "signatureValue": "sec:signatureValue", + "CryptographicKey": "sec:Key", + "EncryptedMessage": "sec:EncryptedMessage", + "GraphSignature2012": "sec:GraphSignature2012", + "LinkedDataSignature2015": "sec:LinkedDataSignature2015", + + "accessControl": {"@id": "perm:accessControl", "@type": "@id"}, + "writePermission": {"@id": "perm:writePermission", "@type": "@id"} + } +}; + +const security_v1 = { + "@context": { + "id": "@id", + "type": "@type", + + "dc": "http://purl.org/dc/terms/", + "sec": "https://w3id.org/security#", + "xsd": "http://www.w3.org/2001/XMLSchema#", + + "EcdsaKoblitzSignature2016": "sec:EcdsaKoblitzSignature2016", + "Ed25519Signature2018": "sec:Ed25519Signature2018", + "EncryptedMessage": "sec:EncryptedMessage", + "GraphSignature2012": "sec:GraphSignature2012", + "LinkedDataSignature2015": "sec:LinkedDataSignature2015", + "LinkedDataSignature2016": "sec:LinkedDataSignature2016", + "CryptographicKey": "sec:Key", + + "authenticationTag": "sec:authenticationTag", + "canonicalizationAlgorithm": "sec:canonicalizationAlgorithm", + "cipherAlgorithm": "sec:cipherAlgorithm", + "cipherData": "sec:cipherData", + "cipherKey": "sec:cipherKey", + "created": {"@id": "dc:created", "@type": "xsd:dateTime"}, + "creator": {"@id": "dc:creator", "@type": "@id"}, + "digestAlgorithm": "sec:digestAlgorithm", + "digestValue": "sec:digestValue", + "domain": "sec:domain", + "encryptionKey": "sec:encryptionKey", + "expiration": {"@id": "sec:expiration", "@type": "xsd:dateTime"}, + "expires": {"@id": "sec:expiration", "@type": "xsd:dateTime"}, + "initializationVector": "sec:initializationVector", + "iterationCount": "sec:iterationCount", + "nonce": "sec:nonce", + "normalizationAlgorithm": "sec:normalizationAlgorithm", + "owner": {"@id": "sec:owner", "@type": "@id"}, + "password": "sec:password", + "privateKey": {"@id": "sec:privateKey", "@type": "@id"}, + "privateKeyPem": "sec:privateKeyPem", + "publicKey": {"@id": "sec:publicKey", "@type": "@id"}, + "publicKeyBase58": "sec:publicKeyBase58", + "publicKeyPem": "sec:publicKeyPem", + "publicKeyWif": "sec:publicKeyWif", + "publicKeyService": {"@id": "sec:publicKeyService", "@type": "@id"}, + "revoked": {"@id": "sec:revoked", "@type": "xsd:dateTime"}, + "salt": "sec:salt", + "signature": "sec:signature", + "signatureAlgorithm": "sec:signingAlgorithm", + "signatureValue": "sec:signatureValue" + } +}; + +const activitystreams = { + "@context": { + "@vocab": "_:", + "xsd": "http://www.w3.org/2001/XMLSchema#", + "as": "https://www.w3.org/ns/activitystreams#", + "ldp": "http://www.w3.org/ns/ldp#", + "vcard": "http://www.w3.org/2006/vcard/ns#", + "id": "@id", + "type": "@type", + "Accept": "as:Accept", + "Activity": "as:Activity", + "IntransitiveActivity": "as:IntransitiveActivity", + "Add": "as:Add", + "Announce": "as:Announce", + "Application": "as:Application", + "Arrive": "as:Arrive", + "Article": "as:Article", + "Audio": "as:Audio", + "Block": "as:Block", + "Collection": "as:Collection", + "CollectionPage": "as:CollectionPage", + "Relationship": "as:Relationship", + "Create": "as:Create", + "Delete": "as:Delete", + "Dislike": "as:Dislike", + "Document": "as:Document", + "Event": "as:Event", + "Follow": "as:Follow", + "Flag": "as:Flag", + "Group": "as:Group", + "Ignore": "as:Ignore", + "Image": "as:Image", + "Invite": "as:Invite", + "Join": "as:Join", + "Leave": "as:Leave", + "Like": "as:Like", + "Link": "as:Link", + "Mention": "as:Mention", + "Note": "as:Note", + "Object": "as:Object", + "Offer": "as:Offer", + "OrderedCollection": "as:OrderedCollection", + "OrderedCollectionPage": "as:OrderedCollectionPage", + "Organization": "as:Organization", + "Page": "as:Page", + "Person": "as:Person", + "Place": "as:Place", + "Profile": "as:Profile", + "Question": "as:Question", + "Reject": "as:Reject", + "Remove": "as:Remove", + "Service": "as:Service", + "TentativeAccept": "as:TentativeAccept", + "TentativeReject": "as:TentativeReject", + "Tombstone": "as:Tombstone", + "Undo": "as:Undo", + "Update": "as:Update", + "Video": "as:Video", + "View": "as:View", + "Listen": "as:Listen", + "Read": "as:Read", + "Move": "as:Move", + "Travel": "as:Travel", + "IsFollowing": "as:IsFollowing", + "IsFollowedBy": "as:IsFollowedBy", + "IsContact": "as:IsContact", + "IsMember": "as:IsMember", + "subject": { + "@id": "as:subject", + "@type": "@id" + }, + "relationship": { + "@id": "as:relationship", + "@type": "@id" + }, + "actor": { + "@id": "as:actor", + "@type": "@id" + }, + "attributedTo": { + "@id": "as:attributedTo", + "@type": "@id" + }, + "attachment": { + "@id": "as:attachment", + "@type": "@id" + }, + "bcc": { + "@id": "as:bcc", + "@type": "@id" + }, + "bto": { + "@id": "as:bto", + "@type": "@id" + }, + "cc": { + "@id": "as:cc", + "@type": "@id" + }, + "context": { + "@id": "as:context", + "@type": "@id" + }, + "current": { + "@id": "as:current", + "@type": "@id" + }, + "first": { + "@id": "as:first", + "@type": "@id" + }, + "generator": { + "@id": "as:generator", + "@type": "@id" + }, + "icon": { + "@id": "as:icon", + "@type": "@id" + }, + "image": { + "@id": "as:image", + "@type": "@id" + }, + "inReplyTo": { + "@id": "as:inReplyTo", + "@type": "@id" + }, + "items": { + "@id": "as:items", + "@type": "@id" + }, + "instrument": { + "@id": "as:instrument", + "@type": "@id" + }, + "orderedItems": { + "@id": "as:items", + "@type": "@id", + "@container": "@list" + }, + "last": { + "@id": "as:last", + "@type": "@id" + }, + "location": { + "@id": "as:location", + "@type": "@id" + }, + "next": { + "@id": "as:next", + "@type": "@id" + }, + "object": { + "@id": "as:object", + "@type": "@id" + }, + "oneOf": { + "@id": "as:oneOf", + "@type": "@id" + }, + "anyOf": { + "@id": "as:anyOf", + "@type": "@id" + }, + "closed": { + "@id": "as:closed", + "@type": "xsd:dateTime" + }, + "origin": { + "@id": "as:origin", + "@type": "@id" + }, + "accuracy": { + "@id": "as:accuracy", + "@type": "xsd:float" + }, + "prev": { + "@id": "as:prev", + "@type": "@id" + }, + "preview": { + "@id": "as:preview", + "@type": "@id" + }, + "replies": { + "@id": "as:replies", + "@type": "@id" + }, + "result": { + "@id": "as:result", + "@type": "@id" + }, + "audience": { + "@id": "as:audience", + "@type": "@id" + }, + "partOf": { + "@id": "as:partOf", + "@type": "@id" + }, + "tag": { + "@id": "as:tag", + "@type": "@id" + }, + "target": { + "@id": "as:target", + "@type": "@id" + }, + "to": { + "@id": "as:to", + "@type": "@id" + }, + "url": { + "@id": "as:url", + "@type": "@id" + }, + "altitude": { + "@id": "as:altitude", + "@type": "xsd:float" + }, + "content": "as:content", + "contentMap": { + "@id": "as:content", + "@container": "@language" + }, + "name": "as:name", + "nameMap": { + "@id": "as:name", + "@container": "@language" + }, + "duration": { + "@id": "as:duration", + "@type": "xsd:duration" + }, + "endTime": { + "@id": "as:endTime", + "@type": "xsd:dateTime" + }, + "height": { + "@id": "as:height", + "@type": "xsd:nonNegativeInteger" + }, + "href": { + "@id": "as:href", + "@type": "@id" + }, + "hreflang": "as:hreflang", + "latitude": { + "@id": "as:latitude", + "@type": "xsd:float" + }, + "longitude": { + "@id": "as:longitude", + "@type": "xsd:float" + }, + "mediaType": "as:mediaType", + "published": { + "@id": "as:published", + "@type": "xsd:dateTime" + }, + "radius": { + "@id": "as:radius", + "@type": "xsd:float" + }, + "rel": "as:rel", + "startIndex": { + "@id": "as:startIndex", + "@type": "xsd:nonNegativeInteger" + }, + "startTime": { + "@id": "as:startTime", + "@type": "xsd:dateTime" + }, + "summary": "as:summary", + "summaryMap": { + "@id": "as:summary", + "@container": "@language" + }, + "totalItems": { + "@id": "as:totalItems", + "@type": "xsd:nonNegativeInteger" + }, + "units": "as:units", + "updated": { + "@id": "as:updated", + "@type": "xsd:dateTime" + }, + "width": { + "@id": "as:width", + "@type": "xsd:nonNegativeInteger" + }, + "describes": { + "@id": "as:describes", + "@type": "@id" + }, + "formerType": { + "@id": "as:formerType", + "@type": "@id" + }, + "deleted": { + "@id": "as:deleted", + "@type": "xsd:dateTime" + }, + "inbox": { + "@id": "ldp:inbox", + "@type": "@id" + }, + "outbox": { + "@id": "as:outbox", + "@type": "@id" + }, + "following": { + "@id": "as:following", + "@type": "@id" + }, + "followers": { + "@id": "as:followers", + "@type": "@id" + }, + "streams": { + "@id": "as:streams", + "@type": "@id" + }, + "preferredUsername": "as:preferredUsername", + "endpoints": { + "@id": "as:endpoints", + "@type": "@id" + }, + "uploadMedia": { + "@id": "as:uploadMedia", + "@type": "@id" + }, + "proxyUrl": { + "@id": "as:proxyUrl", + "@type": "@id" + }, + "liked": { + "@id": "as:liked", + "@type": "@id" + }, + "oauthAuthorizationEndpoint": { + "@id": "as:oauthAuthorizationEndpoint", + "@type": "@id" + }, + "oauthTokenEndpoint": { + "@id": "as:oauthTokenEndpoint", + "@type": "@id" + }, + "provideClientKey": { + "@id": "as:provideClientKey", + "@type": "@id" + }, + "signClientKey": { + "@id": "as:signClientKey", + "@type": "@id" + }, + "sharedInbox": { + "@id": "as:sharedInbox", + "@type": "@id" + }, + "Public": { + "@id": "as:Public", + "@type": "@id" + }, + "source": "as:source", + "likes": { + "@id": "as:likes", + "@type": "@id" + }, + "shares": { + "@id": "as:shares", + "@type": "@id" + }, + "alsoKnownAs": { + "@id": "as:alsoKnownAs", + "@type": "@id" + } + } +}; + +export const CONTEXTS: Record = { + "https://w3id.org/identity/v1": id_v1, + "https://w3id.org/security/v1": security_v1, + "https://www.w3.org/ns/activitystreams": activitystreams, +}; diff --git a/src/remote/activitypub/misc/get-note-html.ts b/packages/backend/src/remote/activitypub/misc/get-note-html.ts similarity index 100% rename from src/remote/activitypub/misc/get-note-html.ts rename to packages/backend/src/remote/activitypub/misc/get-note-html.ts diff --git a/src/remote/activitypub/misc/html-to-mfm.ts b/packages/backend/src/remote/activitypub/misc/html-to-mfm.ts similarity index 100% rename from src/remote/activitypub/misc/html-to-mfm.ts rename to packages/backend/src/remote/activitypub/misc/html-to-mfm.ts diff --git a/src/remote/activitypub/misc/ld-signature.ts b/packages/backend/src/remote/activitypub/misc/ld-signature.ts similarity index 100% rename from src/remote/activitypub/misc/ld-signature.ts rename to packages/backend/src/remote/activitypub/misc/ld-signature.ts diff --git a/src/remote/activitypub/models/icon.ts b/packages/backend/src/remote/activitypub/models/icon.ts similarity index 100% rename from src/remote/activitypub/models/icon.ts rename to packages/backend/src/remote/activitypub/models/icon.ts diff --git a/src/remote/activitypub/models/identifier.ts b/packages/backend/src/remote/activitypub/models/identifier.ts similarity index 100% rename from src/remote/activitypub/models/identifier.ts rename to packages/backend/src/remote/activitypub/models/identifier.ts diff --git a/src/remote/activitypub/models/image.ts b/packages/backend/src/remote/activitypub/models/image.ts similarity index 100% rename from src/remote/activitypub/models/image.ts rename to packages/backend/src/remote/activitypub/models/image.ts diff --git a/src/remote/activitypub/models/mention.ts b/packages/backend/src/remote/activitypub/models/mention.ts similarity index 100% rename from src/remote/activitypub/models/mention.ts rename to packages/backend/src/remote/activitypub/models/mention.ts diff --git a/packages/backend/src/remote/activitypub/models/note.ts b/packages/backend/src/remote/activitypub/models/note.ts new file mode 100644 index 000000000..39efadc65 --- /dev/null +++ b/packages/backend/src/remote/activitypub/models/note.ts @@ -0,0 +1,355 @@ +import * as promiseLimit from 'promise-limit'; + +import config from '@/config/index'; +import Resolver from '../resolver'; +import post from '@/services/note/create'; +import { resolvePerson, updatePerson } from './person'; +import { resolveImage } from './image'; +import { IRemoteUser } from '@/models/entities/user'; +import { htmlToMfm } from '../misc/html-to-mfm'; +import { extractApHashtags } from './tag'; +import { unique, toArray, toSingle } from '@/prelude/array'; +import { extractPollFromQuestion } from './question'; +import vote from '@/services/note/polls/vote'; +import { apLogger } from '../logger'; +import { DriveFile } from '@/models/entities/drive-file'; +import { deliverQuestionUpdate } from '@/services/note/polls/update'; +import { extractDbHost, toPuny } from '@/misc/convert-host'; +import { Emojis, Polls, MessagingMessages } from '@/models/index'; +import { Note } from '@/models/entities/note'; +import { IObject, getOneApId, getApId, getOneApHrefNullable, validPost, IPost, isEmoji, getApType } from '../type'; +import { Emoji } from '@/models/entities/emoji'; +import { genId } from '@/misc/gen-id'; +import { fetchMeta } from '@/misc/fetch-meta'; +import { getApLock } from '@/misc/app-lock'; +import { createMessage } from '@/services/messages/create'; +import { parseAudience } from '../audience'; +import { extractApMentions } from './mention'; +import DbResolver from '../db-resolver'; +import { StatusError } from '@/misc/fetch'; + +const logger = apLogger; + +export function validateNote(object: any, uri: string) { + const expectHost = extractDbHost(uri); + + if (object == null) { + return new Error('invalid Note: object is null'); + } + + if (!validPost.includes(getApType(object))) { + return new Error(`invalid Note: invalid object type ${getApType(object)}`); + } + + if (object.id && extractDbHost(object.id) !== expectHost) { + return new Error(`invalid Note: id has different host. expected: ${expectHost}, actual: ${extractDbHost(object.id)}`); + } + + if (object.attributedTo && extractDbHost(getOneApId(object.attributedTo)) !== expectHost) { + return new Error(`invalid Note: attributedTo has different host. expected: ${expectHost}, actual: ${extractDbHost(object.attributedTo)}`); + } + + return null; +} + +/** + * Noteをフェッチします。 + * + * Misskeyに対象のNoteが登録されていればそれを返します。 + */ +export async function fetchNote(object: string | IObject): Promise { + const dbResolver = new DbResolver(); + return await dbResolver.getNoteFromApId(object); +} + +/** + * Noteを作成します。 + */ +export async function createNote(value: string | IObject, resolver?: Resolver, silent = false): Promise { + if (resolver == null) resolver = new Resolver(); + + const object: any = await resolver.resolve(value); + + const entryUri = getApId(value); + const err = validateNote(object, entryUri); + if (err) { + logger.error(`${err.message}`, { + resolver: { + history: resolver.getHistory() + }, + value: value, + object: object + }); + throw new Error('invalid note'); + } + + const note: IPost = object; + + logger.debug(`Note fetched: ${JSON.stringify(note, null, 2)}`); + + logger.info(`Creating the Note: ${note.id}`); + + // 投稿者をフェッチ + const actor = await resolvePerson(getOneApId(note.attributedTo), resolver) as IRemoteUser; + + // 投稿者が凍結されていたらスキップ + if (actor.isSuspended) { + throw new Error('actor has been suspended'); + } + + const noteAudience = await parseAudience(actor, note.to, note.cc); + let visibility = noteAudience.visibility; + const visibleUsers = noteAudience.visibleUsers; + + // Audience (to, cc) が指定されてなかった場合 + if (visibility === 'specified' && visibleUsers.length === 0) { + if (typeof value === 'string') { // 入力がstringならばresolverでGETが発生している + // こちらから匿名GET出来たものならばpublic + visibility = 'public'; + } + } + + let isTalk = note._misskey_talk && visibility === 'specified'; + + const apMentions = await extractApMentions(note.tag); + const apHashtags = await extractApHashtags(note.tag); + + // 添付ファイル + // TODO: attachmentは必ずしもImageではない + // TODO: attachmentは必ずしも配列ではない + // Noteがsensitiveなら添付もsensitiveにする + const limit = promiseLimit(2); + + note.attachment = Array.isArray(note.attachment) ? note.attachment : note.attachment ? [note.attachment] : []; + const files = note.attachment + .map(attach => attach.sensitive = note.sensitive) + ? (await Promise.all(note.attachment.map(x => limit(() => resolveImage(actor, x)) as Promise))) + .filter(image => image != null) + : []; + + // リプライ + const reply: Note | null = note.inReplyTo + ? await resolveNote(note.inReplyTo, resolver).then(x => { + if (x == null) { + logger.warn(`Specified inReplyTo, but nout found`); + throw new Error('inReplyTo not found'); + } else { + return x; + } + }).catch(async e => { + // トークだったらinReplyToのエラーは無視 + const uri = getApId(note.inReplyTo); + if (uri.startsWith(config.url + '/')) { + const id = uri.split('/').pop(); + const talk = await MessagingMessages.findOne(id); + if (talk) { + isTalk = true; + return null; + } + } + + logger.warn(`Error in inReplyTo ${note.inReplyTo} - ${e.statusCode || e}`); + throw e; + }) + : null; + + // 引用 + let quote: Note | undefined | null; + + if (note._misskey_quote || note.quoteUrl) { + const tryResolveNote = async (uri: string): Promise<{ + status: 'ok'; + res: Note | null; + } | { + status: 'permerror' | 'temperror'; + }> => { + if (typeof uri !== 'string' || !uri.match(/^https?:/)) return { status: 'permerror' }; + try { + const res = await resolveNote(uri); + if (res) { + return { + status: 'ok', + res + }; + } else { + return { + status: 'permerror' + }; + } + } catch (e) { + return { + status: (e instanceof StatusError && e.isClientError) ? 'permerror' : 'temperror' + }; + } + }; + + const uris = unique([note._misskey_quote, note.quoteUrl].filter((x): x is string => typeof x === 'string')); + const results = await Promise.all(uris.map(uri => tryResolveNote(uri))); + + quote = results.filter((x): x is { status: 'ok', res: Note | null } => x.status === 'ok').map(x => x.res).find(x => x); + if (!quote) { + if (results.some(x => x.status === 'temperror')) { + throw 'quote resolve failed'; + } + } + } + + const cw = note.summary === '' ? null : note.summary; + + // テキストのパース + const text = note._misskey_content || (note.content ? htmlToMfm(note.content, note.tag) : null); + + // vote + if (reply && reply.hasPoll) { + const poll = await Polls.findOneOrFail(reply.id); + + const tryCreateVote = async (name: string, index: number): Promise => { + if (poll.expiresAt && Date.now() > new Date(poll.expiresAt).getTime()) { + logger.warn(`vote to expired poll from AP: actor=${actor.username}@${actor.host}, note=${note.id}, choice=${name}`); + } else if (index >= 0) { + logger.info(`vote from AP: actor=${actor.username}@${actor.host}, note=${note.id}, choice=${name}`); + await vote(actor, reply, index); + + // リモートフォロワーにUpdate配信 + deliverQuestionUpdate(reply.id); + } + return null; + }; + + if (note.name) { + return await tryCreateVote(note.name, poll.choices.findIndex(x => x === note.name)); + } + } + + const emojis = await extractEmojis(note.tag || [], actor.host).catch(e => { + logger.info(`extractEmojis: ${e}`); + return [] as Emoji[]; + }); + + const apEmojis = emojis.map(emoji => emoji.name); + + const poll = await extractPollFromQuestion(note, resolver).catch(() => undefined); + + // ユーザーの情報が古かったらついでに更新しておく + if (actor.lastFetchedAt == null || Date.now() - actor.lastFetchedAt.getTime() > 1000 * 60 * 60 * 24) { + if (actor.uri) updatePerson(actor.uri); + } + + if (isTalk) { + for (const recipient of visibleUsers) { + await createMessage(actor, recipient, undefined, text || undefined, (files && files.length > 0) ? files[0] : null, object.id); + return null; + } + } + + return await post(actor, { + createdAt: note.published ? new Date(note.published) : null, + files, + reply, + renote: quote, + name: note.name, + cw, + text, + localOnly: false, + visibility, + visibleUsers, + apMentions, + apHashtags, + apEmojis, + poll, + uri: note.id, + url: getOneApHrefNullable(note.url), + }, silent); +} + +/** + * Noteを解決します。 + * + * Misskeyに対象のNoteが登録されていればそれを返し、そうでなければ + * リモートサーバーからフェッチしてMisskeyに登録しそれを返します。 + */ +export async function resolveNote(value: string | IObject, resolver?: Resolver): Promise { + const uri = typeof value === 'string' ? value : value.id; + if (uri == null) throw new Error('missing uri'); + + // ブロックしてたら中断 + const meta = await fetchMeta(); + if (meta.blockedHosts.includes(extractDbHost(uri))) throw { statusCode: 451 }; + + const unlock = await getApLock(uri); + + try { + //#region このサーバーに既に登録されていたらそれを返す + const exist = await fetchNote(uri); + + if (exist) { + return exist; + } + //#endregion + + if (uri.startsWith(config.url)) { + throw new StatusError('cannot resolve local note', 400, 'cannot resolve local note'); + } + + // リモートサーバーからフェッチしてきて登録 + // ここでuriの代わりに添付されてきたNote Objectが指定されていると、サーバーフェッチを経ずにノートが生成されるが + // 添付されてきたNote Objectは偽装されている可能性があるため、常にuriを指定してサーバーフェッチを行う。 + return await createNote(uri, resolver, true); + } finally { + unlock(); + } +} + +export async function extractEmojis(tags: IObject | IObject[], host: string): Promise { + host = toPuny(host); + + if (!tags) return []; + + const eomjiTags = toArray(tags).filter(isEmoji); + + return await Promise.all(eomjiTags.map(async tag => { + const name = tag.name!.replace(/^:/, '').replace(/:$/, ''); + tag.icon = toSingle(tag.icon); + + const exists = await Emojis.findOne({ + host, + name + }); + + if (exists) { + if ((tag.updated != null && exists.updatedAt == null) + || (tag.id != null && exists.uri == null) + || (tag.updated != null && exists.updatedAt != null && new Date(tag.updated) > exists.updatedAt) + || (tag.icon!.url !== exists.url) + ) { + await Emojis.update({ + host, + name, + }, { + uri: tag.id, + url: tag.icon!.url, + updatedAt: new Date(), + }); + + return await Emojis.findOne({ + host, + name + }) as Emoji; + } + + return exists; + } + + logger.info(`register emoji host=${host}, name=${name}`); + + return await Emojis.save({ + id: genId(), + host, + name, + uri: tag.id, + url: tag.icon!.url, + updatedAt: new Date(), + aliases: [] + } as Partial); + })); +} diff --git a/packages/backend/src/remote/activitypub/models/person.ts b/packages/backend/src/remote/activitypub/models/person.ts new file mode 100644 index 000000000..95db46bff --- /dev/null +++ b/packages/backend/src/remote/activitypub/models/person.ts @@ -0,0 +1,494 @@ +import { URL } from 'url'; +import * as promiseLimit from 'promise-limit'; + +import $, { Context } from 'cafy'; +import config from '@/config/index'; +import Resolver from '../resolver'; +import { resolveImage } from './image'; +import { isCollectionOrOrderedCollection, isCollection, IActor, getApId, getOneApHrefNullable, IObject, isPropertyValue, IApPropertyValue, getApType, isActor } from '../type'; +import { fromHtml } from '../../../mfm/from-html'; +import { htmlToMfm } from '../misc/html-to-mfm'; +import { resolveNote, extractEmojis } from './note'; +import { registerOrFetchInstanceDoc } from '@/services/register-or-fetch-instance-doc'; +import { extractApHashtags } from './tag'; +import { apLogger } from '../logger'; +import { Note } from '@/models/entities/note'; +import { updateUsertags } from '@/services/update-hashtag'; +import { Users, Instances, DriveFiles, Followings, UserProfiles, UserPublickeys } from '@/models/index'; +import { User, IRemoteUser } from '@/models/entities/user'; +import { Emoji } from '@/models/entities/emoji'; +import { UserNotePining } from '@/models/entities/user-note-pining'; +import { genId } from '@/misc/gen-id'; +import { instanceChart, usersChart } from '@/services/chart/index'; +import { UserPublickey } from '@/models/entities/user-publickey'; +import { isDuplicateKeyValueError } from '@/misc/is-duplicate-key-value-error'; +import { toPuny } from '@/misc/convert-host'; +import { UserProfile } from '@/models/entities/user-profile'; +import { getConnection } from 'typeorm'; +import { toArray } from '@/prelude/array'; +import { fetchInstanceMetadata } from '@/services/fetch-instance-metadata'; +import { normalizeForSearch } from '@/misc/normalize-for-search'; +import { truncate } from '@/misc/truncate'; +import { StatusError } from '@/misc/fetch'; + +const logger = apLogger; + +const nameLength = 128; +const summaryLength = 2048; + +/** + * Validate and convert to actor object + * @param x Fetched object + * @param uri Fetch target URI + */ +function validateActor(x: IObject, uri: string): IActor { + const expectHost = toPuny(new URL(uri).hostname); + + if (x == null) { + throw new Error('invalid Actor: object is null'); + } + + if (!isActor(x)) { + throw new Error(`invalid Actor type '${x.type}'`); + } + + const validate = (name: string, value: any, validater: Context) => { + const e = validater.test(value); + if (e) throw new Error(`invalid Actor: ${name} ${e.message}`); + }; + + validate('id', x.id, $.str.min(1)); + validate('inbox', x.inbox, $.str.min(1)); + validate('preferredUsername', x.preferredUsername, $.str.min(1).max(128).match(/^\w([\w-.]*\w)?$/)); + + // These fields are only informational, and some AP software allows these + // fields to be very long. If they are too long, we cut them off. This way + // we can at least see these users and their activities. + validate('name', truncate(x.name, nameLength), $.optional.nullable.str); + validate('summary', truncate(x.summary, summaryLength), $.optional.nullable.str); + + const idHost = toPuny(new URL(x.id!).hostname); + if (idHost !== expectHost) { + throw new Error('invalid Actor: id has different host'); + } + + if (x.publicKey) { + if (typeof x.publicKey.id !== 'string') { + throw new Error('invalid Actor: publicKey.id is not a string'); + } + + const publicKeyIdHost = toPuny(new URL(x.publicKey.id).hostname); + if (publicKeyIdHost !== expectHost) { + throw new Error('invalid Actor: publicKey.id has different host'); + } + } + + return x; +} + +/** + * Personをフェッチします。 + * + * Misskeyに対象のPersonが登録されていればそれを返します。 + */ +export async function fetchPerson(uri: string, resolver?: Resolver): Promise { + if (typeof uri !== 'string') throw new Error('uri is not string'); + + // URIがこのサーバーを指しているならデータベースからフェッチ + if (uri.startsWith(config.url + '/')) { + const id = uri.split('/').pop(); + return await Users.findOne(id).then(x => x || null); + } + + //#region このサーバーに既に登録されていたらそれを返す + const exist = await Users.findOne({ uri }); + + if (exist) { + return exist; + } + //#endregion + + return null; +} + +/** + * Personを作成します。 + */ +export async function createPerson(uri: string, resolver?: Resolver): Promise { + if (typeof uri !== 'string') throw new Error('uri is not string'); + + if (uri.startsWith(config.url)) { + throw new StatusError('cannot resolve local user', 400, 'cannot resolve local user'); + } + + if (resolver == null) resolver = new Resolver(); + + const object = await resolver.resolve(uri) as any; + + const person = validateActor(object, uri); + + logger.info(`Creating the Person: ${person.id}`); + + const host = toPuny(new URL(object.id).hostname); + + const { fields } = analyzeAttachments(person.attachment || []); + + const tags = extractApHashtags(person.tag).map(tag => normalizeForSearch(tag)).splice(0, 32); + + const isBot = getApType(object) === 'Service'; + + const bday = person['vcard:bday']?.match(/^\d{4}-\d{2}-\d{2}/); + + // Create user + let user: IRemoteUser; + try { + // Start transaction + await getConnection().transaction(async transactionalEntityManager => { + user = await transactionalEntityManager.save(new User({ + id: genId(), + avatarId: null, + bannerId: null, + createdAt: new Date(), + lastFetchedAt: new Date(), + name: truncate(person.name, nameLength), + isLocked: !!person.manuallyApprovesFollowers, + isExplorable: !!person.discoverable, + username: person.preferredUsername, + usernameLower: person.preferredUsername!.toLowerCase(), + host, + inbox: person.inbox, + sharedInbox: person.sharedInbox || (person.endpoints ? person.endpoints.sharedInbox : undefined), + followersUri: person.followers ? getApId(person.followers) : undefined, + featured: person.featured ? getApId(person.featured) : undefined, + uri: person.id, + tags, + isBot, + isCat: (person as any).isCat === true + })) as IRemoteUser; + + await transactionalEntityManager.save(new UserProfile({ + userId: user.id, + description: person.summary ? htmlToMfm(truncate(person.summary, summaryLength), person.tag) : null, + url: getOneApHrefNullable(person.url), + fields, + birthday: bday ? bday[0] : null, + location: person['vcard:Address'] || null, + userHost: host + })); + + if (person.publicKey) { + await transactionalEntityManager.save(new UserPublickey({ + userId: user.id, + keyId: person.publicKey.id, + keyPem: person.publicKey.publicKeyPem + })); + } + }); + } catch (e) { + // duplicate key error + if (isDuplicateKeyValueError(e)) { + // /users/@a => /users/:id のように入力がaliasなときにエラーになることがあるのを対応 + const u = await Users.findOne({ + uri: person.id + }); + + if (u) { + user = u as IRemoteUser; + } else { + throw new Error('already registered'); + } + } else { + logger.error(e); + throw e; + } + } + + // Register host + registerOrFetchInstanceDoc(host).then(i => { + Instances.increment({ id: i.id }, 'usersCount', 1); + instanceChart.newUser(i.host); + fetchInstanceMetadata(i); + }); + + usersChart.update(user!, true); + + // ハッシュタグ更新 + updateUsertags(user!, tags); + + //#region アバターとヘッダー画像をフェッチ + const [avatar, banner] = await Promise.all([ + person.icon, + person.image + ].map(img => + img == null + ? Promise.resolve(null) + : resolveImage(user!, img).catch(() => null) + )); + + const avatarId = avatar ? avatar.id : null; + const bannerId = banner ? banner.id : null; + const avatarUrl = avatar ? DriveFiles.getPublicUrl(avatar, true) : null; + const bannerUrl = banner ? DriveFiles.getPublicUrl(banner) : null; + const avatarBlurhash = avatar ? avatar.blurhash : null; + const bannerBlurhash = banner ? banner.blurhash : null; + + await Users.update(user!.id, { + avatarId, + bannerId, + avatarUrl, + bannerUrl, + avatarBlurhash, + bannerBlurhash + }); + + user!.avatarId = avatarId; + user!.bannerId = bannerId; + user!.avatarUrl = avatarUrl; + user!.bannerUrl = bannerUrl; + user!.avatarBlurhash = avatarBlurhash; + user!.bannerBlurhash = bannerBlurhash; + //#endregion + + //#region カスタム絵文字取得 + const emojis = await extractEmojis(person.tag || [], host).catch(e => { + logger.info(`extractEmojis: ${e}`); + return [] as Emoji[]; + }); + + const emojiNames = emojis.map(emoji => emoji.name); + + await Users.update(user!.id, { + emojis: emojiNames + }); + //#endregion + + await updateFeatured(user!.id).catch(err => logger.error(err)); + + return user!; +} + +/** + * Personの情報を更新します。 + * Misskeyに対象のPersonが登録されていなければ無視します。 + * @param uri URI of Person + * @param resolver Resolver + * @param hint Hint of Person object (この値が正当なPersonの場合、Remote resolveをせずに更新に利用します) + */ +export async function updatePerson(uri: string, resolver?: Resolver | null, hint?: Record): Promise { + if (typeof uri !== 'string') throw new Error('uri is not string'); + + // URIがこのサーバーを指しているならスキップ + if (uri.startsWith(config.url + '/')) { + return; + } + + //#region このサーバーに既に登録されているか + const exist = await Users.findOne({ uri }) as IRemoteUser; + + if (exist == null) { + return; + } + //#endregion + + if (resolver == null) resolver = new Resolver(); + + const object = hint || await resolver.resolve(uri) as any; + + const person = validateActor(object, uri); + + logger.info(`Updating the Person: ${person.id}`); + + // アバターとヘッダー画像をフェッチ + const [avatar, banner] = await Promise.all([ + person.icon, + person.image + ].map(img => + img == null + ? Promise.resolve(null) + : resolveImage(exist, img).catch(() => null) + )); + + // カスタム絵文字取得 + const emojis = await extractEmojis(person.tag || [], exist.host).catch(e => { + logger.info(`extractEmojis: ${e}`); + return [] as Emoji[]; + }); + + const emojiNames = emojis.map(emoji => emoji.name); + + const { fields } = analyzeAttachments(person.attachment || []); + + const tags = extractApHashtags(person.tag).map(tag => normalizeForSearch(tag)).splice(0, 32); + + const bday = person['vcard:bday']?.match(/^\d{4}-\d{2}-\d{2}/); + + const updates = { + lastFetchedAt: new Date(), + inbox: person.inbox, + sharedInbox: person.sharedInbox || (person.endpoints ? person.endpoints.sharedInbox : undefined), + followersUri: person.followers ? getApId(person.followers) : undefined, + featured: person.featured, + emojis: emojiNames, + name: truncate(person.name, nameLength), + tags, + isBot: getApType(object) === 'Service', + isCat: (person as any).isCat === true, + isLocked: !!person.manuallyApprovesFollowers, + isExplorable: !!person.discoverable, + } as Partial; + + if (avatar) { + updates.avatarId = avatar.id; + updates.avatarUrl = DriveFiles.getPublicUrl(avatar, true); + updates.avatarBlurhash = avatar.blurhash; + } + + if (banner) { + updates.bannerId = banner.id; + updates.bannerUrl = DriveFiles.getPublicUrl(banner); + updates.bannerBlurhash = banner.blurhash; + } + + // Update user + await Users.update(exist.id, updates); + + if (person.publicKey) { + await UserPublickeys.update({ userId: exist.id }, { + keyId: person.publicKey.id, + keyPem: person.publicKey.publicKeyPem + }); + } + + await UserProfiles.update({ userId: exist.id }, { + url: getOneApHrefNullable(person.url), + fields, + description: person.summary ? htmlToMfm(truncate(person.summary, summaryLength), person.tag) : null, + birthday: bday ? bday[0] : null, + location: person['vcard:Address'] || null, + }); + + // ハッシュタグ更新 + updateUsertags(exist, tags); + + // 該当ユーザーが既にフォロワーになっていた場合はFollowingもアップデートする + await Followings.update({ + followerId: exist.id + }, { + followerSharedInbox: person.sharedInbox || (person.endpoints ? person.endpoints.sharedInbox : undefined) + }); + + await updateFeatured(exist.id).catch(err => logger.error(err)); +} + +/** + * Personを解決します。 + * + * Misskeyに対象のPersonが登録されていればそれを返し、そうでなければ + * リモートサーバーからフェッチしてMisskeyに登録しそれを返します。 + */ +export async function resolvePerson(uri: string, resolver?: Resolver): Promise { + if (typeof uri !== 'string') throw new Error('uri is not string'); + + //#region このサーバーに既に登録されていたらそれを返す + const exist = await fetchPerson(uri); + + if (exist) { + return exist; + } + //#endregion + + // リモートサーバーからフェッチしてきて登録 + if (resolver == null) resolver = new Resolver(); + return await createPerson(uri, resolver); +} + +const services: { + [x: string]: (id: string, username: string) => any + } = { + 'misskey:authentication:twitter': (userId, screenName) => ({ userId, screenName }), + 'misskey:authentication:github': (id, login) => ({ id, login }), + 'misskey:authentication:discord': (id, name) => $discord(id, name) +}; + +const $discord = (id: string, name: string) => { + if (typeof name !== 'string') + name = 'unknown#0000'; + const [username, discriminator] = name.split('#'); + return { id, username, discriminator }; +}; + +function addService(target: { [x: string]: any }, source: IApPropertyValue) { + const service = services[source.name]; + + if (typeof source.value !== 'string') + source.value = 'unknown'; + + const [id, username] = source.value.split('@'); + + if (service) + target[source.name.split(':')[2]] = service(id, username); +} + +export function analyzeAttachments(attachments: IObject | IObject[] | undefined) { + const fields: { + name: string, + value: string + }[] = []; + const services: { [x: string]: any } = {}; + + if (Array.isArray(attachments)) { + for (const attachment of attachments.filter(isPropertyValue)) { + if (isPropertyValue(attachment.identifier)) { + addService(services, attachment.identifier); + } else { + fields.push({ + name: attachment.name, + value: fromHtml(attachment.value) + }); + } + } + } + + return { fields, services }; +} + +export async function updateFeatured(userId: User['id']) { + const user = await Users.findOneOrFail(userId); + if (!Users.isRemoteUser(user)) return; + if (!user.featured) return; + + logger.info(`Updating the featured: ${user.uri}`); + + const resolver = new Resolver(); + + // Resolve to (Ordered)Collection Object + const collection = await resolver.resolveCollection(user.featured); + if (!isCollectionOrOrderedCollection(collection)) throw new Error(`Object is not Collection or OrderedCollection`); + + // Resolve to Object(may be Note) arrays + const unresolvedItems = isCollection(collection) ? collection.items : collection.orderedItems; + const items = await Promise.all(toArray(unresolvedItems).map(x => resolver.resolve(x))); + + // Resolve and regist Notes + const limit = promiseLimit(2); + const featuredNotes = await Promise.all(items + .filter(item => getApType(item) === 'Note') // TODO: Noteでなくてもいいかも + .slice(0, 5) + .map(item => limit(() => resolveNote(item, resolver)))); + + await getConnection().transaction(async transactionalEntityManager => { + await transactionalEntityManager.delete(UserNotePining, { userId: user.id }); + + // とりあえずidを別の時間で生成して順番を維持 + let td = 0; + for (const note of featuredNotes.filter(note => note != null)) { + td -= 1000; + transactionalEntityManager.insert(UserNotePining, { + id: genId(new Date(Date.now() + td)), + createdAt: new Date(), + userId: user.id, + noteId: note!.id + }); + } + }); +} diff --git a/src/remote/activitypub/models/question.ts b/packages/backend/src/remote/activitypub/models/question.ts similarity index 100% rename from src/remote/activitypub/models/question.ts rename to packages/backend/src/remote/activitypub/models/question.ts diff --git a/src/remote/activitypub/models/tag.ts b/packages/backend/src/remote/activitypub/models/tag.ts similarity index 100% rename from src/remote/activitypub/models/tag.ts rename to packages/backend/src/remote/activitypub/models/tag.ts diff --git a/src/remote/activitypub/perform.ts b/packages/backend/src/remote/activitypub/perform.ts similarity index 100% rename from src/remote/activitypub/perform.ts rename to packages/backend/src/remote/activitypub/perform.ts diff --git a/src/remote/activitypub/renderer/accept.ts b/packages/backend/src/remote/activitypub/renderer/accept.ts similarity index 100% rename from src/remote/activitypub/renderer/accept.ts rename to packages/backend/src/remote/activitypub/renderer/accept.ts diff --git a/src/remote/activitypub/renderer/add.ts b/packages/backend/src/remote/activitypub/renderer/add.ts similarity index 100% rename from src/remote/activitypub/renderer/add.ts rename to packages/backend/src/remote/activitypub/renderer/add.ts diff --git a/src/remote/activitypub/renderer/announce.ts b/packages/backend/src/remote/activitypub/renderer/announce.ts similarity index 100% rename from src/remote/activitypub/renderer/announce.ts rename to packages/backend/src/remote/activitypub/renderer/announce.ts diff --git a/src/remote/activitypub/renderer/block.ts b/packages/backend/src/remote/activitypub/renderer/block.ts similarity index 100% rename from src/remote/activitypub/renderer/block.ts rename to packages/backend/src/remote/activitypub/renderer/block.ts diff --git a/src/remote/activitypub/renderer/create.ts b/packages/backend/src/remote/activitypub/renderer/create.ts similarity index 100% rename from src/remote/activitypub/renderer/create.ts rename to packages/backend/src/remote/activitypub/renderer/create.ts diff --git a/src/remote/activitypub/renderer/delete.ts b/packages/backend/src/remote/activitypub/renderer/delete.ts similarity index 100% rename from src/remote/activitypub/renderer/delete.ts rename to packages/backend/src/remote/activitypub/renderer/delete.ts diff --git a/src/remote/activitypub/renderer/document.ts b/packages/backend/src/remote/activitypub/renderer/document.ts similarity index 100% rename from src/remote/activitypub/renderer/document.ts rename to packages/backend/src/remote/activitypub/renderer/document.ts diff --git a/src/remote/activitypub/renderer/emoji.ts b/packages/backend/src/remote/activitypub/renderer/emoji.ts similarity index 100% rename from src/remote/activitypub/renderer/emoji.ts rename to packages/backend/src/remote/activitypub/renderer/emoji.ts diff --git a/src/remote/activitypub/renderer/follow-relay.ts b/packages/backend/src/remote/activitypub/renderer/follow-relay.ts similarity index 100% rename from src/remote/activitypub/renderer/follow-relay.ts rename to packages/backend/src/remote/activitypub/renderer/follow-relay.ts diff --git a/src/remote/activitypub/renderer/follow-user.ts b/packages/backend/src/remote/activitypub/renderer/follow-user.ts similarity index 100% rename from src/remote/activitypub/renderer/follow-user.ts rename to packages/backend/src/remote/activitypub/renderer/follow-user.ts diff --git a/src/remote/activitypub/renderer/follow.ts b/packages/backend/src/remote/activitypub/renderer/follow.ts similarity index 100% rename from src/remote/activitypub/renderer/follow.ts rename to packages/backend/src/remote/activitypub/renderer/follow.ts diff --git a/src/remote/activitypub/renderer/hashtag.ts b/packages/backend/src/remote/activitypub/renderer/hashtag.ts similarity index 100% rename from src/remote/activitypub/renderer/hashtag.ts rename to packages/backend/src/remote/activitypub/renderer/hashtag.ts diff --git a/src/remote/activitypub/renderer/image.ts b/packages/backend/src/remote/activitypub/renderer/image.ts similarity index 100% rename from src/remote/activitypub/renderer/image.ts rename to packages/backend/src/remote/activitypub/renderer/image.ts diff --git a/src/remote/activitypub/renderer/index.ts b/packages/backend/src/remote/activitypub/renderer/index.ts similarity index 100% rename from src/remote/activitypub/renderer/index.ts rename to packages/backend/src/remote/activitypub/renderer/index.ts diff --git a/src/remote/activitypub/renderer/key.ts b/packages/backend/src/remote/activitypub/renderer/key.ts similarity index 100% rename from src/remote/activitypub/renderer/key.ts rename to packages/backend/src/remote/activitypub/renderer/key.ts diff --git a/src/remote/activitypub/renderer/like.ts b/packages/backend/src/remote/activitypub/renderer/like.ts similarity index 100% rename from src/remote/activitypub/renderer/like.ts rename to packages/backend/src/remote/activitypub/renderer/like.ts diff --git a/src/remote/activitypub/renderer/mention.ts b/packages/backend/src/remote/activitypub/renderer/mention.ts similarity index 100% rename from src/remote/activitypub/renderer/mention.ts rename to packages/backend/src/remote/activitypub/renderer/mention.ts diff --git a/src/remote/activitypub/renderer/note.ts b/packages/backend/src/remote/activitypub/renderer/note.ts similarity index 100% rename from src/remote/activitypub/renderer/note.ts rename to packages/backend/src/remote/activitypub/renderer/note.ts diff --git a/src/remote/activitypub/renderer/ordered-collection-page.ts b/packages/backend/src/remote/activitypub/renderer/ordered-collection-page.ts similarity index 100% rename from src/remote/activitypub/renderer/ordered-collection-page.ts rename to packages/backend/src/remote/activitypub/renderer/ordered-collection-page.ts diff --git a/packages/backend/src/remote/activitypub/renderer/ordered-collection.ts b/packages/backend/src/remote/activitypub/renderer/ordered-collection.ts new file mode 100644 index 000000000..c4b4337af --- /dev/null +++ b/packages/backend/src/remote/activitypub/renderer/ordered-collection.ts @@ -0,0 +1,21 @@ +/** + * Render OrderedCollection + * @param id URL of self + * @param totalItems Total number of items + * @param first URL of first page (optional) + * @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) { + const page: any = { + id, + type: 'OrderedCollection', + totalItems, + }; + + if (first) page.first = first; + if (last) page.last = last; + if (orderedItems) page.orderedItems = orderedItems; + + return page; +} diff --git a/src/remote/activitypub/renderer/person.ts b/packages/backend/src/remote/activitypub/renderer/person.ts similarity index 100% rename from src/remote/activitypub/renderer/person.ts rename to packages/backend/src/remote/activitypub/renderer/person.ts diff --git a/src/remote/activitypub/renderer/question.ts b/packages/backend/src/remote/activitypub/renderer/question.ts similarity index 100% rename from src/remote/activitypub/renderer/question.ts rename to packages/backend/src/remote/activitypub/renderer/question.ts diff --git a/src/remote/activitypub/renderer/read.ts b/packages/backend/src/remote/activitypub/renderer/read.ts similarity index 100% rename from src/remote/activitypub/renderer/read.ts rename to packages/backend/src/remote/activitypub/renderer/read.ts diff --git a/src/remote/activitypub/renderer/reject.ts b/packages/backend/src/remote/activitypub/renderer/reject.ts similarity index 100% rename from src/remote/activitypub/renderer/reject.ts rename to packages/backend/src/remote/activitypub/renderer/reject.ts diff --git a/src/remote/activitypub/renderer/remove.ts b/packages/backend/src/remote/activitypub/renderer/remove.ts similarity index 100% rename from src/remote/activitypub/renderer/remove.ts rename to packages/backend/src/remote/activitypub/renderer/remove.ts diff --git a/src/remote/activitypub/renderer/tombstone.ts b/packages/backend/src/remote/activitypub/renderer/tombstone.ts similarity index 100% rename from src/remote/activitypub/renderer/tombstone.ts rename to packages/backend/src/remote/activitypub/renderer/tombstone.ts diff --git a/src/remote/activitypub/renderer/undo.ts b/packages/backend/src/remote/activitypub/renderer/undo.ts similarity index 100% rename from src/remote/activitypub/renderer/undo.ts rename to packages/backend/src/remote/activitypub/renderer/undo.ts diff --git a/src/remote/activitypub/renderer/update.ts b/packages/backend/src/remote/activitypub/renderer/update.ts similarity index 100% rename from src/remote/activitypub/renderer/update.ts rename to packages/backend/src/remote/activitypub/renderer/update.ts diff --git a/src/remote/activitypub/renderer/vote.ts b/packages/backend/src/remote/activitypub/renderer/vote.ts similarity index 100% rename from src/remote/activitypub/renderer/vote.ts rename to packages/backend/src/remote/activitypub/renderer/vote.ts diff --git a/src/remote/activitypub/request.ts b/packages/backend/src/remote/activitypub/request.ts similarity index 100% rename from src/remote/activitypub/request.ts rename to packages/backend/src/remote/activitypub/request.ts diff --git a/src/remote/activitypub/resolver.ts b/packages/backend/src/remote/activitypub/resolver.ts similarity index 100% rename from src/remote/activitypub/resolver.ts rename to packages/backend/src/remote/activitypub/resolver.ts diff --git a/src/remote/activitypub/type.ts b/packages/backend/src/remote/activitypub/type.ts similarity index 100% rename from src/remote/activitypub/type.ts rename to packages/backend/src/remote/activitypub/type.ts diff --git a/src/remote/logger.ts b/packages/backend/src/remote/logger.ts similarity index 100% rename from src/remote/logger.ts rename to packages/backend/src/remote/logger.ts diff --git a/src/remote/resolve-user.ts b/packages/backend/src/remote/resolve-user.ts similarity index 100% rename from src/remote/resolve-user.ts rename to packages/backend/src/remote/resolve-user.ts diff --git a/src/remote/webfinger.ts b/packages/backend/src/remote/webfinger.ts similarity index 100% rename from src/remote/webfinger.ts rename to packages/backend/src/remote/webfinger.ts diff --git a/src/server/activitypub.ts b/packages/backend/src/server/activitypub.ts similarity index 100% rename from src/server/activitypub.ts rename to packages/backend/src/server/activitypub.ts diff --git a/src/server/activitypub/featured.ts b/packages/backend/src/server/activitypub/featured.ts similarity index 100% rename from src/server/activitypub/featured.ts rename to packages/backend/src/server/activitypub/featured.ts diff --git a/packages/backend/src/server/activitypub/followers.ts b/packages/backend/src/server/activitypub/followers.ts new file mode 100644 index 000000000..baf2d2346 --- /dev/null +++ b/packages/backend/src/server/activitypub/followers.ts @@ -0,0 +1,102 @@ +import * as Router from '@koa/router'; +import config from '@/config/index'; +import $ from 'cafy'; +import { ID } from '@/misc/cafy-id'; +import * as url from '@/prelude/url'; +import { renderActivity } from '@/remote/activitypub/renderer/index'; +import renderOrderedCollection from '@/remote/activitypub/renderer/ordered-collection'; +import renderOrderedCollectionPage from '@/remote/activitypub/renderer/ordered-collection-page'; +import renderFollowUser from '@/remote/activitypub/renderer/follow-user'; +import { setResponseType } from '../activitypub'; +import { Users, Followings, UserProfiles } from '@/models/index'; +import { LessThan } from 'typeorm'; + +export default async (ctx: Router.RouterContext) => { + const userId = ctx.params.user; + + // Get 'cursor' parameter + const [cursor, cursorErr] = $.optional.type(ID).get(ctx.request.query.cursor); + + // Get 'page' parameter + const pageErr = !$.optional.str.or(['true', 'false']).ok(ctx.request.query.page); + const page: boolean = ctx.request.query.page === 'true'; + + // Validate parameters + if (cursorErr || pageErr) { + ctx.status = 400; + return; + } + + // Verify user + const user = await Users.findOne({ + id: userId, + host: null + }); + + if (user == null) { + ctx.status = 404; + return; + } + + //#region Check ff visibility + const profile = await UserProfiles.findOneOrFail(user.id); + + if (profile.ffVisibility === 'private') { + ctx.status = 403; + ctx.set('Cache-Control', 'public, max-age=30'); + return; + } else if (profile.ffVisibility === 'followers') { + ctx.status = 403; + ctx.set('Cache-Control', 'public, max-age=30'); + return; + } + //#endregion + + const limit = 10; + const partOf = `${config.url}/users/${userId}/followers`; + + if (page) { + const query = { + followeeId: user.id + } as any; + + // カーソルが指定されている場合 + if (cursor) { + query.id = LessThan(cursor); + } + + // Get followers + const followings = await Followings.find({ + where: query, + take: limit + 1, + order: { id: -1 } + }); + + // 「次のページ」があるかどうか + const inStock = followings.length === limit + 1; + if (inStock) followings.pop(); + + const renderedFollowers = await Promise.all(followings.map(following => renderFollowUser(following.followerId))); + const rendered = renderOrderedCollectionPage( + `${partOf}?${url.query({ + page: 'true', + cursor + })}`, + user.followersCount, renderedFollowers, partOf, + undefined, + inStock ? `${partOf}?${url.query({ + page: 'true', + cursor: followings[followings.length - 1].id + })}` : undefined + ); + + ctx.body = renderActivity(rendered); + setResponseType(ctx); + } else { + // index page + const rendered = renderOrderedCollection(partOf, user.followersCount, `${partOf}?page=true`); + ctx.body = renderActivity(rendered); + ctx.set('Cache-Control', 'public, max-age=180'); + setResponseType(ctx); + } +}; diff --git a/packages/backend/src/server/activitypub/following.ts b/packages/backend/src/server/activitypub/following.ts new file mode 100644 index 000000000..b9eb806c3 --- /dev/null +++ b/packages/backend/src/server/activitypub/following.ts @@ -0,0 +1,103 @@ +import * as Router from '@koa/router'; +import config from '@/config/index'; +import $ from 'cafy'; +import { ID } from '@/misc/cafy-id'; +import * as url from '@/prelude/url'; +import { renderActivity } from '@/remote/activitypub/renderer/index'; +import renderOrderedCollection from '@/remote/activitypub/renderer/ordered-collection'; +import renderOrderedCollectionPage from '@/remote/activitypub/renderer/ordered-collection-page'; +import renderFollowUser from '@/remote/activitypub/renderer/follow-user'; +import { setResponseType } from '../activitypub'; +import { Users, Followings, UserProfiles } from '@/models/index'; +import { LessThan, FindConditions } from 'typeorm'; +import { Following } from '@/models/entities/following'; + +export default async (ctx: Router.RouterContext) => { + const userId = ctx.params.user; + + // Get 'cursor' parameter + const [cursor, cursorErr] = $.optional.type(ID).get(ctx.request.query.cursor); + + // Get 'page' parameter + const pageErr = !$.optional.str.or(['true', 'false']).ok(ctx.request.query.page); + const page: boolean = ctx.request.query.page === 'true'; + + // Validate parameters + if (cursorErr || pageErr) { + ctx.status = 400; + return; + } + + // Verify user + const user = await Users.findOne({ + id: userId, + host: null + }); + + if (user == null) { + ctx.status = 404; + return; + } + + //#region Check ff visibility + const profile = await UserProfiles.findOneOrFail(user.id); + + if (profile.ffVisibility === 'private') { + ctx.status = 403; + ctx.set('Cache-Control', 'public, max-age=30'); + return; + } else if (profile.ffVisibility === 'followers') { + ctx.status = 403; + ctx.set('Cache-Control', 'public, max-age=30'); + return; + } + //#endregion + + const limit = 10; + const partOf = `${config.url}/users/${userId}/following`; + + if (page) { + const query = { + followerId: user.id + } as FindConditions; + + // カーソルが指定されている場合 + if (cursor) { + query.id = LessThan(cursor); + } + + // Get followings + const followings = await Followings.find({ + where: query, + take: limit + 1, + order: { id: -1 } + }); + + // 「次のページ」があるかどうか + const inStock = followings.length === limit + 1; + if (inStock) followings.pop(); + + const renderedFollowees = await Promise.all(followings.map(following => renderFollowUser(following.followeeId))); + const rendered = renderOrderedCollectionPage( + `${partOf}?${url.query({ + page: 'true', + cursor + })}`, + user.followingCount, renderedFollowees, partOf, + undefined, + inStock ? `${partOf}?${url.query({ + page: 'true', + cursor: followings[followings.length - 1].id + })}` : undefined + ); + + ctx.body = renderActivity(rendered); + setResponseType(ctx); + } else { + // index page + const rendered = renderOrderedCollection(partOf, user.followingCount, `${partOf}?page=true`); + ctx.body = renderActivity(rendered); + ctx.set('Cache-Control', 'public, max-age=180'); + setResponseType(ctx); + } +}; diff --git a/src/server/activitypub/outbox.ts b/packages/backend/src/server/activitypub/outbox.ts similarity index 100% rename from src/server/activitypub/outbox.ts rename to packages/backend/src/server/activitypub/outbox.ts diff --git a/src/server/api/2fa.ts b/packages/backend/src/server/api/2fa.ts similarity index 100% rename from src/server/api/2fa.ts rename to packages/backend/src/server/api/2fa.ts diff --git a/src/server/api/api-handler.ts b/packages/backend/src/server/api/api-handler.ts similarity index 100% rename from src/server/api/api-handler.ts rename to packages/backend/src/server/api/api-handler.ts diff --git a/src/server/api/authenticate.ts b/packages/backend/src/server/api/authenticate.ts similarity index 100% rename from src/server/api/authenticate.ts rename to packages/backend/src/server/api/authenticate.ts diff --git a/src/server/api/call.ts b/packages/backend/src/server/api/call.ts similarity index 100% rename from src/server/api/call.ts rename to packages/backend/src/server/api/call.ts diff --git a/src/server/api/common/generate-block-query.ts b/packages/backend/src/server/api/common/generate-block-query.ts similarity index 100% rename from src/server/api/common/generate-block-query.ts rename to packages/backend/src/server/api/common/generate-block-query.ts diff --git a/src/server/api/common/generate-channel-query.ts b/packages/backend/src/server/api/common/generate-channel-query.ts similarity index 100% rename from src/server/api/common/generate-channel-query.ts rename to packages/backend/src/server/api/common/generate-channel-query.ts diff --git a/src/server/api/common/generate-muted-note-query.ts b/packages/backend/src/server/api/common/generate-muted-note-query.ts similarity index 100% rename from src/server/api/common/generate-muted-note-query.ts rename to packages/backend/src/server/api/common/generate-muted-note-query.ts diff --git a/src/server/api/common/generate-muted-note-thread-query.ts b/packages/backend/src/server/api/common/generate-muted-note-thread-query.ts similarity index 100% rename from src/server/api/common/generate-muted-note-thread-query.ts rename to packages/backend/src/server/api/common/generate-muted-note-thread-query.ts diff --git a/src/server/api/common/generate-muted-user-query.ts b/packages/backend/src/server/api/common/generate-muted-user-query.ts similarity index 100% rename from src/server/api/common/generate-muted-user-query.ts rename to packages/backend/src/server/api/common/generate-muted-user-query.ts diff --git a/src/server/api/common/generate-native-user-token.ts b/packages/backend/src/server/api/common/generate-native-user-token.ts similarity index 100% rename from src/server/api/common/generate-native-user-token.ts rename to packages/backend/src/server/api/common/generate-native-user-token.ts diff --git a/src/server/api/common/generate-replies-query.ts b/packages/backend/src/server/api/common/generate-replies-query.ts similarity index 100% rename from src/server/api/common/generate-replies-query.ts rename to packages/backend/src/server/api/common/generate-replies-query.ts diff --git a/src/server/api/common/generate-visibility-query.ts b/packages/backend/src/server/api/common/generate-visibility-query.ts similarity index 100% rename from src/server/api/common/generate-visibility-query.ts rename to packages/backend/src/server/api/common/generate-visibility-query.ts diff --git a/src/server/api/common/getters.ts b/packages/backend/src/server/api/common/getters.ts similarity index 100% rename from src/server/api/common/getters.ts rename to packages/backend/src/server/api/common/getters.ts diff --git a/src/server/api/common/inject-featured.ts b/packages/backend/src/server/api/common/inject-featured.ts similarity index 100% rename from src/server/api/common/inject-featured.ts rename to packages/backend/src/server/api/common/inject-featured.ts diff --git a/src/server/api/common/inject-promo.ts b/packages/backend/src/server/api/common/inject-promo.ts similarity index 100% rename from src/server/api/common/inject-promo.ts rename to packages/backend/src/server/api/common/inject-promo.ts diff --git a/src/server/api/common/is-native-token.ts b/packages/backend/src/server/api/common/is-native-token.ts similarity index 100% rename from src/server/api/common/is-native-token.ts rename to packages/backend/src/server/api/common/is-native-token.ts diff --git a/src/server/api/common/make-pagination-query.ts b/packages/backend/src/server/api/common/make-pagination-query.ts similarity index 100% rename from src/server/api/common/make-pagination-query.ts rename to packages/backend/src/server/api/common/make-pagination-query.ts diff --git a/src/server/api/common/read-messaging-message.ts b/packages/backend/src/server/api/common/read-messaging-message.ts similarity index 100% rename from src/server/api/common/read-messaging-message.ts rename to packages/backend/src/server/api/common/read-messaging-message.ts diff --git a/src/server/api/common/read-notification.ts b/packages/backend/src/server/api/common/read-notification.ts similarity index 100% rename from src/server/api/common/read-notification.ts rename to packages/backend/src/server/api/common/read-notification.ts diff --git a/src/server/api/common/signin.ts b/packages/backend/src/server/api/common/signin.ts similarity index 100% rename from src/server/api/common/signin.ts rename to packages/backend/src/server/api/common/signin.ts diff --git a/src/server/api/common/signup.ts b/packages/backend/src/server/api/common/signup.ts similarity index 100% rename from src/server/api/common/signup.ts rename to packages/backend/src/server/api/common/signup.ts diff --git a/packages/backend/src/server/api/define.ts b/packages/backend/src/server/api/define.ts new file mode 100644 index 000000000..48253e78e --- /dev/null +++ b/packages/backend/src/server/api/define.ts @@ -0,0 +1,87 @@ +import * as fs from 'fs'; +import { ILocalUser } from '@/models/entities/user'; +import { IEndpointMeta } from './endpoints'; +import { ApiError } from './error'; +import { SchemaType } from '@/misc/schema'; +import { AccessToken } from '@/models/entities/access-token'; + +type NonOptional = T extends undefined ? never : T; + +type SimpleUserInfo = { + id: ILocalUser['id']; + host: ILocalUser['host']; + username: ILocalUser['username']; + uri: ILocalUser['uri']; + inbox: ILocalUser['inbox']; + sharedInbox: ILocalUser['sharedInbox']; + isAdmin: ILocalUser['isAdmin']; + isModerator: ILocalUser['isModerator']; + isSilenced: ILocalUser['isSilenced']; +}; + +type Params = { + [P in keyof T['params']]: NonNullable[P]['transform'] extends () => any + ? ReturnType[P]['transform']> + : NonNullable[P]['default'] extends null | number | string + ? NonOptional[P]['validator']['get']>[0]> + : ReturnType[P]['validator']['get']>[0]; +}; + +export type Response = Record | void; + +type executor = + (params: Params, user: T['requireCredential'] extends true ? SimpleUserInfo : SimpleUserInfo | null, token: AccessToken | null, file?: any, cleanup?: () => any) => + Promise>>; + +export default function (meta: T, cb: executor) + : (params: any, user: T['requireCredential'] extends true ? SimpleUserInfo : SimpleUserInfo | null, token: AccessToken | null, file?: any) => Promise { + return (params: any, user: T['requireCredential'] extends true ? SimpleUserInfo : SimpleUserInfo | null, token: AccessToken | null, file?: any) => { + function cleanup() { + fs.unlink(file.path, () => {}); + } + + if (meta.requireFile && file == null) return Promise.reject(new ApiError({ + message: 'File required.', + code: 'FILE_REQUIRED', + id: '4267801e-70d1-416a-b011-4ee502885d8b', + })); + + const [ps, pserr] = getParams(meta, params); + if (pserr) { + if (file) cleanup(); + return Promise.reject(pserr); + } + + return cb(ps, user, token, file, cleanup); + }; +} + +function getParams(defs: T, params: any): [Params, ApiError | null] { + if (defs.params == null) return [params, null]; + + const x: any = {}; + let err: ApiError | null = null; + Object.entries(defs.params).some(([k, def]) => { + const [v, e] = def.validator.get(params[k]); + if (e) { + err = new ApiError({ + message: 'Invalid param.', + code: 'INVALID_PARAM', + id: '3d81ceae-475f-4600-b2a8-2bc116157532', + }, { + param: k, + reason: e.message + }); + return true; + } else { + if (v === undefined && Object.prototype.hasOwnProperty.call(def, 'default')) { + x[k] = def.default; + } else { + x[k] = v; + } + if (def.transform) x[k] = def.transform(x[k]); + return false; + } + }); + return [x, err]; +} diff --git a/src/server/api/endpoints.ts b/packages/backend/src/server/api/endpoints.ts similarity index 100% rename from src/server/api/endpoints.ts rename to packages/backend/src/server/api/endpoints.ts diff --git a/src/server/api/endpoints/admin/abuse-user-reports.ts b/packages/backend/src/server/api/endpoints/admin/abuse-user-reports.ts similarity index 100% rename from src/server/api/endpoints/admin/abuse-user-reports.ts rename to packages/backend/src/server/api/endpoints/admin/abuse-user-reports.ts diff --git a/src/server/api/endpoints/admin/accounts/create.ts b/packages/backend/src/server/api/endpoints/admin/accounts/create.ts similarity index 100% rename from src/server/api/endpoints/admin/accounts/create.ts rename to packages/backend/src/server/api/endpoints/admin/accounts/create.ts diff --git a/src/server/api/endpoints/admin/accounts/delete.ts b/packages/backend/src/server/api/endpoints/admin/accounts/delete.ts similarity index 100% rename from src/server/api/endpoints/admin/accounts/delete.ts rename to packages/backend/src/server/api/endpoints/admin/accounts/delete.ts diff --git a/src/server/api/endpoints/admin/ad/create.ts b/packages/backend/src/server/api/endpoints/admin/ad/create.ts similarity index 100% rename from src/server/api/endpoints/admin/ad/create.ts rename to packages/backend/src/server/api/endpoints/admin/ad/create.ts diff --git a/src/server/api/endpoints/admin/ad/delete.ts b/packages/backend/src/server/api/endpoints/admin/ad/delete.ts similarity index 100% rename from src/server/api/endpoints/admin/ad/delete.ts rename to packages/backend/src/server/api/endpoints/admin/ad/delete.ts diff --git a/src/server/api/endpoints/admin/ad/list.ts b/packages/backend/src/server/api/endpoints/admin/ad/list.ts similarity index 100% rename from src/server/api/endpoints/admin/ad/list.ts rename to packages/backend/src/server/api/endpoints/admin/ad/list.ts diff --git a/src/server/api/endpoints/admin/ad/update.ts b/packages/backend/src/server/api/endpoints/admin/ad/update.ts similarity index 100% rename from src/server/api/endpoints/admin/ad/update.ts rename to packages/backend/src/server/api/endpoints/admin/ad/update.ts diff --git a/src/server/api/endpoints/admin/announcements/create.ts b/packages/backend/src/server/api/endpoints/admin/announcements/create.ts similarity index 100% rename from src/server/api/endpoints/admin/announcements/create.ts rename to packages/backend/src/server/api/endpoints/admin/announcements/create.ts diff --git a/src/server/api/endpoints/admin/announcements/delete.ts b/packages/backend/src/server/api/endpoints/admin/announcements/delete.ts similarity index 100% rename from src/server/api/endpoints/admin/announcements/delete.ts rename to packages/backend/src/server/api/endpoints/admin/announcements/delete.ts diff --git a/src/server/api/endpoints/admin/announcements/list.ts b/packages/backend/src/server/api/endpoints/admin/announcements/list.ts similarity index 100% rename from src/server/api/endpoints/admin/announcements/list.ts rename to packages/backend/src/server/api/endpoints/admin/announcements/list.ts diff --git a/src/server/api/endpoints/admin/announcements/update.ts b/packages/backend/src/server/api/endpoints/admin/announcements/update.ts similarity index 100% rename from src/server/api/endpoints/admin/announcements/update.ts rename to packages/backend/src/server/api/endpoints/admin/announcements/update.ts diff --git a/src/server/api/endpoints/admin/delete-all-files-of-a-user.ts b/packages/backend/src/server/api/endpoints/admin/delete-all-files-of-a-user.ts similarity index 100% rename from src/server/api/endpoints/admin/delete-all-files-of-a-user.ts rename to packages/backend/src/server/api/endpoints/admin/delete-all-files-of-a-user.ts diff --git a/src/server/api/endpoints/admin/delete-logs.ts b/packages/backend/src/server/api/endpoints/admin/delete-logs.ts similarity index 100% rename from src/server/api/endpoints/admin/delete-logs.ts rename to packages/backend/src/server/api/endpoints/admin/delete-logs.ts diff --git a/src/server/api/endpoints/admin/drive/clean-remote-files.ts b/packages/backend/src/server/api/endpoints/admin/drive/clean-remote-files.ts similarity index 100% rename from src/server/api/endpoints/admin/drive/clean-remote-files.ts rename to packages/backend/src/server/api/endpoints/admin/drive/clean-remote-files.ts diff --git a/src/server/api/endpoints/admin/drive/cleanup.ts b/packages/backend/src/server/api/endpoints/admin/drive/cleanup.ts similarity index 100% rename from src/server/api/endpoints/admin/drive/cleanup.ts rename to packages/backend/src/server/api/endpoints/admin/drive/cleanup.ts diff --git a/src/server/api/endpoints/admin/drive/files.ts b/packages/backend/src/server/api/endpoints/admin/drive/files.ts similarity index 100% rename from src/server/api/endpoints/admin/drive/files.ts rename to packages/backend/src/server/api/endpoints/admin/drive/files.ts diff --git a/src/server/api/endpoints/admin/drive/show-file.ts b/packages/backend/src/server/api/endpoints/admin/drive/show-file.ts similarity index 100% rename from src/server/api/endpoints/admin/drive/show-file.ts rename to packages/backend/src/server/api/endpoints/admin/drive/show-file.ts diff --git a/src/server/api/endpoints/admin/emoji/add.ts b/packages/backend/src/server/api/endpoints/admin/emoji/add.ts similarity index 100% rename from src/server/api/endpoints/admin/emoji/add.ts rename to packages/backend/src/server/api/endpoints/admin/emoji/add.ts diff --git a/src/server/api/endpoints/admin/emoji/copy.ts b/packages/backend/src/server/api/endpoints/admin/emoji/copy.ts similarity index 100% rename from src/server/api/endpoints/admin/emoji/copy.ts rename to packages/backend/src/server/api/endpoints/admin/emoji/copy.ts diff --git a/src/server/api/endpoints/admin/emoji/list-remote.ts b/packages/backend/src/server/api/endpoints/admin/emoji/list-remote.ts similarity index 100% rename from src/server/api/endpoints/admin/emoji/list-remote.ts rename to packages/backend/src/server/api/endpoints/admin/emoji/list-remote.ts diff --git a/src/server/api/endpoints/admin/emoji/list.ts b/packages/backend/src/server/api/endpoints/admin/emoji/list.ts similarity index 100% rename from src/server/api/endpoints/admin/emoji/list.ts rename to packages/backend/src/server/api/endpoints/admin/emoji/list.ts diff --git a/src/server/api/endpoints/admin/emoji/remove.ts b/packages/backend/src/server/api/endpoints/admin/emoji/remove.ts similarity index 100% rename from src/server/api/endpoints/admin/emoji/remove.ts rename to packages/backend/src/server/api/endpoints/admin/emoji/remove.ts diff --git a/src/server/api/endpoints/admin/emoji/update.ts b/packages/backend/src/server/api/endpoints/admin/emoji/update.ts similarity index 100% rename from src/server/api/endpoints/admin/emoji/update.ts rename to packages/backend/src/server/api/endpoints/admin/emoji/update.ts diff --git a/src/server/api/endpoints/admin/federation/delete-all-files.ts b/packages/backend/src/server/api/endpoints/admin/federation/delete-all-files.ts similarity index 100% rename from src/server/api/endpoints/admin/federation/delete-all-files.ts rename to packages/backend/src/server/api/endpoints/admin/federation/delete-all-files.ts diff --git a/src/server/api/endpoints/admin/federation/refresh-remote-instance-metadata.ts b/packages/backend/src/server/api/endpoints/admin/federation/refresh-remote-instance-metadata.ts similarity index 100% rename from src/server/api/endpoints/admin/federation/refresh-remote-instance-metadata.ts rename to packages/backend/src/server/api/endpoints/admin/federation/refresh-remote-instance-metadata.ts diff --git a/src/server/api/endpoints/admin/federation/remove-all-following.ts b/packages/backend/src/server/api/endpoints/admin/federation/remove-all-following.ts similarity index 100% rename from src/server/api/endpoints/admin/federation/remove-all-following.ts rename to packages/backend/src/server/api/endpoints/admin/federation/remove-all-following.ts diff --git a/src/server/api/endpoints/admin/federation/update-instance.ts b/packages/backend/src/server/api/endpoints/admin/federation/update-instance.ts similarity index 100% rename from src/server/api/endpoints/admin/federation/update-instance.ts rename to packages/backend/src/server/api/endpoints/admin/federation/update-instance.ts diff --git a/src/server/api/endpoints/admin/get-index-stats.ts b/packages/backend/src/server/api/endpoints/admin/get-index-stats.ts similarity index 100% rename from src/server/api/endpoints/admin/get-index-stats.ts rename to packages/backend/src/server/api/endpoints/admin/get-index-stats.ts diff --git a/src/server/api/endpoints/admin/get-table-stats.ts b/packages/backend/src/server/api/endpoints/admin/get-table-stats.ts similarity index 100% rename from src/server/api/endpoints/admin/get-table-stats.ts rename to packages/backend/src/server/api/endpoints/admin/get-table-stats.ts diff --git a/src/server/api/endpoints/admin/invite.ts b/packages/backend/src/server/api/endpoints/admin/invite.ts similarity index 100% rename from src/server/api/endpoints/admin/invite.ts rename to packages/backend/src/server/api/endpoints/admin/invite.ts diff --git a/src/server/api/endpoints/admin/moderators/add.ts b/packages/backend/src/server/api/endpoints/admin/moderators/add.ts similarity index 100% rename from src/server/api/endpoints/admin/moderators/add.ts rename to packages/backend/src/server/api/endpoints/admin/moderators/add.ts diff --git a/src/server/api/endpoints/admin/moderators/remove.ts b/packages/backend/src/server/api/endpoints/admin/moderators/remove.ts similarity index 100% rename from src/server/api/endpoints/admin/moderators/remove.ts rename to packages/backend/src/server/api/endpoints/admin/moderators/remove.ts diff --git a/src/server/api/endpoints/admin/promo/create.ts b/packages/backend/src/server/api/endpoints/admin/promo/create.ts similarity index 100% rename from src/server/api/endpoints/admin/promo/create.ts rename to packages/backend/src/server/api/endpoints/admin/promo/create.ts diff --git a/src/server/api/endpoints/admin/queue/clear.ts b/packages/backend/src/server/api/endpoints/admin/queue/clear.ts similarity index 100% rename from src/server/api/endpoints/admin/queue/clear.ts rename to packages/backend/src/server/api/endpoints/admin/queue/clear.ts diff --git a/src/server/api/endpoints/admin/queue/deliver-delayed.ts b/packages/backend/src/server/api/endpoints/admin/queue/deliver-delayed.ts similarity index 100% rename from src/server/api/endpoints/admin/queue/deliver-delayed.ts rename to packages/backend/src/server/api/endpoints/admin/queue/deliver-delayed.ts diff --git a/src/server/api/endpoints/admin/queue/inbox-delayed.ts b/packages/backend/src/server/api/endpoints/admin/queue/inbox-delayed.ts similarity index 100% rename from src/server/api/endpoints/admin/queue/inbox-delayed.ts rename to packages/backend/src/server/api/endpoints/admin/queue/inbox-delayed.ts diff --git a/src/server/api/endpoints/admin/queue/jobs.ts b/packages/backend/src/server/api/endpoints/admin/queue/jobs.ts similarity index 100% rename from src/server/api/endpoints/admin/queue/jobs.ts rename to packages/backend/src/server/api/endpoints/admin/queue/jobs.ts diff --git a/src/server/api/endpoints/admin/queue/stats.ts b/packages/backend/src/server/api/endpoints/admin/queue/stats.ts similarity index 100% rename from src/server/api/endpoints/admin/queue/stats.ts rename to packages/backend/src/server/api/endpoints/admin/queue/stats.ts diff --git a/src/server/api/endpoints/admin/relays/add.ts b/packages/backend/src/server/api/endpoints/admin/relays/add.ts similarity index 100% rename from src/server/api/endpoints/admin/relays/add.ts rename to packages/backend/src/server/api/endpoints/admin/relays/add.ts diff --git a/src/server/api/endpoints/admin/relays/list.ts b/packages/backend/src/server/api/endpoints/admin/relays/list.ts similarity index 100% rename from src/server/api/endpoints/admin/relays/list.ts rename to packages/backend/src/server/api/endpoints/admin/relays/list.ts diff --git a/src/server/api/endpoints/admin/relays/remove.ts b/packages/backend/src/server/api/endpoints/admin/relays/remove.ts similarity index 100% rename from src/server/api/endpoints/admin/relays/remove.ts rename to packages/backend/src/server/api/endpoints/admin/relays/remove.ts diff --git a/src/server/api/endpoints/admin/reset-password.ts b/packages/backend/src/server/api/endpoints/admin/reset-password.ts similarity index 100% rename from src/server/api/endpoints/admin/reset-password.ts rename to packages/backend/src/server/api/endpoints/admin/reset-password.ts diff --git a/src/server/api/endpoints/admin/resolve-abuse-user-report.ts b/packages/backend/src/server/api/endpoints/admin/resolve-abuse-user-report.ts similarity index 100% rename from src/server/api/endpoints/admin/resolve-abuse-user-report.ts rename to packages/backend/src/server/api/endpoints/admin/resolve-abuse-user-report.ts diff --git a/src/server/api/endpoints/admin/resync-chart.ts b/packages/backend/src/server/api/endpoints/admin/resync-chart.ts similarity index 100% rename from src/server/api/endpoints/admin/resync-chart.ts rename to packages/backend/src/server/api/endpoints/admin/resync-chart.ts diff --git a/src/server/api/endpoints/admin/send-email.ts b/packages/backend/src/server/api/endpoints/admin/send-email.ts similarity index 100% rename from src/server/api/endpoints/admin/send-email.ts rename to packages/backend/src/server/api/endpoints/admin/send-email.ts diff --git a/src/server/api/endpoints/admin/server-info.ts b/packages/backend/src/server/api/endpoints/admin/server-info.ts similarity index 100% rename from src/server/api/endpoints/admin/server-info.ts rename to packages/backend/src/server/api/endpoints/admin/server-info.ts diff --git a/src/server/api/endpoints/admin/show-moderation-logs.ts b/packages/backend/src/server/api/endpoints/admin/show-moderation-logs.ts similarity index 100% rename from src/server/api/endpoints/admin/show-moderation-logs.ts rename to packages/backend/src/server/api/endpoints/admin/show-moderation-logs.ts diff --git a/src/server/api/endpoints/admin/show-user.ts b/packages/backend/src/server/api/endpoints/admin/show-user.ts similarity index 100% rename from src/server/api/endpoints/admin/show-user.ts rename to packages/backend/src/server/api/endpoints/admin/show-user.ts diff --git a/src/server/api/endpoints/admin/show-users.ts b/packages/backend/src/server/api/endpoints/admin/show-users.ts similarity index 100% rename from src/server/api/endpoints/admin/show-users.ts rename to packages/backend/src/server/api/endpoints/admin/show-users.ts diff --git a/src/server/api/endpoints/admin/silence-user.ts b/packages/backend/src/server/api/endpoints/admin/silence-user.ts similarity index 100% rename from src/server/api/endpoints/admin/silence-user.ts rename to packages/backend/src/server/api/endpoints/admin/silence-user.ts diff --git a/src/server/api/endpoints/admin/suspend-user.ts b/packages/backend/src/server/api/endpoints/admin/suspend-user.ts similarity index 100% rename from src/server/api/endpoints/admin/suspend-user.ts rename to packages/backend/src/server/api/endpoints/admin/suspend-user.ts diff --git a/src/server/api/endpoints/admin/unsilence-user.ts b/packages/backend/src/server/api/endpoints/admin/unsilence-user.ts similarity index 100% rename from src/server/api/endpoints/admin/unsilence-user.ts rename to packages/backend/src/server/api/endpoints/admin/unsilence-user.ts diff --git a/src/server/api/endpoints/admin/unsuspend-user.ts b/packages/backend/src/server/api/endpoints/admin/unsuspend-user.ts similarity index 100% rename from src/server/api/endpoints/admin/unsuspend-user.ts rename to packages/backend/src/server/api/endpoints/admin/unsuspend-user.ts diff --git a/src/server/api/endpoints/admin/update-meta.ts b/packages/backend/src/server/api/endpoints/admin/update-meta.ts similarity index 100% rename from src/server/api/endpoints/admin/update-meta.ts rename to packages/backend/src/server/api/endpoints/admin/update-meta.ts diff --git a/src/server/api/endpoints/admin/vacuum.ts b/packages/backend/src/server/api/endpoints/admin/vacuum.ts similarity index 100% rename from src/server/api/endpoints/admin/vacuum.ts rename to packages/backend/src/server/api/endpoints/admin/vacuum.ts diff --git a/src/server/api/endpoints/announcements.ts b/packages/backend/src/server/api/endpoints/announcements.ts similarity index 100% rename from src/server/api/endpoints/announcements.ts rename to packages/backend/src/server/api/endpoints/announcements.ts diff --git a/src/server/api/endpoints/antennas/create.ts b/packages/backend/src/server/api/endpoints/antennas/create.ts similarity index 100% rename from src/server/api/endpoints/antennas/create.ts rename to packages/backend/src/server/api/endpoints/antennas/create.ts diff --git a/src/server/api/endpoints/antennas/delete.ts b/packages/backend/src/server/api/endpoints/antennas/delete.ts similarity index 100% rename from src/server/api/endpoints/antennas/delete.ts rename to packages/backend/src/server/api/endpoints/antennas/delete.ts diff --git a/src/server/api/endpoints/antennas/list.ts b/packages/backend/src/server/api/endpoints/antennas/list.ts similarity index 100% rename from src/server/api/endpoints/antennas/list.ts rename to packages/backend/src/server/api/endpoints/antennas/list.ts diff --git a/src/server/api/endpoints/antennas/notes.ts b/packages/backend/src/server/api/endpoints/antennas/notes.ts similarity index 100% rename from src/server/api/endpoints/antennas/notes.ts rename to packages/backend/src/server/api/endpoints/antennas/notes.ts diff --git a/src/server/api/endpoints/antennas/show.ts b/packages/backend/src/server/api/endpoints/antennas/show.ts similarity index 100% rename from src/server/api/endpoints/antennas/show.ts rename to packages/backend/src/server/api/endpoints/antennas/show.ts diff --git a/src/server/api/endpoints/antennas/update.ts b/packages/backend/src/server/api/endpoints/antennas/update.ts similarity index 100% rename from src/server/api/endpoints/antennas/update.ts rename to packages/backend/src/server/api/endpoints/antennas/update.ts diff --git a/packages/backend/src/server/api/endpoints/ap/get.ts b/packages/backend/src/server/api/endpoints/ap/get.ts new file mode 100644 index 000000000..2f97a2477 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/ap/get.ts @@ -0,0 +1,36 @@ +import $ from 'cafy'; +import define from '../../define'; +import Resolver from '@/remote/activitypub/resolver'; +import { ApiError } from '../../error'; +import ms from 'ms'; + +export const meta = { + tags: ['federation'], + + requireCredential: true as const, + + limit: { + duration: ms('1hour'), + max: 30 + }, + + params: { + uri: { + validator: $.str, + }, + }, + + errors: { + }, + + res: { + type: 'object' as const, + optional: false as const, nullable: false as const, + } +}; + +export default define(meta, async (ps) => { + const resolver = new Resolver(); + const object = await resolver.resolve(ps.uri); + return object; +}); diff --git a/packages/backend/src/server/api/endpoints/ap/show.ts b/packages/backend/src/server/api/endpoints/ap/show.ts new file mode 100644 index 000000000..32685d44b --- /dev/null +++ b/packages/backend/src/server/api/endpoints/ap/show.ts @@ -0,0 +1,190 @@ +import $ from 'cafy'; +import define from '../../define'; +import config from '@/config/index'; +import { createPerson } from '@/remote/activitypub/models/person'; +import { createNote } from '@/remote/activitypub/models/note'; +import Resolver from '@/remote/activitypub/resolver'; +import { ApiError } from '../../error'; +import { extractDbHost } from '@/misc/convert-host'; +import { Users, Notes } from '@/models/index'; +import { Note } from '@/models/entities/note'; +import { User } from '@/models/entities/user'; +import { fetchMeta } from '@/misc/fetch-meta'; +import { isActor, isPost, getApId } from '@/remote/activitypub/type'; +import ms from 'ms'; + +export const meta = { + tags: ['federation'], + + requireCredential: true as const, + + limit: { + duration: ms('1hour'), + max: 30 + }, + + params: { + uri: { + validator: $.str, + }, + }, + + errors: { + noSuchObject: { + message: 'No such object.', + code: 'NO_SUCH_OBJECT', + id: 'dc94d745-1262-4e63-a17d-fecaa57efc82' + } + }, + + res: { + type: 'object' as const, + optional: false as const, nullable: false as const, + properties: { + type: { + type: 'string' as const, + optional: false as const, nullable: false as const, + enum: ['User', 'Note'] + }, + object: { + type: 'object' as const, + optional: false as const, nullable: false as const + } + } + } +}; + +export default define(meta, async (ps) => { + const object = await fetchAny(ps.uri); + if (object) { + return object; + } else { + throw new ApiError(meta.errors.noSuchObject); + } +}); + +/*** + * URIからUserかNoteを解決する + */ +async function fetchAny(uri: string) { + // URIがこのサーバーを指しているなら、ローカルユーザーIDとしてDBからフェッチ + if (uri.startsWith(config.url + '/')) { + const parts = uri.split('/'); + const id = parts.pop(); + const type = parts.pop(); + + if (type === 'notes') { + const note = await Notes.findOne(id); + + if (note) { + return { + type: 'Note', + object: await Notes.pack(note, null, { detail: true }) + }; + } + } else if (type === 'users') { + const user = await Users.findOne(id); + + if (user) { + return { + type: 'User', + object: await Users.pack(user, null, { detail: true }) + }; + } + } + } + + // ブロックしてたら中断 + const meta = await fetchMeta(); + if (meta.blockedHosts.includes(extractDbHost(uri))) return null; + + // URI(AP Object id)としてDB検索 + { + const [user, note] = await Promise.all([ + Users.findOne({ uri: uri }), + Notes.findOne({ uri: uri }) + ]); + + const packed = await mergePack(user, note); + if (packed !== null) return packed; + } + + // リモートから一旦オブジェクトフェッチ + const resolver = new Resolver(); + const object = await resolver.resolve(uri) as any; + + // /@user のような正規id以外で取得できるURIが指定されていた場合、ここで初めて正規URIが確定する + // これはDBに存在する可能性があるため再度DB検索 + if (uri !== object.id) { + if (object.id.startsWith(config.url + '/')) { + const parts = object.id.split('/'); + const id = parts.pop(); + const type = parts.pop(); + + if (type === 'notes') { + const note = await Notes.findOne(id); + + if (note) { + return { + type: 'Note', + object: await Notes.pack(note, null, { detail: true }) + }; + } + } else if (type === 'users') { + const user = await Users.findOne(id); + + if (user) { + return { + type: 'User', + object: await Users.pack(user, null, { detail: true }) + }; + } + } + } + + const [user, note] = await Promise.all([ + Users.findOne({ uri: object.id }), + Notes.findOne({ uri: object.id }) + ]); + + const packed = await mergePack(user, note); + if (packed !== null) return packed; + } + + // それでもみつからなければ新規であるため登録 + if (isActor(object)) { + const user = await createPerson(getApId(object)); + return { + type: 'User', + object: await Users.pack(user, null, { detail: true }) + }; + } + + if (isPost(object)) { + const note = await createNote(getApId(object), undefined, true); + return { + type: 'Note', + object: await Notes.pack(note!, null, { detail: true }) + }; + } + + return null; +} + +async function mergePack(user: User | null | undefined, note: Note | null | undefined) { + if (user != null) { + return { + type: 'User', + object: await Users.pack(user, null, { detail: true }) + }; + } + + if (note != null) { + return { + type: 'Note', + object: await Notes.pack(note, null, { detail: true }) + }; + } + + return null; +} diff --git a/src/server/api/endpoints/app/create.ts b/packages/backend/src/server/api/endpoints/app/create.ts similarity index 100% rename from src/server/api/endpoints/app/create.ts rename to packages/backend/src/server/api/endpoints/app/create.ts diff --git a/src/server/api/endpoints/app/show.ts b/packages/backend/src/server/api/endpoints/app/show.ts similarity index 100% rename from src/server/api/endpoints/app/show.ts rename to packages/backend/src/server/api/endpoints/app/show.ts diff --git a/src/server/api/endpoints/auth/accept.ts b/packages/backend/src/server/api/endpoints/auth/accept.ts similarity index 100% rename from src/server/api/endpoints/auth/accept.ts rename to packages/backend/src/server/api/endpoints/auth/accept.ts diff --git a/src/server/api/endpoints/auth/session/generate.ts b/packages/backend/src/server/api/endpoints/auth/session/generate.ts similarity index 100% rename from src/server/api/endpoints/auth/session/generate.ts rename to packages/backend/src/server/api/endpoints/auth/session/generate.ts diff --git a/src/server/api/endpoints/auth/session/show.ts b/packages/backend/src/server/api/endpoints/auth/session/show.ts similarity index 100% rename from src/server/api/endpoints/auth/session/show.ts rename to packages/backend/src/server/api/endpoints/auth/session/show.ts diff --git a/src/server/api/endpoints/auth/session/userkey.ts b/packages/backend/src/server/api/endpoints/auth/session/userkey.ts similarity index 100% rename from src/server/api/endpoints/auth/session/userkey.ts rename to packages/backend/src/server/api/endpoints/auth/session/userkey.ts diff --git a/packages/backend/src/server/api/endpoints/blocking/create.ts b/packages/backend/src/server/api/endpoints/blocking/create.ts new file mode 100644 index 000000000..4d33c0947 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/blocking/create.ts @@ -0,0 +1,89 @@ +import $ from 'cafy'; +import { ID } from '@/misc/cafy-id'; +import ms from 'ms'; +import create from '@/services/blocking/create'; +import define from '../../define'; +import { ApiError } from '../../error'; +import { getUser } from '../../common/getters'; +import { Blockings, NoteWatchings, Users } from '@/models/index'; + +export const meta = { + tags: ['account'], + + limit: { + duration: ms('1hour'), + max: 100 + }, + + requireCredential: true as const, + + kind: 'write:blocks', + + params: { + userId: { + validator: $.type(ID), + } + }, + + errors: { + noSuchUser: { + message: 'No such user.', + code: 'NO_SUCH_USER', + id: '7cc4f851-e2f1-4621-9633-ec9e1d00c01e' + }, + + blockeeIsYourself: { + message: 'Blockee is yourself.', + code: 'BLOCKEE_IS_YOURSELF', + id: '88b19138-f28d-42c0-8499-6a31bbd0fdc6' + }, + + alreadyBlocking: { + message: 'You are already blocking that user.', + code: 'ALREADY_BLOCKING', + id: '787fed64-acb9-464a-82eb-afbd745b9614' + }, + }, + + res: { + type: 'object' as const, + optional: false as const, nullable: false as const, + ref: 'User' + } +}; + +export default define(meta, async (ps, user) => { + const blocker = await Users.findOneOrFail(user.id); + + // 自分自身 + if (user.id === ps.userId) { + throw new ApiError(meta.errors.blockeeIsYourself); + } + + // Get blockee + const blockee = await getUser(ps.userId).catch(e => { + if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser); + throw e; + }); + + // Check if already blocking + const exist = await Blockings.findOne({ + blockerId: blocker.id, + blockeeId: blockee.id + }); + + if (exist != null) { + throw new ApiError(meta.errors.alreadyBlocking); + } + + await create(blocker, blockee); + + NoteWatchings.delete({ + userId: blocker.id, + noteUserId: blockee.id + }); + + return await Users.pack(blockee.id, blocker, { + detail: true + }); +}); diff --git a/packages/backend/src/server/api/endpoints/blocking/delete.ts b/packages/backend/src/server/api/endpoints/blocking/delete.ts new file mode 100644 index 000000000..ae5dab020 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/blocking/delete.ts @@ -0,0 +1,85 @@ +import $ from 'cafy'; +import { ID } from '@/misc/cafy-id'; +import ms from 'ms'; +import deleteBlocking from '@/services/blocking/delete'; +import define from '../../define'; +import { ApiError } from '../../error'; +import { getUser } from '../../common/getters'; +import { Blockings, Users } from '@/models/index'; + +export const meta = { + tags: ['account'], + + limit: { + duration: ms('1hour'), + max: 100 + }, + + requireCredential: true as const, + + kind: 'write:blocks', + + params: { + userId: { + validator: $.type(ID), + } + }, + + errors: { + noSuchUser: { + message: 'No such user.', + code: 'NO_SUCH_USER', + id: '8621d8bf-c358-4303-a066-5ea78610eb3f' + }, + + blockeeIsYourself: { + message: 'Blockee is yourself.', + code: 'BLOCKEE_IS_YOURSELF', + id: '06f6fac6-524b-473c-a354-e97a40ae6eac' + }, + + notBlocking: { + message: 'You are not blocking that user.', + code: 'NOT_BLOCKING', + id: '291b2efa-60c6-45c0-9f6a-045c8f9b02cd' + }, + }, + + res: { + type: 'object' as const, + optional: false as const, nullable: false as const, + ref: 'User', + }, +}; + +export default define(meta, async (ps, user) => { + const blocker = await Users.findOneOrFail(user.id); + + // Check if the blockee is yourself + if (user.id === ps.userId) { + throw new ApiError(meta.errors.blockeeIsYourself); + } + + // Get blockee + const blockee = await getUser(ps.userId).catch(e => { + if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser); + throw e; + }); + + // Check not blocking + const exist = await Blockings.findOne({ + blockerId: blocker.id, + blockeeId: blockee.id + }); + + if (exist == null) { + throw new ApiError(meta.errors.notBlocking); + } + + // Delete blocking + await deleteBlocking(blocker, blockee); + + return await Users.pack(blockee.id, blocker, { + detail: true + }); +}); diff --git a/src/server/api/endpoints/blocking/list.ts b/packages/backend/src/server/api/endpoints/blocking/list.ts similarity index 100% rename from src/server/api/endpoints/blocking/list.ts rename to packages/backend/src/server/api/endpoints/blocking/list.ts diff --git a/src/server/api/endpoints/channels/create.ts b/packages/backend/src/server/api/endpoints/channels/create.ts similarity index 100% rename from src/server/api/endpoints/channels/create.ts rename to packages/backend/src/server/api/endpoints/channels/create.ts diff --git a/src/server/api/endpoints/channels/featured.ts b/packages/backend/src/server/api/endpoints/channels/featured.ts similarity index 100% rename from src/server/api/endpoints/channels/featured.ts rename to packages/backend/src/server/api/endpoints/channels/featured.ts diff --git a/src/server/api/endpoints/channels/follow.ts b/packages/backend/src/server/api/endpoints/channels/follow.ts similarity index 100% rename from src/server/api/endpoints/channels/follow.ts rename to packages/backend/src/server/api/endpoints/channels/follow.ts diff --git a/src/server/api/endpoints/channels/followed.ts b/packages/backend/src/server/api/endpoints/channels/followed.ts similarity index 100% rename from src/server/api/endpoints/channels/followed.ts rename to packages/backend/src/server/api/endpoints/channels/followed.ts diff --git a/src/server/api/endpoints/channels/owned.ts b/packages/backend/src/server/api/endpoints/channels/owned.ts similarity index 100% rename from src/server/api/endpoints/channels/owned.ts rename to packages/backend/src/server/api/endpoints/channels/owned.ts diff --git a/src/server/api/endpoints/channels/pin-note.ts b/packages/backend/src/server/api/endpoints/channels/pin-note.ts similarity index 100% rename from src/server/api/endpoints/channels/pin-note.ts rename to packages/backend/src/server/api/endpoints/channels/pin-note.ts diff --git a/src/server/api/endpoints/channels/show.ts b/packages/backend/src/server/api/endpoints/channels/show.ts similarity index 100% rename from src/server/api/endpoints/channels/show.ts rename to packages/backend/src/server/api/endpoints/channels/show.ts diff --git a/src/server/api/endpoints/channels/timeline.ts b/packages/backend/src/server/api/endpoints/channels/timeline.ts similarity index 100% rename from src/server/api/endpoints/channels/timeline.ts rename to packages/backend/src/server/api/endpoints/channels/timeline.ts diff --git a/src/server/api/endpoints/channels/unfollow.ts b/packages/backend/src/server/api/endpoints/channels/unfollow.ts similarity index 100% rename from src/server/api/endpoints/channels/unfollow.ts rename to packages/backend/src/server/api/endpoints/channels/unfollow.ts diff --git a/packages/backend/src/server/api/endpoints/channels/update.ts b/packages/backend/src/server/api/endpoints/channels/update.ts new file mode 100644 index 000000000..05f279d6a --- /dev/null +++ b/packages/backend/src/server/api/endpoints/channels/update.ts @@ -0,0 +1,94 @@ +import $ from 'cafy'; +import { ID } from '@/misc/cafy-id'; +import define from '../../define'; +import { ApiError } from '../../error'; +import { Channels, DriveFiles } from '@/models/index'; + +export const meta = { + tags: ['channels'], + + requireCredential: true as const, + + kind: 'write:channels', + + params: { + channelId: { + validator: $.type(ID), + }, + + name: { + validator: $.optional.str.range(1, 128) + }, + + description: { + validator: $.nullable.optional.str.range(1, 2048) + }, + + bannerId: { + validator: $.nullable.optional.type(ID), + } + }, + + res: { + type: 'object' as const, + optional: false as const, nullable: false as const, + ref: 'Channel', + }, + + errors: { + noSuchChannel: { + message: 'No such channel.', + code: 'NO_SUCH_CHANNEL', + id: 'f9c5467f-d492-4c3c-9a8d-a70dacc86512' + }, + + accessDenied: { + message: 'You do not have edit privilege of the channel.', + code: 'ACCESS_DENIED', + id: '1fb7cb09-d46a-4fdf-b8df-057788cce513' + }, + + noSuchFile: { + message: 'No such file.', + code: 'NO_SUCH_FILE', + id: 'e86c14a4-0da2-4032-8df3-e737a04c7f3b' + }, + } +}; + +export default define(meta, async (ps, me) => { + const channel = await Channels.findOne({ + id: ps.channelId, + }); + + if (channel == null) { + throw new ApiError(meta.errors.noSuchChannel); + } + + if (channel.userId !== me.id) { + throw new ApiError(meta.errors.accessDenied); + } + + // eslint:disable-next-line:no-unnecessary-initializer + let banner = undefined; + if (ps.bannerId != null) { + banner = await DriveFiles.findOne({ + id: ps.bannerId, + userId: me.id + }); + + if (banner == null) { + throw new ApiError(meta.errors.noSuchFile); + } + } else if (ps.bannerId === null) { + banner = null; + } + + await Channels.update(channel.id, { + ...(ps.name !== undefined ? { name: ps.name } : {}), + ...(ps.description !== undefined ? { description: ps.description } : {}), + ...(banner ? { bannerId: banner.id } : {}), + }); + + return await Channels.pack(channel.id, me); +}); diff --git a/src/server/api/endpoints/charts/active-users.ts b/packages/backend/src/server/api/endpoints/charts/active-users.ts similarity index 100% rename from src/server/api/endpoints/charts/active-users.ts rename to packages/backend/src/server/api/endpoints/charts/active-users.ts diff --git a/src/server/api/endpoints/charts/drive.ts b/packages/backend/src/server/api/endpoints/charts/drive.ts similarity index 100% rename from src/server/api/endpoints/charts/drive.ts rename to packages/backend/src/server/api/endpoints/charts/drive.ts diff --git a/src/server/api/endpoints/charts/federation.ts b/packages/backend/src/server/api/endpoints/charts/federation.ts similarity index 100% rename from src/server/api/endpoints/charts/federation.ts rename to packages/backend/src/server/api/endpoints/charts/federation.ts diff --git a/src/server/api/endpoints/charts/hashtag.ts b/packages/backend/src/server/api/endpoints/charts/hashtag.ts similarity index 100% rename from src/server/api/endpoints/charts/hashtag.ts rename to packages/backend/src/server/api/endpoints/charts/hashtag.ts diff --git a/src/server/api/endpoints/charts/instance.ts b/packages/backend/src/server/api/endpoints/charts/instance.ts similarity index 100% rename from src/server/api/endpoints/charts/instance.ts rename to packages/backend/src/server/api/endpoints/charts/instance.ts diff --git a/src/server/api/endpoints/charts/network.ts b/packages/backend/src/server/api/endpoints/charts/network.ts similarity index 100% rename from src/server/api/endpoints/charts/network.ts rename to packages/backend/src/server/api/endpoints/charts/network.ts diff --git a/src/server/api/endpoints/charts/notes.ts b/packages/backend/src/server/api/endpoints/charts/notes.ts similarity index 100% rename from src/server/api/endpoints/charts/notes.ts rename to packages/backend/src/server/api/endpoints/charts/notes.ts diff --git a/src/server/api/endpoints/charts/user/drive.ts b/packages/backend/src/server/api/endpoints/charts/user/drive.ts similarity index 100% rename from src/server/api/endpoints/charts/user/drive.ts rename to packages/backend/src/server/api/endpoints/charts/user/drive.ts diff --git a/src/server/api/endpoints/charts/user/following.ts b/packages/backend/src/server/api/endpoints/charts/user/following.ts similarity index 100% rename from src/server/api/endpoints/charts/user/following.ts rename to packages/backend/src/server/api/endpoints/charts/user/following.ts diff --git a/src/server/api/endpoints/charts/user/notes.ts b/packages/backend/src/server/api/endpoints/charts/user/notes.ts similarity index 100% rename from src/server/api/endpoints/charts/user/notes.ts rename to packages/backend/src/server/api/endpoints/charts/user/notes.ts diff --git a/src/server/api/endpoints/charts/user/reactions.ts b/packages/backend/src/server/api/endpoints/charts/user/reactions.ts similarity index 100% rename from src/server/api/endpoints/charts/user/reactions.ts rename to packages/backend/src/server/api/endpoints/charts/user/reactions.ts diff --git a/src/server/api/endpoints/charts/users.ts b/packages/backend/src/server/api/endpoints/charts/users.ts similarity index 100% rename from src/server/api/endpoints/charts/users.ts rename to packages/backend/src/server/api/endpoints/charts/users.ts diff --git a/src/server/api/endpoints/clips/add-note.ts b/packages/backend/src/server/api/endpoints/clips/add-note.ts similarity index 100% rename from src/server/api/endpoints/clips/add-note.ts rename to packages/backend/src/server/api/endpoints/clips/add-note.ts diff --git a/src/server/api/endpoints/clips/create.ts b/packages/backend/src/server/api/endpoints/clips/create.ts similarity index 100% rename from src/server/api/endpoints/clips/create.ts rename to packages/backend/src/server/api/endpoints/clips/create.ts diff --git a/src/server/api/endpoints/clips/delete.ts b/packages/backend/src/server/api/endpoints/clips/delete.ts similarity index 100% rename from src/server/api/endpoints/clips/delete.ts rename to packages/backend/src/server/api/endpoints/clips/delete.ts diff --git a/src/server/api/endpoints/clips/list.ts b/packages/backend/src/server/api/endpoints/clips/list.ts similarity index 100% rename from src/server/api/endpoints/clips/list.ts rename to packages/backend/src/server/api/endpoints/clips/list.ts diff --git a/src/server/api/endpoints/clips/notes.ts b/packages/backend/src/server/api/endpoints/clips/notes.ts similarity index 100% rename from src/server/api/endpoints/clips/notes.ts rename to packages/backend/src/server/api/endpoints/clips/notes.ts diff --git a/src/server/api/endpoints/clips/show.ts b/packages/backend/src/server/api/endpoints/clips/show.ts similarity index 100% rename from src/server/api/endpoints/clips/show.ts rename to packages/backend/src/server/api/endpoints/clips/show.ts diff --git a/src/server/api/endpoints/clips/update.ts b/packages/backend/src/server/api/endpoints/clips/update.ts similarity index 100% rename from src/server/api/endpoints/clips/update.ts rename to packages/backend/src/server/api/endpoints/clips/update.ts diff --git a/src/server/api/endpoints/drive.ts b/packages/backend/src/server/api/endpoints/drive.ts similarity index 100% rename from src/server/api/endpoints/drive.ts rename to packages/backend/src/server/api/endpoints/drive.ts diff --git a/src/server/api/endpoints/drive/files.ts b/packages/backend/src/server/api/endpoints/drive/files.ts similarity index 100% rename from src/server/api/endpoints/drive/files.ts rename to packages/backend/src/server/api/endpoints/drive/files.ts diff --git a/src/server/api/endpoints/drive/files/attached-notes.ts b/packages/backend/src/server/api/endpoints/drive/files/attached-notes.ts similarity index 100% rename from src/server/api/endpoints/drive/files/attached-notes.ts rename to packages/backend/src/server/api/endpoints/drive/files/attached-notes.ts diff --git a/src/server/api/endpoints/drive/files/check-existence.ts b/packages/backend/src/server/api/endpoints/drive/files/check-existence.ts similarity index 100% rename from src/server/api/endpoints/drive/files/check-existence.ts rename to packages/backend/src/server/api/endpoints/drive/files/check-existence.ts diff --git a/packages/backend/src/server/api/endpoints/drive/files/create.ts b/packages/backend/src/server/api/endpoints/drive/files/create.ts new file mode 100644 index 000000000..89755d949 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/drive/files/create.ts @@ -0,0 +1,89 @@ +import ms from 'ms'; +import $ from 'cafy'; +import { ID } from '@/misc/cafy-id'; +import create from '@/services/drive/add-file'; +import define from '../../../define'; +import { apiLogger } from '../../../logger'; +import { ApiError } from '../../../error'; +import { DriveFiles } from '@/models/index'; + +export const meta = { + tags: ['drive'], + + requireCredential: true as const, + + limit: { + duration: ms('1hour'), + max: 120 + }, + + requireFile: true, + + kind: 'write:drive', + + params: { + folderId: { + validator: $.optional.nullable.type(ID), + default: null, + }, + + name: { + validator: $.optional.nullable.str, + default: null, + }, + + isSensitive: { + validator: $.optional.either($.bool, $.str), + default: false, + transform: (v: any): boolean => v === true || v === 'true', + }, + + force: { + validator: $.optional.either($.bool, $.str), + default: false, + transform: (v: any): boolean => v === true || v === 'true', + } + }, + + res: { + type: 'object' as const, + optional: false as const, nullable: false as const, + ref: 'DriveFile', + }, + + errors: { + invalidFileName: { + message: 'Invalid file name.', + code: 'INVALID_FILE_NAME', + id: 'f449b209-0c60-4e51-84d5-29486263bfd4' + } + } +}; + +export default define(meta, async (ps, user, _, file, cleanup) => { + // Get 'name' parameter + let name = ps.name || file.originalname; + if (name !== undefined && name !== null) { + name = name.trim(); + if (name.length === 0) { + name = null; + } else if (name === 'blob') { + name = null; + } else if (!DriveFiles.validateFileName(name)) { + throw new ApiError(meta.errors.invalidFileName); + } + } else { + name = null; + } + + try { + // Create file + const driveFile = await create(user, file.path, name, null, ps.folderId, ps.force, false, null, null, ps.isSensitive); + return await DriveFiles.pack(driveFile, { self: true }); + } catch (e) { + apiLogger.error(e); + throw new ApiError(); + } finally { + cleanup!(); + } +}); diff --git a/src/server/api/endpoints/drive/files/delete.ts b/packages/backend/src/server/api/endpoints/drive/files/delete.ts similarity index 100% rename from src/server/api/endpoints/drive/files/delete.ts rename to packages/backend/src/server/api/endpoints/drive/files/delete.ts diff --git a/src/server/api/endpoints/drive/files/find-by-hash.ts b/packages/backend/src/server/api/endpoints/drive/files/find-by-hash.ts similarity index 100% rename from src/server/api/endpoints/drive/files/find-by-hash.ts rename to packages/backend/src/server/api/endpoints/drive/files/find-by-hash.ts diff --git a/src/server/api/endpoints/drive/files/find.ts b/packages/backend/src/server/api/endpoints/drive/files/find.ts similarity index 100% rename from src/server/api/endpoints/drive/files/find.ts rename to packages/backend/src/server/api/endpoints/drive/files/find.ts diff --git a/src/server/api/endpoints/drive/files/show.ts b/packages/backend/src/server/api/endpoints/drive/files/show.ts similarity index 100% rename from src/server/api/endpoints/drive/files/show.ts rename to packages/backend/src/server/api/endpoints/drive/files/show.ts diff --git a/src/server/api/endpoints/drive/files/update.ts b/packages/backend/src/server/api/endpoints/drive/files/update.ts similarity index 100% rename from src/server/api/endpoints/drive/files/update.ts rename to packages/backend/src/server/api/endpoints/drive/files/update.ts diff --git a/packages/backend/src/server/api/endpoints/drive/files/upload-from-url.ts b/packages/backend/src/server/api/endpoints/drive/files/upload-from-url.ts new file mode 100644 index 000000000..adb5126fb --- /dev/null +++ b/packages/backend/src/server/api/endpoints/drive/files/upload-from-url.ts @@ -0,0 +1,64 @@ +import $ from 'cafy'; +import { ID } from '@/misc/cafy-id'; +import ms from 'ms'; +import uploadFromUrl from '@/services/drive/upload-from-url'; +import define from '../../../define'; +import { DriveFiles } from '@/models/index'; +import { publishMainStream } from '@/services/stream'; +import { DB_MAX_IMAGE_COMMENT_LENGTH } from '@/misc/hard-limits'; + +export const meta = { + tags: ['drive'], + + limit: { + duration: ms('1hour'), + max: 60 + }, + + requireCredential: true as const, + + kind: 'write:drive', + + params: { + url: { + // TODO: Validate this url + validator: $.str, + }, + + folderId: { + validator: $.optional.nullable.type(ID), + default: null, + }, + + isSensitive: { + validator: $.optional.bool, + default: false, + }, + + comment: { + validator: $.optional.nullable.str.max(DB_MAX_IMAGE_COMMENT_LENGTH), + default: null, + }, + + marker: { + validator: $.optional.nullable.str, + default: null, + }, + + force: { + validator: $.optional.bool, + default: false, + } + } +}; + +export default define(meta, async (ps, user) => { + uploadFromUrl(ps.url, user, ps.folderId, null, ps.isSensitive, ps.force, false, ps.comment).then(file => { + DriveFiles.pack(file, { self: true }).then(packedFile => { + publishMainStream(user.id, 'urlUploadFinished', { + marker: ps.marker, + file: packedFile + }); + }); + }); +}); diff --git a/src/server/api/endpoints/drive/folders.ts b/packages/backend/src/server/api/endpoints/drive/folders.ts similarity index 100% rename from src/server/api/endpoints/drive/folders.ts rename to packages/backend/src/server/api/endpoints/drive/folders.ts diff --git a/src/server/api/endpoints/drive/folders/create.ts b/packages/backend/src/server/api/endpoints/drive/folders/create.ts similarity index 100% rename from src/server/api/endpoints/drive/folders/create.ts rename to packages/backend/src/server/api/endpoints/drive/folders/create.ts diff --git a/src/server/api/endpoints/drive/folders/delete.ts b/packages/backend/src/server/api/endpoints/drive/folders/delete.ts similarity index 100% rename from src/server/api/endpoints/drive/folders/delete.ts rename to packages/backend/src/server/api/endpoints/drive/folders/delete.ts diff --git a/src/server/api/endpoints/drive/folders/find.ts b/packages/backend/src/server/api/endpoints/drive/folders/find.ts similarity index 100% rename from src/server/api/endpoints/drive/folders/find.ts rename to packages/backend/src/server/api/endpoints/drive/folders/find.ts diff --git a/src/server/api/endpoints/drive/folders/show.ts b/packages/backend/src/server/api/endpoints/drive/folders/show.ts similarity index 100% rename from src/server/api/endpoints/drive/folders/show.ts rename to packages/backend/src/server/api/endpoints/drive/folders/show.ts diff --git a/src/server/api/endpoints/drive/folders/update.ts b/packages/backend/src/server/api/endpoints/drive/folders/update.ts similarity index 100% rename from src/server/api/endpoints/drive/folders/update.ts rename to packages/backend/src/server/api/endpoints/drive/folders/update.ts diff --git a/src/server/api/endpoints/drive/stream.ts b/packages/backend/src/server/api/endpoints/drive/stream.ts similarity index 100% rename from src/server/api/endpoints/drive/stream.ts rename to packages/backend/src/server/api/endpoints/drive/stream.ts diff --git a/packages/backend/src/server/api/endpoints/email-address/available.ts b/packages/backend/src/server/api/endpoints/email-address/available.ts new file mode 100644 index 000000000..f6fccd59b --- /dev/null +++ b/packages/backend/src/server/api/endpoints/email-address/available.ts @@ -0,0 +1,34 @@ +import $ from 'cafy'; +import define from '../../define'; +import { validateEmailForAccount } from '@/services/validate-email-for-account'; + +export const meta = { + tags: ['users'], + + requireCredential: false as const, + + params: { + emailAddress: { + validator: $.str + } + }, + + res: { + type: 'object' as const, + optional: false as const, nullable: false as const, + properties: { + available: { + type: 'boolean' as const, + optional: false as const, nullable: false as const, + }, + reason: { + type: 'string' as const, + optional: false as const, nullable: true as const, + }, + } + } +}; + +export default define(meta, async (ps) => { + return await validateEmailForAccount(ps.emailAddress); +}); diff --git a/src/server/api/endpoints/endpoint.ts b/packages/backend/src/server/api/endpoints/endpoint.ts similarity index 100% rename from src/server/api/endpoints/endpoint.ts rename to packages/backend/src/server/api/endpoints/endpoint.ts diff --git a/src/server/api/endpoints/endpoints.ts b/packages/backend/src/server/api/endpoints/endpoints.ts similarity index 100% rename from src/server/api/endpoints/endpoints.ts rename to packages/backend/src/server/api/endpoints/endpoints.ts diff --git a/src/server/api/endpoints/federation/dns.ts b/packages/backend/src/server/api/endpoints/federation/dns.ts similarity index 100% rename from src/server/api/endpoints/federation/dns.ts rename to packages/backend/src/server/api/endpoints/federation/dns.ts diff --git a/src/server/api/endpoints/federation/followers.ts b/packages/backend/src/server/api/endpoints/federation/followers.ts similarity index 100% rename from src/server/api/endpoints/federation/followers.ts rename to packages/backend/src/server/api/endpoints/federation/followers.ts diff --git a/src/server/api/endpoints/federation/following.ts b/packages/backend/src/server/api/endpoints/federation/following.ts similarity index 100% rename from src/server/api/endpoints/federation/following.ts rename to packages/backend/src/server/api/endpoints/federation/following.ts diff --git a/src/server/api/endpoints/federation/instances.ts b/packages/backend/src/server/api/endpoints/federation/instances.ts similarity index 100% rename from src/server/api/endpoints/federation/instances.ts rename to packages/backend/src/server/api/endpoints/federation/instances.ts diff --git a/src/server/api/endpoints/federation/show-instance.ts b/packages/backend/src/server/api/endpoints/federation/show-instance.ts similarity index 100% rename from src/server/api/endpoints/federation/show-instance.ts rename to packages/backend/src/server/api/endpoints/federation/show-instance.ts diff --git a/src/server/api/endpoints/federation/update-remote-user.ts b/packages/backend/src/server/api/endpoints/federation/update-remote-user.ts similarity index 100% rename from src/server/api/endpoints/federation/update-remote-user.ts rename to packages/backend/src/server/api/endpoints/federation/update-remote-user.ts diff --git a/src/server/api/endpoints/federation/users.ts b/packages/backend/src/server/api/endpoints/federation/users.ts similarity index 100% rename from src/server/api/endpoints/federation/users.ts rename to packages/backend/src/server/api/endpoints/federation/users.ts diff --git a/packages/backend/src/server/api/endpoints/following/create.ts b/packages/backend/src/server/api/endpoints/following/create.ts new file mode 100644 index 000000000..92e86bf6b --- /dev/null +++ b/packages/backend/src/server/api/endpoints/following/create.ts @@ -0,0 +1,100 @@ +import $ from 'cafy'; +import { ID } from '@/misc/cafy-id'; +import ms from 'ms'; +import create from '@/services/following/create'; +import define from '../../define'; +import { ApiError } from '../../error'; +import { getUser } from '../../common/getters'; +import { Followings, Users } from '@/models/index'; + +export const meta = { + tags: ['following', 'users'], + + limit: { + duration: ms('1hour'), + max: 100 + }, + + requireCredential: true as const, + + kind: 'write:following', + + params: { + userId: { + validator: $.type(ID), + } + }, + + errors: { + noSuchUser: { + message: 'No such user.', + code: 'NO_SUCH_USER', + id: 'fcd2eef9-a9b2-4c4f-8624-038099e90aa5' + }, + + followeeIsYourself: { + message: 'Followee is yourself.', + code: 'FOLLOWEE_IS_YOURSELF', + id: '26fbe7bb-a331-4857-af17-205b426669a9' + }, + + alreadyFollowing: { + message: 'You are already following that user.', + code: 'ALREADY_FOLLOWING', + id: '35387507-38c7-4cb9-9197-300b93783fa0' + }, + + blocking: { + message: 'You are blocking that user.', + code: 'BLOCKING', + id: '4e2206ec-aa4f-4960-b865-6c23ac38e2d9' + }, + + blocked: { + message: 'You are blocked by that user.', + code: 'BLOCKED', + id: 'c4ab57cc-4e41-45e9-bfd9-584f61e35ce0' + }, + }, + + res: { + type: 'object' as const, + optional: false as const, nullable: false as const, + ref: 'User' + } +}; + +export default define(meta, async (ps, user) => { + const follower = user; + + // 自分自身 + if (user.id === ps.userId) { + throw new ApiError(meta.errors.followeeIsYourself); + } + + // Get followee + const followee = await getUser(ps.userId).catch(e => { + if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser); + throw e; + }); + + // Check if already following + const exist = await Followings.findOne({ + followerId: follower.id, + followeeId: followee.id + }); + + if (exist != null) { + throw new ApiError(meta.errors.alreadyFollowing); + } + + 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); + throw e; + } + + return await Users.pack(followee.id, user); +}); diff --git a/packages/backend/src/server/api/endpoints/following/delete.ts b/packages/backend/src/server/api/endpoints/following/delete.ts new file mode 100644 index 000000000..030d30c9b --- /dev/null +++ b/packages/backend/src/server/api/endpoints/following/delete.ts @@ -0,0 +1,82 @@ +import $ from 'cafy'; +import { ID } from '@/misc/cafy-id'; +import ms from 'ms'; +import deleteFollowing from '@/services/following/delete'; +import define from '../../define'; +import { ApiError } from '../../error'; +import { getUser } from '../../common/getters'; +import { Followings, Users } from '@/models/index'; + +export const meta = { + tags: ['following', 'users'], + + limit: { + duration: ms('1hour'), + max: 100 + }, + + requireCredential: true as const, + + kind: 'write:following', + + params: { + userId: { + validator: $.type(ID), + } + }, + + errors: { + noSuchUser: { + message: 'No such user.', + code: 'NO_SUCH_USER', + id: '5b12c78d-2b28-4dca-99d2-f56139b42ff8' + }, + + followeeIsYourself: { + message: 'Followee is yourself.', + code: 'FOLLOWEE_IS_YOURSELF', + id: 'd9e400b9-36b0-4808-b1d8-79e707f1296c' + }, + + notFollowing: { + message: 'You are not following that user.', + code: 'NOT_FOLLOWING', + id: '5dbf82f5-c92b-40b1-87d1-6c8c0741fd09' + }, + }, + + res: { + type: 'object' as const, + optional: false as const, nullable: false as const, + ref: 'User' + } +}; + +export default define(meta, async (ps, user) => { + const follower = user; + + // Check if the followee is yourself + if (user.id === ps.userId) { + throw new ApiError(meta.errors.followeeIsYourself); + } + + // Get followee + const followee = await getUser(ps.userId).catch(e => { + if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser); + throw e; + }); + + // Check not following + const exist = await Followings.findOne({ + followerId: follower.id, + followeeId: followee.id + }); + + if (exist == null) { + throw new ApiError(meta.errors.notFollowing); + } + + await deleteFollowing(follower, followee); + + return await Users.pack(followee.id, user); +}); diff --git a/src/server/api/endpoints/following/requests/accept.ts b/packages/backend/src/server/api/endpoints/following/requests/accept.ts similarity index 100% rename from src/server/api/endpoints/following/requests/accept.ts rename to packages/backend/src/server/api/endpoints/following/requests/accept.ts diff --git a/src/server/api/endpoints/following/requests/cancel.ts b/packages/backend/src/server/api/endpoints/following/requests/cancel.ts similarity index 100% rename from src/server/api/endpoints/following/requests/cancel.ts rename to packages/backend/src/server/api/endpoints/following/requests/cancel.ts diff --git a/src/server/api/endpoints/following/requests/list.ts b/packages/backend/src/server/api/endpoints/following/requests/list.ts similarity index 100% rename from src/server/api/endpoints/following/requests/list.ts rename to packages/backend/src/server/api/endpoints/following/requests/list.ts diff --git a/src/server/api/endpoints/following/requests/reject.ts b/packages/backend/src/server/api/endpoints/following/requests/reject.ts similarity index 100% rename from src/server/api/endpoints/following/requests/reject.ts rename to packages/backend/src/server/api/endpoints/following/requests/reject.ts diff --git a/src/server/api/endpoints/gallery/featured.ts b/packages/backend/src/server/api/endpoints/gallery/featured.ts similarity index 100% rename from src/server/api/endpoints/gallery/featured.ts rename to packages/backend/src/server/api/endpoints/gallery/featured.ts diff --git a/src/server/api/endpoints/gallery/popular.ts b/packages/backend/src/server/api/endpoints/gallery/popular.ts similarity index 100% rename from src/server/api/endpoints/gallery/popular.ts rename to packages/backend/src/server/api/endpoints/gallery/popular.ts diff --git a/src/server/api/endpoints/gallery/posts.ts b/packages/backend/src/server/api/endpoints/gallery/posts.ts similarity index 100% rename from src/server/api/endpoints/gallery/posts.ts rename to packages/backend/src/server/api/endpoints/gallery/posts.ts diff --git a/packages/backend/src/server/api/endpoints/gallery/posts/create.ts b/packages/backend/src/server/api/endpoints/gallery/posts/create.ts new file mode 100644 index 000000000..34af72695 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/gallery/posts/create.ts @@ -0,0 +1,77 @@ +import $ from 'cafy'; +import ms from 'ms'; +import define from '../../../define'; +import { ID } from '../../../../../misc/cafy-id'; +import { DriveFiles, GalleryPosts } from '@/models/index'; +import { genId } from '../../../../../misc/gen-id'; +import { GalleryPost } from '@/models/entities/gallery-post'; +import { ApiError } from '../../../error'; +import { DriveFile } from '@/models/entities/drive-file'; + +export const meta = { + tags: ['gallery'], + + requireCredential: true as const, + + kind: 'write:gallery', + + limit: { + duration: ms('1hour'), + max: 300 + }, + + params: { + title: { + validator: $.str.min(1), + }, + + description: { + validator: $.optional.nullable.str, + }, + + fileIds: { + validator: $.arr($.type(ID)).unique().range(1, 32), + }, + + isSensitive: { + validator: $.optional.bool, + default: false, + }, + }, + + res: { + type: 'object' as const, + optional: false as const, nullable: false as const, + ref: 'GalleryPost', + }, + + errors: { + + } +}; + +export default define(meta, async (ps, user) => { + const files = (await Promise.all(ps.fileIds.map(fileId => + DriveFiles.findOne({ + id: fileId, + userId: user.id + }) + ))).filter((file): file is DriveFile => file != null); + + if (files.length === 0) { + throw new Error(); + } + + const post = await GalleryPosts.insert(new GalleryPost({ + id: genId(), + createdAt: new Date(), + updatedAt: new Date(), + title: ps.title, + description: ps.description, + userId: user.id, + isSensitive: ps.isSensitive, + fileIds: files.map(file => file.id) + })).then(x => GalleryPosts.findOneOrFail(x.identifiers[0])); + + return await GalleryPosts.pack(post, user); +}); diff --git a/src/server/api/endpoints/gallery/posts/delete.ts b/packages/backend/src/server/api/endpoints/gallery/posts/delete.ts similarity index 100% rename from src/server/api/endpoints/gallery/posts/delete.ts rename to packages/backend/src/server/api/endpoints/gallery/posts/delete.ts diff --git a/src/server/api/endpoints/gallery/posts/like.ts b/packages/backend/src/server/api/endpoints/gallery/posts/like.ts similarity index 100% rename from src/server/api/endpoints/gallery/posts/like.ts rename to packages/backend/src/server/api/endpoints/gallery/posts/like.ts diff --git a/src/server/api/endpoints/gallery/posts/show.ts b/packages/backend/src/server/api/endpoints/gallery/posts/show.ts similarity index 100% rename from src/server/api/endpoints/gallery/posts/show.ts rename to packages/backend/src/server/api/endpoints/gallery/posts/show.ts diff --git a/src/server/api/endpoints/gallery/posts/unlike.ts b/packages/backend/src/server/api/endpoints/gallery/posts/unlike.ts similarity index 100% rename from src/server/api/endpoints/gallery/posts/unlike.ts rename to packages/backend/src/server/api/endpoints/gallery/posts/unlike.ts diff --git a/packages/backend/src/server/api/endpoints/gallery/posts/update.ts b/packages/backend/src/server/api/endpoints/gallery/posts/update.ts new file mode 100644 index 000000000..f94606acf --- /dev/null +++ b/packages/backend/src/server/api/endpoints/gallery/posts/update.ts @@ -0,0 +1,82 @@ +import $ from 'cafy'; +import ms from 'ms'; +import define from '../../../define'; +import { ID } from '../../../../../misc/cafy-id'; +import { DriveFiles, GalleryPosts } from '@/models/index'; +import { GalleryPost } from '@/models/entities/gallery-post'; +import { ApiError } from '../../../error'; +import { DriveFile } from '@/models/entities/drive-file'; + +export const meta = { + tags: ['gallery'], + + requireCredential: true as const, + + kind: 'write:gallery', + + limit: { + duration: ms('1hour'), + max: 300 + }, + + params: { + postId: { + validator: $.type(ID), + }, + + title: { + validator: $.str.min(1), + }, + + description: { + validator: $.optional.nullable.str, + }, + + fileIds: { + validator: $.arr($.type(ID)).unique().range(1, 32), + }, + + isSensitive: { + validator: $.optional.bool, + default: false, + }, + }, + + res: { + type: 'object' as const, + optional: false as const, nullable: false as const, + ref: 'GalleryPost', + }, + + errors: { + + } +}; + +export default define(meta, async (ps, user) => { + const files = (await Promise.all(ps.fileIds.map(fileId => + DriveFiles.findOne({ + id: fileId, + userId: user.id + }) + ))).filter((file): file is DriveFile => file != null); + + if (files.length === 0) { + throw new Error(); + } + + await GalleryPosts.update({ + id: ps.postId, + userId: user.id, + }, { + updatedAt: new Date(), + title: ps.title, + description: ps.description, + isSensitive: ps.isSensitive, + fileIds: files.map(file => file.id) + }); + + const post = await GalleryPosts.findOneOrFail(ps.postId); + + return await GalleryPosts.pack(post, user); +}); diff --git a/src/server/api/endpoints/games/reversi/games.ts b/packages/backend/src/server/api/endpoints/games/reversi/games.ts similarity index 100% rename from src/server/api/endpoints/games/reversi/games.ts rename to packages/backend/src/server/api/endpoints/games/reversi/games.ts diff --git a/src/server/api/endpoints/games/reversi/games/show.ts b/packages/backend/src/server/api/endpoints/games/reversi/games/show.ts similarity index 100% rename from src/server/api/endpoints/games/reversi/games/show.ts rename to packages/backend/src/server/api/endpoints/games/reversi/games/show.ts diff --git a/src/server/api/endpoints/games/reversi/games/surrender.ts b/packages/backend/src/server/api/endpoints/games/reversi/games/surrender.ts similarity index 100% rename from src/server/api/endpoints/games/reversi/games/surrender.ts rename to packages/backend/src/server/api/endpoints/games/reversi/games/surrender.ts diff --git a/src/server/api/endpoints/games/reversi/invitations.ts b/packages/backend/src/server/api/endpoints/games/reversi/invitations.ts similarity index 100% rename from src/server/api/endpoints/games/reversi/invitations.ts rename to packages/backend/src/server/api/endpoints/games/reversi/invitations.ts diff --git a/src/server/api/endpoints/games/reversi/match.ts b/packages/backend/src/server/api/endpoints/games/reversi/match.ts similarity index 100% rename from src/server/api/endpoints/games/reversi/match.ts rename to packages/backend/src/server/api/endpoints/games/reversi/match.ts diff --git a/src/server/api/endpoints/games/reversi/match/cancel.ts b/packages/backend/src/server/api/endpoints/games/reversi/match/cancel.ts similarity index 100% rename from src/server/api/endpoints/games/reversi/match/cancel.ts rename to packages/backend/src/server/api/endpoints/games/reversi/match/cancel.ts diff --git a/src/server/api/endpoints/get-online-users-count.ts b/packages/backend/src/server/api/endpoints/get-online-users-count.ts similarity index 100% rename from src/server/api/endpoints/get-online-users-count.ts rename to packages/backend/src/server/api/endpoints/get-online-users-count.ts diff --git a/src/server/api/endpoints/hashtags/list.ts b/packages/backend/src/server/api/endpoints/hashtags/list.ts similarity index 100% rename from src/server/api/endpoints/hashtags/list.ts rename to packages/backend/src/server/api/endpoints/hashtags/list.ts diff --git a/src/server/api/endpoints/hashtags/search.ts b/packages/backend/src/server/api/endpoints/hashtags/search.ts similarity index 100% rename from src/server/api/endpoints/hashtags/search.ts rename to packages/backend/src/server/api/endpoints/hashtags/search.ts diff --git a/src/server/api/endpoints/hashtags/show.ts b/packages/backend/src/server/api/endpoints/hashtags/show.ts similarity index 100% rename from src/server/api/endpoints/hashtags/show.ts rename to packages/backend/src/server/api/endpoints/hashtags/show.ts diff --git a/src/server/api/endpoints/hashtags/trend.ts b/packages/backend/src/server/api/endpoints/hashtags/trend.ts similarity index 100% rename from src/server/api/endpoints/hashtags/trend.ts rename to packages/backend/src/server/api/endpoints/hashtags/trend.ts diff --git a/src/server/api/endpoints/hashtags/users.ts b/packages/backend/src/server/api/endpoints/hashtags/users.ts similarity index 100% rename from src/server/api/endpoints/hashtags/users.ts rename to packages/backend/src/server/api/endpoints/hashtags/users.ts diff --git a/src/server/api/endpoints/i.ts b/packages/backend/src/server/api/endpoints/i.ts similarity index 100% rename from src/server/api/endpoints/i.ts rename to packages/backend/src/server/api/endpoints/i.ts diff --git a/src/server/api/endpoints/i/2fa/done.ts b/packages/backend/src/server/api/endpoints/i/2fa/done.ts similarity index 100% rename from src/server/api/endpoints/i/2fa/done.ts rename to packages/backend/src/server/api/endpoints/i/2fa/done.ts diff --git a/packages/backend/src/server/api/endpoints/i/2fa/key-done.ts b/packages/backend/src/server/api/endpoints/i/2fa/key-done.ts new file mode 100644 index 000000000..e06d0a9f6 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/i/2fa/key-done.ts @@ -0,0 +1,150 @@ +import $ from 'cafy'; +import * as bcrypt from 'bcryptjs'; +import { promisify } from 'util'; +import * as cbor from 'cbor'; +import define from '../../../define'; +import { + UserProfiles, + UserSecurityKeys, + AttestationChallenges, + Users +} from '@/models/index'; +import config from '@/config/index'; +import { procedures, hash } from '../../../2fa'; +import { publishMainStream } from '@/services/stream'; + +const cborDecodeFirst = promisify(cbor.decodeFirst) as any; + +export const meta = { + requireCredential: true as const, + + secure: true, + + params: { + clientDataJSON: { + validator: $.str + }, + attestationObject: { + validator: $.str + }, + password: { + validator: $.str + }, + challengeId: { + validator: $.str + }, + name: { + validator: $.str + } + } +}; + +const rpIdHashReal = hash(Buffer.from(config.hostname, 'utf-8')); + +export default define(meta, async (ps, user) => { + const profile = await UserProfiles.findOneOrFail(user.id); + + // Compare password + const same = await bcrypt.compare(ps.password, profile.password!); + + if (!same) { + throw new Error('incorrect password'); + } + + if (!profile.twoFactorEnabled) { + throw new Error('2fa not enabled'); + } + + const clientData = JSON.parse(ps.clientDataJSON); + + if (clientData.type != 'webauthn.create') { + throw new Error('not a creation attestation'); + } + if (clientData.origin != config.scheme + '://' + config.host) { + throw new Error('origin mismatch'); + } + + const clientDataJSONHash = hash(Buffer.from(ps.clientDataJSON, 'utf-8')); + + const attestation = await cborDecodeFirst(ps.attestationObject); + + const rpIdHash = attestation.authData.slice(0, 32); + if (!rpIdHashReal.equals(rpIdHash)) { + throw new Error('rpIdHash mismatch'); + } + + const flags = attestation.authData[32]; + + // eslint:disable-next-line:no-bitwise + if (!(flags & 1)) { + throw new Error('user not present'); + } + + const authData = Buffer.from(attestation.authData); + const credentialIdLength = authData.readUInt16BE(53); + const credentialId = authData.slice(55, 55 + credentialIdLength); + const publicKeyData = authData.slice(55 + credentialIdLength); + const publicKey: Map = await cborDecodeFirst(publicKeyData); + if (publicKey.get(3) != -7) { + throw new Error('alg mismatch'); + } + + if (!(procedures as any)[attestation.fmt]) { + throw new Error('unsupported fmt'); + } + + const verificationData = (procedures as any)[attestation.fmt].verify({ + attStmt: attestation.attStmt, + authenticatorData: authData, + clientDataHash: clientDataJSONHash, + credentialId, + publicKey, + rpIdHash + }); + if (!verificationData.valid) throw new Error('signature invalid'); + + const attestationChallenge = await AttestationChallenges.findOne({ + userId: user.id, + id: ps.challengeId, + registrationChallenge: true, + challenge: hash(clientData.challenge).toString('hex') + }); + + if (!attestationChallenge) { + throw new Error('non-existent challenge'); + } + + await AttestationChallenges.delete({ + userId: user.id, + id: ps.challengeId + }); + + // Expired challenge (> 5min old) + if ( + new Date().getTime() - attestationChallenge.createdAt.getTime() >= + 5 * 60 * 1000 + ) { + throw new Error('expired challenge'); + } + + const credentialIdString = credentialId.toString('hex'); + + await UserSecurityKeys.save({ + userId: user.id, + id: credentialIdString, + lastUsed: new Date(), + name: ps.name, + publicKey: verificationData.publicKey.toString('hex') + }); + + // Publish meUpdated event + publishMainStream(user.id, 'meUpdated', await Users.pack(user.id, user, { + detail: true, + includeSecrets: true + })); + + return { + id: credentialIdString, + name: ps.name + }; +}); diff --git a/src/server/api/endpoints/i/2fa/password-less.ts b/packages/backend/src/server/api/endpoints/i/2fa/password-less.ts similarity index 100% rename from src/server/api/endpoints/i/2fa/password-less.ts rename to packages/backend/src/server/api/endpoints/i/2fa/password-less.ts diff --git a/src/server/api/endpoints/i/2fa/register-key.ts b/packages/backend/src/server/api/endpoints/i/2fa/register-key.ts similarity index 100% rename from src/server/api/endpoints/i/2fa/register-key.ts rename to packages/backend/src/server/api/endpoints/i/2fa/register-key.ts diff --git a/src/server/api/endpoints/i/2fa/register.ts b/packages/backend/src/server/api/endpoints/i/2fa/register.ts similarity index 100% rename from src/server/api/endpoints/i/2fa/register.ts rename to packages/backend/src/server/api/endpoints/i/2fa/register.ts diff --git a/src/server/api/endpoints/i/2fa/remove-key.ts b/packages/backend/src/server/api/endpoints/i/2fa/remove-key.ts similarity index 100% rename from src/server/api/endpoints/i/2fa/remove-key.ts rename to packages/backend/src/server/api/endpoints/i/2fa/remove-key.ts diff --git a/src/server/api/endpoints/i/2fa/unregister.ts b/packages/backend/src/server/api/endpoints/i/2fa/unregister.ts similarity index 100% rename from src/server/api/endpoints/i/2fa/unregister.ts rename to packages/backend/src/server/api/endpoints/i/2fa/unregister.ts diff --git a/src/server/api/endpoints/i/apps.ts b/packages/backend/src/server/api/endpoints/i/apps.ts similarity index 100% rename from src/server/api/endpoints/i/apps.ts rename to packages/backend/src/server/api/endpoints/i/apps.ts diff --git a/src/server/api/endpoints/i/authorized-apps.ts b/packages/backend/src/server/api/endpoints/i/authorized-apps.ts similarity index 100% rename from src/server/api/endpoints/i/authorized-apps.ts rename to packages/backend/src/server/api/endpoints/i/authorized-apps.ts diff --git a/src/server/api/endpoints/i/change-password.ts b/packages/backend/src/server/api/endpoints/i/change-password.ts similarity index 100% rename from src/server/api/endpoints/i/change-password.ts rename to packages/backend/src/server/api/endpoints/i/change-password.ts diff --git a/src/server/api/endpoints/i/delete-account.ts b/packages/backend/src/server/api/endpoints/i/delete-account.ts similarity index 100% rename from src/server/api/endpoints/i/delete-account.ts rename to packages/backend/src/server/api/endpoints/i/delete-account.ts diff --git a/packages/backend/src/server/api/endpoints/i/export-blocking.ts b/packages/backend/src/server/api/endpoints/i/export-blocking.ts new file mode 100644 index 000000000..e276ecf38 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/i/export-blocking.ts @@ -0,0 +1,16 @@ +import define from '../../define'; +import { createExportBlockingJob } from '@/queue/index'; +import ms from 'ms'; + +export const meta = { + secure: true, + requireCredential: true as const, + limit: { + duration: ms('1hour'), + max: 1, + }, +}; + +export default define(meta, async (ps, user) => { + createExportBlockingJob(user); +}); diff --git a/packages/backend/src/server/api/endpoints/i/export-following.ts b/packages/backend/src/server/api/endpoints/i/export-following.ts new file mode 100644 index 000000000..a35116111 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/i/export-following.ts @@ -0,0 +1,16 @@ +import define from '../../define'; +import { createExportFollowingJob } from '@/queue/index'; +import ms from 'ms'; + +export const meta = { + secure: true, + requireCredential: true as const, + limit: { + duration: ms('1hour'), + max: 1, + }, +}; + +export default define(meta, async (ps, user) => { + createExportFollowingJob(user); +}); diff --git a/packages/backend/src/server/api/endpoints/i/export-mute.ts b/packages/backend/src/server/api/endpoints/i/export-mute.ts new file mode 100644 index 000000000..b176c7ee8 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/i/export-mute.ts @@ -0,0 +1,16 @@ +import define from '../../define'; +import { createExportMuteJob } from '@/queue/index'; +import ms from 'ms'; + +export const meta = { + secure: true, + requireCredential: true as const, + limit: { + duration: ms('1hour'), + max: 1, + }, +}; + +export default define(meta, async (ps, user) => { + createExportMuteJob(user); +}); diff --git a/packages/backend/src/server/api/endpoints/i/export-notes.ts b/packages/backend/src/server/api/endpoints/i/export-notes.ts new file mode 100644 index 000000000..8cba04552 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/i/export-notes.ts @@ -0,0 +1,16 @@ +import define from '../../define'; +import { createExportNotesJob } from '@/queue/index'; +import ms from 'ms'; + +export const meta = { + secure: true, + requireCredential: true as const, + limit: { + duration: ms('1day'), + max: 1, + }, +}; + +export default define(meta, async (ps, user) => { + createExportNotesJob(user); +}); diff --git a/packages/backend/src/server/api/endpoints/i/export-user-lists.ts b/packages/backend/src/server/api/endpoints/i/export-user-lists.ts new file mode 100644 index 000000000..44d43c0be --- /dev/null +++ b/packages/backend/src/server/api/endpoints/i/export-user-lists.ts @@ -0,0 +1,16 @@ +import define from '../../define'; +import { createExportUserListsJob } from '@/queue/index'; +import ms from 'ms'; + +export const meta = { + secure: true, + requireCredential: true as const, + limit: { + duration: ms('1min'), + max: 1, + }, +}; + +export default define(meta, async (ps, user) => { + createExportUserListsJob(user); +}); diff --git a/src/server/api/endpoints/i/favorites.ts b/packages/backend/src/server/api/endpoints/i/favorites.ts similarity index 100% rename from src/server/api/endpoints/i/favorites.ts rename to packages/backend/src/server/api/endpoints/i/favorites.ts diff --git a/src/server/api/endpoints/i/gallery/likes.ts b/packages/backend/src/server/api/endpoints/i/gallery/likes.ts similarity index 100% rename from src/server/api/endpoints/i/gallery/likes.ts rename to packages/backend/src/server/api/endpoints/i/gallery/likes.ts diff --git a/src/server/api/endpoints/i/gallery/posts.ts b/packages/backend/src/server/api/endpoints/i/gallery/posts.ts similarity index 100% rename from src/server/api/endpoints/i/gallery/posts.ts rename to packages/backend/src/server/api/endpoints/i/gallery/posts.ts diff --git a/src/server/api/endpoints/i/get-word-muted-notes-count.ts b/packages/backend/src/server/api/endpoints/i/get-word-muted-notes-count.ts similarity index 100% rename from src/server/api/endpoints/i/get-word-muted-notes-count.ts rename to packages/backend/src/server/api/endpoints/i/get-word-muted-notes-count.ts diff --git a/packages/backend/src/server/api/endpoints/i/import-blocking.ts b/packages/backend/src/server/api/endpoints/i/import-blocking.ts new file mode 100644 index 000000000..4822bd586 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/i/import-blocking.ts @@ -0,0 +1,60 @@ +import $ from 'cafy'; +import { ID } from '@/misc/cafy-id'; +import define from '../../define'; +import { createImportBlockingJob } from '@/queue/index'; +import ms from 'ms'; +import { ApiError } from '../../error'; +import { DriveFiles } from '@/models/index'; + +export const meta = { + secure: true, + requireCredential: true as const, + + limit: { + duration: ms('1hour'), + max: 1, + }, + + params: { + fileId: { + validator: $.type(ID), + } + }, + + errors: { + noSuchFile: { + message: 'No such file.', + code: 'NO_SUCH_FILE', + id: 'ebb53e5f-6574-9c0c-0b92-7ca6def56d7e' + }, + + unexpectedFileType: { + message: 'We need csv file.', + code: 'UNEXPECTED_FILE_TYPE', + id: 'b6fab7d6-d945-d67c-dfdb-32da1cd12cfe' + }, + + tooBigFile: { + message: 'That file is too big.', + code: 'TOO_BIG_FILE', + id: 'b7fbf0b1-aeef-3b21-29ef-fadd4cb72ccf' + }, + + emptyFile: { + message: 'That file is empty.', + code: 'EMPTY_FILE', + id: '6f3a4dcc-f060-a707-4950-806fbdbe60d6' + }, + } +}; + +export default define(meta, async (ps, user) => { + const file = await DriveFiles.findOne(ps.fileId); + + if (file == null) throw new ApiError(meta.errors.noSuchFile); + //if (!file.type.endsWith('/csv')) throw new ApiError(meta.errors.unexpectedFileType); + if (file.size > 50000) throw new ApiError(meta.errors.tooBigFile); + if (file.size === 0) throw new ApiError(meta.errors.emptyFile); + + createImportBlockingJob(user, file.id); +}); diff --git a/packages/backend/src/server/api/endpoints/i/import-following.ts b/packages/backend/src/server/api/endpoints/i/import-following.ts new file mode 100644 index 000000000..19aa2fa93 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/i/import-following.ts @@ -0,0 +1,59 @@ +import $ from 'cafy'; +import { ID } from '@/misc/cafy-id'; +import define from '../../define'; +import { createImportFollowingJob } from '@/queue/index'; +import ms from 'ms'; +import { ApiError } from '../../error'; +import { DriveFiles } from '@/models/index'; + +export const meta = { + secure: true, + requireCredential: true as const, + limit: { + duration: ms('1hour'), + max: 1, + }, + + params: { + fileId: { + validator: $.type(ID), + } + }, + + errors: { + noSuchFile: { + message: 'No such file.', + code: 'NO_SUCH_FILE', + id: 'b98644cf-a5ac-4277-a502-0b8054a709a3' + }, + + unexpectedFileType: { + message: 'We need csv file.', + code: 'UNEXPECTED_FILE_TYPE', + id: '660f3599-bce0-4f95-9dde-311fd841c183' + }, + + tooBigFile: { + message: 'That file is too big.', + code: 'TOO_BIG_FILE', + id: 'dee9d4ed-ad07-43ed-8b34-b2856398bc60' + }, + + emptyFile: { + message: 'That file is empty.', + code: 'EMPTY_FILE', + id: '31a1b42c-06f7-42ae-8a38-a661c5c9f691' + }, + } +}; + +export default define(meta, async (ps, user) => { + const file = await DriveFiles.findOne(ps.fileId); + + if (file == null) throw new ApiError(meta.errors.noSuchFile); + //if (!file.type.endsWith('/csv')) throw new ApiError(meta.errors.unexpectedFileType); + if (file.size > 50000) throw new ApiError(meta.errors.tooBigFile); + if (file.size === 0) throw new ApiError(meta.errors.emptyFile); + + createImportFollowingJob(user, file.id); +}); diff --git a/packages/backend/src/server/api/endpoints/i/import-muting.ts b/packages/backend/src/server/api/endpoints/i/import-muting.ts new file mode 100644 index 000000000..c474dd718 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/i/import-muting.ts @@ -0,0 +1,60 @@ +import $ from 'cafy'; +import { ID } from '@/misc/cafy-id'; +import define from '../../define'; +import { createImportMutingJob } from '@/queue/index'; +import ms from 'ms'; +import { ApiError } from '../../error'; +import { DriveFiles } from '@/models/index'; + +export const meta = { + secure: true, + requireCredential: true as const, + + limit: { + duration: ms('1hour'), + max: 1, + }, + + params: { + fileId: { + validator: $.type(ID), + } + }, + + errors: { + noSuchFile: { + message: 'No such file.', + code: 'NO_SUCH_FILE', + id: 'e674141e-bd2a-ba85-e616-aefb187c9c2a' + }, + + unexpectedFileType: { + message: 'We need csv file.', + code: 'UNEXPECTED_FILE_TYPE', + id: '568c6e42-c86c-ba09-c004-517f83f9f1a8' + }, + + tooBigFile: { + message: 'That file is too big.', + code: 'TOO_BIG_FILE', + id: '9b4ada6d-d7f7-0472-0713-4f558bd1ec9c' + }, + + emptyFile: { + message: 'That file is empty.', + code: 'EMPTY_FILE', + id: 'd2f12af1-e7b4-feac-86a3-519548f2728e' + }, + } +}; + +export default define(meta, async (ps, user) => { + const file = await DriveFiles.findOne(ps.fileId); + + if (file == null) throw new ApiError(meta.errors.noSuchFile); + //if (!file.type.endsWith('/csv')) throw new ApiError(meta.errors.unexpectedFileType); + if (file.size > 50000) throw new ApiError(meta.errors.tooBigFile); + if (file.size === 0) throw new ApiError(meta.errors.emptyFile); + + createImportMutingJob(user, file.id); +}); diff --git a/packages/backend/src/server/api/endpoints/i/import-user-lists.ts b/packages/backend/src/server/api/endpoints/i/import-user-lists.ts new file mode 100644 index 000000000..ceccdd185 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/i/import-user-lists.ts @@ -0,0 +1,59 @@ +import $ from 'cafy'; +import { ID } from '@/misc/cafy-id'; +import define from '../../define'; +import { createImportUserListsJob } from '@/queue/index'; +import ms from 'ms'; +import { ApiError } from '../../error'; +import { DriveFiles } from '@/models/index'; + +export const meta = { + secure: true, + requireCredential: true as const, + limit: { + duration: ms('1hour'), + max: 1, + }, + + params: { + fileId: { + validator: $.type(ID), + } + }, + + errors: { + noSuchFile: { + message: 'No such file.', + code: 'NO_SUCH_FILE', + id: 'ea9cc34f-c415-4bc6-a6fe-28ac40357049' + }, + + unexpectedFileType: { + message: 'We need csv file.', + code: 'UNEXPECTED_FILE_TYPE', + id: 'a3c9edda-dd9b-4596-be6a-150ef813745c' + }, + + tooBigFile: { + message: 'That file is too big.', + code: 'TOO_BIG_FILE', + id: 'ae6e7a22-971b-4b52-b2be-fc0b9b121fe9' + }, + + emptyFile: { + message: 'That file is empty.', + code: 'EMPTY_FILE', + id: '99efe367-ce6e-4d44-93f8-5fae7b040356' + }, + } +}; + +export default define(meta, async (ps, user) => { + const file = await DriveFiles.findOne(ps.fileId); + + if (file == null) throw new ApiError(meta.errors.noSuchFile); + //if (!file.type.endsWith('/csv')) throw new ApiError(meta.errors.unexpectedFileType); + if (file.size > 30000) throw new ApiError(meta.errors.tooBigFile); + if (file.size === 0) throw new ApiError(meta.errors.emptyFile); + + createImportUserListsJob(user, file.id); +}); diff --git a/src/server/api/endpoints/i/notifications.ts b/packages/backend/src/server/api/endpoints/i/notifications.ts similarity index 100% rename from src/server/api/endpoints/i/notifications.ts rename to packages/backend/src/server/api/endpoints/i/notifications.ts diff --git a/src/server/api/endpoints/i/page-likes.ts b/packages/backend/src/server/api/endpoints/i/page-likes.ts similarity index 100% rename from src/server/api/endpoints/i/page-likes.ts rename to packages/backend/src/server/api/endpoints/i/page-likes.ts diff --git a/src/server/api/endpoints/i/pages.ts b/packages/backend/src/server/api/endpoints/i/pages.ts similarity index 100% rename from src/server/api/endpoints/i/pages.ts rename to packages/backend/src/server/api/endpoints/i/pages.ts diff --git a/src/server/api/endpoints/i/pin.ts b/packages/backend/src/server/api/endpoints/i/pin.ts similarity index 100% rename from src/server/api/endpoints/i/pin.ts rename to packages/backend/src/server/api/endpoints/i/pin.ts diff --git a/src/server/api/endpoints/i/read-all-messaging-messages.ts b/packages/backend/src/server/api/endpoints/i/read-all-messaging-messages.ts similarity index 100% rename from src/server/api/endpoints/i/read-all-messaging-messages.ts rename to packages/backend/src/server/api/endpoints/i/read-all-messaging-messages.ts diff --git a/src/server/api/endpoints/i/read-all-unread-notes.ts b/packages/backend/src/server/api/endpoints/i/read-all-unread-notes.ts similarity index 100% rename from src/server/api/endpoints/i/read-all-unread-notes.ts rename to packages/backend/src/server/api/endpoints/i/read-all-unread-notes.ts diff --git a/src/server/api/endpoints/i/read-announcement.ts b/packages/backend/src/server/api/endpoints/i/read-announcement.ts similarity index 100% rename from src/server/api/endpoints/i/read-announcement.ts rename to packages/backend/src/server/api/endpoints/i/read-announcement.ts diff --git a/src/server/api/endpoints/i/regenerate-token.ts b/packages/backend/src/server/api/endpoints/i/regenerate-token.ts similarity index 100% rename from src/server/api/endpoints/i/regenerate-token.ts rename to packages/backend/src/server/api/endpoints/i/regenerate-token.ts diff --git a/src/server/api/endpoints/i/registry/get-all.ts b/packages/backend/src/server/api/endpoints/i/registry/get-all.ts similarity index 100% rename from src/server/api/endpoints/i/registry/get-all.ts rename to packages/backend/src/server/api/endpoints/i/registry/get-all.ts diff --git a/src/server/api/endpoints/i/registry/get-detail.ts b/packages/backend/src/server/api/endpoints/i/registry/get-detail.ts similarity index 100% rename from src/server/api/endpoints/i/registry/get-detail.ts rename to packages/backend/src/server/api/endpoints/i/registry/get-detail.ts diff --git a/src/server/api/endpoints/i/registry/get.ts b/packages/backend/src/server/api/endpoints/i/registry/get.ts similarity index 100% rename from src/server/api/endpoints/i/registry/get.ts rename to packages/backend/src/server/api/endpoints/i/registry/get.ts diff --git a/src/server/api/endpoints/i/registry/keys-with-type.ts b/packages/backend/src/server/api/endpoints/i/registry/keys-with-type.ts similarity index 100% rename from src/server/api/endpoints/i/registry/keys-with-type.ts rename to packages/backend/src/server/api/endpoints/i/registry/keys-with-type.ts diff --git a/src/server/api/endpoints/i/registry/keys.ts b/packages/backend/src/server/api/endpoints/i/registry/keys.ts similarity index 100% rename from src/server/api/endpoints/i/registry/keys.ts rename to packages/backend/src/server/api/endpoints/i/registry/keys.ts diff --git a/src/server/api/endpoints/i/registry/remove.ts b/packages/backend/src/server/api/endpoints/i/registry/remove.ts similarity index 100% rename from src/server/api/endpoints/i/registry/remove.ts rename to packages/backend/src/server/api/endpoints/i/registry/remove.ts diff --git a/src/server/api/endpoints/i/registry/scopes.ts b/packages/backend/src/server/api/endpoints/i/registry/scopes.ts similarity index 100% rename from src/server/api/endpoints/i/registry/scopes.ts rename to packages/backend/src/server/api/endpoints/i/registry/scopes.ts diff --git a/src/server/api/endpoints/i/registry/set.ts b/packages/backend/src/server/api/endpoints/i/registry/set.ts similarity index 100% rename from src/server/api/endpoints/i/registry/set.ts rename to packages/backend/src/server/api/endpoints/i/registry/set.ts diff --git a/src/server/api/endpoints/i/revoke-token.ts b/packages/backend/src/server/api/endpoints/i/revoke-token.ts similarity index 100% rename from src/server/api/endpoints/i/revoke-token.ts rename to packages/backend/src/server/api/endpoints/i/revoke-token.ts diff --git a/src/server/api/endpoints/i/signin-history.ts b/packages/backend/src/server/api/endpoints/i/signin-history.ts similarity index 100% rename from src/server/api/endpoints/i/signin-history.ts rename to packages/backend/src/server/api/endpoints/i/signin-history.ts diff --git a/src/server/api/endpoints/i/unpin.ts b/packages/backend/src/server/api/endpoints/i/unpin.ts similarity index 100% rename from src/server/api/endpoints/i/unpin.ts rename to packages/backend/src/server/api/endpoints/i/unpin.ts diff --git a/packages/backend/src/server/api/endpoints/i/update-email.ts b/packages/backend/src/server/api/endpoints/i/update-email.ts new file mode 100644 index 000000000..ff5a9f292 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/i/update-email.ts @@ -0,0 +1,94 @@ +import $ from 'cafy'; +import { publishMainStream } from '@/services/stream'; +import define from '../../define'; +import rndstr from 'rndstr'; +import config from '@/config/index'; +import ms from 'ms'; +import * as bcrypt from 'bcryptjs'; +import { Users, UserProfiles } from '@/models/index'; +import { sendEmail } from '@/services/send-email'; +import { ApiError } from '../../error'; +import { validateEmailForAccount } from '@/services/validate-email-for-account'; + +export const meta = { + requireCredential: true as const, + + secure: true, + + limit: { + duration: ms('1hour'), + max: 3 + }, + + params: { + password: { + validator: $.str + }, + + email: { + validator: $.optional.nullable.str + }, + }, + + errors: { + incorrectPassword: { + message: 'Incorrect password.', + code: 'INCORRECT_PASSWORD', + id: 'e54c1d7e-e7d6-4103-86b6-0a95069b4ad3' + }, + + unavailable: { + message: 'Unavailable email address.', + code: 'UNAVAILABLE', + id: 'a2defefb-f220-8849-0af6-17f816099323' + }, + } +}; + +export default define(meta, async (ps, user) => { + const profile = await UserProfiles.findOneOrFail(user.id); + + // Compare password + const same = await bcrypt.compare(ps.password, profile.password!); + + if (!same) { + throw new ApiError(meta.errors.incorrectPassword); + } + + if (ps.email != null) { + const available = await validateEmailForAccount(ps.email); + if (!available) { + throw new ApiError(meta.errors.unavailable); + } + } + + await UserProfiles.update(user.id, { + email: ps.email, + emailVerified: false, + emailVerifyCode: null + }); + + const iObj = await Users.pack(user.id, user, { + detail: true, + includeSecrets: true + }); + + // Publish meUpdated event + publishMainStream(user.id, 'meUpdated', iObj); + + if (ps.email != null) { + const code = rndstr('a-z0-9', 16); + + await UserProfiles.update(user.id, { + emailVerifyCode: code + }); + + const link = `${config.url}/verify-email/${code}`; + + sendEmail(ps.email, 'Email verification', + `To verify email, please click this link:
${link}`, + `To verify email, please click this link: ${link}`); + } + + return iObj; +}); diff --git a/packages/backend/src/server/api/endpoints/i/update.ts b/packages/backend/src/server/api/endpoints/i/update.ts new file mode 100644 index 000000000..d0f201ab6 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/i/update.ts @@ -0,0 +1,294 @@ +import $ from 'cafy'; +import * as mfm from 'mfm-js'; +import { ID } from '@/misc/cafy-id'; +import { publishMainStream, publishUserEvent } from '@/services/stream'; +import acceptAllFollowRequests from '@/services/following/requests/accept-all'; +import { publishToFollowers } from '@/services/i/update'; +import define from '../../define'; +import { extractCustomEmojisFromMfm } from '@/misc/extract-custom-emojis-from-mfm'; +import { extractHashtags } from '@/misc/extract-hashtags'; +import * as langmap from 'langmap'; +import { updateUsertags } from '@/services/update-hashtag'; +import { ApiError } from '../../error'; +import { Users, DriveFiles, UserProfiles, Pages } from '@/models/index'; +import { User } from '@/models/entities/user'; +import { UserProfile } from '@/models/entities/user-profile'; +import { notificationTypes } from '@/types'; +import { normalizeForSearch } from '@/misc/normalize-for-search'; + +export const meta = { + tags: ['account'], + + requireCredential: true as const, + + kind: 'write:account', + + params: { + name: { + validator: $.optional.nullable.use(Users.validateName), + }, + + description: { + validator: $.optional.nullable.use(Users.validateDescription), + }, + + lang: { + validator: $.optional.nullable.str.or(Object.keys(langmap)), + }, + + location: { + validator: $.optional.nullable.use(Users.validateLocation), + }, + + birthday: { + validator: $.optional.nullable.use(Users.validateBirthday), + }, + + avatarId: { + validator: $.optional.nullable.type(ID), + }, + + bannerId: { + validator: $.optional.nullable.type(ID), + }, + + fields: { + validator: $.optional.arr($.object()).range(1, 4), + }, + + isLocked: { + validator: $.optional.bool, + }, + + isExplorable: { + validator: $.optional.bool, + }, + + hideOnlineStatus: { + validator: $.optional.bool, + }, + + publicReactions: { + validator: $.optional.bool, + }, + + ffVisibility: { + validator: $.optional.str, + }, + + carefulBot: { + validator: $.optional.bool, + }, + + autoAcceptFollowed: { + validator: $.optional.bool, + }, + + noCrawle: { + validator: $.optional.bool, + }, + + isBot: { + validator: $.optional.bool, + }, + + isCat: { + validator: $.optional.bool, + }, + + injectFeaturedNote: { + validator: $.optional.bool, + }, + + receiveAnnouncementEmail: { + validator: $.optional.bool, + }, + + alwaysMarkNsfw: { + validator: $.optional.bool, + }, + + pinnedPageId: { + validator: $.optional.nullable.type(ID), + }, + + mutedWords: { + validator: $.optional.arr($.arr($.str)) + }, + + mutingNotificationTypes: { + validator: $.optional.arr($.str.or(notificationTypes as unknown as string[])) + }, + + emailNotificationTypes: { + validator: $.optional.arr($.str) + }, + }, + + errors: { + noSuchAvatar: { + message: 'No such avatar file.', + code: 'NO_SUCH_AVATAR', + id: '539f3a45-f215-4f81-a9a8-31293640207f' + }, + + noSuchBanner: { + message: 'No such banner file.', + code: 'NO_SUCH_BANNER', + id: '0d8f5629-f210-41c2-9433-735831a58595' + }, + + avatarNotAnImage: { + message: 'The file specified as an avatar is not an image.', + code: 'AVATAR_NOT_AN_IMAGE', + id: 'f419f9f8-2f4d-46b1-9fb4-49d3a2fd7191' + }, + + bannerNotAnImage: { + message: 'The file specified as a banner is not an image.', + code: 'BANNER_NOT_AN_IMAGE', + id: '75aedb19-2afd-4e6d-87fc-67941256fa60' + }, + + noSuchPage: { + message: 'No such page.', + code: 'NO_SUCH_PAGE', + id: '8e01b590-7eb9-431b-a239-860e086c408e' + }, + }, + + res: { + type: 'object' as const, + optional: false as const, nullable: false as const, + ref: 'User' + } +}; + +export default define(meta, async (ps, _user, token) => { + const user = await Users.findOneOrFail(_user.id); + const isSecure = token == null; + + const updates = {} as Partial; + const profileUpdates = {} as Partial; + + const profile = await UserProfiles.findOneOrFail(user.id); + + if (ps.name !== undefined) updates.name = ps.name; + if (ps.description !== undefined) profileUpdates.description = ps.description; + if (ps.lang !== undefined) profileUpdates.lang = ps.lang; + if (ps.location !== undefined) profileUpdates.location = ps.location; + if (ps.birthday !== undefined) profileUpdates.birthday = ps.birthday; + if (ps.ffVisibility !== undefined) profileUpdates.ffVisibility = ps.ffVisibility; + if (ps.avatarId !== undefined) updates.avatarId = ps.avatarId; + if (ps.bannerId !== undefined) updates.bannerId = ps.bannerId; + if (ps.mutedWords !== undefined) { + profileUpdates.mutedWords = ps.mutedWords; + profileUpdates.enableWordMute = ps.mutedWords.length > 0; + } + if (ps.mutingNotificationTypes !== undefined) profileUpdates.mutingNotificationTypes = ps.mutingNotificationTypes as typeof notificationTypes[number][]; + if (typeof ps.isLocked === 'boolean') updates.isLocked = ps.isLocked; + if (typeof ps.isExplorable === 'boolean') updates.isExplorable = ps.isExplorable; + 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.carefulBot === 'boolean') profileUpdates.carefulBot = ps.carefulBot; + if (typeof ps.autoAcceptFollowed === 'boolean') profileUpdates.autoAcceptFollowed = ps.autoAcceptFollowed; + if (typeof ps.noCrawle === 'boolean') profileUpdates.noCrawle = ps.noCrawle; + if (typeof ps.isCat === 'boolean') updates.isCat = ps.isCat; + if (typeof ps.injectFeaturedNote === 'boolean') profileUpdates.injectFeaturedNote = ps.injectFeaturedNote; + if (typeof ps.receiveAnnouncementEmail === 'boolean') profileUpdates.receiveAnnouncementEmail = ps.receiveAnnouncementEmail; + if (typeof ps.alwaysMarkNsfw === 'boolean') profileUpdates.alwaysMarkNsfw = ps.alwaysMarkNsfw; + if (ps.emailNotificationTypes !== undefined) profileUpdates.emailNotificationTypes = ps.emailNotificationTypes; + + if (ps.avatarId) { + const avatar = await DriveFiles.findOne(ps.avatarId); + + if (avatar == null || avatar.userId !== user.id) throw new ApiError(meta.errors.noSuchAvatar); + if (!avatar.type.startsWith('image/')) throw new ApiError(meta.errors.avatarNotAnImage); + + updates.avatarUrl = DriveFiles.getPublicUrl(avatar, true); + + if (avatar.blurhash) { + updates.avatarBlurhash = avatar.blurhash; + } + } + + if (ps.bannerId) { + const banner = await DriveFiles.findOne(ps.bannerId); + + if (banner == null || banner.userId !== user.id) throw new ApiError(meta.errors.noSuchBanner); + if (!banner.type.startsWith('image/')) throw new ApiError(meta.errors.bannerNotAnImage); + + updates.bannerUrl = DriveFiles.getPublicUrl(banner, false); + + if (banner.blurhash) { + updates.bannerBlurhash = banner.blurhash; + } + } + + if (ps.pinnedPageId) { + const page = await Pages.findOne(ps.pinnedPageId); + + if (page == null || page.userId !== user.id) throw new ApiError(meta.errors.noSuchPage); + + profileUpdates.pinnedPageId = page.id; + } else if (ps.pinnedPageId === null) { + profileUpdates.pinnedPageId = null; + } + + if (ps.fields) { + profileUpdates.fields = ps.fields + .filter(x => typeof x.name === 'string' && x.name !== '' && typeof x.value === 'string' && x.value !== '') + .map(x => { + return { name: x.name, value: x.value }; + }); + } + + //#region emojis/tags + + let emojis = [] as string[]; + let tags = [] as string[]; + + const newName = updates.name === undefined ? user.name : updates.name; + const newDescription = profileUpdates.description === undefined ? profile.description : profileUpdates.description; + + if (newName != null) { + const tokens = mfm.parsePlain(newName); + emojis = emojis.concat(extractCustomEmojisFromMfm(tokens!)); + } + + if (newDescription != null) { + const tokens = mfm.parse(newDescription); + emojis = emojis.concat(extractCustomEmojisFromMfm(tokens!)); + tags = extractHashtags(tokens!).map(tag => normalizeForSearch(tag)).splice(0, 32); + } + + updates.emojis = emojis; + updates.tags = tags; + + // ハッシュタグ更新 + updateUsertags(user, tags); + //#endregion + + if (Object.keys(updates).length > 0) await Users.update(user.id, updates); + if (Object.keys(profileUpdates).length > 0) await UserProfiles.update(user.id, profileUpdates); + + const iObj = await Users.pack(user.id, user, { + detail: true, + includeSecrets: isSecure + }); + + // Publish meUpdated event + publishMainStream(user.id, 'meUpdated', iObj); + publishUserEvent(user.id, 'updateUserProfile', await UserProfiles.findOne(user.id)); + + // 鍵垢を解除したとき、溜まっていたフォローリクエストがあるならすべて承認 + if (user.isLocked && ps.isLocked === false) { + acceptAllFollowRequests(user); + } + + // フォロワーにUpdateを配信 + publishToFollowers(user.id); + + return iObj; +}); diff --git a/src/server/api/endpoints/i/user-group-invites.ts b/packages/backend/src/server/api/endpoints/i/user-group-invites.ts similarity index 100% rename from src/server/api/endpoints/i/user-group-invites.ts rename to packages/backend/src/server/api/endpoints/i/user-group-invites.ts diff --git a/src/server/api/endpoints/messaging/history.ts b/packages/backend/src/server/api/endpoints/messaging/history.ts similarity index 100% rename from src/server/api/endpoints/messaging/history.ts rename to packages/backend/src/server/api/endpoints/messaging/history.ts diff --git a/src/server/api/endpoints/messaging/messages.ts b/packages/backend/src/server/api/endpoints/messaging/messages.ts similarity index 100% rename from src/server/api/endpoints/messaging/messages.ts rename to packages/backend/src/server/api/endpoints/messaging/messages.ts diff --git a/src/server/api/endpoints/messaging/messages/create.ts b/packages/backend/src/server/api/endpoints/messaging/messages/create.ts similarity index 100% rename from src/server/api/endpoints/messaging/messages/create.ts rename to packages/backend/src/server/api/endpoints/messaging/messages/create.ts diff --git a/packages/backend/src/server/api/endpoints/messaging/messages/delete.ts b/packages/backend/src/server/api/endpoints/messaging/messages/delete.ts new file mode 100644 index 000000000..25bf67638 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/messaging/messages/delete.ts @@ -0,0 +1,48 @@ +import $ from 'cafy'; +import { ID } from '@/misc/cafy-id'; +import define from '../../../define'; +import ms from 'ms'; +import { ApiError } from '../../../error'; +import { MessagingMessages } from '@/models/index'; +import { deleteMessage } from '@/services/messages/delete'; + +export const meta = { + tags: ['messaging'], + + requireCredential: true as const, + + kind: 'write:messaging', + + limit: { + duration: ms('1hour'), + max: 300, + minInterval: ms('1sec') + }, + + params: { + messageId: { + validator: $.type(ID), + } + }, + + errors: { + noSuchMessage: { + message: 'No such message.', + code: 'NO_SUCH_MESSAGE', + id: '54b5b326-7925-42cf-8019-130fda8b56af' + }, + } +}; + +export default define(meta, async (ps, user) => { + const message = await MessagingMessages.findOne({ + id: ps.messageId, + userId: user.id + }); + + if (message == null) { + throw new ApiError(meta.errors.noSuchMessage); + } + + await deleteMessage(message); +}); diff --git a/src/server/api/endpoints/messaging/messages/read.ts b/packages/backend/src/server/api/endpoints/messaging/messages/read.ts similarity index 100% rename from src/server/api/endpoints/messaging/messages/read.ts rename to packages/backend/src/server/api/endpoints/messaging/messages/read.ts diff --git a/src/server/api/endpoints/meta.ts b/packages/backend/src/server/api/endpoints/meta.ts similarity index 100% rename from src/server/api/endpoints/meta.ts rename to packages/backend/src/server/api/endpoints/meta.ts diff --git a/src/server/api/endpoints/miauth/gen-token.ts b/packages/backend/src/server/api/endpoints/miauth/gen-token.ts similarity index 100% rename from src/server/api/endpoints/miauth/gen-token.ts rename to packages/backend/src/server/api/endpoints/miauth/gen-token.ts diff --git a/src/server/api/endpoints/mute/create.ts b/packages/backend/src/server/api/endpoints/mute/create.ts similarity index 100% rename from src/server/api/endpoints/mute/create.ts rename to packages/backend/src/server/api/endpoints/mute/create.ts diff --git a/src/server/api/endpoints/mute/delete.ts b/packages/backend/src/server/api/endpoints/mute/delete.ts similarity index 100% rename from src/server/api/endpoints/mute/delete.ts rename to packages/backend/src/server/api/endpoints/mute/delete.ts diff --git a/src/server/api/endpoints/mute/list.ts b/packages/backend/src/server/api/endpoints/mute/list.ts similarity index 100% rename from src/server/api/endpoints/mute/list.ts rename to packages/backend/src/server/api/endpoints/mute/list.ts diff --git a/src/server/api/endpoints/my/apps.ts b/packages/backend/src/server/api/endpoints/my/apps.ts similarity index 100% rename from src/server/api/endpoints/my/apps.ts rename to packages/backend/src/server/api/endpoints/my/apps.ts diff --git a/src/server/api/endpoints/notes.ts b/packages/backend/src/server/api/endpoints/notes.ts similarity index 100% rename from src/server/api/endpoints/notes.ts rename to packages/backend/src/server/api/endpoints/notes.ts diff --git a/src/server/api/endpoints/notes/children.ts b/packages/backend/src/server/api/endpoints/notes/children.ts similarity index 100% rename from src/server/api/endpoints/notes/children.ts rename to packages/backend/src/server/api/endpoints/notes/children.ts diff --git a/src/server/api/endpoints/notes/clips.ts b/packages/backend/src/server/api/endpoints/notes/clips.ts similarity index 100% rename from src/server/api/endpoints/notes/clips.ts rename to packages/backend/src/server/api/endpoints/notes/clips.ts diff --git a/src/server/api/endpoints/notes/conversation.ts b/packages/backend/src/server/api/endpoints/notes/conversation.ts similarity index 100% rename from src/server/api/endpoints/notes/conversation.ts rename to packages/backend/src/server/api/endpoints/notes/conversation.ts diff --git a/packages/backend/src/server/api/endpoints/notes/create.ts b/packages/backend/src/server/api/endpoints/notes/create.ts new file mode 100644 index 000000000..e9584e7b8 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/notes/create.ts @@ -0,0 +1,293 @@ +import $ from 'cafy'; +import ms from 'ms'; +import { length } from 'stringz'; +import create from '@/services/note/create'; +import define from '../../define'; +import { fetchMeta } from '@/misc/fetch-meta'; +import { ApiError } from '../../error'; +import { ID } from '@/misc/cafy-id'; +import { User } from '@/models/entities/user'; +import { Users, DriveFiles, Notes, Channels, Blockings } from '@/models/index'; +import { DriveFile } from '@/models/entities/drive-file'; +import { Note } from '@/models/entities/note'; +import { DB_MAX_NOTE_TEXT_LENGTH } from '@/misc/hard-limits'; +import { noteVisibilities } from '../../../../types'; +import { Channel } from '@/models/entities/channel'; + +let maxNoteTextLength = 500; + +setInterval(() => { + fetchMeta().then(m => { + maxNoteTextLength = m.maxNoteTextLength; + }); +}, 3000); + +export const meta = { + tags: ['notes'], + + requireCredential: true as const, + + limit: { + duration: ms('1hour'), + max: 300 + }, + + kind: 'write:notes', + + params: { + visibility: { + validator: $.optional.str.or(noteVisibilities as unknown as string[]), + default: 'public', + }, + + visibleUserIds: { + validator: $.optional.arr($.type(ID)).unique().min(0), + }, + + text: { + validator: $.optional.nullable.str.pipe(text => + text.trim() != '' + && length(text.trim()) <= maxNoteTextLength + && Array.from(text.trim()).length <= DB_MAX_NOTE_TEXT_LENGTH // DB limit + ), + default: null, + }, + + cw: { + validator: $.optional.nullable.str.pipe(Notes.validateCw), + }, + + localOnly: { + validator: $.optional.bool, + default: false, + }, + + noExtractMentions: { + validator: $.optional.bool, + default: false, + }, + + noExtractHashtags: { + validator: $.optional.bool, + default: false, + }, + + noExtractEmojis: { + validator: $.optional.bool, + default: false, + }, + + fileIds: { + validator: $.optional.arr($.type(ID)).unique().range(1, 4), + }, + + mediaIds: { + validator: $.optional.arr($.type(ID)).unique().range(1, 4), + deprecated: true, + }, + + replyId: { + validator: $.optional.nullable.type(ID), + }, + + renoteId: { + validator: $.optional.nullable.type(ID), + }, + + channelId: { + validator: $.optional.nullable.type(ID), + }, + + poll: { + validator: $.optional.nullable.obj({ + choices: $.arr($.str) + .unique() + .range(2, 10) + .each(c => c.length > 0 && c.length < 50), + multiple: $.optional.bool, + expiresAt: $.optional.nullable.num.int(), + expiredAfter: $.optional.nullable.num.int().min(1) + }).strict(), + ref: 'poll' + } + }, + + res: { + type: 'object' as const, + optional: false as const, nullable: false as const, + properties: { + createdNote: { + type: 'object' as const, + optional: false as const, nullable: false as const, + ref: 'Note', + } + } + }, + + errors: { + noSuchRenoteTarget: { + message: 'No such renote target.', + code: 'NO_SUCH_RENOTE_TARGET', + id: 'b5c90186-4ab0-49c8-9bba-a1f76c282ba4' + }, + + cannotReRenote: { + message: 'You can not Renote a pure Renote.', + code: 'CANNOT_RENOTE_TO_A_PURE_RENOTE', + id: 'fd4cc33e-2a37-48dd-99cc-9b806eb2031a' + }, + + noSuchReplyTarget: { + message: 'No such reply target.', + code: 'NO_SUCH_REPLY_TARGET', + id: '749ee0f6-d3da-459a-bf02-282e2da4292c' + }, + + cannotReplyToPureRenote: { + message: 'You can not reply to a pure Renote.', + code: 'CANNOT_REPLY_TO_A_PURE_RENOTE', + id: '3ac74a84-8fd5-4bb0-870f-01804f82ce15' + }, + + contentRequired: { + message: 'Content required. You need to set text, fileIds, renoteId or poll.', + code: 'CONTENT_REQUIRED', + id: '6f57e42b-c348-439b-bc45-993995cc515a' + }, + + cannotCreateAlreadyExpiredPoll: { + message: 'Poll is already expired.', + code: 'CANNOT_CREATE_ALREADY_EXPIRED_POLL', + id: '04da457d-b083-4055-9082-955525eda5a5' + }, + + noSuchChannel: { + message: 'No such channel.', + code: 'NO_SUCH_CHANNEL', + id: 'b1653923-5453-4edc-b786-7c4f39bb0bbb' + }, + + youHaveBeenBlocked: { + message: 'You have been blocked by this user.', + code: 'YOU_HAVE_BEEN_BLOCKED', + id: 'b390d7e1-8a5e-46ed-b625-06271cafd3d3' + }, + } +}; + +export default define(meta, async (ps, user) => { + let visibleUsers: User[] = []; + if (ps.visibleUserIds) { + visibleUsers = (await Promise.all(ps.visibleUserIds.map(id => Users.findOne(id)))) + .filter(x => x != null) as User[]; + } + + let files: DriveFile[] = []; + const fileIds = ps.fileIds != null ? ps.fileIds : ps.mediaIds != null ? ps.mediaIds : null; + if (fileIds != null) { + files = (await Promise.all(fileIds.map(fileId => + DriveFiles.findOne({ + id: fileId, + userId: user.id + }) + ))).filter(file => file != null) as DriveFile[]; + } + + let renote: Note | undefined; + if (ps.renoteId != null) { + // Fetch renote to note + renote = await Notes.findOne(ps.renoteId); + + if (renote == null) { + throw new ApiError(meta.errors.noSuchRenoteTarget); + } else if (renote.renoteId && !renote.text && !renote.fileIds) { + throw new ApiError(meta.errors.cannotReRenote); + } + + // Check blocking + if (renote.userId !== user.id) { + const block = await Blockings.findOne({ + blockerId: renote.userId, + blockeeId: user.id, + }); + if (block) { + throw new ApiError(meta.errors.youHaveBeenBlocked); + } + } + } + + let reply: Note | undefined; + if (ps.replyId != null) { + // Fetch reply + reply = await Notes.findOne(ps.replyId); + + if (reply == null) { + throw new ApiError(meta.errors.noSuchReplyTarget); + } + + // 返信対象が引用でないRenoteだったらエラー + if (reply.renoteId && !reply.text && !reply.fileIds) { + throw new ApiError(meta.errors.cannotReplyToPureRenote); + } + + // Check blocking + if (reply.userId !== user.id) { + const block = await Blockings.findOne({ + blockerId: reply.userId, + blockeeId: user.id, + }); + if (block) { + throw new ApiError(meta.errors.youHaveBeenBlocked); + } + } + } + + if (ps.poll) { + if (typeof ps.poll.expiresAt === 'number') { + if (ps.poll.expiresAt < Date.now()) + throw new ApiError(meta.errors.cannotCreateAlreadyExpiredPoll); + } else if (typeof ps.poll.expiredAfter === 'number') { + ps.poll.expiresAt = Date.now() + ps.poll.expiredAfter; + } + } + + // テキストが無いかつ添付ファイルが無いかつRenoteも無いかつ投票も無かったらエラー + if (!(ps.text || files.length || renote || ps.poll)) { + throw new ApiError(meta.errors.contentRequired); + } + + let channel: Channel | undefined; + if (ps.channelId != null) { + channel = await Channels.findOne(ps.channelId); + + if (channel == null) { + throw new ApiError(meta.errors.noSuchChannel); + } + } + + // 投稿を作成 + const note = await create(user, { + createdAt: new Date(), + files: files, + poll: ps.poll ? { + choices: ps.poll.choices, + multiple: ps.poll.multiple || false, + expiresAt: ps.poll.expiresAt ? new Date(ps.poll.expiresAt) : null + } : undefined, + text: ps.text || undefined, + reply, + renote, + cw: ps.cw, + localOnly: ps.localOnly, + visibility: ps.visibility, + visibleUsers, + channel, + apMentions: ps.noExtractMentions ? [] : undefined, + apHashtags: ps.noExtractHashtags ? [] : undefined, + apEmojis: ps.noExtractEmojis ? [] : undefined, + }); + + return { + createdNote: await Notes.pack(note, user) + }; +}); diff --git a/packages/backend/src/server/api/endpoints/notes/delete.ts b/packages/backend/src/server/api/endpoints/notes/delete.ts new file mode 100644 index 000000000..7f0d59669 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/notes/delete.ts @@ -0,0 +1,56 @@ +import $ from 'cafy'; +import { ID } from '@/misc/cafy-id'; +import deleteNote from '@/services/note/delete'; +import define from '../../define'; +import ms from 'ms'; +import { getNote } from '../../common/getters'; +import { ApiError } from '../../error'; +import { Users } from '@/models/index'; + +export const meta = { + tags: ['notes'], + + requireCredential: true as const, + + kind: 'write:notes', + + limit: { + duration: ms('1hour'), + max: 300, + minInterval: ms('1sec') + }, + + params: { + noteId: { + validator: $.type(ID), + } + }, + + errors: { + noSuchNote: { + message: 'No such note.', + code: 'NO_SUCH_NOTE', + id: '490be23f-8c1f-4796-819f-94cb4f9d1630' + }, + + accessDenied: { + message: 'Access denied.', + code: 'ACCESS_DENIED', + id: 'fe8d7103-0ea8-4ec3-814d-f8b401dc69e9' + } + } +}; + +export default define(meta, async (ps, user) => { + const note = await getNote(ps.noteId).catch(e => { + if (e.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote); + throw e; + }); + + if (!user.isAdmin && !user.isModerator && (note.userId !== user.id)) { + throw new ApiError(meta.errors.accessDenied); + } + + // この操作を行うのが投稿者とは限らない(例えばモデレーター)ため + await deleteNote(await Users.findOneOrFail(note.userId), note); +}); diff --git a/src/server/api/endpoints/notes/favorites/create.ts b/packages/backend/src/server/api/endpoints/notes/favorites/create.ts similarity index 100% rename from src/server/api/endpoints/notes/favorites/create.ts rename to packages/backend/src/server/api/endpoints/notes/favorites/create.ts diff --git a/src/server/api/endpoints/notes/favorites/delete.ts b/packages/backend/src/server/api/endpoints/notes/favorites/delete.ts similarity index 100% rename from src/server/api/endpoints/notes/favorites/delete.ts rename to packages/backend/src/server/api/endpoints/notes/favorites/delete.ts diff --git a/src/server/api/endpoints/notes/featured.ts b/packages/backend/src/server/api/endpoints/notes/featured.ts similarity index 100% rename from src/server/api/endpoints/notes/featured.ts rename to packages/backend/src/server/api/endpoints/notes/featured.ts diff --git a/src/server/api/endpoints/notes/global-timeline.ts b/packages/backend/src/server/api/endpoints/notes/global-timeline.ts similarity index 100% rename from src/server/api/endpoints/notes/global-timeline.ts rename to packages/backend/src/server/api/endpoints/notes/global-timeline.ts diff --git a/src/server/api/endpoints/notes/hybrid-timeline.ts b/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts similarity index 100% rename from src/server/api/endpoints/notes/hybrid-timeline.ts rename to packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts diff --git a/src/server/api/endpoints/notes/local-timeline.ts b/packages/backend/src/server/api/endpoints/notes/local-timeline.ts similarity index 100% rename from src/server/api/endpoints/notes/local-timeline.ts rename to packages/backend/src/server/api/endpoints/notes/local-timeline.ts diff --git a/src/server/api/endpoints/notes/mentions.ts b/packages/backend/src/server/api/endpoints/notes/mentions.ts similarity index 100% rename from src/server/api/endpoints/notes/mentions.ts rename to packages/backend/src/server/api/endpoints/notes/mentions.ts diff --git a/src/server/api/endpoints/notes/polls/recommendation.ts b/packages/backend/src/server/api/endpoints/notes/polls/recommendation.ts similarity index 100% rename from src/server/api/endpoints/notes/polls/recommendation.ts rename to packages/backend/src/server/api/endpoints/notes/polls/recommendation.ts diff --git a/src/server/api/endpoints/notes/polls/vote.ts b/packages/backend/src/server/api/endpoints/notes/polls/vote.ts similarity index 100% rename from src/server/api/endpoints/notes/polls/vote.ts rename to packages/backend/src/server/api/endpoints/notes/polls/vote.ts diff --git a/src/server/api/endpoints/notes/reactions.ts b/packages/backend/src/server/api/endpoints/notes/reactions.ts similarity index 100% rename from src/server/api/endpoints/notes/reactions.ts rename to packages/backend/src/server/api/endpoints/notes/reactions.ts diff --git a/src/server/api/endpoints/notes/reactions/create.ts b/packages/backend/src/server/api/endpoints/notes/reactions/create.ts similarity index 100% rename from src/server/api/endpoints/notes/reactions/create.ts rename to packages/backend/src/server/api/endpoints/notes/reactions/create.ts diff --git a/packages/backend/src/server/api/endpoints/notes/reactions/delete.ts b/packages/backend/src/server/api/endpoints/notes/reactions/delete.ts new file mode 100644 index 000000000..ea851458d --- /dev/null +++ b/packages/backend/src/server/api/endpoints/notes/reactions/delete.ts @@ -0,0 +1,52 @@ +import $ from 'cafy'; +import { ID } from '@/misc/cafy-id'; +import define from '../../../define'; +import ms from 'ms'; +import deleteReaction from '@/services/note/reaction/delete'; +import { getNote } from '../../../common/getters'; +import { ApiError } from '../../../error'; + +export const meta = { + tags: ['reactions', 'notes'], + + requireCredential: true as const, + + kind: 'write:reactions', + + limit: { + duration: ms('1hour'), + max: 60, + minInterval: ms('3sec') + }, + + params: { + noteId: { + validator: $.type(ID), + }, + }, + + errors: { + noSuchNote: { + message: 'No such note.', + code: 'NO_SUCH_NOTE', + id: '764d9fce-f9f2-4a0e-92b1-6ceac9a7ad37' + }, + + notReacted: { + message: 'You are not reacting to that note.', + code: 'NOT_REACTED', + id: '92f4426d-4196-4125-aa5b-02943e2ec8fc' + }, + } +}; + +export default define(meta, async (ps, user) => { + const note = await getNote(ps.noteId).catch(e => { + if (e.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote); + throw e; + }); + await deleteReaction(user, note).catch(e => { + if (e.id === '60527ec9-b4cb-4a88-a6bd-32d3ad26817d') throw new ApiError(meta.errors.notReacted); + throw e; + }); +}); diff --git a/src/server/api/endpoints/notes/renotes.ts b/packages/backend/src/server/api/endpoints/notes/renotes.ts similarity index 100% rename from src/server/api/endpoints/notes/renotes.ts rename to packages/backend/src/server/api/endpoints/notes/renotes.ts diff --git a/src/server/api/endpoints/notes/replies.ts b/packages/backend/src/server/api/endpoints/notes/replies.ts similarity index 100% rename from src/server/api/endpoints/notes/replies.ts rename to packages/backend/src/server/api/endpoints/notes/replies.ts diff --git a/src/server/api/endpoints/notes/search-by-tag.ts b/packages/backend/src/server/api/endpoints/notes/search-by-tag.ts similarity index 100% rename from src/server/api/endpoints/notes/search-by-tag.ts rename to packages/backend/src/server/api/endpoints/notes/search-by-tag.ts diff --git a/src/server/api/endpoints/notes/search.ts b/packages/backend/src/server/api/endpoints/notes/search.ts similarity index 100% rename from src/server/api/endpoints/notes/search.ts rename to packages/backend/src/server/api/endpoints/notes/search.ts diff --git a/src/server/api/endpoints/notes/show.ts b/packages/backend/src/server/api/endpoints/notes/show.ts similarity index 100% rename from src/server/api/endpoints/notes/show.ts rename to packages/backend/src/server/api/endpoints/notes/show.ts diff --git a/src/server/api/endpoints/notes/state.ts b/packages/backend/src/server/api/endpoints/notes/state.ts similarity index 100% rename from src/server/api/endpoints/notes/state.ts rename to packages/backend/src/server/api/endpoints/notes/state.ts diff --git a/src/server/api/endpoints/notes/thread-muting/create.ts b/packages/backend/src/server/api/endpoints/notes/thread-muting/create.ts similarity index 100% rename from src/server/api/endpoints/notes/thread-muting/create.ts rename to packages/backend/src/server/api/endpoints/notes/thread-muting/create.ts diff --git a/src/server/api/endpoints/notes/thread-muting/delete.ts b/packages/backend/src/server/api/endpoints/notes/thread-muting/delete.ts similarity index 100% rename from src/server/api/endpoints/notes/thread-muting/delete.ts rename to packages/backend/src/server/api/endpoints/notes/thread-muting/delete.ts diff --git a/src/server/api/endpoints/notes/timeline.ts b/packages/backend/src/server/api/endpoints/notes/timeline.ts similarity index 100% rename from src/server/api/endpoints/notes/timeline.ts rename to packages/backend/src/server/api/endpoints/notes/timeline.ts diff --git a/src/server/api/endpoints/notes/translate.ts b/packages/backend/src/server/api/endpoints/notes/translate.ts similarity index 100% rename from src/server/api/endpoints/notes/translate.ts rename to packages/backend/src/server/api/endpoints/notes/translate.ts diff --git a/packages/backend/src/server/api/endpoints/notes/unrenote.ts b/packages/backend/src/server/api/endpoints/notes/unrenote.ts new file mode 100644 index 000000000..d3fba6609 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/notes/unrenote.ts @@ -0,0 +1,52 @@ +import $ from 'cafy'; +import { ID } from '@/misc/cafy-id'; +import deleteNote from '@/services/note/delete'; +import define from '../../define'; +import ms from 'ms'; +import { getNote } from '../../common/getters'; +import { ApiError } from '../../error'; +import { Notes, Users } from '@/models/index'; + +export const meta = { + tags: ['notes'], + + requireCredential: true as const, + + kind: 'write:notes', + + limit: { + duration: ms('1hour'), + max: 300, + minInterval: ms('1sec') + }, + + params: { + noteId: { + validator: $.type(ID), + } + }, + + errors: { + noSuchNote: { + message: 'No such note.', + code: 'NO_SUCH_NOTE', + id: 'efd4a259-2442-496b-8dd7-b255aa1a160f' + }, + } +}; + +export default define(meta, async (ps, user) => { + const note = await getNote(ps.noteId).catch(e => { + if (e.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote); + throw e; + }); + + const renotes = await Notes.find({ + userId: user.id, + renoteId: note.id + }); + + for (const note of renotes) { + deleteNote(await Users.findOneOrFail(user.id), note); + } +}); diff --git a/src/server/api/endpoints/notes/user-list-timeline.ts b/packages/backend/src/server/api/endpoints/notes/user-list-timeline.ts similarity index 100% rename from src/server/api/endpoints/notes/user-list-timeline.ts rename to packages/backend/src/server/api/endpoints/notes/user-list-timeline.ts diff --git a/src/server/api/endpoints/notes/watching/create.ts b/packages/backend/src/server/api/endpoints/notes/watching/create.ts similarity index 100% rename from src/server/api/endpoints/notes/watching/create.ts rename to packages/backend/src/server/api/endpoints/notes/watching/create.ts diff --git a/src/server/api/endpoints/notes/watching/delete.ts b/packages/backend/src/server/api/endpoints/notes/watching/delete.ts similarity index 100% rename from src/server/api/endpoints/notes/watching/delete.ts rename to packages/backend/src/server/api/endpoints/notes/watching/delete.ts diff --git a/src/server/api/endpoints/notifications/create.ts b/packages/backend/src/server/api/endpoints/notifications/create.ts similarity index 100% rename from src/server/api/endpoints/notifications/create.ts rename to packages/backend/src/server/api/endpoints/notifications/create.ts diff --git a/src/server/api/endpoints/notifications/mark-all-as-read.ts b/packages/backend/src/server/api/endpoints/notifications/mark-all-as-read.ts similarity index 100% rename from src/server/api/endpoints/notifications/mark-all-as-read.ts rename to packages/backend/src/server/api/endpoints/notifications/mark-all-as-read.ts diff --git a/src/server/api/endpoints/notifications/read.ts b/packages/backend/src/server/api/endpoints/notifications/read.ts similarity index 100% rename from src/server/api/endpoints/notifications/read.ts rename to packages/backend/src/server/api/endpoints/notifications/read.ts diff --git a/src/server/api/endpoints/page-push.ts b/packages/backend/src/server/api/endpoints/page-push.ts similarity index 100% rename from src/server/api/endpoints/page-push.ts rename to packages/backend/src/server/api/endpoints/page-push.ts diff --git a/packages/backend/src/server/api/endpoints/pages/create.ts b/packages/backend/src/server/api/endpoints/pages/create.ts new file mode 100644 index 000000000..0ec287c59 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/pages/create.ts @@ -0,0 +1,128 @@ +import $ from 'cafy'; +import ms from 'ms'; +import define from '../../define'; +import { ID } from '@/misc/cafy-id'; +import { Pages, DriveFiles } from '@/models/index'; +import { genId } from '@/misc/gen-id'; +import { Page } from '@/models/entities/page'; +import { ApiError } from '../../error'; + +export const meta = { + tags: ['pages'], + + requireCredential: true as const, + + kind: 'write:pages', + + limit: { + duration: ms('1hour'), + max: 300 + }, + + params: { + title: { + validator: $.str, + }, + + name: { + validator: $.str.min(1), + }, + + summary: { + validator: $.optional.nullable.str, + }, + + content: { + validator: $.arr($.obj()) + }, + + variables: { + validator: $.arr($.obj()) + }, + + script: { + validator: $.str, + }, + + eyeCatchingImageId: { + validator: $.optional.nullable.type(ID), + }, + + font: { + validator: $.optional.str.or(['serif', 'sans-serif']), + default: 'sans-serif' + }, + + alignCenter: { + validator: $.optional.bool, + default: false + }, + + hideTitleWhenPinned: { + validator: $.optional.bool, + default: false + }, + }, + + res: { + type: 'object' as const, + optional: false as const, nullable: false as const, + ref: 'Page', + }, + + errors: { + noSuchFile: { + message: 'No such file.', + code: 'NO_SUCH_FILE', + id: 'b7b97489-0f66-4b12-a5ff-b21bd63f6e1c' + }, + nameAlreadyExists: { + message: 'Specified name already exists.', + code: 'NAME_ALREADY_EXISTS', + id: '4650348e-301c-499a-83c9-6aa988c66bc1' + } + } +}; + +export default define(meta, async (ps, user) => { + let eyeCatchingImage = null; + if (ps.eyeCatchingImageId != null) { + eyeCatchingImage = await DriveFiles.findOne({ + id: ps.eyeCatchingImageId, + userId: user.id + }); + + if (eyeCatchingImage == null) { + throw new ApiError(meta.errors.noSuchFile); + } + } + + await Pages.find({ + userId: user.id, + name: ps.name + }).then(result => { + if (result.length > 0) { + throw new ApiError(meta.errors.nameAlreadyExists); + } + }); + + const page = await Pages.save(new Page({ + id: genId(), + createdAt: new Date(), + updatedAt: new Date(), + title: ps.title, + name: ps.name, + summary: ps.summary, + content: ps.content, + variables: ps.variables, + script: ps.script, + eyeCatchingImageId: eyeCatchingImage ? eyeCatchingImage.id : null, + userId: user.id, + visibility: 'public', + alignCenter: ps.alignCenter, + hideTitleWhenPinned: ps.hideTitleWhenPinned, + font: ps.font + })); + + return await Pages.pack(page); +}); diff --git a/src/server/api/endpoints/pages/delete.ts b/packages/backend/src/server/api/endpoints/pages/delete.ts similarity index 100% rename from src/server/api/endpoints/pages/delete.ts rename to packages/backend/src/server/api/endpoints/pages/delete.ts diff --git a/src/server/api/endpoints/pages/featured.ts b/packages/backend/src/server/api/endpoints/pages/featured.ts similarity index 100% rename from src/server/api/endpoints/pages/featured.ts rename to packages/backend/src/server/api/endpoints/pages/featured.ts diff --git a/src/server/api/endpoints/pages/like.ts b/packages/backend/src/server/api/endpoints/pages/like.ts similarity index 100% rename from src/server/api/endpoints/pages/like.ts rename to packages/backend/src/server/api/endpoints/pages/like.ts diff --git a/src/server/api/endpoints/pages/show.ts b/packages/backend/src/server/api/endpoints/pages/show.ts similarity index 100% rename from src/server/api/endpoints/pages/show.ts rename to packages/backend/src/server/api/endpoints/pages/show.ts diff --git a/src/server/api/endpoints/pages/unlike.ts b/packages/backend/src/server/api/endpoints/pages/unlike.ts similarity index 100% rename from src/server/api/endpoints/pages/unlike.ts rename to packages/backend/src/server/api/endpoints/pages/unlike.ts diff --git a/packages/backend/src/server/api/endpoints/pages/update.ts b/packages/backend/src/server/api/endpoints/pages/update.ts new file mode 100644 index 000000000..4aaf2aed5 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/pages/update.ts @@ -0,0 +1,141 @@ +import $ from 'cafy'; +import ms from 'ms'; +import define from '../../define'; +import { ApiError } from '../../error'; +import { Pages, DriveFiles } from '@/models/index'; +import { ID } from '@/misc/cafy-id'; +import { Not } from 'typeorm'; + +export const meta = { + tags: ['pages'], + + requireCredential: true as const, + + kind: 'write:pages', + + limit: { + duration: ms('1hour'), + max: 300 + }, + + params: { + pageId: { + validator: $.type(ID), + }, + + title: { + validator: $.str, + }, + + name: { + validator: $.str.min(1), + }, + + summary: { + validator: $.optional.nullable.str, + }, + + content: { + validator: $.arr($.obj()) + }, + + variables: { + validator: $.arr($.obj()) + }, + + script: { + validator: $.str, + }, + + eyeCatchingImageId: { + validator: $.optional.nullable.type(ID), + }, + + font: { + validator: $.optional.str.or(['serif', 'sans-serif']), + }, + + alignCenter: { + validator: $.optional.bool, + }, + + hideTitleWhenPinned: { + validator: $.optional.bool, + }, + }, + + errors: { + noSuchPage: { + message: 'No such page.', + code: 'NO_SUCH_PAGE', + id: '21149b9e-3616-4778-9592-c4ce89f5a864' + }, + + accessDenied: { + message: 'Access denied.', + code: 'ACCESS_DENIED', + id: '3c15cd52-3b4b-4274-967d-6456fc4f792b' + }, + + noSuchFile: { + message: 'No such file.', + code: 'NO_SUCH_FILE', + id: 'cfc23c7c-3887-490e-af30-0ed576703c82' + }, + nameAlreadyExists: { + message: 'Specified name already exists.', + code: 'NAME_ALREADY_EXISTS', + id: '2298a392-d4a1-44c5-9ebb-ac1aeaa5a9ab' + } + } +}; + +export default define(meta, async (ps, user) => { + const page = await Pages.findOne(ps.pageId); + if (page == null) { + throw new ApiError(meta.errors.noSuchPage); + } + if (page.userId !== user.id) { + throw new ApiError(meta.errors.accessDenied); + } + + let eyeCatchingImage = null; + if (ps.eyeCatchingImageId != null) { + eyeCatchingImage = await DriveFiles.findOne({ + id: ps.eyeCatchingImageId, + userId: user.id + }); + + if (eyeCatchingImage == null) { + throw new ApiError(meta.errors.noSuchFile); + } + } + + await Pages.find({ + id: Not(ps.pageId), + userId: user.id, + name: ps.name + }).then(result => { + if (result.length > 0) { + throw new ApiError(meta.errors.nameAlreadyExists); + } + }); + + await Pages.update(page.id, { + updatedAt: new Date(), + title: ps.title, + name: ps.name === undefined ? page.name : ps.name, + summary: ps.name === undefined ? page.summary : ps.summary, + content: ps.content, + variables: ps.variables, + script: ps.script, + alignCenter: ps.alignCenter === undefined ? page.alignCenter : ps.alignCenter, + hideTitleWhenPinned: ps.hideTitleWhenPinned === undefined ? page.hideTitleWhenPinned : ps.hideTitleWhenPinned, + font: ps.font === undefined ? page.font : ps.font, + eyeCatchingImageId: ps.eyeCatchingImageId === null + ? null + : ps.eyeCatchingImageId === undefined + ? page.eyeCatchingImageId + : eyeCatchingImage!.id, + }); +}); diff --git a/src/server/api/endpoints/ping.ts b/packages/backend/src/server/api/endpoints/ping.ts similarity index 100% rename from src/server/api/endpoints/ping.ts rename to packages/backend/src/server/api/endpoints/ping.ts diff --git a/packages/backend/src/server/api/endpoints/pinned-users.ts b/packages/backend/src/server/api/endpoints/pinned-users.ts new file mode 100644 index 000000000..39cf7b0df --- /dev/null +++ b/packages/backend/src/server/api/endpoints/pinned-users.ts @@ -0,0 +1,32 @@ +import define from '../define'; +import { Users } from '@/models/index'; +import { fetchMeta } from '@/misc/fetch-meta'; +import * as Acct from 'misskey-js/built/acct'; +import { User } from '@/models/entities/user'; + +export const meta = { + tags: ['users'], + + requireCredential: false as const, + + params: { + }, + + res: { + type: 'array' as const, + optional: false as const, nullable: false as const, + items: { + type: 'object' as const, + optional: false as const, nullable: false as const, + ref: 'User', + } + }, +}; + +export default define(meta, async (ps, me) => { + const meta = await fetchMeta(); + + const users = await Promise.all(meta.pinnedUsers.map(acct => Users.findOne(Acct.parse(acct)))); + + return await Users.packMany(users.filter(x => x !== undefined) as User[], me, { detail: true }); +}); diff --git a/src/server/api/endpoints/promo/read.ts b/packages/backend/src/server/api/endpoints/promo/read.ts similarity index 100% rename from src/server/api/endpoints/promo/read.ts rename to packages/backend/src/server/api/endpoints/promo/read.ts diff --git a/packages/backend/src/server/api/endpoints/request-reset-password.ts b/packages/backend/src/server/api/endpoints/request-reset-password.ts new file mode 100644 index 000000000..7bb50bf6a --- /dev/null +++ b/packages/backend/src/server/api/endpoints/request-reset-password.ts @@ -0,0 +1,73 @@ +import $ from 'cafy'; +import { publishMainStream } from '@/services/stream'; +import define from '../define'; +import rndstr from 'rndstr'; +import config from '@/config/index'; +import ms from 'ms'; +import { Users, UserProfiles, PasswordResetRequests } from '@/models/index'; +import { sendEmail } from '@/services/send-email'; +import { ApiError } from '../error'; +import { genId } from '@/misc/gen-id'; +import { IsNull } from 'typeorm'; + +export const meta = { + requireCredential: false as const, + + limit: { + duration: ms('1hour'), + max: 3 + }, + + params: { + username: { + validator: $.str + }, + + email: { + validator: $.str + }, + }, + + errors: { + + } +}; + +export default define(meta, async (ps) => { + const user = await Users.findOne({ + usernameLower: ps.username.toLowerCase(), + host: IsNull() + }); + + // 合致するユーザーが登録されていなかったら無視 + if (user == null) { + return; + } + + const profile = await UserProfiles.findOneOrFail(user.id); + + // 合致するメアドが登録されていなかったら無視 + if (profile.email !== ps.email) { + return; + } + + // メアドが認証されていなかったら無視 + if (!profile.emailVerified) { + return; + } + + const token = rndstr('a-z0-9', 64); + + await PasswordResetRequests.insert({ + id: genId(), + createdAt: new Date(), + userId: profile.userId, + token + }); + + const link = `${config.url}/reset-password/${token}`; + + sendEmail(ps.email, 'Password reset requested', + `To reset password, please click this link:
${link}`, + `To reset password, please click this link: ${link}`); +}); diff --git a/src/server/api/endpoints/reset-db.ts b/packages/backend/src/server/api/endpoints/reset-db.ts similarity index 100% rename from src/server/api/endpoints/reset-db.ts rename to packages/backend/src/server/api/endpoints/reset-db.ts diff --git a/src/server/api/endpoints/reset-password.ts b/packages/backend/src/server/api/endpoints/reset-password.ts similarity index 100% rename from src/server/api/endpoints/reset-password.ts rename to packages/backend/src/server/api/endpoints/reset-password.ts diff --git a/src/server/api/endpoints/room/show.ts b/packages/backend/src/server/api/endpoints/room/show.ts similarity index 100% rename from src/server/api/endpoints/room/show.ts rename to packages/backend/src/server/api/endpoints/room/show.ts diff --git a/src/server/api/endpoints/room/update.ts b/packages/backend/src/server/api/endpoints/room/update.ts similarity index 100% rename from src/server/api/endpoints/room/update.ts rename to packages/backend/src/server/api/endpoints/room/update.ts diff --git a/src/server/api/endpoints/server-info.ts b/packages/backend/src/server/api/endpoints/server-info.ts similarity index 100% rename from src/server/api/endpoints/server-info.ts rename to packages/backend/src/server/api/endpoints/server-info.ts diff --git a/src/server/api/endpoints/stats.ts b/packages/backend/src/server/api/endpoints/stats.ts similarity index 100% rename from src/server/api/endpoints/stats.ts rename to packages/backend/src/server/api/endpoints/stats.ts diff --git a/src/server/api/endpoints/sw/register.ts b/packages/backend/src/server/api/endpoints/sw/register.ts similarity index 100% rename from src/server/api/endpoints/sw/register.ts rename to packages/backend/src/server/api/endpoints/sw/register.ts diff --git a/src/server/api/endpoints/sw/unregister.ts b/packages/backend/src/server/api/endpoints/sw/unregister.ts similarity index 100% rename from src/server/api/endpoints/sw/unregister.ts rename to packages/backend/src/server/api/endpoints/sw/unregister.ts diff --git a/src/server/api/endpoints/username/available.ts b/packages/backend/src/server/api/endpoints/username/available.ts similarity index 100% rename from src/server/api/endpoints/username/available.ts rename to packages/backend/src/server/api/endpoints/username/available.ts diff --git a/src/server/api/endpoints/users.ts b/packages/backend/src/server/api/endpoints/users.ts similarity index 100% rename from src/server/api/endpoints/users.ts rename to packages/backend/src/server/api/endpoints/users.ts diff --git a/src/server/api/endpoints/users/clips.ts b/packages/backend/src/server/api/endpoints/users/clips.ts similarity index 100% rename from src/server/api/endpoints/users/clips.ts rename to packages/backend/src/server/api/endpoints/users/clips.ts diff --git a/packages/backend/src/server/api/endpoints/users/followers.ts b/packages/backend/src/server/api/endpoints/users/followers.ts new file mode 100644 index 000000000..6d042a286 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/users/followers.ts @@ -0,0 +1,104 @@ +import $ from 'cafy'; +import { ID } from '@/misc/cafy-id'; +import define from '../../define'; +import { ApiError } from '../../error'; +import { Users, Followings, UserProfiles } from '@/models/index'; +import { makePaginationQuery } from '../../common/make-pagination-query'; +import { toPunyNullable } from '@/misc/convert-host'; + +export const meta = { + tags: ['users'], + + requireCredential: false as const, + + params: { + userId: { + validator: $.optional.type(ID), + }, + + username: { + validator: $.optional.str + }, + + host: { + validator: $.optional.nullable.str + }, + + sinceId: { + validator: $.optional.type(ID), + }, + + untilId: { + validator: $.optional.type(ID), + }, + + limit: { + validator: $.optional.num.range(1, 100), + default: 10 + }, + }, + + res: { + type: 'array' as const, + optional: false as const, nullable: false as const, + items: { + type: 'object' as const, + optional: false as const, nullable: false as const, + ref: 'Following', + } + }, + + errors: { + noSuchUser: { + message: 'No such user.', + code: 'NO_SUCH_USER', + id: '27fa5435-88ab-43de-9360-387de88727cd' + }, + + forbidden: { + message: 'Forbidden.', + code: 'FORBIDDEN', + id: '3c6a84db-d619-26af-ca14-06232a21df8a' + }, + } +}; + +export default define(meta, async (ps, me) => { + const user = await Users.findOne(ps.userId != null + ? { id: ps.userId } + : { usernameLower: ps.username!.toLowerCase(), host: toPunyNullable(ps.host) }); + + if (user == null) { + throw new ApiError(meta.errors.noSuchUser); + } + + const profile = await UserProfiles.findOneOrFail(user.id); + + if (profile.ffVisibility === 'private') { + if (me == null || (me.id !== user.id)) { + throw new ApiError(meta.errors.forbidden); + } + } else if (profile.ffVisibility === 'followers') { + if (me == null) { + throw new ApiError(meta.errors.forbidden); + } else if (me.id !== user.id) { + const following = await Followings.findOne({ + followeeId: user.id, + followerId: me.id, + }); + if (following == null) { + throw new ApiError(meta.errors.forbidden); + } + } + } + + const query = makePaginationQuery(Followings.createQueryBuilder('following'), ps.sinceId, ps.untilId) + .andWhere(`following.followeeId = :userId`, { userId: user.id }) + .innerJoinAndSelect('following.follower', 'follower'); + + const followings = await query + .take(ps.limit!) + .getMany(); + + return await Followings.packMany(followings, me, { populateFollower: true }); +}); diff --git a/packages/backend/src/server/api/endpoints/users/following.ts b/packages/backend/src/server/api/endpoints/users/following.ts new file mode 100644 index 000000000..1033117ef --- /dev/null +++ b/packages/backend/src/server/api/endpoints/users/following.ts @@ -0,0 +1,104 @@ +import $ from 'cafy'; +import { ID } from '@/misc/cafy-id'; +import define from '../../define'; +import { ApiError } from '../../error'; +import { Users, Followings, UserProfiles } from '@/models/index'; +import { makePaginationQuery } from '../../common/make-pagination-query'; +import { toPunyNullable } from '@/misc/convert-host'; + +export const meta = { + tags: ['users'], + + requireCredential: false as const, + + params: { + userId: { + validator: $.optional.type(ID), + }, + + username: { + validator: $.optional.str + }, + + host: { + validator: $.optional.nullable.str + }, + + sinceId: { + validator: $.optional.type(ID), + }, + + untilId: { + validator: $.optional.type(ID), + }, + + limit: { + validator: $.optional.num.range(1, 100), + default: 10 + }, + }, + + res: { + type: 'array' as const, + optional: false as const, nullable: false as const, + items: { + type: 'object' as const, + optional: false as const, nullable: false as const, + ref: 'Following', + } + }, + + errors: { + noSuchUser: { + message: 'No such user.', + code: 'NO_SUCH_USER', + id: '63e4aba4-4156-4e53-be25-c9559e42d71b' + }, + + forbidden: { + message: 'Forbidden.', + code: 'FORBIDDEN', + id: 'f6cdb0df-c19f-ec5c-7dbb-0ba84a1f92ba' + }, + } +}; + +export default define(meta, async (ps, me) => { + const user = await Users.findOne(ps.userId != null + ? { id: ps.userId } + : { usernameLower: ps.username!.toLowerCase(), host: toPunyNullable(ps.host) }); + + if (user == null) { + throw new ApiError(meta.errors.noSuchUser); + } + + const profile = await UserProfiles.findOneOrFail(user.id); + + if (profile.ffVisibility === 'private') { + if (me == null || (me.id !== user.id)) { + throw new ApiError(meta.errors.forbidden); + } + } else if (profile.ffVisibility === 'followers') { + if (me == null) { + throw new ApiError(meta.errors.forbidden); + } else if (me.id !== user.id) { + const following = await Followings.findOne({ + followeeId: user.id, + followerId: me.id, + }); + if (following == null) { + throw new ApiError(meta.errors.forbidden); + } + } + } + + const query = makePaginationQuery(Followings.createQueryBuilder('following'), ps.sinceId, ps.untilId) + .andWhere(`following.followerId = :userId`, { userId: user.id }) + .innerJoinAndSelect('following.followee', 'followee'); + + const followings = await query + .take(ps.limit!) + .getMany(); + + return await Followings.packMany(followings, me, { populateFollowee: true }); +}); diff --git a/src/server/api/endpoints/users/gallery/posts.ts b/packages/backend/src/server/api/endpoints/users/gallery/posts.ts similarity index 100% rename from src/server/api/endpoints/users/gallery/posts.ts rename to packages/backend/src/server/api/endpoints/users/gallery/posts.ts diff --git a/src/server/api/endpoints/users/get-frequently-replied-users.ts b/packages/backend/src/server/api/endpoints/users/get-frequently-replied-users.ts similarity index 100% rename from src/server/api/endpoints/users/get-frequently-replied-users.ts rename to packages/backend/src/server/api/endpoints/users/get-frequently-replied-users.ts diff --git a/src/server/api/endpoints/users/groups/create.ts b/packages/backend/src/server/api/endpoints/users/groups/create.ts similarity index 100% rename from src/server/api/endpoints/users/groups/create.ts rename to packages/backend/src/server/api/endpoints/users/groups/create.ts diff --git a/src/server/api/endpoints/users/groups/delete.ts b/packages/backend/src/server/api/endpoints/users/groups/delete.ts similarity index 100% rename from src/server/api/endpoints/users/groups/delete.ts rename to packages/backend/src/server/api/endpoints/users/groups/delete.ts diff --git a/src/server/api/endpoints/users/groups/invitations/accept.ts b/packages/backend/src/server/api/endpoints/users/groups/invitations/accept.ts similarity index 100% rename from src/server/api/endpoints/users/groups/invitations/accept.ts rename to packages/backend/src/server/api/endpoints/users/groups/invitations/accept.ts diff --git a/src/server/api/endpoints/users/groups/invitations/reject.ts b/packages/backend/src/server/api/endpoints/users/groups/invitations/reject.ts similarity index 100% rename from src/server/api/endpoints/users/groups/invitations/reject.ts rename to packages/backend/src/server/api/endpoints/users/groups/invitations/reject.ts diff --git a/src/server/api/endpoints/users/groups/invite.ts b/packages/backend/src/server/api/endpoints/users/groups/invite.ts similarity index 100% rename from src/server/api/endpoints/users/groups/invite.ts rename to packages/backend/src/server/api/endpoints/users/groups/invite.ts diff --git a/src/server/api/endpoints/users/groups/joined.ts b/packages/backend/src/server/api/endpoints/users/groups/joined.ts similarity index 100% rename from src/server/api/endpoints/users/groups/joined.ts rename to packages/backend/src/server/api/endpoints/users/groups/joined.ts diff --git a/src/server/api/endpoints/users/groups/leave.ts b/packages/backend/src/server/api/endpoints/users/groups/leave.ts similarity index 100% rename from src/server/api/endpoints/users/groups/leave.ts rename to packages/backend/src/server/api/endpoints/users/groups/leave.ts diff --git a/src/server/api/endpoints/users/groups/owned.ts b/packages/backend/src/server/api/endpoints/users/groups/owned.ts similarity index 100% rename from src/server/api/endpoints/users/groups/owned.ts rename to packages/backend/src/server/api/endpoints/users/groups/owned.ts diff --git a/src/server/api/endpoints/users/groups/pull.ts b/packages/backend/src/server/api/endpoints/users/groups/pull.ts similarity index 100% rename from src/server/api/endpoints/users/groups/pull.ts rename to packages/backend/src/server/api/endpoints/users/groups/pull.ts diff --git a/src/server/api/endpoints/users/groups/show.ts b/packages/backend/src/server/api/endpoints/users/groups/show.ts similarity index 100% rename from src/server/api/endpoints/users/groups/show.ts rename to packages/backend/src/server/api/endpoints/users/groups/show.ts diff --git a/src/server/api/endpoints/users/groups/transfer.ts b/packages/backend/src/server/api/endpoints/users/groups/transfer.ts similarity index 100% rename from src/server/api/endpoints/users/groups/transfer.ts rename to packages/backend/src/server/api/endpoints/users/groups/transfer.ts diff --git a/src/server/api/endpoints/users/groups/update.ts b/packages/backend/src/server/api/endpoints/users/groups/update.ts similarity index 100% rename from src/server/api/endpoints/users/groups/update.ts rename to packages/backend/src/server/api/endpoints/users/groups/update.ts diff --git a/src/server/api/endpoints/users/lists/create.ts b/packages/backend/src/server/api/endpoints/users/lists/create.ts similarity index 100% rename from src/server/api/endpoints/users/lists/create.ts rename to packages/backend/src/server/api/endpoints/users/lists/create.ts diff --git a/src/server/api/endpoints/users/lists/delete.ts b/packages/backend/src/server/api/endpoints/users/lists/delete.ts similarity index 100% rename from src/server/api/endpoints/users/lists/delete.ts rename to packages/backend/src/server/api/endpoints/users/lists/delete.ts diff --git a/src/server/api/endpoints/users/lists/list.ts b/packages/backend/src/server/api/endpoints/users/lists/list.ts similarity index 100% rename from src/server/api/endpoints/users/lists/list.ts rename to packages/backend/src/server/api/endpoints/users/lists/list.ts diff --git a/src/server/api/endpoints/users/lists/pull.ts b/packages/backend/src/server/api/endpoints/users/lists/pull.ts similarity index 100% rename from src/server/api/endpoints/users/lists/pull.ts rename to packages/backend/src/server/api/endpoints/users/lists/pull.ts diff --git a/src/server/api/endpoints/users/lists/push.ts b/packages/backend/src/server/api/endpoints/users/lists/push.ts similarity index 100% rename from src/server/api/endpoints/users/lists/push.ts rename to packages/backend/src/server/api/endpoints/users/lists/push.ts diff --git a/src/server/api/endpoints/users/lists/show.ts b/packages/backend/src/server/api/endpoints/users/lists/show.ts similarity index 100% rename from src/server/api/endpoints/users/lists/show.ts rename to packages/backend/src/server/api/endpoints/users/lists/show.ts diff --git a/src/server/api/endpoints/users/lists/update.ts b/packages/backend/src/server/api/endpoints/users/lists/update.ts similarity index 100% rename from src/server/api/endpoints/users/lists/update.ts rename to packages/backend/src/server/api/endpoints/users/lists/update.ts diff --git a/src/server/api/endpoints/users/notes.ts b/packages/backend/src/server/api/endpoints/users/notes.ts similarity index 100% rename from src/server/api/endpoints/users/notes.ts rename to packages/backend/src/server/api/endpoints/users/notes.ts diff --git a/src/server/api/endpoints/users/pages.ts b/packages/backend/src/server/api/endpoints/users/pages.ts similarity index 100% rename from src/server/api/endpoints/users/pages.ts rename to packages/backend/src/server/api/endpoints/users/pages.ts diff --git a/src/server/api/endpoints/users/reactions.ts b/packages/backend/src/server/api/endpoints/users/reactions.ts similarity index 100% rename from src/server/api/endpoints/users/reactions.ts rename to packages/backend/src/server/api/endpoints/users/reactions.ts diff --git a/packages/backend/src/server/api/endpoints/users/recommendation.ts b/packages/backend/src/server/api/endpoints/users/recommendation.ts new file mode 100644 index 000000000..7c775c4dc --- /dev/null +++ b/packages/backend/src/server/api/endpoints/users/recommendation.ts @@ -0,0 +1,63 @@ +import ms from 'ms'; +import $ from 'cafy'; +import define from '../../define'; +import { Users, Followings } from '@/models/index'; +import { generateMutedUserQueryForUsers } from '../../common/generate-muted-user-query'; +import { generateBlockedUserQuery, generateBlockQueryForUsers } from '../../common/generate-block-query'; + +export const meta = { + tags: ['users'], + + requireCredential: true as const, + + kind: 'read:account', + + params: { + limit: { + validator: $.optional.num.range(1, 100), + default: 10 + }, + + offset: { + validator: $.optional.num.min(0), + default: 0 + } + }, + + res: { + type: 'array' as const, + optional: false as const, nullable: false as const, + items: { + type: 'object' as const, + optional: false as const, nullable: false as const, + ref: 'User', + } + }, +}; + +export default define(meta, async (ps, me) => { + const query = Users.createQueryBuilder('user') + .where('user.isLocked = FALSE') + .andWhere('user.isExplorable = TRUE') + .andWhere('user.host IS NULL') + .andWhere('user.updatedAt >= :date', { date: new Date(Date.now() - ms('7days')) }) + .andWhere('user.id != :meId', { meId: me.id }) + .orderBy('user.followersCount', 'DESC'); + + generateMutedUserQueryForUsers(query, me); + generateBlockQueryForUsers(query, me); + generateBlockedUserQuery(query, me); + + const followingQuery = Followings.createQueryBuilder('following') + .select('following.followeeId') + .where('following.followerId = :followerId', { followerId: me.id }); + + query + .andWhere(`user.id NOT IN (${ followingQuery.getQuery() })`); + + query.setParameters(followingQuery.getParameters()); + + const users = await query.take(ps.limit!).skip(ps.offset).getMany(); + + return await Users.packMany(users, me, { detail: true }); +}); diff --git a/src/server/api/endpoints/users/relation.ts b/packages/backend/src/server/api/endpoints/users/relation.ts similarity index 100% rename from src/server/api/endpoints/users/relation.ts rename to packages/backend/src/server/api/endpoints/users/relation.ts diff --git a/packages/backend/src/server/api/endpoints/users/report-abuse.ts b/packages/backend/src/server/api/endpoints/users/report-abuse.ts new file mode 100644 index 000000000..a1d837665 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/users/report-abuse.ts @@ -0,0 +1,101 @@ +import $ from 'cafy'; +import * as sanitizeHtml from 'sanitize-html'; +import { ID } from '@/misc/cafy-id'; +import define from '../../define'; +import { publishAdminStream } from '@/services/stream'; +import { ApiError } from '../../error'; +import { getUser } from '../../common/getters'; +import { AbuseUserReports, Users } from '@/models/index'; +import { genId } from '@/misc/gen-id'; +import { sendEmail } from '@/services/send-email'; +import { fetchMeta } from '@/misc/fetch-meta'; + +export const meta = { + tags: ['users'], + + requireCredential: true as const, + + params: { + userId: { + validator: $.type(ID), + }, + + comment: { + validator: $.str.range(1, 2048), + }, + }, + + errors: { + noSuchUser: { + message: 'No such user.', + code: 'NO_SUCH_USER', + id: '1acefcb5-0959-43fd-9685-b48305736cb5', + }, + + cannotReportYourself: { + message: 'Cannot report yourself.', + code: 'CANNOT_REPORT_YOURSELF', + id: '1e13149e-b1e8-43cf-902e-c01dbfcb202f', + }, + + cannotReportAdmin: { + message: 'Cannot report the admin.', + code: 'CANNOT_REPORT_THE_ADMIN', + id: '35e166f5-05fb-4f87-a2d5-adb42676d48f', + }, + }, +}; + +// eslint-disable-next-line import/no-default-export +export default define(meta, async (ps, me) => { + // Lookup user + const user = await getUser(ps.userId).catch(e => { + if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser); + throw e; + }); + + if (user.id === me.id) { + throw new ApiError(meta.errors.cannotReportYourself); + } + + if (user.isAdmin) { + throw new ApiError(meta.errors.cannotReportAdmin); + } + + const report = await AbuseUserReports.save({ + id: genId(), + createdAt: new Date(), + targetUserId: user.id, + targetUserHost: user.host, + reporterId: me.id, + reporterHost: null, + comment: ps.comment, + }); + + // Publish event to moderators + setTimeout(async () => { + const moderators = await Users.find({ + where: [{ + isAdmin: true, + }, { + isModerator: true, + }], + }); + + for (const moderator of moderators) { + publishAdminStream(moderator.id, 'newAbuseUserReport', { + id: report.id, + targetUserId: report.targetUserId, + reporterId: report.reporterId, + comment: report.comment, + }); + } + + const meta = await fetchMeta(); + if (meta.email) { + sendEmail(meta.email, 'New abuse report', + sanitizeHtml(ps.comment), + sanitizeHtml(ps.comment)); + } + }, 1); +}); diff --git a/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 similarity index 100% rename from src/server/api/endpoints/users/search-by-username-and-host.ts rename to packages/backend/src/server/api/endpoints/users/search-by-username-and-host.ts diff --git a/src/server/api/endpoints/users/search.ts b/packages/backend/src/server/api/endpoints/users/search.ts similarity index 100% rename from src/server/api/endpoints/users/search.ts rename to packages/backend/src/server/api/endpoints/users/search.ts diff --git a/src/server/api/endpoints/users/show.ts b/packages/backend/src/server/api/endpoints/users/show.ts similarity index 100% rename from src/server/api/endpoints/users/show.ts rename to packages/backend/src/server/api/endpoints/users/show.ts diff --git a/src/server/api/endpoints/users/stats.ts b/packages/backend/src/server/api/endpoints/users/stats.ts similarity index 100% rename from src/server/api/endpoints/users/stats.ts rename to packages/backend/src/server/api/endpoints/users/stats.ts diff --git a/src/server/api/error.ts b/packages/backend/src/server/api/error.ts similarity index 100% rename from src/server/api/error.ts rename to packages/backend/src/server/api/error.ts diff --git a/src/server/api/index.ts b/packages/backend/src/server/api/index.ts similarity index 100% rename from src/server/api/index.ts rename to packages/backend/src/server/api/index.ts diff --git a/packages/backend/src/server/api/limiter.ts b/packages/backend/src/server/api/limiter.ts new file mode 100644 index 000000000..82a8613c9 --- /dev/null +++ b/packages/backend/src/server/api/limiter.ts @@ -0,0 +1,83 @@ +import * as Limiter from 'ratelimiter'; +import { redisClient } from '../../db/redis'; +import { IEndpoint } from './endpoints'; +import * as Acct from 'misskey-js/built/acct'; +import { User } from '@/models/entities/user'; +import Logger from '@/services/logger'; + +const logger = new Logger('limiter'); + +export default (endpoint: IEndpoint, user: User) => new Promise((ok, reject) => { + const limitation = endpoint.meta.limit!; + + const key = Object.prototype.hasOwnProperty.call(limitation, 'key') + ? limitation.key + : endpoint.name; + + const hasShortTermLimit = + Object.prototype.hasOwnProperty.call(limitation, 'minInterval'); + + const hasLongTermLimit = + Object.prototype.hasOwnProperty.call(limitation, 'duration') && + Object.prototype.hasOwnProperty.call(limitation, 'max'); + + if (hasShortTermLimit) { + min(); + } else if (hasLongTermLimit) { + max(); + } else { + ok(); + } + + // Short-term limit + function min() { + const minIntervalLimiter = new Limiter({ + id: `${user.id}:${key}:min`, + duration: limitation.minInterval, + max: 1, + db: redisClient + }); + + minIntervalLimiter.get((err, info) => { + if (err) { + return reject('ERR'); + } + + logger.debug(`@${Acct.toString(user)} ${endpoint.name} min remaining: ${info.remaining}`); + + if (info.remaining === 0) { + reject('BRIEF_REQUEST_INTERVAL'); + } else { + if (hasLongTermLimit) { + max(); + } else { + ok(); + } + } + }); + } + + // Long term limit + function max() { + const limiter = new Limiter({ + id: `${user.id}:${key}`, + duration: limitation.duration, + max: limitation.max, + db: redisClient + }); + + limiter.get((err, info) => { + if (err) { + return reject('ERR'); + } + + logger.debug(`@${Acct.toString(user)} ${endpoint.name} max remaining: ${info.remaining}`); + + if (info.remaining === 0) { + reject('RATE_LIMIT_EXCEEDED'); + } else { + ok(); + } + }); + } +}); diff --git a/src/server/api/logger.ts b/packages/backend/src/server/api/logger.ts similarity index 100% rename from src/server/api/logger.ts rename to packages/backend/src/server/api/logger.ts diff --git a/src/server/api/openapi/errors.ts b/packages/backend/src/server/api/openapi/errors.ts similarity index 100% rename from src/server/api/openapi/errors.ts rename to packages/backend/src/server/api/openapi/errors.ts diff --git a/packages/backend/src/server/api/openapi/gen-spec.ts b/packages/backend/src/server/api/openapi/gen-spec.ts new file mode 100644 index 000000000..48b819727 --- /dev/null +++ b/packages/backend/src/server/api/openapi/gen-spec.ts @@ -0,0 +1,235 @@ +import endpoints from '../endpoints'; +import { Context } from 'cafy'; +import config from '@/config/index'; +import { errors as basicErrors } from './errors'; +import { schemas, convertSchemaToOpenApiSchema } from './schemas'; + +export function genOpenapiSpec(lang = 'ja-JP') { + const spec = { + openapi: '3.0.0', + + info: { + version: 'v1', + title: 'Misskey API', + 'x-logo': { url: '/static-assets/api-doc.png' } + }, + + externalDocs: { + description: 'Repository', + url: 'https://github.com/misskey-dev/misskey' + }, + + servers: [{ + url: config.apiUrl + }], + + paths: {} as any, + + components: { + schemas: schemas, + + securitySchemes: { + ApiKeyAuth: { + type: 'apiKey', + in: 'body', + name: 'i' + } + } + } + }; + + function genProps(props: { [key: string]: Context; }) { + const properties = {} as any; + + for (const [k, v] of Object.entries(props)) { + properties[k] = genProp(v); + } + + return properties; + } + + function genProp(param: Context): any { + const required = param.name === 'Object' ? (param as any).props ? Object.entries((param as any).props).filter(([k, v]: any) => !v.isOptional).map(([k, v]) => k) : [] : []; + return { + description: (param.data || {}).desc, + default: (param.data || {}).default, + deprecated: (param.data || {}).deprecated, + ...((param.data || {}).default ? { default: (param.data || {}).default } : {}), + type: param.name === 'ID' ? 'string' : param.name.toLowerCase(), + ...(param.name === 'ID' ? { example: 'xxxxxxxxxx', format: 'id' } : {}), + nullable: param.isNullable, + ...(param.name === 'String' ? { + ...((param as any).enum ? { enum: (param as any).enum } : {}), + ...((param as any).minLength ? { minLength: (param as any).minLength } : {}), + ...((param as any).maxLength ? { maxLength: (param as any).maxLength } : {}), + } : {}), + ...(param.name === 'Number' ? { + ...((param as any).minimum ? { minimum: (param as any).minimum } : {}), + ...((param as any).maximum ? { maximum: (param as any).maximum } : {}), + } : {}), + ...(param.name === 'Object' ? { + ...(required.length > 0 ? { required } : {}), + properties: (param as any).props ? genProps((param as any).props) : {} + } : {}), + ...(param.name === 'Array' ? { + items: (param as any).ctx ? genProp((param as any).ctx) : {} + } : {}) + }; + } + + for (const endpoint of endpoints.filter(ep => !ep.meta.secure)) { + const porops = {} as any; + const errors = {} as any; + + if (endpoint.meta.errors) { + for (const e of Object.values(endpoint.meta.errors)) { + errors[e.code] = { + value: { + error: e + } + }; + } + } + + if (endpoint.meta.params) { + for (const [k, v] of Object.entries(endpoint.meta.params)) { + if (v.validator.data == null) v.validator.data = {}; + if (v.desc) v.validator.data.desc = v.desc[lang]; + if (v.deprecated) v.validator.data.deprecated = v.deprecated; + if (v.default) v.validator.data.default = v.default; + porops[k] = v.validator; + } + } + + const required = endpoint.meta.params ? Object.entries(endpoint.meta.params).filter(([k, v]) => !v.validator.isOptional).map(([k, v]) => k) : []; + + const resSchema = endpoint.meta.res ? convertSchemaToOpenApiSchema(endpoint.meta.res) : {}; + + let desc = (endpoint.meta.desc ? endpoint.meta.desc[lang] : 'No description provided.') + '\n\n'; + desc += `**Credential required**: *${endpoint.meta.requireCredential ? 'Yes' : 'No'}*`; + if (endpoint.meta.kind) { + const kind = endpoint.meta.kind; + desc += ` / **Permission**: *${kind}*`; + } + + const info = { + operationId: endpoint.name, + summary: endpoint.name, + description: desc, + externalDocs: { + description: 'Source code', + url: `https://github.com/misskey-dev/misskey/blob/develop/src/server/api/endpoints/${endpoint.name}.ts` + }, + ...(endpoint.meta.tags ? { + tags: [endpoint.meta.tags[0]] + } : {}), + ...(endpoint.meta.requireCredential ? { + security: [{ + ApiKeyAuth: [] + }] + } : {}), + requestBody: { + required: true, + content: { + 'application/json': { + schema: { + type: 'object', + ...(required.length > 0 ? { required } : {}), + properties: endpoint.meta.params ? genProps(porops) : {} + } + } + } + }, + responses: { + ...(endpoint.meta.res ? { + '200': { + description: 'OK (with results)', + content: { + 'application/json': { + schema: resSchema + } + } + } + } : { + '204': { + description: 'OK (without any results)', + } + }), + '400': { + description: 'Client error', + content: { + 'application/json': { + schema: { + $ref: '#/components/schemas/Error' + }, + examples: { ...errors, ...basicErrors['400'] } + } + } + }, + '401': { + description: 'Authentication error', + content: { + 'application/json': { + schema: { + $ref: '#/components/schemas/Error' + }, + examples: basicErrors['401'] + } + } + }, + '403': { + description: 'Forbidden error', + content: { + 'application/json': { + schema: { + $ref: '#/components/schemas/Error' + }, + examples: basicErrors['403'] + } + } + }, + '418': { + description: 'I\'m Ai', + content: { + 'application/json': { + schema: { + $ref: '#/components/schemas/Error' + }, + examples: basicErrors['418'] + } + } + }, + ...(endpoint.meta.limit ? { + '429': { + description: 'To many requests', + content: { + 'application/json': { + schema: { + $ref: '#/components/schemas/Error' + }, + examples: basicErrors['429'] + } + } + } + } : {}), + '500': { + description: 'Internal server error', + content: { + 'application/json': { + schema: { + $ref: '#/components/schemas/Error' + }, + examples: basicErrors['500'] + } + } + }, + } + }; + + spec.paths['/' + endpoint.name] = { + post: info + }; + } + + return spec; +} diff --git a/src/server/api/openapi/schemas.ts b/packages/backend/src/server/api/openapi/schemas.ts similarity index 100% rename from src/server/api/openapi/schemas.ts rename to packages/backend/src/server/api/openapi/schemas.ts diff --git a/src/server/api/private/signin.ts b/packages/backend/src/server/api/private/signin.ts similarity index 100% rename from src/server/api/private/signin.ts rename to packages/backend/src/server/api/private/signin.ts diff --git a/src/server/api/private/signup-pending.ts b/packages/backend/src/server/api/private/signup-pending.ts similarity index 100% rename from src/server/api/private/signup-pending.ts rename to packages/backend/src/server/api/private/signup-pending.ts diff --git a/packages/backend/src/server/api/private/signup.ts b/packages/backend/src/server/api/private/signup.ts new file mode 100644 index 000000000..2b6a3eb00 --- /dev/null +++ b/packages/backend/src/server/api/private/signup.ts @@ -0,0 +1,112 @@ +import * as Koa from 'koa'; +import rndstr from 'rndstr'; +import * as bcrypt from 'bcryptjs'; +import { fetchMeta } from '@/misc/fetch-meta'; +import { verifyHcaptcha, verifyRecaptcha } from '@/misc/captcha'; +import { Users, RegistrationTickets, UserPendings } from '@/models/index'; +import { signup } from '../common/signup'; +import config from '@/config'; +import { sendEmail } from '@/services/send-email'; +import { genId } from '@/misc/gen-id'; +import { validateEmailForAccount } from '@/services/validate-email-for-account'; + +export default async (ctx: Koa.Context) => { + const body = ctx.request.body; + + const instance = await fetchMeta(true); + + // Verify *Captcha + // ただしテスト時はこの機構は障害となるため無効にする + if (process.env.NODE_ENV !== 'test') { + if (instance.enableHcaptcha && instance.hcaptchaSecretKey) { + await verifyHcaptcha(instance.hcaptchaSecretKey, body['hcaptcha-response']).catch(e => { + ctx.throw(400, e); + }); + } + + if (instance.enableRecaptcha && instance.recaptchaSecretKey) { + await verifyRecaptcha(instance.recaptchaSecretKey, body['g-recaptcha-response']).catch(e => { + ctx.throw(400, e); + }); + } + } + + const username = body['username']; + const password = body['password']; + const host: string | null = process.env.NODE_ENV === 'test' ? (body['host'] || null) : null; + const invitationCode = body['invitationCode']; + const emailAddress = body['emailAddress']; + + if (instance.emailRequiredForSignup) { + if (emailAddress == null || typeof emailAddress != 'string') { + ctx.status = 400; + return; + } + + const available = await validateEmailForAccount(emailAddress); + if (!available) { + ctx.status = 400; + return; + } + } + + if (instance.disableRegistration) { + if (invitationCode == null || typeof invitationCode != 'string') { + ctx.status = 400; + return; + } + + const ticket = await RegistrationTickets.findOne({ + code: invitationCode + }); + + if (ticket == null) { + ctx.status = 400; + return; + } + + RegistrationTickets.delete(ticket.id); + } + + if (instance.emailRequiredForSignup) { + const code = rndstr('a-z0-9', 16); + + // Generate hash of password + const salt = await bcrypt.genSalt(8); + const hash = await bcrypt.hash(password, salt); + + await UserPendings.insert({ + id: genId(), + createdAt: new Date(), + code, + email: emailAddress, + username: username, + password: hash, + }); + + const link = `${config.url}/signup-complete/${code}`; + + sendEmail(emailAddress, 'Signup', + `To complete signup, please click this link:
${link}`, + `To complete signup, please click this link: ${link}`); + + ctx.status = 204; + } else { + try { + const { account, secret } = await signup({ + username, password, host + }); + + const res = await Users.pack(account, account, { + detail: true, + includeSecrets: true + }); + + (res as any).token = secret; + + ctx.body = res; + } catch (e) { + ctx.throw(400, e); + } + } +}; diff --git a/src/server/api/service/discord.ts b/packages/backend/src/server/api/service/discord.ts similarity index 100% rename from src/server/api/service/discord.ts rename to packages/backend/src/server/api/service/discord.ts diff --git a/src/server/api/service/github.ts b/packages/backend/src/server/api/service/github.ts similarity index 100% rename from src/server/api/service/github.ts rename to packages/backend/src/server/api/service/github.ts diff --git a/src/server/api/service/twitter.ts b/packages/backend/src/server/api/service/twitter.ts similarity index 100% rename from src/server/api/service/twitter.ts rename to packages/backend/src/server/api/service/twitter.ts diff --git a/src/server/api/stream/channel.ts b/packages/backend/src/server/api/stream/channel.ts similarity index 100% rename from src/server/api/stream/channel.ts rename to packages/backend/src/server/api/stream/channel.ts diff --git a/src/server/api/stream/channels/admin.ts b/packages/backend/src/server/api/stream/channels/admin.ts similarity index 100% rename from src/server/api/stream/channels/admin.ts rename to packages/backend/src/server/api/stream/channels/admin.ts diff --git a/src/server/api/stream/channels/antenna.ts b/packages/backend/src/server/api/stream/channels/antenna.ts similarity index 100% rename from src/server/api/stream/channels/antenna.ts rename to packages/backend/src/server/api/stream/channels/antenna.ts diff --git a/src/server/api/stream/channels/channel.ts b/packages/backend/src/server/api/stream/channels/channel.ts similarity index 100% rename from src/server/api/stream/channels/channel.ts rename to packages/backend/src/server/api/stream/channels/channel.ts diff --git a/src/server/api/stream/channels/drive.ts b/packages/backend/src/server/api/stream/channels/drive.ts similarity index 100% rename from src/server/api/stream/channels/drive.ts rename to packages/backend/src/server/api/stream/channels/drive.ts diff --git a/src/server/api/stream/channels/games/reversi-game.ts b/packages/backend/src/server/api/stream/channels/games/reversi-game.ts similarity index 100% rename from src/server/api/stream/channels/games/reversi-game.ts rename to packages/backend/src/server/api/stream/channels/games/reversi-game.ts diff --git a/packages/backend/src/server/api/stream/channels/games/reversi.ts b/packages/backend/src/server/api/stream/channels/games/reversi.ts new file mode 100644 index 000000000..399750c26 --- /dev/null +++ b/packages/backend/src/server/api/stream/channels/games/reversi.ts @@ -0,0 +1,34 @@ +import autobind from 'autobind-decorator'; +import { publishMainStream } from '@/services/stream'; +import Channel from '../../channel'; +import { ReversiMatchings } from '@/models/index'; + +export default class extends Channel { + public readonly chName = 'gamesReversi'; + public static shouldShare = true; + public static requireCredential = true; + + @autobind + public async init(params: any) { + // Subscribe reversi stream + this.subscriber.on(`reversiStream:${this.user!.id}`, data => { + this.send(data); + }); + } + + @autobind + public async onMessage(type: string, body: any) { + switch (type) { + case 'ping': { + if (body.id == null) return; + const matching = await ReversiMatchings.findOne({ + parentId: this.user!.id, + childId: body.id + }); + if (matching == null) return; + publishMainStream(matching.childId, 'reversiInvited', await ReversiMatchings.pack(matching, { id: matching.childId })); + break; + } + } + } +} diff --git a/src/server/api/stream/channels/global-timeline.ts b/packages/backend/src/server/api/stream/channels/global-timeline.ts similarity index 100% rename from src/server/api/stream/channels/global-timeline.ts rename to packages/backend/src/server/api/stream/channels/global-timeline.ts diff --git a/src/server/api/stream/channels/hashtag.ts b/packages/backend/src/server/api/stream/channels/hashtag.ts similarity index 100% rename from src/server/api/stream/channels/hashtag.ts rename to packages/backend/src/server/api/stream/channels/hashtag.ts diff --git a/src/server/api/stream/channels/home-timeline.ts b/packages/backend/src/server/api/stream/channels/home-timeline.ts similarity index 100% rename from src/server/api/stream/channels/home-timeline.ts rename to packages/backend/src/server/api/stream/channels/home-timeline.ts diff --git a/src/server/api/stream/channels/hybrid-timeline.ts b/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts similarity index 100% rename from src/server/api/stream/channels/hybrid-timeline.ts rename to packages/backend/src/server/api/stream/channels/hybrid-timeline.ts diff --git a/src/server/api/stream/channels/index.ts b/packages/backend/src/server/api/stream/channels/index.ts similarity index 100% rename from src/server/api/stream/channels/index.ts rename to packages/backend/src/server/api/stream/channels/index.ts diff --git a/src/server/api/stream/channels/local-timeline.ts b/packages/backend/src/server/api/stream/channels/local-timeline.ts similarity index 100% rename from src/server/api/stream/channels/local-timeline.ts rename to packages/backend/src/server/api/stream/channels/local-timeline.ts diff --git a/src/server/api/stream/channels/main.ts b/packages/backend/src/server/api/stream/channels/main.ts similarity index 100% rename from src/server/api/stream/channels/main.ts rename to packages/backend/src/server/api/stream/channels/main.ts diff --git a/src/server/api/stream/channels/messaging-index.ts b/packages/backend/src/server/api/stream/channels/messaging-index.ts similarity index 100% rename from src/server/api/stream/channels/messaging-index.ts rename to packages/backend/src/server/api/stream/channels/messaging-index.ts diff --git a/src/server/api/stream/channels/messaging.ts b/packages/backend/src/server/api/stream/channels/messaging.ts similarity index 100% rename from src/server/api/stream/channels/messaging.ts rename to packages/backend/src/server/api/stream/channels/messaging.ts diff --git a/src/server/api/stream/channels/queue-stats.ts b/packages/backend/src/server/api/stream/channels/queue-stats.ts similarity index 100% rename from src/server/api/stream/channels/queue-stats.ts rename to packages/backend/src/server/api/stream/channels/queue-stats.ts diff --git a/src/server/api/stream/channels/server-stats.ts b/packages/backend/src/server/api/stream/channels/server-stats.ts similarity index 100% rename from src/server/api/stream/channels/server-stats.ts rename to packages/backend/src/server/api/stream/channels/server-stats.ts diff --git a/src/server/api/stream/channels/user-list.ts b/packages/backend/src/server/api/stream/channels/user-list.ts similarity index 100% rename from src/server/api/stream/channels/user-list.ts rename to packages/backend/src/server/api/stream/channels/user-list.ts diff --git a/src/server/api/stream/index.ts b/packages/backend/src/server/api/stream/index.ts similarity index 100% rename from src/server/api/stream/index.ts rename to packages/backend/src/server/api/stream/index.ts diff --git a/packages/backend/src/server/api/stream/types.ts b/packages/backend/src/server/api/stream/types.ts new file mode 100644 index 000000000..f4302f64a --- /dev/null +++ b/packages/backend/src/server/api/stream/types.ts @@ -0,0 +1,299 @@ +import { EventEmitter } from 'events'; +import Emitter from 'strict-event-emitter-types'; +import { Channel } from '@/models/entities/channel'; +import { User } from '@/models/entities/user'; +import { UserProfile } from '@/models/entities/user-profile'; +import { Note } from '@/models/entities/note'; +import { Antenna } from '@/models/entities/antenna'; +import { DriveFile } from '@/models/entities/drive-file'; +import { DriveFolder } from '@/models/entities/drive-folder'; +import { Emoji } from '@/models/entities/emoji'; +import { UserList } from '@/models/entities/user-list'; +import { MessagingMessage } from '@/models/entities/messaging-message'; +import { UserGroup } from '@/models/entities/user-group'; +import { ReversiGame } from '@/models/entities/games/reversi/game'; +import { AbuseUserReport } from '@/models/entities/abuse-user-report'; +import { Signin } from '@/models/entities/signin'; +import { Page } from '@/models/entities/page'; +import { Packed } from '@/misc/schema'; + +//#region Stream type-body definitions +export interface InternalStreamTypes { + antennaCreated: Antenna; + antennaDeleted: Antenna; + antennaUpdated: Antenna; +} + +export interface BroadcastTypes { + emojiAdded: { + emoji: Packed<'Emoji'>; + }; +} + +export interface UserStreamTypes { + terminate: Record; + followChannel: Channel; + unfollowChannel: Channel; + updateUserProfile: UserProfile; + mute: User; + unmute: User; + follow: Packed<'User'>; + unfollow: Packed<'User'>; + userAdded: Packed<'User'>; +} + +export interface MainStreamTypes { + notification: Packed<'Notification'>; + mention: Packed<'Note'>; + reply: Packed<'Note'>; + renote: Packed<'Note'>; + follow: Packed<'User'>; + followed: Packed<'User'>; + unfollow: Packed<'User'>; + meUpdated: Packed<'User'>; + pageEvent: { + pageId: Page['id']; + event: string; + var: any; + userId: User['id']; + user: Packed<'User'>; + }; + urlUploadFinished: { + marker?: string | null; + file: Packed<'DriveFile'>; + }; + readAllNotifications: undefined; + unreadNotification: Packed<'Notification'>; + unreadMention: Note['id']; + readAllUnreadMentions: undefined; + unreadSpecifiedNote: Note['id']; + readAllUnreadSpecifiedNotes: undefined; + readAllMessagingMessages: undefined; + messagingMessage: Packed<'MessagingMessage'>; + unreadMessagingMessage: Packed<'MessagingMessage'>; + readAllAntennas: undefined; + unreadAntenna: Antenna; + readAllAnnouncements: undefined; + readAllChannels: undefined; + unreadChannel: Note['id']; + myTokenRegenerated: undefined; + reversiNoInvites: undefined; + reversiInvited: Packed<'ReversiMatching'>; + signin: Signin; + registryUpdated: { + scope?: string[]; + key: string; + value: any | null; + }; + driveFileCreated: Packed<'DriveFile'>; + readAntenna: Antenna; +} + +export interface DriveStreamTypes { + fileCreated: Packed<'DriveFile'>; + fileDeleted: DriveFile['id']; + fileUpdated: Packed<'DriveFile'>; + folderCreated: Packed<'DriveFolder'>; + folderDeleted: DriveFolder['id']; + folderUpdated: Packed<'DriveFolder'>; +} + +export interface NoteStreamTypes { + pollVoted: { + choice: number; + userId: User['id']; + }; + deleted: { + deletedAt: Date; + }; + reacted: { + reaction: string; + emoji?: Emoji; + userId: User['id']; + }; + unreacted: { + reaction: string; + userId: User['id']; + }; +} +type NoteStreamEventTypes = { + [key in keyof NoteStreamTypes]: { + id: Note['id']; + body: NoteStreamTypes[key]; + }; +}; + +export interface ChannelStreamTypes { + typing: User['id']; +} + +export interface UserListStreamTypes { + userAdded: Packed<'User'>; + userRemoved: Packed<'User'>; +} + +export interface AntennaStreamTypes { + note: Note; +} + +export interface MessagingStreamTypes { + read: MessagingMessage['id'][]; + typing: User['id']; + message: Packed<'MessagingMessage'>; + deleted: MessagingMessage['id']; +} + +export interface GroupMessagingStreamTypes { + read: { + ids: MessagingMessage['id'][]; + userId: User['id']; + }; + typing: User['id']; + message: Packed<'MessagingMessage'>; + deleted: MessagingMessage['id']; +} + +export interface MessagingIndexStreamTypes { + read: MessagingMessage['id'][]; + message: Packed<'MessagingMessage'>; +} + +export interface ReversiStreamTypes { + matched: Packed<'ReversiGame'>; + invited: Packed<'ReversiMatching'>; +} + +export interface ReversiGameStreamTypes { + started: Packed<'ReversiGame'>; + ended: { + winnerId?: User['id'] | null, + game: Packed<'ReversiGame'>; + }; + updateSettings: { + key: string; + value: FIXME; + }; + initForm: { + userId: User['id']; + form: FIXME; + }; + updateForm: { + userId: User['id']; + id: string; + value: FIXME; + }; + message: { + userId: User['id']; + message: FIXME; + }; + changeAccepts: { + user1: boolean; + user2: boolean; + }; + set: { + at: Date; + color: boolean; + pos: number; + next: boolean; + }; + watching: User['id']; +} + +export interface AdminStreamTypes { + newAbuseUserReport: { + id: AbuseUserReport['id']; + targetUserId: User['id'], + reporterId: User['id'], + comment: string; + }; +} +//#endregion + +// 辞書(interface or type)から{ type, body }ユニオンを定義 +// https://stackoverflow.com/questions/49311989/can-i-infer-the-type-of-a-value-using-extends-keyof-type +// VS Codeの展開を防止するためにEvents型を定義 +type Events = { [K in keyof T]: { type: K; body: T[K]; } }; +type EventUnionFromDictionary< + T extends object, + U = Events +> = U[keyof U]; + +// name/messages(spec) pairs dictionary +export type StreamMessages = { + internal: { + name: 'internal'; + payload: EventUnionFromDictionary; + }; + broadcast: { + name: 'broadcast'; + payload: EventUnionFromDictionary; + }; + user: { + name: `user:${User['id']}`; + payload: EventUnionFromDictionary; + }; + main: { + name: `mainStream:${User['id']}`; + payload: EventUnionFromDictionary; + }; + drive: { + name: `driveStream:${User['id']}`; + payload: EventUnionFromDictionary; + }; + note: { + name: `noteStream:${Note['id']}`; + payload: EventUnionFromDictionary; + }; + channel: { + name: `channelStream:${Channel['id']}`; + payload: EventUnionFromDictionary; + }; + userList: { + name: `userListStream:${UserList['id']}`; + payload: EventUnionFromDictionary; + }; + antenna: { + name: `antennaStream:${Antenna['id']}`; + payload: EventUnionFromDictionary; + }; + messaging: { + name: `messagingStream:${User['id']}-${User['id']}`; + payload: EventUnionFromDictionary; + }; + groupMessaging: { + name: `messagingStream:${UserGroup['id']}`; + payload: EventUnionFromDictionary; + }; + messagingIndex: { + name: `messagingIndexStream:${User['id']}`; + payload: EventUnionFromDictionary; + }; + reversi: { + name: `reversiStream:${User['id']}`; + payload: EventUnionFromDictionary; + }; + reversiGame: { + name: `reversiGameStream:${ReversiGame['id']}`; + payload: EventUnionFromDictionary; + }; + admin: { + name: `adminStream:${User['id']}`; + payload: EventUnionFromDictionary; + }; + notes: { + name: 'notesStream'; + payload: Packed<'Note'>; + }; +}; + +// API event definitions +// ストリームごとのEmitterの辞書を用意 +type EventEmitterDictionary = { [x in keyof StreamMessages]: Emitter void }> }; +// 共用体型を交差型にする型 https://stackoverflow.com/questions/54938141/typescript-convert-union-to-intersection +type UnionToIntersection = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never; +// Emitter辞書から共用体型を作り、UnionToIntersectionで交差型にする +export type StreamEventEmitter = UnionToIntersection; +// { [y in name]: (e: spec) => void }をまとめてその交差型をEmitterにかけるとts(2590)にひっかかる + +// provide stream channels union +export type StreamChannels = StreamMessages[keyof StreamMessages]['name']; diff --git a/src/server/api/streaming.ts b/packages/backend/src/server/api/streaming.ts similarity index 100% rename from src/server/api/streaming.ts rename to packages/backend/src/server/api/streaming.ts diff --git a/src/server/file/assets/bad-egg.png b/packages/backend/src/server/file/assets/bad-egg.png similarity index 100% rename from src/server/file/assets/bad-egg.png rename to packages/backend/src/server/file/assets/bad-egg.png diff --git a/src/server/file/assets/cache-expired.png b/packages/backend/src/server/file/assets/cache-expired.png similarity index 100% rename from src/server/file/assets/cache-expired.png rename to packages/backend/src/server/file/assets/cache-expired.png diff --git a/src/server/file/assets/dummy.png b/packages/backend/src/server/file/assets/dummy.png similarity index 100% rename from src/server/file/assets/dummy.png rename to packages/backend/src/server/file/assets/dummy.png diff --git a/src/server/file/assets/not-an-image.png b/packages/backend/src/server/file/assets/not-an-image.png similarity index 100% rename from src/server/file/assets/not-an-image.png rename to packages/backend/src/server/file/assets/not-an-image.png diff --git a/src/server/file/assets/thumbnail-not-available.png b/packages/backend/src/server/file/assets/thumbnail-not-available.png similarity index 100% rename from src/server/file/assets/thumbnail-not-available.png rename to packages/backend/src/server/file/assets/thumbnail-not-available.png diff --git a/src/server/file/assets/tombstone.png b/packages/backend/src/server/file/assets/tombstone.png similarity index 100% rename from src/server/file/assets/tombstone.png rename to packages/backend/src/server/file/assets/tombstone.png diff --git a/src/server/file/index.ts b/packages/backend/src/server/file/index.ts similarity index 100% rename from src/server/file/index.ts rename to packages/backend/src/server/file/index.ts diff --git a/src/server/file/send-drive-file.ts b/packages/backend/src/server/file/send-drive-file.ts similarity index 100% rename from src/server/file/send-drive-file.ts rename to packages/backend/src/server/file/send-drive-file.ts diff --git a/packages/backend/src/server/index.ts b/packages/backend/src/server/index.ts new file mode 100644 index 000000000..507178a46 --- /dev/null +++ b/packages/backend/src/server/index.ts @@ -0,0 +1,179 @@ +/** + * Core Server + */ + +import * as fs from 'fs'; +import * as http from 'http'; +import * as http2 from 'http2'; +import * as https from 'https'; +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'; +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 { genAvatar } from '@/misc/gen-avatar'; +import { createTemp } from '@/misc/create-temp'; +import { publishMainStream } from '@/services/stream'; +import * as Acct from 'misskey-js/built/acct'; + +export const serverLogger = new Logger('server', 'gray', false); + +// Init app +const app = new Koa(); +app.proxy = true; + +if (!['production', 'test'].includes(process.env.NODE_ENV || '')) { + // Logger + app.use(koaLogger(str => { + serverLogger.info(str); + })); + + // Delay + if (envOption.slow) { + app.use(slow({ + delay: 3000 + })); + } +} + +// HSTS +// 6months (15552000sec) +if (config.url.startsWith('https') && !config.disableHsts) { + app.use(async (ctx, next) => { + ctx.set('strict-transport-security', 'max-age=15552000; preload'); + await next(); + }); +} + +app.use(mount('/api', apiServer)); +app.use(mount('/files', require('./file'))); +app.use(mount('/proxy', require('./proxy'))); + +// Init router +const router = new Router(); + +// Routing +router.use(activityPub.routes()); +router.use(nodeinfo.routes()); +router.use(wellKnown.routes()); + +router.get('/avatar/@:acct', async ctx => { + const { username, host } = Acct.parse(ctx.params.acct); + const user = await Users.findOne({ + usernameLower: username.toLowerCase(), + host: host === config.host ? null : host, + isSuspended: false + }); + + if (user) { + ctx.redirect(Users.getAvatarUrl(user)); + } else { + ctx.redirect('/static-assets/user-unknown.png'); + } +}); + +router.get('/random-avatar/:x', async ctx => { + const [temp] = await createTemp(); + await genAvatar(ctx.params.x, fs.createWriteStream(temp)); + ctx.set('Content-Type', 'image/png'); + ctx.body = fs.createReadStream(temp); +}); + +router.get('/verify-email/:code', async ctx => { + const profile = await UserProfiles.findOne({ + emailVerifyCode: ctx.params.code + }); + + if (profile != null) { + ctx.body = 'Verify succeeded!'; + ctx.status = 200; + + await UserProfiles.update({ userId: profile.userId }, { + emailVerified: true, + emailVerifyCode: null + }); + + publishMainStream(profile.userId, 'meUpdated', await Users.pack(profile.userId, { id: profile.userId }, { + detail: true, + includeSecrets: true + })); + } else { + ctx.status = 404; + } +}); + +// Register router +app.use(router.routes()); + +app.use(mount(require('./web'))); + +function createServer() { + if (config.https) { + const certs: any = {}; + for (const k of Object.keys(config.https)) { + certs[k] = fs.readFileSync(config.https[k]); + } + certs['allowHTTP1'] = true; + return http2.createSecureServer(certs, app.callback()) as https.Server; + } else { + return http.createServer(app.callback()); + } +} + +// For testing +export const startServer = () => { + const server = createServer(); + + // Init stream server + require('./api/streaming')(server); + + // Listen + server.listen(config.port); + + return server; +}; + +export default () => new Promise(resolve => { + const server = createServer(); + + // Init stream server + require('./api/streaming')(server); + + // 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/src/server/nodeinfo.ts b/packages/backend/src/server/nodeinfo.ts similarity index 100% rename from src/server/nodeinfo.ts rename to packages/backend/src/server/nodeinfo.ts diff --git a/src/server/proxy/index.ts b/packages/backend/src/server/proxy/index.ts similarity index 100% rename from src/server/proxy/index.ts rename to packages/backend/src/server/proxy/index.ts diff --git a/src/server/proxy/proxy-media.ts b/packages/backend/src/server/proxy/proxy-media.ts similarity index 100% rename from src/server/proxy/proxy-media.ts rename to packages/backend/src/server/proxy/proxy-media.ts diff --git a/src/server/web/bios.css b/packages/backend/src/server/web/bios.css similarity index 100% rename from src/server/web/bios.css rename to packages/backend/src/server/web/bios.css diff --git a/src/server/web/bios.js b/packages/backend/src/server/web/bios.js similarity index 100% rename from src/server/web/bios.js rename to packages/backend/src/server/web/bios.js diff --git a/src/server/web/boot.js b/packages/backend/src/server/web/boot.js similarity index 100% rename from src/server/web/boot.js rename to packages/backend/src/server/web/boot.js diff --git a/src/server/web/cli.css b/packages/backend/src/server/web/cli.css similarity index 100% rename from src/server/web/cli.css rename to packages/backend/src/server/web/cli.css diff --git a/src/server/web/cli.js b/packages/backend/src/server/web/cli.js similarity index 100% rename from src/server/web/cli.js rename to packages/backend/src/server/web/cli.js diff --git a/packages/backend/src/server/web/feed.ts b/packages/backend/src/server/web/feed.ts new file mode 100644 index 000000000..1d4c47daf --- /dev/null +++ b/packages/backend/src/server/web/feed.ts @@ -0,0 +1,58 @@ +import { Feed } from 'feed'; +import config from '@/config/index'; +import { User } from '@/models/entities/user'; +import { Notes, DriveFiles, UserProfiles } from '@/models/index'; +import { In } from 'typeorm'; + +export default async function(user: User) { + const author = { + link: `${config.url}/@${user.username}`, + name: user.name || user.username + }; + + const profile = await UserProfiles.findOneOrFail(user.id); + + const notes = await Notes.find({ + where: { + userId: user.id, + renoteId: null, + visibility: In(['public', 'home']) + }, + order: { createdAt: -1 }, + take: 20 + }); + + const feed = new Feed({ + id: author.link, + title: `${author.name} (@${user.username}@${config.host})`, + updated: notes[0].createdAt, + generator: 'Misskey', + description: `${user.notesCount} Notes, ${profile.ffVisibility === 'public' ? user.followingCount : '?'} Following, ${profile.ffVisibility === 'public' ? user.followersCount : '?'} Followers${profile.description ? ` · ${profile.description}` : ''}`, + link: author.link, + image: user.avatarUrl ? user.avatarUrl : undefined, + feedLinks: { + json: `${author.link}.json`, + atom: `${author.link}.atom`, + }, + author, + copyright: user.name || user.username + }); + + for (const note of notes) { + const files = note.fileIds.length > 0 ? await DriveFiles.find({ + id: In(note.fileIds) + }) : []; + const file = files.find(file => file.type.startsWith('image/')); + + feed.addItem({ + title: `New note by ${author.name}`, + link: `${config.url}/notes/${note.id}`, + date: note.createdAt, + description: note.cw || undefined, + content: note.text || undefined, + image: file ? DriveFiles.getPublicUrl(file) || undefined : undefined + }); + } + + return feed; +} diff --git a/packages/backend/src/server/web/index.ts b/packages/backend/src/server/web/index.ts new file mode 100644 index 000000000..d80d73f25 --- /dev/null +++ b/packages/backend/src/server/web/index.ts @@ -0,0 +1,422 @@ +/** + * Web Client Server + */ + +import { dirname } from 'path'; +import ms from 'ms'; +import * as Koa from 'koa'; +import * as Router from '@koa/router'; +import * as send from 'koa-send'; +import * as favicon from 'koa-favicon'; +import * as views from 'koa-views'; + +import packFeed from './feed'; +import { fetchMeta } from '@/misc/fetch-meta'; +import { genOpenapiSpec } from '../api/openapi/gen-spec'; +import config from '@/config/index'; +import { Users, Notes, UserProfiles, Pages, Channels, Clips, GalleryPosts } from '@/models/index'; +import * as Acct from 'misskey-js/built/acct'; +import { getNoteSummary } from '@/misc/get-note-summary'; + +//const _filename = fileURLToPath(import.meta.url); +const _filename = __filename; +const _dirname = dirname(_filename); + +const staticAssets = `${_dirname}/../../../assets/`; +const clientAssets = `${_dirname}/../../../../client/assets/`; +const assets = `${_dirname}/../../../../../built/_client_dist_/`; + +// Init app +const app = new Koa(); + +// Init renderer +app.use(views(_dirname + '/views', { + extension: 'pug', + options: { + version: config.version, + config + } +})); + +// Serve favicon +app.use(favicon(`${_dirname}/../../../assets/favicon.ico`)); + +// Common request handler +app.use(async (ctx, next) => { + // IFrameの中に入れられないようにする + ctx.set('X-Frame-Options', 'DENY'); + await next(); +}); + +// Init router +const router = new Router(); + +//#region static assets + +router.get('/static-assets/(.*)', async ctx => { + await send(ctx as any, ctx.path.replace('/static-assets/', ''), { + root: staticAssets, + maxage: ms('7 days'), + }); +}); + +router.get('/client-assets/(.*)', async ctx => { + await send(ctx as any, ctx.path.replace('/client-assets/', ''), { + root: clientAssets, + maxage: ms('7 days'), + }); +}); + +router.get('/assets/(.*)', async ctx => { + await send(ctx as any, ctx.path.replace('/assets/', ''), { + root: assets, + maxage: ms('7 days'), + }); +}); + +// Apple touch icon +router.get('/apple-touch-icon.png', async ctx => { + await send(ctx as any, '/apple-touch-icon.png', { + root: staticAssets + }); +}); + +router.get('/twemoji/(.*)', async ctx => { + const path = ctx.path.replace('/twemoji/', ''); + + if (!path.match(/^[0-9a-f-]+\.svg$/)) { + ctx.status = 404; + return; + } + + ctx.set('Content-Security-Policy', `default-src 'none'; style-src 'unsafe-inline'`); + + await send(ctx as any, path, { + root: `${_dirname}/../../../node_modules/@discordapp/twemoji/dist/svg/`, + maxage: ms('30 days'), + }); +}); + +// ServiceWorker +router.get('/sw.js', async ctx => { + await send(ctx as any, `/sw.${config.version}.js`, { + root: assets + }); +}); + +// Manifest +router.get('/manifest.json', require('./manifest')); + +router.get('/robots.txt', async ctx => { + await send(ctx as any, '/robots.txt', { + root: staticAssets + }); +}); + +//#endregion + +// Docs +router.get('/api-doc', async ctx => { + await send(ctx as any, '/redoc.html', { + root: staticAssets + }); +}); + +// URL preview endpoint +router.get('/url', require('./url-preview')); + +router.get('/api.json', async ctx => { + ctx.body = genOpenapiSpec(); +}); + +const getFeed = async (acct: string) => { + const { username, host } = Acct.parse(acct); + const user = await Users.findOne({ + usernameLower: username.toLowerCase(), + host, + isSuspended: false + }); + + return user && await packFeed(user); +}; + +// Atom +router.get('/@:user.atom', async ctx => { + const feed = await getFeed(ctx.params.user); + + if (feed) { + ctx.set('Content-Type', 'application/atom+xml; charset=utf-8'); + ctx.body = feed.atom1(); + } else { + ctx.status = 404; + } +}); + +// RSS +router.get('/@:user.rss', async ctx => { + const feed = await getFeed(ctx.params.user); + + if (feed) { + ctx.set('Content-Type', 'application/rss+xml; charset=utf-8'); + ctx.body = feed.rss2(); + } else { + ctx.status = 404; + } +}); + +// JSON +router.get('/@:user.json', async ctx => { + const feed = await getFeed(ctx.params.user); + + if (feed) { + ctx.set('Content-Type', 'application/json; charset=utf-8'); + ctx.body = feed.json1(); + } else { + ctx.status = 404; + } +}); + +//#region SSR (for crawlers) +// User +router.get(['/@:user', '/@:user/:sub'], async (ctx, next) => { + const { username, host } = Acct.parse(ctx.params.user); + const user = await Users.findOne({ + usernameLower: username.toLowerCase(), + host, + isSuspended: false + }); + + if (user != null) { + const profile = await UserProfiles.findOneOrFail(user.id); + const meta = await fetchMeta(); + const me = profile.fields + ? profile.fields + .filter(filed => filed.value != null && filed.value.match(/^https?:/)) + .map(field => field.value) + : []; + + await ctx.render('user', { + user, profile, me, + sub: ctx.params.sub, + instanceName: meta.name || 'Misskey', + icon: meta.iconUrl + }); + ctx.set('Cache-Control', 'public, max-age=30'); + } else { + // リモートユーザーなので + // モデレータがAPI経由で参照可能にするために404にはしない + await next(); + } +}); + +router.get('/users/:user', async ctx => { + const user = await Users.findOne({ + id: ctx.params.user, + host: null, + isSuspended: false + }); + + if (user == null) { + ctx.status = 404; + return; + } + + ctx.redirect(`/@${user.username}${ user.host == null ? '' : '@' + user.host}`); +}); + +// Note +router.get('/notes/:note', async (ctx, next) => { + const note = await Notes.findOne(ctx.params.note); + + if (note) { + const _note = await Notes.pack(note); + const profile = await UserProfiles.findOneOrFail(note.userId); + const meta = await fetchMeta(); + await ctx.render('note', { + note: _note, + profile, + // TODO: Let locale changeable by instance setting + summary: getNoteSummary(_note), + instanceName: meta.name || 'Misskey', + icon: meta.iconUrl + }); + + if (['public', 'home'].includes(note.visibility)) { + ctx.set('Cache-Control', 'public, max-age=180'); + } else { + ctx.set('Cache-Control', 'private, max-age=0, must-revalidate'); + } + + return; + } + + await next(); +}); + +// Page +router.get('/@:user/pages/:page', async (ctx, next) => { + const { username, host } = Acct.parse(ctx.params.user); + const user = await Users.findOne({ + usernameLower: username.toLowerCase(), + host + }); + + if (user == null) return; + + const page = await Pages.findOne({ + name: ctx.params.page, + userId: user.id + }); + + if (page) { + const _page = await Pages.pack(page); + const profile = await UserProfiles.findOneOrFail(page.userId); + const meta = await fetchMeta(); + await ctx.render('page', { + page: _page, + profile, + instanceName: meta.name || 'Misskey' + }); + + if (['public'].includes(page.visibility)) { + ctx.set('Cache-Control', 'public, max-age=180'); + } else { + ctx.set('Cache-Control', 'private, max-age=0, must-revalidate'); + } + + return; + } + + await next(); +}); + +// Clip +// TODO: 非publicなclipのハンドリング +router.get('/clips/:clip', async (ctx, next) => { + const clip = await Clips.findOne({ + id: ctx.params.clip, + }); + + if (clip) { + const _clip = await Clips.pack(clip); + const profile = await UserProfiles.findOneOrFail(clip.userId); + const meta = await fetchMeta(); + await ctx.render('clip', { + clip: _clip, + profile, + instanceName: meta.name || 'Misskey' + }); + + ctx.set('Cache-Control', 'public, max-age=180'); + + return; + } + + await next(); +}); + +// Gallery post +router.get('/gallery/:post', async (ctx, next) => { + const post = await GalleryPosts.findOne(ctx.params.post); + + if (post) { + const _post = await GalleryPosts.pack(post); + const profile = await UserProfiles.findOneOrFail(post.userId); + const meta = await fetchMeta(); + await ctx.render('gallery-post', { + post: _post, + profile, + instanceName: meta.name || 'Misskey', + icon: meta.iconUrl + }); + + ctx.set('Cache-Control', 'public, max-age=180'); + + return; + } + + await next(); +}); + +// Channel +router.get('/channels/:channel', async (ctx, next) => { + const channel = await Channels.findOne({ + id: ctx.params.channel, + }); + + if (channel) { + const _channel = await Channels.pack(channel); + const meta = await fetchMeta(); + await ctx.render('channel', { + channel: _channel, + instanceName: meta.name || 'Misskey' + }); + + ctx.set('Cache-Control', 'public, max-age=180'); + + return; + } + + await next(); +}); +//#endregion + +router.get('/_info_card_', async ctx => { + const meta = await fetchMeta(true); + + ctx.remove('X-Frame-Options'); + + await ctx.render('info-card', { + version: config.version, + host: config.host, + meta: meta, + originalUsersCount: await Users.count({ host: null }), + originalNotesCount: await Notes.count({ userHost: null }) + }); +}); + +router.get('/bios', async ctx => { + await ctx.render('bios', { + version: config.version, + }); +}); + +router.get('/cli', async ctx => { + await ctx.render('cli', { + version: config.version, + }); +}); + +const override = (source: string, target: string, depth: number = 0) => + [, ...target.split('/').filter(x => x), ...source.split('/').filter(x => x).splice(depth)].join('/'); + +router.get('/othello', async ctx => ctx.redirect(override(ctx.URL.pathname, 'games/reversi', 1))); +router.get('/reversi', async ctx => ctx.redirect(override(ctx.URL.pathname, 'games'))); + +router.get('/flush', async ctx => { + await ctx.render('flush'); +}); + +// streamingに非WebSocketリクエストが来た場合にbase htmlをキャシュ付きで返すと、Proxy等でそのパスがキャッシュされておかしくなる +router.get('/streaming', async ctx => { + ctx.status = 503; + ctx.set('Cache-Control', 'private, max-age=0'); +}); + +// Render base html for all requests +router.get('(.*)', async ctx => { + const meta = await fetchMeta(); + await ctx.render('base', { + img: meta.bannerUrl, + title: meta.name || 'Misskey', + instanceName: meta.name || 'Misskey', + desc: meta.description, + icon: meta.iconUrl + }); + ctx.set('Cache-Control', 'public, max-age=300'); +}); + +// Register router +app.use(router.routes()); + +module.exports = app; diff --git a/src/server/web/manifest.json b/packages/backend/src/server/web/manifest.json similarity index 100% rename from src/server/web/manifest.json rename to packages/backend/src/server/web/manifest.json diff --git a/src/server/web/manifest.ts b/packages/backend/src/server/web/manifest.ts similarity index 100% rename from src/server/web/manifest.ts rename to packages/backend/src/server/web/manifest.ts diff --git a/src/server/web/style.css b/packages/backend/src/server/web/style.css similarity index 100% rename from src/server/web/style.css rename to packages/backend/src/server/web/style.css diff --git a/src/server/web/url-preview.ts b/packages/backend/src/server/web/url-preview.ts similarity index 100% rename from src/server/web/url-preview.ts rename to packages/backend/src/server/web/url-preview.ts diff --git a/src/server/web/views/base.pug b/packages/backend/src/server/web/views/base.pug similarity index 100% rename from src/server/web/views/base.pug rename to packages/backend/src/server/web/views/base.pug diff --git a/src/server/web/views/bios.pug b/packages/backend/src/server/web/views/bios.pug similarity index 100% rename from src/server/web/views/bios.pug rename to packages/backend/src/server/web/views/bios.pug diff --git a/src/server/web/views/channel.pug b/packages/backend/src/server/web/views/channel.pug similarity index 100% rename from src/server/web/views/channel.pug rename to packages/backend/src/server/web/views/channel.pug diff --git a/src/server/web/views/cli.pug b/packages/backend/src/server/web/views/cli.pug similarity index 100% rename from src/server/web/views/cli.pug rename to packages/backend/src/server/web/views/cli.pug diff --git a/src/server/web/views/clip.pug b/packages/backend/src/server/web/views/clip.pug similarity index 100% rename from src/server/web/views/clip.pug rename to packages/backend/src/server/web/views/clip.pug diff --git a/src/server/web/views/flush.pug b/packages/backend/src/server/web/views/flush.pug similarity index 100% rename from src/server/web/views/flush.pug rename to packages/backend/src/server/web/views/flush.pug diff --git a/src/server/web/views/gallery-post.pug b/packages/backend/src/server/web/views/gallery-post.pug similarity index 100% rename from src/server/web/views/gallery-post.pug rename to packages/backend/src/server/web/views/gallery-post.pug diff --git a/packages/backend/src/server/web/views/info-card.pug b/packages/backend/src/server/web/views/info-card.pug new file mode 100644 index 000000000..1d62778ce --- /dev/null +++ b/packages/backend/src/server/web/views/info-card.pug @@ -0,0 +1,50 @@ +doctype html + +html + + head + meta(charset='utf-8') + meta(name='application-name' content='Misskey') + title= meta.name || host + style. + html, body { + margin: 0; + padding: 0; + min-height: 100vh; + background: #fff; + } + + #a { + display: block; + } + + #banner { + background-size: cover; + background-position: center center; + } + + #title { + display: inline-block; + margin: 24px; + padding: 0.5em 0.8em; + color: #fff; + background: rgba(0, 0, 0, 0.5); + font-weight: bold; + font-size: 1.3em; + } + + #content { + overflow: auto; + color: #353c3e; + } + + #description { + margin: 24px; + } + + body + a#a(href=`https://${host}` target="_blank") + header#banner(style=`background-image: url(${meta.bannerUrl})`) + div#title= meta.name || host + div#content + div#description= meta.description diff --git a/src/server/web/views/note.pug b/packages/backend/src/server/web/views/note.pug similarity index 100% rename from src/server/web/views/note.pug rename to packages/backend/src/server/web/views/note.pug diff --git a/src/server/web/views/page.pug b/packages/backend/src/server/web/views/page.pug similarity index 100% rename from src/server/web/views/page.pug rename to packages/backend/src/server/web/views/page.pug diff --git a/src/server/web/views/user.pug b/packages/backend/src/server/web/views/user.pug similarity index 100% rename from src/server/web/views/user.pug rename to packages/backend/src/server/web/views/user.pug diff --git a/packages/backend/src/server/well-known.ts b/packages/backend/src/server/well-known.ts new file mode 100644 index 000000000..5e99b0065 --- /dev/null +++ b/packages/backend/src/server/well-known.ts @@ -0,0 +1,149 @@ +import * as Router from '@koa/router'; + +import config from '@/config/index'; +import * as Acct from 'misskey-js/built/acct'; +import { links } from './nodeinfo'; +import { escapeAttribute, escapeValue } from '@/prelude/xml'; +import { Users } from '@/models/index'; +import { User } from '@/models/entities/user'; + +// Init router +const router = new Router(); + +const XRD = (...x: { element: string, value?: string, attributes?: Record }[]) => + `${x.map(({ element, value, attributes }) => + `<${ + Object.entries(typeof attributes === 'object' && attributes || {}).reduce((a, [k, v]) => `${a} ${k}="${escapeAttribute(v)}"`, element) + }${ + typeof value === 'string' ? `>${escapeValue(value)}`).reduce((a, c) => a + c, '')}`; + +const allPath = '/.well-known/(.*)'; +const webFingerPath = '/.well-known/webfinger'; +const jrd = 'application/jrd+json'; +const xrd = 'application/xrd+xml'; + +router.use(allPath, async (ctx, next) => { + ctx.set({ + 'Access-Control-Allow-Headers': 'Accept', + 'Access-Control-Allow-Methods': 'GET, OPTIONS', + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Expose-Headers': 'Vary', + }); + await next(); +}); + +router.options(allPath, async ctx => { + ctx.status = 204; +}); + +router.get('/.well-known/host-meta', async ctx => { + ctx.set('Content-Type', xrd); + ctx.body = XRD({ element: 'Link', attributes: { + type: xrd, + template: `${config.url}${webFingerPath}?resource={uri}` + }}); +}); + +router.get('/.well-known/host-meta.json', async ctx => { + ctx.set('Content-Type', jrd); + ctx.body = { + links: [{ + rel: 'lrdd', + type: jrd, + template: `${config.url}${webFingerPath}?resource={uri}` + }] + }; +}); + +router.get('/.well-known/nodeinfo', async ctx => { + ctx.body = { links }; +}); + +/* TODO +router.get('/.well-known/change-password', async ctx => { +}); +*/ + +router.get(webFingerPath, async ctx => { + const fromId = (id: User['id']): Record => ({ + id, + host: null, + isSuspended: false + }); + + const generateQuery = (resource: string) => + resource.startsWith(`${config.url.toLowerCase()}/users/`) ? + fromId(resource.split('/').pop()!) : + fromAcct(Acct.parse( + resource.startsWith(`${config.url.toLowerCase()}/@`) ? resource.split('/').pop()! : + resource.startsWith('acct:') ? resource.slice('acct:'.length) : + resource)); + + const fromAcct = (acct: Acct.Acct): Record | number => + !acct.host || acct.host === config.host.toLowerCase() ? { + usernameLower: acct.username, + host: null, + isSuspended: false + } : 422; + + if (typeof ctx.query.resource !== 'string') { + ctx.status = 400; + return; + } + + const query = generateQuery(ctx.query.resource.toLowerCase()); + + if (typeof query === 'number') { + ctx.status = query; + return; + } + + const user = await Users.findOne(query); + + if (user == null) { + ctx.status = 404; + return; + } + + const subject = `acct:${user.username}@${config.host}`; + const self = { + rel: 'self', + type: 'application/activity+json', + href: `${config.url}/users/${user.id}` + }; + const profilePage = { + rel: 'http://webfinger.net/rel/profile-page', + type: 'text/html', + href: `${config.url}/@${user.username}` + }; + const subscribe = { + rel: 'http://ostatus.org/schema/1.0/subscribe', + template: `${config.url}/authorize-follow?acct={uri}` + }; + + if (ctx.accepts(jrd, xrd) === xrd) { + ctx.body = XRD( + { element: 'Subject', value: subject }, + { element: 'Link', attributes: self }, + { element: 'Link', attributes: profilePage }, + { element: 'Link', attributes: subscribe }); + ctx.type = xrd; + } else { + ctx.body = { + subject, + links: [self, profilePage, subscribe] + }; + ctx.type = jrd; + } + + ctx.vary('Accept'); + ctx.set('Cache-Control', 'public, max-age=180'); +}); + +// Return 404 for other .well-known +router.all(allPath, async ctx => { + ctx.status = 404; +}); + +export default router; diff --git a/src/services/add-note-to-antenna.ts b/packages/backend/src/services/add-note-to-antenna.ts similarity index 100% rename from src/services/add-note-to-antenna.ts rename to packages/backend/src/services/add-note-to-antenna.ts diff --git a/src/services/blocking/create.ts b/packages/backend/src/services/blocking/create.ts similarity index 100% rename from src/services/blocking/create.ts rename to packages/backend/src/services/blocking/create.ts diff --git a/src/services/blocking/delete.ts b/packages/backend/src/services/blocking/delete.ts similarity index 100% rename from src/services/blocking/delete.ts rename to packages/backend/src/services/blocking/delete.ts diff --git a/src/services/chart/charts/classes/active-users.ts b/packages/backend/src/services/chart/charts/classes/active-users.ts similarity index 100% rename from src/services/chart/charts/classes/active-users.ts rename to packages/backend/src/services/chart/charts/classes/active-users.ts diff --git a/src/services/chart/charts/classes/drive.ts b/packages/backend/src/services/chart/charts/classes/drive.ts similarity index 100% rename from src/services/chart/charts/classes/drive.ts rename to packages/backend/src/services/chart/charts/classes/drive.ts diff --git a/src/services/chart/charts/classes/federation.ts b/packages/backend/src/services/chart/charts/classes/federation.ts similarity index 100% rename from src/services/chart/charts/classes/federation.ts rename to packages/backend/src/services/chart/charts/classes/federation.ts diff --git a/src/services/chart/charts/classes/hashtag.ts b/packages/backend/src/services/chart/charts/classes/hashtag.ts similarity index 100% rename from src/services/chart/charts/classes/hashtag.ts rename to packages/backend/src/services/chart/charts/classes/hashtag.ts diff --git a/src/services/chart/charts/classes/instance.ts b/packages/backend/src/services/chart/charts/classes/instance.ts similarity index 100% rename from src/services/chart/charts/classes/instance.ts rename to packages/backend/src/services/chart/charts/classes/instance.ts diff --git a/src/services/chart/charts/classes/network.ts b/packages/backend/src/services/chart/charts/classes/network.ts similarity index 100% rename from src/services/chart/charts/classes/network.ts rename to packages/backend/src/services/chart/charts/classes/network.ts diff --git a/src/services/chart/charts/classes/notes.ts b/packages/backend/src/services/chart/charts/classes/notes.ts similarity index 100% rename from src/services/chart/charts/classes/notes.ts rename to packages/backend/src/services/chart/charts/classes/notes.ts diff --git a/src/services/chart/charts/classes/per-user-drive.ts b/packages/backend/src/services/chart/charts/classes/per-user-drive.ts similarity index 100% rename from src/services/chart/charts/classes/per-user-drive.ts rename to packages/backend/src/services/chart/charts/classes/per-user-drive.ts diff --git a/src/services/chart/charts/classes/per-user-following.ts b/packages/backend/src/services/chart/charts/classes/per-user-following.ts similarity index 100% rename from src/services/chart/charts/classes/per-user-following.ts rename to packages/backend/src/services/chart/charts/classes/per-user-following.ts diff --git a/src/services/chart/charts/classes/per-user-notes.ts b/packages/backend/src/services/chart/charts/classes/per-user-notes.ts similarity index 100% rename from src/services/chart/charts/classes/per-user-notes.ts rename to packages/backend/src/services/chart/charts/classes/per-user-notes.ts diff --git a/src/services/chart/charts/classes/per-user-reactions.ts b/packages/backend/src/services/chart/charts/classes/per-user-reactions.ts similarity index 100% rename from src/services/chart/charts/classes/per-user-reactions.ts rename to packages/backend/src/services/chart/charts/classes/per-user-reactions.ts diff --git a/src/services/chart/charts/classes/test-grouped.ts b/packages/backend/src/services/chart/charts/classes/test-grouped.ts similarity index 100% rename from src/services/chart/charts/classes/test-grouped.ts rename to packages/backend/src/services/chart/charts/classes/test-grouped.ts diff --git a/src/services/chart/charts/classes/test-unique.ts b/packages/backend/src/services/chart/charts/classes/test-unique.ts similarity index 100% rename from src/services/chart/charts/classes/test-unique.ts rename to packages/backend/src/services/chart/charts/classes/test-unique.ts diff --git a/src/services/chart/charts/classes/test.ts b/packages/backend/src/services/chart/charts/classes/test.ts similarity index 100% rename from src/services/chart/charts/classes/test.ts rename to packages/backend/src/services/chart/charts/classes/test.ts diff --git a/src/services/chart/charts/classes/users.ts b/packages/backend/src/services/chart/charts/classes/users.ts similarity index 100% rename from src/services/chart/charts/classes/users.ts rename to packages/backend/src/services/chart/charts/classes/users.ts diff --git a/src/services/chart/charts/schemas/active-users.ts b/packages/backend/src/services/chart/charts/schemas/active-users.ts similarity index 100% rename from src/services/chart/charts/schemas/active-users.ts rename to packages/backend/src/services/chart/charts/schemas/active-users.ts diff --git a/src/services/chart/charts/schemas/drive.ts b/packages/backend/src/services/chart/charts/schemas/drive.ts similarity index 100% rename from src/services/chart/charts/schemas/drive.ts rename to packages/backend/src/services/chart/charts/schemas/drive.ts diff --git a/src/services/chart/charts/schemas/federation.ts b/packages/backend/src/services/chart/charts/schemas/federation.ts similarity index 100% rename from src/services/chart/charts/schemas/federation.ts rename to packages/backend/src/services/chart/charts/schemas/federation.ts diff --git a/src/services/chart/charts/schemas/hashtag.ts b/packages/backend/src/services/chart/charts/schemas/hashtag.ts similarity index 100% rename from src/services/chart/charts/schemas/hashtag.ts rename to packages/backend/src/services/chart/charts/schemas/hashtag.ts diff --git a/src/services/chart/charts/schemas/instance.ts b/packages/backend/src/services/chart/charts/schemas/instance.ts similarity index 100% rename from src/services/chart/charts/schemas/instance.ts rename to packages/backend/src/services/chart/charts/schemas/instance.ts diff --git a/src/services/chart/charts/schemas/network.ts b/packages/backend/src/services/chart/charts/schemas/network.ts similarity index 100% rename from src/services/chart/charts/schemas/network.ts rename to packages/backend/src/services/chart/charts/schemas/network.ts diff --git a/src/services/chart/charts/schemas/notes.ts b/packages/backend/src/services/chart/charts/schemas/notes.ts similarity index 100% rename from src/services/chart/charts/schemas/notes.ts rename to packages/backend/src/services/chart/charts/schemas/notes.ts diff --git a/src/services/chart/charts/schemas/per-user-drive.ts b/packages/backend/src/services/chart/charts/schemas/per-user-drive.ts similarity index 100% rename from src/services/chart/charts/schemas/per-user-drive.ts rename to packages/backend/src/services/chart/charts/schemas/per-user-drive.ts diff --git a/src/services/chart/charts/schemas/per-user-following.ts b/packages/backend/src/services/chart/charts/schemas/per-user-following.ts similarity index 100% rename from src/services/chart/charts/schemas/per-user-following.ts rename to packages/backend/src/services/chart/charts/schemas/per-user-following.ts diff --git a/src/services/chart/charts/schemas/per-user-notes.ts b/packages/backend/src/services/chart/charts/schemas/per-user-notes.ts similarity index 100% rename from src/services/chart/charts/schemas/per-user-notes.ts rename to packages/backend/src/services/chart/charts/schemas/per-user-notes.ts diff --git a/src/services/chart/charts/schemas/per-user-reactions.ts b/packages/backend/src/services/chart/charts/schemas/per-user-reactions.ts similarity index 100% rename from src/services/chart/charts/schemas/per-user-reactions.ts rename to packages/backend/src/services/chart/charts/schemas/per-user-reactions.ts diff --git a/src/services/chart/charts/schemas/test-grouped.ts b/packages/backend/src/services/chart/charts/schemas/test-grouped.ts similarity index 100% rename from src/services/chart/charts/schemas/test-grouped.ts rename to packages/backend/src/services/chart/charts/schemas/test-grouped.ts diff --git a/src/services/chart/charts/schemas/test-unique.ts b/packages/backend/src/services/chart/charts/schemas/test-unique.ts similarity index 100% rename from src/services/chart/charts/schemas/test-unique.ts rename to packages/backend/src/services/chart/charts/schemas/test-unique.ts diff --git a/src/services/chart/charts/schemas/test.ts b/packages/backend/src/services/chart/charts/schemas/test.ts similarity index 100% rename from src/services/chart/charts/schemas/test.ts rename to packages/backend/src/services/chart/charts/schemas/test.ts diff --git a/src/services/chart/charts/schemas/users.ts b/packages/backend/src/services/chart/charts/schemas/users.ts similarity index 100% rename from src/services/chart/charts/schemas/users.ts rename to packages/backend/src/services/chart/charts/schemas/users.ts diff --git a/packages/backend/src/services/chart/core.ts b/packages/backend/src/services/chart/core.ts new file mode 100644 index 000000000..78b7dd135 --- /dev/null +++ b/packages/backend/src/services/chart/core.ts @@ -0,0 +1,563 @@ +/** + * チャートエンジン + * + * Tests located in test/chart + */ + +import * as nestedProperty from 'nested-property'; +import autobind from 'autobind-decorator'; +import Logger from '../logger'; +import { SimpleSchema } from '@/misc/simple-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 }; + +export type DeepPartial = { + [P in keyof T]?: DeepPartial; +}; + +type ArrayValue = { + [P in keyof T]: T[P] extends number ? T[P][] : ArrayValue; +}; + +type Log = { + id: number; + + /** + * 集計のグループ + */ + group: string | null; + + /** + * 集計日時のUnixタイムスタンプ(秒) + */ + date: number; +}; + +const camelToSnake = (str: string) => { + return str.replace(/([A-Z])/g, s => '_' + s.charAt(0).toLowerCase()); +}; + +const removeDuplicates = (array: any[]) => Array.from(new Set(array)); + +/** + * 様々なチャートの管理を司るクラス + */ +export default abstract class Chart> { + private static readonly columnPrefix = '___'; + private static readonly columnDot = '_'; + + private name: string; + private buffer: { + diff: DeepPartial; + group: string | null; + }[] = []; + public schema: SimpleSchema; + protected repository: Repository; + + protected abstract genNewLog(latest: T): DeepPartial; + + /** + * @param logs 日時が新しい方が先頭 + */ + protected abstract aggregate(logs: T[]): T; + + protected abstract fetchActual(group: string | null): Promise>; + + @autobind + private static convertSchemaToFlatColumnDefinitions(schema: SimpleSchema) { + const columns = {} as Record; + 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, + }; + } + } + }; + flatColumns(schema.properties!); + return columns; + } + + @autobind + private static convertFlattenColumnsToObject(x: Record): Record { + const obj = {} as Record; + 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) { + const columns = {} as Record; + 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) { + const exec = (x: Obj) => { + const res = {} as Record; + 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) { + const query: Record 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'] { + return Math.floor(x.getTime() / 1000); + } + + @autobind + private static parseDate(date: Date): [number, number, number, number, number, number, number] { + const y = date.getUTCFullYear(); + const m = date.getUTCMonth(); + const d = date.getUTCDate(); + const h = date.getUTCHours(); + const _m = date.getUTCMinutes(); + const _s = date.getUTCSeconds(); + const _ms = date.getUTCMilliseconds(); + + return [y, m, d, h, _m, _s, _ms]; + } + + @autobind + private static getCurrentDate() { + return Chart.parseDate(new Date()); + } + + @autobind + public static schemaToEntity(name: string, schema: SimpleSchema): EntitySchema { + return new EntitySchema({ + name: `__chart__${camelToSnake(name)}`, + columns: { + id: { + type: 'integer', + primary: true, + generated: true + }, + date: { + type: 'integer', + }, + group: { + type: 'varchar', + length: 128, + nullable: true + }, + ...Chart.convertSchemaToFlatColumnDefinitions(schema) + }, + indices: [{ + columns: ['date', 'group'], + unique: true, + }, { // groupにnullが含まれると↑のuniqueは機能しないので↓の部分インデックスでカバー + columns: ['date'], + unique: true, + where: '"group" IS NULL' + }] + }); + } + + constructor(name: string, schema: SimpleSchema, grouped = false) { + this.name = name; + this.schema = schema; + const entity = Chart.schemaToEntity(name, schema); + + const keys = ['date']; + if (grouped) keys.push('group'); + + entity.options.uniques = [{ + columns: keys + }]; + + this.repository = getRepository(entity); + } + + @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); + } + } + } + }; + flatColumns(this.schema.properties!); + return log as T; + } + + @autobind + private getLatestLog(group: string | null = null): Promise { + return this.repository.findOne({ + group: group, + }, { + order: { + date: -1 + } + }).then(x => x || null); + } + + @autobind + private async getCurrentLog(group: string | null = null): Promise { + const [y, m, d, h] = Chart.getCurrentDate(); + + const current = dateUTC([y, m, d, h]); + + // 現在(=今のHour)のログ + const currentLog = await this.repository.findOne({ + date: Chart.dateToTimestamp(current), + ...(group ? { group: group } : {}) + }); + + // ログがあればそれを返して終了 + if (currentLog != null) { + return currentLog; + } + + let log: Log; + let data: T; + + // 集計期間が変わってから、初めてのチャート更新なら + // 最も最近のログを持ってくる + // * 例えば集計期間が「日」である場合で考えると、 + // * 昨日何もチャートを更新するような出来事がなかった場合は、 + // * ログがそもそも作られずドキュメントが存在しないということがあり得るため、 + // * 「昨日の」と決め打ちせずに「もっとも最近の」とします + const latest = await this.getLatestLog(group); + + if (latest != null) { + const obj = Chart.convertFlattenColumnsToObject(latest) as T; + + // 空ログデータを作成 + data = this.getNewLog(obj); + } else { + // ログが存在しなかったら + // (Misskeyインスタンスを建てて初めてのチャート更新時など) + + // 初期ログデータを作成 + data = this.getNewLog(null); + + logger.info(`${this.name + (group ? `:${group}` : '')}: Initial commit created`); + } + + const date = Chart.dateToTimestamp(current); + const lockKey = `${this.name}:${date}:${group}`; + + const unlock = await getChartInsertLock(lockKey); + try { + // ロック内でもう1回チェックする + const currentLog = await this.repository.findOne({ + date: date, + ...(group ? { group: group } : {}) + }); + + // ログがあればそれを返して終了 + if (currentLog != null) return currentLog; + + // 新規ログ挿入 + log = await this.repository.insert({ + group: group, + date: date, + ...Chart.convertObjectToFlattenColumns(data) + }).then(x => this.repository.findOneOrFail(x.identifiers[0])); + + logger.info(`${this.name + (group ? `:${group}` : '')}: New commit created`); + + return log; + } finally { + unlock(); + } + } + + @autobind + protected commit(diff: DeepPartial, group: string | null = null): void { + this.buffer.push({ + diff, group, + }); + } + + @autobind + public async save(): Promise { + if (this.buffer.length === 0) { + logger.info(`${this.name}: Write skipped`); + return; + } + + // TODO: 前の時間のログがbufferにあった場合のハンドリング + // 例えば、save が20分ごとに行われるとして、前回行われたのは 01:50 だったとする。 + // 次に save が行われるのは 02:10 ということになるが、もし 01:55 に新規ログが buffer に追加されたとすると、 + // そのログは本来は 01:00~ のログとしてDBに保存されて欲しいのに、02:00~ のログ扱いになってしまう。 + // これを回避するための実装は複雑になりそうなため、一旦保留。 + + const update = async (log: Log) => { + const finalDiffs = {} as Record; + + for (const diff of this.buffer.filter(q => q.group === log.group).map(q => q.diff)) { + const columns = Chart.convertObjectToFlattenColumns(diff); + + for (const [k, v] of Object.entries(columns)) { + if (finalDiffs[k] == null) { + finalDiffs[k] = v; + } else { + if (typeof finalDiffs[k] === 'number') { + (finalDiffs[k] as number) += v as number; + } else { + (finalDiffs[k] as unknown[]) = (finalDiffs[k] as unknown[]).concat(v); + } + } + } + } + + const query = Chart.convertQuery(finalDiffs); + + // ログ更新 + await this.repository.createQueryBuilder() + .update() + .set(query) + .where('id = :id', { id: log.id }) + .execute(); + + logger.info(`${this.name + (log.group ? `:${log.group}` : '')}: Updated`); + + // TODO: この一連の処理が始まった後に新たにbufferに入ったものは消さないようにする + this.buffer = this.buffer.filter(q => q.group !== log.group); + }; + + const groups = removeDuplicates(this.buffer.map(log => log.group)); + + await Promise.all(groups.map(group => this.getCurrentLog(group).then(log => update(log)))); + } + + @autobind + public async resync(group: string | null = null): Promise { + const data = await this.fetchActual(group); + + const update = async (log: Log) => { + await this.repository.createQueryBuilder() + .update() + .set(Chart.convertObjectToFlattenColumns(data)) + .where('id = :id', { id: log.id }) + .execute(); + }; + + return this.getCurrentLog(group).then(log => update(log)); + } + + @autobind + protected async inc(inc: DeepPartial, group: string | null = null): Promise { + await this.commit(inc, group); + } + + @autobind + public async getChart(span: 'hour' | 'day', amount: number, cursor: Date | null, group: string | null = null): Promise> { + 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; + + const lt = dateUTC([y, m, d, h, _m, _s, _ms]); + + const gt = + span === 'day' ? subtractTime(cursor ? dateUTC([y2, m2, d2, 0]) : dateUTC([y, m, d, 0]), amount - 1, 'day') : + span === 'hour' ? subtractTime(cursor ? dateUTC([y2, m2, d2, h2]) : dateUTC([y, m, d, h]), amount - 1, 'hour') : + null as never; + + // ログ取得 + let logs = await this.repository.find({ + where: { + group: group, + date: Between(Chart.dateToTimestamp(gt), Chart.dateToTimestamp(lt)) + }, + order: { + date: -1 + }, + }); + + // 要求された範囲にログがひとつもなかったら + if (logs.length === 0) { + // もっとも新しいログを持ってくる + // (すくなくともひとつログが無いと隙間埋めできないため) + const recentLog = await this.repository.findOne({ + group: group, + }, { + order: { + date: -1 + }, + }); + + if (recentLog) { + logs = [recentLog]; + } + + // 要求された範囲の最も古い箇所に位置するログが存在しなかったら + } else if (!isTimeSame(new Date(logs[logs.length - 1].date * 1000), gt)) { + // 要求された範囲の最も古い箇所時点での最も新しいログを持ってきて末尾に追加する + // (隙間埋めできないため) + const outdatedLog = await this.repository.findOne({ + group: group, + date: LessThan(Chart.dateToTimestamp(gt)) + }, { + order: { + date: -1 + }, + }); + + if (outdatedLog) { + logs.push(outdatedLog); + } + } + + const chart: T[] = []; + + if (span === 'hour') { + for (let i = (amount - 1); i >= 0; i--) { + const current = subtractTime(dateUTC([y, m, d, h]), i, 'hour'); + + 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); + } 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); + } + } + } else if (span === 'day') { + const logsForEachDays: T[][] = []; + let currentDay = -1; + let currentDayIndex = -1; + for (let i = ((amount - 1) * 24) + h; i >= 0; i--) { + const current = subtractTime(dateUTC([y, m, d, h]), i, 'hour'); + const _currentDay = Chart.parseDate(current)[2]; + if (currentDay != _currentDay) currentDayIndex++; + currentDay = _currentDay; + + const log = logs.find(l => isTimeSame(new Date(l.date * 1000), current)); + + if (log) { + if (logsForEachDays[currentDayIndex]) { + logsForEachDays[currentDayIndex].unshift(Chart.convertFlattenColumnsToObject(log) as T); + } else { + logsForEachDays[currentDayIndex] = [Chart.convertFlattenColumnsToObject(log) as T]; + } + } else { + // 隙間埋め + const latest = logs.find(l => isTimeBefore(new Date(l.date * 1000), current)); + const data = latest ? Chart.convertFlattenColumnsToObject(latest) as T : null; + const newLog = this.getNewLog(data); + if (logsForEachDays[currentDayIndex]) { + logsForEachDays[currentDayIndex].unshift(newLog); + } else { + logsForEachDays[currentDayIndex] = [newLog]; + } + } + } + + for (const logs of logsForEachDays) { + const log = this.aggregate(logs); + chart.unshift(Chart.countUniqueFields(log) as T); + } + } + + const res: ArrayValue = {} as any; + + /** + * [{ foo: 1, bar: 5 }, { foo: 2, bar: 6 }, { foo: 3, bar: 7 }] + * を + * { foo: [1, 2, 3], bar: [5, 6, 7] } + * にする + */ + const compact = (x: Obj, path?: string) => { + for (const [k, v] of Object.entries(x)) { + const p = path ? `${path}.${k}` : k; + if (typeof v === 'object' && !Array.isArray(v)) { + compact(v, p); + } else { + const values = chart.map(s => nestedProperty.get(s, p)); + nestedProperty.set(res, p, values); + } + } + }; + + compact(chart[0]); + + return res; + } +} + +export function convertLog(logSchema: SimpleSchema): SimpleSchema { + const v: SimpleSchema = 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]); + } + } + return v; +} diff --git a/src/services/chart/entities.ts b/packages/backend/src/services/chart/entities.ts similarity index 100% rename from src/services/chart/entities.ts rename to packages/backend/src/services/chart/entities.ts diff --git a/src/services/chart/index.ts b/packages/backend/src/services/chart/index.ts similarity index 100% rename from src/services/chart/index.ts rename to packages/backend/src/services/chart/index.ts diff --git a/src/services/create-notification.ts b/packages/backend/src/services/create-notification.ts similarity index 100% rename from src/services/create-notification.ts rename to packages/backend/src/services/create-notification.ts diff --git a/src/services/create-system-user.ts b/packages/backend/src/services/create-system-user.ts similarity index 100% rename from src/services/create-system-user.ts rename to packages/backend/src/services/create-system-user.ts diff --git a/src/services/drive/add-file.ts b/packages/backend/src/services/drive/add-file.ts similarity index 100% rename from src/services/drive/add-file.ts rename to packages/backend/src/services/drive/add-file.ts diff --git a/packages/backend/src/services/drive/delete-file.ts b/packages/backend/src/services/drive/delete-file.ts new file mode 100644 index 000000000..2ac11b829 --- /dev/null +++ b/packages/backend/src/services/drive/delete-file.ts @@ -0,0 +1,103 @@ +import { DriveFile } from '@/models/entities/drive-file'; +import { InternalStorage } from './internal-storage'; +import { DriveFiles, Instances } from '@/models/index'; +import { driveChart, perUserDriveChart, instanceChart } from '@/services/chart/index'; +import { createDeleteObjectStorageFileJob } from '@/queue/index'; +import { fetchMeta } from '@/misc/fetch-meta'; +import { getS3 } from './s3'; +import { v4 as uuid } from 'uuid'; + +export async function deleteFile(file: DriveFile, isExpired = false) { + if (file.storedInternal) { + InternalStorage.del(file.accessKey!); + + if (file.thumbnailUrl) { + InternalStorage.del(file.thumbnailAccessKey!); + } + + if (file.webpublicUrl) { + InternalStorage.del(file.webpublicAccessKey!); + } + } else if (!file.isLink) { + createDeleteObjectStorageFileJob(file.accessKey!); + + if (file.thumbnailUrl) { + createDeleteObjectStorageFileJob(file.thumbnailAccessKey!); + } + + if (file.webpublicUrl) { + createDeleteObjectStorageFileJob(file.webpublicAccessKey!); + } + } + + postProcess(file, isExpired); +} + +export async function deleteFileSync(file: DriveFile, isExpired = false) { + if (file.storedInternal) { + InternalStorage.del(file.accessKey!); + + if (file.thumbnailUrl) { + InternalStorage.del(file.thumbnailAccessKey!); + } + + if (file.webpublicUrl) { + InternalStorage.del(file.webpublicAccessKey!); + } + } else if (!file.isLink) { + const promises = []; + + promises.push(deleteObjectStorageFile(file.accessKey!)); + + if (file.thumbnailUrl) { + promises.push(deleteObjectStorageFile(file.thumbnailAccessKey!)); + } + + if (file.webpublicUrl) { + promises.push(deleteObjectStorageFile(file.webpublicAccessKey!)); + } + + await Promise.all(promises); + } + + postProcess(file, isExpired); +} + +async function postProcess(file: DriveFile, isExpired = false) { + // リモートファイル期限切れ削除後は直リンクにする + if (isExpired && file.userHost !== null && file.uri != null) { + DriveFiles.update(file.id, { + isLink: true, + url: file.uri, + thumbnailUrl: null, + webpublicUrl: null, + storedInternal: false, + // ローカルプロキシ用 + accessKey: uuid(), + thumbnailAccessKey: 'thumbnail-' + uuid(), + webpublicAccessKey: 'webpublic-' + uuid(), + }); + } else { + DriveFiles.delete(file.id); + } + + // 統計を更新 + driveChart.update(file, false); + perUserDriveChart.update(file, false); + if (file.userHost !== null) { + instanceChart.updateDrive(file, false); + Instances.decrement({ host: file.userHost }, 'driveUsage', file.size); + Instances.decrement({ host: file.userHost }, 'driveFiles', 1); + } +} + +export async function deleteObjectStorageFile(key: string) { + const meta = await fetchMeta(); + + const s3 = getS3(meta); + + await s3.deleteObject({ + Bucket: meta.objectStorageBucket!, + Key: key + }).promise(); +} diff --git a/src/services/drive/generate-video-thumbnail.ts b/packages/backend/src/services/drive/generate-video-thumbnail.ts similarity index 100% rename from src/services/drive/generate-video-thumbnail.ts rename to packages/backend/src/services/drive/generate-video-thumbnail.ts diff --git a/src/services/drive/image-processor.ts b/packages/backend/src/services/drive/image-processor.ts similarity index 100% rename from src/services/drive/image-processor.ts rename to packages/backend/src/services/drive/image-processor.ts diff --git a/packages/backend/src/services/drive/internal-storage.ts b/packages/backend/src/services/drive/internal-storage.ts new file mode 100644 index 000000000..fe190a028 --- /dev/null +++ b/packages/backend/src/services/drive/internal-storage.ts @@ -0,0 +1,35 @@ +import * as fs from 'fs'; +import * as Path from 'path'; +import { fileURLToPath } from 'url'; +import { dirname } from 'path'; +import config from '@/config/index'; + +//const _filename = fileURLToPath(import.meta.url); +const _filename = __filename; +const _dirname = dirname(_filename); + +export class InternalStorage { + private static readonly path = Path.resolve(_dirname, '../../../../../files'); + + public static resolvePath = (key: string) => Path.resolve(InternalStorage.path, key); + + public static read(key: string) { + return fs.createReadStream(InternalStorage.resolvePath(key)); + } + + public static saveFromPath(key: string, srcPath: string) { + fs.mkdirSync(InternalStorage.path, { recursive: true }); + fs.copyFileSync(srcPath, InternalStorage.resolvePath(key)); + return `${config.url}/files/${key}`; + } + + public static saveFromBuffer(key: string, data: Buffer) { + fs.mkdirSync(InternalStorage.path, { recursive: true }); + fs.writeFileSync(InternalStorage.resolvePath(key), data); + return `${config.url}/files/${key}`; + } + + public static del(key: string) { + fs.unlink(InternalStorage.resolvePath(key), () => {}); + } +} diff --git a/src/services/drive/logger.ts b/packages/backend/src/services/drive/logger.ts similarity index 100% rename from src/services/drive/logger.ts rename to packages/backend/src/services/drive/logger.ts diff --git a/src/services/drive/s3.ts b/packages/backend/src/services/drive/s3.ts similarity index 100% rename from src/services/drive/s3.ts rename to packages/backend/src/services/drive/s3.ts diff --git a/src/services/drive/upload-from-url.ts b/packages/backend/src/services/drive/upload-from-url.ts similarity index 100% rename from src/services/drive/upload-from-url.ts rename to packages/backend/src/services/drive/upload-from-url.ts diff --git a/src/services/fetch-instance-metadata.ts b/packages/backend/src/services/fetch-instance-metadata.ts similarity index 100% rename from src/services/fetch-instance-metadata.ts rename to packages/backend/src/services/fetch-instance-metadata.ts diff --git a/src/services/following/create.ts b/packages/backend/src/services/following/create.ts similarity index 100% rename from src/services/following/create.ts rename to packages/backend/src/services/following/create.ts diff --git a/src/services/following/delete.ts b/packages/backend/src/services/following/delete.ts similarity index 100% rename from src/services/following/delete.ts rename to packages/backend/src/services/following/delete.ts diff --git a/src/services/following/requests/accept-all.ts b/packages/backend/src/services/following/requests/accept-all.ts similarity index 100% rename from src/services/following/requests/accept-all.ts rename to packages/backend/src/services/following/requests/accept-all.ts diff --git a/src/services/following/requests/accept.ts b/packages/backend/src/services/following/requests/accept.ts similarity index 100% rename from src/services/following/requests/accept.ts rename to packages/backend/src/services/following/requests/accept.ts diff --git a/src/services/following/requests/cancel.ts b/packages/backend/src/services/following/requests/cancel.ts similarity index 100% rename from src/services/following/requests/cancel.ts rename to packages/backend/src/services/following/requests/cancel.ts diff --git a/src/services/following/requests/create.ts b/packages/backend/src/services/following/requests/create.ts similarity index 100% rename from src/services/following/requests/create.ts rename to packages/backend/src/services/following/requests/create.ts diff --git a/src/services/following/requests/reject.ts b/packages/backend/src/services/following/requests/reject.ts similarity index 100% rename from src/services/following/requests/reject.ts rename to packages/backend/src/services/following/requests/reject.ts diff --git a/src/services/i/pin.ts b/packages/backend/src/services/i/pin.ts similarity index 100% rename from src/services/i/pin.ts rename to packages/backend/src/services/i/pin.ts diff --git a/src/services/i/update.ts b/packages/backend/src/services/i/update.ts similarity index 100% rename from src/services/i/update.ts rename to packages/backend/src/services/i/update.ts diff --git a/src/services/insert-moderation-log.ts b/packages/backend/src/services/insert-moderation-log.ts similarity index 100% rename from src/services/insert-moderation-log.ts rename to packages/backend/src/services/insert-moderation-log.ts diff --git a/src/services/instance-actor.ts b/packages/backend/src/services/instance-actor.ts similarity index 100% rename from src/services/instance-actor.ts rename to packages/backend/src/services/instance-actor.ts diff --git a/packages/backend/src/services/logger.ts b/packages/backend/src/services/logger.ts new file mode 100644 index 000000000..709b9bae5 --- /dev/null +++ b/packages/backend/src/services/logger.ts @@ -0,0 +1,127 @@ +import * as cluster from 'cluster'; +import * as chalk from 'chalk'; +import * as dateformat from 'dateformat'; +import { envOption } from '../env'; +import config from '@/config/index'; + +import * as SyslogPro from 'syslog-pro'; + +type Domain = { + name: string; + color?: string; +}; + +type Level = 'error' | 'success' | 'warning' | 'debug' | 'info'; + +export default class Logger { + private domain: Domain; + private parentLogger: Logger | null = null; + private store: boolean; + private syslogClient: any | null = null; + + constructor(domain: string, color?: string, store = true) { + this.domain = { + name: domain, + color: color, + }; + this.store = store; + + if (config.syslog) { + this.syslogClient = new SyslogPro.RFC5424({ + applacationName: 'Misskey', + timestamp: true, + encludeStructuredData: true, + color: true, + extendedColor: true, + server: { + target: config.syslog.host, + port: config.syslog.port, + } + }); + } + } + + public createSubLogger(domain: string, color?: string, store = true): Logger { + const logger = new Logger(domain, color, store); + logger.parentLogger = this; + return logger; + } + + private log(level: Level, message: string, data?: Record | null, important = false, subDomains: Domain[] = [], store = true): void { + if (envOption.quiet) return; + if (!this.store) store = false; + if (level === 'debug') store = false; + + if (this.parentLogger) { + this.parentLogger.log(level, message, data, important, [this.domain].concat(subDomains), store); + return; + } + + 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 ') : + level === 'warning' ? chalk.yellow('WARN') : + level === 'success' ? important ? chalk.bgGreen.white('DONE') : chalk.green('DONE') : + level === 'debug' ? chalk.gray('VERB') : + level === 'info' ? chalk.blue('INFO') : + null; + const domains = [this.domain].concat(subDomains).map(d => d.color ? chalk.keyword(d.color)(d.name) : chalk.white(d.name)); + const m = + level === 'error' ? chalk.red(message) : + level === 'warning' ? chalk.yellow(message) : + level === 'success' ? chalk.green(message) : + level === 'debug' ? chalk.gray(message) : + level === 'info' ? message : + null; + + let log = `${l} ${worker}\t[${domains.join(' ')}]\t${m}`; + if (envOption.withLogTime) log = chalk.gray(time) + ' ' + log; + + console.log(important ? chalk.bold(log) : log); + + if (store) { + if (this.syslogClient) { + const send = + level === 'error' ? this.syslogClient.error : + level === 'warning' ? this.syslogClient.warning : + level === 'success' ? this.syslogClient.info : + level === 'debug' ? this.syslogClient.info : + level === 'info' ? this.syslogClient.info : + null as never; + + send.bind(this.syslogClient)(message).catch(() => {}); + } + } + } + + public error(x: string | Error, data?: Record | null, important = false): void { // 実行を継続できない状況で使う + if (x instanceof Error) { + data = data || {}; + data.e = x; + this.log('error', x.toString(), data, important); + } else if (typeof x === 'object') { + this.log('error', `${(x as any).message || (x as any).name || x}`, data, important); + } else { + this.log('error', `${x}`, data, important); + } + } + + public warn(message: string, data?: Record | null, important = false): void { // 実行を継続できるが改善すべき状況で使う + this.log('warning', message, data, important); + } + + public succ(message: string, data?: Record | null, important = false): void { // 何かに成功した状況で使う + this.log('success', message, data, important); + } + + public debug(message: string, data?: Record | null, important = false): void { // デバッグ用に使う(開発者に必要だが利用者に不要な情報) + if (process.env.NODE_ENV != 'production' || envOption.verbose) { + this.log('debug', message, data, important); + } + } + + public info(message: string, data?: Record | null, important = false): void { // それ以外 + this.log('info', message, data, important); + } +} diff --git a/src/services/messages/create.ts b/packages/backend/src/services/messages/create.ts similarity index 100% rename from src/services/messages/create.ts rename to packages/backend/src/services/messages/create.ts diff --git a/src/services/messages/delete.ts b/packages/backend/src/services/messages/delete.ts similarity index 100% rename from src/services/messages/delete.ts rename to packages/backend/src/services/messages/delete.ts diff --git a/packages/backend/src/services/note/create.ts b/packages/backend/src/services/note/create.ts new file mode 100644 index 000000000..8f6c2fe3a --- /dev/null +++ b/packages/backend/src/services/note/create.ts @@ -0,0 +1,642 @@ +import * as mfm from 'mfm-js'; +import es from '../../db/elasticsearch'; +import { publishMainStream, publishNotesStream } from '@/services/stream'; +import DeliverManager from '@/remote/activitypub/deliver-manager'; +import renderNote from '@/remote/activitypub/renderer/note'; +import renderCreate from '@/remote/activitypub/renderer/create'; +import renderAnnounce from '@/remote/activitypub/renderer/announce'; +import { renderActivity } from '@/remote/activitypub/renderer/index'; +import { resolveUser } from '@/remote/resolve-user'; +import config from '@/config/index'; +import { updateHashtags } from '../update-hashtag'; +import { concat } from '@/prelude/array'; +import { insertNoteUnread } from '@/services/note/unread'; +import { registerOrFetchInstanceDoc } from '../register-or-fetch-instance-doc'; +import { extractMentions } from '@/misc/extract-mentions'; +import { extractCustomEmojisFromMfm } from '@/misc/extract-custom-emojis-from-mfm'; +import { extractHashtags } from '@/misc/extract-hashtags'; +import { Note, IMentionedRemoteUsers } from '@/models/entities/note'; +import { Mutings, Users, NoteWatchings, Notes, Instances, UserProfiles, Antennas, Followings, MutedNotes, Channels, ChannelFollowings, Blockings, NoteThreadMutings } from '@/models/index'; +import { DriveFile } from '@/models/entities/drive-file'; +import { App } from '@/models/entities/app'; +import { Not, getConnection, In } from 'typeorm'; +import { User, ILocalUser, IRemoteUser } from '@/models/entities/user'; +import { genId } from '@/misc/gen-id'; +import { notesChart, perUserNotesChart, activeUsersChart, instanceChart } from '@/services/chart/index'; +import { Poll, IPoll } from '@/models/entities/poll'; +import { createNotification } from '../create-notification'; +import { isDuplicateKeyValueError } from '@/misc/is-duplicate-key-value-error'; +import { checkHitAntenna } from '@/misc/check-hit-antenna'; +import { checkWordMute } from '@/misc/check-word-mute'; +import { addNoteToAntenna } from '../add-note-to-antenna'; +import { countSameRenotes } from '@/misc/count-same-renotes'; +import { deliverToRelays } from '../relay'; +import { Channel } from '@/models/entities/channel'; +import { normalizeForSearch } from '@/misc/normalize-for-search'; +import { getAntennas } from '@/misc/antenna-cache'; + +type NotificationType = 'reply' | 'renote' | 'quote' | 'mention'; + +class NotificationManager { + private notifier: { id: User['id']; }; + private note: Note; + private queue: { + target: ILocalUser['id']; + reason: NotificationType; + }[]; + + constructor(notifier: { id: User['id']; }, note: Note) { + this.notifier = notifier; + this.note = note; + this.queue = []; + } + + public push(notifiee: ILocalUser['id'], reason: NotificationType) { + // 自分自身へは通知しない + if (this.notifier.id === notifiee) return; + + const exist = this.queue.find(x => x.target === notifiee); + + if (exist) { + // 「メンションされているかつ返信されている」場合は、メンションとしての通知ではなく返信としての通知にする + if (reason != 'mention') { + exist.reason = reason; + } + } else { + this.queue.push({ + reason: reason, + target: notifiee + }); + } + } + + public async deliver() { + for (const x of this.queue) { + // ミュート情報を取得 + const mentioneeMutes = await Mutings.find({ + muterId: x.target + }); + + const mentioneesMutedUserIds = mentioneeMutes.map(m => m.muteeId); + + // 通知される側のユーザーが通知する側のユーザーをミュートしていない限りは通知する + if (!mentioneesMutedUserIds.includes(this.notifier.id)) { + createNotification(x.target, x.reason, { + notifierId: this.notifier.id, + noteId: this.note.id + }); + } + } + } +} + +type Option = { + createdAt?: Date | null; + name?: string | null; + text?: string | null; + reply?: Note | null; + renote?: Note | null; + files?: DriveFile[] | null; + poll?: IPoll | null; + localOnly?: boolean | null; + cw?: string | null; + visibility?: string; + visibleUsers?: User[] | null; + channel?: Channel | null; + apMentions?: User[] | null; + apHashtags?: string[] | null; + apEmojis?: string[] | null; + uri?: string | null; + url?: string | null; + 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(async (res, rej) => { + // チャンネル外にリプライしたら対象のスコープに合わせる + // (クライアントサイドでやっても良い処理だと思うけどとりあえずサーバーサイドで) + if (data.reply && data.channel && data.reply.channelId !== data.channel.id) { + if (data.reply.channelId) { + data.channel = await Channels.findOne(data.reply.channelId); + } else { + data.channel = null; + } + } + + // チャンネル内にリプライしたら対象のスコープに合わせる + // (クライアントサイドでやっても良い処理だと思うけどとりあえずサーバーサイドで) + if (data.reply && (data.channel == null) && data.reply.channelId) { + data.channel = await Channels.findOne(data.reply.channelId); + } + + if (data.createdAt == null) data.createdAt = new Date(); + if (data.visibility == null) data.visibility = 'public'; + if (data.localOnly == null) data.localOnly = false; + if (data.channel != null) data.visibility = 'public'; + if (data.channel != null) data.visibleUsers = []; + if (data.channel != null) data.localOnly = true; + + // サイレンス + if (user.isSilenced && data.visibility === 'public' && data.channel == null) { + data.visibility = 'home'; + } + + // Renote対象が「ホームまたは全体」以外の公開範囲ならreject + if (data.renote && data.renote.visibility !== 'public' && data.renote.visibility !== 'home' && data.renote.userId !== user.id) { + return rej('Renote target is not public or home'); + } + + // Renote対象がpublicではないならhomeにする + if (data.renote && data.renote.visibility !== 'public' && data.visibility === 'public') { + data.visibility = 'home'; + } + + // Renote対象がfollowersならfollowersにする + if (data.renote && data.renote.visibility === 'followers') { + data.visibility = 'followers'; + } + + // 返信対象がpublicではないならhomeにする + if (data.reply && data.reply.visibility !== 'public' && data.visibility === 'public') { + data.visibility = 'home'; + } + + // ローカルのみをRenoteしたらローカルのみにする + if (data.renote && data.renote.localOnly && data.channel == null) { + data.localOnly = true; + } + + // ローカルのみにリプライしたらローカルのみにする + if (data.reply && data.reply.localOnly && data.channel == null) { + data.localOnly = true; + } + + if (data.text) { + data.text = data.text.trim(); + } + + let tags = data.apHashtags; + let emojis = data.apEmojis; + let mentionedUsers = data.apMentions; + + // Parse MFM if needed + if (!tags || !emojis || !mentionedUsers) { + const tokens = data.text ? mfm.parse(data.text)! : []; + const cwTokens = data.cw ? mfm.parse(data.cw)! : []; + const choiceTokens = data.poll && data.poll.choices + ? concat(data.poll.choices.map(choice => mfm.parse(choice)!)) + : []; + + const combinedTokens = tokens.concat(cwTokens).concat(choiceTokens); + + tags = data.apHashtags || extractHashtags(combinedTokens); + + emojis = data.apEmojis || extractCustomEmojisFromMfm(combinedTokens); + + mentionedUsers = data.apMentions || await extractMentionedUsers(user, combinedTokens); + } + + tags = tags.filter(tag => Array.from(tag || '').length <= 128).splice(0, 32); + + if (data.reply && (user.id !== data.reply.userId) && !mentionedUsers.some(u => u.id === data.reply!.userId)) { + mentionedUsers.push(await Users.findOneOrFail(data.reply.userId)); + } + + if (data.visibility == 'specified') { + if (data.visibleUsers == null) throw new Error('invalid param'); + + for (const u of data.visibleUsers) { + if (!mentionedUsers.some(x => x.id === u.id)) { + mentionedUsers.push(u); + } + } + + if (data.reply && !data.visibleUsers.some(x => x.id === data.reply!.userId)) { + data.visibleUsers.push(await Users.findOneOrFail(data.reply.userId)); + } + } + + const note = await insertNote(user, data, tags, emojis, mentionedUsers); + + res(note); + + // 統計を更新 + notesChart.update(note, true); + perUserNotesChart.update(user, note, true); + + // Register host + if (Users.isRemoteUser(user)) { + registerOrFetchInstanceDoc(user.host).then(i => { + Instances.increment({ id: i.id }, 'notesCount', 1); + instanceChart.updateNote(i.host, note, true); + }); + } + + // ハッシュタグ更新 + if (data.visibility === 'public' || data.visibility === 'home') { + updateHashtags(user, tags); + } + + // Increment notes count (user) + incNotesCountOfUser(user); + + // Word mute + // TODO: cache + UserProfiles.find({ + enableWordMute: true + }).then(us => { + for (const u of us) { + checkWordMute(note, { id: u.userId }, u.mutedWords).then(shouldMute => { + if (shouldMute) { + MutedNotes.insert({ + id: genId(), + userId: u.userId, + noteId: note.id, + reason: 'word', + }); + } + }); + } + }); + + // Antenna + Followings.createQueryBuilder('following') + .andWhere(`following.followeeId = :userId`, { userId: note.userId }) + .getMany() + .then(async followings => { + const blockings = await Blockings.find({ blockerId: user.id }); // TODO: キャッシュしたい + const followers = followings.map(f => f.followerId); + for (const antenna of (await getAntennas())) { + if (blockings.some(blocking => blocking.blockeeId === antenna.userId)) continue; // この処理は checkHitAntenna 内でやるようにしてもいいかも + checkHitAntenna(antenna, note, user, followers).then(hit => { + if (hit) { + addNoteToAntenna(antenna, note, user); + } + }); + } + }); + + // Channel + if (note.channelId) { + ChannelFollowings.find({ followeeId: note.channelId }).then(followings => { + for (const following of followings) { + insertNoteUnread(following.followerId, note, { + isSpecified: false, + isMentioned: false, + }); + } + }); + } + + if (data.reply) { + saveReply(data.reply, note); + } + + // この投稿を除く指定したユーザーによる指定したノートのリノートが存在しないとき + if (data.renote && (await countSameRenotes(user.id, data.renote.id, note.id) === 0)) { + incRenoteCount(data.renote); + } + + if (!silent) { + // ローカルユーザーのチャートはタイムライン取得時に更新しているのでリモートユーザーの場合だけでよい + if (Users.isRemoteUser(user)) activeUsersChart.update(user); + + // 未読通知を作成 + if (data.visibility == 'specified') { + if (data.visibleUsers == null) throw new Error('invalid param'); + + for (const u of data.visibleUsers) { + // ローカルユーザーのみ + if (!Users.isLocalUser(u)) continue; + + insertNoteUnread(u.id, note, { + isSpecified: true, + isMentioned: false, + }); + } + } else { + for (const u of mentionedUsers) { + // ローカルユーザーのみ + if (!Users.isLocalUser(u)) continue; + + insertNoteUnread(u.id, note, { + isSpecified: false, + isMentioned: true, + }); + } + } + + // Pack the note + const noteObj = await Notes.pack(note); + + publishNotesStream(noteObj); + + const nm = new NotificationManager(user, note); + const nmRelatedPromises = []; + + await createMentionedEvents(mentionedUsers, note, nm); + + // If has in reply to note + if (data.reply) { + // Fetch watchers + nmRelatedPromises.push(notifyToWatchersOfReplyee(data.reply, user, nm)); + + // 通知 + if (data.reply.userHost === null) { + const threadMuted = await NoteThreadMutings.findOne({ + userId: data.reply.userId, + threadId: data.reply.threadId || data.reply.id, + }); + + if (!threadMuted) { + nm.push(data.reply.userId, 'reply'); + publishMainStream(data.reply.userId, 'reply', noteObj); + } + } + } + + // If it is renote + if (data.renote) { + const type = data.text ? 'quote' : 'renote'; + + // Notify + if (data.renote.userHost === null) { + nm.push(data.renote.userId, type); + } + + // Fetch watchers + nmRelatedPromises.push(notifyToWatchersOfRenotee(data.renote, user, nm, type)); + + // Publish event + if ((user.id !== data.renote.userId) && data.renote.userHost === null) { + publishMainStream(data.renote.userId, 'renote', noteObj); + } + } + + Promise.all(nmRelatedPromises).then(() => { + nm.deliver(); + }); + + //#region AP deliver + if (Users.isLocalUser(user)) { + (async () => { + const noteActivity = await renderNoteOrRenoteActivity(data, note); + const dm = new DeliverManager(user, noteActivity); + + // メンションされたリモートユーザーに配送 + for (const u of mentionedUsers.filter(u => Users.isRemoteUser(u))) { + dm.addDirectRecipe(u as IRemoteUser); + } + + // 投稿がリプライかつ投稿者がローカルユーザーかつリプライ先の投稿の投稿者がリモートユーザーなら配送 + if (data.reply && data.reply.userHost !== null) { + const u = await Users.findOne(data.reply.userId); + if (u && Users.isRemoteUser(u)) dm.addDirectRecipe(u); + } + + // 投稿がRenoteかつ投稿者がローカルユーザーかつRenote元の投稿の投稿者がリモートユーザーなら配送 + if (data.renote && data.renote.userHost !== null) { + const u = await Users.findOne(data.renote.userId); + if (u && Users.isRemoteUser(u)) dm.addDirectRecipe(u); + } + + // フォロワーに配送 + if (['public', 'home', 'followers'].includes(note.visibility)) { + dm.addFollowersRecipe(); + } + + if (['public'].includes(note.visibility)) { + deliverToRelays(user, noteActivity); + } + + dm.execute(); + })(); + } + //#endregion + } + + if (data.channel) { + Channels.increment({ id: data.channel.id }, 'notesCount', 1); + Channels.update(data.channel.id, { + lastNotedAt: new Date(), + }); + + Notes.count({ + userId: user.id, + channelId: data.channel.id, + }).then(count => { + // この処理が行われるのはノート作成後なので、ノートが一つしかなかったら最初の投稿だと判断できる + // TODO: とはいえノートを削除して何回も投稿すればその分だけインクリメントされる雑さもあるのでどうにかしたい + if (count === 1) { + Channels.increment({ id: data.channel!.id }, 'usersCount', 1); + } + }); + } + + // Register to search database + index(note); +}); + +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) + ? renderAnnounce(data.renote.uri ? data.renote.uri : `${config.url}/notes/${data.renote.id}`, note) + : renderCreate(await renderNote(note, false), note); + + return renderActivity(content); +} + +function incRenoteCount(renote: Note) { + Notes.createQueryBuilder().update() + .set({ + renoteCount: () => '"renoteCount" + 1', + score: () => '"score" + 1' + }) + .where('id = :id', { id: renote.id }) + .execute(); +} + +async function insertNote(user: { id: User['id']; host: User['host']; }, data: Option, tags: string[], emojis: string[], mentionedUsers: User[]) { + const insert = new Note({ + id: genId(data.createdAt!), + createdAt: data.createdAt!, + fileIds: data.files ? data.files.map(file => file.id) : [], + replyId: data.reply ? data.reply.id : null, + renoteId: data.renote ? data.renote.id : null, + channelId: data.channel ? data.channel.id : null, + threadId: data.reply + ? data.reply.threadId + ? data.reply.threadId + : data.reply.id + : null, + name: data.name, + text: data.text, + hasPoll: data.poll != null, + cw: data.cw == null ? null : data.cw, + tags: tags.map(tag => normalizeForSearch(tag)), + emojis, + userId: user.id, + localOnly: data.localOnly!, + visibility: data.visibility as any, + visibleUserIds: data.visibility == 'specified' + ? data.visibleUsers + ? data.visibleUsers.map(u => u.id) + : [] + : [], + + attachedFileTypes: data.files ? data.files.map(file => file.type) : [], + + // 以下非正規化データ + replyUserId: data.reply ? data.reply.userId : null, + replyUserHost: data.reply ? data.reply.userHost : null, + renoteUserId: data.renote ? data.renote.userId : null, + renoteUserHost: data.renote ? data.renote.userHost : null, + userHost: user.host, + }); + + if (data.uri != null) insert.uri = data.uri; + if (data.url != null) insert.url = data.url; + + // Append mentions data + if (mentionedUsers.length > 0) { + 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 url = profile != null ? profile.url : null; + return { + uri: u.uri, + url: url == null ? undefined : url, + username: u.username, + host: u.host + } as IMentionedRemoteUsers[0]; + })); + } + + // 投稿を作成 + try { + if (insert.hasPoll) { + // Start transaction + await getConnection().transaction(async transactionalEntityManager => { + await transactionalEntityManager.insert(Note, insert); + + const poll = new Poll({ + noteId: insert.id, + choices: data.poll!.choices, + expiresAt: data.poll!.expiresAt, + multiple: data.poll!.multiple, + votes: new Array(data.poll!.choices.length).fill(0), + noteVisibility: insert.visibility, + userId: user.id, + userHost: user.host + }); + + await transactionalEntityManager.insert(Poll, poll); + }); + } else { + await Notes.insert(insert); + } + + return insert; + } catch (e) { + // duplicate key error + if (isDuplicateKeyValueError(e)) { + const err = new Error('Duplicated note'); + err.name = 'duplicated'; + throw err; + } + + console.error(e); + + throw e; + } +} + +function index(note: Note) { + if (note.text == null || config.elasticsearch == null) return; + + es!.index({ + index: config.elasticsearch.index || 'misskey_note', + id: note.id.toString(), + body: { + text: normalizeForSearch(note.text), + userId: note.userId, + userHost: note.userHost + } + }); +} + +async function notifyToWatchersOfRenotee(renote: Note, user: { id: User['id']; }, nm: NotificationManager, type: NotificationType) { + const watchers = await NoteWatchings.find({ + noteId: renote.id, + userId: Not(user.id) + }); + + for (const watcher of watchers) { + nm.push(watcher.userId, type); + } +} + +async function notifyToWatchersOfReplyee(reply: Note, user: { id: User['id']; }, nm: NotificationManager) { + const watchers = await NoteWatchings.find({ + noteId: reply.id, + userId: Not(user.id) + }); + + for (const watcher of watchers) { + nm.push(watcher.userId, 'reply'); + } +} + +async function createMentionedEvents(mentionedUsers: User[], note: Note, nm: NotificationManager) { + for (const u of mentionedUsers.filter(u => Users.isLocalUser(u))) { + const threadMuted = await NoteThreadMutings.findOne({ + userId: u.id, + threadId: note.threadId || note.id, + }); + + if (threadMuted) { + continue; + } + + const detailPackedNote = await Notes.pack(note, u, { + detail: true + }); + + publishMainStream(u.id, 'mention', detailPackedNote); + + // Create notification + nm.push(u.id, 'mention'); + } +} + +function saveReply(reply: Note, note: Note) { + Notes.increment({ id: reply.id }, 'repliesCount', 1); +} + +function incNotesCountOfUser(user: { id: User['id']; }) { + Users.createQueryBuilder().update() + .set({ + updatedAt: new Date(), + notesCount: () => '"notesCount" + 1' + }) + .where('id = :id', { id: user.id }) + .execute(); +} + +async function extractMentionedUsers(user: { host: User['host']; }, tokens: mfm.MfmNode[]): Promise { + if (tokens == null) return []; + + const mentions = extractMentions(tokens); + + let mentionedUsers = (await Promise.all(mentions.map(m => + resolveUser(m.username, m.host || user.host).catch(() => null) + ))).filter(x => x != null) as User[]; + + // Drop duplicate users + mentionedUsers = mentionedUsers.filter((u, i, self) => + i === self.findIndex(u2 => u.id === u2.id) + ); + + return mentionedUsers; +} diff --git a/src/services/note/delete.ts b/packages/backend/src/services/note/delete.ts similarity index 100% rename from src/services/note/delete.ts rename to packages/backend/src/services/note/delete.ts diff --git a/src/services/note/polls/update.ts b/packages/backend/src/services/note/polls/update.ts similarity index 100% rename from src/services/note/polls/update.ts rename to packages/backend/src/services/note/polls/update.ts diff --git a/src/services/note/polls/vote.ts b/packages/backend/src/services/note/polls/vote.ts similarity index 100% rename from src/services/note/polls/vote.ts rename to packages/backend/src/services/note/polls/vote.ts diff --git a/src/services/note/reaction/create.ts b/packages/backend/src/services/note/reaction/create.ts similarity index 100% rename from src/services/note/reaction/create.ts rename to packages/backend/src/services/note/reaction/create.ts diff --git a/src/services/note/reaction/delete.ts b/packages/backend/src/services/note/reaction/delete.ts similarity index 100% rename from src/services/note/reaction/delete.ts rename to packages/backend/src/services/note/reaction/delete.ts diff --git a/src/services/note/read.ts b/packages/backend/src/services/note/read.ts similarity index 100% rename from src/services/note/read.ts rename to packages/backend/src/services/note/read.ts diff --git a/src/services/note/unread.ts b/packages/backend/src/services/note/unread.ts similarity index 100% rename from src/services/note/unread.ts rename to packages/backend/src/services/note/unread.ts diff --git a/src/services/note/unwatch.ts b/packages/backend/src/services/note/unwatch.ts similarity index 100% rename from src/services/note/unwatch.ts rename to packages/backend/src/services/note/unwatch.ts diff --git a/src/services/note/watch.ts b/packages/backend/src/services/note/watch.ts similarity index 100% rename from src/services/note/watch.ts rename to packages/backend/src/services/note/watch.ts diff --git a/src/services/push-notification.ts b/packages/backend/src/services/push-notification.ts similarity index 100% rename from src/services/push-notification.ts rename to packages/backend/src/services/push-notification.ts diff --git a/src/services/register-or-fetch-instance-doc.ts b/packages/backend/src/services/register-or-fetch-instance-doc.ts similarity index 100% rename from src/services/register-or-fetch-instance-doc.ts rename to packages/backend/src/services/register-or-fetch-instance-doc.ts diff --git a/src/services/relay.ts b/packages/backend/src/services/relay.ts similarity index 100% rename from src/services/relay.ts rename to packages/backend/src/services/relay.ts diff --git a/packages/backend/src/services/send-email-notification.ts b/packages/backend/src/services/send-email-notification.ts new file mode 100644 index 000000000..157bacb46 --- /dev/null +++ b/packages/backend/src/services/send-email-notification.ts @@ -0,0 +1,31 @@ +import { UserProfiles } from '@/models/index'; +import { User } from '@/models/entities/user'; +import { sendEmail } from './send-email'; +import { I18n } from '@/misc/i18n'; +import * as Acct from 'misskey-js/built/acct'; +const locales = require('../../../../locales/index.js'); + +// TODO: locale ファイルをクライアント用とサーバー用で分けたい + +async function follow(userId: User['id'], follower: User) { + const userProfile = await UserProfiles.findOneOrFail({ userId: userId }); + if (!userProfile.email || !userProfile.emailNotificationTypes.includes('follow')) return; + const locale = locales[userProfile.lang || 'ja-JP']; + const i18n = new I18n(locale); + // TODO: render user information html + sendEmail(userProfile.email, i18n.t('_email._follow.title'), `${follower.name} (@${Acct.toString(follower)})`, `${follower.name} (@${Acct.toString(follower)})`); +} + +async function receiveFollowRequest(userId: User['id'], follower: User) { + const userProfile = await UserProfiles.findOneOrFail({ userId: userId }); + if (!userProfile.email || !userProfile.emailNotificationTypes.includes('receiveFollowRequest')) return; + const locale = locales[userProfile.lang || 'ja-JP']; + const i18n = new I18n(locale); + // TODO: render user information html + sendEmail(userProfile.email, i18n.t('_email._receiveFollowRequest.title'), `${follower.name} (@${Acct.toString(follower)})`, `${follower.name} (@${Acct.toString(follower)})`); +} + +export const sendEmailNotification = { + follow, + receiveFollowRequest, +}; diff --git a/packages/backend/src/services/send-email.ts b/packages/backend/src/services/send-email.ts new file mode 100644 index 000000000..f5f36148f --- /dev/null +++ b/packages/backend/src/services/send-email.ts @@ -0,0 +1,122 @@ +import * as nodemailer from 'nodemailer'; +import { fetchMeta } from '@/misc/fetch-meta'; +import Logger from './logger'; +import config from '@/config/index'; + +export const logger = new Logger('email'); + +export async function sendEmail(to: string, subject: string, html: string, text: string) { + const meta = await fetchMeta(true); + + const iconUrl = `${config.url}/static-assets/mi-white.png`; + const emailSettingUrl = `${config.url}/settings/email`; + + const enableAuth = meta.smtpUser != null && meta.smtpUser !== ''; + + const transporter = nodemailer.createTransport({ + host: meta.smtpHost, + port: meta.smtpPort, + secure: meta.smtpSecure, + ignoreTLS: !enableAuth, + proxy: config.proxySmtp, + auth: enableAuth ? { + user: meta.smtpUser, + pass: meta.smtpPass, + } : undefined, + } as any); + + try { + // TODO: htmlサニタイズ + const info = await transporter.sendMail({ + from: meta.email!, + to: to, + subject: subject, + text: text, + html: ` + + + + ${ subject } + + + +
+
+ +
+
+

${ subject }

+
${ html }
+
+ +
+ + +`, + }); + + logger.info('Message sent: %s', info.messageId); + } catch (e) { + logger.error(e); + throw e; + } +} diff --git a/packages/backend/src/services/stream.ts b/packages/backend/src/services/stream.ts new file mode 100644 index 000000000..0901857c3 --- /dev/null +++ b/packages/backend/src/services/stream.ts @@ -0,0 +1,129 @@ +import { redisClient } from '../db/redis'; +import { User } from '@/models/entities/user'; +import { Note } from '@/models/entities/note'; +import { UserList } from '@/models/entities/user-list'; +import { ReversiGame } from '@/models/entities/games/reversi/game'; +import { UserGroup } from '@/models/entities/user-group'; +import config from '@/config/index'; +import { Antenna } from '@/models/entities/antenna'; +import { Channel } from '@/models/entities/channel'; +import { + StreamChannels, + AdminStreamTypes, + AntennaStreamTypes, + BroadcastTypes, + ChannelStreamTypes, + DriveStreamTypes, + GroupMessagingStreamTypes, + InternalStreamTypes, + MainStreamTypes, + MessagingIndexStreamTypes, + MessagingStreamTypes, + NoteStreamTypes, + ReversiGameStreamTypes, + ReversiStreamTypes, + UserListStreamTypes, + UserStreamTypes +} from '@/server/api/stream/types'; +import { Packed } from '@/misc/schema'; + +class Publisher { + private publish = (channel: StreamChannels, type: string | null, value?: any): void => { + const message = type == null ? value : value == null ? + { type: type, body: null } : + { type: type, body: value }; + + redisClient.publish(config.host, JSON.stringify({ + channel: channel, + message: message + })); + }; + + public publishInternalEvent = (type: K, value?: InternalStreamTypes[K]): void => { + this.publish('internal', type, typeof value === 'undefined' ? null : value); + }; + + public publishUserEvent = (userId: User['id'], type: K, value?: UserStreamTypes[K]): void => { + this.publish(`user:${userId}`, type, typeof value === 'undefined' ? null : value); + }; + + public publishBroadcastStream = (type: K, value?: BroadcastTypes[K]): void => { + this.publish('broadcast', type, typeof value === 'undefined' ? null : value); + }; + + public publishMainStream = (userId: User['id'], type: K, value?: MainStreamTypes[K]): void => { + this.publish(`mainStream:${userId}`, type, typeof value === 'undefined' ? null : value); + }; + + public publishDriveStream = (userId: User['id'], type: K, value?: DriveStreamTypes[K]): void => { + this.publish(`driveStream:${userId}`, type, typeof value === 'undefined' ? null : value); + }; + + public publishNoteStream = (noteId: Note['id'], type: K, value?: NoteStreamTypes[K]): void => { + this.publish(`noteStream:${noteId}`, type, { + id: noteId, + body: value + }); + }; + + public publishChannelStream = (channelId: Channel['id'], type: K, value?: ChannelStreamTypes[K]): void => { + this.publish(`channelStream:${channelId}`, type, typeof value === 'undefined' ? null : value); + }; + + public publishUserListStream = (listId: UserList['id'], type: K, value?: UserListStreamTypes[K]): void => { + this.publish(`userListStream:${listId}`, type, typeof value === 'undefined' ? null : value); + }; + + public publishAntennaStream = (antennaId: Antenna['id'], type: K, value?: AntennaStreamTypes[K]): void => { + this.publish(`antennaStream:${antennaId}`, type, typeof value === 'undefined' ? null : value); + }; + + public publishMessagingStream = (userId: User['id'], otherpartyId: User['id'], type: K, value?: MessagingStreamTypes[K]): void => { + this.publish(`messagingStream:${userId}-${otherpartyId}`, type, typeof value === 'undefined' ? null : value); + }; + + public publishGroupMessagingStream = (groupId: UserGroup['id'], type: K, value?: GroupMessagingStreamTypes[K]): void => { + this.publish(`messagingStream:${groupId}`, type, typeof value === 'undefined' ? null : value); + }; + + public publishMessagingIndexStream = (userId: User['id'], type: K, value?: MessagingIndexStreamTypes[K]): void => { + this.publish(`messagingIndexStream:${userId}`, type, typeof value === 'undefined' ? null : value); + }; + + public publishReversiStream = (userId: User['id'], type: K, value?: ReversiStreamTypes[K]): void => { + this.publish(`reversiStream:${userId}`, type, typeof value === 'undefined' ? null : value); + }; + + public publishReversiGameStream = (gameId: ReversiGame['id'], type: K, value?: ReversiGameStreamTypes[K]): void => { + this.publish(`reversiGameStream:${gameId}`, type, typeof value === 'undefined' ? null : value); + }; + + public publishNotesStream = (note: Packed<'Note'>): void => { + this.publish('notesStream', null, note); + }; + + public publishAdminStream = (userId: User['id'], type: K, value?: AdminStreamTypes[K]): void => { + this.publish(`adminStream:${userId}`, type, typeof value === 'undefined' ? null : value); + }; +} + +const publisher = new Publisher(); + +export default publisher; + +export const publishInternalEvent = publisher.publishInternalEvent; +export const publishUserEvent = publisher.publishUserEvent; +export const publishBroadcastStream = publisher.publishBroadcastStream; +export const publishMainStream = publisher.publishMainStream; +export const publishDriveStream = publisher.publishDriveStream; +export const publishNoteStream = publisher.publishNoteStream; +export const publishNotesStream = publisher.publishNotesStream; +export const publishChannelStream = publisher.publishChannelStream; +export const publishUserListStream = publisher.publishUserListStream; +export const publishAntennaStream = publisher.publishAntennaStream; +export const publishMessagingStream = publisher.publishMessagingStream; +export const publishGroupMessagingStream = publisher.publishGroupMessagingStream; +export const publishMessagingIndexStream = publisher.publishMessagingIndexStream; +export const publishReversiStream = publisher.publishReversiStream; +export const publishReversiGameStream = publisher.publishReversiGameStream; +export const publishAdminStream = publisher.publishAdminStream; diff --git a/src/services/suspend-user.ts b/packages/backend/src/services/suspend-user.ts similarity index 100% rename from src/services/suspend-user.ts rename to packages/backend/src/services/suspend-user.ts diff --git a/src/services/unsuspend-user.ts b/packages/backend/src/services/unsuspend-user.ts similarity index 100% rename from src/services/unsuspend-user.ts rename to packages/backend/src/services/unsuspend-user.ts diff --git a/src/services/update-hashtag.ts b/packages/backend/src/services/update-hashtag.ts similarity index 100% rename from src/services/update-hashtag.ts rename to packages/backend/src/services/update-hashtag.ts diff --git a/src/services/user-list/push.ts b/packages/backend/src/services/user-list/push.ts similarity index 100% rename from src/services/user-list/push.ts rename to packages/backend/src/services/user-list/push.ts diff --git a/packages/backend/src/services/validate-email-for-account.ts b/packages/backend/src/services/validate-email-for-account.ts new file mode 100644 index 000000000..1d039fb26 --- /dev/null +++ b/packages/backend/src/services/validate-email-for-account.ts @@ -0,0 +1,34 @@ +import validateEmail from 'deep-email-validator'; +import { UserProfiles } from '@/models'; + +export async function validateEmailForAccount(emailAddress: string): Promise<{ + available: boolean; + reason: null | 'used' | 'format' | 'disposable' | 'mx' | 'smtp'; +}> { + const exist = await UserProfiles.count({ + emailVerified: true, + email: emailAddress, + }); + + const validated = await validateEmail({ + email: emailAddress, + validateRegex: true, + validateMx: true, + validateTypo: false, // TLDを見ているみたいだけどclubとか弾かれるので + validateDisposable: true, // 捨てアドかどうかチェック + validateSMTP: false, // 日本だと25ポートが殆どのプロバイダーで塞がれていてタイムアウトになるので + }); + + const available = exist === 0 && validated.valid; + + return { + available, + reason: available ? null : + exist !== 0 ? 'used' : + validated.reason === 'regex' ? 'format' : + validated.reason === 'disposable' ? 'disposable' : + validated.reason === 'mx' ? 'mx' : + validated.reason === 'smtp' ? 'smtp' : + null, + }; +} diff --git a/packages/backend/src/types.ts b/packages/backend/src/types.ts new file mode 100644 index 000000000..20f6f8bb8 --- /dev/null +++ b/packages/backend/src/types.ts @@ -0,0 +1,7 @@ +export const notificationTypes = ['follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'receiveFollowRequest', 'followRequestAccepted', 'groupInvited', 'app'] as const; + +export const noteVisibilities = ['public', 'home', 'followers', 'specified'] as const; + +export const mutedNoteReasons = ['word', 'manual', 'spam', 'other'] as const; + +export const ffVisibility = ['public', 'followers', 'private'] as const; diff --git a/test/.eslintrc b/packages/backend/test/.eslintrc similarity index 100% rename from test/.eslintrc rename to packages/backend/test/.eslintrc diff --git a/test/activitypub.ts b/packages/backend/test/activitypub.ts similarity index 100% rename from test/activitypub.ts rename to packages/backend/test/activitypub.ts diff --git a/test/ap-request.ts b/packages/backend/test/ap-request.ts similarity index 100% rename from test/ap-request.ts rename to packages/backend/test/ap-request.ts diff --git a/test/api-visibility.ts b/packages/backend/test/api-visibility.ts similarity index 100% rename from test/api-visibility.ts rename to packages/backend/test/api-visibility.ts diff --git a/test/api.ts b/packages/backend/test/api.ts similarity index 100% rename from test/api.ts rename to packages/backend/test/api.ts diff --git a/test/block.ts b/packages/backend/test/block.ts similarity index 100% rename from test/block.ts rename to packages/backend/test/block.ts diff --git a/test/chart.ts b/packages/backend/test/chart.ts similarity index 100% rename from test/chart.ts rename to packages/backend/test/chart.ts diff --git a/test/docker-compose.yml b/packages/backend/test/docker-compose.yml similarity index 100% rename from test/docker-compose.yml rename to packages/backend/test/docker-compose.yml diff --git a/test/extract-mentions.ts b/packages/backend/test/extract-mentions.ts similarity index 100% rename from test/extract-mentions.ts rename to packages/backend/test/extract-mentions.ts diff --git a/test/fetch-resource.ts b/packages/backend/test/fetch-resource.ts similarity index 100% rename from test/fetch-resource.ts rename to packages/backend/test/fetch-resource.ts diff --git a/packages/backend/test/ff-visibility.ts b/packages/backend/test/ff-visibility.ts new file mode 100644 index 000000000..295ab1933 --- /dev/null +++ b/packages/backend/test/ff-visibility.ts @@ -0,0 +1,167 @@ +process.env.NODE_ENV = 'test'; + +import * as assert from 'assert'; +import * as childProcess from 'child_process'; +import { async, signup, request, post, react, connectStream, startServer, shutdownServer, simpleGet } from './utils'; + +describe('FF visibility', () => { + let p: childProcess.ChildProcess; + + let alice: any; + let bob: any; + let carol: any; + + before(async () => { + p = await startServer(); + alice = await signup({ username: 'alice' }); + bob = await signup({ username: 'bob' }); + carol = await signup({ username: 'carol' }); + }); + + after(async () => { + await shutdownServer(p); + }); + + it('ffVisibility が public なユーザーのフォロー/フォロワーを誰でも見れる', async(async () => { + await request('/i/update', { + ffVisibility: 'public', + }, alice); + + const followingRes = await request('/users/following', { + userId: alice.id, + }, bob); + const followersRes = await request('/users/followers', { + userId: alice.id, + }, bob); + + assert.strictEqual(followingRes.status, 200); + assert.strictEqual(Array.isArray(followingRes.body), true); + assert.strictEqual(followersRes.status, 200); + assert.strictEqual(Array.isArray(followersRes.body), true); + })); + + it('ffVisibility が followers なユーザーのフォロー/フォロワーを自分で見れる', async(async () => { + await request('/i/update', { + ffVisibility: 'followers', + }, alice); + + const followingRes = await request('/users/following', { + userId: alice.id, + }, alice); + const followersRes = await request('/users/followers', { + userId: alice.id, + }, alice); + + assert.strictEqual(followingRes.status, 200); + assert.strictEqual(Array.isArray(followingRes.body), true); + assert.strictEqual(followersRes.status, 200); + assert.strictEqual(Array.isArray(followersRes.body), true); + })); + + it('ffVisibility が followers なユーザーのフォロー/フォロワーを非フォロワーが見れない', async(async () => { + await request('/i/update', { + ffVisibility: 'followers', + }, alice); + + const followingRes = await request('/users/following', { + userId: alice.id, + }, bob); + const followersRes = await request('/users/followers', { + userId: alice.id, + }, bob); + + assert.strictEqual(followingRes.status, 400); + assert.strictEqual(followersRes.status, 400); + })); + + it('ffVisibility が followers なユーザーのフォロー/フォロワーをフォロワーが見れる', async(async () => { + await request('/i/update', { + ffVisibility: 'followers', + }, alice); + + await request('/following/create', { + userId: alice.id, + }, bob); + + const followingRes = await request('/users/following', { + userId: alice.id, + }, bob); + const followersRes = await request('/users/followers', { + userId: alice.id, + }, bob); + + assert.strictEqual(followingRes.status, 200); + assert.strictEqual(Array.isArray(followingRes.body), true); + assert.strictEqual(followersRes.status, 200); + assert.strictEqual(Array.isArray(followersRes.body), true); + })); + + it('ffVisibility が private なユーザーのフォロー/フォロワーを自分で見れる', async(async () => { + await request('/i/update', { + ffVisibility: 'private', + }, alice); + + const followingRes = await request('/users/following', { + userId: alice.id, + }, alice); + const followersRes = await request('/users/followers', { + userId: alice.id, + }, alice); + + assert.strictEqual(followingRes.status, 200); + assert.strictEqual(Array.isArray(followingRes.body), true); + assert.strictEqual(followersRes.status, 200); + assert.strictEqual(Array.isArray(followersRes.body), true); + })); + + it('ffVisibility が private なユーザーのフォロー/フォロワーを他人が見れない', async(async () => { + await request('/i/update', { + ffVisibility: 'private', + }, alice); + + const followingRes = await request('/users/following', { + userId: alice.id, + }, bob); + const followersRes = await request('/users/followers', { + userId: alice.id, + }, bob); + + assert.strictEqual(followingRes.status, 400); + assert.strictEqual(followersRes.status, 400); + })); + + describe('AP', () => { + it('ffVisibility が public 以外ならばAPからは取得できない', async(async () => { + { + await request('/i/update', { + ffVisibility: 'public', + }, alice); + + const followingRes = await simpleGet(`/users/${alice.id}/following`, 'application/activity+json'); + const followersRes = await simpleGet(`/users/${alice.id}/followers`, 'application/activity+json'); + assert.strictEqual(followingRes.status, 200); + assert.strictEqual(followersRes.status, 200); + } + { + await request('/i/update', { + ffVisibility: 'followers', + }, alice); + + const followingRes = await simpleGet(`/users/${alice.id}/following`, 'application/activity+json').catch(res => ({ status: res.statusCode })); + const followersRes = await simpleGet(`/users/${alice.id}/followers`, 'application/activity+json').catch(res => ({ status: res.statusCode })); + assert.strictEqual(followingRes.status, 403); + assert.strictEqual(followersRes.status, 403); + } + { + await request('/i/update', { + ffVisibility: 'private', + }, alice); + + const followingRes = await simpleGet(`/users/${alice.id}/following`, 'application/activity+json').catch(res => ({ status: res.statusCode })); + const followersRes = await simpleGet(`/users/${alice.id}/followers`, 'application/activity+json').catch(res => ({ status: res.statusCode })); + assert.strictEqual(followingRes.status, 403); + assert.strictEqual(followersRes.status, 403); + } + })); + }); +}); diff --git a/test/get-file-info.ts b/packages/backend/test/get-file-info.ts similarity index 100% rename from test/get-file-info.ts rename to packages/backend/test/get-file-info.ts diff --git a/test/mfm.ts b/packages/backend/test/mfm.ts similarity index 100% rename from test/mfm.ts rename to packages/backend/test/mfm.ts diff --git a/test/misc/mock-resolver.ts b/packages/backend/test/misc/mock-resolver.ts similarity index 100% rename from test/misc/mock-resolver.ts rename to packages/backend/test/misc/mock-resolver.ts diff --git a/test/mute.ts b/packages/backend/test/mute.ts similarity index 100% rename from test/mute.ts rename to packages/backend/test/mute.ts diff --git a/test/note.ts b/packages/backend/test/note.ts similarity index 100% rename from test/note.ts rename to packages/backend/test/note.ts diff --git a/test/prelude/maybe.ts b/packages/backend/test/prelude/maybe.ts similarity index 100% rename from test/prelude/maybe.ts rename to packages/backend/test/prelude/maybe.ts diff --git a/test/prelude/url.ts b/packages/backend/test/prelude/url.ts similarity index 100% rename from test/prelude/url.ts rename to packages/backend/test/prelude/url.ts diff --git a/test/reaction-lib.ts b/packages/backend/test/reaction-lib.ts similarity index 100% rename from test/reaction-lib.ts rename to packages/backend/test/reaction-lib.ts diff --git a/test/resources/25000x25000.png b/packages/backend/test/resources/25000x25000.png similarity index 100% rename from test/resources/25000x25000.png rename to packages/backend/test/resources/25000x25000.png diff --git a/test/resources/Lenna.jpg b/packages/backend/test/resources/Lenna.jpg similarity index 100% rename from test/resources/Lenna.jpg rename to packages/backend/test/resources/Lenna.jpg diff --git a/test/resources/Lenna.png b/packages/backend/test/resources/Lenna.png similarity index 100% rename from test/resources/Lenna.png rename to packages/backend/test/resources/Lenna.png diff --git a/test/resources/anime.gif b/packages/backend/test/resources/anime.gif similarity index 100% rename from test/resources/anime.gif rename to packages/backend/test/resources/anime.gif diff --git a/test/resources/anime.png b/packages/backend/test/resources/anime.png similarity index 100% rename from test/resources/anime.png rename to packages/backend/test/resources/anime.png diff --git a/test/resources/emptyfile b/packages/backend/test/resources/emptyfile similarity index 100% rename from test/resources/emptyfile rename to packages/backend/test/resources/emptyfile diff --git a/test/resources/image.svg b/packages/backend/test/resources/image.svg similarity index 100% rename from test/resources/image.svg rename to packages/backend/test/resources/image.svg diff --git a/test/resources/with-alpha.png b/packages/backend/test/resources/with-alpha.png similarity index 100% rename from test/resources/with-alpha.png rename to packages/backend/test/resources/with-alpha.png diff --git a/test/resources/with-xml-def.svg b/packages/backend/test/resources/with-xml-def.svg similarity index 100% rename from test/resources/with-xml-def.svg rename to packages/backend/test/resources/with-xml-def.svg diff --git a/test/streaming.ts b/packages/backend/test/streaming.ts similarity index 100% rename from test/streaming.ts rename to packages/backend/test/streaming.ts diff --git a/test/thread-mute.ts b/packages/backend/test/thread-mute.ts similarity index 100% rename from test/thread-mute.ts rename to packages/backend/test/thread-mute.ts diff --git a/test/tsconfig.json b/packages/backend/test/tsconfig.json similarity index 100% rename from test/tsconfig.json rename to packages/backend/test/tsconfig.json diff --git a/test/user-notes.ts b/packages/backend/test/user-notes.ts similarity index 100% rename from test/user-notes.ts rename to packages/backend/test/user-notes.ts diff --git a/packages/backend/test/utils.ts b/packages/backend/test/utils.ts new file mode 100644 index 000000000..b7f6cfbda --- /dev/null +++ b/packages/backend/test/utils.ts @@ -0,0 +1,212 @@ +import * as fs from 'fs'; +import * as WebSocket from 'ws'; +import * as misskey from 'misskey-js'; +import fetch from 'node-fetch'; +const FormData = require('form-data'); +import * as childProcess from 'child_process'; +import * as http from 'http'; +import loadConfig from '../src/config/load'; +import { SIGKILL } from 'constants'; +import { createConnection, getConnection } from 'typeorm'; +import { entities } from '../src/db/postgre'; + +const config = loadConfig(); +export const port = config.port; + +export const async = (fn: Function) => (done: Function) => { + fn().then(() => { + done(); + }, (err: Error) => { + done(err); + }); +}; + +export const request = async (endpoint: string, params: any, me?: any): Promise<{ body: any, status: number }> => { + const auth = me ? { + i: me.token + } : {}; + + const res = await fetch(`http://localhost:${port}/api${endpoint}`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify(Object.assign(auth, params)) + }); + + const status = res.status; + const body = res.status !== 204 ? await res.json().catch() : null; + + return { + body, status + }; +}; + +export const signup = async (params?: any): Promise => { + const q = Object.assign({ + username: 'test', + password: 'test' + }, params); + + const res = await request('/signup', q); + + return res.body; +}; + +export const post = async (user: any, params?: misskey.Endpoints['notes/create']['req']): Promise => { + const q = Object.assign({ + text: 'test' + }, params); + + const res = await request('/notes/create', q, user); + + return res.body ? res.body.createdNote : null; +}; + +export const react = async (user: any, note: any, reaction: string): Promise => { + await request('/notes/reactions/create', { + noteId: note.id, + reaction: reaction + }, user); +}; + +export const uploadFile = (user: any, path?: string): Promise => { + const formData = new FormData(); + formData.append('i', user.token); + formData.append('file', fs.createReadStream(path || __dirname + '/resources/Lenna.png')); + + return fetch(`http://localhost:${port}/api/drive/files/create`, { + method: 'post', + body: formData, + timeout: 30 * 1000, + }).then(res => { + if (!res.ok) { + throw `${res.status} ${res.statusText}`; + } else { + return res.json(); + } + }); +}; + +export function connectStream(user: any, channel: string, listener: (message: Record) => any, params?: any): Promise { + return new Promise((res, rej) => { + const ws = new WebSocket(`ws://localhost:${port}/streaming?i=${user.token}`); + + ws.on('open', () => { + ws.on('message', data => { + const msg = JSON.parse(data.toString()); + if (msg.type == 'channel' && msg.body.id == 'a') { + listener(msg.body); + } else if (msg.type == 'connected' && msg.body.id == 'a') { + res(ws); + } + }); + + ws.send(JSON.stringify({ + type: 'connect', + body: { + channel: channel, + id: 'a', + pong: true, + params: params + } + })); + }); + }); +} + +export const simpleGet = async (path: string, accept = '*/*'): Promise<{ status?: number, type?: string, location?: string }> => { + // node-fetchだと3xxを取れない + return await new Promise((resolve, reject) => { + const req = http.request(`http://localhost:${port}${path}`, { + headers: { + Accept: accept + } + }, res => { + if (res.statusCode! >= 400) { + reject(res); + } else { + resolve({ + status: res.statusCode, + type: res.headers['content-type'], + location: res.headers.location, + }); + } + }); + + req.end(); + }); +}; + +export function launchServer(callbackSpawnedProcess: (p: childProcess.ChildProcess) => void, moreProcess: () => Promise = async () => {}) { + return (done: (err?: Error) => any) => { + const p = childProcess.spawn('node', [__dirname + '/../index.js'], { + stdio: ['inherit', 'inherit', 'inherit', 'ipc'], + env: { NODE_ENV: 'test', PATH: process.env.PATH } + }); + callbackSpawnedProcess(p); + p.on('message', message => { + if (message === 'ok') moreProcess().then(() => done()).catch(e => done(e)); + }); + }; +} + +export async function initTestDb(justBorrow = false, initEntities?: any[]) { + if (process.env.NODE_ENV !== 'test') throw 'NODE_ENV is not a test'; + + try { + const conn = await getConnection(); + await conn.close(); + } catch (e) {} + + return await createConnection({ + type: 'postgres', + host: config.db.host, + port: config.db.port, + username: config.db.user, + password: config.db.pass, + database: config.db.db, + synchronize: true && !justBorrow, + dropSchema: true && !justBorrow, + entities: initEntities || entities + }); +} + +export function startServer(timeout = 30 * 1000): Promise { + return new Promise((res, rej) => { + const t = setTimeout(() => { + p.kill(SIGKILL); + rej('timeout to start'); + }, timeout); + + const p = childProcess.spawn('node', [__dirname + '/../built/index.js'], { + stdio: ['inherit', 'inherit', 'inherit', 'ipc'], + env: { NODE_ENV: 'test', PATH: process.env.PATH } + }); + + p.on('error', e => rej(e)); + + p.on('message', message => { + if (message === 'ok') { + clearTimeout(t); + res(p); + } + }); + }); +} + +export function shutdownServer(p: childProcess.ChildProcess, timeout = 20 * 1000) { + return new Promise((res, rej) => { + const t = setTimeout(() => { + p.kill(SIGKILL); + res('force exit'); + }, timeout); + + p.once('exit', () => { + clearTimeout(t); + res('exited'); + }); + + p.kill(); + }); +} diff --git a/packages/backend/tools/accept-migration.js b/packages/backend/tools/accept-migration.js new file mode 100644 index 000000000..309a4ab5e --- /dev/null +++ b/packages/backend/tools/accept-migration.js @@ -0,0 +1,26 @@ +"use strict"; +// ex) node built/tools/accept-migration Yo 1000000000001 +Object.defineProperty(exports, "__esModule", { value: true }); +const typeorm_1 = require("typeorm"); +const index_1 = require("@/config/index"); +(0, typeorm_1.createConnection)({ + type: 'postgres', + host: index_1.default.db.host, + port: index_1.default.db.port, + username: index_1.default.db.user, + password: index_1.default.db.pass, + database: index_1.default.db.db, + extra: index_1.default.db.extra, + synchronize: false, + dropSchema: false, +}).then(c => { + c.query(`INSERT INTO migrations(timestamp,name) VALUES (${process.argv[3]}, '${process.argv[2]}${process.argv[3]}');`).then(() => { + console.log('done'); + process.exit(0); + }).catch(e => { + console.log('ERROR:'); + console.log(e); + process.exit(1); + }); +}); +//# sourceMappingURL=accept-migration.js.map \ No newline at end of file diff --git a/packages/backend/tools/accept-migration.js.map b/packages/backend/tools/accept-migration.js.map new file mode 100644 index 000000000..c158a4966 --- /dev/null +++ b/packages/backend/tools/accept-migration.js.map @@ -0,0 +1 @@ +{"version":3,"file":"accept-migration.js","sourceRoot":"","sources":["accept-migration.ts"],"names":[],"mappings":";AAAA,yDAAyD;;AAEzD,qCAA2C;AAC3C,0CAAoC;AAEpC,IAAA,0BAAgB,EAAC;IAChB,IAAI,EAAE,UAAU;IAChB,IAAI,EAAE,eAAM,CAAC,EAAE,CAAC,IAAI;IACpB,IAAI,EAAE,eAAM,CAAC,EAAE,CAAC,IAAI;IACpB,QAAQ,EAAE,eAAM,CAAC,EAAE,CAAC,IAAI;IACxB,QAAQ,EAAE,eAAM,CAAC,EAAE,CAAC,IAAI;IACxB,QAAQ,EAAE,eAAM,CAAC,EAAE,CAAC,EAAE;IACtB,KAAK,EAAE,eAAM,CAAC,EAAE,CAAC,KAAK;IACtB,WAAW,EAAE,KAAK;IAClB,UAAU,EAAE,KAAK;CACjB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;IACX,CAAC,CAAC,KAAK,CAAC,kDAAkD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE;QAChI,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;QACZ,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC"} \ No newline at end of file diff --git a/src/tools/accept-migration.ts b/packages/backend/tools/accept-migration.ts similarity index 100% rename from src/tools/accept-migration.ts rename to packages/backend/tools/accept-migration.ts diff --git a/packages/backend/tools/add-emoji.js b/packages/backend/tools/add-emoji.js new file mode 100644 index 000000000..df02f554a --- /dev/null +++ b/packages/backend/tools/add-emoji.js @@ -0,0 +1,30 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const index_1 = require("@/models/index"); +const gen_id_1 = require("@/misc/gen-id"); +async function main(name, url, alias) { + const aliases = alias != null ? [alias] : []; + await index_1.Emojis.save({ + id: (0, gen_id_1.genId)(), + host: null, + name, + url, + aliases, + updatedAt: new Date() + }); +} +const args = process.argv.slice(2); +const name = args[0]; +const url = args[1]; +if (!name) + throw new Error('require name'); +if (!url) + throw new Error('require url'); +main(name, url).then(() => { + console.log('success'); + process.exit(0); +}).catch(e => { + console.warn(e); + process.exit(1); +}); +//# sourceMappingURL=add-emoji.js.map \ No newline at end of file diff --git a/packages/backend/tools/add-emoji.js.map b/packages/backend/tools/add-emoji.js.map new file mode 100644 index 000000000..03bf31b98 --- /dev/null +++ b/packages/backend/tools/add-emoji.js.map @@ -0,0 +1 @@ +{"version":3,"file":"add-emoji.js","sourceRoot":"","sources":["add-emoji.ts"],"names":[],"mappings":";;AAAA,0CAAwC;AACxC,0CAAsC;AAEtC,KAAK,UAAU,IAAI,CAAC,IAAY,EAAE,GAAW,EAAE,KAAc;IAC5D,MAAM,OAAO,GAAG,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,CAAE,KAAK,CAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAE/C,MAAM,cAAM,CAAC,IAAI,CAAC;QACjB,EAAE,EAAE,IAAA,cAAK,GAAE;QACX,IAAI,EAAE,IAAI;QACV,IAAI;QACJ,GAAG;QACH,OAAO;QACP,SAAS,EAAE,IAAI,IAAI,EAAE;KACrB,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACnC,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;AACrB,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;AAEpB,IAAI,CAAC,IAAI;IAAE,MAAM,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC;AAC3C,IAAI,CAAC,GAAG;IAAE,MAAM,IAAI,KAAK,CAAC,aAAa,CAAC,CAAC;AAEzC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE;IACzB,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACvB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;IACZ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAChB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC,CAAC,CAAC"} \ No newline at end of file diff --git a/src/tools/add-emoji.ts b/packages/backend/tools/add-emoji.ts similarity index 100% rename from src/tools/add-emoji.ts rename to packages/backend/tools/add-emoji.ts diff --git a/packages/backend/tools/demote-admin.js b/packages/backend/tools/demote-admin.js new file mode 100644 index 000000000..d6a296883 --- /dev/null +++ b/packages/backend/tools/demote-admin.js @@ -0,0 +1,30 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const postgre_1 = require("../db/postgre"); +const typeorm_1 = require("typeorm"); +const user_1 = require("@/models/entities/user"); +async function main(username) { + if (!username) + throw `username required`; + username = username.replace(/^@/, ''); + await (0, postgre_1.initDb)(); + const Users = (0, typeorm_1.getRepository)(user_1.User); + const res = await Users.update({ + usernameLower: username.toLowerCase(), + host: null + }, { + isAdmin: false + }); + if (res.affected !== 1) { + throw 'Failed'; + } +} +const args = process.argv.slice(2); +main(args[0]).then(() => { + console.log('Success'); + process.exit(0); +}).catch(e => { + console.error(`Error: ${e.message || e}`); + process.exit(1); +}); +//# sourceMappingURL=demote-admin.js.map \ No newline at end of file diff --git a/packages/backend/tools/demote-admin.js.map b/packages/backend/tools/demote-admin.js.map new file mode 100644 index 000000000..4403e2bab --- /dev/null +++ b/packages/backend/tools/demote-admin.js.map @@ -0,0 +1 @@ +{"version":3,"file":"demote-admin.js","sourceRoot":"","sources":["demote-admin.ts"],"names":[],"mappings":";;AAAA,2CAAuC;AACvC,qCAAwC;AACxC,iDAA8C;AAE9C,KAAK,UAAU,IAAI,CAAC,QAAgB;IACnC,IAAI,CAAC,QAAQ;QAAE,MAAM,mBAAmB,CAAC;IACzC,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAEtC,MAAM,IAAA,gBAAM,GAAE,CAAC;IACf,MAAM,KAAK,GAAG,IAAA,uBAAa,EAAC,WAAI,CAAC,CAAC;IAElC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC;QAC9B,aAAa,EAAE,QAAQ,CAAC,WAAW,EAAE;QACrC,IAAI,EAAE,IAAI;KACV,EAAE;QACF,OAAO,EAAE,KAAK;KACd,CAAC,CAAC;IAEH,IAAI,GAAG,CAAC,QAAQ,KAAK,CAAC,EAAE;QACvB,MAAM,QAAQ,CAAC;KACf;AACF,CAAC;AAED,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAEnC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE;IACvB,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACvB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;IACZ,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,OAAO,IAAI,CAAC,EAAE,CAAC,CAAC;IAC1C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC,CAAC,CAAC"} \ No newline at end of file diff --git a/src/tools/demote-admin.ts b/packages/backend/tools/demote-admin.ts similarity index 100% rename from src/tools/demote-admin.ts rename to packages/backend/tools/demote-admin.ts diff --git a/packages/backend/tools/mark-admin.js b/packages/backend/tools/mark-admin.js new file mode 100644 index 000000000..4563d9c33 --- /dev/null +++ b/packages/backend/tools/mark-admin.js @@ -0,0 +1,30 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const postgre_1 = require("../db/postgre"); +const typeorm_1 = require("typeorm"); +const user_1 = require("@/models/entities/user"); +async function main(username) { + if (!username) + throw `username required`; + username = username.replace(/^@/, ''); + await (0, postgre_1.initDb)(); + const Users = (0, typeorm_1.getRepository)(user_1.User); + const res = await Users.update({ + usernameLower: username.toLowerCase(), + host: null + }, { + isAdmin: true + }); + if (res.affected !== 1) { + throw 'Failed'; + } +} +const args = process.argv.slice(2); +main(args[0]).then(() => { + console.log('Success'); + process.exit(0); +}).catch(e => { + console.error(`Error: ${e.message || e}`); + process.exit(1); +}); +//# sourceMappingURL=mark-admin.js.map \ No newline at end of file diff --git a/packages/backend/tools/mark-admin.js.map b/packages/backend/tools/mark-admin.js.map new file mode 100644 index 000000000..5633e2f89 --- /dev/null +++ b/packages/backend/tools/mark-admin.js.map @@ -0,0 +1 @@ +{"version":3,"file":"mark-admin.js","sourceRoot":"","sources":["mark-admin.ts"],"names":[],"mappings":";;AAAA,2CAAuC;AACvC,qCAAwC;AACxC,iDAA8C;AAE9C,KAAK,UAAU,IAAI,CAAC,QAAgB;IACnC,IAAI,CAAC,QAAQ;QAAE,MAAM,mBAAmB,CAAC;IACzC,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAEtC,MAAM,IAAA,gBAAM,GAAE,CAAC;IACf,MAAM,KAAK,GAAG,IAAA,uBAAa,EAAC,WAAI,CAAC,CAAC;IAElC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC;QAC9B,aAAa,EAAE,QAAQ,CAAC,WAAW,EAAE;QACrC,IAAI,EAAE,IAAI;KACV,EAAE;QACF,OAAO,EAAE,IAAI;KACb,CAAC,CAAC;IAEH,IAAI,GAAG,CAAC,QAAQ,KAAK,CAAC,EAAE;QACvB,MAAM,QAAQ,CAAC;KACf;AACF,CAAC;AAED,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAEnC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE;IACvB,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACvB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;IACZ,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,OAAO,IAAI,CAAC,EAAE,CAAC,CAAC;IAC1C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC,CAAC,CAAC"} \ No newline at end of file diff --git a/src/tools/mark-admin.ts b/packages/backend/tools/mark-admin.ts similarity index 100% rename from src/tools/mark-admin.ts rename to packages/backend/tools/mark-admin.ts diff --git a/packages/backend/tools/refresh-question.js b/packages/backend/tools/refresh-question.js new file mode 100644 index 000000000..0536c3820 --- /dev/null +++ b/packages/backend/tools/refresh-question.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const question_1 = require("@/remote/activitypub/models/question"); +async function main(uri) { + return await (0, question_1.updateQuestion)(uri); +} +const args = process.argv.slice(2); +const uri = args[0]; +main(uri).then(result => { + console.log(`Done: ${result}`); +}).catch(e => { + console.warn(e); +}); +//# sourceMappingURL=refresh-question.js.map \ No newline at end of file diff --git a/packages/backend/tools/refresh-question.js.map b/packages/backend/tools/refresh-question.js.map new file mode 100644 index 000000000..3db6d0b8b --- /dev/null +++ b/packages/backend/tools/refresh-question.js.map @@ -0,0 +1 @@ +{"version":3,"file":"refresh-question.js","sourceRoot":"","sources":["refresh-question.ts"],"names":[],"mappings":";;AAAA,mEAAsE;AAEtE,KAAK,UAAU,IAAI,CAAC,GAAW;IAC9B,OAAO,MAAM,IAAA,yBAAc,EAAC,GAAG,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACnC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;AAEpB,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;IACvB,OAAO,CAAC,GAAG,CAAC,SAAS,MAAM,EAAE,CAAC,CAAC;AAChC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;IACZ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC,CAAC,CAAC"} \ No newline at end of file diff --git a/src/tools/refresh-question.ts b/packages/backend/tools/refresh-question.ts similarity index 100% rename from src/tools/refresh-question.ts rename to packages/backend/tools/refresh-question.ts diff --git a/packages/backend/tools/resync-remote-user.js b/packages/backend/tools/resync-remote-user.js new file mode 100644 index 000000000..05d76ecc9 --- /dev/null +++ b/packages/backend/tools/resync-remote-user.js @@ -0,0 +1,26 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const postgre_1 = require("@/db/postgre"); +const Acct = require("misskey-js/built/acct"); +async function main(acct) { + await (0, postgre_1.initDb)(); + const { resolveUser } = await Promise.resolve().then(() => require('@/remote/resolve-user')); + const { username, host } = Acct.parse(acct); + await resolveUser(username, host, {}, true); +} +// get args +const args = process.argv.slice(2); +let acct = args[0]; +// normalize args +acct = acct.replace(/^@/, ''); +// check args +if (!acct.match(/^\w+@\w/)) { + throw `Invalid acct format. Valid format are user@host`; +} +console.log(`resync ${acct}`); +main(acct).then(() => { + console.log('Done'); +}).catch(e => { + console.warn(e); +}); +//# sourceMappingURL=resync-remote-user.js.map \ No newline at end of file diff --git a/packages/backend/tools/resync-remote-user.js.map b/packages/backend/tools/resync-remote-user.js.map new file mode 100644 index 000000000..456d7da1d --- /dev/null +++ b/packages/backend/tools/resync-remote-user.js.map @@ -0,0 +1 @@ +{"version":3,"file":"resync-remote-user.js","sourceRoot":"","sources":["resync-remote-user.ts"],"names":[],"mappings":";;AAAA,0CAAsC;AACtC,8CAA8C;AAE9C,KAAK,UAAU,IAAI,CAAC,IAAY;IAC/B,MAAM,IAAA,gBAAM,GAAE,CAAC;IACf,MAAM,EAAE,WAAW,EAAE,GAAG,2CAAa,uBAAuB,EAAC,CAAC;IAE9D,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5C,MAAM,WAAW,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC;AAC7C,CAAC;AAED,WAAW;AACX,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACnC,IAAI,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;AAEnB,iBAAiB;AACjB,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;AAE9B,aAAa;AACb,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE;IAC3B,MAAM,iDAAiD,CAAC;CACxD;AAED,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC;AAE9B,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE;IACpB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AACrB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;IACZ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC,CAAC,CAAC"} \ No newline at end of file diff --git a/packages/backend/tools/resync-remote-user.ts b/packages/backend/tools/resync-remote-user.ts new file mode 100644 index 000000000..22d2f7c89 --- /dev/null +++ b/packages/backend/tools/resync-remote-user.ts @@ -0,0 +1,30 @@ +import { initDb } from '@/db/postgre'; +import * as Acct from 'misskey-js/built/acct'; + +async function main(acct: string): Promise { + await initDb(); + const { resolveUser } = await import('@/remote/resolve-user'); + + const { username, host } = Acct.parse(acct); + await resolveUser(username, host, {}, true); +} + +// get args +const args = process.argv.slice(2); +let acct = args[0]; + +// normalize args +acct = acct.replace(/^@/, ''); + +// check args +if (!acct.match(/^\w+@\w/)) { + throw `Invalid acct format. Valid format are user@host`; +} + +console.log(`resync ${acct}`); + +main(acct).then(() => { + console.log('Done'); +}).catch(e => { + console.warn(e); +}); diff --git a/packages/backend/tools/show-signin-history.js b/packages/backend/tools/show-signin-history.js new file mode 100644 index 000000000..daeea8461 --- /dev/null +++ b/packages/backend/tools/show-signin-history.js @@ -0,0 +1,47 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const index_1 = require("@/models/index"); +// node built/tools/show-signin-history username +// => {Success} {Date} {IPAddrsss} +// node built/tools/show-signin-history username user-agent,x-forwarded-for +// with user-agent and x-forwarded-for +// node built/tools/show-signin-history username all +// with full request headers +async function main(username, headers) { + const user = await index_1.Users.findOne({ + host: null, + usernameLower: username.toLowerCase(), + }); + if (user == null) + throw new Error('User not found'); + const history = await index_1.Signins.find({ + userId: user.id + }); + for (const signin of history) { + console.log(`${signin.success ? 'OK' : 'NG'} ${signin.createdAt ? signin.createdAt.toISOString() : 'Unknown'} ${signin.ip}`); + // headers + if (headers != null) { + for (const key of Object.keys(signin.headers)) { + if (headers.includes('all') || headers.includes(key)) { + console.log(` ${key}: ${signin.headers[key]}`); + } + } + } + } +} +// get args +const args = process.argv.slice(2); +let username = args[0]; +let headers; +if (args[1] != null) { + headers = args[1].split(/,/).map(header => header.toLowerCase()); +} +// normalize args +username = username.replace(/^@/, ''); +main(username, headers).then(() => { + process.exit(0); +}).catch(e => { + console.warn(e); + process.exit(1); +}); +//# sourceMappingURL=show-signin-history.js.map \ No newline at end of file diff --git a/packages/backend/tools/show-signin-history.js.map b/packages/backend/tools/show-signin-history.js.map new file mode 100644 index 000000000..b421825bc --- /dev/null +++ b/packages/backend/tools/show-signin-history.js.map @@ -0,0 +1 @@ +{"version":3,"file":"show-signin-history.js","sourceRoot":"","sources":["show-signin-history.ts"],"names":[],"mappings":";;AAAA,0CAAgD;AAEhD,gDAAgD;AAChD,mCAAmC;AAEnC,2EAA2E;AAC3E,uCAAuC;AAEvC,oDAAoD;AACpD,6BAA6B;AAE7B,KAAK,UAAU,IAAI,CAAC,QAAgB,EAAE,OAAkB;IACvD,MAAM,IAAI,GAAG,MAAM,aAAK,CAAC,OAAO,CAAC;QAChC,IAAI,EAAE,IAAI;QACV,aAAa,EAAE,QAAQ,CAAC,WAAW,EAAE;KACrC,CAAC,CAAC;IAEH,IAAI,IAAI,IAAI,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;IAEpD,MAAM,OAAO,GAAG,MAAM,eAAO,CAAC,IAAI,CAAC;QAClC,MAAM,EAAE,IAAI,CAAC,EAAE;KACf,CAAC,CAAC;IAEH,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE;QAC7B,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,SAAS,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC;QAE7H,UAAU;QACV,IAAI,OAAO,IAAI,IAAI,EAAE;YACpB,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE;gBAC9C,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;oBACrD,OAAO,CAAC,GAAG,CAAC,MAAM,GAAG,KAAK,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;iBACjD;aACD;SACD;KACD;AACF,CAAC;AAED,WAAW;AACX,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAEnC,IAAI,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;AACvB,IAAI,OAA6B,CAAC;AAElC,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE;IACpB,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;CACjE;AAED,iBAAiB;AACjB,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;AAEtC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE;IACjC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;IACZ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAChB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC,CAAC,CAAC"} \ No newline at end of file diff --git a/src/tools/show-signin-history.ts b/packages/backend/tools/show-signin-history.ts similarity index 100% rename from src/tools/show-signin-history.ts rename to packages/backend/tools/show-signin-history.ts diff --git a/packages/backend/tsconfig.json b/packages/backend/tsconfig.json new file mode 100644 index 000000000..3311e117d --- /dev/null +++ b/packages/backend/tsconfig.json @@ -0,0 +1,43 @@ +{ + "compilerOptions": { + "allowJs": true, + "noEmitOnError": false, + "noImplicitAny": true, + "noImplicitReturns": true, + "noUnusedParameters": false, + "noUnusedLocals": false, + "noFallthroughCasesInSwitch": true, + "declaration": false, + "sourceMap": false, + "target": "es2017", + "module": "commonjs", + "moduleResolution": "node", + "allowSyntheticDefaultImports": true, + "removeComments": false, + "noLib": false, + "strict": true, + "strictNullChecks": true, + "strictPropertyInitialization": false, + "experimentalDecorators": true, + "emitDecoratorMetadata": true, + "resolveJsonModule": true, + "isolatedModules": true, + "rootDir": "./src", + "baseUrl": "./", + "paths": { + "@/*": ["./src/*"] + }, + "outDir": "./built", + "typeRoots": [ + "./node_modules/@types", + "./@types" + ], + "lib": [ + "esnext" + ] + }, + "compileOnSave": false, + "include": [ + "./src/**/*.ts" + ], +} diff --git a/packages/backend/yarn.lock b/packages/backend/yarn.lock new file mode 100644 index 000000000..aa8794f7b --- /dev/null +++ b/packages/backend/yarn.lock @@ -0,0 +1,8632 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/helper-validator-identifier@^7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed" + integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw== + +"@babel/parser@^7.6.0", "@babel/parser@^7.9.6": + version "7.13.9" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.13.9.tgz#ca34cb95e1c2dd126863a84465ae8ef66114be99" + integrity sha512-nEUfRiARCcaVo3ny3ZQjURjHQZUo/JkEw7rLlSZy/psWGnvwXFtPcr6jb7Yb41DVW5LTe6KRq9LGleRNsg1Frw== + +"@babel/runtime@^7.16.0": + version "7.16.3" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.3.tgz#b86f0db02a04187a3c17caa77de69840165d42d5" + integrity sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ== + dependencies: + regenerator-runtime "^0.13.4" + +"@babel/runtime@^7.6.2": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.13.tgz#0a21452352b02542db0ffb928ac2d3ca7cb6d66d" + integrity sha512-8+3UMPBrjFa/6TtKi/7sehPKqfAm4g6K+YQjyyFOLUTxzOngcRZTlAVY8sc2CORJYqdHQY8gRPHmn+qo15rCBw== + dependencies: + regenerator-runtime "^0.13.4" + +"@babel/types@^7.6.1", "@babel/types@^7.9.6": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.13.0.tgz#74424d2816f0171b4100f0ab34e9a374efdf7f80" + integrity sha512-hE+HE8rnG1Z6Wzo+MhaKE5lM5eMx71T4EHJgku2E3xIfaULhDcxiiRxUYgwX8qwP1BBSlag+TdGOt6JAidIZTA== + dependencies: + "@babel/helper-validator-identifier" "^7.12.11" + lodash "^4.17.19" + to-fast-properties "^2.0.0" + +"@cspotcode/source-map-consumer@0.8.0": + version "0.8.0" + resolved "https://registry.yarnpkg.com/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz#33bf4b7b39c178821606f669bbc447a6a629786b" + integrity sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg== + +"@cspotcode/source-map-support@0.7.0": + version "0.7.0" + resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz#4789840aa859e46d2f3173727ab707c66bf344f5" + integrity sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA== + dependencies: + "@cspotcode/source-map-consumer" "0.8.0" + +"@cto.af/textdecoder@^0.0.0": + version "0.0.0" + resolved "https://registry.yarnpkg.com/@cto.af/textdecoder/-/textdecoder-0.0.0.tgz#e1e8d84c936c30a0f4619971f19ca41941af9fdc" + integrity sha512-sJpx3F5xcVV/9jNYJQtvimo4Vfld/nD3ph+ZWtQzZ03Zo8rJC7QKQTRcIGS13Rcz80DwFNthCWMrd58vpY4ZAQ== + +"@digitalbazaar/http-client@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@digitalbazaar/http-client/-/http-client-1.1.0.tgz#cac383b24ace04b18b919deab773462b03d3d7b0" + integrity sha512-ks7hqa6hm9NyULdbm9qL6TRS8rADzBw8R0lETvUgvdNXu9H62XG2YqoKRDThtfgWzWxLwRJ3Z2o4ev81dZZbyQ== + dependencies: + esm "^3.2.22" + ky "^0.25.1" + ky-universal "^0.8.2" + +"@discordapp/twemoji@13.1.0": + version "13.1.0" + resolved "https://registry.yarnpkg.com/@discordapp/twemoji/-/twemoji-13.1.0.tgz#6b25f3958fa8fd68692248c87776bc737fd009a9" + integrity sha512-KEw/te+ylD2MHutzigafyptv0kdTU05Dbgxr9Y5J9IAQw8PbFz16nKtlPnJtA23BLp9fZQeNXzUmegkRi7fpDA== + dependencies: + fs-extra "^8.0.1" + jsonfile "^5.0.0" + twemoji-parser "13.1.0" + universalify "^0.1.2" + +"@elastic/elasticsearch@7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@elastic/elasticsearch/-/elasticsearch-7.11.0.tgz#e196243d0ed026742fc160d72cc5b4b5b6c7807d" + integrity sha512-AFVVuANIdbV1qYjuOi4hnsX/DehWYG+bbhQO4amq9K4/NnzU7mpGWOPgVlRQTiX+vBfBkx7SL6h4QEjIlM3ztA== + dependencies: + debug "^4.1.1" + hpagent "^0.1.1" + ms "^2.1.1" + pump "^3.0.0" + secure-json-parse "^2.1.0" + +"@eslint/eslintrc@^1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.0.4.tgz#dfe0ff7ba270848d10c5add0715e04964c034b31" + integrity sha512-h8Vx6MdxwWI2WM8/zREHMoqdgLNXEL4QX3MWSVMdyNJGvXVOs+6lp+m2hc3FnuMHDc4poxFNI20vCk0OmI4G0Q== + dependencies: + ajv "^6.12.4" + debug "^4.3.2" + espree "^9.0.0" + globals "^13.9.0" + ignore "^4.0.6" + import-fresh "^3.2.1" + js-yaml "^4.1.0" + minimatch "^3.0.4" + strip-json-comments "^3.1.1" + +"@humanwhocodes/config-array@^0.6.0": + version "0.6.0" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.6.0.tgz#b5621fdb3b32309d2d16575456cbc277fa8f021a" + integrity sha512-JQlEKbcgEUjBFhLIF4iqM7u/9lwgHRBcpHrmUNCALK0Q3amXN6lxdoXLnF0sm11E9VqTmBALR87IlUg1bZ8A9A== + dependencies: + "@humanwhocodes/object-schema" "^1.2.0" + debug "^4.1.1" + minimatch "^3.0.4" + +"@humanwhocodes/object-schema@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz#87de7af9c231826fdd68ac7258f77c429e0e5fcf" + integrity sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w== + +"@jfonx/console-utils@^1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@jfonx/console-utils/-/console-utils-1.0.3.tgz#cbb7f911e4191a4a2fe1ba4807d29f100b5d099f" + integrity sha512-/XbnqjWc7yNZVLAJJO9rimfIz9DYte+cj3EF9hwhIv7vw6ok2t3cjl0huYsmD89srKH03vWjeqAcIH86CuYj3g== + dependencies: + colors "^1.3.3" + +"@jfonx/file-utils@^3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@jfonx/file-utils/-/file-utils-3.0.1.tgz#8d3d6e931a283420fe29802ea71c28dd397cd8d3" + integrity sha512-qwH0CuzWmghtTHGMyuPHj6SJPQgWeiXFJBfrxCWMbzxVCa3aLZPEfzSdlSnC/UABsk6feRkNdHXw59rVshNPqw== + dependencies: + "@jfonx/console-utils" "^1.0.3" + comment-json "^4.1.0" + find-up "^4.1.0" + +"@koa/cors@3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@koa/cors/-/cors-3.1.0.tgz#618bb073438cfdbd3ebd0e648a76e33b84f3a3b2" + integrity sha512-7ulRC1da/rBa6kj6P4g2aJfnET3z8Uf3SWu60cjbtxTA5g8lxRdX/Bd2P92EagGwwAhANeNw8T8if99rJliR6Q== + dependencies: + vary "^1.1.2" + +"@koa/multer@3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@koa/multer/-/multer-3.0.0.tgz#439777949f28097d7b329c0b4ce3048074c862f8" + integrity sha512-y+OQBmex5D1jIl723gAEUYcAWPEicIXppaAKw/zCMfpllQ08ZNweDPwoCLxEoatqd5pCu2XG6V8dl67JRq3RJw== + +"@koa/router@9.0.1": + version "9.0.1" + resolved "https://registry.yarnpkg.com/@koa/router/-/router-9.0.1.tgz#4090a14223ea7e78aa13b632761209cba69acd95" + integrity sha512-OI+OU49CJV4px0WkIMmayBeqVXB/JS1ZMq7UoGlTZt6Y7ijK7kdeQ18+SEHHJPytmtI1y6Hf8XLrpxva3mhv5Q== + dependencies: + debug "^4.1.1" + http-errors "^1.7.3" + koa-compose "^4.1.0" + methods "^1.1.2" + path-to-regexp "^6.1.0" + +"@nodelib/fs.scandir@2.1.3": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz#3a582bdb53804c6ba6d146579c46e52130cf4a3b" + integrity sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw== + dependencies: + "@nodelib/fs.stat" "2.0.3" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.3", "@nodelib/fs.stat@^2.0.2": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz#34dc5f4cabbc720f4e60f75a747e7ecd6c175bd3" + integrity sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz#011b9202a70a6366e436ca5c065844528ab04976" + integrity sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ== + dependencies: + "@nodelib/fs.scandir" "2.1.3" + fastq "^1.6.0" + +"@npmcli/move-file@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-1.1.2.tgz#1a82c3e372f7cae9253eb66d72543d6b8685c674" + integrity sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg== + dependencies: + mkdirp "^1.0.4" + rimraf "^3.0.2" + +"@redocly/ajv@^8.6.2": + version "8.6.2" + resolved "https://registry.yarnpkg.com/@redocly/ajv/-/ajv-8.6.2.tgz#8c4e485e72f7864f91fae40093bed548ec2619b2" + integrity sha512-tU8fQs0D76ZKhJ2cWtnfQthWqiZgGBx0gH0+5D8JvaBEBaqA8foPPBt3Nonwr3ygyv5xrw2IzKWgIY86BlGs+w== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + +"@redocly/openapi-core@1.0.0-beta.54": + version "1.0.0-beta.54" + resolved "https://registry.yarnpkg.com/@redocly/openapi-core/-/openapi-core-1.0.0-beta.54.tgz#42575a849c4dd54b9d0c6413fb8ca547e087cd11" + integrity sha512-uYs0N1Trjkh7u8IMIuCU2VxCXhMyGWSZUkP/WNdTR1OgBUtvNdF9C32zoQV+hyCIH4gVu42ROHkjisy333ZX+w== + dependencies: + "@redocly/ajv" "^8.6.2" + "@types/node" "^14.11.8" + colorette "^1.2.0" + js-levenshtein "^1.1.6" + js-yaml "^3.14.1" + lodash.isequal "^4.5.0" + minimatch "^3.0.4" + node-fetch "^2.6.1" + yaml-ast-parser "0.0.43" + +"@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== + +"@sinonjs/commons@^1.7.0": + version "1.7.2" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.7.2.tgz#505f55c74e0272b43f6c52d81946bed7058fc0e2" + integrity sha512-+DUO6pnp3udV/v2VfUWgaY5BIE1IfT7lLfeDzPVeMT1XKkaAp9LgSI9x5RtrFQoZ9Oi0PgXQQHPaoKu7dCjVxw== + 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== + dependencies: + "@sinonjs/commons" "^1.7.0" + +"@sqltools/formatter@^1.2.2": + version "1.2.3" + resolved "https://registry.yarnpkg.com/@sqltools/formatter/-/formatter-1.2.3.tgz#1185726610acc37317ddab11c3c7f9066966bd20" + integrity sha512-O3uyB/JbkAEMZaP3YqyHH7TMnex7tWyCbCI4EfJdOCoN6HIhqdJBWTM6aCCiWQ/5f5wxjgU735QAIpJbjDvmzg== + +"@syuilo/aiscript@0.11.1": + version "0.11.1" + resolved "https://registry.yarnpkg.com/@syuilo/aiscript/-/aiscript-0.11.1.tgz#52c14692113c58d1d62e6ae696352ba49abdf2eb" + integrity sha512-chwOIA3yLUKvOB0G611hjLArKTeOWNmTm3lHERSaDW1d+dS6do56naX6Lkwy2UpnwWC0qzeNSgg35elk6t2gZg== + dependencies: + autobind-decorator "2.4.0" + chalk "4.0.0" + seedrandom "3.0.5" + stringz "2.1.0" + uuid "7.0.3" + +"@szmarczak/http-timer@^4.0.5": + version "4.0.5" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.5.tgz#bfbd50211e9dfa51ba07da58a14cdfd333205152" + integrity sha512-PyRA9sm1Yayuj5OIoJ1hGt2YISX45w9WcFbh6ddT0Z/0yaFxOtGLInr4jUfU1EAFVs0Yfyfev4RNwBlUaHdlDQ== + dependencies: + defer-to-connect "^2.0.0" + +"@tokenizer/token@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@tokenizer/token/-/token-0.3.0.tgz#fe98a93fe789247e998c75e74e9c7c63217aa276" + integrity sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A== + +"@tootallnate/once@1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" + integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== + +"@trysound/sax@0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad" + integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA== + +"@tsconfig/node10@^1.0.7": + version "1.0.7" + resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.7.tgz#1eb1de36c73478a2479cc661ef5af1c16d86d606" + integrity sha512-aBvUmXLQbayM4w3A8TrjwrXs4DZ8iduJnuJLLRGdkWlyakCf1q6uHZJBzXoRA/huAEknG5tcUyQxN3A+In5euQ== + +"@tsconfig/node12@^1.0.7": + version "1.0.7" + resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.7.tgz#677bd9117e8164dc319987dd6ff5fc1ba6fbf18b" + integrity sha512-dgasobK/Y0wVMswcipr3k0HpevxFJLijN03A8mYfEPvWvOs14v0ZlYTR4kIgMx8g4+fTyTFv8/jLCIfRqLDJ4A== + +"@tsconfig/node14@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.0.tgz#5bd046e508b1ee90bc091766758838741fdefd6e" + integrity sha512-RKkL8eTdPv6t5EHgFKIVQgsDapugbuOptNd9OOunN/HAkzmmTnZELx1kNCK0rSdUYGmiFMM3rRQMAWiyp023LQ== + +"@tsconfig/node16@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.2.tgz#423c77877d0569db20e1fc80885ac4118314010e" + integrity sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA== + +"@types/accepts@*": + version "1.3.5" + resolved "https://registry.yarnpkg.com/@types/accepts/-/accepts-1.3.5.tgz#c34bec115cfc746e04fe5a059df4ce7e7b391575" + integrity sha512-jOdnI/3qTpHABjM5cx1Hc0sKsPoYCp+DP/GJRGtDlPd7fiV9oXGGIcjW/ZOxLIvjGz8MA+uMZI9metHlgqbgwQ== + 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" + integrity sha512-LiMQ6EOPob/4yUL66SZzu6Yh77cbzJFYll+ZfaPiPPFswtIlA/Fs1MzdKYA7JApHU49zQTbJGX3PDmCpIdDBRQ== + +"@types/body-parser@*": + version "1.19.0" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.0.tgz#0685b3c47eb3006ffed117cdd55164b61f80538f" + integrity sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ== + dependencies: + "@types/connect" "*" + "@types/node" "*" + +"@types/bull@3.15.5": + version "3.15.5" + resolved "https://registry.yarnpkg.com/@types/bull/-/bull-3.15.5.tgz#a4459c127c5b10fb847531579a2cd5db35751366" + integrity sha512-XgJQWJ03jyKMfdoL8IAIoHIo7JkkL74kcxuujTONkSJswm0giIJ9kuVgDNHS0OvD+OiPNcFmbBl0H3scj2+A8A== + dependencies: + "@types/ioredis" "*" + +"@types/cacheable-request@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.1.tgz#5d22f3dded1fd3a84c0bbeb5039a7419c2c91976" + integrity sha512-ykFq2zmBGOCbpIXtoVbz4SKY5QriWPh3AjyU4G74RYbtt5yOc5OfaY75ftjg7mikMOla1CTGpX3lLbuJh8DTrQ== + dependencies: + "@types/http-cache-semantics" "*" + "@types/keyv" "*" + "@types/node" "*" + "@types/responselike" "*" + +"@types/cbor@6.0.0": + version "6.0.0" + resolved "https://registry.yarnpkg.com/@types/cbor/-/cbor-6.0.0.tgz#ddead015e14ef4463287d40cd92a6297a34dac8d" + integrity sha512-mGQ1lbYOwVti5Xlarn1bTeBZqgY0kstsdjnkoEovgohYKdBjGejHyNGXHdMBeqyQazIv32Jjp33+5pBEaSRy2w== + dependencies: + cbor "*" + +"@types/cheerio@0.22.18": + version "0.22.18" + resolved "https://registry.yarnpkg.com/@types/cheerio/-/cheerio-0.22.18.tgz#19018dceae691509901e339d63edf1e935978fe6" + integrity sha512-Fq7R3fINAPSdUEhOyjG4iVxgHrOnqDJbY0/BUuiN0pvD/rfmZWekVZnv+vcs8TtpA2XF50uv50LaE4EnpEL/Hw== + dependencies: + "@types/node" "*" + +"@types/color-name@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" + integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== + +"@types/connect@*": + version "3.4.33" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.33.tgz#31610c901eca573b8713c3330abc6e6b9f588546" + integrity sha512-2+FrkXY4zllzTNfJth7jOqEHC+enpLeGslEhpnTAkg21GkRrWV4SsAtqchtT4YS9/nODBU2/ZfsBY2X4J/dX7A== + dependencies: + "@types/node" "*" + +"@types/content-disposition@*": + version "0.5.3" + resolved "https://registry.yarnpkg.com/@types/content-disposition/-/content-disposition-0.5.3.tgz#0aa116701955c2faa0717fc69cd1596095e49d96" + integrity sha512-P1bffQfhD3O4LW0ioENXUhZ9OIa0Zn+P7M+pWgkCKaT53wVLSq0mrKksCID/FGHpFhRSxRGhgrQmfhRuzwtKdg== + +"@types/cookies@*": + version "0.7.4" + resolved "https://registry.yarnpkg.com/@types/cookies/-/cookies-0.7.4.tgz#26dedf791701abc0e36b5b79a5722f40e455f87b" + integrity sha512-oTGtMzZZAVuEjTwCjIh8T8FrC8n/uwy+PG0yTvQcdZ7etoel7C7/3MSd7qrukENTgQtotG7gvBlBojuVs7X5rw== + dependencies: + "@types/connect" "*" + "@types/express" "*" + "@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" + integrity sha512-SDKwyYTjk3y5aZBxxc38yRecpJPjsqn57STz1bNxYYlv4k11bBe7QB8w4llXDTmQXKT1mFvgGmJv+8Zdu3YmJw== + +"@types/escape-regexp@0.0.0": + version "0.0.0" + resolved "https://registry.yarnpkg.com/@types/escape-regexp/-/escape-regexp-0.0.0.tgz#bff0225f9ef30d0dbdbe0e2a24283ee5342990c3" + integrity sha512-HTansGo4tJ7K7W9I9LBdQqnHtPB/Y7tlS+EMrkboaAQLsRPhRpHaqAHe01K1HVXM5e1u1IplRd8EBh+pJrp7Dg== + +"@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" + integrity sha512-578YH5Lt88AKoADy0b2jQGwJtrBxezXtVe/MBqWXKZpqx91SnC0pVkVCcxcytz3lWW+cHBYDi3Ysh0WXc+rAYw== + dependencies: + "@types/node" "*" + "@types/range-parser" "*" + +"@types/express@*": + version "4.17.6" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.6.tgz#6bce49e49570507b86ea1b07b806f04697fac45e" + integrity sha512-n/mr9tZI83kd4azlPG5y997C/M4DNABK9yErhFM6hKdym4kkmd9j0vtsJyjFIwfRBxtrxZtAfGZCNRIBMFLK5w== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "*" + "@types/qs" "*" + "@types/serve-static" "*" + +"@types/fluent-ffmpeg@2.1.17": + version "2.1.17" + resolved "https://registry.yarnpkg.com/@types/fluent-ffmpeg/-/fluent-ffmpeg-2.1.17.tgz#6958dda400fe1b33c21f3683db76905cb210d053" + integrity sha512-/bdvjKw/mtBHlJ2370d04nt4CsWqU5MrwS/NtO96V01jxitJ4+iq8OFNcqc5CegeV3TQOK3uueK02kvRK+zjUg== + dependencies: + "@types/node" "*" + +"@types/glob@7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb" + integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA== + dependencies: + "@types/minimatch" "*" + "@types/node" "*" + +"@types/http-assert@*": + version "1.5.1" + resolved "https://registry.yarnpkg.com/@types/http-assert/-/http-assert-1.5.1.tgz#d775e93630c2469c2f980fc27e3143240335db3b" + integrity sha512-PGAK759pxyfXE78NbKxyfRcWYA/KwW17X290cNev/qAsn9eQIxkH4shoNBafH37wewhDG/0p1cHPbK6+SzZjWQ== + +"@types/http-cache-semantics@*": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.0.tgz#9140779736aa2655635ee756e2467d787cfe8a2a" + integrity sha512-c3Xy026kOF7QOTn00hbIllV1dLR9hG9NkSrLQgCVs8NF6sBU+VGWjD3wLPhmh1TYAc7ugCFsvHYMN4VcBN1U1A== + +"@types/http-errors@*": + version "1.8.0" + resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-1.8.0.tgz#682477dbbbd07cd032731cb3b0e7eaee3d026b69" + integrity sha512-2aoSC4UUbHDj2uCsCxcG/vRMXey/m17bC7UwitVm5hn22nI8O8Y9iDpA76Orc+DWkQ4zZrOKEshCqR/jSuXAHA== + +"@types/ioredis@*": + version "4.14.9" + resolved "https://registry.yarnpkg.com/@types/ioredis/-/ioredis-4.14.9.tgz#774387d44d3ad60e1b849044b2b28b96e5813866" + integrity sha512-yNdzppM6vY4DYqXCnt4A3PXArxsMWeJCYxFlyl4AJKrNSGMEAP9TPcXR+8Q6zh9glcCtxmwMQhi4pwdqqHH3OA== + dependencies: + "@types/node" "*" + +"@types/is-url@1.2.30": + version "1.2.30" + resolved "https://registry.yarnpkg.com/@types/is-url/-/is-url-1.2.30.tgz#85567e8bee4fee69202bc3448f9fb34b0d56c50a" + integrity sha512-AnlNFwjzC8XLda5VjRl4ItSd8qp8pSNowvsut0WwQyBWHpOxjxRJm8iO6uETWqEyLdYdb9/1j+Qd9gQ4l5I4fw== + +"@types/js-yaml@4.0.4": + version "4.0.4" + resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-4.0.4.tgz#cc38781257612581a1a0eb25f1709d2b06812fce" + integrity sha512-AuHubXUmg0AzkXH0Mx6sIxeY/1C110mm/EkE/gB1sTRz3h2dao2W/63q42SlVST+lICxz5Oki2hzYA6+KnnieQ== + +"@types/jsdom@16.2.13": + version "16.2.13" + resolved "https://registry.yarnpkg.com/@types/jsdom/-/jsdom-16.2.13.tgz#126c8b7441b159d6234610a48de77b6066f1823f" + integrity sha512-8JQCjdeAidptSsOcRWk2iTm9wCcwn9l+kRG6k5bzUacrnm1ezV4forq0kWjUih/tumAeoG+OspOvQEbbRucBTw== + dependencies: + "@types/node" "*" + "@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" + integrity sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw== + +"@types/json-schema@^7.0.9": + version "7.0.9" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d" + integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ== + +"@types/json5@^0.0.29": + version "0.0.29" + resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" + integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= + +"@types/jsonld@1.5.6": + version "1.5.6" + resolved "https://registry.yarnpkg.com/@types/jsonld/-/jsonld-1.5.6.tgz#4396c0b17128abf5773bb68b5453b88fc565b0d4" + integrity sha512-OUcfMjRie5IOrJulUQwVNvV57SOdKcTfBj3pjXNxzXqeOIrY2aGDNGW/Tlp83EQPkz4tCE6YWVrGuc/ZeaAQGg== + +"@types/keygrip@*": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@types/keygrip/-/keygrip-1.0.2.tgz#513abfd256d7ad0bf1ee1873606317b33b1b2a72" + integrity sha512-GJhpTepz2udxGexqos8wgaBx4I/zWIDPh/KOGEwAqtuGDkOUJu5eFvwmdBX4AmB8Odsr+9pHCQqiAqDL/yKMKw== + +"@types/keyv@*": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.1.tgz#e45a45324fca9dab716ab1230ee249c9fb52cfa7" + integrity sha512-MPtoySlAZQ37VoLaPcTHCu1RWJ4llDkULYZIzOYxlhxBqYPB0RsRlmMU0R6tahtFe27mIdkHV+551ZWV4PLmVw== + dependencies: + "@types/node" "*" + +"@types/koa-bodyparser@4.3.3": + version "4.3.3" + resolved "https://registry.yarnpkg.com/@types/koa-bodyparser/-/koa-bodyparser-4.3.3.tgz#9c7d4295576bc863d550002f732f1c57dd88cc58" + integrity sha512-/ileIpXsy1fFEzgZhZ07eZH8rAVL7jwuk/kaoVEfauO6s80g2LIDIJKEyDbuAL9S/BWflKzEC0PHD6aXkmaSbw== + dependencies: + "@types/koa" "*" + +"@types/koa-compose@*": + version "3.2.5" + resolved "https://registry.yarnpkg.com/@types/koa-compose/-/koa-compose-3.2.5.tgz#85eb2e80ac50be95f37ccf8c407c09bbe3468e9d" + integrity sha512-B8nG/OoE1ORZqCkBVsup/AKcvjdgoHnfi4pZMn5UwAPCbhk/96xyv284eBYW8JlQbQ7zDmnpFr68I/40mFoIBQ== + dependencies: + "@types/koa" "*" + +"@types/koa-cors@0.0.2": + version "0.0.2" + resolved "https://registry.yarnpkg.com/@types/koa-cors/-/koa-cors-0.0.2.tgz#369c753fb383640f225579c70a4f9a286b4931b7" + integrity sha512-uNaDY26HUVO+2C6arK8ZFODs9mBjYprD8mlvkVe2bYdX9wzEeKtycVXPafXpUkePhMh4sffIMkhRDyedokG/QA== + dependencies: + "@types/koa" "*" + +"@types/koa-favicon@2.0.21": + version "2.0.21" + resolved "https://registry.yarnpkg.com/@types/koa-favicon/-/koa-favicon-2.0.21.tgz#d8a0ed062a6f5e3f838fe09c21e8b3f0490369cd" + integrity sha512-paH1nheVhijx/VduoR/RCD/qTCiX+OI/6fHLi3mZae053Ts+gUBOrKtzl3pMTDbdEBqdLolfLje3PZbb6jW0jQ== + dependencies: + "@types/koa" "*" + +"@types/koa-logger@3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@types/koa-logger/-/koa-logger-3.1.2.tgz#91e890f405ddb0626bc385767e4cc0cd7226d1a8" + integrity sha512-sioTA1xlKYiIgryANWPRHBkG3XGbWftw9slWADUPC+qvPIY/yRLSrhvX7zkJwMrntub5dPO0GuAoyGGf0yitfQ== + dependencies: + "@types/koa" "*" + +"@types/koa-mount@4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@types/koa-mount/-/koa-mount-4.0.1.tgz#2994be86eaa3d9dc97365e6ebfa227cee3c5f157" + integrity sha512-HNeg80CVS9Dfq8dGYqCZZCAUm7g6jPCNJ1ydqVLEJxLrjmeburpvq+lOZkE4rxBZ6O38dr3tj9IA3IfbdoI05w== + dependencies: + "@types/koa" "*" + +"@types/koa-send@4.1.3": + version "4.1.3" + resolved "https://registry.yarnpkg.com/@types/koa-send/-/koa-send-4.1.3.tgz#17193c6472ae9e5d1b99ae8086949cc4fd69179d" + integrity sha512-daaTqPZlgjIJycSTNjKpHYuKhXYP30atFc1pBcy6HHqB9+vcymDgYTguPdx9tO4HMOqNyz6bz/zqpxt5eLR+VA== + dependencies: + "@types/koa" "*" + +"@types/koa-views@7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@types/koa-views/-/koa-views-7.0.0.tgz#5613450c77ab69c980c47104378da4b7669c5f2e" + integrity sha512-AB/NB+oFHcLOZJYFv3bG5Af8YbwYCD9/zK0WcKALsbjI/FRKrcXTUTC64RebDrkyOkBm3bpCgpGndhAH/3YQ2Q== + dependencies: + koa-views "*" + +"@types/koa@*", "@types/koa@^2.13.1": + version "2.13.1" + resolved "https://registry.yarnpkg.com/@types/koa/-/koa-2.13.1.tgz#e29877a6b5ad3744ab1024f6ec75b8cbf6ec45db" + integrity sha512-Qbno7FWom9nNqu0yHZ6A0+RWt4mrYBhw3wpBAQ3+IuzGcLlfeYkzZrnMq5wsxulN2np8M4KKeUpTodsOsSad5Q== + dependencies: + "@types/accepts" "*" + "@types/content-disposition" "*" + "@types/cookies" "*" + "@types/http-assert" "*" + "@types/http-errors" "*" + "@types/keygrip" "*" + "@types/koa-compose" "*" + "@types/node" "*" + +"@types/koa@2.13.4": + version "2.13.4" + resolved "https://registry.yarnpkg.com/@types/koa/-/koa-2.13.4.tgz#10620b3f24a8027ef5cbae88b393d1b31205726b" + integrity sha512-dfHYMfU+z/vKtQB7NUrthdAEiSvnLebvBjwHtfFmpZmB7em2N3WVQdHgnFq+xvyVgxW5jKDmjWfLD3lw4g4uTw== + dependencies: + "@types/accepts" "*" + "@types/content-disposition" "*" + "@types/cookies" "*" + "@types/http-assert" "*" + "@types/http-errors" "*" + "@types/keygrip" "*" + "@types/koa-compose" "*" + "@types/node" "*" + +"@types/koa__cors@3.0.3": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/koa__cors/-/koa__cors-3.0.3.tgz#49d75813b443ba3d4da28ea6cf6244b7e99a3b23" + integrity sha512-74Xb4hJOPGKlrQ4PRBk1A/p0gfLpgbnpT0o67OMVbwyeMXvlBN+ZCRztAAmkKZs+8hKbgMutUlZVbA52Hr/0IA== + dependencies: + "@types/koa" "*" + +"@types/koa__multer@2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@types/koa__multer/-/koa__multer-2.0.4.tgz#e0f0fd1800a46b51886bebab480a57100f2488b0" + integrity sha512-WRkshXhE5rpYFUbbtAjyMhdOOSdbu1XX+2AQlRNM6AZtgxd0/WXMU4lrP7e9tk5HWVTWbx8DOOsVBmfHjSGJ4w== + dependencies: + "@types/koa" "*" + +"@types/koa__router@8.0.8": + version "8.0.8" + resolved "https://registry.yarnpkg.com/@types/koa__router/-/koa__router-8.0.8.tgz#b1e0e9a512498777d3366bbdf0e853df27ec831c" + integrity sha512-9pGCaDtzCsj4HJ8HmGuqzk8+s57sPj4njWd08GG5o92n5Xp9io2snc40CPpXFhoKcZ8OKhuu6ht4gNou9e1C2w== + dependencies: + "@types/koa" "*" + +"@types/mime@*": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.1.tgz#dc488842312a7f075149312905b5e3c0b054c79d" + integrity sha512-FwI9gX75FgVBJ7ywgnq/P7tw+/o1GUbtP0KzbtusLigAOgIgNISRK0ZPl4qertvXSIE8YbsVJueQ90cDt9YYyw== + +"@types/minimatch@*": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" + integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== + +"@types/mocha@8.2.3": + version "8.2.3" + resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-8.2.3.tgz#bbeb55fbc73f28ea6de601fbfa4613f58d785323" + integrity sha512-ekGvFhFgrc2zYQoX4JeZPmVzZxw6Dtllga7iGHzfbYIYkAMUx/sAFP2GdFpLff+vdHXu5fl7WX9AT+TtqYcsyw== + +"@types/node-fetch@2.5.12": + version "2.5.12" + resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.5.12.tgz#8a6f779b1d4e60b7a57fb6fd48d84fb545b9cc66" + integrity sha512-MKgC4dlq4kKNa/mYrwpKfzQMB5X3ee5U6fSprkKpToBqBmX4nFZL9cW5jl6sWn+xpRJ7ypWh2yyqqr8UUCstSw== + dependencies: + "@types/node" "*" + form-data "^3.0.0" + +"@types/node@*": + version "16.6.2" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.6.2.tgz#331b7b9f8621c638284787c5559423822fdffc50" + integrity sha512-LSw8TZt12ZudbpHc6EkIyDM3nHVWKYrAvGy6EAJfNfjusbwnThqjqxUKKRwuV3iWYeW/LYMzNgaq3MaLffQ2xA== + +"@types/node@16.11.7": + version "16.11.7" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.7.tgz#36820945061326978c42a01e56b61cd223dfdc42" + integrity sha512-QB5D2sqfSjCmTuWcBWyJ+/44bcjO7VbjSbOE0ucoVbAsSNQc4Lt6QkgkVXkTDwkL4z/beecZNDvVX15D4P8Jbw== + +"@types/node@^14.11.8": + version "14.17.9" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.17.9.tgz#b97c057e6138adb7b720df2bd0264b03c9f504fd" + integrity sha512-CMjgRNsks27IDwI785YMY0KLt3co/c0cQ5foxHYv/shC2w8oOnVwz5Ubq1QG5KzrcW+AXk6gzdnxIkDnTvzu3g== + +"@types/nodemailer@6.4.4": + version "6.4.4" + resolved "https://registry.yarnpkg.com/@types/nodemailer/-/nodemailer-6.4.4.tgz#c265f7e7a51df587597b3a49a023acaf0c741f4b" + integrity sha512-Ksw4t7iliXeYGvIQcSIgWQ5BLuC/mljIEbjf615svhZL10PE9t+ei8O9gDaD3FPCasUJn9KTLwz2JFJyiiyuqw== + dependencies: + "@types/node" "*" + +"@types/nprogress@0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@types/nprogress/-/nprogress-0.2.0.tgz#86c593682d4199212a0509cc3c4d562bbbd6e45f" + integrity sha512-1cYJrqq9GezNFPsWTZpFut/d4CjpZqA0vhqDUPFWYKF1oIyBz5qnoYMzR+0C/T96t3ebLAC1SSnwrVOm5/j74A== + +"@types/oauth@0.9.1": + version "0.9.1" + resolved "https://registry.yarnpkg.com/@types/oauth/-/oauth-0.9.1.tgz#e17221e7f7936b0459ae7d006255dff61adca305" + integrity sha512-a1iY62/a3yhZ7qH7cNUsxoI3U/0Fe9+RnuFrpTKr+0WVOzbKlSLojShCKe20aOD1Sppv+i8Zlq0pLDuTJnwS4A== + dependencies: + "@types/node" "*" + +"@types/parse5@*": + version "5.0.3" + resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-5.0.3.tgz#e7b5aebbac150f8b5fdd4a46e7f0bd8e65e19109" + integrity sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw== + +"@types/parse5@6.0.2": + version "6.0.2" + resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-6.0.2.tgz#99f6b72d82e34cea03a4d8f2ed72114d909c1c61" + integrity sha512-+hQX+WyJAOne7Fh3zF5CxPemILIbuhNcqHHodzK9caYOLnC8pD5efmPleRnw0z++LfKUC/sVNMwk0Gap+B0baA== + +"@types/parsimmon@1.10.6": + version "1.10.6" + resolved "https://registry.yarnpkg.com/@types/parsimmon/-/parsimmon-1.10.6.tgz#8fcf95990514d2a7624aa5f630c13bf2427f9cdd" + integrity sha512-FwAQwMRbkhx0J6YELkwIpciVzCcgEqXEbIrIn3a2P5d3kGEHQ3wVhlN3YdVepYP+bZzCYO6OjmD4o9TGOZ40rA== + +"@types/portscanner@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@types/portscanner/-/portscanner-2.1.1.tgz#89d5094e16f3d941f20f3889dfa5d3a164b3dd3b" + integrity sha512-1NsVIbgBKvrqxwtMN0V6CLji1ERwKSI/RWz0J3y++CzSwYNGBStCfpIFgxV3ZwxsDR5PoZqoUWhwraDm+Ztn0Q== + +"@types/pug@2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@types/pug/-/pug-2.0.5.tgz#69bc700934dd473c7ab97270bd2dbacefe562231" + integrity sha512-LOnASQoeNZMkzexRuyqcBBDZ6rS+rQxUMkmj5A0PkhhiSZivLIuz6Hxyr1mkGoEZEkk66faROmpMi4fFkrKsBA== + +"@types/punycode@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@types/punycode/-/punycode-2.1.0.tgz#89e4f3d09b3f92e87a80505af19be7e0c31d4e83" + integrity sha512-PG5aLpW6PJOeV2fHRslP4IOMWn+G+Uq8CfnyJ+PDS8ndCbU+soO+fB3NKCKo0p/Jh2Y4aPaiQZsrOXFdzpcA6g== + +"@types/qrcode@1.4.1": + version "1.4.1" + resolved "https://registry.yarnpkg.com/@types/qrcode/-/qrcode-1.4.1.tgz#0689f400c3a95d2db040c99c99834faa09ee9dc1" + integrity sha512-vxMyr7JM7tYPxu8vUE83NiosWX5DZieCyYeJRoOIg0pAkyofCBzknJ2ycUZkPGDFis2RS8GN/BeJLnRnAPxeCA== + dependencies: + "@types/node" "*" + +"@types/qs@*": + version "6.9.1" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.1.tgz#937fab3194766256ee09fcd40b781740758617e7" + integrity sha512-lhbQXx9HKZAPgBkISrBcmAcMpZsmpe/Cd/hY7LGZS5OfkySUBItnPZHgQPssWYUET8elF+yCFBbP1Q0RZPTdaw== + +"@types/random-seed@0.3.3": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@types/random-seed/-/random-seed-0.3.3.tgz#7741f7b0a4513198a9396ce4ad25832f799a6727" + integrity sha512-kHsCbIRHNXJo6EN5W8EA5b4i1hdT6jaZke5crBPLUcLqaLdZ0QBq8QVMbafHzhjFF83Cl9qlee2dChD18d/kPg== + +"@types/range-parser@*": + version "1.2.3" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c" + integrity sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA== + +"@types/ratelimiter@3.4.2": + version "3.4.2" + resolved "https://registry.yarnpkg.com/@types/ratelimiter/-/ratelimiter-3.4.2.tgz#adf1a6d0cbe72d42207efc510a9170602e23456c" + integrity sha512-iz+yyY+ViphaM8ZwrX1mUQzelIeC59zyaaLKTJ0YVOOCkCpIYpaysiIM4z5Xv9HdXYqIb80S+DhH7J22A0rW2w== + +"@types/readable-stream@^2.3.9": + version "2.3.9" + resolved "https://registry.yarnpkg.com/@types/readable-stream/-/readable-stream-2.3.9.tgz#40a8349e6ace3afd2dd1b6d8e9b02945de4566a9" + integrity sha512-sqsgQqFT7HmQz/V5jH1O0fvQQnXAJO46Gg9LRO/JPfjmVmGUlcx831TZZO3Y3HtWhIkzf3kTsNT0Z0kzIhIvZw== + dependencies: + "@types/node" "*" + safe-buffer "*" + +"@types/redis@2.8.32": + version "2.8.32" + resolved "https://registry.yarnpkg.com/@types/redis/-/redis-2.8.32.tgz#1d3430219afbee10f8cfa389dad2571a05ecfb11" + integrity sha512-7jkMKxcGq9p242exlbsVzuJb57KqHRhNl4dHoQu2Y5v9bCAbtIXXH0R3HleSQW4CTOqpHIYUW3t6tpUj4BVQ+w== + dependencies: + "@types/node" "*" + +"@types/rename@1.0.4": + version "1.0.4" + 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" + integrity sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA== + dependencies: + "@types/node" "*" + +"@types/rsvp@^4.0.4": + version "4.0.4" + resolved "https://registry.yarnpkg.com/@types/rsvp/-/rsvp-4.0.4.tgz#55e93e7054027f1ad4b4ebc1e60e59eb091e2d32" + integrity sha512-J3Ol++HCC7/hwZhanDvggFYU/GtxHxE/e7cGRWxR04BF7Tt3TqJZ84BkzQgDxmX0uu8IagiyfmfoUlBACh2Ilg== + +"@types/sanitize-html@2.5.0": + version "2.5.0" + resolved "https://registry.yarnpkg.com/@types/sanitize-html/-/sanitize-html-2.5.0.tgz#bfef58fbcf2674b20ffcc23c3506faa68c3a13e3" + integrity sha512-PeFIEZsO9m1+ACJlXUaimgrR+5DEDiIXhz7Hso307jmq5Yz0lb5kDp8LiTr5dMMMliC/jNNx/qds7Zoxa4zexw== + 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/serve-static@*": + version "1.13.3" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.3.tgz#eb7e1c41c4468272557e897e9171ded5e2ded9d1" + integrity sha512-oprSwp094zOglVrXdlo/4bAHtKTAxX6VT8FOZlBKrmyLbNvE1zxZyJ6yikMVtHIvwP45+ZQGJn+FdXGKTozq0g== + dependencies: + "@types/express-serve-static-core" "*" + "@types/mime" "*" + +"@types/sharp@0.29.3": + version "0.29.3" + resolved "https://registry.yarnpkg.com/@types/sharp/-/sharp-0.29.3.tgz#54ceb81b68bb99a0e62db2b52f4fb0bea84878ac" + integrity sha512-83Xp05eK2hvfNnmKLr2Fz0C2A0jrr2TnSLqKRbkLTYuAu+Erj6mKQLoEMGafE73Om8p3q3ryZxtHFM/7hy4Adg== + 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/speakeasy@2.0.6": + version "2.0.6" + resolved "https://registry.yarnpkg.com/@types/speakeasy/-/speakeasy-2.0.6.tgz#12540f7b64d08180393ae2c5c8c280866a85da61" + integrity sha512-2wIXZp5yJUddhsSZarYCZIakCvzwQgTVdtT29DYVdFzc0cHttanaQx9THRhtjY4kDqVaF2jhyFOEofozOioFdQ== + 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" + integrity sha512-5eQEtSCoESnh2FsiLTxE121IiE60hnMqcb435fShf4bpLRjEu1Eoekht23y6zXS9Ts3l+Szu3TARnTsA0GkOkQ== + +"@types/tinycolor2@1.4.3": + version "1.4.3" + resolved "https://registry.yarnpkg.com/@types/tinycolor2/-/tinycolor2-1.4.3.tgz#ed4a0901f954b126e6a914b4839c77462d56e706" + integrity sha512-Kf1w9NE5HEgGxCRyIcRXR/ZYtDv0V8FVPtYHwLxl0O+maGX0erE77pQlD0gpP+/KByMZ87mOA79SjifhSB3PjQ== + +"@types/tmp@0.2.2": + version "0.2.2" + resolved "https://registry.yarnpkg.com/@types/tmp/-/tmp-0.2.2.tgz#424537a3b91828cb26aaf697f21ae3cd1b69f7e7" + integrity sha512-MhSa0yylXtVMsyT8qFpHA1DLHj4DvQGH5ntxrhHSh8PxUVNi35Wk+P5hVgqbO2qZqOotqr9jaoPRL+iRjWYm/A== + +"@types/tough-cookie@*": + version "4.0.0" + 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.1": + version "8.3.1" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.1.tgz#1a32969cf8f0364b3d8c8af9cc3555b7805df14f" + integrity sha512-Y2mHTRAbqfFkpjldbkHGY8JIzRN6XqYRliG8/24FcHm2D2PwW24fl5xMRTVGdrb7iMrwCaIEbLWerGIkXuFWVg== + +"@types/web-push@3.3.2": + version "3.3.2" + resolved "https://registry.yarnpkg.com/@types/web-push/-/web-push-3.3.2.tgz#8c32434147c0396415862e86405c9edc9c50fc15" + integrity sha512-JxWGVL/m7mWTIg4mRYO+A6s0jPmBkr4iJr39DqJpRJAc+jrPiEe1/asmkwerzRon8ZZDxaZJpsxpv0Z18Wo9gw== + 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== + dependencies: + "@types/node" "*" + +"@types/ws@8.2.0": + version "8.2.0" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.2.0.tgz#75faefbe2328f3b833cb8dc640658328990d04f3" + integrity sha512-cyeefcUCgJlEk+hk2h3N+MqKKsPViQgF5boi9TTHSK+PoR9KWBb/C5ccPcDyAqgsbAYHTwulch725DV84+pSpg== + dependencies: + "@types/node" "*" + +"@types/zen-observable@^0.8.2": + version "0.8.2" + resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.8.2.tgz#808c9fa7e4517274ed555fa158f2de4b4f468e71" + integrity sha512-HrCIVMLjE1MOozVoD86622S7aunluLb2PJdPfb3nYiEtohm8mIB/vyv0Fd37AdeMFrTUQXEunw78YloMA3Qilg== + +"@typescript-eslint/eslint-plugin@5.3.1": + version "5.3.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.3.1.tgz#d8ff412f10f54f6364e7fd7c1e70eb6767f434c3" + integrity sha512-cFImaoIr5Ojj358xI/SDhjog57OK2NqlpxwdcgyxDA3bJlZcJq5CPzUXtpD7CxI2Hm6ATU7w5fQnnkVnmwpHqw== + dependencies: + "@typescript-eslint/experimental-utils" "5.3.1" + "@typescript-eslint/scope-manager" "5.3.1" + debug "^4.3.2" + functional-red-black-tree "^1.0.1" + ignore "^5.1.8" + regexpp "^3.2.0" + semver "^7.3.5" + tsutils "^3.21.0" + +"@typescript-eslint/experimental-utils@5.3.1": + version "5.3.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-5.3.1.tgz#bbd8f9b67b4d5fdcb9d2f90297d8fcda22561e05" + integrity sha512-RgFn5asjZ5daUhbK5Sp0peq0SSMytqcrkNfU4pnDma2D8P3ElZ6JbYjY8IMSFfZAJ0f3x3tnO3vXHweYg0g59w== + dependencies: + "@types/json-schema" "^7.0.9" + "@typescript-eslint/scope-manager" "5.3.1" + "@typescript-eslint/types" "5.3.1" + "@typescript-eslint/typescript-estree" "5.3.1" + eslint-scope "^5.1.1" + eslint-utils "^3.0.0" + +"@typescript-eslint/parser@5.1.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.1.0.tgz#6c7f837d210d2bc0a811e7ea742af414f4e00908" + integrity sha512-vx1P+mhCtYw3+bRHmbalq/VKP2Y3gnzNgxGxfEWc6OFpuEL7iQdAeq11Ke3Rhy8NjgB+AHsIWEwni3e+Y7djKA== + dependencies: + "@typescript-eslint/scope-manager" "5.1.0" + "@typescript-eslint/types" "5.1.0" + "@typescript-eslint/typescript-estree" "5.1.0" + debug "^4.3.2" + +"@typescript-eslint/scope-manager@5.1.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.1.0.tgz#6f1f26ad66a8f71bbb33b635e74fec43f76b44df" + integrity sha512-yYlyVjvn5lvwCL37i4hPsa1s0ORsjkauhTqbb8MnpvUs7xykmcjGqwlNZ2Q5QpoqkJ1odlM2bqHqJwa28qV6Tw== + dependencies: + "@typescript-eslint/types" "5.1.0" + "@typescript-eslint/visitor-keys" "5.1.0" + +"@typescript-eslint/scope-manager@5.3.1": + version "5.3.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.3.1.tgz#3cfbfbcf5488fb2a9a6fbbe97963ee1e8d419269" + integrity sha512-XksFVBgAq0Y9H40BDbuPOTUIp7dn4u8oOuhcgGq7EoDP50eqcafkMVGrypyVGvDYHzjhdUCUwuwVUK4JhkMAMg== + dependencies: + "@typescript-eslint/types" "5.3.1" + "@typescript-eslint/visitor-keys" "5.3.1" + +"@typescript-eslint/types@5.1.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.1.0.tgz#a8a75ddfc611660de6be17d3ad950302385607a9" + integrity sha512-sEwNINVxcB4ZgC6Fe6rUyMlvsB2jvVdgxjZEjQUQVlaSPMNamDOwO6/TB98kFt4sYYfNhdhTPBEQqNQZjMMswA== + +"@typescript-eslint/types@5.3.1": + version "5.3.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.3.1.tgz#afaa715b69ebfcfde3af8b0403bf27527912f9b7" + integrity sha512-bG7HeBLolxKHtdHG54Uac750eXuQQPpdJfCYuw4ZI3bZ7+GgKClMWM8jExBtp7NSP4m8PmLRM8+lhzkYnSmSxQ== + +"@typescript-eslint/typescript-estree@5.1.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.1.0.tgz#132aea34372df09decda961cb42457433aa6e83d" + integrity sha512-SSz+l9YrIIsW4s0ZqaEfnjl156XQ4VRmJsbA0ZE1XkXrD3cRpzuZSVCyqeCMR3EBjF27IisWakbBDGhGNIOvfQ== + dependencies: + "@typescript-eslint/types" "5.1.0" + "@typescript-eslint/visitor-keys" "5.1.0" + debug "^4.3.2" + globby "^11.0.4" + is-glob "^4.0.3" + semver "^7.3.5" + tsutils "^3.21.0" + +"@typescript-eslint/typescript-estree@5.3.1": + version "5.3.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.3.1.tgz#50cc4bfb93dc31bc75e08ae52e29fcb786d606ec" + integrity sha512-PwFbh/PKDVo/Wct6N3w+E4rLZxUDgsoII/GrWM2A62ETOzJd4M6s0Mu7w4CWsZraTbaC5UQI+dLeyOIFF1PquQ== + dependencies: + "@typescript-eslint/types" "5.3.1" + "@typescript-eslint/visitor-keys" "5.3.1" + debug "^4.3.2" + globby "^11.0.4" + is-glob "^4.0.3" + semver "^7.3.5" + tsutils "^3.21.0" + +"@typescript-eslint/visitor-keys@5.1.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.1.0.tgz#e01a01b27eb173092705ae983aa1451bd1842630" + integrity sha512-uqNXepKBg81JVwjuqAxYrXa1Ql/YDzM+8g/pS+TCPxba0wZttl8m5DkrasbfnmJGHs4lQ2jTbcZ5azGhI7kK+w== + dependencies: + "@typescript-eslint/types" "5.1.0" + eslint-visitor-keys "^3.0.0" + +"@typescript-eslint/visitor-keys@5.3.1": + version "5.3.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.3.1.tgz#c2860ff22939352db4f3806f34b21d8ad00588ba" + integrity sha512-3cHUzUuVTuNHx0Gjjt5pEHa87+lzyqOiHXy/Gz+SJOCW1mpw9xQHIIEwnKn+Thph1mgWyZ90nboOcSuZr/jTTQ== + dependencies: + "@typescript-eslint/types" "5.3.1" + eslint-visitor-keys "^3.0.0" + +"@ungap/promise-all-settled@1.1.2": + version "1.1.2" + 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" + integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== + +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + +abort-controller@3.0.0, abort-controller@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" + integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== + dependencies: + event-target-shim "^5.0.0" + +accepts@^1.3.5: + version "1.3.7" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" + integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== + dependencies: + mime-types "~2.1.24" + negotiator "0.6.2" + +acorn-globals@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-6.0.0.tgz#46cdd39f0f8ff08a876619b55f5ac8a6dc770b45" + integrity sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg== + dependencies: + acorn "^7.1.1" + acorn-walk "^7.1.1" + +acorn-jsx@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b" + integrity sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng== + +acorn-walk@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.1.1.tgz#345f0dffad5c735e7373d2fec9a1023e6a44b83e" + integrity sha512-wdlPY2tm/9XBr7QkKlq0WQVgiuGTX6YWPyRyBviSoScBuLfTVQhvwg6wJ369GJ/1nPfTLMfnrFIfjqVg6d+jQQ== + +acorn-walk@^8.1.1: + version "8.1.1" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.1.1.tgz#3ddab7f84e4a7e2313f6c414c5b7dac85f4e3ebc" + integrity sha512-FbJdceMlPHEAWJOILDk1fXD8lnTlEIWFkqtfk+MvmL5q/qlHfN7GEHcsFZWt/Tea9jRNPWUZG4G976nqAAmU9w== + +acorn@^7.1.1: + version "7.4.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.5.0: + version "8.5.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.5.0.tgz#4512ccb99b3698c752591e9bb4472e38ad43cee2" + integrity sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q== + +agent-base@6: + version "6.0.2" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== + dependencies: + debug "4" + +agentkeepalive@^4.1.3: + version "4.1.4" + resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.1.4.tgz#d928028a4862cb11718e55227872e842a44c945b" + integrity sha512-+V/rGa3EuU74H6wR04plBb7Ks10FbtUQgRj/FQOG7uUIEuaINI+AiqJR1k6t3SVNs7o7ZjIdus6706qqzVq8jQ== + dependencies: + debug "^4.1.0" + depd "^1.1.2" + humanize-ms "^1.2.1" + +aggregate-error@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" + integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== + dependencies: + clean-stack "^2.0.0" + indent-string "^4.0.0" + +ajv-keywords@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" + integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== + +ajv@^6.10.0, ajv@^6.12.4, ajv@^6.12.5, ajv@^6.5.5: + version "6.12.5" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.5.tgz#19b0e8bae8f476e5ba666300387775fb1a00a4da" + integrity sha512-lRF8RORchjpKG50/WFf8xmg7sgCLFiYNNnqdKflk63whMQcWR5ngGjiSXkL9bjxy6B2npOK2HSMN49jEBMSkag== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +alphanum-sort@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" + integrity sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM= + +ansi-colors@4.1.1, ansi-colors@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= + +ansi-regex@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" + integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== + +ansi-regex@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" + integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^3.2.0, ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359" + integrity sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA== + dependencies: + "@types/color-name" "^1.1.1" + color-convert "^2.0.1" + +any-promise@^1.0.0, any-promise@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" + integrity sha1-q8av7tzqUugJzcA3au0845Y10X8= + +anymatch@~3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" + integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +app-root-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/app-root-path/-/app-root-path-3.0.0.tgz#210b6f43873227e18a4b810a032283311555d5ad" + integrity sha512-qMcx+Gy2UZynHjOHOIXPNvpf+9cjvk3cWrBBK7zg4gH9+clobJRb9NGzcT7mQTcV/6Gm/1WelUtqxVXnNlrwcw== + +append-field@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/append-field/-/append-field-1.0.0.tgz#1e3440e915f0b1203d23748e78edd7b9b5b43e56" + integrity sha1-HjRA6RXwsSA9I3SOeO3XubW0PlY= + +aproba@^1.0.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== + +are-we-there-yet@~1.1.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" + integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + +arg@^4.1.0: + version "4.1.3" + resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" + integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +array-includes@^3.1.4: + version "3.1.4" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.4.tgz#f5b493162c760f3539631f005ba2bb46acb45ba9" + integrity sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.1" + get-intrinsic "^1.1.1" + is-string "^1.0.7" + +array-timsort@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-timsort/-/array-timsort-1.0.3.tgz#3c9e4199e54fb2b9c3fe5976396a21614ef0d926" + integrity sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ== + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + +array.prototype.flat@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz#07e0975d84bbc7c48cd1879d609e682598d33e13" + integrity sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.0" + +asap@~2.0.3: + version "2.0.6" + resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" + integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= + +asn1.js@^5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-5.3.0.tgz#439099fe9174e09cff5a54a9dda70260517e8689" + integrity sha512-WHnQJFcOrIWT1RLOkFFBQkFVvyt9BPOOrH+Dp152Zk4R993rSzXUGPmkybIcUFhHE2d/iHH+nCaOWVCDbO8fgA== + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + safer-buffer "^2.1.0" + +asn1@~0.2.3: + version "0.2.4" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" + integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== + dependencies: + safer-buffer "~2.1.0" + +assert-never@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/assert-never/-/assert-never-1.2.1.tgz#11f0e363bf146205fb08193b5c7b90f4d1cf44fe" + integrity sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw== + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= + +async@>=0.2.9: + version "3.2.0" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.0.tgz#b3a2685c5ebb641d3de02d161002c60fc9f85720" + integrity sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw== + +async@^2.6.0: + version "2.6.3" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" + integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== + dependencies: + lodash "^4.17.14" + +async@^3.2.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.1.tgz#d3274ec66d107a47476a4c49136aacdb00665fc8" + integrity sha512-XdD5lRO/87udXCMC9meWdYiR+Nq6ZjUfXidViUZGu2F1MO4T3XwZ1et0hb2++BgLfhyJwy44BGB/yx80ABx8hg== + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + +autobind-decorator@2.4.0, autobind-decorator@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/autobind-decorator/-/autobind-decorator-2.4.0.tgz#ea9e1c98708cf3b5b356f7cf9f10f265ff18239c" + integrity sha512-OGYhWUO72V6DafbF8PM8rm3EPbfuyMZcJhtm5/n26IDwO18pohE4eNazLoCGhPiXOCD0gEGmrbU3849QvM8bbw== + +autosize@4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/autosize/-/autosize-4.0.4.tgz#924f13853a466b633b9309330833936d8bccce03" + integrity sha512-5yxLQ22O0fCRGoxGfeLSNt3J8LB1v+umtpMnPW6XjkTWXKoN0AmXAIhelJcDtFT/Y/wYWmfE+oqU10Q0b8FhaQ== + +autwh@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/autwh/-/autwh-0.1.0.tgz#24a5300923309d105133401a2568f9c8ab7d7e03" + integrity sha512-IkGZ4kjVlZMkEmDiVtZpGG3lDGHPqsMBIh4IpQKN7idYOJ5EGedqKPO+ychNqh8zrJEEqYsN0NcBkcmoE2uFAw== + dependencies: + oauth "0.9.15" + +aws-sdk@2.1013.0: + version "2.1013.0" + resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.1013.0.tgz#85babc473b0bc90cc1160eb48baf616ddb86e346" + integrity sha512-TXxkp/meAdofpC15goFpNuur7fvh/mcMRfHJoP1jYzTtD0wcoB4FK16GLcny0uDYgkQgZuiO9QYv3Rq5bhGCqQ== + dependencies: + buffer "4.9.2" + events "1.1.1" + ieee754 "1.1.13" + jmespath "0.15.0" + querystring "0.2.0" + sax "1.2.1" + url "0.10.3" + uuid "3.3.2" + xml2js "0.4.19" + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= + +aws4@^1.8.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.9.1.tgz#7e33d8f7d449b3f673cd72deb9abdc552dbe528e" + integrity sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug== + +axios@^0.19.2: + version "0.19.2" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27" + integrity sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA== + dependencies: + follow-redirects "1.5.10" + +babel-walk@3.0.0-canary-5: + version "3.0.0-canary-5" + resolved "https://registry.yarnpkg.com/babel-walk/-/babel-walk-3.0.0-canary-5.tgz#f66ecd7298357aee44955f235a6ef54219104b11" + integrity sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw== + dependencies: + "@babel/types" "^7.9.6" + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + +base32.js@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/base32.js/-/base32.js-0.0.1.tgz#d045736a57b1f6c139f0c7df42518a84e91bb2ba" + integrity sha1-0EVzalex9sE58MffQlGKhOkbsro= + +base64-js@^1.0.2: + version "1.3.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" + integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== + +base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= + dependencies: + tweetnacl "^0.14.3" + +bcryptjs@2.4.3: + version "2.4.3" + resolved "https://registry.yarnpkg.com/bcryptjs/-/bcryptjs-2.4.3.tgz#9ab5627b93e60621ff7cdac5da9733027df1d0cb" + integrity sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms= + +big-integer@^1.6.16: + version "1.6.48" + resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.48.tgz#8fd88bd1632cba4a1c8c3e3d7159f08bb95b4b9e" + integrity sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w== + +big.js@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" + integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== + +binary-extensions@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.0.0.tgz#23c0df14f6a88077f5f986c0d167ec03c3d5537c" + integrity sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow== + +bl@^4.0.1, bl@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/bl/-/bl-4.0.3.tgz#12d6287adc29080e22a705e5764b2a9522cdc489" + integrity sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg== + dependencies: + buffer "^5.5.0" + inherits "^2.0.4" + readable-stream "^3.4.0" + +bluebird@^3.7.2: + version "3.7.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== + +blurhash@1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/blurhash/-/blurhash-1.1.4.tgz#a7010ceb3019cd2c9809b17c910ebf6175d29244" + integrity sha512-MXIPz6zwYUKayju+Uidf83KhH0vodZfeRl6Ich8Gu+KGl0JgKiFq9LsfqV7cVU5fKD/AotmduZqvOfrGKOfTaA== + +bn.js@^4.0.0: + version "4.11.8" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" + integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== + +boolbase@^1.0.0, boolbase@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^3.0.1, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +broadcast-channel@4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/broadcast-channel/-/broadcast-channel-4.5.0.tgz#d4717c493e219908fcb7f2f9078fe0baf95b77c1" + integrity sha512-jp+VPlQ1HyR0CM3uIYUrdpXupBvhTMFRkjR6mEmt5W4HaGDPFEzrO2Jqvi2PZ6zCC4zwLeco7CC5EUJPrVH8Tw== + dependencies: + "@babel/runtime" "^7.16.0" + detect-node "^2.1.0" + microseconds "0.2.0" + nano-time "1.0.0" + oblivious-set "1.0.0" + rimraf "3.0.2" + unload "2.3.1" + +browser-process-hrtime@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" + integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== + +browser-stdout@1.3.1: + version "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.0.0, 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" + +browserslist@^4.16.0: + version "4.16.4" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.4.tgz#7ebf913487f40caf4637b892b268069951c35d58" + integrity sha512-d7rCxYV8I9kj41RH8UKYnvDYCRENUlHRgyXy/Rhr/1BaeLGfiCptEdFE8MIrvGfWbBFNjVYx76SQWvNX1j+/cQ== + dependencies: + caniuse-lite "^1.0.30001208" + colorette "^1.2.2" + electron-to-chromium "^1.3.712" + escalade "^3.1.1" + node-releases "^1.1.71" + +browserslist@^4.16.6: + version "4.16.6" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.6.tgz#d7901277a5a88e554ed305b183ec9b0c08f66fa2" + integrity sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ== + dependencies: + caniuse-lite "^1.0.30001219" + colorette "^1.2.2" + electron-to-chromium "^1.3.723" + escalade "^3.1.1" + node-releases "^1.1.71" + +bs-logger@0.x: + version "0.2.6" + resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" + integrity sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog== + dependencies: + fast-json-stable-stringify "2.x" + +buffer-alloc-unsafe@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" + integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== + +buffer-alloc@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" + integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== + dependencies: + buffer-alloc-unsafe "^1.1.0" + buffer-fill "^1.0.0" + +buffer-equal-constant-time@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" + integrity sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk= + +buffer-fill@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" + integrity sha1-+PeLdniYiO858gXNY39o5wISKyw= + +buffer-from@1.x: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +buffer-from@^1.0.0, buffer-from@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== + +buffer-writer@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/buffer-writer/-/buffer-writer-2.0.0.tgz#ce7eb81a38f7829db09c873f2fbb792c0c98ec04" + integrity sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw== + +buffer@4.9.2: + version "4.9.2" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" + integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.0" + +buffer@^5.4.3, buffer@^5.5.0: + version "5.6.0" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.6.0.tgz#a31749dc7d81d84db08abf937b6b8c4033f62786" + integrity sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + +buffer@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" + integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.2.1" + +bufferutil@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.1.tgz#3a177e8e5819a1243fe16b63a199951a7ad8d4a7" + integrity sha512-xowrxvpxojqkagPcWRQVXZl0YXhRhAtBEIq3VoER1NH5Mw1n1o0ojdspp+GS2J//2gCVyrzQDApQ4unGF+QOoA== + dependencies: + node-gyp-build "~3.7.0" + +bull@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/bull/-/bull-4.1.0.tgz#ff8f628694e7dbbdf89b6a6860a1f33e990527fd" + integrity sha512-rQcLuAmzZIv1dHJO/yKrWu497xcTxMpYeTEBfpStrJFZ1UZpBSGHSx+defbtFVeGEeY8Pn0aMGRvRtldUBVUyQ== + dependencies: + cron-parser "^2.13.0" + debuglog "^1.0.0" + get-port "^5.1.1" + ioredis "^4.27.0" + lodash "^4.17.21" + p-timeout "^3.2.0" + promise.prototype.finally "^3.1.2" + semver "^7.3.2" + util.promisify "^1.0.1" + uuid "^8.3.0" + +busboy@^0.2.11: + version "0.2.14" + resolved "https://registry.yarnpkg.com/busboy/-/busboy-0.2.14.tgz#6c2a622efcf47c57bbbe1e2a9c37ad36c7925453" + integrity sha1-bCpiLvz0fFe7vh4qnDetNseSVFM= + dependencies: + dicer "0.2.5" + readable-stream "1.1.x" + +bytes@3.1.0, bytes@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" + integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== + +cacache@^15.0.5: + version "15.1.0" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.1.0.tgz#164c2f857ee606e4cc793c63018fefd0ea5eba7b" + integrity sha512-mfx0C+mCfWjD1PnwQ9yaOrwG1ou9FkKnx0SvzUHWdFt7r7GaRtzT+9M8HAvLu62zIHtnpQ/1m93nWNDCckJGXQ== + dependencies: + "@npmcli/move-file" "^1.0.1" + chownr "^2.0.0" + fs-minipass "^2.0.0" + glob "^7.1.4" + infer-owner "^1.0.4" + lru-cache "^6.0.0" + minipass "^3.1.1" + minipass-collect "^1.0.2" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.2" + mkdirp "^1.0.3" + p-map "^4.0.0" + promise-inflight "^1.0.1" + rimraf "^3.0.2" + ssri "^8.0.1" + tar "^6.0.2" + unique-filename "^1.1.1" + +cache-content-type@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-content-type/-/cache-content-type-1.0.1.tgz#035cde2b08ee2129f4a8315ea8f00a00dba1453c" + integrity sha512-IKufZ1o4Ut42YUrZSo8+qnMTrFuKkvyoLXUywKz9GJ5BrhOFGhLdkx9sG4KAnVvbY6kEcSFjLQul+DVmBm2bgA== + dependencies: + mime-types "^2.1.18" + ylru "^1.2.0" + +cacheable-lookup@6.0.4: + version "6.0.4" + resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-6.0.4.tgz#65c0e51721bb7f9f2cb513aed6da4a1b93ad7dc8" + integrity sha512-mbcDEZCkv2CZF4G01kr8eBd/5agkt9oCqz75tJMSIsquvRZ2sL6Hi5zGVKi/0OSC9oO1GHfJ2AV0ZIOY9vye0A== + +cacheable-lookup@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.3.tgz#049fdc59dffdd4fc285e8f4f82936591bd59fec3" + integrity sha512-W+JBqF9SWe18A72XFzN/V/CULFzPm7sBXzzR6ekkE+3tLG72wFZrBiBZhrZuDoYexop4PHJVdFAKb/Nj9+tm9w== + +cacheable-request@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.1.tgz#062031c2856232782ed694a257fa35da93942a58" + integrity sha512-lt0mJ6YAnsrBErpTMWeu5kl/tg9xMAWjavYTN6VQXM1A/teBITuNcccXsCxF0tDQQJf9DfAaX5O4e0zp0KlfZw== + dependencies: + clone-response "^1.0.2" + get-stream "^5.1.0" + http-cache-semantics "^4.0.0" + keyv "^4.0.0" + lowercase-keys "^2.0.0" + normalize-url "^4.1.0" + responselike "^2.0.0" + +cafy@15.2.1: + version "15.2.1" + resolved "https://registry.yarnpkg.com/cafy/-/cafy-15.2.1.tgz#5a55eaeb721c604c7dca652f3d555c392e5f995a" + integrity sha512-g2zOmFb63p6XcZ/zeMWKYP8YKQYNWnhJmi6K71Ql4EAFTAay31xF0PBPtdBCCfQ0fiETgWTMxKtySAVI/Od6aQ== + +call-bind@^1.0.0, call-bind@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +camelcase@^5.0.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +camelcase@^6.0.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809" + integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== + +caniuse-api@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0" + integrity sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw== + dependencies: + browserslist "^4.0.0" + caniuse-lite "^1.0.0" + lodash.memoize "^4.1.2" + lodash.uniq "^4.5.0" + +caniuse-lite@^1.0.0: + version "1.0.30001048" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001048.tgz#4bb4f1bc2eb304e5e1154da80b93dee3f1cf447e" + integrity sha512-g1iSHKVxornw0K8LG9LLdf+Fxnv7T1Z+mMsf0/YYLclQX4Cd522Ap0Lrw6NFqHgezit78dtyWxzlV2Xfc7vgRg== + +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== + +caniuse-lite@^1.0.30001208: + version "1.0.30001208" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001208.tgz#a999014a35cebd4f98c405930a057a0d75352eb9" + integrity sha512-OE5UE4+nBOro8Dyvv0lfx+SRtfVIOM9uhKqFmJeUbGriqhhStgp1A0OyBpgy3OUF8AhYCT+PVwPC1gMl2ZcQMA== + +caniuse-lite@^1.0.30001219: + version "1.0.30001230" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001230.tgz#8135c57459854b2240b57a4a6786044bdc5a9f71" + integrity sha512-5yBd5nWCBS+jWKTcHOzXwo5xzcj4ePE/yjtkZyUV1BTUmrBaA9MRGC+e7mxnqXSA90CmCA8L3eKLaSUkt099IQ== + +canonicalize@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/canonicalize/-/canonicalize-1.0.1.tgz#657b4f3fa38a6ecb97a9e5b7b26d7a19cc6e0da9" + integrity sha512-N3cmB3QLhS5TJ5smKFf1w42rJXWe6C1qP01z4dxJiI5v269buii4fLHWETDyf7yEd0azGLNC63VxNMiPd2u0Cg== + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= + +cbor@*: + version "7.0.5" + resolved "https://registry.yarnpkg.com/cbor/-/cbor-7.0.5.tgz#ed54cdbc19fa7352bb328d00a5393aa7ce45a10f" + integrity sha512-0aaAPgW92lLmypb9iCd22k7tSD1FbF6dps8VQzmIBKY6ych2gO09b2vo/SbaLTmezJuB8Kh88Rvpl/Uq52mNZg== + dependencies: + "@cto.af/textdecoder" "^0.0.0" + nofilter "^2.0.3" + +cbor@8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/cbor/-/cbor-8.1.0.tgz#cfc56437e770b73417a2ecbfc9caf6b771af60d5" + integrity sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg== + dependencies: + nofilter "^3.1.0" + +chalk@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.0.0.tgz#6e98081ed2d17faab615eb52ac66ec1fe6209e72" + integrity sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chalk@4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^4.0.0, chalk@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" + integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +char-regex@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" + integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== + +character-parser@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/character-parser/-/character-parser-2.2.0.tgz#c7ce28f36d4bcd9744e5ffc2c5fcde1c73261fc0" + integrity sha1-x84o821LzZdE5f/CxfzeHHMmH8A= + dependencies: + is-regex "^1.0.3" + +chart.js@3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-3.6.0.tgz#a87fce8431d4e7c5523d721f487f53aada1e42fe" + integrity sha512-iOzzDKePL+bj+ccIsVAgWQehCXv8xOKGbaU2fO/myivH736zcx535PGJzQGanvcSGVOqX6yuLZsN3ygcQ35UgQ== + +chartjs-adapter-date-fns@2.0.0: + version "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-zoom@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/chartjs-plugin-zoom/-/chartjs-plugin-zoom-1.1.1.tgz#8a28923a17fcb5eb57a0dc94c5113bf402677647" + integrity sha512-1q54WOzK7FtAjkbemQeqvmFUV0btNYIQny2HbQ6Awq9wUtCz7Zmj6vIgp3C1DYMQwN0nqgpC3vnApqiwI7cSdQ== + dependencies: + hammerjs "^2.0.8" + +cheerio-httpcli@0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/cheerio-httpcli/-/cheerio-httpcli-0.8.2.tgz#0189bda71c8bd2852de78e154291e2288184fbf2" + integrity sha512-grIzTwQg/nE7Oy6VvL19pf0UlM6wiluy/AOpXfQLVFrSi21F8wnO3dLchtaH2hfMF6jz68ot0/ngyQQVrp2VTw== + dependencies: + "@types/cheerio" "0.22.18" + "@types/rsvp" "^4.0.4" + async "^3.2.0" + cheerio "^0.22.0" + colors "^1.4.0" + foreach "^2.0.5" + he "^1.2.0" + iconv-lite "^0.6.3" + import-fresh "^3.3.0" + jschardet "^3.0.0" + object-assign "^4.1.1" + os-locale "^5.0.0" + prettyjson "^1.2.1" + request "^2.88.2" + rsvp "^4.8.5" + tough-cookie "^2.5.0" + type-of "^2.0.1" + valid-url "^1.0.9" + +cheerio@^0.22.0: + version "0.22.0" + resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-0.22.0.tgz#a9baa860a3f9b595a6b81b1a86873121ed3a269e" + integrity sha1-qbqoYKP5tZWmuBsahocxIe06Jp4= + dependencies: + css-select "~1.2.0" + dom-serializer "~0.1.0" + entities "~1.1.1" + htmlparser2 "^3.9.1" + lodash.assignin "^4.0.9" + lodash.bind "^4.1.4" + lodash.defaults "^4.0.1" + lodash.filter "^4.4.0" + lodash.flatten "^4.2.0" + lodash.foreach "^4.3.0" + lodash.map "^4.4.0" + lodash.merge "^4.4.0" + lodash.pick "^4.2.1" + lodash.reduce "^4.4.0" + lodash.reject "^4.4.0" + lodash.some "^4.4.0" + +chokidar@3.5.1, chokidar@^3.3.1, chokidar@^3.5.0: + version "3.3.1" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.3.1.tgz#c84e5b3d18d9a4d77558fef466b1bf16bbeb3450" + integrity sha512-4QYCEWOcK3OJrxwvyyAOxFuhpvOVCYkr33LPfFNBjAD/w3sEzWsp2BUOkI4l9bHvWioAd0rc6NlHUOEaWkTeqg== + dependencies: + anymatch "~3.1.1" + braces "~3.0.2" + glob-parent "~5.1.0" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.3.0" + optionalDependencies: + fsevents "~2.1.2" + +chownr@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== + +chownr@^2.0.0: + version "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" + integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== + +cli-highlight@2.1.11, cli-highlight@^2.1.11: + version "2.1.11" + resolved "https://registry.yarnpkg.com/cli-highlight/-/cli-highlight-2.1.11.tgz#49736fa452f0aaf4fae580e30acb26828d2dc1bf" + integrity sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg== + dependencies: + chalk "^4.0.0" + highlight.js "^10.7.1" + mz "^2.4.0" + parse5 "^5.1.1" + parse5-htmlparser2-tree-adapter "^6.0.0" + yargs "^16.0.0" + +cliui@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" + integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== + dependencies: + string-width "^3.1.0" + strip-ansi "^5.2.0" + wrap-ansi "^5.1.0" + +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + +clone-response@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" + integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws= + dependencies: + mimic-response "^1.0.0" + +cluster-key-slot@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.1.0.tgz#30474b2a981fb12172695833052bc0d01336d10d" + integrity sha512-2Nii8p3RwAPiFwsnZvukotvow2rIHM+yQ6ZcBXGHdniadkYGZYiGmkHJIbZPIV9nfv7m/U1IPMVVcAhoWFeklw== + +co-body@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/co-body/-/co-body-5.2.0.tgz#5a0a658c46029131e0e3a306f67647302f71c124" + integrity sha512-sX/LQ7LqUhgyaxzbe7IqwPeTr2yfpfUIQ/dgpKo6ZI4y4lpQA0YxAomWIY+7I7rHWcG02PG+OuPREzMW/5tszQ== + dependencies: + inflation "^2.0.0" + qs "^6.4.0" + raw-body "^2.2.0" + type-is "^1.6.14" + +co-body@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/co-body/-/co-body-6.0.0.tgz#965b9337d7f5655480787471f4237664820827e3" + integrity sha512-9ZIcixguuuKIptnY8yemEOuhb71L/lLf+Rl5JfJEUiDNJk0e02MBt7BPxR2GEh5mw8dPthQYR4jPI/BnS1MQgw== + dependencies: + inflation "^2.0.0" + qs "^6.5.2" + raw-body "^2.3.3" + type-is "^1.6.16" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +color-name@^1.0.0, color-name@~1.1.4: + version "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== + dependencies: + color-name "^1.0.0" + simple-swizzle "^0.2.2" + +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== + dependencies: + color-convert "^2.0.1" + color-string "^1.6.0" + +colord@^2.9.1: + version "2.9.1" + resolved "https://registry.yarnpkg.com/colord/-/colord-2.9.1.tgz#c961ea0efeb57c9f0f4834458f26cb9cc4a3f90e" + integrity sha512-4LBMSt09vR0uLnPVkOUBnmxgoaeN4ewRbx801wY/bXcltXfpR/G46OdWn96XpYmCWuYvO46aBZP4NgX8HpNAcw== + +colorette@^1.2.0, colorette@^1.2.1, colorette@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" + integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w== + +colors@^1.1.2, colors@^1.3.3, colors@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" + integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== + +combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +commander@^2.19.0, commander@^2.20.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== + +commander@^6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" + integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== + +commander@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" + integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== + +comment-json@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/comment-json/-/comment-json-4.1.1.tgz#49df4948704bebb1cc0ffa6910e25669b668b7c5" + integrity sha512-v8gmtPvxhBlhdRBLwdHSjGy9BgA23t9H1FctdQKyUrErPjSrJcdDMqBq9B4Irtm7w3TNYLQJNH6ARKnpyag1sA== + dependencies: + array-timsort "^1.0.3" + core-util-is "^1.0.2" + esprima "^4.0.1" + has-own-prop "^2.0.0" + repeat-string "^1.6.1" + +compare-versions@3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-3.6.0.tgz#1a5689913685e5a87637b8d3ffca75514ec41d62" + integrity sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +concat-stream@^1.5.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +concurrently@6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-6.3.0.tgz#63128cb4a6ed54d3c0ed8528728590a5fe54582a" + integrity sha512-k4k1jQGHHKsfbqzkUszVf29qECBrkvBKkcPJEUDTyVR7tZd1G/JOfnst4g1sYbFvJ4UjHZisj1aWQR8yLKpGPw== + dependencies: + chalk "^4.1.0" + date-fns "^2.16.1" + lodash "^4.17.21" + rxjs "^6.6.3" + spawn-command "^0.0.2-1" + supports-color "^8.1.0" + tree-kill "^1.2.2" + yargs "^16.2.0" + +condense-newlines@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/condense-newlines/-/condense-newlines-0.2.1.tgz#3de985553139475d32502c83b02f60684d24c55f" + integrity sha1-PemFVTE5R10yUCyDsC9gaE0kxV8= + dependencies: + extend-shallow "^2.0.1" + is-whitespace "^0.3.0" + kind-of "^3.0.2" + +config-chain@^1.1.12: + version "1.1.12" + resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.12.tgz#0fde8d091200eb5e808caf25fe618c02f48e4efa" + integrity sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA== + dependencies: + ini "^1.3.4" + proto-list "~1.2.1" + +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= + +consolidate@^0.16.0: + version "0.16.0" + resolved "https://registry.yarnpkg.com/consolidate/-/consolidate-0.16.0.tgz#a11864768930f2f19431660a65906668f5fbdc16" + integrity sha512-Nhl1wzCslqXYTJVDyJCu3ODohy9OfBMB5uD2BiBTzd7w+QY0lBzafkR8y8755yMYHAaMD4NuzbAw03/xzfw+eQ== + dependencies: + bluebird "^3.7.2" + +constantinople@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/constantinople/-/constantinople-4.0.1.tgz#0def113fa0e4dc8de83331a5cf79c8b325213151" + integrity sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw== + dependencies: + "@babel/parser" "^7.6.0" + "@babel/types" "^7.6.1" + +content-disposition@0.5.3, content-disposition@~0.5.2: + version "0.5.3" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" + integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== + dependencies: + safe-buffer "5.1.2" + +content-type@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + +cookies@~0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/cookies/-/cookies-0.8.0.tgz#1293ce4b391740a8406e3c9870e828c4b54f3f90" + integrity sha512-8aPsApQfebXnuI+537McwYsDtjVxGm8gTIzQI3FDW6t5t/DAhERxtnbEPN/8RX+uZthoz4eCOgloXaE5cYyNow== + dependencies: + depd "~2.0.0" + keygrip "~1.1.0" + +copy-to@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/copy-to/-/copy-to-2.0.1.tgz#2680fbb8068a48d08656b6098092bdafc906f4a5" + integrity sha1-JoD7uAaKSNCGVrYJgJK9r8kG9KU= + +core-util-is@1.0.2, core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + +core-util-is@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + +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== + dependencies: + exit-on-epipe "~1.0.1" + printj "~1.1.0" + +create-require@^1.1.0: + version "1.1.1" + 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== + dependencies: + is-nan "^1.2.1" + moment-timezone "^0.5.25" + +cross-env@7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf" + integrity sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw== + dependencies: + cross-spawn "^7.0.1" + +cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.2: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +css-color-names@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-1.0.1.tgz#6ff7ee81a823ad46e020fa2fd6ab40a887e2ba67" + integrity sha512-/loXYOch1qU1biStIFsHH8SxTmOseh1IJqFvy8IujXOm1h+QjUdDhkzOrR5HG8K8mlxREj0yfi8ewCHx0eMxzA== + +css-declaration-sorter@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.0.3.tgz#9dfd8ea0df4cc7846827876fafb52314890c21a9" + integrity sha512-52P95mvW1SMzuRZegvpluT6yEv0FqQusydKQPZsNN5Q7hh8EwQvN8E2nwuJ16BBvNN6LcoIZXu/Bk58DAhrrxw== + dependencies: + timsort "^0.3.0" + +css-loader@6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.5.1.tgz#0c43d4fbe0d97f699c91e9818cb585759091d1b1" + integrity sha512-gEy2w9AnJNnD9Kuo4XAP9VflW/ujKoS9c/syO+uWMlm5igc7LysKzPXaDoR2vroROkSwsTS2tGr1yGGEbZOYZQ== + dependencies: + icss-utils "^5.1.0" + postcss "^8.2.15" + postcss-modules-extract-imports "^3.0.0" + postcss-modules-local-by-default "^4.0.0" + postcss-modules-scope "^3.0.0" + postcss-modules-values "^4.0.0" + postcss-value-parser "^4.1.0" + semver "^7.3.5" + +css-select@^4.1.3: + version "4.1.3" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.1.3.tgz#a70440f70317f2669118ad74ff105e65849c7067" + integrity sha512-gT3wBNd9Nj49rAbmtFHj1cljIAOLYSX1nZ8CB7TBO3INYckygm5B7LISU/szY//YmdiSLbJvDLOx9VnMVpMBxA== + dependencies: + boolbase "^1.0.0" + css-what "^5.0.0" + domhandler "^4.2.0" + domutils "^2.6.0" + nth-check "^2.0.0" + +css-select@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858" + integrity sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg= + dependencies: + boolbase "~1.0.0" + css-what "2.1" + domutils "1.5.1" + nth-check "~1.0.1" + +css-tree@^1.1.2, css-tree@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d" + integrity sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q== + dependencies: + mdn-data "2.0.14" + source-map "^0.6.1" + +css-what@2.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2" + integrity sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg== + +css-what@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-5.1.0.tgz#3f7b707aadf633baf62c2ceb8579b545bb40f7fe" + integrity sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw== + +cssesc@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" + integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== + +cssnano-preset-default@^5.1.6: + version "5.1.6" + resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-5.1.6.tgz#1bdb83be6a6b1fee6dc5e9ec2e61286bcadcc7a6" + integrity sha512-X2nDeNGBXc0486oHjT2vSj+TdeyVsxRvJUxaOH50hOM6vSDLkKd0+59YXpSZRInJ4sNtBOykS4KsPfhdrU/35w== + dependencies: + css-declaration-sorter "^6.0.3" + cssnano-utils "^2.0.1" + postcss-calc "^8.0.0" + postcss-colormin "^5.2.1" + postcss-convert-values "^5.0.2" + postcss-discard-comments "^5.0.1" + postcss-discard-duplicates "^5.0.1" + postcss-discard-empty "^5.0.1" + postcss-discard-overridden "^5.0.1" + postcss-merge-longhand "^5.0.3" + postcss-merge-rules "^5.0.2" + postcss-minify-font-values "^5.0.1" + postcss-minify-gradients "^5.0.3" + postcss-minify-params "^5.0.1" + postcss-minify-selectors "^5.1.0" + postcss-normalize-charset "^5.0.1" + postcss-normalize-display-values "^5.0.1" + postcss-normalize-positions "^5.0.1" + postcss-normalize-repeat-style "^5.0.1" + postcss-normalize-string "^5.0.1" + postcss-normalize-timing-functions "^5.0.1" + postcss-normalize-unicode "^5.0.1" + postcss-normalize-url "^5.0.2" + postcss-normalize-whitespace "^5.0.1" + postcss-ordered-values "^5.0.2" + postcss-reduce-initial "^5.0.1" + postcss-reduce-transforms "^5.0.1" + postcss-svgo "^5.0.3" + postcss-unique-selectors "^5.0.1" + +cssnano-utils@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/cssnano-utils/-/cssnano-utils-2.0.1.tgz#8660aa2b37ed869d2e2f22918196a9a8b6498ce2" + integrity sha512-i8vLRZTnEH9ubIyfdZCAdIdgnHAUeQeByEeQ2I7oTilvP9oHO6RScpeq3GsFUVqeB8uZgOQ9pw8utofNn32hhQ== + +cssnano@5.0.10: + version "5.0.10" + resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-5.0.10.tgz#92207eb7c9c6dc08d318050726f9fad0adf7220b" + integrity sha512-YfNhVJJ04imffOpbPbXP2zjIoByf0m8E2c/s/HnvSvjXgzXMfgopVjAEGvxYOjkOpWuRQDg/OZFjO7WW94Ri8w== + dependencies: + cssnano-preset-default "^5.1.6" + is-resolvable "^1.1.0" + lilconfig "^2.0.3" + yaml "^1.10.2" + +csso@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/csso/-/csso-4.2.0.tgz#ea3a561346e8dc9f546d6febedd50187cf389529" + integrity sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA== + dependencies: + css-tree "^1.1.2" + +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.3.6: + version "0.3.8" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" + integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== + +cssstyle@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-2.3.0.tgz#ff665a0ddbdc31864b09647f34163443d90b0852" + integrity sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A== + dependencies: + cssom "~0.3.6" + +d@1, d@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" + integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== + dependencies: + es5-ext "^0.10.50" + type "^1.0.1" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= + dependencies: + assert-plus "^1.0.0" + +data-uri-to-buffer@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz#594b8973938c5bc2c33046535785341abc4f3636" + integrity sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og== + +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== + dependencies: + abab "^2.0.3" + whatwg-mimetype "^2.3.0" + whatwg-url "^8.0.0" + +date-fns@2.25.0: + version "2.25.0" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.25.0.tgz#8c5c8f1d958be3809a9a03f4b742eba894fc5680" + integrity sha512-ovYRFnTrbGPD4nqaEqescPEv1mNwvt+UTqI3Ay9SzNtey9NZnYu6E2qCcBBgJ6/2VF1zGGygpyTDITqpQQ5e+w== + +date-fns@^2.16.1: + version "2.19.0" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.19.0.tgz#65193348635a28d5d916c43ec7ce6fbd145059e1" + integrity sha512-X3bf2iTPgCAQp9wvjOQytnf5vO5rESYRXlPIVcgSbtT5OTScPcsf9eZU+B/YIkKAtYr5WeCii58BgATrNitlWg== + +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== + +debug@2, debug@^2.2.0, debug@^2.5.2, debug@^2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@4, debug@4.3.1, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" + integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== + dependencies: + ms "2.1.2" + +debug@4.3.2, debug@^4.3.2: + version "4.3.2" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" + integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== + dependencies: + ms "2.1.2" + +debug@=3.1.0, debug@~3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== + dependencies: + ms "2.0.0" + +debug@^3.2.6: + version "3.2.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== + dependencies: + ms "^2.1.1" + +debug@^3.2.7: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + +debuglog@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" + integrity sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI= + +decamelize@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + +decamelize@^4.0.0: + version "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== + +decompress-response@^4.2.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-4.2.1.tgz#414023cc7a302da25ce2ec82d0d5238ccafd8986" + integrity sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw== + dependencies: + mimic-response "^2.0.0" + +decompress-response@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" + integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== + dependencies: + mimic-response "^3.1.0" + +deep-email-validator@0.1.18: + version "0.1.18" + resolved "https://registry.yarnpkg.com/deep-email-validator/-/deep-email-validator-0.1.18.tgz#a072a93f28e11863cc6b9ca3ae964e0e45b3ece8" + integrity sha512-eo2WEUidQvppg6Qdek8iwOqmXvaxRJ2D2VJKbIOwUgLZNFveDDdJMBsFc+yq0S+lILEUcmzrJRrCWbyoe7QUzQ== + dependencies: + "@types/disposable-email-domains" "^1.0.1" + axios "^0.19.2" + disposable-email-domains "^1.0.53" + lodash "^4.17.15" + mailcheck "^1.1.1" + ts-jest "^25.2.1" + +deep-equal@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" + integrity sha1-9dJgKStmDghO/0zbyfCK0yR0SLU= + +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + +deep-is@^0.1.3, deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= + +deepmerge@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" + integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== + +defer-to-connect@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.0.tgz#83d6b199db041593ac84d781b5222308ccf4c2c1" + integrity sha512-bYL2d05vOSf1JEZNx5vSAtPuBMkX8K9EUutg7zlKvTqKXHt7RhWJFbmd7qakVuf13i+IkGmp6FwSsONOf6VYIg== + +define-properties@^1.1.2, define-properties@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= + +denque@^1.1.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/denque/-/denque-1.4.1.tgz#6744ff7641c148c3f8a69c307e51235c1f4a37cf" + integrity sha512-OfzPuSZKGcgr96rf1oODnfjqBFmr1DVoc/TrItj3Ohe0Ah1C5WX5Baquw/9U9KovnQ88EqmJbD66rKYUQYN1tQ== + +denque@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/denque/-/denque-1.5.0.tgz#773de0686ff2d8ec2ff92914316a47b73b1c73de" + integrity sha512-CYiCSgIF1p6EUByQPlGkKnP1M9g0ZV3qMIrqMqZqdwazygIA/YP2vrbcyl1h/WppKJTdl1F85cXIle+394iDAQ== + +depd@^1.1.2, depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= + +depd@^2.0.0, depd@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + +destroy@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= + +detect-file@^1.0.0: + version "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-node@2.1.0, detect-node@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" + integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== + +dicer@0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/dicer/-/dicer-0.2.5.tgz#5996c086bb33218c812c090bddc09cd12facb70f" + integrity sha1-WZbAhrszIYyBLAkL3cCc0S+stw8= + dependencies: + readable-stream "1.1.x" + streamsearch "0.1.2" + +diff@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" + integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== + +diff@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + +dijkstrajs@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/dijkstrajs/-/dijkstrajs-1.0.1.tgz#d3cd81221e3ea40742cfcde556d4e99e98ddc71b" + integrity sha1-082BIh4+pAdCz83lVtTpnpjdxxs= + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +disposable-email-domains@^1.0.53: + version "1.0.58" + resolved "https://registry.yarnpkg.com/disposable-email-domains/-/disposable-email-domains-1.0.58.tgz#ac9c879c02c4f0898bfb6c0c80b959c0b0b7bc51" + integrity sha512-frnNCPqTjk6t/sosPoco6EIFHbP9SazHQkeltJNfZeUyNgewaVf+kFjEfVkVDVd436Vln43YElJPb8JozhBs7Q== + +doctrine@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" + integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== + dependencies: + esutils "^2.0.2" + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + +doctypes@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/doctypes/-/doctypes-1.1.0.tgz#ea80b106a87538774e8a3a4a5afe293de489e0a9" + integrity sha1-6oCxBqh1OHdOijpKWv4pPeSJ4Kk= + +dom-serializer@0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51" + integrity sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g== + dependencies: + domelementtype "^2.0.1" + entities "^2.0.0" + +dom-serializer@^1.0.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.3.1.tgz#d845a1565d7c041a95e5dab62184ab41e3a519be" + integrity sha512-Pv2ZluG5ife96udGgEDovOOOA5UELkltfJpnIExPrAk1LTvecolUGn6lIaoLh86d83GiB86CjzciMd9BuRB71Q== + dependencies: + domelementtype "^2.0.1" + domhandler "^4.0.0" + entities "^2.0.0" + +dom-serializer@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.1.tgz#1ec4059e284babed36eec2941d4a970a189ce7c0" + integrity sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA== + dependencies: + domelementtype "^1.3.0" + entities "^1.1.1" + +domelementtype@1, domelementtype@^1.3.0, domelementtype@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" + integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== + +domelementtype@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.0.1.tgz#1f8bdfe91f5a78063274e803b4bdcedf6e94f94d" + integrity sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ== + +domelementtype@^2.2.0: + version "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== + dependencies: + webidl-conversions "^5.0.0" + +domhandler@^2.3.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803" + integrity sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA== + dependencies: + domelementtype "1" + +domhandler@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.1.0.tgz#c1d8d494d5ec6db22de99e46a149c2a4d23ddd43" + integrity sha512-/6/kmsGlMY4Tup/nGVutdrK9yQi4YjWVcVeoQmixpzjOUK1U7pQkvAPHBJeUxOgxF0J8f8lwCJSlCfD0V4CMGQ== + dependencies: + domelementtype "^2.2.0" + +domhandler@^4.2.0: + version "4.2.2" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.2.2.tgz#e825d721d19a86b8c201a35264e226c678ee755f" + integrity sha512-PzE9aBMsdZO8TK4BnuJwH0QT41wgMbRzuZrHUcpYncEjmQazq8QEaBWgLG7ZyC/DAZKEgglpIA6j4Qn/HmxS3w== + dependencies: + domelementtype "^2.2.0" + +domutils@1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" + integrity sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8= + dependencies: + dom-serializer "0" + domelementtype "1" + +domutils@^1.5.1: + version "1.7.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" + integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg== + dependencies: + dom-serializer "0" + domelementtype "1" + +domutils@^2.5.2, domutils@^2.6.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135" + integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A== + dependencies: + dom-serializer "^1.0.1" + domelementtype "^2.2.0" + domhandler "^4.2.0" + +dotenv@^8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a" + integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw== + +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + +ecdsa-sig-formatter@1.0.11: + version "1.0.11" + resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf" + integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ== + dependencies: + safe-buffer "^5.0.1" + +editorconfig@^0.15.3: + version "0.15.3" + resolved "https://registry.yarnpkg.com/editorconfig/-/editorconfig-0.15.3.tgz#bef84c4e75fb8dcb0ce5cee8efd51c15999befc5" + integrity sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g== + dependencies: + commander "^2.19.0" + lru-cache "^4.1.5" + semver "^5.6.0" + sigmund "^1.0.1" + +ee-first@1.1.1: + version "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== + +electron-to-chromium@^1.3.712: + version "1.3.717" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.717.tgz#78d4c857070755fb58ab64bcc173db1d51cbc25f" + integrity sha512-OfzVPIqD1MkJ7fX+yTl2nKyOE4FReeVfMCzzxQS+Kp43hZYwHwThlGP+EGIZRXJsxCM7dqo8Y65NOX/HP12iXQ== + +electron-to-chromium@^1.3.723: + version "1.3.742" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.742.tgz#7223215acbbd3a5284962ebcb6df85d88b95f200" + integrity sha512-ihL14knI9FikJmH2XUIDdZFWJxvr14rPSdOhJ7PpS27xbz8qmaRwCwyg/bmFwjWKmWK9QyamiCZVCvXm5CH//Q== + +emoji-regex@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +emojis-list@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" + integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== + +encodeurl@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= + +encoding@^0.1.12: + version "0.1.13" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" + integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== + dependencies: + iconv-lite "^0.6.2" + +end-of-stream@^1.1.0, end-of-stream@^1.4.1: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + +enhanced-resolve@^5.0.0: + version "5.8.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.8.0.tgz#d9deae58f9d3773b6a111a5a46831da5be5c9ac0" + integrity sha512-Sl3KRpJA8OpprrtaIswVki3cWPiPKxXuFxJXBp+zNb6s6VwNWwFRUdtmzd2ReUut8n+sCPx7QCtQ7w5wfJhSgQ== + dependencies: + 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" + +enquirer@^2.3.5: + version "2.3.6" + resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" + integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== + dependencies: + ansi-colors "^4.1.1" + +entities@^1.1.1, entities@~1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" + integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== + +entities@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.0.tgz#68d6084cab1b079767540d80e56a39b423e4abf4" + integrity sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw== + +env-paths@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.0.tgz#cdca557dc009152917d6166e2febe1f039685e43" + integrity sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA== + +err-code@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9" + integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA== + +es-abstract@^1.17.0-next.0, es-abstract@^1.17.0-next.1, es-abstract@^1.17.2, es-abstract@^1.17.5: + version "1.17.5" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.5.tgz#d8c9d1d66c8981fb9200e2251d799eee92774ae9" + integrity sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg== + dependencies: + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + is-callable "^1.1.5" + is-regex "^1.0.5" + object-inspect "^1.7.0" + object-keys "^1.1.1" + object.assign "^4.1.0" + string.prototype.trimleft "^2.1.1" + string.prototype.trimright "^2.1.1" + +es-abstract@^1.19.0, es-abstract@^1.19.1: + version "1.19.1" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.19.1.tgz#d4885796876916959de78edaa0df456627115ec3" + integrity sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w== + dependencies: + call-bind "^1.0.2" + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + get-intrinsic "^1.1.1" + get-symbol-description "^1.0.0" + has "^1.0.3" + has-symbols "^1.0.2" + internal-slot "^1.0.3" + is-callable "^1.2.4" + is-negative-zero "^2.0.1" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.1" + is-string "^1.0.7" + is-weakref "^1.0.1" + object-inspect "^1.11.0" + object-keys "^1.1.1" + object.assign "^4.1.2" + string.prototype.trimend "^1.0.4" + 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" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + +es5-ext@^0.10.35, es5-ext@^0.10.50: + version "0.10.53" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.53.tgz#93c5a3acfdbef275220ad72644ad02ee18368de1" + integrity sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q== + dependencies: + es6-iterator "~2.0.3" + es6-symbol "~3.1.3" + next-tick "~1.0.0" + +es6-iterator@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c= + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + +es6-symbol@^3.1.1, es6-symbol@~3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" + integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== + dependencies: + d "^1.0.1" + ext "^1.1.2" + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-html@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= + +escape-regexp@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/escape-regexp/-/escape-regexp-0.0.1.tgz#f44bda12d45bbdf9cb7f862ee7e4827b3dd32254" + integrity sha1-9EvaEtRbvfnLf4Yu5+SCez3TIlQ= + +escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +escodegen@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.0.0.tgz#5e32b12833e8aa8fa35e1bf0befa89380484c7dd" + integrity sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw== + dependencies: + esprima "^4.0.1" + estraverse "^5.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + +eslint-import-resolver-node@^0.3.6: + version "0.3.6" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz#4048b958395da89668252001dbd9eca6b83bacbd" + integrity sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw== + dependencies: + debug "^3.2.7" + resolve "^1.20.0" + +eslint-module-utils@^2.7.1: + version "2.7.1" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.7.1.tgz#b435001c9f8dd4ab7f6d0efcae4b9696d4c24b7c" + integrity sha512-fjoetBXQZq2tSTWZ9yWVl2KuFrTZZH3V+9iD1V1RfpDgxzJR+mPd/KZmMiA8gbPqdBzpNiEHOuT7IYEWxrH0zQ== + dependencies: + debug "^3.2.7" + find-up "^2.1.0" + pkg-dir "^2.0.0" + +eslint-plugin-import@2.25.3: + version "2.25.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.25.3.tgz#a554b5f66e08fb4f6dc99221866e57cfff824766" + integrity sha512-RzAVbby+72IB3iOEL8clzPLzL3wpDrlwjsTBAQXgyp5SeTqqY+0bFubwuo+y/HLhNZcXV4XqTBO4LGsfyHIDXg== + dependencies: + array-includes "^3.1.4" + array.prototype.flat "^1.2.5" + debug "^2.6.9" + doctrine "^2.1.0" + eslint-import-resolver-node "^0.3.6" + eslint-module-utils "^2.7.1" + has "^1.0.3" + is-core-module "^2.8.0" + is-glob "^4.0.3" + minimatch "^3.0.4" + object.values "^1.1.5" + resolve "^1.20.0" + tsconfig-paths "^3.11.0" + +eslint-plugin-vue@8.0.3: + version "8.0.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-vue/-/eslint-plugin-vue-8.0.3.tgz#791cc4543940319e612ea61a1d779e8c87cf749a" + integrity sha512-Rlhhy5ltzde0sRwSkqHuNePTXLMMaJ5+qsQubM4RYloYsQ8cXlnJT5MDaCzSirkGADipOHtmQXIbbPFAzUrADg== + dependencies: + eslint-utils "^3.0.0" + natural-compare "^1.4.0" + semver "^7.3.5" + vue-eslint-parser "^8.0.1" + +eslint-scope@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + +eslint-scope@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-6.0.0.tgz#9cf45b13c5ac8f3d4c50f46a5121f61b3e318978" + integrity sha512-uRDL9MWmQCkaFus8RF5K9/L/2fn+80yoW3jkD53l4shjCh26fCtvJGasxjUqP5OT87SYTxCVA3BwTUzuELx9kA== + dependencies: + esrecurse "^4.3.0" + estraverse "^5.2.0" + +eslint-utils@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672" + integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== + dependencies: + eslint-visitor-keys "^2.0.0" + +eslint-visitor-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz#21fdc8fbcd9c795cc0321f0563702095751511a8" + integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ== + +eslint-visitor-keys@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.0.0.tgz#e32e99c6cdc2eb063f204eda5db67bfe58bb4186" + integrity sha512-mJOZa35trBTb3IyRmo8xmKBZlxf+N7OnUl4+ZhJHs/r+0770Wh/LEACE2pqMGMe27G/4y8P2bYGk4J70IC5k1Q== + +eslint@8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.2.0.tgz#44d3fb506d0f866a506d97a0fc0e90ee6d06a815" + integrity sha512-erw7XmM+CLxTOickrimJ1SiF55jiNlVSp2qqm0NuBWPtHYQCegD5ZMaW0c3i5ytPqL+SSLaCxdvQXFPLJn+ABw== + dependencies: + "@eslint/eslintrc" "^1.0.4" + "@humanwhocodes/config-array" "^0.6.0" + ajv "^6.10.0" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.3.2" + doctrine "^3.0.0" + enquirer "^2.3.5" + escape-string-regexp "^4.0.0" + eslint-scope "^6.0.0" + eslint-utils "^3.0.0" + eslint-visitor-keys "^3.0.0" + espree "^9.0.0" + esquery "^1.4.0" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" + functional-red-black-tree "^1.0.1" + glob-parent "^6.0.1" + globals "^13.6.0" + ignore "^4.0.6" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + js-yaml "^4.1.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash.merge "^4.6.2" + minimatch "^3.0.4" + natural-compare "^1.4.0" + optionator "^0.9.1" + progress "^2.0.0" + regexpp "^3.2.0" + semver "^7.2.1" + strip-ansi "^6.0.1" + strip-json-comments "^3.1.0" + text-table "^0.2.0" + v8-compile-cache "^2.0.3" + +esm@^3.2.22: + version "3.2.25" + resolved "https://registry.yarnpkg.com/esm/-/esm-3.2.25.tgz#342c18c29d56157688ba5ce31f8431fbb795cc10" + integrity sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA== + +espree@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.0.0.tgz#e90a2965698228502e771c7a58489b1a9d107090" + integrity sha512-r5EQJcYZ2oaGbeR0jR0fFVijGOcwai07/690YRXLINuhmVeRY4UKSAsQPe/0BNuDgwP7Ophoc1PRsr2E3tkbdQ== + dependencies: + acorn "^8.5.0" + acorn-jsx "^5.3.1" + eslint-visitor-keys "^3.0.0" + +esprima@^4.0.0, esprima@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esquery@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" + integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== + dependencies: + estraverse "^5.1.0" + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.1.0.tgz#374309d39fd935ae500e7b92e8a6b4c720e59642" + integrity sha512-FyohXK+R0vE+y1nHLoBM7ZTyqRpqAlhdZHCWIWEviFLiGB8b04H6bQs8G+XTthacvT8VuwvteiP7RJSxMs8UEw== + +estraverse@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" + integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +event-target-shim@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" + integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== + +eventemitter3@4.0.7, eventemitter3@^4.0.7: + version "4.0.7" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== + +events@1.1.1: + version "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@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-4.1.0.tgz#4e5491ad1572f2f17a77d388c6c857135b22847a" + integrity sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA== + dependencies: + cross-spawn "^7.0.0" + get-stream "^5.0.0" + human-signals "^1.1.1" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.0" + onetime "^5.1.0" + signal-exit "^3.0.2" + strip-final-newline "^2.0.0" + +exit-on-epipe@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz#0bdd92e87d5285d267daa8171d0eb06159689692" + integrity sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw== + +expand-template@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" + integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== + +expand-tilde@^2.0.0, expand-tilde@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" + integrity sha1-l+gBqgUt8CRU3kawK/YhZCzchQI= + dependencies: + homedir-polyfill "^1.0.1" + +ext@^1.1.2: + version "1.4.0" + resolved "https://registry.yarnpkg.com/ext/-/ext-1.4.0.tgz#89ae7a07158f79d35517882904324077e4379244" + integrity sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A== + dependencies: + type "^2.0.0" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= + dependencies: + is-extendable "^0.1.0" + +extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= + +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= + +fast-deep-equal@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4" + integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA== + +fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-glob@^3.1.1: + version "3.2.4" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.4.tgz#d20aefbf99579383e7f3cc66529158c9b98554d3" + integrity sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.0" + merge2 "^1.3.0" + micromatch "^4.0.2" + picomatch "^2.2.1" + +fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + +fast-xml-parser@^3.19.0: + version "3.19.0" + resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-3.19.0.tgz#cb637ec3f3999f51406dd8ff0e6fc4d83e520d01" + integrity sha512-4pXwmBplsCPv8FOY1WRakF970TjNGnGnfbOnLqjlYvMiF1SR3yOHyxMR/YCXpPTOspNF5gwudqktIP4VsWkvBg== + +fastq@^1.6.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.8.0.tgz#550e1f9f59bbc65fe185cb6a9b4d95357107f481" + integrity sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q== + dependencies: + reusify "^1.0.4" + +feed@4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/feed/-/feed-4.2.2.tgz#865783ef6ed12579e2c44bbef3c9113bc4956a7e" + integrity sha512-u5/sxGfiMfZNtJ3OvQpXcvotFpYkL0n9u9mM2vkui2nGo8b4wvDkJ8gAkYqbA8QpGyFCv3RK0Z+Iv+9veCS9bQ== + dependencies: + xml-js "^1.6.11" + +fetch-blob@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/fetch-blob/-/fetch-blob-2.1.2.tgz#a7805db1361bd44c1ef62bb57fb5fe8ea173ef3c" + integrity sha512-YKqtUDwqLyfyMnmbw8XD6Q8j9i/HggKtPEI+pZ1+8bvheBu78biSmNaXWusx1TauGqtUUGx/cBb1mKdq2rLYow== + +file-entry-cache@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== + dependencies: + flat-cache "^3.0.4" + +file-type@16.5.3: + version "16.5.3" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-16.5.3.tgz#474b7e88c74724046abb505e9b8ed4db30c4fc06" + integrity sha512-uVsl7iFhHSOY4bEONLlTK47iAHtNsFHWP5YE4xJfZ4rnX7S1Q3wce09XgqSC7E/xh8Ncv/be1lNoyprlUH/x6A== + dependencies: + readable-web-to-node-stream "^3.0.0" + strtok3 "^6.2.4" + token-types "^4.1.1" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +find-node-modules@^2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/find-node-modules/-/find-node-modules-2.1.2.tgz#57565a3455baf671b835bc6b2134a9b938b9c53c" + integrity sha512-x+3P4mbtRPlSiVE1Qco0Z4YLU8WFiFcuWTf3m75OV9Uzcfs2Bg+O9N+r/K0AnmINBW06KpfqKwYJbFlFq4qNug== + dependencies: + findup-sync "^4.0.0" + merge "^2.1.0" + +find-up@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + +find-up@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= + dependencies: + locate-path "^2.0.0" + +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + +find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +findup-sync@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-4.0.0.tgz#956c9cdde804052b881b428512905c4a5f2cdef0" + integrity sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ== + dependencies: + detect-file "^1.0.0" + is-glob "^4.0.0" + micromatch "^4.0.2" + resolve-dir "^1.0.1" + +flat-cache@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" + integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== + dependencies: + flatted "^3.1.0" + rimraf "^3.0.2" + +flat@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" + integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== + +flatted@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.1.0.tgz#a5d06b4a8b01e3a63771daa5cb7a1903e2e57067" + integrity sha512-tW+UkmtNg/jv9CSofAKvgVcO7c2URjhTdW1ZTkcAritblu8tajiYy7YisnIflEwtKssCtOxpnBRoCB7iap0/TA== + +fluent-ffmpeg@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/fluent-ffmpeg/-/fluent-ffmpeg-2.1.2.tgz#c952de2240f812ebda0aa8006d7776ee2acf7d74" + integrity sha1-yVLeIkD4EuvaCqgAbXd27irPfXQ= + dependencies: + async ">=0.2.9" + which "^1.1.1" + +follow-redirects@1.5.10: + version "1.5.10" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a" + integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ== + dependencies: + debug "=3.1.0" + +foreach@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" + integrity sha1-C+4AUBiusmDQo6865ljdATbsG5k= + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= + +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== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + +form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + +fresh@~0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= + +fs-constants@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" + integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== + +fs-extra@^8.0.1: + version "8.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" + integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-minipass@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" + integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== + dependencies: + minipass "^3.0.0" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fsevents@~2.1.2: + version "2.1.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" + integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= + +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + +get-caller-file@^2.0.1, get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" + integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + +get-paths@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/get-paths/-/get-paths-0.0.7.tgz#15331086752077cf130166ccd233a1cdbeefcf38" + integrity sha512-0wdJt7C1XKQxuCgouqd+ZvLJ56FQixKoki9MrFaO4EriqzXOiH9gbukaDE1ou08S8Ns3/yDzoBAISNPqj6e6tA== + dependencies: + pify "^4.0.1" + +get-port@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/get-port/-/get-port-5.1.1.tgz#0469ed07563479de6efb986baf053dcd7d4e3193" + integrity sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ== + +get-stream@^5.0.0, get-stream@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" + integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== + dependencies: + pump "^3.0.0" + +get-symbol-description@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" + integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.1" + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= + dependencies: + assert-plus "^1.0.0" + +github-from-package@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" + integrity sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4= + +glob-parent@^5.1.0, glob-parent@~5.1.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" + integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ== + dependencies: + is-glob "^4.0.1" + +glob-parent@^6.0.1: + version "6.0.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== + 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" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" + integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +global-modules@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" + integrity sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg== + dependencies: + global-prefix "^1.0.1" + is-windows "^1.0.1" + resolve-dir "^1.0.0" + +global-prefix@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe" + integrity sha1-2/dDxsFJklk8ZVVoy2btMsASLr4= + dependencies: + expand-tilde "^2.0.2" + homedir-polyfill "^1.0.1" + ini "^1.3.4" + is-windows "^1.0.1" + which "^1.2.14" + +globals@^13.6.0: + version "13.7.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.7.0.tgz#aed3bcefd80ad3ec0f0be2cf0c895110c0591795" + integrity sha512-Aipsz6ZKRxa/xQkZhNg0qIWXT6x6rD46f6x/PCnBomlttdIyAPak4YD9jTmKpZ72uROSMU87qJtcgpgHaVchiA== + dependencies: + type-fest "^0.20.2" + +globals@^13.9.0: + version "13.9.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.9.0.tgz#4bf2bf635b334a173fb1daf7c5e6b218ecdc06cb" + integrity sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA== + dependencies: + type-fest "^0.20.2" + +globby@^11.0.2, globby@^11.0.4: + version "11.0.4" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.4.tgz#2cbaff77c2f2a62e71e9b2813a67b97a3a3001a5" + integrity sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.1.1" + ignore "^5.1.4" + merge2 "^1.3.0" + slash "^3.0.0" + +got@11.8.2: + version "11.8.2" + resolved "https://registry.yarnpkg.com/got/-/got-11.8.2.tgz#7abb3959ea28c31f3576f1576c1effce23f33599" + integrity sha512-D0QywKgIe30ODs+fm8wMZiAcZjypcCodPNuMz5H9Mny7RJ+IjJ10BdmGW7OM7fHXP+O7r6ZwapQ/YQmMSvB0UQ== + dependencies: + "@sindresorhus/is" "^4.0.0" + "@szmarczak/http-timer" "^4.0.5" + "@types/cacheable-request" "^6.0.1" + "@types/responselike" "^1.0.0" + cacheable-lookup "^5.0.3" + cacheable-request "^7.0.1" + decompress-response "^6.0.0" + http2-wrapper "^1.0.0-beta.5.2" + lowercase-keys "^2.0.0" + p-cancelable "^2.0.0" + responselike "^2.0.0" + +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.4: + version "4.2.4" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" + integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== + +graceful-fs@^4.2.0: + version "4.2.8" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a" + integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg== + +graceful-fs@^4.2.6: + version "4.2.6" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" + integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== + +growl@1.10.5: + version "1.10.5" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" + integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== + +hammerjs@^2.0.8: + version "2.0.8" + resolved "https://registry.yarnpkg.com/hammerjs/-/hammerjs-2.0.8.tgz#04ef77862cff2bb79d30f7692095930222bf60f1" + integrity sha1-BO93hiz/K7edMPdpIJWTAiK/YPE= + +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= + +har-validator@~5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" + integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== + dependencies: + ajv "^6.5.5" + har-schema "^2.0.0" + +has-bigints@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" + integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-own-prop@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-own-prop/-/has-own-prop-2.0.0.tgz#f0f95d58f65804f5d218db32563bb85b8e0417af" + integrity sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ== + +has-symbols@^1.0.0, has-symbols@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" + integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== + +has-symbols@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" + integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== + +has-tostringtag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" + integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== + dependencies: + has-symbols "^1.0.2" + +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +he@1.2.0, he@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +highlight.js@^10.7.1: + version "10.7.2" + resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.7.2.tgz#89319b861edc66c48854ed1e6da21ea89f847360" + integrity sha512-oFLl873u4usRM9K63j4ME9u3etNF0PLiJhSQ8rdfuL51Wn3zkD6drf9ZW0dOzjnZI22YYG24z30JcmfCZjMgYg== + +homedir-polyfill@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8" + integrity sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA== + dependencies: + parse-passwd "^1.0.0" + +hpagent@0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/hpagent/-/hpagent-0.1.2.tgz#cab39c66d4df2d4377dbd212295d878deb9bdaa9" + integrity sha512-ePqFXHtSQWAFXYmj+JtOTHr84iNrII4/QRlAAPPE+zqnKy4xJo7Ie1Y4kC7AdB+LxLxSTTzBMASsEcy0q8YyvQ== + +hpagent@^0.1.1: + version "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== + dependencies: + whatwg-encoding "^1.0.5" + +html-entities@2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.3.2.tgz#760b404685cb1d794e4f4b744332e3b00dcfe488" + integrity sha512-c3Ab/url5ksaT0WyleslpBEthOzWhrjQbg75y7XUsfSzi3Dgzt0l8w5e7DylRn15MTlMMD58dTfzddNS2kcAjQ== + +htmlparser2@^3.9.1: + version "3.10.1" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f" + integrity sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ== + dependencies: + domelementtype "^1.3.1" + domhandler "^2.3.0" + domutils "^1.5.1" + entities "^1.1.1" + inherits "^2.0.1" + readable-stream "^3.1.1" + +htmlparser2@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.1.0.tgz#c4d762b6c3371a05dbe65e94ae43a9f845fb8fb7" + integrity sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A== + dependencies: + domelementtype "^2.0.1" + domhandler "^4.0.0" + domutils "^2.5.2" + entities "^2.0.0" + +http-assert@^1.3.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/http-assert/-/http-assert-1.4.1.tgz#c5f725d677aa7e873ef736199b89686cceb37878" + integrity sha512-rdw7q6GTlibqVVbXr0CKelfV5iY8G2HqEUkhSk297BMbSpSL8crXC+9rjKoMcZZEsksX30le6f/4ul4E28gegw== + dependencies: + deep-equal "~1.0.1" + http-errors "~1.7.2" + +http-cache-semantics@^4.0.0, http-cache-semantics@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" + integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== + +http-errors@1.7.3, http-errors@^1.6.3, http-errors@^1.7.3, http-errors@~1.7.2: + version "1.7.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" + integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + +http-errors@~1.6.2: + version "1.6.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= + dependencies: + depd "~1.1.2" + inherits "2.0.3" + 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" + integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== + dependencies: + "@tootallnate/once" "1" + agent-base "6" + debug "4" + +http-signature@1.3.5: + version "1.3.5" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.3.5.tgz#9f19496ffbf3227298d7b5f156e0e1a948678683" + integrity sha512-NwoTQYSJoFt34jSBbwzDHDofoA61NGXzu6wXh95o1Ry62EnmKjXb/nR/RknLeZ3G/uGwrlKNY2z7uPt+Cdl7Tw== + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.14.1" + +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.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" + integrity sha512-bptAfCDdPJxOs5zYSe7Y3lpr772s1G346R4Td5LgRUeCwIGpCGDUTJxRrhTNcAXbx37spge0kWEIH7QAYWNTlA== + dependencies: + urlsafe-base64 "~1.0.0" + +https-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" + integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA== + dependencies: + agent-base "6" + debug "4" + +human-signals@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" + integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== + +humanize-ms@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" + integrity sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0= + dependencies: + ms "^2.0.0" + +humanize-number@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/humanize-number/-/humanize-number-0.0.2.tgz#11c0af6a471643633588588048f1799541489c18" + integrity sha1-EcCvakcWQ2M1iFiASPF5lUFInBg= + +iconv-lite@0.4.24, iconv-lite@^0.4.4: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +iconv-lite@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.2.tgz#ce13d1875b0c3a674bd6a04b7f76b01b1b6ded01" + integrity sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + +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" + +icss-utils@^5.0.0, icss-utils@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" + integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== + +idb-keyval@5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/idb-keyval/-/idb-keyval-5.1.3.tgz#6ef5dff371897c23f144322dc6374eadd6a345d9" + integrity sha512-N9HbCK/FaXSRVI+k6Xq4QgWxbcZRUv+SfG1y7HJ28JdV8yEJu6k+C/YLea7npGckX2DQJeEVuMc4bKOBeU/2LQ== + dependencies: + safari-14-idb-fix "^1.0.4" + +ieee754@1.1.13, ieee754@^1.1.4: + version "1.1.13" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" + integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== + +ieee754@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + +ignore@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== + +ignore@^5.1.4: + version "5.1.8" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" + integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== + +ignore@^5.1.8: + version "5.1.9" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.9.tgz#9ec1a5cbe8e1446ec60d4420060d43aa6e7382fb" + integrity sha512-2zeMQpbKz5dhZ9IwL0gbxSW5w0NK/MSAMtNuhgIHEPmaU3vPdKPL0UdvUCXs5SS4JAwsBxysK5sFMW8ocFiVjQ== + +import-fresh@^3.0.0, import-fresh@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66" + integrity sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +import-fresh@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + +indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== + +indexes-of@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" + integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc= + +infer-owner@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" + integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== + +inflation@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/inflation/-/inflation-2.0.0.tgz#8b417e47c28f925a45133d914ca1fd389107f30f" + integrity sha1-i0F+R8KPklpFEz2RTKH9OJEH8w8= + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +ini@^1.3.4, ini@~1.3.0: + version "1.3.7" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.7.tgz#a09363e1911972ea16d7a8851005d84cf09a9a84" + integrity sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ== + +insert-text-at-cursor@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/insert-text-at-cursor/-/insert-text-at-cursor-0.3.0.tgz#1819607680ec1570618347c4cd475e791faa25da" + integrity sha512-/nPtyeX9xPUvxZf+r0518B7uqNKlP+LqNJqSiXFEaa2T71rWIwTVXGH7hB9xO/EVdwa5/pWlFCPwShOW81XIxQ== + +install-artifact-from-github@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/install-artifact-from-github/-/install-artifact-from-github-1.2.0.tgz#adcbd123c16a4337ec44ea76d0ebf253cc16b074" + integrity sha512-3OxCPcY55XlVM3kkfIpeCgmoSKnMsz2A3Dbhsq0RXpIknKQmrX1YiznCeW9cD2ItFmDxziA3w6Eg8d80AoL3oA== + +internal-slot@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" + integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== + dependencies: + get-intrinsic "^1.1.0" + has "^1.0.3" + side-channel "^1.0.4" + +invert-kv@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-3.0.1.tgz#a93c7a3d4386a1dc8325b97da9bb1620c0282523" + integrity sha512-CYdFeFexxhv/Bcny+Q0BfOV+ltRlJcd4BBZBYFX/O0u4npJrgZtIcjokegtiSMAvlMTJ+Koq0GBCc//3bueQxw== + +ioredis@^4.27.0: + version "4.27.6" + resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-4.27.6.tgz#a53d427d3fe75fbd10ed7ad150ce00559df8dcf8" + integrity sha512-6W3ZHMbpCa8ByMyC1LJGOi7P2WiOKP9B3resoZOVLDhi+6dDBOW+KNsRq3yI36Hmnb2sifCxHX+YSarTeXh48A== + dependencies: + cluster-key-slot "^1.1.0" + debug "^4.3.1" + denque "^1.1.0" + lodash.defaults "^4.2.0" + lodash.flatten "^4.4.0" + p-map "^2.1.0" + redis-commands "1.7.0" + redis-errors "^1.2.0" + redis-parser "^3.0.0" + standard-as-callback "^2.1.0" + +ip-address@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/ip-address/-/ip-address-7.1.0.tgz#4a9c699e75b51cbeb18b38de8ed216efa1a490c5" + integrity sha512-V9pWC/VJf2lsXqP7IWJ+pe3P1/HCYGBMZrrnT62niLGjAfCbeiwXMUxaeHvnVlz19O27pvXP4azs+Pj/A0x+SQ== + dependencies: + jsbn "1.1.0" + sprintf-js "1.1.2" + +ip-cidr@3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/ip-cidr/-/ip-cidr-3.0.4.tgz#a915c47e00f47ea8d5f8ed662ea6161471c44375" + integrity sha512-pKNiqmBlTvEkhaLAa3+FOmYSY0/jjADVxxjA3NbujZZTT8mjLI90Q+6mwg6kd0fNm0RuAOkWJ1u1a/ETmlrPNQ== + dependencies: + ip-address "^7.1.0" + jsbn "^1.1.0" + +ip-regex@^4.0.0, ip-regex@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-4.3.0.tgz#687275ab0f57fa76978ff8f4dddc8a23d5990db5" + integrity sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q== + +ip@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" + integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= + +ipaddr.js@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.0.1.tgz#eca256a7a877e917aeb368b0a7497ddf42ef81c0" + integrity sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng== + +is-absolute-url@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-3.0.3.tgz#96c6a22b6a23929b11ea0afb1836c36ad4a5d698" + integrity sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q== + +is-arrayish@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" + integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== + +is-bigint@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" + integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== + dependencies: + has-bigints "^1.0.1" + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-boolean-object@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" + integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== + +is-callable@^1.1.4, is-callable@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.5.tgz#f7e46b596890456db74e7f6e976cb3273d06faab" + integrity sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q== + +is-callable@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" + integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w== + +is-core-module@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.2.0.tgz#97037ef3d52224d85163f5597b2b63d9afed981a" + integrity sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ== + dependencies: + has "^1.0.3" + +is-core-module@^2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.0.tgz#0321336c3d0925e497fd97f5d95cb114a5ccd548" + integrity sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw== + dependencies: + has "^1.0.3" + +is-date-object@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" + integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== + +is-expression@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-expression/-/is-expression-4.0.0.tgz#c33155962abf21d0afd2552514d67d2ec16fd2ab" + integrity sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A== + dependencies: + acorn "^7.1.1" + object-assign "^4.1.1" + +is-extendable@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-generator-function@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.7.tgz#d2132e529bb0000a7f80794d4bdf5cd5e5813522" + integrity sha512-YZc5EwyO4f2kWCax7oegfuSr9mFz1ZvieNYBEjmukLxgXfBUbxAWGVF7GZf0zidYtoBl3WvC07YK0wT76a+Rtw== + +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== + dependencies: + is-extglob "^2.1.1" + +is-glob@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-ip@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-ip/-/is-ip-3.1.0.tgz#2ae5ddfafaf05cb8008a62093cf29734f657c5d8" + integrity sha512-35vd5necO7IitFPjd/YBeqwWnyDWbuLH9ZXQdMfDA8TEo7pv5X8yfrvVO3xbJbLUlERCMvf6X0hTUamQxCYJ9Q== + dependencies: + ip-regex "^4.0.0" + +is-lambda@^1.0.1: + version "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" + integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w== + +is-number-like@^1.0.3: + version "1.0.8" + resolved "https://registry.yarnpkg.com/is-number-like/-/is-number-like-1.0.8.tgz#2e129620b50891042e44e9bbbb30593e75cfbbe3" + integrity sha512-6rZi3ezCyFcn5L71ywzz2bS5b2Igl1En3eTlZlvKjpz1n3IZLAYMbKYAIQgFmEu0GENg92ziU/faEOA/aixjbA== + dependencies: + lodash.isfinite "^3.3.2" + +is-number-object@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.6.tgz#6a7aaf838c7f0686a50b4553f7e54a96494e89f0" + integrity sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g== + dependencies: + has-tostringtag "^1.0.0" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-plain-obj@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" + integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== + +is-plain-object@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" + integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== + +is-potential-custom-element-name@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" + integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== + +is-promise@^2.0.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.2.2.tgz#39ab959ccbf9a774cf079f7b40c7a26f763135f1" + integrity sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ== + +is-regex@^1.0.3, is-regex@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae" + integrity sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ== + dependencies: + has "^1.0.3" + +is-regex@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" + integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-resolvable@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" + integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg== + +is-shared-array-buffer@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz#97b0c85fbdacb59c9c446fe653b82cf2b5b7cfe6" + integrity sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA== + +is-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" + integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== + +is-string@^1.0.5, is-string@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" + integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== + dependencies: + has-tostringtag "^1.0.0" + +is-svg@4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-4.3.1.tgz#8c63ec8c67c8c7f0a8de0a71c8c7d58eccf4406b" + integrity sha512-h2CGs+yPUyvkgTJQS9cJzo9lYK06WgRiXUqBBHtglSzVKAuH4/oWsqk7LGfbSa1hGk9QcZ0SyQtVggvBA8LZXA== + dependencies: + fast-xml-parser "^3.19.0" + +is-symbol@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" + integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ== + dependencies: + has-symbols "^1.0.1" + +is-symbol@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" + integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== + dependencies: + has-symbols "^1.0.2" + +is-typedarray@^1.0.0, is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + +is-weakref@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.1.tgz#842dba4ec17fa9ac9850df2d6efbc1737274f2a2" + integrity sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ== + dependencies: + call-bind "^1.0.0" + +is-whitespace@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/is-whitespace/-/is-whitespace-0.3.0.tgz#1639ecb1be036aec69a54cbb401cfbed7114ab7f" + integrity sha1-Fjnssb4DauxppUy7QBz77XEUq38= + +is-windows@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== + +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= + +isarray@^1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +isarray@^2.0.1: + version "2.0.5" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" + integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= + +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.15.0: + version "0.15.0" + resolved "https://registry.yarnpkg.com/jmespath/-/jmespath-0.15.0.tgz#a3f222a9aae9f966f5d27c796510e28091764217" + integrity sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc= + +jpeg-js@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.4.1.tgz#937a3ae911eb6427f151760f8123f04c8bfe6ef7" + integrity sha512-jA55yJiB5tCXEddos8JBbvW+IMrqY0y1tjjx9KNVtA+QPmu7ND5j0zkKopClpUTsaETL135uOM2XfcYG4XRjmw== + +js-beautify@^1.6.12: + version "1.11.0" + resolved "https://registry.yarnpkg.com/js-beautify/-/js-beautify-1.11.0.tgz#afb873dc47d58986360093dcb69951e8bcd5ded2" + integrity sha512-a26B+Cx7USQGSWnz9YxgJNMmML/QG2nqIaL7VVYPCXbqiKz8PN0waSNvroMtvAK6tY7g/wPdNWGEP+JTNIBr6A== + dependencies: + config-chain "^1.1.12" + editorconfig "^0.15.3" + glob "^7.1.3" + mkdirp "~1.0.3" + nopt "^4.0.3" + +js-levenshtein@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.6.tgz#c6cee58eb3550372df8deb85fad5ce66ce01d59d" + integrity sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g== + +js-stringify@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/js-stringify/-/js-stringify-1.0.2.tgz#1736fddfd9724f28a3682adc6230ae7e4e9679db" + integrity sha1-Fzb939lyTyijaCrcYjCufk6Weds= + +js-yaml@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.0.0.tgz#f426bc0ff4b4051926cd588c71113183409a121f" + integrity sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q== + dependencies: + argparse "^2.0.1" + +js-yaml@4.1.0, js-yaml@^4.0.0, js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + +js-yaml@^3.14.1: + version "3.14.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jsbn@1.1.0, jsbn@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-1.1.0.tgz#b01307cb29b618a1ed26ec79e911f803c4da0040" + integrity sha1-sBMHyym2GKHtJux56RH4A8TaAEA= + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= + +jschardet@^3.0.0: + version "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== + dependencies: + abab "^2.0.5" + acorn "^8.2.4" + acorn-globals "^6.0.0" + cssom "^0.4.4" + cssstyle "^2.3.0" + data-urls "^2.0.0" + decimal.js "^10.2.1" + domexception "^2.0.1" + escodegen "^2.0.0" + form-data "^3.0.0" + html-encoding-sniffer "^2.0.1" + http-proxy-agent "^4.0.1" + https-proxy-agent "^5.0.0" + is-potential-custom-element-name "^1.0.1" + nwsapi "^2.2.0" + parse5 "6.0.1" + saxes "^5.0.1" + 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" + +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" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + +json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= + +json5-loader@4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/json5-loader/-/json5-loader-4.0.1.tgz#6d17a1181e8f3c3d9204dca2a4ce4627306c8498" + integrity sha512-c9viNZlZTz0MTIcf/4qvek5Dz1/PU3DNCB4PwUhlEZIV3qb1bSD6vQQymlV17/Wm6ncra1aCvmIPsuRj+KfEEg== + dependencies: + json5 "^2.1.3" + loader-utils "^2.0.0" + schema-utils "^3.0.0" + +json5@2.2.0, json5@2.x: + version "2.2.0" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" + integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA== + dependencies: + minimist "^1.2.5" + +json5@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" + integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== + dependencies: + minimist "^1.2.0" + +json5@^2.1.2, json5@^2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43" + integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA== + dependencies: + minimist "^1.2.5" + +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= + optionalDependencies: + graceful-fs "^4.1.6" + +jsonfile@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-5.0.0.tgz#e6b718f73da420d612823996fdf14a03f6ff6922" + integrity sha512-NQRZ5CRo74MhMMC3/3r5g2k4fjodJ/wh8MxjFbCViWKFjxrnudWSY5vomh+23ZaXzAS7J3fBZIR2dV6WbmfM0w== + dependencies: + universalify "^0.1.2" + optionalDependencies: + graceful-fs "^4.1.6" + +jsonld@5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/jsonld/-/jsonld-5.2.0.tgz#d1e8af38a334cb95edf0f2ae4e2b58baf8d2b5a9" + integrity sha512-JymgT6Xzk5CHEmHuEyvoTNviEPxv6ihLWSPu1gFdtjSAyM6cFqNrv02yS/SIur3BBIkCf0HjizRc24d8/FfQKw== + dependencies: + "@digitalbazaar/http-client" "^1.1.0" + canonicalize "^1.0.1" + lru-cache "^6.0.0" + rdf-canonize "^3.0.0" + +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + +jsrsasign@8.0.20: + version "8.0.20" + resolved "https://registry.yarnpkg.com/jsrsasign/-/jsrsasign-8.0.20.tgz#37d8029c9d8f794d8ac8d8998bce319921491f11" + integrity sha512-JTXt9+nqdynIB8wFsS6e8ffHhIjilhywXwdaEVHSj9OVmwldG2H0EoCqkQ+KXkm2tVqREfH/HEmklY4k1/6Rcg== + +jstransformer@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/jstransformer/-/jstransformer-1.0.0.tgz#ed8bf0921e2f3f1ed4d5c1a44f68709ed24722c3" + integrity sha1-7Yvwkh4vPx7U1cGkT2hwntJHIsM= + dependencies: + is-promise "^2.0.0" + promise "^7.0.1" + +jwa@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/jwa/-/jwa-2.0.0.tgz#a7e9c3f29dae94027ebcaf49975c9345593410fc" + integrity sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA== + dependencies: + buffer-equal-constant-time "1.0.1" + ecdsa-sig-formatter "1.0.11" + safe-buffer "^5.0.1" + +jws@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jws/-/jws-4.0.0.tgz#2d4e8cf6a318ffaa12615e9dec7e86e6c97310f4" + integrity sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg== + dependencies: + jwa "^2.0.0" + safe-buffer "^5.0.1" + +keygrip@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/keygrip/-/keygrip-1.1.0.tgz#871b1681d5e159c62a445b0c74b615e0917e7226" + integrity sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ== + dependencies: + tsscmp "1.0.6" + +keyv@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.0.3.tgz#4f3aa98de254803cafcd2896734108daa35e4254" + integrity sha512-zdGa2TOpSZPq5mU6iowDARnMBZgtCqJ11dJROFi6tg6kTn4nuUdU09lFyLFSaHrWqpIJ+EBq4E8/Dc0Vx5vLdA== + dependencies: + json-buffer "3.0.1" + +kind-of@^3.0.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= + dependencies: + is-buffer "^1.1.5" + +koa-bodyparser@4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/koa-bodyparser/-/koa-bodyparser-4.3.0.tgz#274c778555ff48fa221ee7f36a9fbdbace22759a" + integrity sha512-uyV8G29KAGwZc4q/0WUAjH+Tsmuv9ImfBUF2oZVyZtaeo0husInagyn/JH85xMSxM0hEk/mbCII5ubLDuqW/Rw== + dependencies: + co-body "^6.0.0" + copy-to "^2.0.1" + +koa-compose@^3.0.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/koa-compose/-/koa-compose-3.2.1.tgz#a85ccb40b7d986d8e5a345b3a1ace8eabcf54de7" + integrity sha1-qFzLQLfZhtjlo0Wzoazo6rz1Tec= + dependencies: + any-promise "^1.1.0" + +koa-compose@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/koa-compose/-/koa-compose-4.1.0.tgz#507306b9371901db41121c812e923d0d67d3e877" + integrity sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw== + +koa-convert@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/koa-convert/-/koa-convert-1.2.0.tgz#da40875df49de0539098d1700b50820cebcd21d0" + integrity sha1-2kCHXfSd4FOQmNFwC1CCDOvNIdA= + dependencies: + co "^4.6.0" + koa-compose "^3.0.0" + +koa-convert@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/koa-convert/-/koa-convert-2.0.0.tgz#86a0c44d81d40551bae22fee6709904573eea4f5" + integrity sha512-asOvN6bFlSnxewce2e/DK3p4tltyfC4VM7ZwuTuepI7dEQVcvpyFuBcEARu1+Hxg8DIwytce2n7jrZtRlPrARA== + dependencies: + co "^4.6.0" + koa-compose "^4.1.0" + +koa-favicon@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/koa-favicon/-/koa-favicon-2.1.0.tgz#c430cc594614fb494adcb5ee1196a2f7f53ea442" + integrity sha512-LvukcooYjxKtnZq0RXdBup+JDhaHwLgnLlDHB/xvjwQEjbc4rbp/0WkmOzpOvaHujc+fIwPear0dpKX1V+dHVg== + dependencies: + mz "^2.7.0" + +koa-json-body@5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/koa-json-body/-/koa-json-body-5.3.0.tgz#64aad3f400adfb81df54b63f7a5eb38bad62d980" + integrity sha1-ZKrT9ACt+4HfVLY/el6zi61i2YA= + dependencies: + co-body "^5.0.0" + +koa-logger@3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/koa-logger/-/koa-logger-3.2.1.tgz#ab9db879526db3837cc9ce4fd983c025b1689f22" + integrity sha512-MjlznhLLKy9+kG8nAXKJLM0/ClsQp/Or2vI3a5rbSQmgl8IJBQO0KI5FA70BvW+hqjtxjp49SpH2E7okS6NmHg== + dependencies: + bytes "^3.1.0" + chalk "^2.4.2" + humanize-number "0.0.2" + passthrough-counter "^1.0.0" + +koa-mount@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/koa-mount/-/koa-mount-4.0.0.tgz#e0265e58198e1a14ef889514c607254ff386329c" + integrity sha512-rm71jaA/P+6HeCpoRhmCv8KVBIi0tfGuO/dMKicbQnQW/YJntJ6MnnspkodoA4QstMVEZArsCphmd0bJEtoMjQ== + dependencies: + debug "^4.0.1" + koa-compose "^4.1.0" + +koa-send@5.0.1, koa-send@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/koa-send/-/koa-send-5.0.1.tgz#39dceebfafb395d0d60beaffba3a70b4f543fe79" + integrity sha512-tmcyQ/wXXuxpDxyNXv5yNNkdAMdFRqwtegBXUaowiQzUKqJehttS0x2j0eOZDQAyloAth5w6wwBImnFzkUz3pQ== + dependencies: + debug "^4.1.1" + http-errors "^1.7.3" + resolve-path "^1.4.0" + +koa-slow@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/koa-slow/-/koa-slow-2.1.0.tgz#39007ca628c620f2b307b90dbf423d7a0c9be971" + integrity sha1-OQB8pijGIPKzB7kNv0I9egyb6XE= + dependencies: + lodash.isregexp "3.0.5" + q "1.4.1" + +koa-views@*: + version "7.0.1" + resolved "https://registry.yarnpkg.com/koa-views/-/koa-views-7.0.1.tgz#0c8f8e65d5cd2e08249430cb83dc361e49a17a5a" + integrity sha512-yS8751DXHXXDbdl/oUZd0PsgnxR0MLiguu77Eqrgu6yawE9Hi99wNKiVENb0Kfgsmvq/8px7YCI+USgxaTB1LA== + dependencies: + "@types/koa" "^2.13.1" + consolidate "^0.16.0" + debug "^4.1.0" + get-paths "0.0.7" + koa-send "^5.0.0" + mz "^2.4.0" + pretty "^2.0.0" + resolve-path "^1.4.0" + +koa-views@7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/koa-views/-/koa-views-7.0.2.tgz#c96fd9e2143ef00c29dc5160c5ed639891aa723d" + integrity sha512-dvx3mdVeSVuIPEaKAoGbxLcenudvhl821xxyuRbcoA+bOJ2dvN8wlGjkLu0ZFMlkCscXZV6lzxy28rafeazI/w== + dependencies: + consolidate "^0.16.0" + debug "^4.1.0" + get-paths "0.0.7" + koa-send "^5.0.0" + mz "^2.4.0" + pretty "^2.0.0" + resolve-path "^1.4.0" + +koa@2.13.1: + version "2.13.1" + resolved "https://registry.yarnpkg.com/koa/-/koa-2.13.1.tgz#6275172875b27bcfe1d454356a5b6b9f5a9b1051" + integrity sha512-Lb2Dloc72auj5vK4X4qqL7B5jyDPQaZucc9sR/71byg7ryoD1NCaCm63CShk9ID9quQvDEi1bGR/iGjCG7As3w== + dependencies: + accepts "^1.3.5" + cache-content-type "^1.0.0" + content-disposition "~0.5.2" + content-type "^1.0.4" + cookies "~0.8.0" + debug "~3.1.0" + delegates "^1.0.0" + depd "^2.0.0" + destroy "^1.0.4" + encodeurl "^1.0.2" + escape-html "^1.0.3" + fresh "~0.5.2" + http-assert "^1.3.0" + http-errors "^1.6.3" + is-generator-function "^1.0.7" + koa-compose "^4.1.0" + koa-convert "^1.2.0" + on-finished "^2.3.0" + only "~0.0.2" + parseurl "^1.3.2" + statuses "^1.5.0" + type-is "^1.6.16" + vary "^1.1.2" + +koa@2.13.4: + version "2.13.4" + resolved "https://registry.yarnpkg.com/koa/-/koa-2.13.4.tgz#ee5b0cb39e0b8069c38d115139c774833d32462e" + integrity sha512-43zkIKubNbnrULWlHdN5h1g3SEKXOEzoAlRsHOTFpnlDu8JlAOZSMJBLULusuXRequboiwJcj5vtYXKB3k7+2g== + dependencies: + accepts "^1.3.5" + cache-content-type "^1.0.0" + content-disposition "~0.5.2" + content-type "^1.0.4" + cookies "~0.8.0" + debug "^4.3.2" + delegates "^1.0.0" + depd "^2.0.0" + destroy "^1.0.4" + encodeurl "^1.0.2" + escape-html "^1.0.3" + fresh "~0.5.2" + http-assert "^1.3.0" + http-errors "^1.6.3" + is-generator-function "^1.0.7" + koa-compose "^4.1.0" + koa-convert "^2.0.0" + on-finished "^2.3.0" + only "~0.0.2" + parseurl "^1.3.2" + statuses "^1.5.0" + type-is "^1.6.16" + vary "^1.1.2" + +ky-universal@^0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/ky-universal/-/ky-universal-0.8.2.tgz#edc398d54cf495d7d6830aa1ab69559a3cc7f824" + integrity sha512-xe0JaOH9QeYxdyGLnzUOVGK4Z6FGvDVzcXFTdrYA1f33MZdEa45sUDaMBy98xQMcsd2XIBrTXRrRYnegcSdgVQ== + dependencies: + abort-controller "^3.0.0" + node-fetch "3.0.0-beta.9" + +ky@^0.25.1: + version "0.25.1" + resolved "https://registry.yarnpkg.com/ky/-/ky-0.25.1.tgz#0df0bd872a9cc57e31acd5dbc1443547c881bfbc" + integrity sha512-PjpCEWlIU7VpiMVrTwssahkYXX1by6NCT0fhTUX34F3DTinARlgMpriuroolugFPcMgpPWrOW4mTb984Qm1RXA== + +langmap@0.0.16: + version "0.0.16" + resolved "https://registry.yarnpkg.com/langmap/-/langmap-0.0.16.tgz#2fe3e98a531fec0fec546624ebe168c2855bab56" + integrity sha512-AtYvBK7BsDvWwnSfmO7CfgeUy7GUT1wK3QX8eKH/Ey/eXodqoHuAtvdQ82hmWD9QVFVKnuiNjym9fGY4qSJeLA== + +lcid@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-3.1.1.tgz#9030ec479a058fc36b5e8243ebaac8b6ac582fd0" + integrity sha512-M6T051+5QCGLBQb8id3hdvIW8+zeFV2FyBGFS9IEK5H9Wt4MueD4bW1eWikpHgZp+5xR3l5c8pZUkQsIA0BFZg== + dependencies: + invert-kv "^3.0.0" + +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + +levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +lilconfig@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.0.3.tgz#68f3005e921dafbd2a2afb48379986aa6d2579fd" + integrity sha512-EHKqr/+ZvdKCifpNrJCKxBTgk5XupZA3y/aCPY9mxfgBzmgh93Mt/WqjjQ38oMxXuvDokaKiM3lAgvSH2sjtHg== + +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" + integrity sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^2.1.2" + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +lodash.assignin@^4.0.9: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.assignin/-/lodash.assignin-4.2.0.tgz#ba8df5fb841eb0a3e8044232b0e263a8dc6a28a2" + integrity sha1-uo31+4QesKPoBEIysOJjqNxqKKI= + +lodash.bind@^4.1.4: + version "4.2.1" + resolved "https://registry.yarnpkg.com/lodash.bind/-/lodash.bind-4.2.1.tgz#7ae3017e939622ac31b7d7d7dcb1b34db1690d35" + integrity sha1-euMBfpOWIqwxt9fX3LGzTbFpDTU= + +lodash.defaults@^4.0.1, lodash.defaults@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" + integrity sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw= + +lodash.filter@^4.4.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.filter/-/lodash.filter-4.6.0.tgz#668b1d4981603ae1cc5a6fa760143e480b4c4ace" + integrity sha1-ZosdSYFgOuHMWm+nYBQ+SAtMSs4= + +lodash.flatten@^4.2.0, lodash.flatten@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" + integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8= + +lodash.foreach@^4.3.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.foreach/-/lodash.foreach-4.5.0.tgz#1a6a35eace401280c7f06dddec35165ab27e3e53" + integrity sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM= + +lodash.isequal@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" + integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA= + +lodash.isfinite@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/lodash.isfinite/-/lodash.isfinite-3.3.2.tgz#fb89b65a9a80281833f0b7478b3a5104f898ebb3" + integrity sha1-+4m2WpqAKBgz8LdHizpRBPiY67M= + +lodash.isregexp@3.0.5: + version "3.0.5" + resolved "https://registry.yarnpkg.com/lodash.isregexp/-/lodash.isregexp-3.0.5.tgz#e0f596242f2fa228a840086b6c8ad82e4b71fd2d" + integrity sha1-4PWWJC8voiioQAhrbIrYLktx/S0= + +lodash.map@^4.4.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.map/-/lodash.map-4.6.0.tgz#771ec7839e3473d9c4cde28b19394c3562f4f6d3" + integrity sha1-dx7Hg540c9nEzeKLGTlMNWL09tM= + +lodash.memoize@4.x, lodash.memoize@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" + integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= + +lodash.merge@^4.4.0, lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + +lodash.pick@^4.2.1: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3" + integrity sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM= + +lodash.reduce@^4.4.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.reduce/-/lodash.reduce-4.6.0.tgz#f1ab6b839299ad48f784abbf476596f03b914d3b" + integrity sha1-8atrg5KZrUj3hKu/R2WW8DuRTTs= + +lodash.reject@^4.4.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.reject/-/lodash.reject-4.6.0.tgz#80d6492dc1470864bbf583533b651f42a9f52415" + integrity sha1-gNZJLcFHCGS79YNTO2UfQqn1JBU= + +lodash.some@^4.4.0: + version "4.6.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.uniq@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" + integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= + +lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21, lodash@^4.7.0: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +log-symbols@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.0.0.tgz#69b3cc46d20f448eccdb75ea1fa733d9e821c920" + integrity sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA== + dependencies: + chalk "^4.0.0" + +lowercase-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" + integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== + +lru-cache@^4.1.5: + version "4.1.5" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" + integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +mailcheck@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/mailcheck/-/mailcheck-1.1.1.tgz#d87cf6ba0b64ba512199dbf93f1489f479591e34" + integrity sha1-2Hz2ugtkulEhmdv5PxSJ9HlZHjQ= + +make-error@1.x, make-error@^1.1.1: + version "1.3.6" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + +make-fetch-happen@^8.0.14: + version "8.0.14" + resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-8.0.14.tgz#aaba73ae0ab5586ad8eaa68bd83332669393e222" + integrity sha512-EsS89h6l4vbfJEtBZnENTOFk8mCRpY5ru36Xe5bcX1KYIli2mkSHqoFsp5O1wMDvTJJzxe/4THpCTtygjeeGWQ== + dependencies: + agentkeepalive "^4.1.3" + cacache "^15.0.5" + http-cache-semantics "^4.1.0" + http-proxy-agent "^4.0.1" + https-proxy-agent "^5.0.0" + is-lambda "^1.0.1" + lru-cache "^6.0.0" + minipass "^3.1.3" + minipass-collect "^1.0.2" + minipass-fetch "^1.3.2" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.4" + promise-retry "^2.0.1" + socks-proxy-agent "^5.0.0" + ssri "^8.0.0" + +map-age-cleaner@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" + integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== + dependencies: + p-defer "^1.0.0" + +mdn-data@2.0.14: + version "2.0.14" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50" + integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow== + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= + +mem@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/mem/-/mem-5.1.1.tgz#7059b67bf9ac2c924c9f1cff7155a064394adfb3" + integrity sha512-qvwipnozMohxLXG1pOqoLiZKNkC4r4qqRucSoDwXowsNGDSULiqFTRUF05vcZWnwJSG22qTsynQhxbaMtnX9gw== + dependencies: + map-age-cleaner "^0.1.3" + mimic-fn "^2.1.0" + p-is-promise "^2.1.0" + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +merge2@^1.3.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +merge@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/merge/-/merge-2.1.1.tgz#59ef4bf7e0b3e879186436e8481c06a6c162ca98" + integrity sha512-jz+Cfrg9GWOZbQAnDQ4hlVnQky+341Yk5ru8bZSe6sIDTCIg8n9i/u7hSQGSVOF3C7lH6mGtqjkiT9G4wFLL0w== + +methods@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= + +mfm-js@0.20.0: + version "0.20.0" + resolved "https://registry.yarnpkg.com/mfm-js/-/mfm-js-0.20.0.tgz#3afdcd7959461fd825aa8af9b9e8a57cdbddc290" + integrity sha512-1+3tV3nWUKQNh/ztX3wXu5iLBtdsg6q3wUhl+XyOhc2H3sQdG+sih/w2c0nR9TIawjN+Z1/pvgGzxMJHfmKQmA== + dependencies: + twemoji-parser "13.1.x" + +micromatch@4.x: + version "4.0.4" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" + integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== + dependencies: + braces "^3.0.1" + picomatch "^2.2.3" + +micromatch@^4.0.0, micromatch@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259" + integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q== + dependencies: + braces "^3.0.1" + picomatch "^2.0.5" + +microseconds@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/microseconds/-/microseconds-0.2.0.tgz#233b25f50c62a65d861f978a4a4f8ec18797dc39" + integrity sha512-n7DHHMjR1avBbSpsTBj6fmMGh2AGrifVV4e+WYc3Q9lO+xnSZ3NyhcBND3vzzatt05LFhoKFRxrIyklmLlUtyA== + +mime-db@1.44.0: + version "1.44.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" + integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== + +mime-types@^2.1.12, mime-types@^2.1.18, mime-types@^2.1.27, mime-types@~2.1.19, 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== + dependencies: + mime-db "1.44.0" + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +mimic-response@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" + integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== + +mimic-response@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-2.1.0.tgz#d13763d35f613d09ec37ebb30bac0469c0ee8f43" + integrity sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA== + +mimic-response@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" + integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== + +minimalistic-assert@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimatch@3.0.4, minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + +minipass-collect@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617" + integrity sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA== + dependencies: + minipass "^3.0.0" + +minipass-fetch@^1.3.2: + version "1.3.3" + resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-1.3.3.tgz#34c7cea038c817a8658461bf35174551dce17a0a" + integrity sha512-akCrLDWfbdAWkMLBxJEeWTdNsjML+dt5YgOI4gJ53vuO0vrmYQkUPxa6j6V65s9CcePIr2SSWqjT2EcrNseryQ== + dependencies: + minipass "^3.1.0" + minipass-sized "^1.0.3" + minizlib "^2.0.0" + optionalDependencies: + encoding "^0.1.12" + +minipass-flush@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373" + integrity sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw== + dependencies: + minipass "^3.0.0" + +minipass-pipeline@^1.2.2, minipass-pipeline@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz#68472f79711c084657c067c5c6ad93cddea8214c" + integrity sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A== + dependencies: + minipass "^3.0.0" + +minipass-sized@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/minipass-sized/-/minipass-sized-1.0.3.tgz#70ee5a7c5052070afacfbc22977ea79def353b70" + integrity sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g== + dependencies: + minipass "^3.0.0" + +minipass@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.1.tgz#7607ce778472a185ad6d89082aa2070f79cedcd5" + integrity sha512-UFqVihv6PQgwj8/yTGvl9kPz7xIAY+R5z6XYjRInD3Gk3qx6QGSD6zEcpeG4Dy/lQnv1J6zv8ejV90hyYIKf3w== + dependencies: + yallist "^4.0.0" + +minipass@^3.1.0, minipass@^3.1.1, minipass@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.3.tgz#7d42ff1f39635482e15f9cdb53184deebd5815fd" + integrity sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg== + dependencies: + yallist "^4.0.0" + +minizlib@^2.0.0, minizlib@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" + integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== + dependencies: + minipass "^3.0.0" + yallist "^4.0.0" + +misskey-js@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/misskey-js/-/misskey-js-0.0.8.tgz#b47a1ec54bff96b23cc2a6b307a3895f99a94424" + integrity sha512-Q1L6FaroVz8kpW7T4xQyJmJKSwjOYPbNY3TspOUWmbIBDf2JP0HVeKEFLI9dvdSL0kSkdQNz3MSVLjlHiyPqLQ== + dependencies: + autobind-decorator "^2.4.0" + eventemitter3 "^4.0.7" + reconnecting-websocket "^4.4.0" + +mkdirp-classic@^0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.2.tgz#54c441ce4c96cd7790e10b41a87aa51068ecab2b" + integrity sha512-ejdnDQcR75gwknmMw/tx02AuRs8jCtqFoFqDZMjiNxsu85sRIJVXDKHuLYvUUPRBUtV2FpSZa9bL1BUa3BdR2g== + +mkdirp-classic@^0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" + integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== + +mkdirp@0.x, mkdirp@^0.5.4: + version "0.5.5" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== + dependencies: + minimist "^1.2.5" + +mkdirp@^1.0.3, mkdirp@^1.0.4, mkdirp@~1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + +mocha@8.4.0: + version "8.4.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-8.4.0.tgz#677be88bf15980a3cae03a73e10a0fc3997f0cff" + integrity sha512-hJaO0mwDXmZS4ghXsvPVriOhsxQ7ofcpQdm8dE+jISUOKopitvnXFQmpRR7jd2K6VBG6E26gU3IAbXXGIbu4sQ== + dependencies: + "@ungap/promise-all-settled" "1.1.2" + ansi-colors "4.1.1" + browser-stdout "1.3.1" + chokidar "3.5.1" + debug "4.3.1" + diff "5.0.0" + escape-string-regexp "4.0.0" + find-up "5.0.0" + glob "7.1.6" + growl "1.10.5" + he "1.2.0" + js-yaml "4.0.0" + log-symbols "4.0.0" + minimatch "3.0.4" + ms "2.1.3" + nanoid "3.1.20" + serialize-javascript "5.0.1" + strip-json-comments "3.1.1" + supports-color "8.1.1" + which "2.0.2" + wide-align "1.1.3" + workerpool "6.1.0" + yargs "16.2.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: + version "2.24.0" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b" + integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg== + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@2.1.3, ms@^2.0.0, ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +ms@3.0.0-canary.1: + version "3.0.0-canary.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-3.0.0-canary.1.tgz#c7b34fbce381492fd0b345d1cf56e14d67b77b80" + integrity sha512-kh8ARjh8rMN7Du2igDRO9QJnqCb2xYTJxyQYK7vJJS4TvLLmsbyhiKpSW+t+y26gyOyMd0riphX0GeWKU3ky5g== + +multer@1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/multer/-/multer-1.4.3.tgz#4db352d6992e028ac0eacf7be45c6efd0264297b" + integrity sha512-np0YLKncuZoTzufbkM6wEKp68EhWJXcU6fq6QqrSwkckd2LlMgd1UqhUJLj6NS/5sZ8dE8LYDWslsltJznnXlg== + dependencies: + append-field "^1.0.0" + busboy "^0.2.11" + concat-stream "^1.5.2" + mkdirp "^0.5.4" + object-assign "^4.1.1" + on-finished "^2.3.0" + type-is "^1.6.4" + xtend "^4.0.0" + +mz@^2.4.0, mz@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" + integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== + dependencies: + any-promise "^1.0.0" + object-assign "^4.0.1" + thenify-all "^1.0.0" + +nan@^2.14.2: + version "2.14.2" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19" + integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ== + +nano-time@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/nano-time/-/nano-time-1.0.0.tgz#b0554f69ad89e22d0907f7a12b0993a5d96137ef" + integrity sha1-sFVPaa2J4i0JB/ehKwmTpdlhN+8= + dependencies: + big-integer "^1.6.16" + +nanoid@3.1.20: + version "3.1.20" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.20.tgz#badc263c6b1dcf14b71efaa85f6ab4c1d6cfc788" + integrity sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw== + +nanoid@^3.1.23: + version "3.1.23" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.23.tgz#f744086ce7c2bc47ee0a8472574d5c78e4183a81" + integrity sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw== + +nanoid@^3.1.30: + version "3.1.30" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.30.tgz#63f93cc548d2a113dc5dfbc63bfa09e2b9b64362" + integrity sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ== + +napi-build-utils@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806" + integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + +needle@^2.5.2: + version "2.5.2" + resolved "https://registry.yarnpkg.com/needle/-/needle-2.5.2.tgz#cf1a8fce382b5a280108bba90a14993c00e4010a" + integrity sha512-LbRIwS9BfkPvNwNHlsA41Q29kL2L/6VaOJ0qisM5lLWsTV3nP15abO5ITL6L81zqFhzjRKDAYjpcBcwM0AVvLQ== + dependencies: + debug "^3.2.6" + iconv-lite "^0.4.4" + sax "^1.2.4" + +negotiator@0.6.2: + version "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" + integrity sha512-yFehXNWRs4cM0+dz7QxCd06hTbWbSkV0ISsqBfkntU6TOY4Qm3Q88fRRLOddkGh2Qq6dZvnKVAahfhjcUvLnyA== + +netmask@^2.0.2: + version "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" + integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= + +node-abi@^2.21.0: + version "2.21.0" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.21.0.tgz#c2dc9ebad6f4f53d6ea9b531e7b8faad81041d48" + integrity sha512-smhrivuPqEM3H5LmnY3KU6HfYv0u4QklgAxfFyRNujKUzbUcYZ+Jc2EhukB9SRcD2VpqhxM7n/MIcp1Ua1/JMg== + dependencies: + semver "^5.4.1" + +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-fetch@2.6.1, node-fetch@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" + integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== + +node-fetch@3.0.0-beta.9: + version "3.0.0-beta.9" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-3.0.0-beta.9.tgz#0a7554cfb824380dd6812864389923c783c80d9b" + integrity sha512-RdbZCEynH2tH46+tj0ua9caUHVWrd/RHnRfvly2EVdqGmI3ndS1Vn/xjm5KuGejDt2RNDQsVRLPNd2QPwcewVg== + dependencies: + data-uri-to-buffer "^3.0.1" + fetch-blob "^2.1.1" + +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" + integrity sha512-L/Eg02Epx6Si2NXmedx+Okg+4UHqmaf3TNcxd50SF9NQGcJaON3AtU++kax69XV7YWz4tUspqZSAsVofhFKG2w== + +node-gyp@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-8.0.0.tgz#225af2b06b8419ae81f924bf25ae4c167f6378a5" + integrity sha512-Jod6NxyWtcwrpAQe0O/aXOpC5QfncotgtG73dg65z6VW/C6g/G4jiajXQUBIJ8pk/VfM6mBYE9BN/HvudTunUQ== + dependencies: + env-paths "^2.2.0" + glob "^7.1.4" + graceful-fs "^4.2.6" + make-fetch-happen "^8.0.14" + nopt "^5.0.0" + npmlog "^4.1.2" + rimraf "^3.0.2" + semver "^7.3.5" + tar "^6.1.0" + which "^2.0.2" + +node-releases@^1.1.70, node-releases@^1.1.71: + 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.0: + version "6.7.0" + resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.7.0.tgz#86614722c4e0c33d1b5b02aecb90d6d629932b0d" + integrity sha512-AtiTVUFHLiiDnMQ43zi0YgkzHOEWUkhDgPlBXrsDzJiJvB29Alo4OKxHQ0ugF3gRqRQIneCLtZU3yiUo7pItZw== + +nofilter@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/nofilter/-/nofilter-2.0.3.tgz#f5460f3cb33147005883e3f5d4476239501fa187" + integrity sha512-FbuXC+lK+GU2+63D1kC1ETiZo+Z7SIi7B+mxKTCH1byrh6WFvfBCN/wpherFz0a0bjGd7EKTst/cz0yLeNngug== + dependencies: + "@cto.af/textdecoder" "^0.0.0" + +nofilter@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/nofilter/-/nofilter-3.1.0.tgz#c757ba68801d41ff930ba2ec55bab52ca184aa66" + integrity sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g== + +nopt@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.3.tgz#a375cad9d02fd921278d954c2254d5aa57e15e48" + integrity sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg== + dependencies: + abbrev "1" + osenv "^0.1.4" + +nopt@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" + integrity sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ== + dependencies: + abbrev "1" + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +normalize-url@^4.1.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129" + integrity sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ== + +normalize-url@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" + integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== + +npm-run-path@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + +npmlog@^4.0.1, npmlog@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" + +nth-check@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.0.0.tgz#1bb4f6dac70072fc313e8c9cd1417b5074c0a125" + integrity sha512-i4sc/Kj8htBrAiH1viZ0TgU8Y5XqCaV/FziYK6TBczxmeKm3AEFWqqF3195yKudrarqy7Zu80Ra5dobFjn9X/Q== + dependencies: + boolbase "^1.0.0" + +nth-check@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" + integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg== + dependencies: + boolbase "~1.0.0" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= + +nwsapi@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" + integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== + +oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== + +oauth@0.9.15: + version "0.9.15" + resolved "https://registry.yarnpkg.com/oauth/-/oauth-0.9.15.tgz#bd1fefaf686c96b75475aed5196412ff60cfb9c1" + integrity sha1-vR/vr2hslrdUda7VGWQS/2DPucE= + +object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +object-inspect@^1.11.0, object-inspect@^1.9.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.11.0.tgz#9dceb146cedd4148a0d9e51ab88d34cf509922b1" + integrity sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg== + +object-inspect@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67" + integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw== + +object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object.assign@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" + integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== + dependencies: + define-properties "^1.1.2" + function-bind "^1.1.1" + has-symbols "^1.0.0" + object-keys "^1.0.11" + +object.assign@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" + integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + has-symbols "^1.0.1" + object-keys "^1.1.1" + +object.getownpropertydescriptors@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz#369bf1f9592d8ab89d712dced5cb81c7c5352649" + integrity sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0-next.1" + +object.values@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.5.tgz#959f63e3ce9ef108720333082131e4a459b716ac" + integrity sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.1" + +oblivious-set@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/oblivious-set/-/oblivious-set-1.0.0.tgz#c8316f2c2fb6ff7b11b6158db3234c49f733c566" + integrity sha512-z+pI07qxo4c2CulUHCDf9lcqDlMSo72N/4rLUpRXf6fu+q8vjt8y0xS+Tlf8NTJDdTXHbdeO1n3MlbctwEoXZw== + +on-finished@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= + dependencies: + ee-first "1.1.1" + +once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +onetime@^5.1.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +only@~0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/only/-/only-0.0.2.tgz#2afde84d03e50b9a8edc444e30610a70295edfb4" + integrity sha1-Kv3oTQPlC5qO3EROMGEKcCle37Q= + +opentype.js@^0.4.3: + version "0.4.11" + resolved "https://registry.yarnpkg.com/opentype.js/-/opentype.js-0.4.11.tgz#281a2390639cc15931c955d8d63c14a7c7772b41" + integrity sha1-KBojkGOcwVkxyVXY1jwUp8d3K0E= + +optionator@^0.8.1: + version "0.8.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" + integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.6" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + word-wrap "~1.2.3" + +optionator@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" + integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== + dependencies: + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + word-wrap "^1.2.3" + +os-homedir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= + +os-locale@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-5.0.0.tgz#6d26c1d95b6597c5d5317bf5fba37eccec3672e0" + integrity sha512-tqZcNEDAIZKBEPnHPlVDvKrp7NzgLi7jRmhKiUoa2NUmhl13FtkAGLUVR+ZsYvApBQdBfYm43A4tXXQ4IrYLBA== + dependencies: + execa "^4.0.0" + lcid "^3.0.0" + mem "^5.0.0" + +os-tmpdir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= + +os-utils@0.0.14: + version "0.0.14" + resolved "https://registry.yarnpkg.com/os-utils/-/os-utils-0.0.14.tgz#29e511697b1982b8c627722175fe39797ef64156" + integrity sha1-KeURaXsZgrjGJ3Ihdf45eX72QVY= + +osenv@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" + integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + +p-cancelable@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.0.0.tgz#4a3740f5bdaf5ed5d7c3e34882c6fb5d6b266a6e" + integrity sha512-wvPXDmbMmu2ksjkB4Z3nZWTSkJEb9lqVdMaCKpZUGJG9TMiNp9XcbG3fn9fPKjem04fJMJnXoyFPk2FmgiaiNg== + +p-defer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" + integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= + +p-is-promise@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" + integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg== + +p-limit@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== + dependencies: + p-try "^1.0.0" + +p-limit@^2.0.0, p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-limit@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.0.2.tgz#1664e010af3cadc681baafd3e2a437be7b0fb5fe" + integrity sha512-iwqZSOoWIW+Ew4kAGUlN16J4M7OB3ysMLSZtnhmqx7njIHFPlxWBX8xo3lVTyFVq6mI/lL9qt2IsN1sHwaxJkg== + 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" + integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= + dependencies: + p-limit "^1.1.0" + +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + +p-map@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" + integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw== + +p-map@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" + integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== + dependencies: + aggregate-error "^3.0.0" + +p-timeout@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-3.2.0.tgz#c7e17abc971d2a7962ef83626b35d635acf23dfe" + integrity sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg== + dependencies: + p-finally "^1.0.0" + +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +packet-reader@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/packet-reader/-/packet-reader-1.0.0.tgz#9238e5480dedabacfe1fe3f2771063f164157d74" + integrity sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ== + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +parse-passwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" + integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY= + +parse-srcset@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/parse-srcset/-/parse-srcset-1.0.2.tgz#f2bd221f6cc970a938d88556abc589caaaa2bde1" + integrity sha1-8r0iH2zJcKk42IVWq8WJyqqiveE= + +parse5-htmlparser2-tree-adapter@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz#2cdf9ad823321140370d4dbf5d3e92c7c8ddc6e6" + integrity sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA== + dependencies: + parse5 "^6.0.1" + +parse5@6.0.1, parse5@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" + integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== + +parse5@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.1.tgz#f68e4e5ba1852ac2cadc00f4555fff6c2abb6178" + integrity sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug== + +parseurl@^1.3.2: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +passthrough-counter@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/passthrough-counter/-/passthrough-counter-1.0.0.tgz#1967d9e66da572b5c023c787db112a387ab166fa" + integrity sha1-GWfZ5m2lcrXAI8eH2xEqOHqxZvo= + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@1.0.1, path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" + integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== + +path-to-regexp@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-6.1.0.tgz#0b18f88b7a0ce0bfae6a25990c909ab86f512427" + integrity sha512-h9DqehX3zZZDCEm+xbfU0ZmwCGFCAAraPJWMXJ4+v32NjZJilVg3k1TcKsRgIb8IQ/izZSaydDc1OhJCZvs2Dw== + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +peek-readable@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/peek-readable/-/peek-readable-4.0.1.tgz#9a045f291db254111c3412c1ce4fec27ddd4d202" + integrity sha512-7qmhptnR0WMSpxT5rMHG9bW/mYSR1uqaPFj2MHvT+y/aOUu6msJijpKt5SkTDKySwg65OWG2JwTMBlgcbwMHrQ== + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= + +pg-connection-string@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.5.0.tgz#538cadd0f7e603fc09a12590f3b8a452c2c0cf34" + integrity sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ== + +pg-int8@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/pg-int8/-/pg-int8-1.0.1.tgz#943bd463bf5b71b4170115f80f8efc9a0c0eb78c" + integrity sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw== + +pg-pool@^3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-3.4.1.tgz#0e71ce2c67b442a5e862a9c182172c37eda71e9c" + integrity sha512-TVHxR/gf3MeJRvchgNHxsYsTCHQ+4wm3VIHSS19z8NC0+gioEhq1okDY1sm/TYbfoP6JLFx01s0ShvZ3puP/iQ== + +pg-protocol@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/pg-protocol/-/pg-protocol-1.5.0.tgz#b5dd452257314565e2d54ab3c132adc46565a6a0" + integrity sha512-muRttij7H8TqRNu/DxrAJQITO4Ac7RmX3Klyr/9mJEOBeIpgnF8f9jAfRz5d3XwQZl5qBjF9gLsUtMPJE0vezQ== + +pg-types@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/pg-types/-/pg-types-2.2.0.tgz#2d0250d636454f7cfa3b6ae0382fdfa8063254a3" + integrity sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA== + dependencies: + pg-int8 "1.0.1" + postgres-array "~2.0.0" + postgres-bytea "~1.0.0" + postgres-date "~1.0.4" + postgres-interval "^1.1.0" + +pg@8.7.1: + version "8.7.1" + resolved "https://registry.yarnpkg.com/pg/-/pg-8.7.1.tgz#9ea9d1ec225980c36f94e181d009ab9f4ce4c471" + integrity sha512-7bdYcv7V6U3KAtWjpQJJBww0UEsWuh4yQ/EjNf2HeO/NnvKjpvhEIe/A/TleP6wtmSKnUnghs5A9jUoK6iDdkA== + dependencies: + buffer-writer "2.0.0" + packet-reader "1.0.0" + pg-connection-string "^2.5.0" + pg-pool "^3.4.1" + pg-protocol "^1.5.0" + pg-types "^2.1.0" + pgpass "1.x" + +pgpass@1.x: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pgpass/-/pgpass-1.0.2.tgz#2a7bb41b6065b67907e91da1b07c1847c877b306" + integrity sha1-Knu0G2BltnkH6R2hsHwYR8h3swY= + dependencies: + split "^1.0.0" + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.0.7, picomatch@^2.2.1: + version "2.2.2" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" + integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== + +picomatch@^2.2.3: + version "2.3.0" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" + integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== + +pify@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" + integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== + +pkg-dir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" + integrity sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s= + dependencies: + find-up "^2.1.0" + +pngjs@^3.3.0, pngjs@^3.3.1: + version "3.4.0" + resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-3.4.0.tgz#99ca7d725965fb655814eaf65f38f12bbdbf555f" + integrity sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w== + +portscanner@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/portscanner/-/portscanner-2.2.0.tgz#6059189b3efa0965c9d96a56b958eb9508411cf1" + integrity sha512-IFroCz/59Lqa2uBvzK3bKDbDDIEaAY8XJ1jFxcLWTqosrsc32//P4VuSB2vZXoHiHqOmx8B5L5hnKOxL/7FlPw== + dependencies: + async "^2.6.0" + is-number-like "^1.0.3" + +postcss-calc@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-8.0.0.tgz#a05b87aacd132740a5db09462a3612453e5df90a" + integrity sha512-5NglwDrcbiy8XXfPM11F3HeC6hoT9W7GUH/Zi5U/p7u3Irv4rHhdDcIZwG0llHXV4ftsBjpfWMXAnXNl4lnt8g== + dependencies: + postcss-selector-parser "^6.0.2" + postcss-value-parser "^4.0.2" + +postcss-colormin@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-5.2.1.tgz#6e444a806fd3c578827dbad022762df19334414d" + integrity sha512-VVwMrEYLcHYePUYV99Ymuoi7WhKrMGy/V9/kTS0DkCoJYmmjdOMneyhzYUxcNgteKDVbrewOkSM7Wje/MFwxzA== + dependencies: + browserslist "^4.16.6" + caniuse-api "^3.0.0" + colord "^2.9.1" + postcss-value-parser "^4.1.0" + +postcss-convert-values@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-5.0.2.tgz#879b849dc3677c7d6bc94b6a2c1a3f0808798059" + integrity sha512-KQ04E2yadmfa1LqXm7UIDwW1ftxU/QWZmz6NKnHnUvJ3LEYbbcX6i329f/ig+WnEByHegulocXrECaZGLpL8Zg== + dependencies: + postcss-value-parser "^4.1.0" + +postcss-discard-comments@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-5.0.1.tgz#9eae4b747cf760d31f2447c27f0619d5718901fe" + integrity sha512-lgZBPTDvWrbAYY1v5GYEv8fEO/WhKOu/hmZqmCYfrpD6eyDWWzAOsl2rF29lpvziKO02Gc5GJQtlpkTmakwOWg== + +postcss-discard-duplicates@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-5.0.1.tgz#68f7cc6458fe6bab2e46c9f55ae52869f680e66d" + integrity sha512-svx747PWHKOGpAXXQkCc4k/DsWo+6bc5LsVrAsw+OU+Ibi7klFZCyX54gjYzX4TH+f2uzXjRviLARxkMurA2bA== + +postcss-discard-empty@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-5.0.1.tgz#ee136c39e27d5d2ed4da0ee5ed02bc8a9f8bf6d8" + integrity sha512-vfU8CxAQ6YpMxV2SvMcMIyF2LX1ZzWpy0lqHDsOdaKKLQVQGVP1pzhrI9JlsO65s66uQTfkQBKBD/A5gp9STFw== + +postcss-discard-overridden@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-5.0.1.tgz#454b41f707300b98109a75005ca4ab0ff2743ac6" + integrity sha512-Y28H7y93L2BpJhrdUR2SR2fnSsT+3TVx1NmVQLbcnZWwIUpJ7mfcTC6Za9M2PG6w8j7UQRfzxqn8jU2VwFxo3Q== + +postcss-merge-longhand@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-5.0.3.tgz#42194a5ffbaa5513edbf606ef79c44958564658b" + integrity sha512-kmB+1TjMTj/bPw6MCDUiqSA5e/x4fvLffiAdthra3a0m2/IjTrWsTmD3FdSskzUjEwkj5ZHBDEbv5dOcqD7CMQ== + dependencies: + css-color-names "^1.0.1" + postcss-value-parser "^4.1.0" + stylehacks "^5.0.1" + +postcss-merge-rules@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-5.0.2.tgz#d6e4d65018badbdb7dcc789c4f39b941305d410a" + integrity sha512-5K+Md7S3GwBewfB4rjDeol6V/RZ8S+v4B66Zk2gChRqLTCC8yjnHQ601omj9TKftS19OPGqZ/XzoqpzNQQLwbg== + dependencies: + browserslist "^4.16.6" + caniuse-api "^3.0.0" + cssnano-utils "^2.0.1" + postcss-selector-parser "^6.0.5" + vendors "^1.0.3" + +postcss-minify-font-values@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-5.0.1.tgz#a90cefbfdaa075bd3dbaa1b33588bb4dc268addf" + integrity sha512-7JS4qIsnqaxk+FXY1E8dHBDmraYFWmuL6cgt0T1SWGRO5bzJf8sUoelwa4P88LEWJZweHevAiDKxHlofuvtIoA== + dependencies: + postcss-value-parser "^4.1.0" + +postcss-minify-gradients@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-5.0.3.tgz#f970a11cc71e08e9095e78ec3a6b34b91c19550e" + integrity sha512-Z91Ol22nB6XJW+5oe31+YxRsYooxOdFKcbOqY/V8Fxse1Y3vqlNRpi1cxCqoACZTQEhl+xvt4hsbWiV5R+XI9Q== + dependencies: + colord "^2.9.1" + cssnano-utils "^2.0.1" + postcss-value-parser "^4.1.0" + +postcss-minify-params@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-5.0.1.tgz#371153ba164b9d8562842fdcd929c98abd9e5b6c" + integrity sha512-4RUC4k2A/Q9mGco1Z8ODc7h+A0z7L7X2ypO1B6V8057eVK6mZ6xwz6QN64nHuHLbqbclkX1wyzRnIrdZehTEHw== + dependencies: + alphanum-sort "^1.0.2" + browserslist "^4.16.0" + cssnano-utils "^2.0.1" + postcss-value-parser "^4.1.0" + uniqs "^2.0.0" + +postcss-minify-selectors@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-5.1.0.tgz#4385c845d3979ff160291774523ffa54eafd5a54" + integrity sha512-NzGBXDa7aPsAcijXZeagnJBKBPMYLaJJzB8CQh6ncvyl2sIndLVWfbcDi0SBjRWk5VqEjXvf8tYwzoKf4Z07og== + dependencies: + alphanum-sort "^1.0.2" + postcss-selector-parser "^6.0.5" + +postcss-modules-extract-imports@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz#cda1f047c0ae80c97dbe28c3e76a43b88025741d" + integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw== + +postcss-modules-local-by-default@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz#ebbb54fae1598eecfdf691a02b3ff3b390a5a51c" + integrity sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ== + dependencies: + icss-utils "^5.0.0" + postcss-selector-parser "^6.0.2" + postcss-value-parser "^4.1.0" + +postcss-modules-scope@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz#9ef3151456d3bbfa120ca44898dfca6f2fa01f06" + integrity sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg== + dependencies: + postcss-selector-parser "^6.0.4" + +postcss-modules-values@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz#d7c5e7e68c3bb3c9b27cbf48ca0bb3ffb4602c9c" + integrity sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ== + dependencies: + icss-utils "^5.0.0" + +postcss-normalize-charset@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-5.0.1.tgz#121559d1bebc55ac8d24af37f67bd4da9efd91d0" + integrity sha512-6J40l6LNYnBdPSk+BHZ8SF+HAkS4q2twe5jnocgd+xWpz/mx/5Sa32m3W1AA8uE8XaXN+eg8trIlfu8V9x61eg== + +postcss-normalize-display-values@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-5.0.1.tgz#62650b965981a955dffee83363453db82f6ad1fd" + integrity sha512-uupdvWk88kLDXi5HEyI9IaAJTE3/Djbcrqq8YgjvAVuzgVuqIk3SuJWUisT2gaJbZm1H9g5k2w1xXilM3x8DjQ== + dependencies: + cssnano-utils "^2.0.1" + postcss-value-parser "^4.1.0" + +postcss-normalize-positions@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-5.0.1.tgz#868f6af1795fdfa86fbbe960dceb47e5f9492fe5" + integrity sha512-rvzWAJai5xej9yWqlCb1OWLd9JjW2Ex2BCPzUJrbaXmtKtgfL8dBMOOMTX6TnvQMtjk3ei1Lswcs78qKO1Skrg== + dependencies: + postcss-value-parser "^4.1.0" + +postcss-normalize-repeat-style@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.0.1.tgz#cbc0de1383b57f5bb61ddd6a84653b5e8665b2b5" + integrity sha512-syZ2itq0HTQjj4QtXZOeefomckiV5TaUO6ReIEabCh3wgDs4Mr01pkif0MeVwKyU/LHEkPJnpwFKRxqWA/7O3w== + dependencies: + cssnano-utils "^2.0.1" + postcss-value-parser "^4.1.0" + +postcss-normalize-string@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-5.0.1.tgz#d9eafaa4df78c7a3b973ae346ef0e47c554985b0" + integrity sha512-Ic8GaQ3jPMVl1OEn2U//2pm93AXUcF3wz+OriskdZ1AOuYV25OdgS7w9Xu2LO5cGyhHCgn8dMXh9bO7vi3i9pA== + dependencies: + postcss-value-parser "^4.1.0" + +postcss-normalize-timing-functions@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.0.1.tgz#8ee41103b9130429c6cbba736932b75c5e2cb08c" + integrity sha512-cPcBdVN5OsWCNEo5hiXfLUnXfTGtSFiBU9SK8k7ii8UD7OLuznzgNRYkLZow11BkQiiqMcgPyh4ZqXEEUrtQ1Q== + dependencies: + cssnano-utils "^2.0.1" + postcss-value-parser "^4.1.0" + +postcss-normalize-unicode@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-5.0.1.tgz#82d672d648a411814aa5bf3ae565379ccd9f5e37" + integrity sha512-kAtYD6V3pK0beqrU90gpCQB7g6AOfP/2KIPCVBKJM2EheVsBQmx/Iof+9zR9NFKLAx4Pr9mDhogB27pmn354nA== + dependencies: + browserslist "^4.16.0" + postcss-value-parser "^4.1.0" + +postcss-normalize-url@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-5.0.2.tgz#ddcdfb7cede1270740cf3e4dfc6008bd96abc763" + integrity sha512-k4jLTPUxREQ5bpajFQZpx8bCF2UrlqOTzP9kEqcEnOfwsRshWs2+oAFIHfDQB8GO2PaUaSE0NlTAYtbluZTlHQ== + dependencies: + is-absolute-url "^3.0.3" + normalize-url "^6.0.1" + postcss-value-parser "^4.1.0" + +postcss-normalize-whitespace@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.0.1.tgz#b0b40b5bcac83585ff07ead2daf2dcfbeeef8e9a" + integrity sha512-iPklmI5SBnRvwceb/XH568yyzK0qRVuAG+a1HFUsFRf11lEJTiQQa03a4RSCQvLKdcpX7XsI1Gen9LuLoqwiqA== + dependencies: + postcss-value-parser "^4.1.0" + +postcss-ordered-values@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-5.0.2.tgz#1f351426977be00e0f765b3164ad753dac8ed044" + integrity sha512-8AFYDSOYWebJYLyJi3fyjl6CqMEG/UVworjiyK1r573I56kb3e879sCJLGvR3merj+fAdPpVplXKQZv+ey6CgQ== + dependencies: + cssnano-utils "^2.0.1" + postcss-value-parser "^4.1.0" + +postcss-reduce-initial@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-5.0.1.tgz#9d6369865b0f6f6f6b165a0ef5dc1a4856c7e946" + integrity sha512-zlCZPKLLTMAqA3ZWH57HlbCjkD55LX9dsRyxlls+wfuRfqCi5mSlZVan0heX5cHr154Dq9AfbH70LyhrSAezJw== + dependencies: + browserslist "^4.16.0" + caniuse-api "^3.0.0" + +postcss-reduce-transforms@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-5.0.1.tgz#93c12f6a159474aa711d5269923e2383cedcf640" + integrity sha512-a//FjoPeFkRuAguPscTVmRQUODP+f3ke2HqFNgGPwdYnpeC29RZdCBvGRGTsKpMURb/I3p6jdKoBQ2zI+9Q7kA== + dependencies: + cssnano-utils "^2.0.1" + postcss-value-parser "^4.1.0" + +postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4: + version "6.0.4" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.4.tgz#56075a1380a04604c38b063ea7767a129af5c2b3" + integrity sha512-gjMeXBempyInaBqpp8gODmwZ52WaYsVOsfr4L4lDQ7n3ncD6mEyySiDtgzCT+NYC0mmeOLvtsF8iaEf0YT6dBw== + dependencies: + cssesc "^3.0.0" + indexes-of "^1.0.1" + uniq "^1.0.1" + util-deprecate "^1.0.2" + +postcss-selector-parser@^6.0.5: + version "6.0.6" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz#2c5bba8174ac2f6981ab631a42ab0ee54af332ea" + integrity sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg== + dependencies: + cssesc "^3.0.0" + util-deprecate "^1.0.2" + +postcss-svgo@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-5.0.3.tgz#d945185756e5dfaae07f9edb0d3cae7ff79f9b30" + integrity sha512-41XZUA1wNDAZrQ3XgWREL/M2zSw8LJPvb5ZWivljBsUQAGoEKMYm6okHsTjJxKYI4M75RQEH4KYlEM52VwdXVA== + dependencies: + postcss-value-parser "^4.1.0" + svgo "^2.7.0" + +postcss-unique-selectors@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-5.0.1.tgz#3be5c1d7363352eff838bd62b0b07a0abad43bfc" + integrity sha512-gwi1NhHV4FMmPn+qwBNuot1sG1t2OmacLQ/AX29lzyggnjd+MnVD5uqQmpXO3J17KGL2WAxQruj1qTd3H0gG/w== + dependencies: + alphanum-sort "^1.0.2" + postcss-selector-parser "^6.0.5" + uniqs "^2.0.0" + +postcss-value-parser@^4.0.2, postcss-value-parser@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb" + integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ== + +postcss@^8.2.15: + version "8.3.0" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.3.0.tgz#b1a713f6172ca427e3f05ef1303de8b65683325f" + integrity sha512-+ogXpdAjWGa+fdYY5BQ96V/6tAo+TdSSIMP5huJBIygdWwKtVoB5JWZ7yUd4xZ8r+8Kvvx4nyg/PQ071H4UtcQ== + dependencies: + colorette "^1.2.2" + nanoid "^3.1.23" + source-map-js "^0.6.2" + +postcss@^8.3.11: + version "8.3.11" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.3.11.tgz#c3beca7ea811cd5e1c4a3ec6d2e7599ef1f8f858" + integrity sha512-hCmlUAIlUiav8Xdqw3Io4LcpA1DOt7h3LSTAC4G6JGHFFaWzI6qvFt9oilvl8BmkbBRX1IhM90ZAmpk68zccQA== + dependencies: + nanoid "^3.1.30" + picocolors "^1.0.0" + source-map-js "^0.6.2" + +postgres-array@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-2.0.0.tgz#48f8fce054fbc69671999329b8834b772652d82e" + integrity sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA== + +postgres-bytea@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/postgres-bytea/-/postgres-bytea-1.0.0.tgz#027b533c0aa890e26d172d47cf9ccecc521acd35" + integrity sha1-AntTPAqokOJtFy1Hz5zOzFIazTU= + +postgres-date@~1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/postgres-date/-/postgres-date-1.0.5.tgz#710b27de5f27d550f6e80b5d34f7ba189213c2ee" + integrity sha512-pdau6GRPERdAYUQwkBnGKxEfPyhVZXG/JiS44iZWiNdSOWE09N2lUgN6yshuq6fVSon4Pm0VMXd1srUUkLe9iA== + +postgres-interval@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/postgres-interval/-/postgres-interval-1.2.0.tgz#b460c82cb1587507788819a06aa0fffdb3544695" + integrity sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ== + dependencies: + xtend "^4.0.0" + +prebuild-install@^6.1.4: + version "6.1.4" + resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-6.1.4.tgz#ae3c0142ad611d58570b89af4986088a4937e00f" + integrity sha512-Z4vpywnK1lBg+zdPCVCsKq0xO66eEV9rWo2zrROGGiRS4JtueBOdlB1FnY8lcy7JsUud/Q3ijUxyWN26Ika0vQ== + dependencies: + detect-libc "^1.0.3" + expand-template "^2.0.3" + github-from-package "0.0.0" + minimist "^1.2.3" + mkdirp-classic "^0.5.3" + napi-build-utils "^1.0.1" + node-abi "^2.21.0" + npmlog "^4.0.1" + pump "^3.0.0" + rc "^1.2.7" + simple-get "^3.0.3" + tar-fs "^2.0.0" + tunnel-agent "^0.6.0" + +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= + +pretty@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pretty/-/pretty-2.0.0.tgz#adbc7960b7bbfe289a557dc5f737619a220d06a5" + integrity sha1-rbx5YLe7/iiaVX3F9zdhmiINBqU= + dependencies: + condense-newlines "^0.2.1" + extend-shallow "^2.0.1" + js-beautify "^1.6.12" + +prettyjson@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/prettyjson/-/prettyjson-1.2.1.tgz#fcffab41d19cab4dfae5e575e64246619b12d289" + integrity sha1-/P+rQdGcq0365eV15kJGYZsS0ok= + dependencies: + colors "^1.1.2" + minimist "^1.2.0" + +printj@~1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/printj/-/printj-1.1.2.tgz#d90deb2975a8b9f600fb3a1c94e3f4c53c78a222" + integrity sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ== + +prismjs@1.25.0: + version "1.25.0" + resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.25.0.tgz#6f822df1bdad965734b310b315a23315cf999756" + integrity sha512-WCjJHl1KEWbnkQom1+SzftbtXMKQoezOCYs5rECqMN+jP+apI7ftoflyqigqzopSO3hMhTEb0mFClA8lkolgEg== + +private-ip@2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/private-ip/-/private-ip-2.3.3.tgz#1e80ff8443e5ac78f555631aec3ea6ff027fa6aa" + integrity sha512-5zyFfekIVUOTVbL92hc8LJOtE/gyGHeREHkJ2yTyByP8Q2YZVoBqLg3EfYLeF0oVvGqtaEX2t2Qovja0/gStXw== + dependencies: + ip-regex "^4.3.0" + ipaddr.js "^2.0.1" + is-ip "^3.1.0" + netmask "^2.0.2" + +probe-image-size@7.2.1: + version "7.2.1" + resolved "https://registry.yarnpkg.com/probe-image-size/-/probe-image-size-7.2.1.tgz#df0c924e67e247bc94f8fcb0fad7f0081061fc44" + integrity sha512-d+6L3NvQBCNt4peRDoEfA7r9bPm6/qy18FnLKwg4NWBC5JrJm0pMLRg1kF4XNsPe1bUdt3WIMonPJzQWN2HXjQ== + dependencies: + lodash.merge "^4.6.2" + needle "^2.5.2" + stream-parser "~0.3.1" + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +progress@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + +promise-inflight@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" + integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= + +promise-limit@2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/promise-limit/-/promise-limit-2.7.0.tgz#eb5737c33342a030eaeaecea9b3d3a93cb592b26" + integrity sha512-7nJ6v5lnJsXwGprnGXga4wx6d1POjvi5Qmf1ivTRxTjH4Z/9Czja/UCMLVmB9N93GeWOU93XaFaEt6jbuoagNw== + +promise-retry@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-2.0.1.tgz#ff747a13620ab57ba688f5fc67855410c370da22" + integrity sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g== + dependencies: + err-code "^2.0.2" + retry "^0.12.0" + +promise.prototype.finally@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/promise.prototype.finally/-/promise.prototype.finally-3.1.2.tgz#b8af89160c9c673cefe3b4c4435b53cfd0287067" + integrity sha512-A2HuJWl2opDH0EafgdjwEw7HysI8ff/n4lW4QEVBCUXFk9QeGecBWv0Deph0UmLe3tTNYegz8MOjsVuE6SMoJA== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0-next.0" + function-bind "^1.1.1" + +promise@^7.0.1: + version "7.3.1" + resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" + integrity sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg== + dependencies: + asap "~2.0.3" + +proto-list@~1.2.1: + version "1.2.4" + resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" + integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk= + +pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= + +psl@^1.1.28, psl@^1.1.33: + version "1.8.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" + integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== + +pug-attrs@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pug-attrs/-/pug-attrs-3.0.0.tgz#b10451e0348165e31fad1cc23ebddd9dc7347c41" + integrity sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA== + dependencies: + constantinople "^4.0.1" + js-stringify "^1.0.2" + pug-runtime "^3.0.0" + +pug-code-gen@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/pug-code-gen/-/pug-code-gen-3.0.2.tgz#ad190f4943133bf186b60b80de483100e132e2ce" + integrity sha512-nJMhW16MbiGRiyR4miDTQMRWDgKplnHyeLvioEJYbk1RsPI3FuA3saEP8uwnTb2nTJEKBU90NFVWJBk4OU5qyg== + dependencies: + constantinople "^4.0.1" + doctypes "^1.1.0" + js-stringify "^1.0.2" + pug-attrs "^3.0.0" + pug-error "^2.0.0" + pug-runtime "^3.0.0" + void-elements "^3.1.0" + with "^7.0.0" + +pug-error@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pug-error/-/pug-error-2.0.0.tgz#5c62173cb09c34de2a2ce04f17b8adfec74d8ca5" + integrity sha512-sjiUsi9M4RAGHktC1drQfCr5C5eriu24Lfbt4s+7SykztEOwVZtbFk1RRq0tzLxcMxMYTBR+zMQaG07J/btayQ== + +pug-filters@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/pug-filters/-/pug-filters-4.0.0.tgz#d3e49af5ba8472e9b7a66d980e707ce9d2cc9b5e" + integrity sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A== + dependencies: + constantinople "^4.0.1" + jstransformer "1.0.0" + pug-error "^2.0.0" + pug-walk "^2.0.0" + resolve "^1.15.1" + +pug-lexer@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/pug-lexer/-/pug-lexer-5.0.1.tgz#ae44628c5bef9b190b665683b288ca9024b8b0d5" + integrity sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w== + dependencies: + character-parser "^2.2.0" + is-expression "^4.0.0" + pug-error "^2.0.0" + +pug-linker@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/pug-linker/-/pug-linker-4.0.0.tgz#12cbc0594fc5a3e06b9fc59e6f93c146962a7708" + integrity sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw== + dependencies: + pug-error "^2.0.0" + pug-walk "^2.0.0" + +pug-load@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pug-load/-/pug-load-3.0.0.tgz#9fd9cda52202b08adb11d25681fb9f34bd41b662" + integrity sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ== + dependencies: + object-assign "^4.1.1" + pug-walk "^2.0.0" + +pug-parser@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/pug-parser/-/pug-parser-6.0.0.tgz#a8fdc035863a95b2c1dc5ebf4ecf80b4e76a1260" + integrity sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw== + dependencies: + pug-error "^2.0.0" + token-stream "1.0.0" + +pug-runtime@^3.0.0, pug-runtime@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/pug-runtime/-/pug-runtime-3.0.1.tgz#f636976204723f35a8c5f6fad6acda2a191b83d7" + integrity sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg== + +pug-strip-comments@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pug-strip-comments/-/pug-strip-comments-2.0.0.tgz#f94b07fd6b495523330f490a7f554b4ff876303e" + integrity sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ== + dependencies: + pug-error "^2.0.0" + +pug-walk@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pug-walk/-/pug-walk-2.0.0.tgz#417aabc29232bb4499b5b5069a2b2d2a24d5f5fe" + integrity sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ== + +pug@3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/pug/-/pug-3.0.2.tgz#f35c7107343454e43bc27ae0ff76c731b78ea535" + integrity sha512-bp0I/hiK1D1vChHh6EfDxtndHji55XP/ZJKwsRqrz6lRia6ZC2OZbdAymlxdVFwd1L70ebrVJw4/eZ79skrIaw== + dependencies: + pug-code-gen "^3.0.2" + pug-filters "^4.0.0" + pug-lexer "^5.0.1" + pug-linker "^4.0.0" + pug-load "^3.0.0" + pug-parser "^6.0.0" + pug-runtime "^3.0.1" + pug-strip-comments "^2.0.0" + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +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.1, punycode@^2.1.0, punycode@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +pureimage@0.3.5: + version "0.3.5" + resolved "https://registry.yarnpkg.com/pureimage/-/pureimage-0.3.5.tgz#cd5e91f7b6409fcf4880297aaa3e7fc0afc24d5e" + integrity sha512-+CFUEpoX6GemlKlHihI7Ii4IqKqF5KZjd682sAxwzbc4t4zU4Gwhxd4W3UMZW94nJzf0n4nA9zJrwTR4jZB4TA== + dependencies: + jpeg-js "^0.4.1" + opentype.js "^0.4.3" + pngjs "^3.3.1" + +q@1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/q/-/q-1.4.1.tgz#55705bcd93c5f3673530c2c2cbc0c2b3addc286e" + integrity sha1-VXBbzZPF82c1MMLCy8DCs63cKG4= + +qrcode@1.4.4: + version "1.4.4" + resolved "https://registry.yarnpkg.com/qrcode/-/qrcode-1.4.4.tgz#f0c43568a7e7510a55efc3b88d9602f71963ea83" + integrity sha512-oLzEC5+NKFou9P0bMj5+v6Z40evexeE29Z9cummZXZ9QXyMr3lphkURzxjXgPJC5azpxcshoDWV1xE46z+/c3Q== + dependencies: + buffer "^5.4.3" + buffer-alloc "^1.2.0" + buffer-from "^1.1.1" + dijkstrajs "^1.0.1" + isarray "^2.0.1" + pngjs "^3.3.0" + yargs "^13.2.4" + +qs@^6.4.0, qs@^6.5.2: + version "6.9.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.3.tgz#bfadcd296c2d549f1dffa560619132c977f5008e" + integrity sha512-EbZYNarm6138UKKq46tdx08Yo/q9ZhFoAXAI1meAFd2GtbRDhbZY2WQSICskT0c5q99aFzLG1D4nvTk9tqfXIw== + +qs@~6.5.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" + integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== + +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= + +quick-lru@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" + integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== + +random-seed@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/random-seed/-/random-seed-0.3.0.tgz#d945f2e1f38f49e8d58913431b8bf6bb937556cd" + integrity sha1-2UXy4fOPSejViRNDG4v2u5N1Vs0= + dependencies: + json-stringify-safe "^5.0.1" + +randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +rangestr@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/rangestr/-/rangestr-0.0.1.tgz#f72ff9246f10f2a7d7c16e14616f617be2c2635a" + integrity sha1-9y/5JG8Q8qfXwW4UYW9he+LCY1o= + +ratelimiter@3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/ratelimiter/-/ratelimiter-3.4.1.tgz#fa69e94937413382a926aaa17aaeaa6263af4659" + integrity sha512-5FJbRW/Jkkdk29ksedAfWFkQkhbUrMx3QJGwMKAypeIiQf4yrLW+gtPKZiaWt4zPrtw1uGufOjGO7UGM6VllsQ== + +raw-body@^2.2.0, raw-body@^2.3.3: + version "2.4.1" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.1.tgz#30ac82f98bb5ae8c152e67149dac8d55153b168c" + integrity sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA== + dependencies: + bytes "3.1.0" + http-errors "1.7.3" + iconv-lite "0.4.24" + unpipe "1.0.0" + +rc@^1.2.7: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +rdf-canonize@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/rdf-canonize/-/rdf-canonize-3.0.0.tgz#f5bade563e5e58f5cc5881afcba3c43839e8c747" + integrity sha512-LXRkhab1QaPJnhUIt1gtXXKswQCZ9zpflsSZFczG7mCLAkMvVjdqCGk9VXCUss0aOUeEyV2jtFxGcdX8DSkj9w== + dependencies: + setimmediate "^1.0.5" + +re2@1.16.0: + version "1.16.0" + resolved "https://registry.yarnpkg.com/re2/-/re2-1.16.0.tgz#f311eb4865b1296123800ea8e013cec8dab25590" + integrity sha512-eizTZL2ZO0ZseLqfD4t3Qd0M3b3Nr0MBWpX81EbPMIud/1d/CSfUIx2GQK8fWiAeHoSekO5EOeFib2udTZLwYw== + dependencies: + install-artifact-from-github "^1.2.0" + nan "^2.14.2" + node-gyp "^8.0.0" + +readable-stream@1.1.x: + version "1.1.14" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk= + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readable-stream@^2.0.6, readable-stream@^2.2.2: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readable-web-to-node-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.0.tgz#4ca5408e70471069119d691934141a52de413955" + integrity sha512-HNmLb3n0SteGAs8HQlErYPGeO+y7cvL/mVUKtXeUkl0iCZ/2GIgKGrCFHyS7UXFnO8uc9U+0y3pYIzAPsjFfvA== + dependencies: + "@types/readable-stream" "^2.3.9" + readable-stream "^3.6.0" + +readdirp@~3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.3.0.tgz#984458d13a1e42e2e9f5841b129e162f369aff17" + integrity sha512-zz0pAkSPOXXm1viEwygWIPSPkcBYjW1xU5j/JBh5t9bGCJwa6f9+BJa6VaB2g+b55yVrmXzqkyLf4xaWYM0IkQ== + dependencies: + picomatch "^2.0.7" + +reconnecting-websocket@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/reconnecting-websocket/-/reconnecting-websocket-4.4.0.tgz#3b0e5b96ef119e78a03135865b8bb0af1b948783" + integrity sha512-D2E33ceRPga0NvTDhJmphEgJ7FUYF0v4lr1ki0csq06OdlxKfugGzN0dSkxM/NfqCxYELK4KcaTOUOjTV6Dcng== + +redis-commands@1.7.0, redis-commands@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/redis-commands/-/redis-commands-1.7.0.tgz#15a6fea2d58281e27b1cd1acfb4b293e278c3a89" + integrity sha512-nJWqw3bTFy21hX/CPKHth6sfhZbdiHP6bTawSgQBlKOVRG7EZkfHbbHwQJnrE4vsQf0CMNE+3gJ4Fmm16vdVlQ== + +redis-errors@^1.0.0, redis-errors@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/redis-errors/-/redis-errors-1.2.0.tgz#eb62d2adb15e4eaf4610c04afe1529384250abad" + integrity sha1-62LSrbFeTq9GEMBK/hUpOEJQq60= + +redis-lock@0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/redis-lock/-/redis-lock-0.1.4.tgz#e83590bee22b5f01cdb65bfbd88d988045356272" + integrity sha512-7/+zu86XVQfJVx1nHTzux5reglDiyUCDwmW7TSlvVezfhH2YLc/Rc8NE0ejQG+8/0lwKzm29/u/4+ogKeLosiA== + +redis-parser@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/redis-parser/-/redis-parser-3.0.0.tgz#b66d828cdcafe6b4b8a428a7def4c6bcac31c8b4" + integrity sha1-tm2CjNyv5rS4pCin3vTGvKwxyLQ= + dependencies: + redis-errors "^1.0.0" + +redis@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/redis/-/redis-3.1.2.tgz#766851117e80653d23e0ed536254677ab647638c" + integrity sha512-grn5KoZLr/qrRQVwoSkmzdbw6pwF+/rwODtrOr6vuBRiR/f3rjSTGupbF90Zpqm2oenix8Do6RV7pYEkGwlKkw== + dependencies: + denque "^1.5.0" + redis-commands "^1.7.0" + redis-errors "^1.2.0" + redis-parser "^3.0.0" + +reflect-metadata@0.1.13, reflect-metadata@^0.1.13: + version "0.1.13" + resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08" + integrity sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg== + +regenerator-runtime@^0.13.4: + version "0.13.7" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55" + integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew== + +regexpp@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" + integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== + +rename@1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/rename/-/rename-1.0.4.tgz#a0f25078fa4195e650f73050c7c12ccf689f430b" + integrity sha1-oPJQePpBleZQ9zBQx8Esz2ifQws= + dependencies: + debug "^2.5.2" + +repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= + +request-promise-core@1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.4.tgz#3eedd4223208d419867b78ce815167d10593a22f" + integrity sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw== + dependencies: + lodash "^4.17.19" + +request-promise-native@1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.9.tgz#e407120526a5efdc9a39b28a5679bf47b9d9dc28" + integrity sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g== + dependencies: + request-promise-core "1.1.4" + stealthy-require "^1.1.1" + tough-cookie "^2.3.3" + +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" + +request@2.88.2, request@^2.88.2: + version "2.88.2" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" + integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.3" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.5.0" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + +require-all@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/require-all/-/require-all-3.0.0.tgz#473d49704be310115ce124f77383b1ebd8671312" + integrity sha1-Rz1JcEvjEBFc4ST3c4Ox69hnExI= + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + +require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + +require-main-filename@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" + integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== + +resolve-alpn@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.0.0.tgz#745ad60b3d6aff4b4a48e01b8c0bdc70959e0e8c" + integrity sha512-rTuiIEqFmGxne4IovivKSDzld2lWW9QCjqv80SYjPgf+gS35eaCAjaP54CCwGAwBtnCsvNLYtqxe1Nw+i6JEmA== + +resolve-dir@^1.0.0, resolve-dir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" + integrity sha1-eaQGRMNivoLybv/nOcm7U4IEb0M= + dependencies: + expand-tilde "^2.0.0" + global-modules "^1.0.0" + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +resolve-path@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/resolve-path/-/resolve-path-1.4.0.tgz#c4bda9f5efb2fce65247873ab36bb4d834fe16f7" + integrity sha1-xL2p9e+y/OZSR4c6s2u02DT+Fvc= + dependencies: + http-errors "~1.6.2" + path-is-absolute "1.0.1" + +resolve@^1.15.1, resolve@^1.20.0: + version "1.20.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" + integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== + dependencies: + is-core-module "^2.2.0" + path-parse "^1.0.6" + +responselike@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.0.tgz#26391bcc3174f750f9a79eacc40a12a5c42d7723" + integrity sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw== + dependencies: + lowercase-keys "^2.0.0" + +retry@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" + integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rimraf@3.0.2, rimraf@^3.0.0, rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +rndstr@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/rndstr/-/rndstr-1.0.0.tgz#77e66fa8f9b4836853fdd91e50719591bb67d349" + integrity sha1-d+ZvqPm0g2hT/dkeUHGVkbtn00k= + dependencies: + rangestr "0.0.1" + seedrandom "2.4.2" + +rsvp@^4.8.5: + version "4.8.5" + resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734" + integrity sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA== + +run-parallel@^1.1.9: + version "1.1.9" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.9.tgz#c9dd3a7cf9f4b2c4b6244e173a6ed866e61dd679" + integrity sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q== + +rxjs@^6.6.3: + version "6.6.6" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.6.tgz#14d8417aa5a07c5e633995b525e1e3c0dec03b70" + integrity sha512-/oTwee4N4iWzAMAL9xdGKjkEHmIwupR3oXbQjCKywF1BeFohswF3vZdogbmEF6pZkOsXTzWkrZszrWpQTByYVg== + dependencies: + tslib "^1.9.0" + +s-age@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/s-age/-/s-age-1.1.2.tgz#c0cf15233ccc93f41de92ea42c36d957977d1ea2" + integrity sha512-aSN2TlF39WLoZA/6cgYSJZhKt63kJ4EaadejPWjWY9/h4rksIqvfWY3gfd+3uAegSM1IXsA9aWeEhJtkxkFQtA== + +safari-14-idb-fix@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/safari-14-idb-fix/-/safari-14-idb-fix-1.0.4.tgz#5c68ba63e2a8ae0d89a0aa1e13fe89e3aef7da19" + integrity sha512-4+Y2baQdgJpzu84d0QjySl70Kyygzf0pepVg8NVg4NnQEPpfC91fAn0baNvtStlCjUUxxiu0BOMiafa98fRRuA== + +safe-buffer@*: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@~5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" + integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== + +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +sanitize-html@2.5.3: + version "2.5.3" + resolved "https://registry.yarnpkg.com/sanitize-html/-/sanitize-html-2.5.3.tgz#91aa3dc760b072cdf92f9c6973747569b1ba1cd8" + integrity sha512-DGATXd1fs/Rm287/i5FBKVYSBBUL0iAaztOA1/RFhEs4yqo39/X52i/q/CwsfCUG5cilmXSBmnQmyWfnKhBlOg== + dependencies: + deepmerge "^4.2.2" + escape-string-regexp "^4.0.0" + htmlparser2 "^6.0.0" + is-plain-object "^5.0.0" + parse-srcset "^1.0.2" + postcss "^8.3.11" + +sax@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a" + integrity sha1-e45lYZCyKOgaZq6nSEgNgozS03o= + +sax@>=0.6.0, sax@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + +saxes@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d" + integrity sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw== + dependencies: + xmlchars "^2.2.0" + +schema-utils@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.0.0.tgz#67502f6aa2b66a2d4032b4279a2944978a0913ef" + integrity sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA== + dependencies: + "@types/json-schema" "^7.0.6" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + +secure-json-parse@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/secure-json-parse/-/secure-json-parse-2.1.0.tgz#ae76f5624256b5c497af887090a5d9e156c9fb20" + integrity sha512-GckO+MS/wT4UogDyoI/H/S1L0MCcKS1XX/vp48wfmU7Nw4woBmb8mIpu4zPBQjKlRT88/bt9xdoV4111jPpNJA== + +seedrandom@2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/seedrandom/-/seedrandom-2.4.2.tgz#18d78c41287d13aff8eadb29e235938b248aa9ff" + integrity sha1-GNeMQSh9E6/46tsp4jWTiySKqf8= + +seedrandom@3.0.5: + version "3.0.5" + resolved "https://registry.yarnpkg.com/seedrandom/-/seedrandom-3.0.5.tgz#54edc85c95222525b0c7a6f6b3543d8e0b3aa0a7" + integrity sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg== + +semver@6.x: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +semver@^5.4.1, semver@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +semver@^7.2.1, semver@^7.3.2, semver@^7.3.4: + version "7.3.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.4.tgz#27aaa7d2e4ca76452f98d3add093a72c943edc97" + integrity sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw== + dependencies: + lru-cache "^6.0.0" + +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== + dependencies: + lru-cache "^6.0.0" + +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== + dependencies: + randombytes "^2.1.0" + +set-blocking@^2.0.0, set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + +setimmediate@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= + +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== + +setprototypeof@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" + integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== + +sha.js@^2.4.11: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +sharp@0.29.2: + version "0.29.2" + resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.29.2.tgz#e8c003cd9cb321585b32dbda6eed3baa7d6f2308" + integrity sha512-XWRdiYLIJ3tDUejRyG24KERnJzMfIoyiJBntd2S6/uj3NEeNgRFRLgiBlvPxMa8aml14dKKD98yHinSNKp1xzQ== + dependencies: + color "^4.0.1" + detect-libc "^1.0.3" + node-addon-api "^4.2.0" + prebuild-install "^6.1.4" + semver "^7.3.5" + simple-get "^3.1.0" + tar-fs "^2.1.1" + tunnel-agent "^0.6.0" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + +sigmund@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" + integrity sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA= + +signal-exit@^3.0.0, signal-exit@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" + integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== + +simple-concat@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.0.tgz#7344cbb8b6e26fb27d66b2fc86f9f6d5997521c6" + integrity sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY= + +simple-get@^3.0.3, simple-get@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-3.1.0.tgz#b45be062435e50d159540b576202ceec40b9c6b3" + integrity sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA== + dependencies: + decompress-response "^4.2.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" + integrity sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo= + dependencies: + is-arrayish "^0.3.1" + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +smart-buffer@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.1.0.tgz#91605c25d91652f4661ea69ccf45f1b331ca21ba" + integrity sha512-iVICrxOzCynf/SNaBQCw34eM9jROU/s5rzIhpOvzhzuYHfJR/DhZfDkXiZSgKXfgv26HT3Yni3AV/DGw0cGnnw== + +socks-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-5.0.0.tgz#7c0f364e7b1cf4a7a437e71253bed72e9004be60" + integrity sha512-lEpa1zsWCChxiynk+lCycKuC502RxDWLKJZoIhnxrWNjLSDGYRFflHA1/228VkRcnv9TIb8w98derGbpKxJRgA== + dependencies: + agent-base "6" + debug "4" + socks "^2.3.3" + +socks@^2.3.3: + version "2.6.1" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.6.1.tgz#989e6534a07cf337deb1b1c94aaa44296520d30e" + integrity sha512-kLQ9N5ucj8uIcxrDwjm0Jsqk06xdpBjGNQtpXy4Q8/QY2k+fY7nZH8CARy+hkbG+SGAovmzzuauCpBlb8FrnBA== + dependencies: + 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: + 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== + +spawn-command@^0.0.2-1: + version "0.0.2-1" + resolved "https://registry.yarnpkg.com/spawn-command/-/spawn-command-0.0.2-1.tgz#62f5e9466981c1b796dc5929937e11c9c6921bd0" + integrity sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A= + +speakeasy@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/speakeasy/-/speakeasy-2.0.0.tgz#85c91a071b09a5cb8642590d983566165f57613a" + integrity sha1-hckaBxsJpcuGQlkNmDVmFl9XYTo= + dependencies: + base32.js "0.0.1" + +split@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9" + integrity sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg== + dependencies: + through "2" + +sprintf-js@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.2.tgz#da1765262bf8c0f571749f2ad6c26300207ae673" + integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug== + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +sshpk@^1.14.1, sshpk@^1.7.0: + version "1.16.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" + integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + +ssri@^8.0.0, ssri@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.1.tgz#638e4e439e2ffbd2cd289776d5ca457c4f51a2af" + integrity sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ== + dependencies: + minipass "^3.1.1" + +stable@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" + integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== + +standard-as-callback@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/standard-as-callback/-/standard-as-callback-2.1.0.tgz#8953fc05359868a77b5b9739a665c5977bb7df45" + integrity sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A== + +"statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2", statuses@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= + +stealthy-require@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" + integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= + +stream-parser@~0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/stream-parser/-/stream-parser-0.3.1.tgz#1618548694420021a1182ff0af1911c129761773" + integrity sha1-FhhUhpRCACGhGC/wrxkRwSl2F3M= + dependencies: + debug "2" + +streamsearch@0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a" + integrity sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo= + +strict-event-emitter-types@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strict-event-emitter-types/-/strict-event-emitter-types-2.0.0.tgz#05e15549cb4da1694478a53543e4e2f4abcf277f" + integrity sha512-Nk/brWYpD85WlOgzw5h173aci0Teyv8YdIAEtV+N88nDB0dLlazZyJMIsN6eo1/AR61l+p6CJTG1JIyFaoNEEA== + +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +"string-width@^1.0.2 || 2": + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string-width@^3.0.0, string-width@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" + integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== + dependencies: + emoji-regex "^7.0.1" + is-fullwidth-code-point "^2.0.0" + strip-ansi "^5.1.0" + +string-width@^4.1.0, string-width@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" + integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.0" + +string.prototype.trimend@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz#85812a6b847ac002270f5808146064c995fb6913" + integrity sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" + +string.prototype.trimend@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80" + integrity sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +string.prototype.trimleft@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz#4408aa2e5d6ddd0c9a80739b087fbc067c03b3cc" + integrity sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" + string.prototype.trimstart "^1.0.0" + +string.prototype.trimright@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz#c76f1cef30f21bbad8afeb8db1511496cfb0f2a3" + integrity sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" + string.prototype.trimend "^1.0.0" + +string.prototype.trimstart@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz#14af6d9f34b053f7cfc89b72f8f2ee14b9039a54" + integrity sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" + +string.prototype.trimstart@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed" + integrity sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +stringz@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/stringz/-/stringz-2.1.0.tgz#5896b4713eac31157556040fb90258fb02c1630c" + integrity sha512-KlywLT+MZ+v0IRepfMxRtnSvDCMc3nR1qqCs3m/qIbSOWkNZYT8XHQA31rS3TnKp0c5xjZu3M4GY/2aRKSi/6A== + dependencies: + char-regex "^1.0.2" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= + dependencies: + ansi-regex "^3.0.0" + +strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" + integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== + dependencies: + ansi-regex "^4.1.0" + +strip-ansi@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" + integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== + dependencies: + ansi-regex "^5.0.0" + +strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= + +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + +strip-json-comments@3.1.1, strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= + +strtok3@^6.2.4: + version "6.2.4" + resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-6.2.4.tgz#302aea64c0fa25d12a0385069ba66253fdc38a81" + integrity sha512-GO8IcFF9GmFDvqduIspUBwCzCbqzegyVKIsSymcMgiZKeCfrN9SowtUoi8+b59WZMAjIzVZic/Ft97+pynR3Iw== + dependencies: + "@tokenizer/token" "^0.3.0" + peek-readable "^4.0.1" + +style-loader@3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.3.1.tgz#057dfa6b3d4d7c7064462830f9113ed417d38575" + integrity sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ== + +stylehacks@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-5.0.1.tgz#323ec554198520986806388c7fdaebc38d2c06fb" + integrity sha512-Es0rVnHIqbWzveU1b24kbw92HsebBepxfcqe5iix7t9j0PQqhs0IxXVXv0pY2Bxa08CgMkzD6OWql7kbGOuEdA== + dependencies: + browserslist "^4.16.0" + postcss-selector-parser "^6.0.4" + +summaly@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/summaly/-/summaly-2.4.1.tgz#d2a8fa6bad10c1651eb0b849aab3009e87216a3d" + integrity sha512-1gETEQXqK5RD7yIGgdGeTwGL1uh+uj14u99atzNLNmvsxwdtZbPvDHZBPXkAW0cqsd8teoBJln5Dh1QeAhvGIg== + dependencies: + cheerio-httpcli "0.8.2" + debug "4.3.2" + escape-regexp "0.0.1" + html-entities "2.3.2" + koa "2.13.1" + request "2.88.2" + request-promise-native "1.0.9" + require-all "3.0.0" + trace-redirect "1.0.6" + +supports-color@8.1.1, supports-color@^8.1.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.0.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== + dependencies: + has-flag "^4.0.0" + +svgo@^2.7.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/svgo/-/svgo-2.8.0.tgz#4ff80cce6710dc2795f0c7c74101e6764cfccd24" + integrity sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg== + dependencies: + "@trysound/sax" "0.2.0" + commander "^7.2.0" + css-select "^4.1.3" + css-tree "^1.1.3" + csso "^4.2.0" + picocolors "^1.0.0" + stable "^0.1.8" + +symbol-tree@^3.2.4: + version "3.2.4" + resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" + integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== + +syslog-pro@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/syslog-pro/-/syslog-pro-1.0.0.tgz#e46bfd39f58937352645091e84a3b903f39e12ea" + integrity sha512-7SNMJKtQBJlwBUp1jxFT7bXya71cnINXPCYJ2AVhlQE4MKL7o2QiPdAXbMdWRiLeykQ2rx+7TNrnoGzvzhO+eA== + 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== + +tapable@^2.1.1, tapable@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.0.tgz#5c373d281d9c672848213d0e037d1c4165ab426b" + integrity sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw== + +tar-fs@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.0.1.tgz#e44086c1c60d31a4f0cf893b1c4e155dabfae9e2" + integrity sha512-6tzWDMeroL87uF/+lin46k+Q+46rAJ0SyPGz7OW7wTgblI273hsBqk2C1j0/xNadNLKDTUL9BukSjB7cwgmlPA== + dependencies: + chownr "^1.1.1" + mkdirp-classic "^0.5.2" + pump "^3.0.0" + tar-stream "^2.0.0" + +tar-fs@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" + integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== + dependencies: + chownr "^1.1.1" + mkdirp-classic "^0.5.2" + pump "^3.0.0" + tar-stream "^2.1.4" + +tar-stream@^2.0.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.1.2.tgz#6d5ef1a7e5783a95ff70b69b97455a5968dc1325" + integrity sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q== + dependencies: + bl "^4.0.1" + end-of-stream "^1.4.1" + fs-constants "^1.0.0" + inherits "^2.0.3" + readable-stream "^3.1.1" + +tar-stream@^2.1.4: + version "2.2.0" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" + integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== + dependencies: + bl "^4.0.3" + end-of-stream "^1.4.1" + fs-constants "^1.0.0" + inherits "^2.0.3" + readable-stream "^3.1.1" + +tar@^6.0.2: + version "6.0.5" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.0.5.tgz#bde815086e10b39f1dcd298e89d596e1535e200f" + integrity sha512-0b4HOimQHj9nXNEAA7zWwMM91Zhhba3pspja6sQbgTpynOJf+bkjBnfybNYzbpLbnwXnbyB4LOREvlyXLkCHSg== + dependencies: + chownr "^2.0.0" + fs-minipass "^2.0.0" + minipass "^3.0.0" + minizlib "^2.1.1" + mkdirp "^1.0.3" + yallist "^4.0.0" + +tar@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.0.tgz#d1724e9bcc04b977b18d5c573b333a2207229a83" + integrity sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA== + dependencies: + chownr "^2.0.0" + fs-minipass "^2.0.0" + minipass "^3.0.0" + minizlib "^2.1.1" + 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" + integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= + +thenify-all@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" + integrity sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY= + dependencies: + thenify ">= 3.1.0 < 4" + +"thenify@>= 3.1.0 < 4": + version "3.3.1" + resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f" + integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw== + dependencies: + any-promise "^1.0.0" + +throttle-debounce@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/throttle-debounce/-/throttle-debounce-3.0.1.tgz#32f94d84dfa894f786c9a1f290e7a645b6a19abb" + integrity sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg== + +through@2: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= + +timsort@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4" + integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q= + +tinycolor2@1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.4.2.tgz#3f6a4d1071ad07676d7fa472e1fac40a719d8803" + integrity sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA== + +tmp@0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" + integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== + dependencies: + rimraf "^3.0.0" + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +toidentifier@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" + integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== + +token-stream@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/token-stream/-/token-stream-1.0.0.tgz#cc200eab2613f4166d27ff9afc7ca56d49df6eb4" + integrity sha1-zCAOqyYT9BZtJ/+a/HylbUnfbrQ= + +token-types@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/token-types/-/token-types-4.1.1.tgz#ef9e8c8e2e0ded9f1b3f8dbaa46a3228b113ba1a" + integrity sha512-hD+QyuUAyI2spzsI0B7gf/jJ2ggR4RjkAo37j3StuePhApJUwcWDjnHDOFdIWYSwNR28H14hpwm4EI+V1Ted1w== + dependencies: + "@tokenizer/token" "^0.3.0" + ieee754 "^1.2.1" + +tough-cookie@^2.3.3, tough-cookie@^2.5.0, tough-cookie@~2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + +tough-cookie@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4" + integrity sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg== + dependencies: + psl "^1.1.33" + 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== + dependencies: + punycode "^2.1.1" + +trace-redirect@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/trace-redirect/-/trace-redirect-1.0.6.tgz#ac629b5bf8247d30dde5a35fe9811b811075b504" + integrity sha512-UUfa1DjjU5flcjMdaFIiIEGDTyu2y/IiMjOX4uGXa7meKBS4vD4f2Uy/tken9Qkd4Jsm4sRsfZcIIPqrRVF3Mg== + +tree-kill@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" + integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== + +ts-jest@^25.2.1: + version "25.5.1" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-25.5.1.tgz#2913afd08f28385d54f2f4e828be4d261f4337c7" + integrity sha512-kHEUlZMK8fn8vkxDjwbHlxXRB9dHYpyzqKIGDNxbzs+Rz+ssNDSDNusEK8Fk/sDd4xE6iKoQLfFkFVaskmTJyw== + dependencies: + bs-logger "0.x" + buffer-from "1.x" + fast-json-stable-stringify "2.x" + json5 "2.x" + lodash.memoize "4.x" + make-error "1.x" + micromatch "4.x" + mkdirp "0.x" + semver "6.x" + yargs-parser "18.x" + +ts-loader@9.2.6: + version "9.2.6" + resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.2.6.tgz#9937c4dd0a1e3dbbb5e433f8102a6601c6615d74" + integrity sha512-QMTC4UFzHmu9wU2VHZEmWWE9cUajjfcdcws+Gh7FhiO+Dy0RnR1bNz0YCHqhI0yRowCE9arVnNxYHqELOy9Hjw== + dependencies: + chalk "^4.1.0" + enhanced-resolve "^5.0.0" + micromatch "^4.0.0" + semver "^7.3.4" + +ts-node@10.4.0: + version "10.4.0" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.4.0.tgz#680f88945885f4e6cf450e7f0d6223dd404895f7" + integrity sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A== + dependencies: + "@cspotcode/source-map-support" "0.7.0" + "@tsconfig/node10" "^1.0.7" + "@tsconfig/node12" "^1.0.7" + "@tsconfig/node14" "^1.0.0" + "@tsconfig/node16" "^1.0.2" + acorn "^8.4.1" + acorn-walk "^8.1.1" + arg "^4.1.0" + create-require "^1.1.0" + diff "^4.0.1" + make-error "^1.1.1" + yn "3.1.1" + +tsc-alias@1.3.10: + version "1.3.10" + resolved "https://registry.yarnpkg.com/tsc-alias/-/tsc-alias-1.3.10.tgz#6ccf81c644092387ab9be3a3a75549a95eeffd80" + integrity sha512-7SF56qiV7Oh/bON+XjF/uAzEFqbmwCuEIHQyoTyVJAK80WnxaIyhO9TBwD/x8InIMU8lnvExQBOrgKkRPsHH+w== + dependencies: + "@jfonx/console-utils" "^1.0.3" + "@jfonx/file-utils" "^3.0.1" + chokidar "^3.5.0" + commander "^6.2.1" + find-node-modules "^2.1.0" + globby "^11.0.2" + normalize-path "^3.0.0" + +tsconfig-paths@3.11.0, tsconfig-paths@^3.11.0: + version "3.11.0" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz#954c1fe973da6339c78e06b03ce2e48810b65f36" + integrity sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA== + dependencies: + "@types/json5" "^0.0.29" + json5 "^1.0.1" + minimist "^1.2.0" + strip-bom "^3.0.0" + +tslib@^1.8.1, tslib@^1.9.0: + version "1.11.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35" + integrity sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA== + +tslib@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.2.0.tgz#fb2c475977e35e241311ede2693cee1ec6698f5c" + integrity sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w== + +tsscmp@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/tsscmp/-/tsscmp-1.0.6.tgz#85b99583ac3589ec4bfef825b5000aa911d605eb" + integrity sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA== + +tsutils@^3.21.0: + version "3.21.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" + integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== + dependencies: + tslib "^1.8.1" + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= + +twemoji-parser@13.1.0, twemoji-parser@13.1.x: + version "13.1.0" + resolved "https://registry.yarnpkg.com/twemoji-parser/-/twemoji-parser-13.1.0.tgz#65e7e449c59258791b22ac0b37077349127e3ea4" + integrity sha512-AQOzLJpYlpWMy8n+0ATyKKZzWlZBJN+G0C+5lhX7Ftc2PeEVdUU/7ns2Pn2vVje26AIZ/OHwFoUbdv6YYD/wGg== + +type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== + dependencies: + prelude-ls "^1.2.1" + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= + dependencies: + prelude-ls "~1.1.2" + +type-detect@4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== + +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + +type-is@^1.6.14, type-is@^1.6.16, type-is@^1.6.4: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +type-of@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/type-of/-/type-of-2.0.1.tgz#e72a1741896568e9f628378d816d6912f7f23972" + integrity sha1-5yoXQYllaOn2KDeNgW1pEvfyOXI= + +type@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" + integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== + +type@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/type/-/type-2.0.0.tgz#5f16ff6ef2eb44f260494dae271033b29c09a9c3" + integrity sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow== + +typedarray-to-buffer@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== + dependencies: + is-typedarray "^1.0.0" + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= + +typeorm@0.2.39: + version "0.2.39" + resolved "https://registry.yarnpkg.com/typeorm/-/typeorm-0.2.39.tgz#4d22fc68d114b2ca88a8d7b064f31af15e836ade" + integrity sha512-yQdvDpmmmn8wp1We25V76KIBPYR/lDbymNbGC++Uq8mSRhpHIPnlg26VAT4CF6Ypqx72zn8eqr+/72uSo7HdJQ== + dependencies: + "@sqltools/formatter" "^1.2.2" + app-root-path "^3.0.0" + buffer "^6.0.3" + chalk "^4.1.0" + cli-highlight "^2.1.11" + debug "^4.3.1" + dotenv "^8.2.0" + glob "^7.1.6" + js-yaml "^4.0.0" + mkdirp "^1.0.4" + reflect-metadata "^0.1.13" + sha.js "^2.4.11" + tslib "^2.1.0" + xml2js "^0.4.23" + yargs "^17.0.1" + zen-observable-ts "^1.0.0" + +typescript@4.4.4: + version "4.4.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.4.4.tgz#2cd01a1a1f160704d3101fd5a58ff0f9fcb8030c" + integrity sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA== + +ulid@2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/ulid/-/ulid-2.3.0.tgz#93063522771a9774121a84d126ecd3eb9804071f" + integrity sha512-keqHubrlpvT6G2wH0OEfSW4mquYRcbe/J8NMmveoQOjUqmo+hXtO+ORCpWhdbZ7k72UtY61BL7haGxW6enBnjw== + +unbox-primitive@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" + integrity sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw== + dependencies: + function-bind "^1.1.1" + has-bigints "^1.0.1" + has-symbols "^1.0.2" + which-boxed-primitive "^1.0.2" + +uniq@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" + integrity sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8= + +uniqs@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/uniqs/-/uniqs-2.0.0.tgz#ffede4b36b25290696e6e165d4a59edb998e6b02" + integrity sha1-/+3ks2slKQaW5uFl1KWe25mOawI= + +unique-filename@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" + integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== + dependencies: + unique-slug "^2.0.0" + +unique-slug@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c" + integrity sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w== + dependencies: + imurmurhash "^0.1.4" + +universalify@^0.1.0, universalify@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +unload@2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/unload/-/unload-2.3.1.tgz#9d16862d372a5ce5cb630ad1309c2fd6e35dacfe" + integrity sha512-MUZEiDqvAN9AIDRbbBnVYVvfcR6DrjCqeU2YQMmliFZl9uaBUjTkhuDQkBiyAy8ad5bx1TXVbqZ3gg7namsWjA== + dependencies: + "@babel/runtime" "^7.6.2" + detect-node "2.1.0" + +unpipe@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= + +uri-js@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" + integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== + dependencies: + punycode "^2.1.0" + +url@0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/url/-/url-0.10.3.tgz#021e4d9c7705f21bbf37d03ceb58767402774c64" + integrity sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ= + dependencies: + punycode "1.3.2" + querystring "0.2.0" + +urlsafe-base64@^1.0.0, urlsafe-base64@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/urlsafe-base64/-/urlsafe-base64-1.0.0.tgz#23f89069a6c62f46cf3a1d3b00169cefb90be0c6" + integrity sha1-I/iQaabGL0bPOh07ABac77kL4MY= + +utf-8-validate@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.2.tgz#63cfbccd85dc1f2b66cf7a1d0eebc08ed056bfb3" + integrity sha512-SwV++i2gTD5qh2XqaPzBnNX88N6HdyhQrNNRykvcS0QKvItV9u3vPEJr+X5Hhfb1JC0r0e1alL0iB09rY8+nmw== + dependencies: + node-gyp-build "~3.7.0" + +util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +util.promisify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.1.tgz#6baf7774b80eeb0f7520d8b81d07982a59abbaee" + integrity sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.2" + has-symbols "^1.0.1" + object.getownpropertydescriptors "^2.1.0" + +uuid@3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" + integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== + +uuid@7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-7.0.3.tgz#c5c9f2c8cf25dc0a372c4df1441c41f5bd0c680b" + integrity sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg== + +uuid@8.3.2, uuid@^8.3.0: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + +uuid@^3.3.2: + version "3.4.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== + +v8-compile-cache@^2.0.3: + version "2.2.0" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz#9471efa3ef9128d2f7c6a7ca39c4dd6b5055b132" + integrity sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q== + +valid-url@^1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/valid-url/-/valid-url-1.0.9.tgz#1c14479b40f1397a75782f115e4086447433a200" + integrity sha1-HBRHm0DxOXp1eC8RXkCGRHQzogA= + +vary@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= + +vendors@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.4.tgz#e2b800a53e7a29b93506c3cf41100d16c4c4ad8e" + integrity sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w== + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +void-elements@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-3.1.0.tgz#614f7fbf8d801f0bb5f0661f5b2f5785750e4f09" + integrity sha1-YU9/v42AHwu18GYfWy9XhXUOTwk= + +vue-eslint-parser@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-8.0.1.tgz#25e08b20a414551531f3e19f999902e1ecf45f13" + integrity sha512-lhWjDXJhe3UZw2uu3ztX51SJAPGPey1Tff2RK3TyZURwbuI4vximQLzz4nQfCv8CZq4xx7uIiogHMMoSJPr33A== + dependencies: + debug "^4.3.2" + eslint-scope "^6.0.0" + eslint-visitor-keys "^3.0.0" + espree "^9.0.0" + esquery "^1.4.0" + lodash "^4.17.21" + semver "^7.3.5" + +w3c-hr-time@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" + integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ== + 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== + dependencies: + glob-to-regexp "^0.4.1" + graceful-fs "^4.1.2" + +web-push@3.4.5: + version "3.4.5" + resolved "https://registry.yarnpkg.com/web-push/-/web-push-3.4.5.tgz#f94074ff150538872c7183e4d8881c8305920cf1" + integrity sha512-2njbTqZ6Q7ZqqK14YpK1GGmaZs3NmuGYF5b7abCXulUIWFSlSYcZ3NBJQRFcMiQDceD7vQknb8FUuvI1F7Qe/g== + dependencies: + asn1.js "^5.3.0" + http_ece "1.1.0" + https-proxy-agent "^5.0.0" + jws "^4.0.0" + minimist "^1.2.5" + urlsafe-base64 "^1.0.0" + +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" + +websocket@1.0.34: + version "1.0.34" + resolved "https://registry.yarnpkg.com/websocket/-/websocket-1.0.34.tgz#2bdc2602c08bf2c82253b730655c0ef7dcab3111" + integrity sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ== + dependencies: + bufferutil "^4.0.1" + debug "^2.2.0" + es5-ext "^0.10.50" + typedarray-to-buffer "^3.1.5" + 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== + dependencies: + iconv-lite "0.4.24" + +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-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== + dependencies: + lodash "^4.7.0" + tr46 "^2.0.2" + webidl-conversions "^6.1.0" + +which-boxed-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" + integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== + dependencies: + is-bigint "^1.0.1" + is-boolean-object "^1.1.0" + is-number-object "^1.0.4" + is-string "^1.0.5" + is-symbol "^1.0.3" + +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= + +which@2.0.2, which@^2.0.1, which@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +which@^1.1.1, which@^1.2.14: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +wide-align@1.1.3, wide-align@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== + dependencies: + string-width "^1.0.2 || 2" + +with@^7.0.0: + version "7.0.2" + resolved "https://registry.yarnpkg.com/with/-/with-7.0.2.tgz#ccee3ad542d25538a7a7a80aad212b9828495bac" + integrity sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w== + dependencies: + "@babel/parser" "^7.9.6" + "@babel/types" "^7.9.6" + assert-never "^1.2.1" + babel-walk "3.0.0-canary-5" + +word-wrap@^1.2.3, word-wrap@~1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + +workerpool@6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.1.0.tgz#a8e038b4c94569596852de7a8ea4228eefdeb37b" + integrity sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg== + +wrap-ansi@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" + integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== + dependencies: + ansi-styles "^3.2.0" + string-width "^3.0.0" + strip-ansi "^5.0.0" + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +ws@8.2.3: + version "8.2.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.2.3.tgz#63a56456db1b04367d0b721a0b80cae6d8becbba" + integrity sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA== + +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" + integrity sha512-icDf9M67bDge0F2qf02WKZq+s7mMO/SbPv67ZQPym6JThLEOdlWWLdB7VTVgRJp3ekgaiVItCAyH6aoKCPvfIA== + +xml-js@^1.6.11: + version "1.6.11" + resolved "https://registry.yarnpkg.com/xml-js/-/xml-js-1.6.11.tgz#927d2f6947f7f1c19a316dd8eea3614e8b18f8e9" + integrity sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g== + 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== + +xml2js@0.4.19: + version "0.4.19" + resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.19.tgz#686c20f213209e94abf0d1bcf1efaa291c7827a7" + integrity sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q== + dependencies: + sax ">=0.6.0" + xmlbuilder "~9.0.1" + +xml2js@^0.4.23: + version "0.4.23" + resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66" + integrity sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug== + dependencies: + sax ">=0.6.0" + xmlbuilder "~11.0.0" + +xmlbuilder@~11.0.0: + version "11.0.1" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" + integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== + +xmlbuilder@~9.0.1: + version "9.0.7" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d" + integrity sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0= + +xmlchars@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" + integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== + +xtend@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + +y18n@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.1.tgz#8db2b83c31c5d75099bb890b23f3094891e247d4" + integrity sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ== + +y18n@^5.0.5: + version "5.0.5" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.5.tgz#8769ec08d03b1ea2df2500acef561743bbb9ab18" + integrity sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg== + +yaeti@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/yaeti/-/yaeti-0.0.6.tgz#f26f484d72684cf42bedfb76970aa1608fbf9577" + integrity sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc= + +yallist@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yaml-ast-parser@0.0.43: + version "0.0.43" + resolved "https://registry.yarnpkg.com/yaml-ast-parser/-/yaml-ast-parser-0.0.43.tgz#e8a23e6fb4c38076ab92995c5dca33f3d3d7c9bb" + integrity sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A== + +yaml@^1.10.2: + version "1.10.2" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" + integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== + +yargs-parser@18.x: + version "18.1.3" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0" + integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs-parser@20.2.4, yargs-parser@^20.2.2: + version "20.2.4" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" + integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== + +yargs-parser@^13.1.2: + version "13.1.2" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" + integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs-unparser@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" + integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== + dependencies: + camelcase "^6.0.0" + decamelize "^4.0.0" + flat "^5.0.2" + is-plain-obj "^2.1.0" + +yargs@16.2.0, yargs@^16.0.0, yargs@^16.2.0: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + +yargs@^13.2.4: + version "13.3.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" + integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw== + dependencies: + cliui "^5.0.0" + find-up "^3.0.0" + get-caller-file "^2.0.1" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^3.0.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^13.1.2" + +yargs@^17.0.1: + version "17.1.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.1.1.tgz#c2a8091564bdb196f7c0a67c1d12e5b85b8067ba" + integrity sha512-c2k48R0PwKIqKhPMWjeiF6y2xY/gPMUlro0sgxqXpbOIohWiLNXWslsootttv7E1e73QPAMQSg5FeySbVcpsPQ== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + +ylru@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ylru/-/ylru-1.2.1.tgz#f576b63341547989c1de7ba288760923b27fe84f" + integrity sha512-faQrqNMzcPCHGVC2aaOINk13K+aaBDUPjGWl0teOXywElLjyVAB6Oe2jj62jHYtwsU49jXhScYbvPENK+6zAvQ== + +yn@3.1.1: + version "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" + integrity sha512-KmWcbz+9kKUeAQ8btY8m1SsEFgBcp7h/Uf3V5quhan7ZWdjGsf0JcGLULQiwOZibbFWnHkYq8Nn2AZbJabovQg== + dependencies: + "@types/zen-observable" "^0.8.2" + zen-observable "^0.8.15" + +zen-observable@^0.8.15: + version "0.8.15" + resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.8.15.tgz#96415c512d8e3ffd920afd3889604e30b9eaac15" + integrity sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ== diff --git a/packages/client/.eslintrc b/packages/client/.eslintrc new file mode 100644 index 000000000..b3b631e1d --- /dev/null +++ b/packages/client/.eslintrc @@ -0,0 +1,32 @@ +{ + "env": { + "node": false + }, + "extends": [ + "eslint:recommended", + "plugin:vue/recommended" + ], + "rules": { + "vue/require-v-for-key": 0, + "vue/max-attributes-per-line": 0, + "vue/html-indent": 0, + "vue/html-self-closing": 0, + "vue/no-unused-vars": 0, + "vue/attributes-order": 0, + "vue/require-prop-types": 0, + "vue/require-default-prop": 0, + "vue/html-closing-bracket-spacing": 0, + "vue/singleline-html-element-content-newline": 0, + "vue/no-v-html": 0 + }, + "globals": { + "_DEV_": false, + "_LANGS_": false, + "_VERSION_": false, + "_ENV_": false, + "_PERF_PREFIX_": false, + "_DATA_TRANSFER_DRIVE_FILE_": false, + "_DATA_TRANSFER_DRIVE_FOLDER_": false, + "_DATA_TRANSFER_DECK_COLUMN_": false + } +} diff --git a/packages/client/.npmrc b/packages/client/.npmrc new file mode 100644 index 000000000..6b5f38e89 --- /dev/null +++ b/packages/client/.npmrc @@ -0,0 +1,2 @@ +save-exact = true +package-lock = false diff --git a/packages/client/.yarnrc b/packages/client/.yarnrc new file mode 100644 index 000000000..788570fcd --- /dev/null +++ b/packages/client/.yarnrc @@ -0,0 +1 @@ +network-timeout 600000 diff --git a/packages/client/@types/global.d.ts b/packages/client/@types/global.d.ts new file mode 100644 index 000000000..c75748290 --- /dev/null +++ b/packages/client/@types/global.d.ts @@ -0,0 +1,10 @@ +type FIXME = any; + +declare const _LANGS_: string[][]; +declare const _VERSION_: string; +declare const _ENV_: string; +declare const _DEV_: boolean; +declare const _PERF_PREFIX_: string; +declare const _DATA_TRANSFER_DRIVE_FILE_: string; +declare const _DATA_TRANSFER_DRIVE_FOLDER_: string; +declare const _DATA_TRANSFER_DECK_COLUMN_: string; diff --git a/src/client/@types/vue.d.ts b/packages/client/@types/vue.d.ts similarity index 100% rename from src/client/@types/vue.d.ts rename to packages/client/@types/vue.d.ts diff --git a/assets/client/about-icon.png b/packages/client/assets/about-icon.png similarity index 100% rename from assets/client/about-icon.png rename to packages/client/assets/about-icon.png diff --git a/assets/client/fedi.jpg b/packages/client/assets/fedi.jpg similarity index 100% rename from assets/client/fedi.jpg rename to packages/client/assets/fedi.jpg diff --git a/assets/client/label-red.svg b/packages/client/assets/label-red.svg similarity index 100% rename from assets/client/label-red.svg rename to packages/client/assets/label-red.svg diff --git a/assets/client/label.svg b/packages/client/assets/label.svg similarity index 100% rename from assets/client/label.svg rename to packages/client/assets/label.svg diff --git a/assets/client/misskey.svg b/packages/client/assets/misskey.svg similarity index 100% rename from assets/client/misskey.svg rename to packages/client/assets/misskey.svg diff --git a/assets/client/remove.png b/packages/client/assets/remove.png similarity index 100% rename from assets/client/remove.png rename to packages/client/assets/remove.png diff --git a/assets/client/room/furnitures/banknote/banknote.blend b/packages/client/assets/room/furnitures/banknote/banknote.blend similarity index 100% rename from assets/client/room/furnitures/banknote/banknote.blend rename to packages/client/assets/room/furnitures/banknote/banknote.blend diff --git a/assets/client/room/furnitures/banknote/banknote.glb b/packages/client/assets/room/furnitures/banknote/banknote.glb similarity index 100% rename from assets/client/room/furnitures/banknote/banknote.glb rename to packages/client/assets/room/furnitures/banknote/banknote.glb diff --git a/assets/client/room/furnitures/banknote/tex.png b/packages/client/assets/room/furnitures/banknote/tex.png similarity index 100% rename from assets/client/room/furnitures/banknote/tex.png rename to packages/client/assets/room/furnitures/banknote/tex.png diff --git a/assets/client/room/furnitures/bed/bed.blend b/packages/client/assets/room/furnitures/bed/bed.blend similarity index 100% rename from assets/client/room/furnitures/bed/bed.blend rename to packages/client/assets/room/furnitures/bed/bed.blend diff --git a/assets/client/room/furnitures/bed/bed.glb b/packages/client/assets/room/furnitures/bed/bed.glb similarity index 100% rename from assets/client/room/furnitures/bed/bed.glb rename to packages/client/assets/room/furnitures/bed/bed.glb diff --git a/assets/client/room/furnitures/bin/bin.blend b/packages/client/assets/room/furnitures/bin/bin.blend similarity index 100% rename from assets/client/room/furnitures/bin/bin.blend rename to packages/client/assets/room/furnitures/bin/bin.blend diff --git a/assets/client/room/furnitures/bin/bin.glb b/packages/client/assets/room/furnitures/bin/bin.glb similarity index 100% rename from assets/client/room/furnitures/bin/bin.glb rename to packages/client/assets/room/furnitures/bin/bin.glb diff --git a/assets/client/room/furnitures/book/book.blend b/packages/client/assets/room/furnitures/book/book.blend similarity index 100% rename from assets/client/room/furnitures/book/book.blend rename to packages/client/assets/room/furnitures/book/book.blend diff --git a/assets/client/room/furnitures/book/book.glb b/packages/client/assets/room/furnitures/book/book.glb similarity index 100% rename from assets/client/room/furnitures/book/book.glb rename to packages/client/assets/room/furnitures/book/book.glb diff --git a/assets/client/room/furnitures/book2/barcode.png b/packages/client/assets/room/furnitures/book2/barcode.png similarity index 100% rename from assets/client/room/furnitures/book2/barcode.png rename to packages/client/assets/room/furnitures/book2/barcode.png diff --git a/assets/client/room/furnitures/book2/book2.blend b/packages/client/assets/room/furnitures/book2/book2.blend similarity index 100% rename from assets/client/room/furnitures/book2/book2.blend rename to packages/client/assets/room/furnitures/book2/book2.blend diff --git a/assets/client/room/furnitures/book2/book2.glb b/packages/client/assets/room/furnitures/book2/book2.glb similarity index 100% rename from assets/client/room/furnitures/book2/book2.glb rename to packages/client/assets/room/furnitures/book2/book2.glb diff --git a/assets/client/room/furnitures/book2/texture.afdesign b/packages/client/assets/room/furnitures/book2/texture.afdesign similarity index 100% rename from assets/client/room/furnitures/book2/texture.afdesign rename to packages/client/assets/room/furnitures/book2/texture.afdesign diff --git a/assets/client/room/furnitures/book2/texture.png b/packages/client/assets/room/furnitures/book2/texture.png similarity index 100% rename from assets/client/room/furnitures/book2/texture.png rename to packages/client/assets/room/furnitures/book2/texture.png diff --git a/assets/client/room/furnitures/book2/uv.png b/packages/client/assets/room/furnitures/book2/uv.png similarity index 100% rename from assets/client/room/furnitures/book2/uv.png rename to packages/client/assets/room/furnitures/book2/uv.png diff --git a/assets/client/room/furnitures/cardboard-box/cardboard-box.blend b/packages/client/assets/room/furnitures/cardboard-box/cardboard-box.blend similarity index 100% rename from assets/client/room/furnitures/cardboard-box/cardboard-box.blend rename to packages/client/assets/room/furnitures/cardboard-box/cardboard-box.blend diff --git a/assets/client/room/furnitures/cardboard-box/cardboard-box.glb b/packages/client/assets/room/furnitures/cardboard-box/cardboard-box.glb similarity index 100% rename from assets/client/room/furnitures/cardboard-box/cardboard-box.glb rename to packages/client/assets/room/furnitures/cardboard-box/cardboard-box.glb diff --git a/assets/client/room/furnitures/cardboard-box2/cardboard-box2.blend b/packages/client/assets/room/furnitures/cardboard-box2/cardboard-box2.blend similarity index 100% rename from assets/client/room/furnitures/cardboard-box2/cardboard-box2.blend rename to packages/client/assets/room/furnitures/cardboard-box2/cardboard-box2.blend diff --git a/assets/client/room/furnitures/cardboard-box2/cardboard-box2.glb b/packages/client/assets/room/furnitures/cardboard-box2/cardboard-box2.glb similarity index 100% rename from assets/client/room/furnitures/cardboard-box2/cardboard-box2.glb rename to packages/client/assets/room/furnitures/cardboard-box2/cardboard-box2.glb diff --git a/assets/client/room/furnitures/cardboard-box2/texture.png b/packages/client/assets/room/furnitures/cardboard-box2/texture.png similarity index 100% rename from assets/client/room/furnitures/cardboard-box2/texture.png rename to packages/client/assets/room/furnitures/cardboard-box2/texture.png diff --git a/assets/client/room/furnitures/cardboard-box2/uv.png b/packages/client/assets/room/furnitures/cardboard-box2/uv.png similarity index 100% rename from assets/client/room/furnitures/cardboard-box2/uv.png rename to packages/client/assets/room/furnitures/cardboard-box2/uv.png diff --git a/assets/client/room/furnitures/cardboard-box3/cardboard-box3.blend b/packages/client/assets/room/furnitures/cardboard-box3/cardboard-box3.blend similarity index 100% rename from assets/client/room/furnitures/cardboard-box3/cardboard-box3.blend rename to packages/client/assets/room/furnitures/cardboard-box3/cardboard-box3.blend diff --git a/assets/client/room/furnitures/cardboard-box3/cardboard-box3.glb b/packages/client/assets/room/furnitures/cardboard-box3/cardboard-box3.glb similarity index 100% rename from assets/client/room/furnitures/cardboard-box3/cardboard-box3.glb rename to packages/client/assets/room/furnitures/cardboard-box3/cardboard-box3.glb diff --git a/assets/client/room/furnitures/cardboard-box3/texture.png b/packages/client/assets/room/furnitures/cardboard-box3/texture.png similarity index 100% rename from assets/client/room/furnitures/cardboard-box3/texture.png rename to packages/client/assets/room/furnitures/cardboard-box3/texture.png diff --git a/assets/client/room/furnitures/cardboard-box3/texture.xcf b/packages/client/assets/room/furnitures/cardboard-box3/texture.xcf similarity index 100% rename from assets/client/room/furnitures/cardboard-box3/texture.xcf rename to packages/client/assets/room/furnitures/cardboard-box3/texture.xcf diff --git a/assets/client/room/furnitures/cardboard-box3/uv.png b/packages/client/assets/room/furnitures/cardboard-box3/uv.png similarity index 100% rename from assets/client/room/furnitures/cardboard-box3/uv.png rename to packages/client/assets/room/furnitures/cardboard-box3/uv.png diff --git a/assets/client/room/furnitures/carpet-stripe/carpet-stripe.blend b/packages/client/assets/room/furnitures/carpet-stripe/carpet-stripe.blend similarity index 100% rename from assets/client/room/furnitures/carpet-stripe/carpet-stripe.blend rename to packages/client/assets/room/furnitures/carpet-stripe/carpet-stripe.blend diff --git a/assets/client/room/furnitures/carpet-stripe/carpet-stripe.glb b/packages/client/assets/room/furnitures/carpet-stripe/carpet-stripe.glb similarity index 100% rename from assets/client/room/furnitures/carpet-stripe/carpet-stripe.glb rename to packages/client/assets/room/furnitures/carpet-stripe/carpet-stripe.glb diff --git a/assets/client/room/furnitures/chair/chair.blend b/packages/client/assets/room/furnitures/chair/chair.blend similarity index 100% rename from assets/client/room/furnitures/chair/chair.blend rename to packages/client/assets/room/furnitures/chair/chair.blend diff --git a/assets/client/room/furnitures/chair/chair.glb b/packages/client/assets/room/furnitures/chair/chair.glb similarity index 100% rename from assets/client/room/furnitures/chair/chair.glb rename to packages/client/assets/room/furnitures/chair/chair.glb diff --git a/assets/client/room/furnitures/chair2/chair2.blend b/packages/client/assets/room/furnitures/chair2/chair2.blend similarity index 100% rename from assets/client/room/furnitures/chair2/chair2.blend rename to packages/client/assets/room/furnitures/chair2/chair2.blend diff --git a/assets/client/room/furnitures/chair2/chair2.glb b/packages/client/assets/room/furnitures/chair2/chair2.glb similarity index 100% rename from assets/client/room/furnitures/chair2/chair2.glb rename to packages/client/assets/room/furnitures/chair2/chair2.glb diff --git a/assets/client/room/furnitures/color-box/color-box.blend b/packages/client/assets/room/furnitures/color-box/color-box.blend similarity index 100% rename from assets/client/room/furnitures/color-box/color-box.blend rename to packages/client/assets/room/furnitures/color-box/color-box.blend diff --git a/assets/client/room/furnitures/color-box/color-box.glb b/packages/client/assets/room/furnitures/color-box/color-box.glb similarity index 100% rename from assets/client/room/furnitures/color-box/color-box.glb rename to packages/client/assets/room/furnitures/color-box/color-box.glb diff --git a/assets/client/room/furnitures/corkboard/corkboard.blend b/packages/client/assets/room/furnitures/corkboard/corkboard.blend similarity index 100% rename from assets/client/room/furnitures/corkboard/corkboard.blend rename to packages/client/assets/room/furnitures/corkboard/corkboard.blend diff --git a/assets/client/room/furnitures/corkboard/corkboard.glb b/packages/client/assets/room/furnitures/corkboard/corkboard.glb similarity index 100% rename from assets/client/room/furnitures/corkboard/corkboard.glb rename to packages/client/assets/room/furnitures/corkboard/corkboard.glb diff --git a/assets/client/room/furnitures/cube/cube.blend b/packages/client/assets/room/furnitures/cube/cube.blend similarity index 100% rename from assets/client/room/furnitures/cube/cube.blend rename to packages/client/assets/room/furnitures/cube/cube.blend diff --git a/assets/client/room/furnitures/cube/cube.glb b/packages/client/assets/room/furnitures/cube/cube.glb similarity index 100% rename from assets/client/room/furnitures/cube/cube.glb rename to packages/client/assets/room/furnitures/cube/cube.glb diff --git a/assets/client/room/furnitures/cup-noodle/cup-noodle.blend b/packages/client/assets/room/furnitures/cup-noodle/cup-noodle.blend similarity index 100% rename from assets/client/room/furnitures/cup-noodle/cup-noodle.blend rename to packages/client/assets/room/furnitures/cup-noodle/cup-noodle.blend diff --git a/assets/client/room/furnitures/cup-noodle/cup-noodle.glb b/packages/client/assets/room/furnitures/cup-noodle/cup-noodle.glb similarity index 100% rename from assets/client/room/furnitures/cup-noodle/cup-noodle.glb rename to packages/client/assets/room/furnitures/cup-noodle/cup-noodle.glb diff --git a/assets/client/room/furnitures/cup-noodle/noodle.png b/packages/client/assets/room/furnitures/cup-noodle/noodle.png similarity index 100% rename from assets/client/room/furnitures/cup-noodle/noodle.png rename to packages/client/assets/room/furnitures/cup-noodle/noodle.png diff --git a/assets/client/room/furnitures/desk/desk.blend b/packages/client/assets/room/furnitures/desk/desk.blend similarity index 100% rename from assets/client/room/furnitures/desk/desk.blend rename to packages/client/assets/room/furnitures/desk/desk.blend diff --git a/assets/client/room/furnitures/desk/desk.glb b/packages/client/assets/room/furnitures/desk/desk.glb similarity index 100% rename from assets/client/room/furnitures/desk/desk.glb rename to packages/client/assets/room/furnitures/desk/desk.glb diff --git a/assets/client/room/furnitures/doll-ai/doll-ai.blend b/packages/client/assets/room/furnitures/doll-ai/doll-ai.blend similarity index 100% rename from assets/client/room/furnitures/doll-ai/doll-ai.blend rename to packages/client/assets/room/furnitures/doll-ai/doll-ai.blend diff --git a/assets/client/room/furnitures/doll-ai/doll-ai.glb b/packages/client/assets/room/furnitures/doll-ai/doll-ai.glb similarity index 100% rename from assets/client/room/furnitures/doll-ai/doll-ai.glb rename to packages/client/assets/room/furnitures/doll-ai/doll-ai.glb diff --git a/assets/client/room/furnitures/doll-ai/doll_ai_tex.png b/packages/client/assets/room/furnitures/doll-ai/doll_ai_tex.png similarity index 100% rename from assets/client/room/furnitures/doll-ai/doll_ai_tex.png rename to packages/client/assets/room/furnitures/doll-ai/doll_ai_tex.png diff --git a/assets/client/room/furnitures/energy-drink/energy-drink.blend b/packages/client/assets/room/furnitures/energy-drink/energy-drink.blend similarity index 100% rename from assets/client/room/furnitures/energy-drink/energy-drink.blend rename to packages/client/assets/room/furnitures/energy-drink/energy-drink.blend diff --git a/assets/client/room/furnitures/energy-drink/energy-drink.glb b/packages/client/assets/room/furnitures/energy-drink/energy-drink.glb similarity index 100% rename from assets/client/room/furnitures/energy-drink/energy-drink.glb rename to packages/client/assets/room/furnitures/energy-drink/energy-drink.glb diff --git a/assets/client/room/furnitures/energy-drink/texture.afdesign b/packages/client/assets/room/furnitures/energy-drink/texture.afdesign similarity index 100% rename from assets/client/room/furnitures/energy-drink/texture.afdesign rename to packages/client/assets/room/furnitures/energy-drink/texture.afdesign diff --git a/assets/client/room/furnitures/energy-drink/texture.png b/packages/client/assets/room/furnitures/energy-drink/texture.png similarity index 100% rename from assets/client/room/furnitures/energy-drink/texture.png rename to packages/client/assets/room/furnitures/energy-drink/texture.png diff --git a/assets/client/room/furnitures/energy-drink/uv.png b/packages/client/assets/room/furnitures/energy-drink/uv.png similarity index 100% rename from assets/client/room/furnitures/energy-drink/uv.png rename to packages/client/assets/room/furnitures/energy-drink/uv.png diff --git a/assets/client/room/furnitures/eraser/cover.png b/packages/client/assets/room/furnitures/eraser/cover.png similarity index 100% rename from assets/client/room/furnitures/eraser/cover.png rename to packages/client/assets/room/furnitures/eraser/cover.png diff --git a/assets/client/room/furnitures/eraser/cover.psd b/packages/client/assets/room/furnitures/eraser/cover.psd similarity index 100% rename from assets/client/room/furnitures/eraser/cover.psd rename to packages/client/assets/room/furnitures/eraser/cover.psd diff --git a/assets/client/room/furnitures/eraser/eraser-uv.png b/packages/client/assets/room/furnitures/eraser/eraser-uv.png similarity index 100% rename from assets/client/room/furnitures/eraser/eraser-uv.png rename to packages/client/assets/room/furnitures/eraser/eraser-uv.png diff --git a/assets/client/room/furnitures/eraser/eraser.blend b/packages/client/assets/room/furnitures/eraser/eraser.blend similarity index 100% rename from assets/client/room/furnitures/eraser/eraser.blend rename to packages/client/assets/room/furnitures/eraser/eraser.blend diff --git a/assets/client/room/furnitures/eraser/eraser.glb b/packages/client/assets/room/furnitures/eraser/eraser.glb similarity index 100% rename from assets/client/room/furnitures/eraser/eraser.glb rename to packages/client/assets/room/furnitures/eraser/eraser.glb diff --git a/assets/client/room/furnitures/facial-tissue/facial-tissue-uv.png b/packages/client/assets/room/furnitures/facial-tissue/facial-tissue-uv.png similarity index 100% rename from assets/client/room/furnitures/facial-tissue/facial-tissue-uv.png rename to packages/client/assets/room/furnitures/facial-tissue/facial-tissue-uv.png diff --git a/assets/client/room/furnitures/facial-tissue/facial-tissue.blend b/packages/client/assets/room/furnitures/facial-tissue/facial-tissue.blend similarity index 100% rename from assets/client/room/furnitures/facial-tissue/facial-tissue.blend rename to packages/client/assets/room/furnitures/facial-tissue/facial-tissue.blend diff --git a/assets/client/room/furnitures/facial-tissue/facial-tissue.glb b/packages/client/assets/room/furnitures/facial-tissue/facial-tissue.glb similarity index 100% rename from assets/client/room/furnitures/facial-tissue/facial-tissue.glb rename to packages/client/assets/room/furnitures/facial-tissue/facial-tissue.glb diff --git a/assets/client/room/furnitures/facial-tissue/facial-tissue.png b/packages/client/assets/room/furnitures/facial-tissue/facial-tissue.png similarity index 100% rename from assets/client/room/furnitures/facial-tissue/facial-tissue.png rename to packages/client/assets/room/furnitures/facial-tissue/facial-tissue.png diff --git a/assets/client/room/furnitures/facial-tissue/facial-tissue.psd b/packages/client/assets/room/furnitures/facial-tissue/facial-tissue.psd similarity index 100% rename from assets/client/room/furnitures/facial-tissue/facial-tissue.psd rename to packages/client/assets/room/furnitures/facial-tissue/facial-tissue.psd diff --git a/assets/client/room/furnitures/fan/fan.blend b/packages/client/assets/room/furnitures/fan/fan.blend similarity index 100% rename from assets/client/room/furnitures/fan/fan.blend rename to packages/client/assets/room/furnitures/fan/fan.blend diff --git a/assets/client/room/furnitures/fan/fan.glb b/packages/client/assets/room/furnitures/fan/fan.glb similarity index 100% rename from assets/client/room/furnitures/fan/fan.glb rename to packages/client/assets/room/furnitures/fan/fan.glb diff --git a/assets/client/room/furnitures/holo-display/holo-display.blend b/packages/client/assets/room/furnitures/holo-display/holo-display.blend similarity index 100% rename from assets/client/room/furnitures/holo-display/holo-display.blend rename to packages/client/assets/room/furnitures/holo-display/holo-display.blend diff --git a/assets/client/room/furnitures/holo-display/holo-display.glb b/packages/client/assets/room/furnitures/holo-display/holo-display.glb similarity index 100% rename from assets/client/room/furnitures/holo-display/holo-display.glb rename to packages/client/assets/room/furnitures/holo-display/holo-display.glb diff --git a/assets/client/room/furnitures/holo-display/ray-uv.png b/packages/client/assets/room/furnitures/holo-display/ray-uv.png similarity index 100% rename from assets/client/room/furnitures/holo-display/ray-uv.png rename to packages/client/assets/room/furnitures/holo-display/ray-uv.png diff --git a/assets/client/room/furnitures/holo-display/ray.png b/packages/client/assets/room/furnitures/holo-display/ray.png similarity index 100% rename from assets/client/room/furnitures/holo-display/ray.png rename to packages/client/assets/room/furnitures/holo-display/ray.png diff --git a/assets/client/room/furnitures/keyboard/keyboard.blend b/packages/client/assets/room/furnitures/keyboard/keyboard.blend similarity index 100% rename from assets/client/room/furnitures/keyboard/keyboard.blend rename to packages/client/assets/room/furnitures/keyboard/keyboard.blend diff --git a/assets/client/room/furnitures/keyboard/keyboard.glb b/packages/client/assets/room/furnitures/keyboard/keyboard.glb similarity index 100% rename from assets/client/room/furnitures/keyboard/keyboard.glb rename to packages/client/assets/room/furnitures/keyboard/keyboard.glb diff --git a/assets/client/room/furnitures/low-table/low-table.blend b/packages/client/assets/room/furnitures/low-table/low-table.blend similarity index 100% rename from assets/client/room/furnitures/low-table/low-table.blend rename to packages/client/assets/room/furnitures/low-table/low-table.blend diff --git a/assets/client/room/furnitures/low-table/low-table.glb b/packages/client/assets/room/furnitures/low-table/low-table.glb similarity index 100% rename from assets/client/room/furnitures/low-table/low-table.glb rename to packages/client/assets/room/furnitures/low-table/low-table.glb diff --git a/assets/client/room/furnitures/mat/mat.blend b/packages/client/assets/room/furnitures/mat/mat.blend similarity index 100% rename from assets/client/room/furnitures/mat/mat.blend rename to packages/client/assets/room/furnitures/mat/mat.blend diff --git a/assets/client/room/furnitures/mat/mat.glb b/packages/client/assets/room/furnitures/mat/mat.glb similarity index 100% rename from assets/client/room/furnitures/mat/mat.glb rename to packages/client/assets/room/furnitures/mat/mat.glb diff --git a/assets/client/room/furnitures/milk/milk-uv.png b/packages/client/assets/room/furnitures/milk/milk-uv.png similarity index 100% rename from assets/client/room/furnitures/milk/milk-uv.png rename to packages/client/assets/room/furnitures/milk/milk-uv.png diff --git a/assets/client/room/furnitures/milk/milk.blend b/packages/client/assets/room/furnitures/milk/milk.blend similarity index 100% rename from assets/client/room/furnitures/milk/milk.blend rename to packages/client/assets/room/furnitures/milk/milk.blend diff --git a/assets/client/room/furnitures/milk/milk.glb b/packages/client/assets/room/furnitures/milk/milk.glb similarity index 100% rename from assets/client/room/furnitures/milk/milk.glb rename to packages/client/assets/room/furnitures/milk/milk.glb diff --git a/assets/client/room/furnitures/milk/milk.png b/packages/client/assets/room/furnitures/milk/milk.png similarity index 100% rename from assets/client/room/furnitures/milk/milk.png rename to packages/client/assets/room/furnitures/milk/milk.png diff --git a/assets/client/room/furnitures/milk/milk.psd b/packages/client/assets/room/furnitures/milk/milk.psd similarity index 100% rename from assets/client/room/furnitures/milk/milk.psd rename to packages/client/assets/room/furnitures/milk/milk.psd diff --git a/assets/client/room/furnitures/monitor/monitor.blend b/packages/client/assets/room/furnitures/monitor/monitor.blend similarity index 100% rename from assets/client/room/furnitures/monitor/monitor.blend rename to packages/client/assets/room/furnitures/monitor/monitor.blend diff --git a/assets/client/room/furnitures/monitor/monitor.glb b/packages/client/assets/room/furnitures/monitor/monitor.glb similarity index 100% rename from assets/client/room/furnitures/monitor/monitor.glb rename to packages/client/assets/room/furnitures/monitor/monitor.glb diff --git a/assets/client/room/furnitures/monitor/monitor.psd b/packages/client/assets/room/furnitures/monitor/monitor.psd similarity index 100% rename from assets/client/room/furnitures/monitor/monitor.psd rename to packages/client/assets/room/furnitures/monitor/monitor.psd diff --git a/assets/client/room/furnitures/monitor/screen-uv.png b/packages/client/assets/room/furnitures/monitor/screen-uv.png similarity index 100% rename from assets/client/room/furnitures/monitor/screen-uv.png rename to packages/client/assets/room/furnitures/monitor/screen-uv.png diff --git a/assets/client/room/furnitures/monitor/screen.jpg b/packages/client/assets/room/furnitures/monitor/screen.jpg similarity index 100% rename from assets/client/room/furnitures/monitor/screen.jpg rename to packages/client/assets/room/furnitures/monitor/screen.jpg diff --git a/assets/client/room/furnitures/moon/moon.blend b/packages/client/assets/room/furnitures/moon/moon.blend similarity index 100% rename from assets/client/room/furnitures/moon/moon.blend rename to packages/client/assets/room/furnitures/moon/moon.blend diff --git a/assets/client/room/furnitures/moon/moon.glb b/packages/client/assets/room/furnitures/moon/moon.glb similarity index 100% rename from assets/client/room/furnitures/moon/moon.glb rename to packages/client/assets/room/furnitures/moon/moon.glb diff --git a/assets/client/room/furnitures/moon/moon.jpg b/packages/client/assets/room/furnitures/moon/moon.jpg similarity index 100% rename from assets/client/room/furnitures/moon/moon.jpg rename to packages/client/assets/room/furnitures/moon/moon.jpg diff --git a/assets/client/room/furnitures/mousepad/mousepad.blend b/packages/client/assets/room/furnitures/mousepad/mousepad.blend similarity index 100% rename from assets/client/room/furnitures/mousepad/mousepad.blend rename to packages/client/assets/room/furnitures/mousepad/mousepad.blend diff --git a/assets/client/room/furnitures/mousepad/mousepad.glb b/packages/client/assets/room/furnitures/mousepad/mousepad.glb similarity index 100% rename from assets/client/room/furnitures/mousepad/mousepad.glb rename to packages/client/assets/room/furnitures/mousepad/mousepad.glb diff --git a/assets/client/room/furnitures/pc/motherboard-uv.png b/packages/client/assets/room/furnitures/pc/motherboard-uv.png similarity index 100% rename from assets/client/room/furnitures/pc/motherboard-uv.png rename to packages/client/assets/room/furnitures/pc/motherboard-uv.png diff --git a/assets/client/room/furnitures/pc/motherboard-uv.psd b/packages/client/assets/room/furnitures/pc/motherboard-uv.psd similarity index 100% rename from assets/client/room/furnitures/pc/motherboard-uv.psd rename to packages/client/assets/room/furnitures/pc/motherboard-uv.psd diff --git a/assets/client/room/furnitures/pc/motherboard.jpg b/packages/client/assets/room/furnitures/pc/motherboard.jpg similarity index 100% rename from assets/client/room/furnitures/pc/motherboard.jpg rename to packages/client/assets/room/furnitures/pc/motherboard.jpg diff --git a/assets/client/room/furnitures/pc/pc.blend b/packages/client/assets/room/furnitures/pc/pc.blend similarity index 100% rename from assets/client/room/furnitures/pc/pc.blend rename to packages/client/assets/room/furnitures/pc/pc.blend diff --git a/assets/client/room/furnitures/pc/pc.glb b/packages/client/assets/room/furnitures/pc/pc.glb similarity index 100% rename from assets/client/room/furnitures/pc/pc.glb rename to packages/client/assets/room/furnitures/pc/pc.glb diff --git a/assets/client/room/furnitures/pencil/pencil.blend b/packages/client/assets/room/furnitures/pencil/pencil.blend similarity index 100% rename from assets/client/room/furnitures/pencil/pencil.blend rename to packages/client/assets/room/furnitures/pencil/pencil.blend diff --git a/assets/client/room/furnitures/pencil/pencil.glb b/packages/client/assets/room/furnitures/pencil/pencil.glb similarity index 100% rename from assets/client/room/furnitures/pencil/pencil.glb rename to packages/client/assets/room/furnitures/pencil/pencil.glb diff --git a/assets/client/room/furnitures/photoframe/photo-uv.png b/packages/client/assets/room/furnitures/photoframe/photo-uv.png similarity index 100% rename from assets/client/room/furnitures/photoframe/photo-uv.png rename to packages/client/assets/room/furnitures/photoframe/photo-uv.png diff --git a/assets/client/room/furnitures/photoframe/photo.jpg b/packages/client/assets/room/furnitures/photoframe/photo.jpg similarity index 100% rename from assets/client/room/furnitures/photoframe/photo.jpg rename to packages/client/assets/room/furnitures/photoframe/photo.jpg diff --git a/assets/client/room/furnitures/photoframe/photoframe.blend b/packages/client/assets/room/furnitures/photoframe/photoframe.blend similarity index 100% rename from assets/client/room/furnitures/photoframe/photoframe.blend rename to packages/client/assets/room/furnitures/photoframe/photoframe.blend diff --git a/assets/client/room/furnitures/photoframe/photoframe.glb b/packages/client/assets/room/furnitures/photoframe/photoframe.glb similarity index 100% rename from assets/client/room/furnitures/photoframe/photoframe.glb rename to packages/client/assets/room/furnitures/photoframe/photoframe.glb diff --git a/assets/client/room/furnitures/piano/piano.blend b/packages/client/assets/room/furnitures/piano/piano.blend similarity index 100% rename from assets/client/room/furnitures/piano/piano.blend rename to packages/client/assets/room/furnitures/piano/piano.blend diff --git a/assets/client/room/furnitures/piano/piano.glb b/packages/client/assets/room/furnitures/piano/piano.glb similarity index 100% rename from assets/client/room/furnitures/piano/piano.glb rename to packages/client/assets/room/furnitures/piano/piano.glb diff --git a/assets/client/room/furnitures/pinguin/pinguin.blend b/packages/client/assets/room/furnitures/pinguin/pinguin.blend similarity index 100% rename from assets/client/room/furnitures/pinguin/pinguin.blend rename to packages/client/assets/room/furnitures/pinguin/pinguin.blend diff --git a/assets/client/room/furnitures/pinguin/pinguin.glb b/packages/client/assets/room/furnitures/pinguin/pinguin.glb similarity index 100% rename from assets/client/room/furnitures/pinguin/pinguin.glb rename to packages/client/assets/room/furnitures/pinguin/pinguin.glb diff --git a/assets/client/room/furnitures/plant/plant-soil-uv.png b/packages/client/assets/room/furnitures/plant/plant-soil-uv.png similarity index 100% rename from assets/client/room/furnitures/plant/plant-soil-uv.png rename to packages/client/assets/room/furnitures/plant/plant-soil-uv.png diff --git a/assets/client/room/furnitures/plant/plant-soil.png b/packages/client/assets/room/furnitures/plant/plant-soil.png similarity index 100% rename from assets/client/room/furnitures/plant/plant-soil.png rename to packages/client/assets/room/furnitures/plant/plant-soil.png diff --git a/assets/client/room/furnitures/plant/plant-soil.psd b/packages/client/assets/room/furnitures/plant/plant-soil.psd similarity index 100% rename from assets/client/room/furnitures/plant/plant-soil.psd rename to packages/client/assets/room/furnitures/plant/plant-soil.psd diff --git a/assets/client/room/furnitures/plant/plant.blend b/packages/client/assets/room/furnitures/plant/plant.blend similarity index 100% rename from assets/client/room/furnitures/plant/plant.blend rename to packages/client/assets/room/furnitures/plant/plant.blend diff --git a/assets/client/room/furnitures/plant/plant.glb b/packages/client/assets/room/furnitures/plant/plant.glb similarity index 100% rename from assets/client/room/furnitures/plant/plant.glb rename to packages/client/assets/room/furnitures/plant/plant.glb diff --git a/assets/client/room/furnitures/plant2/plant2.blend b/packages/client/assets/room/furnitures/plant2/plant2.blend similarity index 100% rename from assets/client/room/furnitures/plant2/plant2.blend rename to packages/client/assets/room/furnitures/plant2/plant2.blend diff --git a/assets/client/room/furnitures/plant2/plant2.glb b/packages/client/assets/room/furnitures/plant2/plant2.glb similarity index 100% rename from assets/client/room/furnitures/plant2/plant2.glb rename to packages/client/assets/room/furnitures/plant2/plant2.glb diff --git a/assets/client/room/furnitures/plant2/soil.png b/packages/client/assets/room/furnitures/plant2/soil.png similarity index 100% rename from assets/client/room/furnitures/plant2/soil.png rename to packages/client/assets/room/furnitures/plant2/soil.png diff --git a/assets/client/room/furnitures/poster-h/poster-h.blend b/packages/client/assets/room/furnitures/poster-h/poster-h.blend similarity index 100% rename from assets/client/room/furnitures/poster-h/poster-h.blend rename to packages/client/assets/room/furnitures/poster-h/poster-h.blend diff --git a/assets/client/room/furnitures/poster-h/poster-h.glb b/packages/client/assets/room/furnitures/poster-h/poster-h.glb similarity index 100% rename from assets/client/room/furnitures/poster-h/poster-h.glb rename to packages/client/assets/room/furnitures/poster-h/poster-h.glb diff --git a/assets/client/room/furnitures/poster-h/uv.png b/packages/client/assets/room/furnitures/poster-h/uv.png similarity index 100% rename from assets/client/room/furnitures/poster-h/uv.png rename to packages/client/assets/room/furnitures/poster-h/uv.png diff --git a/assets/client/room/furnitures/poster-v/poster-v.blend b/packages/client/assets/room/furnitures/poster-v/poster-v.blend similarity index 100% rename from assets/client/room/furnitures/poster-v/poster-v.blend rename to packages/client/assets/room/furnitures/poster-v/poster-v.blend diff --git a/assets/client/room/furnitures/poster-v/poster-v.glb b/packages/client/assets/room/furnitures/poster-v/poster-v.glb similarity index 100% rename from assets/client/room/furnitures/poster-v/poster-v.glb rename to packages/client/assets/room/furnitures/poster-v/poster-v.glb diff --git a/assets/client/room/furnitures/poster-v/uv.png b/packages/client/assets/room/furnitures/poster-v/uv.png similarity index 100% rename from assets/client/room/furnitures/poster-v/uv.png rename to packages/client/assets/room/furnitures/poster-v/uv.png diff --git a/assets/client/room/furnitures/pudding/pudding.blend b/packages/client/assets/room/furnitures/pudding/pudding.blend similarity index 100% rename from assets/client/room/furnitures/pudding/pudding.blend rename to packages/client/assets/room/furnitures/pudding/pudding.blend diff --git a/assets/client/room/furnitures/pudding/pudding.glb b/packages/client/assets/room/furnitures/pudding/pudding.glb similarity index 100% rename from assets/client/room/furnitures/pudding/pudding.glb rename to packages/client/assets/room/furnitures/pudding/pudding.glb diff --git a/assets/client/room/furnitures/rubik-cube/rubik-cube.blend b/packages/client/assets/room/furnitures/rubik-cube/rubik-cube.blend similarity index 100% rename from assets/client/room/furnitures/rubik-cube/rubik-cube.blend rename to packages/client/assets/room/furnitures/rubik-cube/rubik-cube.blend diff --git a/assets/client/room/furnitures/rubik-cube/rubik-cube.glb b/packages/client/assets/room/furnitures/rubik-cube/rubik-cube.glb similarity index 100% rename from assets/client/room/furnitures/rubik-cube/rubik-cube.glb rename to packages/client/assets/room/furnitures/rubik-cube/rubik-cube.glb diff --git a/assets/client/room/furnitures/server/rack-uv.png b/packages/client/assets/room/furnitures/server/rack-uv.png similarity index 100% rename from assets/client/room/furnitures/server/rack-uv.png rename to packages/client/assets/room/furnitures/server/rack-uv.png diff --git a/assets/client/room/furnitures/server/rack.png b/packages/client/assets/room/furnitures/server/rack.png similarity index 100% rename from assets/client/room/furnitures/server/rack.png rename to packages/client/assets/room/furnitures/server/rack.png diff --git a/assets/client/room/furnitures/server/server.blend b/packages/client/assets/room/furnitures/server/server.blend similarity index 100% rename from assets/client/room/furnitures/server/server.blend rename to packages/client/assets/room/furnitures/server/server.blend diff --git a/assets/client/room/furnitures/server/server.glb b/packages/client/assets/room/furnitures/server/server.glb similarity index 100% rename from assets/client/room/furnitures/server/server.glb rename to packages/client/assets/room/furnitures/server/server.glb diff --git a/assets/client/room/furnitures/server/server.png b/packages/client/assets/room/furnitures/server/server.png similarity index 100% rename from assets/client/room/furnitures/server/server.png rename to packages/client/assets/room/furnitures/server/server.png diff --git a/assets/client/room/furnitures/server/uv.png b/packages/client/assets/room/furnitures/server/uv.png similarity index 100% rename from assets/client/room/furnitures/server/uv.png rename to packages/client/assets/room/furnitures/server/uv.png diff --git a/assets/client/room/furnitures/sofa/sofa.blend b/packages/client/assets/room/furnitures/sofa/sofa.blend similarity index 100% rename from assets/client/room/furnitures/sofa/sofa.blend rename to packages/client/assets/room/furnitures/sofa/sofa.blend diff --git a/assets/client/room/furnitures/sofa/sofa.glb b/packages/client/assets/room/furnitures/sofa/sofa.glb similarity index 100% rename from assets/client/room/furnitures/sofa/sofa.glb rename to packages/client/assets/room/furnitures/sofa/sofa.glb diff --git a/assets/client/room/furnitures/spiral/spiral.blend b/packages/client/assets/room/furnitures/spiral/spiral.blend similarity index 100% rename from assets/client/room/furnitures/spiral/spiral.blend rename to packages/client/assets/room/furnitures/spiral/spiral.blend diff --git a/assets/client/room/furnitures/spiral/spiral.glb b/packages/client/assets/room/furnitures/spiral/spiral.glb similarity index 100% rename from assets/client/room/furnitures/spiral/spiral.glb rename to packages/client/assets/room/furnitures/spiral/spiral.glb diff --git a/assets/client/room/furnitures/tv/screen-uv.png b/packages/client/assets/room/furnitures/tv/screen-uv.png similarity index 100% rename from assets/client/room/furnitures/tv/screen-uv.png rename to packages/client/assets/room/furnitures/tv/screen-uv.png diff --git a/assets/client/room/furnitures/tv/tv.blend b/packages/client/assets/room/furnitures/tv/tv.blend similarity index 100% rename from assets/client/room/furnitures/tv/tv.blend rename to packages/client/assets/room/furnitures/tv/tv.blend diff --git a/assets/client/room/furnitures/tv/tv.glb b/packages/client/assets/room/furnitures/tv/tv.glb similarity index 100% rename from assets/client/room/furnitures/tv/tv.glb rename to packages/client/assets/room/furnitures/tv/tv.glb diff --git a/assets/client/room/furnitures/wall-clock/wall-clock.blend b/packages/client/assets/room/furnitures/wall-clock/wall-clock.blend similarity index 100% rename from assets/client/room/furnitures/wall-clock/wall-clock.blend rename to packages/client/assets/room/furnitures/wall-clock/wall-clock.blend diff --git a/assets/client/room/furnitures/wall-clock/wall-clock.glb b/packages/client/assets/room/furnitures/wall-clock/wall-clock.glb similarity index 100% rename from assets/client/room/furnitures/wall-clock/wall-clock.glb rename to packages/client/assets/room/furnitures/wall-clock/wall-clock.glb diff --git a/assets/client/room/rooms/default/default.blend b/packages/client/assets/room/rooms/default/default.blend similarity index 100% rename from assets/client/room/rooms/default/default.blend rename to packages/client/assets/room/rooms/default/default.blend diff --git a/assets/client/room/rooms/default/default.glb b/packages/client/assets/room/rooms/default/default.glb similarity index 100% rename from assets/client/room/rooms/default/default.glb rename to packages/client/assets/room/rooms/default/default.glb diff --git a/assets/client/room/rooms/washitsu/husuma-uv.png b/packages/client/assets/room/rooms/washitsu/husuma-uv.png similarity index 100% rename from assets/client/room/rooms/washitsu/husuma-uv.png rename to packages/client/assets/room/rooms/washitsu/husuma-uv.png diff --git a/assets/client/room/rooms/washitsu/husuma.png b/packages/client/assets/room/rooms/washitsu/husuma.png similarity index 100% rename from assets/client/room/rooms/washitsu/husuma.png rename to packages/client/assets/room/rooms/washitsu/husuma.png diff --git a/assets/client/room/rooms/washitsu/tatami-single1600.png b/packages/client/assets/room/rooms/washitsu/tatami-single1600.png similarity index 100% rename from assets/client/room/rooms/washitsu/tatami-single1600.png rename to packages/client/assets/room/rooms/washitsu/tatami-single1600.png diff --git a/assets/client/room/rooms/washitsu/tatami-uv.png b/packages/client/assets/room/rooms/washitsu/tatami-uv.png similarity index 100% rename from assets/client/room/rooms/washitsu/tatami-uv.png rename to packages/client/assets/room/rooms/washitsu/tatami-uv.png diff --git a/assets/client/room/rooms/washitsu/tatami.afdesign b/packages/client/assets/room/rooms/washitsu/tatami.afdesign similarity index 100% rename from assets/client/room/rooms/washitsu/tatami.afdesign rename to packages/client/assets/room/rooms/washitsu/tatami.afdesign diff --git a/assets/client/room/rooms/washitsu/tatami.png b/packages/client/assets/room/rooms/washitsu/tatami.png similarity index 100% rename from assets/client/room/rooms/washitsu/tatami.png rename to packages/client/assets/room/rooms/washitsu/tatami.png diff --git a/assets/client/room/rooms/washitsu/washitsu.blend b/packages/client/assets/room/rooms/washitsu/washitsu.blend similarity index 100% rename from assets/client/room/rooms/washitsu/washitsu.blend rename to packages/client/assets/room/rooms/washitsu/washitsu.blend diff --git a/assets/client/room/rooms/washitsu/washitsu.glb b/packages/client/assets/room/rooms/washitsu/washitsu.glb similarity index 100% rename from assets/client/room/rooms/washitsu/washitsu.glb rename to packages/client/assets/room/rooms/washitsu/washitsu.glb diff --git a/assets/client/sounds/aisha/1.mp3 b/packages/client/assets/sounds/aisha/1.mp3 similarity index 100% rename from assets/client/sounds/aisha/1.mp3 rename to packages/client/assets/sounds/aisha/1.mp3 diff --git a/assets/client/sounds/aisha/2.mp3 b/packages/client/assets/sounds/aisha/2.mp3 similarity index 100% rename from assets/client/sounds/aisha/2.mp3 rename to packages/client/assets/sounds/aisha/2.mp3 diff --git a/assets/client/sounds/aisha/3.mp3 b/packages/client/assets/sounds/aisha/3.mp3 similarity index 100% rename from assets/client/sounds/aisha/3.mp3 rename to packages/client/assets/sounds/aisha/3.mp3 diff --git a/assets/client/sounds/noizenecio/kick_gaba.mp3 b/packages/client/assets/sounds/noizenecio/kick_gaba.mp3 similarity index 100% rename from assets/client/sounds/noizenecio/kick_gaba.mp3 rename to packages/client/assets/sounds/noizenecio/kick_gaba.mp3 diff --git a/assets/client/sounds/noizenecio/kick_gaba2.mp3 b/packages/client/assets/sounds/noizenecio/kick_gaba2.mp3 similarity index 100% rename from assets/client/sounds/noizenecio/kick_gaba2.mp3 rename to packages/client/assets/sounds/noizenecio/kick_gaba2.mp3 diff --git a/assets/client/sounds/syuilo/down.mp3 b/packages/client/assets/sounds/syuilo/down.mp3 similarity index 100% rename from assets/client/sounds/syuilo/down.mp3 rename to packages/client/assets/sounds/syuilo/down.mp3 diff --git a/assets/client/sounds/syuilo/kick.mp3 b/packages/client/assets/sounds/syuilo/kick.mp3 similarity index 100% rename from assets/client/sounds/syuilo/kick.mp3 rename to packages/client/assets/sounds/syuilo/kick.mp3 diff --git a/assets/client/sounds/syuilo/pirori-square-wet.mp3 b/packages/client/assets/sounds/syuilo/pirori-square-wet.mp3 similarity index 100% rename from assets/client/sounds/syuilo/pirori-square-wet.mp3 rename to packages/client/assets/sounds/syuilo/pirori-square-wet.mp3 diff --git a/assets/client/sounds/syuilo/pirori-wet.mp3 b/packages/client/assets/sounds/syuilo/pirori-wet.mp3 similarity index 100% rename from assets/client/sounds/syuilo/pirori-wet.mp3 rename to packages/client/assets/sounds/syuilo/pirori-wet.mp3 diff --git a/assets/client/sounds/syuilo/pirori.mp3 b/packages/client/assets/sounds/syuilo/pirori.mp3 similarity index 100% rename from assets/client/sounds/syuilo/pirori.mp3 rename to packages/client/assets/sounds/syuilo/pirori.mp3 diff --git a/assets/client/sounds/syuilo/poi1.mp3 b/packages/client/assets/sounds/syuilo/poi1.mp3 similarity index 100% rename from assets/client/sounds/syuilo/poi1.mp3 rename to packages/client/assets/sounds/syuilo/poi1.mp3 diff --git a/assets/client/sounds/syuilo/poi2.mp3 b/packages/client/assets/sounds/syuilo/poi2.mp3 similarity index 100% rename from assets/client/sounds/syuilo/poi2.mp3 rename to packages/client/assets/sounds/syuilo/poi2.mp3 diff --git a/assets/client/sounds/syuilo/pope1.mp3 b/packages/client/assets/sounds/syuilo/pope1.mp3 similarity index 100% rename from assets/client/sounds/syuilo/pope1.mp3 rename to packages/client/assets/sounds/syuilo/pope1.mp3 diff --git a/assets/client/sounds/syuilo/pope2.mp3 b/packages/client/assets/sounds/syuilo/pope2.mp3 similarity index 100% rename from assets/client/sounds/syuilo/pope2.mp3 rename to packages/client/assets/sounds/syuilo/pope2.mp3 diff --git a/assets/client/sounds/syuilo/popo.mp3 b/packages/client/assets/sounds/syuilo/popo.mp3 similarity index 100% rename from assets/client/sounds/syuilo/popo.mp3 rename to packages/client/assets/sounds/syuilo/popo.mp3 diff --git a/assets/client/sounds/syuilo/queue-jammed.mp3 b/packages/client/assets/sounds/syuilo/queue-jammed.mp3 similarity index 100% rename from assets/client/sounds/syuilo/queue-jammed.mp3 rename to packages/client/assets/sounds/syuilo/queue-jammed.mp3 diff --git a/assets/client/sounds/syuilo/reverved.mp3 b/packages/client/assets/sounds/syuilo/reverved.mp3 similarity index 100% rename from assets/client/sounds/syuilo/reverved.mp3 rename to packages/client/assets/sounds/syuilo/reverved.mp3 diff --git a/assets/client/sounds/syuilo/ryukyu.mp3 b/packages/client/assets/sounds/syuilo/ryukyu.mp3 similarity index 100% rename from assets/client/sounds/syuilo/ryukyu.mp3 rename to packages/client/assets/sounds/syuilo/ryukyu.mp3 diff --git a/assets/client/sounds/syuilo/snare.mp3 b/packages/client/assets/sounds/syuilo/snare.mp3 similarity index 100% rename from assets/client/sounds/syuilo/snare.mp3 rename to packages/client/assets/sounds/syuilo/snare.mp3 diff --git a/assets/client/sounds/syuilo/square-pico.mp3 b/packages/client/assets/sounds/syuilo/square-pico.mp3 similarity index 100% rename from assets/client/sounds/syuilo/square-pico.mp3 rename to packages/client/assets/sounds/syuilo/square-pico.mp3 diff --git a/assets/client/sounds/syuilo/triple.mp3 b/packages/client/assets/sounds/syuilo/triple.mp3 similarity index 100% rename from assets/client/sounds/syuilo/triple.mp3 rename to packages/client/assets/sounds/syuilo/triple.mp3 diff --git a/assets/client/sounds/syuilo/up.mp3 b/packages/client/assets/sounds/syuilo/up.mp3 similarity index 100% rename from assets/client/sounds/syuilo/up.mp3 rename to packages/client/assets/sounds/syuilo/up.mp3 diff --git a/assets/client/sounds/syuilo/waon.mp3 b/packages/client/assets/sounds/syuilo/waon.mp3 similarity index 100% rename from assets/client/sounds/syuilo/waon.mp3 rename to packages/client/assets/sounds/syuilo/waon.mp3 diff --git a/assets/client/sparkle-spritesheet.png b/packages/client/assets/sparkle-spritesheet.png similarity index 100% rename from assets/client/sparkle-spritesheet.png rename to packages/client/assets/sparkle-spritesheet.png diff --git a/assets/client/unread.svg b/packages/client/assets/unread.svg similarity index 100% rename from assets/client/unread.svg rename to packages/client/assets/unread.svg diff --git a/packages/client/package.json b/packages/client/package.json new file mode 100644 index 000000000..02ccb57e1 --- /dev/null +++ b/packages/client/package.json @@ -0,0 +1,158 @@ +{ + "private": true, + "scripts": { + "watch": "webpack --watch", + "build": "webpack" + }, + "resolutions": { + "chokidar": "^3.3.1", + "lodash": "^4.17.21" + }, + "dependencies": { + "@discordapp/twemoji": "13.1.0", + "@elastic/elasticsearch": "7.11.0", + "@sentry/browser": "5.29.2", + "@sentry/tracing": "5.29.2", + "@sinonjs/fake-timers": "7.1.2", + "@syuilo/aiscript": "0.11.1", + "@types/dateformat": "3.0.1", + "@types/escape-regexp": "0.0.0", + "@types/glob": "7.2.0", + "@types/gulp": "4.0.9", + "@types/gulp-rename": "2.0.1", + "@types/is-url": "1.2.30", + "@types/js-yaml": "4.0.4", + "@types/katex": "0.11.1", + "@types/matter-js": "0.17.6", + "@types/mocha": "8.2.3", + "@types/node": "16.11.7", + "@types/node-fetch": "2.5.12", + "@types/nodemailer": "6.4.4", + "@types/nprogress": "0.2.0", + "@types/oauth": "0.9.1", + "@types/parse5": "6.0.2", + "@types/parsimmon": "1.10.6", + "@types/portscanner": "2.1.1", + "@types/pug": "2.0.5", + "@types/punycode": "2.1.0", + "@types/qrcode": "1.4.1", + "@types/random-seed": "0.3.3", + "@types/rename": "1.0.4", + "@types/request-stats": "3.0.0", + "@types/seedrandom": "2.4.28", + "@types/sinonjs__fake-timers": "6.0.4", + "@types/speakeasy": "2.0.6", + "@types/throttle-debounce": "2.1.0", + "@types/tinycolor2": "1.4.3", + "@types/tmp": "0.2.2", + "@types/uuid": "8.3.1", + "@types/web-push": "3.3.2", + "@types/webpack": "5.28.0", + "@types/webpack-stream": "3.2.12", + "@types/websocket": "1.0.4", + "@types/ws": "8.2.0", + "@typescript-eslint/parser": "5.1.0", + "@vue/compiler-sfc": "3.2.21", + "abort-controller": "3.0.0", + "autobind-decorator": "2.4.0", + "autosize": "4.0.4", + "autwh": "0.1.0", + "blurhash": "1.1.4", + "broadcast-channel": "4.5.0", + "chart.js": "3.6.0", + "chartjs-adapter-date-fns": "2.0.0", + "chartjs-plugin-zoom": "1.1.1", + "compare-versions": "3.6.0", + "concurrently": "6.3.0", + "content-disposition": "0.5.3", + "crc-32": "1.2.0", + "css-loader": "6.5.1", + "cssnano": "5.0.10", + "date-fns": "2.25.0", + "dateformat": "4.5.1", + "escape-regexp": "0.0.1", + "eslint": "8.2.0", + "eslint-plugin-vue": "8.0.3", + "eventemitter3": "4.0.7", + "feed": "4.2.2", + "glob": "7.2.0", + "got": "11.8.2", + "idb-keyval": "5.1.3", + "insert-text-at-cursor": "0.3.0", + "ip-cidr": "3.0.4", + "is-svg": "4.3.1", + "js-yaml": "4.1.0", + "json5": "2.2.0", + "json5-loader": "4.0.1", + "katex": "0.13.18", + "langmap": "0.0.16", + "matter-js": "0.17.1", + "mfm-js": "0.20.0", + "misskey-js": "0.0.10", + "mocha": "8.4.0", + "ms": "2.1.3", + "nested-property": "4.0.0", + "node-fetch": "2.6.1", + "parse5": "6.0.1", + "photoswipe": "git://github.com/dimsemenov/photoswipe#v5-beta", + "portscanner": "2.2.0", + "postcss": "8.3.11", + "postcss-loader": "6.2.0", + "prismjs": "1.25.0", + "private-ip": "2.3.3", + "probe-image-size": "7.2.1", + "promise-limit": "2.7.0", + "pug": "3.0.2", + "punycode": "2.1.1", + "pureimage": "0.3.5", + "qrcode": "1.4.4", + "random-seed": "0.3.0", + "ratelimiter": "3.4.1", + "reflect-metadata": "0.1.13", + "rename": "1.0.4", + "request-stats": "3.0.0", + "rndstr": "1.0.0", + "s-age": "1.1.2", + "sass": "1.43.4", + "sass-loader": "12.3.0", + "seedrandom": "3.0.5", + "speakeasy": "2.0.0", + "strict-event-emitter-types": "2.0.0", + "stringz": "2.1.0", + "style-loader": "3.3.1", + "syuilo-password-strength": "0.0.1", + "textarea-caret": "3.1.0", + "three": "0.117.1", + "throttle-debounce": "3.0.1", + "tinycolor2": "1.4.2", + "tmp": "0.2.1", + "ts-loader": "9.2.6", + "ts-node": "10.4.0", + "tsc-alias": "1.3.10", + "tsconfig-paths": "3.11.0", + "twemoji-parser": "13.1.0", + "typescript": "4.4.4", + "uuid": "8.3.2", + "v-debounce": "0.1.2", + "vanilla-tilt": "1.7.2", + "vue": "3.2.21", + "vue-loader": "16.7.0", + "vue-prism-editor": "2.0.0-alpha.2", + "vue-router": "4.0.5", + "vue-style-loader": "4.1.3", + "vue-svg-loader": "0.17.0-beta.2", + "vuedraggable": "4.0.1", + "web-push": "3.4.5", + "webpack": "5.63.0", + "webpack-cli": "4.9.1", + "websocket": "1.0.34", + "ws": "8.2.3" + }, + "devDependencies": { + "@redocly/openapi-core": "1.0.0-beta.54", + "@types/fluent-ffmpeg": "2.1.17", + "cross-env": "7.0.3", + "cypress": "8.5.0", + "start-server-and-test": "1.14.0" + } +} diff --git a/packages/client/src/account.ts b/packages/client/src/account.ts new file mode 100644 index 000000000..ef7eb8f60 --- /dev/null +++ b/packages/client/src/account.ts @@ -0,0 +1,211 @@ +import { del, get, set } from '@/scripts/idb-proxy'; +import { reactive } from 'vue'; +import { apiUrl } from '@/config'; +import { waiting, api, popup, popupMenu, success } from '@/os'; +import { unisonReload, reloadChannel } from '@/scripts/unison-reload'; +import { showSuspendedDialog } from './scripts/show-suspended-dialog'; +import { i18n } from './i18n'; + +// TODO: 他のタブと永続化されたstateを同期 + +type Account = { + id: string; + token: string; + isModerator: boolean; + isAdmin: boolean; + isDeleted: boolean; +}; + +const data = localStorage.getItem('account'); + +// TODO: 外部からはreadonlyに +export const $i = data ? reactive(JSON.parse(data) as Account) : null; + +export async function signout() { + waiting(); + localStorage.removeItem('account'); + + //#region Remove account + const accounts = await getAccounts(); + accounts.splice(accounts.findIndex(x => x.id === $i.id), 1); + + if (accounts.length > 0) await set('accounts', accounts); + else await del('accounts'); + //#endregion + + //#region Remove service worker registration + try { + if (navigator.serviceWorker.controller) { + const registration = await navigator.serviceWorker.ready; + const push = await registration.pushManager.getSubscription(); + if (push) { + await fetch(`${apiUrl}/sw/unregister`, { + method: 'POST', + body: JSON.stringify({ + i: $i.token, + endpoint: push.endpoint, + }), + }); + } + } + + if (accounts.length === 0) { + await navigator.serviceWorker.getRegistrations() + .then(registrations => { + return Promise.all(registrations.map(registration => registration.unregister())); + }); + } + } catch (e) {} + //#endregion + + document.cookie = `igi=; path=/`; + + if (accounts.length > 0) login(accounts[0].token); + else unisonReload('/'); +} + +export async function getAccounts(): Promise<{ id: Account['id'], token: Account['token'] }[]> { + return (await get('accounts')) || []; +} + +export async function addAccount(id: Account['id'], token: Account['token']) { + const accounts = await getAccounts(); + if (!accounts.some(x => x.id === id)) { + await set('accounts', accounts.concat([{ id, token }])); + } +} + +function fetchAccount(token): Promise { + return new Promise((done, fail) => { + // Fetch user + fetch(`${apiUrl}/i`, { + method: 'POST', + body: JSON.stringify({ + i: token + }) + }) + .then(res => res.json()) + .then(res => { + if (res.error) { + if (res.error.id === 'a8c724b3-6e9c-4b46-b1a8-bc3ed6258370') { + showSuspendedDialog().then(() => { + signout(); + }); + } else { + signout(); + } + } else { + res.token = token; + done(res); + } + }) + .catch(fail); + }); +} + +export function updateAccount(data) { + for (const [key, value] of Object.entries(data)) { + $i[key] = value; + } + localStorage.setItem('account', JSON.stringify($i)); +} + +export function refreshAccount() { + return fetchAccount($i.token).then(updateAccount); +} + +export async function login(token: Account['token'], redirect?: string) { + waiting(); + if (_DEV_) console.log('logging as token ', token); + const me = await fetchAccount(token); + localStorage.setItem('account', JSON.stringify(me)); + await addAccount(me.id, token); + + if (redirect) { + // 他のタブは再読み込みするだけ + reloadChannel.postMessage(null); + // このページはredirectで指定された先に移動 + location.href = redirect; + return; + } + + unisonReload(); +} + +export async function openAccountMenu(ev: MouseEvent) { + function showSigninDialog() { + popup(import('@/components/signin-dialog.vue'), {}, { + done: res => { + addAccount(res.id, res.i); + success(); + }, + }, 'closed'); + } + + function createAccount() { + popup(import('@/components/signup-dialog.vue'), {}, { + done: res => { + addAccount(res.id, res.i); + switchAccountWithToken(res.i); + }, + }, 'closed'); + } + + async function switchAccount(account: any) { + const storedAccounts = await getAccounts(); + const token = storedAccounts.find(x => x.id === account.id).token; + switchAccountWithToken(token); + } + + function switchAccountWithToken(token: string) { + login(token); + } + + const storedAccounts = await getAccounts().then(accounts => accounts.filter(x => x.id !== $i.id)); + const accountsPromise = api('users/show', { userIds: storedAccounts.map(x => x.id) }); + + const accountItemPromises = storedAccounts.map(a => new Promise(res => { + accountsPromise.then(accounts => { + const account = accounts.find(x => x.id === a.id); + if (account == null) return res(null); + res({ + type: 'user', + user: account, + action: () => { switchAccount(account); } + }); + }); + })); + + popupMenu([...[{ + type: 'link', + text: i18n.locale.profile, + to: `/@${ $i.username }`, + avatar: $i, + }, null, ...accountItemPromises, { + icon: 'fas fa-plus', + text: i18n.locale.addAccount, + action: () => { + popupMenu([{ + text: i18n.locale.existingAccount, + action: () => { showSigninDialog(); }, + }, { + text: i18n.locale.createAccount, + action: () => { createAccount(); }, + }], ev.currentTarget || ev.target); + }, + }, { + type: 'link', + icon: 'fas fa-users', + text: i18n.locale.manageAccounts, + to: `/settings/accounts`, + }]], ev.currentTarget || ev.target, { + align: 'left' + }); +} + +// このファイルに書きたくないけどここに書かないと何故かVeturが認識しない +declare module '@vue/runtime-core' { + interface ComponentCustomProperties { + $i: typeof $i; + } +} diff --git a/packages/client/src/components/abuse-report-window.vue b/packages/client/src/components/abuse-report-window.vue new file mode 100644 index 000000000..700ce30bb --- /dev/null +++ b/packages/client/src/components/abuse-report-window.vue @@ -0,0 +1,79 @@ + + + + + diff --git a/src/client/components/analog-clock.vue b/packages/client/src/components/analog-clock.vue similarity index 100% rename from src/client/components/analog-clock.vue rename to packages/client/src/components/analog-clock.vue diff --git a/packages/client/src/components/autocomplete.vue b/packages/client/src/components/autocomplete.vue new file mode 100644 index 000000000..a7d2d507e --- /dev/null +++ b/packages/client/src/components/autocomplete.vue @@ -0,0 +1,501 @@ + + + + + diff --git a/packages/client/src/components/avatars.vue b/packages/client/src/components/avatars.vue new file mode 100644 index 000000000..e843d26da --- /dev/null +++ b/packages/client/src/components/avatars.vue @@ -0,0 +1,30 @@ + + + diff --git a/src/client/components/captcha.vue b/packages/client/src/components/captcha.vue similarity index 100% rename from src/client/components/captcha.vue rename to packages/client/src/components/captcha.vue diff --git a/packages/client/src/components/channel-follow-button.vue b/packages/client/src/components/channel-follow-button.vue new file mode 100644 index 000000000..9af65325b --- /dev/null +++ b/packages/client/src/components/channel-follow-button.vue @@ -0,0 +1,140 @@ + + + + + diff --git a/src/client/components/channel-preview.vue b/packages/client/src/components/channel-preview.vue similarity index 100% rename from src/client/components/channel-preview.vue rename to packages/client/src/components/channel-preview.vue diff --git a/packages/client/src/components/chart.vue b/packages/client/src/components/chart.vue new file mode 100644 index 000000000..c4d0eb85d --- /dev/null +++ b/packages/client/src/components/chart.vue @@ -0,0 +1,691 @@ + + + + + diff --git a/src/client/components/code-core.vue b/packages/client/src/components/code-core.vue similarity index 100% rename from src/client/components/code-core.vue rename to packages/client/src/components/code-core.vue diff --git a/src/client/components/code.vue b/packages/client/src/components/code.vue similarity index 100% rename from src/client/components/code.vue rename to packages/client/src/components/code.vue diff --git a/packages/client/src/components/cw-button.vue b/packages/client/src/components/cw-button.vue new file mode 100644 index 000000000..4bec7b511 --- /dev/null +++ b/packages/client/src/components/cw-button.vue @@ -0,0 +1,70 @@ + + + + + diff --git a/packages/client/src/components/date-separated-list.vue b/packages/client/src/components/date-separated-list.vue new file mode 100644 index 000000000..1aea9fd35 --- /dev/null +++ b/packages/client/src/components/date-separated-list.vue @@ -0,0 +1,188 @@ + + + diff --git a/src/client/components/debobigego/base.vue b/packages/client/src/components/debobigego/base.vue similarity index 100% rename from src/client/components/debobigego/base.vue rename to packages/client/src/components/debobigego/base.vue diff --git a/src/client/components/debobigego/button.vue b/packages/client/src/components/debobigego/button.vue similarity index 100% rename from src/client/components/debobigego/button.vue rename to packages/client/src/components/debobigego/button.vue diff --git a/src/client/components/debobigego/debobigego.scss b/packages/client/src/components/debobigego/debobigego.scss similarity index 100% rename from src/client/components/debobigego/debobigego.scss rename to packages/client/src/components/debobigego/debobigego.scss diff --git a/src/client/components/debobigego/group.vue b/packages/client/src/components/debobigego/group.vue similarity index 100% rename from src/client/components/debobigego/group.vue rename to packages/client/src/components/debobigego/group.vue diff --git a/src/client/components/debobigego/info.vue b/packages/client/src/components/debobigego/info.vue similarity index 100% rename from src/client/components/debobigego/info.vue rename to packages/client/src/components/debobigego/info.vue diff --git a/src/client/components/debobigego/input.vue b/packages/client/src/components/debobigego/input.vue similarity index 100% rename from src/client/components/debobigego/input.vue rename to packages/client/src/components/debobigego/input.vue diff --git a/src/client/components/debobigego/key-value-view.vue b/packages/client/src/components/debobigego/key-value-view.vue similarity index 100% rename from src/client/components/debobigego/key-value-view.vue rename to packages/client/src/components/debobigego/key-value-view.vue diff --git a/src/client/components/debobigego/link.vue b/packages/client/src/components/debobigego/link.vue similarity index 100% rename from src/client/components/debobigego/link.vue rename to packages/client/src/components/debobigego/link.vue diff --git a/src/client/components/debobigego/object-view.vue b/packages/client/src/components/debobigego/object-view.vue similarity index 100% rename from src/client/components/debobigego/object-view.vue rename to packages/client/src/components/debobigego/object-view.vue diff --git a/packages/client/src/components/debobigego/pagination.vue b/packages/client/src/components/debobigego/pagination.vue new file mode 100644 index 000000000..07012cb75 --- /dev/null +++ b/packages/client/src/components/debobigego/pagination.vue @@ -0,0 +1,42 @@ + + + + + diff --git a/packages/client/src/components/debobigego/radios.vue b/packages/client/src/components/debobigego/radios.vue new file mode 100644 index 000000000..b4c584133 --- /dev/null +++ b/packages/client/src/components/debobigego/radios.vue @@ -0,0 +1,112 @@ + + + diff --git a/src/client/components/debobigego/range.vue b/packages/client/src/components/debobigego/range.vue similarity index 100% rename from src/client/components/debobigego/range.vue rename to packages/client/src/components/debobigego/range.vue diff --git a/src/client/components/debobigego/select.vue b/packages/client/src/components/debobigego/select.vue similarity index 100% rename from src/client/components/debobigego/select.vue rename to packages/client/src/components/debobigego/select.vue diff --git a/packages/client/src/components/debobigego/suspense.vue b/packages/client/src/components/debobigego/suspense.vue new file mode 100644 index 000000000..b5ba63b4b --- /dev/null +++ b/packages/client/src/components/debobigego/suspense.vue @@ -0,0 +1,101 @@ + + + + + diff --git a/src/client/components/debobigego/switch.vue b/packages/client/src/components/debobigego/switch.vue similarity index 100% rename from src/client/components/debobigego/switch.vue rename to packages/client/src/components/debobigego/switch.vue diff --git a/src/client/components/debobigego/textarea.vue b/packages/client/src/components/debobigego/textarea.vue similarity index 100% rename from src/client/components/debobigego/textarea.vue rename to packages/client/src/components/debobigego/textarea.vue diff --git a/src/client/components/debobigego/tuple.vue b/packages/client/src/components/debobigego/tuple.vue similarity index 100% rename from src/client/components/debobigego/tuple.vue rename to packages/client/src/components/debobigego/tuple.vue diff --git a/packages/client/src/components/dialog.vue b/packages/client/src/components/dialog.vue new file mode 100644 index 000000000..90086fd43 --- /dev/null +++ b/packages/client/src/components/dialog.vue @@ -0,0 +1,212 @@ + + + + + diff --git a/packages/client/src/components/drive-file-thumbnail.vue b/packages/client/src/components/drive-file-thumbnail.vue new file mode 100644 index 000000000..9b6a0c9a0 --- /dev/null +++ b/packages/client/src/components/drive-file-thumbnail.vue @@ -0,0 +1,108 @@ + + + + + diff --git a/packages/client/src/components/drive-select-dialog.vue b/packages/client/src/components/drive-select-dialog.vue new file mode 100644 index 000000000..f9a402545 --- /dev/null +++ b/packages/client/src/components/drive-select-dialog.vue @@ -0,0 +1,70 @@ + + + diff --git a/packages/client/src/components/drive-window.vue b/packages/client/src/components/drive-window.vue new file mode 100644 index 000000000..43f07ebe7 --- /dev/null +++ b/packages/client/src/components/drive-window.vue @@ -0,0 +1,44 @@ + + + diff --git a/packages/client/src/components/drive.file.vue b/packages/client/src/components/drive.file.vue new file mode 100644 index 000000000..c191127e8 --- /dev/null +++ b/packages/client/src/components/drive.file.vue @@ -0,0 +1,366 @@ + + + + + diff --git a/packages/client/src/components/drive.folder.vue b/packages/client/src/components/drive.folder.vue new file mode 100644 index 000000000..91e27cc8a --- /dev/null +++ b/packages/client/src/components/drive.folder.vue @@ -0,0 +1,326 @@ + + + + + diff --git a/packages/client/src/components/drive.nav-folder.vue b/packages/client/src/components/drive.nav-folder.vue new file mode 100644 index 000000000..4f0e6ce0e --- /dev/null +++ b/packages/client/src/components/drive.nav-folder.vue @@ -0,0 +1,135 @@ + + + + + diff --git a/packages/client/src/components/drive.vue b/packages/client/src/components/drive.vue new file mode 100644 index 000000000..2b72a0a1c --- /dev/null +++ b/packages/client/src/components/drive.vue @@ -0,0 +1,784 @@ + + + + + diff --git a/packages/client/src/components/emoji-picker-dialog.vue b/packages/client/src/components/emoji-picker-dialog.vue new file mode 100644 index 000000000..1d48bbb8a --- /dev/null +++ b/packages/client/src/components/emoji-picker-dialog.vue @@ -0,0 +1,76 @@ + + + + + diff --git a/packages/client/src/components/emoji-picker-window.vue b/packages/client/src/components/emoji-picker-window.vue new file mode 100644 index 000000000..0ffa0c118 --- /dev/null +++ b/packages/client/src/components/emoji-picker-window.vue @@ -0,0 +1,197 @@ + + + + + diff --git a/packages/client/src/components/emoji-picker.section.vue b/packages/client/src/components/emoji-picker.section.vue new file mode 100644 index 000000000..2401eca2a --- /dev/null +++ b/packages/client/src/components/emoji-picker.section.vue @@ -0,0 +1,50 @@ + + + + + diff --git a/packages/client/src/components/emoji-picker.vue b/packages/client/src/components/emoji-picker.vue new file mode 100644 index 000000000..015e20126 --- /dev/null +++ b/packages/client/src/components/emoji-picker.vue @@ -0,0 +1,501 @@ + + + + + diff --git a/packages/client/src/components/featured-photos.vue b/packages/client/src/components/featured-photos.vue new file mode 100644 index 000000000..276344dfb --- /dev/null +++ b/packages/client/src/components/featured-photos.vue @@ -0,0 +1,32 @@ + + + + + diff --git a/packages/client/src/components/file-type-icon.vue b/packages/client/src/components/file-type-icon.vue new file mode 100644 index 000000000..be1af5e50 --- /dev/null +++ b/packages/client/src/components/file-type-icon.vue @@ -0,0 +1,28 @@ + + + diff --git a/packages/client/src/components/follow-button.vue b/packages/client/src/components/follow-button.vue new file mode 100644 index 000000000..a96899027 --- /dev/null +++ b/packages/client/src/components/follow-button.vue @@ -0,0 +1,210 @@ + + + + + diff --git a/packages/client/src/components/forgot-password.vue b/packages/client/src/components/forgot-password.vue new file mode 100644 index 000000000..a42ea5864 --- /dev/null +++ b/packages/client/src/components/forgot-password.vue @@ -0,0 +1,84 @@ + + + + + diff --git a/packages/client/src/components/form-dialog.vue b/packages/client/src/components/form-dialog.vue new file mode 100644 index 000000000..172e6a513 --- /dev/null +++ b/packages/client/src/components/form-dialog.vue @@ -0,0 +1,125 @@ + + + + + diff --git a/packages/client/src/components/form/input.vue b/packages/client/src/components/form/input.vue new file mode 100644 index 000000000..f2c1ead00 --- /dev/null +++ b/packages/client/src/components/form/input.vue @@ -0,0 +1,315 @@ + + + + + diff --git a/src/client/components/form/radio.vue b/packages/client/src/components/form/radio.vue similarity index 100% rename from src/client/components/form/radio.vue rename to packages/client/src/components/form/radio.vue diff --git a/src/client/components/form/radios.vue b/packages/client/src/components/form/radios.vue similarity index 100% rename from src/client/components/form/radios.vue rename to packages/client/src/components/form/radios.vue diff --git a/src/client/components/form/range.vue b/packages/client/src/components/form/range.vue similarity index 100% rename from src/client/components/form/range.vue rename to packages/client/src/components/form/range.vue diff --git a/src/client/components/form/section.vue b/packages/client/src/components/form/section.vue similarity index 100% rename from src/client/components/form/section.vue rename to packages/client/src/components/form/section.vue diff --git a/packages/client/src/components/form/select.vue b/packages/client/src/components/form/select.vue new file mode 100644 index 000000000..f7eb5cd14 --- /dev/null +++ b/packages/client/src/components/form/select.vue @@ -0,0 +1,312 @@ + + + + + diff --git a/src/client/components/form/slot.vue b/packages/client/src/components/form/slot.vue similarity index 100% rename from src/client/components/form/slot.vue rename to packages/client/src/components/form/slot.vue diff --git a/src/client/components/form/switch.vue b/packages/client/src/components/form/switch.vue similarity index 100% rename from src/client/components/form/switch.vue rename to packages/client/src/components/form/switch.vue diff --git a/packages/client/src/components/form/textarea.vue b/packages/client/src/components/form/textarea.vue new file mode 100644 index 000000000..fdb24f1e2 --- /dev/null +++ b/packages/client/src/components/form/textarea.vue @@ -0,0 +1,252 @@ + + + + + diff --git a/packages/client/src/components/formula-core.vue b/packages/client/src/components/formula-core.vue new file mode 100644 index 000000000..cf8dee872 --- /dev/null +++ b/packages/client/src/components/formula-core.vue @@ -0,0 +1,34 @@ + + + + + + diff --git a/packages/client/src/components/formula.vue b/packages/client/src/components/formula.vue new file mode 100644 index 000000000..fbb40bace --- /dev/null +++ b/packages/client/src/components/formula.vue @@ -0,0 +1,23 @@ + + + diff --git a/packages/client/src/components/gallery-post-preview.vue b/packages/client/src/components/gallery-post-preview.vue new file mode 100644 index 000000000..824590297 --- /dev/null +++ b/packages/client/src/components/gallery-post-preview.vue @@ -0,0 +1,126 @@ + + + + + diff --git a/packages/client/src/components/global/a.vue b/packages/client/src/components/global/a.vue new file mode 100644 index 000000000..5db61203c --- /dev/null +++ b/packages/client/src/components/global/a.vue @@ -0,0 +1,138 @@ + + + diff --git a/packages/client/src/components/global/acct.vue b/packages/client/src/components/global/acct.vue new file mode 100644 index 000000000..b0c41c99c --- /dev/null +++ b/packages/client/src/components/global/acct.vue @@ -0,0 +1,38 @@ + + + + + diff --git a/packages/client/src/components/global/ad.vue b/packages/client/src/components/global/ad.vue new file mode 100644 index 000000000..71cb16740 --- /dev/null +++ b/packages/client/src/components/global/ad.vue @@ -0,0 +1,200 @@ + + + + + diff --git a/packages/client/src/components/global/avatar.vue b/packages/client/src/components/global/avatar.vue new file mode 100644 index 000000000..e509e893d --- /dev/null +++ b/packages/client/src/components/global/avatar.vue @@ -0,0 +1,163 @@ + + + + + diff --git a/src/client/components/global/ellipsis.vue b/packages/client/src/components/global/ellipsis.vue similarity index 100% rename from src/client/components/global/ellipsis.vue rename to packages/client/src/components/global/ellipsis.vue diff --git a/packages/client/src/components/global/emoji.vue b/packages/client/src/components/global/emoji.vue new file mode 100644 index 000000000..67a3dea2c --- /dev/null +++ b/packages/client/src/components/global/emoji.vue @@ -0,0 +1,125 @@ + + + + + diff --git a/packages/client/src/components/global/error.vue b/packages/client/src/components/global/error.vue new file mode 100644 index 000000000..8ce5d16ac --- /dev/null +++ b/packages/client/src/components/global/error.vue @@ -0,0 +1,46 @@ + + + + + diff --git a/packages/client/src/components/global/header.vue b/packages/client/src/components/global/header.vue new file mode 100644 index 000000000..7d5e426f2 --- /dev/null +++ b/packages/client/src/components/global/header.vue @@ -0,0 +1,360 @@ + + + + + diff --git a/src/client/components/global/i18n.ts b/packages/client/src/components/global/i18n.ts similarity index 100% rename from src/client/components/global/i18n.ts rename to packages/client/src/components/global/i18n.ts diff --git a/src/client/components/global/loading.vue b/packages/client/src/components/global/loading.vue similarity index 100% rename from src/client/components/global/loading.vue rename to packages/client/src/components/global/loading.vue diff --git a/packages/client/src/components/global/misskey-flavored-markdown.vue b/packages/client/src/components/global/misskey-flavored-markdown.vue new file mode 100644 index 000000000..ab2040490 --- /dev/null +++ b/packages/client/src/components/global/misskey-flavored-markdown.vue @@ -0,0 +1,157 @@ + + + + + + + diff --git a/src/client/components/global/spacer.vue b/packages/client/src/components/global/spacer.vue similarity index 100% rename from src/client/components/global/spacer.vue rename to packages/client/src/components/global/spacer.vue diff --git a/src/client/components/global/sticky-container.vue b/packages/client/src/components/global/sticky-container.vue similarity index 100% rename from src/client/components/global/sticky-container.vue rename to packages/client/src/components/global/sticky-container.vue diff --git a/src/client/components/global/time.vue b/packages/client/src/components/global/time.vue similarity index 100% rename from src/client/components/global/time.vue rename to packages/client/src/components/global/time.vue diff --git a/packages/client/src/components/global/url.vue b/packages/client/src/components/global/url.vue new file mode 100644 index 000000000..092fe6620 --- /dev/null +++ b/packages/client/src/components/global/url.vue @@ -0,0 +1,142 @@ + + + + + diff --git a/src/client/components/global/user-name.vue b/packages/client/src/components/global/user-name.vue similarity index 100% rename from src/client/components/global/user-name.vue rename to packages/client/src/components/global/user-name.vue diff --git a/packages/client/src/components/google.vue b/packages/client/src/components/google.vue new file mode 100644 index 000000000..c48feffbf --- /dev/null +++ b/packages/client/src/components/google.vue @@ -0,0 +1,64 @@ + + + + + diff --git a/packages/client/src/components/image-viewer.vue b/packages/client/src/components/image-viewer.vue new file mode 100644 index 000000000..fc28c30b5 --- /dev/null +++ b/packages/client/src/components/image-viewer.vue @@ -0,0 +1,85 @@ + + + + + diff --git a/src/client/components/img-with-blurhash.vue b/packages/client/src/components/img-with-blurhash.vue similarity index 100% rename from src/client/components/img-with-blurhash.vue rename to packages/client/src/components/img-with-blurhash.vue diff --git a/packages/client/src/components/index.ts b/packages/client/src/components/index.ts new file mode 100644 index 000000000..26bac6324 --- /dev/null +++ b/packages/client/src/components/index.ts @@ -0,0 +1,58 @@ +import { App } from 'vue'; + +import Mfm from './global/misskey-flavored-markdown.vue'; +import MkA from './global/a.vue'; +import MkAcct from './global/acct.vue'; +import MkAvatar from './global/avatar.vue'; +import MkEmoji from './global/emoji.vue'; +import MkUserName from './global/user-name.vue'; +import MkEllipsis from './global/ellipsis.vue'; +import MkTime from './global/time.vue'; +import MkUrl from './global/url.vue'; +import I18n from './global/i18n'; +import MkLoading from './global/loading.vue'; +import MkError from './global/error.vue'; +import MkAd from './global/ad.vue'; +import MkHeader from './global/header.vue'; +import MkSpacer from './global/spacer.vue'; +import MkStickyContainer from './global/sticky-container.vue'; + +export default function(app: App) { + app.component('I18n', I18n); + app.component('Mfm', Mfm); + app.component('MkA', MkA); + app.component('MkAcct', MkAcct); + app.component('MkAvatar', MkAvatar); + app.component('MkEmoji', MkEmoji); + app.component('MkUserName', MkUserName); + app.component('MkEllipsis', MkEllipsis); + app.component('MkTime', MkTime); + app.component('MkUrl', MkUrl); + app.component('MkLoading', MkLoading); + app.component('MkError', MkError); + app.component('MkAd', MkAd); + app.component('MkHeader', MkHeader); + app.component('MkSpacer', MkSpacer); + app.component('MkStickyContainer', MkStickyContainer); +} + +declare module '@vue/runtime-core' { + export interface GlobalComponents { + I18n: typeof I18n; + Mfm: typeof Mfm; + MkA: typeof MkA; + MkAcct: typeof MkAcct; + MkAvatar: typeof MkAvatar; + MkEmoji: typeof MkEmoji; + MkUserName: typeof MkUserName; + MkEllipsis: typeof MkEllipsis; + MkTime: typeof MkTime; + MkUrl: typeof MkUrl; + MkLoading: typeof MkLoading; + MkError: typeof MkError; + MkAd: typeof MkAd; + MkHeader: typeof MkHeader; + MkSpacer: typeof MkSpacer; + MkStickyContainer: typeof MkStickyContainer; + } +} diff --git a/packages/client/src/components/instance-stats.vue b/packages/client/src/components/instance-stats.vue new file mode 100644 index 000000000..bc62998a4 --- /dev/null +++ b/packages/client/src/components/instance-stats.vue @@ -0,0 +1,80 @@ + + + + + diff --git a/packages/client/src/components/instance-ticker.vue b/packages/client/src/components/instance-ticker.vue new file mode 100644 index 000000000..1ce5a1c2c --- /dev/null +++ b/packages/client/src/components/instance-ticker.vue @@ -0,0 +1,62 @@ + + + + + diff --git a/packages/client/src/components/launch-pad.vue b/packages/client/src/components/launch-pad.vue new file mode 100644 index 000000000..09f5f89f9 --- /dev/null +++ b/packages/client/src/components/launch-pad.vue @@ -0,0 +1,152 @@ + + + + + diff --git a/packages/client/src/components/link.vue b/packages/client/src/components/link.vue new file mode 100644 index 000000000..a8e096e0a --- /dev/null +++ b/packages/client/src/components/link.vue @@ -0,0 +1,92 @@ + + + + + diff --git a/packages/client/src/components/media-banner.vue b/packages/client/src/components/media-banner.vue new file mode 100644 index 000000000..2cf8c772e --- /dev/null +++ b/packages/client/src/components/media-banner.vue @@ -0,0 +1,107 @@ + + + + + diff --git a/packages/client/src/components/media-caption.vue b/packages/client/src/components/media-caption.vue new file mode 100644 index 000000000..08a3ca2b4 --- /dev/null +++ b/packages/client/src/components/media-caption.vue @@ -0,0 +1,259 @@ + + + + + diff --git a/packages/client/src/components/media-image.vue b/packages/client/src/components/media-image.vue new file mode 100644 index 000000000..8843b6320 --- /dev/null +++ b/packages/client/src/components/media-image.vue @@ -0,0 +1,155 @@ + + + + + diff --git a/packages/client/src/components/media-list.vue b/packages/client/src/components/media-list.vue new file mode 100644 index 000000000..51eaa86f3 --- /dev/null +++ b/packages/client/src/components/media-list.vue @@ -0,0 +1,167 @@ + + + + + diff --git a/packages/client/src/components/media-video.vue b/packages/client/src/components/media-video.vue new file mode 100644 index 000000000..aa885bd56 --- /dev/null +++ b/packages/client/src/components/media-video.vue @@ -0,0 +1,97 @@ + + + + + diff --git a/packages/client/src/components/mention.vue b/packages/client/src/components/mention.vue new file mode 100644 index 000000000..a5be3fab2 --- /dev/null +++ b/packages/client/src/components/mention.vue @@ -0,0 +1,84 @@ + + + + + diff --git a/packages/client/src/components/mfm.ts b/packages/client/src/components/mfm.ts new file mode 100644 index 000000000..d41cf6fc2 --- /dev/null +++ b/packages/client/src/components/mfm.ts @@ -0,0 +1,321 @@ +import { VNode, defineComponent, h } from 'vue'; +import * as mfm from 'mfm-js'; +import MkUrl from '@/components/global/url.vue'; +import MkLink from '@/components/link.vue'; +import MkMention from '@/components/mention.vue'; +import MkEmoji from '@/components/global/emoji.vue'; +import { concat } from '@/scripts/array'; +import MkFormula from '@/components/formula.vue'; +import MkCode from '@/components/code.vue'; +import MkGoogle from '@/components/google.vue'; +import MkSparkle from '@/components/sparkle.vue'; +import MkA from '@/components/global/a.vue'; +import { host } from '@/config'; +import { MFM_TAGS } from '@/scripts/mfm-tags'; + +export default defineComponent({ + props: { + text: { + type: String, + required: true + }, + plain: { + type: Boolean, + default: false + }, + nowrap: { + type: Boolean, + default: false + }, + author: { + type: Object, + default: null + }, + i: { + type: Object, + default: null + }, + customEmojis: { + required: false, + }, + isNote: { + type: Boolean, + default: true + }, + }, + + render() { + if (this.text == null || this.text == '') return; + + const ast = (this.plain ? mfm.parsePlain : mfm.parse)(this.text, { fnNameList: MFM_TAGS }); + + const validTime = (t: string | null | undefined) => { + if (t == null) return null; + return t.match(/^[0-9.]+s$/) ? t : null; + }; + + const genEl = (ast: mfm.MfmNode[]) => concat(ast.map((token): VNode[] => { + switch (token.type) { + case 'text': { + const text = token.props.text.replace(/(\r\n|\n|\r)/g, '\n'); + + if (!this.plain) { + const res = []; + for (const t of text.split('\n')) { + res.push(h('br')); + res.push(t); + } + res.shift(); + return res; + } else { + return [text.replace(/\n/g, ' ')]; + } + } + + case 'bold': { + return [h('b', genEl(token.children))]; + } + + case 'strike': { + return [h('del', genEl(token.children))]; + } + + case 'italic': { + return h('i', { + style: 'font-style: oblique;' + }, genEl(token.children)); + } + + case 'fn': { + // TODO: CSSを文字列で組み立てていくと token.props.args.~~~ 経由でCSSインジェクションできるのでよしなにやる + let style; + switch (token.props.name) { + case 'tada': { + style = `font-size: 150%;` + (this.$store.state.animatedMfm ? 'animation: tada 1s linear infinite both;' : ''); + break; + } + case 'jelly': { + const speed = validTime(token.props.args.speed) || '1s'; + style = (this.$store.state.animatedMfm ? `animation: mfm-rubberBand ${speed} linear infinite both;` : ''); + break; + } + case 'twitch': { + const speed = validTime(token.props.args.speed) || '0.5s'; + style = this.$store.state.animatedMfm ? `animation: mfm-twitch ${speed} ease infinite;` : ''; + break; + } + case 'shake': { + const speed = validTime(token.props.args.speed) || '0.5s'; + style = this.$store.state.animatedMfm ? `animation: mfm-shake ${speed} ease infinite;` : ''; + break; + } + case 'spin': { + const direction = + token.props.args.left ? 'reverse' : + token.props.args.alternate ? 'alternate' : + 'normal'; + const anime = + token.props.args.x ? 'mfm-spinX' : + token.props.args.y ? 'mfm-spinY' : + 'mfm-spin'; + const speed = validTime(token.props.args.speed) || '1.5s'; + style = this.$store.state.animatedMfm ? `animation: ${anime} ${speed} linear infinite; animation-direction: ${direction};` : ''; + break; + } + case 'jump': { + style = this.$store.state.animatedMfm ? 'animation: mfm-jump 0.75s linear infinite;' : ''; + break; + } + case 'bounce': { + style = this.$store.state.animatedMfm ? 'animation: mfm-bounce 0.75s linear infinite; transform-origin: center bottom;' : ''; + break; + } + case 'flip': { + const transform = + (token.props.args.h && token.props.args.v) ? 'scale(-1, -1)' : + token.props.args.v ? 'scaleY(-1)' : + 'scaleX(-1)'; + style = `transform: ${transform};`; + break; + } + case 'x2': { + style = `font-size: 200%;`; + break; + } + case 'x3': { + style = `font-size: 400%;`; + break; + } + case 'x4': { + style = `font-size: 600%;`; + break; + } + case 'font': { + const family = + token.props.args.serif ? 'serif' : + token.props.args.monospace ? 'monospace' : + token.props.args.cursive ? 'cursive' : + token.props.args.fantasy ? 'fantasy' : + token.props.args.emoji ? 'emoji' : + token.props.args.math ? 'math' : + null; + if (family) style = `font-family: ${family};`; + break; + } + case 'blur': { + return h('span', { + class: '_mfm_blur_', + }, genEl(token.children)); + } + case 'rainbow': { + style = this.$store.state.animatedMfm ? 'animation: mfm-rainbow 1s linear infinite;' : ''; + break; + } + case 'sparkle': { + if (!this.$store.state.animatedMfm) { + return genEl(token.children); + } + let count = token.props.args.count ? parseInt(token.props.args.count) : 10; + if (count > 100) { + count = 100; + } + const speed = token.props.args.speed ? parseFloat(token.props.args.speed) : 1; + return h(MkSparkle, { + count, speed, + }, genEl(token.children)); + } + } + if (style == null) { + return h('span', {}, ['$[', token.props.name, ' ', ...genEl(token.children), ']']); + } else { + return h('span', { + style: 'display: inline-block;' + style, + }, genEl(token.children)); + } + } + + case 'small': { + return [h('small', { + style: 'opacity: 0.7;' + }, genEl(token.children))]; + } + + case 'center': { + return [h('div', { + style: 'text-align:center;' + }, genEl(token.children))]; + } + + case 'url': { + return [h(MkUrl, { + key: Math.random(), + url: token.props.url, + rel: 'nofollow noopener', + })]; + } + + case 'link': { + return [h(MkLink, { + key: Math.random(), + url: token.props.url, + rel: 'nofollow noopener', + }, genEl(token.children))]; + } + + case 'mention': { + return [h(MkMention, { + key: Math.random(), + host: (token.props.host == null && this.author && this.author.host != null ? this.author.host : token.props.host) || host, + username: token.props.username + })]; + } + + case 'hashtag': { + return [h(MkA, { + key: Math.random(), + to: this.isNote ? `/tags/${encodeURIComponent(token.props.hashtag)}` : `/explore/tags/${encodeURIComponent(token.props.hashtag)}`, + style: 'color:var(--hashtag);' + }, `#${token.props.hashtag}`)]; + } + + case 'blockCode': { + return [h(MkCode, { + key: Math.random(), + code: token.props.code, + lang: token.props.lang, + })]; + } + + case 'inlineCode': { + return [h(MkCode, { + key: Math.random(), + code: token.props.code, + inline: true + })]; + } + + case 'quote': { + if (!this.nowrap) { + return [h('div', { + class: 'quote' + }, genEl(token.children))]; + } else { + return [h('span', { + class: 'quote' + }, genEl(token.children))]; + } + } + + case 'emojiCode': { + return [h(MkEmoji, { + key: Math.random(), + emoji: `:${token.props.name}:`, + customEmojis: this.customEmojis, + normal: this.plain + })]; + } + + case 'unicodeEmoji': { + return [h(MkEmoji, { + key: Math.random(), + emoji: token.props.emoji, + customEmojis: this.customEmojis, + normal: this.plain + })]; + } + + case 'mathInline': { + return [h(MkFormula, { + key: Math.random(), + formula: token.props.formula, + block: false + })]; + } + + case 'mathBlock': { + return [h(MkFormula, { + key: Math.random(), + formula: token.props.formula, + block: true + })]; + } + + case 'search': { + return [h(MkGoogle, { + key: Math.random(), + q: token.props.query + })]; + } + + default: { + console.error('unrecognized ast type:', token.type); + + return []; + } + } + })); + + // Parse ast to DOM + return h('span', genEl(ast)); + } +}); diff --git a/packages/client/src/components/mini-chart.vue b/packages/client/src/components/mini-chart.vue new file mode 100644 index 000000000..2eb9ae8cb --- /dev/null +++ b/packages/client/src/components/mini-chart.vue @@ -0,0 +1,90 @@ + + + diff --git a/packages/client/src/components/modal-page-window.vue b/packages/client/src/components/modal-page-window.vue new file mode 100644 index 000000000..208673668 --- /dev/null +++ b/packages/client/src/components/modal-page-window.vue @@ -0,0 +1,223 @@ + + + + + diff --git a/packages/client/src/components/note-detailed.vue b/packages/client/src/components/note-detailed.vue new file mode 100644 index 000000000..3b5b12a60 --- /dev/null +++ b/packages/client/src/components/note-detailed.vue @@ -0,0 +1,1197 @@ + + + + + diff --git a/packages/client/src/components/note-header.vue b/packages/client/src/components/note-header.vue new file mode 100644 index 000000000..c22886903 --- /dev/null +++ b/packages/client/src/components/note-header.vue @@ -0,0 +1,110 @@ + + + + + diff --git a/src/client/components/note-preview.vue b/packages/client/src/components/note-preview.vue similarity index 100% rename from src/client/components/note-preview.vue rename to packages/client/src/components/note-preview.vue diff --git a/packages/client/src/components/note-simple.vue b/packages/client/src/components/note-simple.vue new file mode 100644 index 000000000..2f19bd6e0 --- /dev/null +++ b/packages/client/src/components/note-simple.vue @@ -0,0 +1,113 @@ + + + + + diff --git a/packages/client/src/components/note.sub.vue b/packages/client/src/components/note.sub.vue new file mode 100644 index 000000000..45204854b --- /dev/null +++ b/packages/client/src/components/note.sub.vue @@ -0,0 +1,146 @@ + + + + + diff --git a/packages/client/src/components/note.vue b/packages/client/src/components/note.vue new file mode 100644 index 000000000..2ab769db4 --- /dev/null +++ b/packages/client/src/components/note.vue @@ -0,0 +1,1197 @@ + + + + + diff --git a/packages/client/src/components/notes.vue b/packages/client/src/components/notes.vue new file mode 100644 index 000000000..1e7da7a2b --- /dev/null +++ b/packages/client/src/components/notes.vue @@ -0,0 +1,130 @@ + + + + + diff --git a/packages/client/src/components/notification-setting-window.vue b/packages/client/src/components/notification-setting-window.vue new file mode 100644 index 000000000..ec1efec26 --- /dev/null +++ b/packages/client/src/components/notification-setting-window.vue @@ -0,0 +1,99 @@ + + + diff --git a/packages/client/src/components/notification.vue b/packages/client/src/components/notification.vue new file mode 100644 index 000000000..40670daa9 --- /dev/null +++ b/packages/client/src/components/notification.vue @@ -0,0 +1,331 @@ + + + + + diff --git a/packages/client/src/components/notifications.vue b/packages/client/src/components/notifications.vue new file mode 100644 index 000000000..4ebb12c44 --- /dev/null +++ b/packages/client/src/components/notifications.vue @@ -0,0 +1,159 @@ + + + + + diff --git a/packages/client/src/components/number-diff.vue b/packages/client/src/components/number-diff.vue new file mode 100644 index 000000000..9889c97ec --- /dev/null +++ b/packages/client/src/components/number-diff.vue @@ -0,0 +1,47 @@ + + + + + diff --git a/packages/client/src/components/page-preview.vue b/packages/client/src/components/page-preview.vue new file mode 100644 index 000000000..05df1dc16 --- /dev/null +++ b/packages/client/src/components/page-preview.vue @@ -0,0 +1,162 @@ + + + + + diff --git a/packages/client/src/components/page-window.vue b/packages/client/src/components/page-window.vue new file mode 100644 index 000000000..b6be114cd --- /dev/null +++ b/packages/client/src/components/page-window.vue @@ -0,0 +1,167 @@ + + + + + diff --git a/packages/client/src/components/page/page.block.vue b/packages/client/src/components/page/page.block.vue new file mode 100644 index 000000000..54b8b3027 --- /dev/null +++ b/packages/client/src/components/page/page.block.vue @@ -0,0 +1,44 @@ + + + diff --git a/packages/client/src/components/page/page.button.vue b/packages/client/src/components/page/page.button.vue new file mode 100644 index 000000000..51da84bd4 --- /dev/null +++ b/packages/client/src/components/page/page.button.vue @@ -0,0 +1,66 @@ + + + + + diff --git a/packages/client/src/components/page/page.canvas.vue b/packages/client/src/components/page/page.canvas.vue new file mode 100644 index 000000000..8f49b88e5 --- /dev/null +++ b/packages/client/src/components/page/page.canvas.vue @@ -0,0 +1,49 @@ + + + + + diff --git a/packages/client/src/components/page/page.counter.vue b/packages/client/src/components/page/page.counter.vue new file mode 100644 index 000000000..b1af8954b --- /dev/null +++ b/packages/client/src/components/page/page.counter.vue @@ -0,0 +1,52 @@ + + + + + diff --git a/packages/client/src/components/page/page.if.vue b/packages/client/src/components/page/page.if.vue new file mode 100644 index 000000000..ec25332db --- /dev/null +++ b/packages/client/src/components/page/page.if.vue @@ -0,0 +1,31 @@ + + + diff --git a/packages/client/src/components/page/page.image.vue b/packages/client/src/components/page/page.image.vue new file mode 100644 index 000000000..04ce74bd7 --- /dev/null +++ b/packages/client/src/components/page/page.image.vue @@ -0,0 +1,40 @@ + + + + + diff --git a/packages/client/src/components/page/page.note.vue b/packages/client/src/components/page/page.note.vue new file mode 100644 index 000000000..925844c1b --- /dev/null +++ b/packages/client/src/components/page/page.note.vue @@ -0,0 +1,47 @@ + + + + + diff --git a/packages/client/src/components/page/page.number-input.vue b/packages/client/src/components/page/page.number-input.vue new file mode 100644 index 000000000..b5120d0f8 --- /dev/null +++ b/packages/client/src/components/page/page.number-input.vue @@ -0,0 +1,55 @@ + + + + + diff --git a/packages/client/src/components/page/page.post.vue b/packages/client/src/components/page/page.post.vue new file mode 100644 index 000000000..1b86ea1ab --- /dev/null +++ b/packages/client/src/components/page/page.post.vue @@ -0,0 +1,109 @@ + + + + + diff --git a/packages/client/src/components/page/page.radio-button.vue b/packages/client/src/components/page/page.radio-button.vue new file mode 100644 index 000000000..4d3c03291 --- /dev/null +++ b/packages/client/src/components/page/page.radio-button.vue @@ -0,0 +1,45 @@ + + + diff --git a/packages/client/src/components/page/page.section.vue b/packages/client/src/components/page/page.section.vue new file mode 100644 index 000000000..d32f5dc73 --- /dev/null +++ b/packages/client/src/components/page/page.section.vue @@ -0,0 +1,60 @@ + + + + + diff --git a/packages/client/src/components/page/page.switch.vue b/packages/client/src/components/page/page.switch.vue new file mode 100644 index 000000000..1ece88157 --- /dev/null +++ b/packages/client/src/components/page/page.switch.vue @@ -0,0 +1,55 @@ + + + + + diff --git a/packages/client/src/components/page/page.text-input.vue b/packages/client/src/components/page/page.text-input.vue new file mode 100644 index 000000000..e4d3f6039 --- /dev/null +++ b/packages/client/src/components/page/page.text-input.vue @@ -0,0 +1,55 @@ + + + + + diff --git a/packages/client/src/components/page/page.text.vue b/packages/client/src/components/page/page.text.vue new file mode 100644 index 000000000..7dd41ed86 --- /dev/null +++ b/packages/client/src/components/page/page.text.vue @@ -0,0 +1,68 @@ + + + + + diff --git a/packages/client/src/components/page/page.textarea-input.vue b/packages/client/src/components/page/page.textarea-input.vue new file mode 100644 index 000000000..6e082b2be --- /dev/null +++ b/packages/client/src/components/page/page.textarea-input.vue @@ -0,0 +1,47 @@ + + + diff --git a/packages/client/src/components/page/page.textarea.vue b/packages/client/src/components/page/page.textarea.vue new file mode 100644 index 000000000..5b4ee2b45 --- /dev/null +++ b/packages/client/src/components/page/page.textarea.vue @@ -0,0 +1,39 @@ + + + diff --git a/packages/client/src/components/page/page.vue b/packages/client/src/components/page/page.vue new file mode 100644 index 000000000..6d1c419a4 --- /dev/null +++ b/packages/client/src/components/page/page.vue @@ -0,0 +1,86 @@ + + + + + diff --git a/src/client/components/particle.vue b/packages/client/src/components/particle.vue similarity index 100% rename from src/client/components/particle.vue rename to packages/client/src/components/particle.vue diff --git a/packages/client/src/components/poll-editor.vue b/packages/client/src/components/poll-editor.vue new file mode 100644 index 000000000..aa213cfe4 --- /dev/null +++ b/packages/client/src/components/poll-editor.vue @@ -0,0 +1,251 @@ + + + + + diff --git a/packages/client/src/components/poll.vue b/packages/client/src/components/poll.vue new file mode 100644 index 000000000..049fe3a43 --- /dev/null +++ b/packages/client/src/components/poll.vue @@ -0,0 +1,174 @@ + + + + + diff --git a/packages/client/src/components/post-form-attaches.vue b/packages/client/src/components/post-form-attaches.vue new file mode 100644 index 000000000..dff0dec21 --- /dev/null +++ b/packages/client/src/components/post-form-attaches.vue @@ -0,0 +1,193 @@ + + + + + diff --git a/packages/client/src/components/post-form-dialog.vue b/packages/client/src/components/post-form-dialog.vue new file mode 100644 index 000000000..ae1cd7f01 --- /dev/null +++ b/packages/client/src/components/post-form-dialog.vue @@ -0,0 +1,19 @@ + + + diff --git a/packages/client/src/components/post-form.vue b/packages/client/src/components/post-form.vue new file mode 100644 index 000000000..882a71a37 --- /dev/null +++ b/packages/client/src/components/post-form.vue @@ -0,0 +1,978 @@ + + + + + diff --git a/packages/client/src/pages/messaging/messaging-room.message.vue b/packages/client/src/pages/messaging/messaging-room.message.vue new file mode 100644 index 000000000..432d11add --- /dev/null +++ b/packages/client/src/pages/messaging/messaging-room.message.vue @@ -0,0 +1,350 @@ + + + + + diff --git a/packages/client/src/pages/messaging/messaging-room.vue b/packages/client/src/pages/messaging/messaging-room.vue new file mode 100644 index 000000000..3a19b1276 --- /dev/null +++ b/packages/client/src/pages/messaging/messaging-room.vue @@ -0,0 +1,470 @@ + + + + + diff --git a/packages/client/src/pages/mfm-cheat-sheet.vue b/packages/client/src/pages/mfm-cheat-sheet.vue new file mode 100644 index 000000000..e9a3b6deb --- /dev/null +++ b/packages/client/src/pages/mfm-cheat-sheet.vue @@ -0,0 +1,365 @@ + + + + + diff --git a/packages/client/src/pages/miauth.vue b/packages/client/src/pages/miauth.vue new file mode 100644 index 000000000..6430588c4 --- /dev/null +++ b/packages/client/src/pages/miauth.vue @@ -0,0 +1,100 @@ + + + + + diff --git a/packages/client/src/pages/my-antennas/create.vue b/packages/client/src/pages/my-antennas/create.vue new file mode 100644 index 000000000..173807475 --- /dev/null +++ b/packages/client/src/pages/my-antennas/create.vue @@ -0,0 +1,51 @@ + + + + + diff --git a/packages/client/src/pages/my-antennas/edit.vue b/packages/client/src/pages/my-antennas/edit.vue new file mode 100644 index 000000000..04928c81a --- /dev/null +++ b/packages/client/src/pages/my-antennas/edit.vue @@ -0,0 +1,56 @@ + + + + + diff --git a/packages/client/src/pages/my-antennas/editor.vue b/packages/client/src/pages/my-antennas/editor.vue new file mode 100644 index 000000000..5ad3d5048 --- /dev/null +++ b/packages/client/src/pages/my-antennas/editor.vue @@ -0,0 +1,190 @@ + + + + + diff --git a/packages/client/src/pages/my-antennas/index.vue b/packages/client/src/pages/my-antennas/index.vue new file mode 100644 index 000000000..029f1949d --- /dev/null +++ b/packages/client/src/pages/my-antennas/index.vue @@ -0,0 +1,71 @@ + + + + + diff --git a/packages/client/src/pages/my-clips/index.vue b/packages/client/src/pages/my-clips/index.vue new file mode 100644 index 000000000..cbcdb85fa --- /dev/null +++ b/packages/client/src/pages/my-clips/index.vue @@ -0,0 +1,104 @@ + + + + + diff --git a/packages/client/src/pages/my-groups/group.vue b/packages/client/src/pages/my-groups/group.vue new file mode 100644 index 000000000..9548c374d --- /dev/null +++ b/packages/client/src/pages/my-groups/group.vue @@ -0,0 +1,184 @@ + + + + + diff --git a/packages/client/src/pages/my-groups/index.vue b/packages/client/src/pages/my-groups/index.vue new file mode 100644 index 000000000..77e7d6088 --- /dev/null +++ b/packages/client/src/pages/my-groups/index.vue @@ -0,0 +1,121 @@ + + + + + diff --git a/packages/client/src/pages/my-lists/index.vue b/packages/client/src/pages/my-lists/index.vue new file mode 100644 index 000000000..adb59db66 --- /dev/null +++ b/packages/client/src/pages/my-lists/index.vue @@ -0,0 +1,88 @@ + + + + + diff --git a/packages/client/src/pages/my-lists/list.vue b/packages/client/src/pages/my-lists/list.vue new file mode 100644 index 000000000..f2a02cadc --- /dev/null +++ b/packages/client/src/pages/my-lists/list.vue @@ -0,0 +1,170 @@ + + + + + diff --git a/packages/client/src/pages/not-found.vue b/packages/client/src/pages/not-found.vue new file mode 100644 index 000000000..92d3f399f --- /dev/null +++ b/packages/client/src/pages/not-found.vue @@ -0,0 +1,25 @@ + + + diff --git a/packages/client/src/pages/note.vue b/packages/client/src/pages/note.vue new file mode 100644 index 000000000..ecd391dfb --- /dev/null +++ b/packages/client/src/pages/note.vue @@ -0,0 +1,209 @@ + + + + + diff --git a/packages/client/src/pages/notifications.vue b/packages/client/src/pages/notifications.vue new file mode 100644 index 000000000..f8e610a71 --- /dev/null +++ b/packages/client/src/pages/notifications.vue @@ -0,0 +1,88 @@ + + + + + diff --git a/packages/client/src/pages/page-editor/els/page-editor.el.button.vue b/packages/client/src/pages/page-editor/els/page-editor.el.button.vue new file mode 100644 index 000000000..a25a892ea --- /dev/null +++ b/packages/client/src/pages/page-editor/els/page-editor.el.button.vue @@ -0,0 +1,84 @@ + + + + + diff --git a/packages/client/src/pages/page-editor/els/page-editor.el.canvas.vue b/packages/client/src/pages/page-editor/els/page-editor.el.canvas.vue new file mode 100644 index 000000000..5d009561e --- /dev/null +++ b/packages/client/src/pages/page-editor/els/page-editor.el.canvas.vue @@ -0,0 +1,50 @@ + + + diff --git a/packages/client/src/pages/page-editor/els/page-editor.el.counter.vue b/packages/client/src/pages/page-editor/els/page-editor.el.counter.vue new file mode 100644 index 000000000..3704c6425 --- /dev/null +++ b/packages/client/src/pages/page-editor/els/page-editor.el.counter.vue @@ -0,0 +1,46 @@ + + + diff --git a/packages/client/src/pages/page-editor/els/page-editor.el.if.vue b/packages/client/src/pages/page-editor/els/page-editor.el.if.vue new file mode 100644 index 000000000..f76d59abe --- /dev/null +++ b/packages/client/src/pages/page-editor/els/page-editor.el.if.vue @@ -0,0 +1,84 @@ + + + + + diff --git a/packages/client/src/pages/page-editor/els/page-editor.el.image.vue b/packages/client/src/pages/page-editor/els/page-editor.el.image.vue new file mode 100644 index 000000000..396c83f51 --- /dev/null +++ b/packages/client/src/pages/page-editor/els/page-editor.el.image.vue @@ -0,0 +1,72 @@ + + + + + diff --git a/packages/client/src/pages/page-editor/els/page-editor.el.note.vue b/packages/client/src/pages/page-editor/els/page-editor.el.note.vue new file mode 100644 index 000000000..263b60d3e --- /dev/null +++ b/packages/client/src/pages/page-editor/els/page-editor.el.note.vue @@ -0,0 +1,65 @@ + + + diff --git a/packages/client/src/pages/page-editor/els/page-editor.el.number-input.vue b/packages/client/src/pages/page-editor/els/page-editor.el.number-input.vue new file mode 100644 index 000000000..3a2f4a762 --- /dev/null +++ b/packages/client/src/pages/page-editor/els/page-editor.el.number-input.vue @@ -0,0 +1,46 @@ + + + diff --git a/packages/client/src/pages/page-editor/els/page-editor.el.post.vue b/packages/client/src/pages/page-editor/els/page-editor.el.post.vue new file mode 100644 index 000000000..780786144 --- /dev/null +++ b/packages/client/src/pages/page-editor/els/page-editor.el.post.vue @@ -0,0 +1,43 @@ + + + diff --git a/packages/client/src/pages/page-editor/els/page-editor.el.radio-button.vue b/packages/client/src/pages/page-editor/els/page-editor.el.radio-button.vue new file mode 100644 index 000000000..f01a47c54 --- /dev/null +++ b/packages/client/src/pages/page-editor/els/page-editor.el.radio-button.vue @@ -0,0 +1,50 @@ + + + diff --git a/packages/client/src/pages/page-editor/els/page-editor.el.section.vue b/packages/client/src/pages/page-editor/els/page-editor.el.section.vue new file mode 100644 index 000000000..16e32d840 --- /dev/null +++ b/packages/client/src/pages/page-editor/els/page-editor.el.section.vue @@ -0,0 +1,96 @@ + + + + + diff --git a/packages/client/src/pages/page-editor/els/page-editor.el.switch.vue b/packages/client/src/pages/page-editor/els/page-editor.el.switch.vue new file mode 100644 index 000000000..e72f7b44d --- /dev/null +++ b/packages/client/src/pages/page-editor/els/page-editor.el.switch.vue @@ -0,0 +1,46 @@ + + + + + diff --git a/packages/client/src/pages/page-editor/els/page-editor.el.text-input.vue b/packages/client/src/pages/page-editor/els/page-editor.el.text-input.vue new file mode 100644 index 000000000..908862cf0 --- /dev/null +++ b/packages/client/src/pages/page-editor/els/page-editor.el.text-input.vue @@ -0,0 +1,39 @@ + + + diff --git a/packages/client/src/pages/page-editor/els/page-editor.el.text.vue b/packages/client/src/pages/page-editor/els/page-editor.el.text.vue new file mode 100644 index 000000000..05b1a9c67 --- /dev/null +++ b/packages/client/src/pages/page-editor/els/page-editor.el.text.vue @@ -0,0 +1,57 @@ + + + + + diff --git a/packages/client/src/pages/page-editor/els/page-editor.el.textarea-input.vue b/packages/client/src/pages/page-editor/els/page-editor.el.textarea-input.vue new file mode 100644 index 000000000..bb37158ec --- /dev/null +++ b/packages/client/src/pages/page-editor/els/page-editor.el.textarea-input.vue @@ -0,0 +1,40 @@ + + + diff --git a/packages/client/src/pages/page-editor/els/page-editor.el.textarea.vue b/packages/client/src/pages/page-editor/els/page-editor.el.textarea.vue new file mode 100644 index 000000000..4ca83da17 --- /dev/null +++ b/packages/client/src/pages/page-editor/els/page-editor.el.textarea.vue @@ -0,0 +1,57 @@ + + + + + diff --git a/packages/client/src/pages/page-editor/page-editor.blocks.vue b/packages/client/src/pages/page-editor/page-editor.blocks.vue new file mode 100644 index 000000000..b91d9abae --- /dev/null +++ b/packages/client/src/pages/page-editor/page-editor.blocks.vue @@ -0,0 +1,78 @@ + + + diff --git a/src/client/pages/page-editor/page-editor.container.vue b/packages/client/src/pages/page-editor/page-editor.container.vue similarity index 100% rename from src/client/pages/page-editor/page-editor.container.vue rename to packages/client/src/pages/page-editor/page-editor.container.vue diff --git a/packages/client/src/pages/page-editor/page-editor.script-block.vue b/packages/client/src/pages/page-editor/page-editor.script-block.vue new file mode 100644 index 000000000..07958c902 --- /dev/null +++ b/packages/client/src/pages/page-editor/page-editor.script-block.vue @@ -0,0 +1,281 @@ + + + + + diff --git a/packages/client/src/pages/page-editor/page-editor.vue b/packages/client/src/pages/page-editor/page-editor.vue new file mode 100644 index 000000000..684b1f8c7 --- /dev/null +++ b/packages/client/src/pages/page-editor/page-editor.vue @@ -0,0 +1,561 @@ + + + + + diff --git a/packages/client/src/pages/page.vue b/packages/client/src/pages/page.vue new file mode 100644 index 000000000..1eff1a98c --- /dev/null +++ b/packages/client/src/pages/page.vue @@ -0,0 +1,311 @@ + + + + + diff --git a/packages/client/src/pages/pages.vue b/packages/client/src/pages/pages.vue new file mode 100644 index 000000000..d66fc2ad5 --- /dev/null +++ b/packages/client/src/pages/pages.vue @@ -0,0 +1,96 @@ + + + + + diff --git a/packages/client/src/pages/preview.vue b/packages/client/src/pages/preview.vue new file mode 100644 index 000000000..9d1ebb74e --- /dev/null +++ b/packages/client/src/pages/preview.vue @@ -0,0 +1,32 @@ + + + + + diff --git a/packages/client/src/pages/reset-password.vue b/packages/client/src/pages/reset-password.vue new file mode 100644 index 000000000..f9a250084 --- /dev/null +++ b/packages/client/src/pages/reset-password.vue @@ -0,0 +1,69 @@ + + + + + diff --git a/packages/client/src/pages/reversi/game.board.vue b/packages/client/src/pages/reversi/game.board.vue new file mode 100644 index 000000000..529e00d96 --- /dev/null +++ b/packages/client/src/pages/reversi/game.board.vue @@ -0,0 +1,528 @@ + + + + + diff --git a/packages/client/src/pages/reversi/game.setting.vue b/packages/client/src/pages/reversi/game.setting.vue new file mode 100644 index 000000000..e6a6661f1 --- /dev/null +++ b/packages/client/src/pages/reversi/game.setting.vue @@ -0,0 +1,390 @@ + + + + + diff --git a/packages/client/src/pages/reversi/game.vue b/packages/client/src/pages/reversi/game.vue new file mode 100644 index 000000000..b1ed63290 --- /dev/null +++ b/packages/client/src/pages/reversi/game.vue @@ -0,0 +1,76 @@ + + + diff --git a/packages/client/src/pages/reversi/index.vue b/packages/client/src/pages/reversi/index.vue new file mode 100644 index 000000000..1b8f1ffb7 --- /dev/null +++ b/packages/client/src/pages/reversi/index.vue @@ -0,0 +1,279 @@ + + + + + diff --git a/packages/client/src/pages/room/preview.vue b/packages/client/src/pages/room/preview.vue new file mode 100644 index 000000000..b0e600d4f --- /dev/null +++ b/packages/client/src/pages/room/preview.vue @@ -0,0 +1,107 @@ + + + diff --git a/packages/client/src/pages/room/room.vue b/packages/client/src/pages/room/room.vue new file mode 100644 index 000000000..1671bcd58 --- /dev/null +++ b/packages/client/src/pages/room/room.vue @@ -0,0 +1,285 @@ + + + + + diff --git a/packages/client/src/pages/scratchpad.vue b/packages/client/src/pages/scratchpad.vue new file mode 100644 index 000000000..c26658cbc --- /dev/null +++ b/packages/client/src/pages/scratchpad.vue @@ -0,0 +1,149 @@ + + + + + diff --git a/packages/client/src/pages/search.vue b/packages/client/src/pages/search.vue new file mode 100644 index 000000000..c7da3fe1c --- /dev/null +++ b/packages/client/src/pages/search.vue @@ -0,0 +1,53 @@ + + + diff --git a/packages/client/src/pages/settings/2fa.vue b/packages/client/src/pages/settings/2fa.vue new file mode 100644 index 000000000..dce217559 --- /dev/null +++ b/packages/client/src/pages/settings/2fa.vue @@ -0,0 +1,247 @@ + + + diff --git a/packages/client/src/pages/settings/account-info.vue b/packages/client/src/pages/settings/account-info.vue new file mode 100644 index 000000000..f3d5e2f2c --- /dev/null +++ b/packages/client/src/pages/settings/account-info.vue @@ -0,0 +1,185 @@ + + + diff --git a/packages/client/src/pages/settings/accounts.vue b/packages/client/src/pages/settings/accounts.vue new file mode 100644 index 000000000..94a3c9483 --- /dev/null +++ b/packages/client/src/pages/settings/accounts.vue @@ -0,0 +1,149 @@ + + + + + diff --git a/packages/client/src/pages/settings/api.vue b/packages/client/src/pages/settings/api.vue new file mode 100644 index 000000000..1def0189e --- /dev/null +++ b/packages/client/src/pages/settings/api.vue @@ -0,0 +1,65 @@ + + + diff --git a/packages/client/src/pages/settings/apps.vue b/packages/client/src/pages/settings/apps.vue new file mode 100644 index 000000000..6eec80d80 --- /dev/null +++ b/packages/client/src/pages/settings/apps.vue @@ -0,0 +1,113 @@ + + + + + diff --git a/packages/client/src/pages/settings/custom-css.vue b/packages/client/src/pages/settings/custom-css.vue new file mode 100644 index 000000000..8c878fb08 --- /dev/null +++ b/packages/client/src/pages/settings/custom-css.vue @@ -0,0 +1,73 @@ + + + diff --git a/packages/client/src/pages/settings/deck.vue b/packages/client/src/pages/settings/deck.vue new file mode 100644 index 000000000..a96c6cd68 --- /dev/null +++ b/packages/client/src/pages/settings/deck.vue @@ -0,0 +1,107 @@ + + + diff --git a/packages/client/src/pages/settings/delete-account.vue b/packages/client/src/pages/settings/delete-account.vue new file mode 100644 index 000000000..018f7c795 --- /dev/null +++ b/packages/client/src/pages/settings/delete-account.vue @@ -0,0 +1,68 @@ + + + diff --git a/packages/client/src/pages/settings/drive.vue b/packages/client/src/pages/settings/drive.vue new file mode 100644 index 000000000..ed5282e23 --- /dev/null +++ b/packages/client/src/pages/settings/drive.vue @@ -0,0 +1,147 @@ + + + + + diff --git a/packages/client/src/pages/settings/email-address.vue b/packages/client/src/pages/settings/email-address.vue new file mode 100644 index 000000000..476d0c0e1 --- /dev/null +++ b/packages/client/src/pages/settings/email-address.vue @@ -0,0 +1,70 @@ + + + diff --git a/packages/client/src/pages/settings/email-notification.vue b/packages/client/src/pages/settings/email-notification.vue new file mode 100644 index 000000000..c1735a072 --- /dev/null +++ b/packages/client/src/pages/settings/email-notification.vue @@ -0,0 +1,91 @@ + + + diff --git a/packages/client/src/pages/settings/email.vue b/packages/client/src/pages/settings/email.vue new file mode 100644 index 000000000..d1dda20f0 --- /dev/null +++ b/packages/client/src/pages/settings/email.vue @@ -0,0 +1,66 @@ + + + diff --git a/packages/client/src/pages/settings/experimental-features.vue b/packages/client/src/pages/settings/experimental-features.vue new file mode 100644 index 000000000..5a7bcb3b4 --- /dev/null +++ b/packages/client/src/pages/settings/experimental-features.vue @@ -0,0 +1,52 @@ + + + diff --git a/packages/client/src/pages/settings/general.vue b/packages/client/src/pages/settings/general.vue new file mode 100644 index 000000000..8e3dcc3e4 --- /dev/null +++ b/packages/client/src/pages/settings/general.vue @@ -0,0 +1,223 @@ + + + diff --git a/packages/client/src/pages/settings/import-export.vue b/packages/client/src/pages/settings/import-export.vue new file mode 100644 index 000000000..8923483b9 --- /dev/null +++ b/packages/client/src/pages/settings/import-export.vue @@ -0,0 +1,112 @@ + + + + + diff --git a/packages/client/src/pages/settings/index.vue b/packages/client/src/pages/settings/index.vue new file mode 100644 index 000000000..b9d390326 --- /dev/null +++ b/packages/client/src/pages/settings/index.vue @@ -0,0 +1,326 @@ + + + + + diff --git a/packages/client/src/pages/settings/integration.vue b/packages/client/src/pages/settings/integration.vue new file mode 100644 index 000000000..405f93b77 --- /dev/null +++ b/packages/client/src/pages/settings/integration.vue @@ -0,0 +1,141 @@ + + + diff --git a/packages/client/src/pages/settings/menu.vue b/packages/client/src/pages/settings/menu.vue new file mode 100644 index 000000000..e40740a3a --- /dev/null +++ b/packages/client/src/pages/settings/menu.vue @@ -0,0 +1,117 @@ + + + diff --git a/packages/client/src/pages/settings/mute-block.vue b/packages/client/src/pages/settings/mute-block.vue new file mode 100644 index 000000000..4a9633a20 --- /dev/null +++ b/packages/client/src/pages/settings/mute-block.vue @@ -0,0 +1,85 @@ + + + diff --git a/packages/client/src/pages/settings/notifications.vue b/packages/client/src/pages/settings/notifications.vue new file mode 100644 index 000000000..7de10a182 --- /dev/null +++ b/packages/client/src/pages/settings/notifications.vue @@ -0,0 +1,77 @@ + + + diff --git a/packages/client/src/pages/settings/other.vue b/packages/client/src/pages/settings/other.vue new file mode 100644 index 000000000..fbc895a07 --- /dev/null +++ b/packages/client/src/pages/settings/other.vue @@ -0,0 +1,97 @@ + + + diff --git a/packages/client/src/pages/settings/plugin.install.vue b/packages/client/src/pages/settings/plugin.install.vue new file mode 100644 index 000000000..9958f98f5 --- /dev/null +++ b/packages/client/src/pages/settings/plugin.install.vue @@ -0,0 +1,147 @@ + + + diff --git a/packages/client/src/pages/settings/plugin.manage.vue b/packages/client/src/pages/settings/plugin.manage.vue new file mode 100644 index 000000000..3a0168d13 --- /dev/null +++ b/packages/client/src/pages/settings/plugin.manage.vue @@ -0,0 +1,115 @@ + + + + + diff --git a/packages/client/src/pages/settings/plugin.vue b/packages/client/src/pages/settings/plugin.vue new file mode 100644 index 000000000..50e53f459 --- /dev/null +++ b/packages/client/src/pages/settings/plugin.vue @@ -0,0 +1,44 @@ + + + + + diff --git a/packages/client/src/pages/settings/privacy.vue b/packages/client/src/pages/settings/privacy.vue new file mode 100644 index 000000000..94afba9aa --- /dev/null +++ b/packages/client/src/pages/settings/privacy.vue @@ -0,0 +1,120 @@ + + + diff --git a/packages/client/src/pages/settings/profile.vue b/packages/client/src/pages/settings/profile.vue new file mode 100644 index 000000000..a7ddc6d17 --- /dev/null +++ b/packages/client/src/pages/settings/profile.vue @@ -0,0 +1,281 @@ + + + + + diff --git a/packages/client/src/pages/settings/reaction.vue b/packages/client/src/pages/settings/reaction.vue new file mode 100644 index 000000000..905a3e495 --- /dev/null +++ b/packages/client/src/pages/settings/reaction.vue @@ -0,0 +1,152 @@ + + + + + diff --git a/packages/client/src/pages/settings/registry.keys.vue b/packages/client/src/pages/settings/registry.keys.vue new file mode 100644 index 000000000..ca4d01cc9 --- /dev/null +++ b/packages/client/src/pages/settings/registry.keys.vue @@ -0,0 +1,114 @@ + + + diff --git a/packages/client/src/pages/settings/registry.value.vue b/packages/client/src/pages/settings/registry.value.vue new file mode 100644 index 000000000..36f989dbc --- /dev/null +++ b/packages/client/src/pages/settings/registry.value.vue @@ -0,0 +1,149 @@ + + + diff --git a/packages/client/src/pages/settings/registry.vue b/packages/client/src/pages/settings/registry.vue new file mode 100644 index 000000000..0bfed0ddb --- /dev/null +++ b/packages/client/src/pages/settings/registry.vue @@ -0,0 +1,90 @@ + + + diff --git a/packages/client/src/pages/settings/security.vue b/packages/client/src/pages/settings/security.vue new file mode 100644 index 000000000..4d81bf1b9 --- /dev/null +++ b/packages/client/src/pages/settings/security.vue @@ -0,0 +1,158 @@ + + + + + diff --git a/packages/client/src/pages/settings/sounds.vue b/packages/client/src/pages/settings/sounds.vue new file mode 100644 index 000000000..ea3daced9 --- /dev/null +++ b/packages/client/src/pages/settings/sounds.vue @@ -0,0 +1,155 @@ + + + diff --git a/packages/client/src/pages/settings/theme.install.vue b/packages/client/src/pages/settings/theme.install.vue new file mode 100644 index 000000000..59ad3ad9b --- /dev/null +++ b/packages/client/src/pages/settings/theme.install.vue @@ -0,0 +1,105 @@ + + + diff --git a/packages/client/src/pages/settings/theme.manage.vue b/packages/client/src/pages/settings/theme.manage.vue new file mode 100644 index 000000000..8a24481ae --- /dev/null +++ b/packages/client/src/pages/settings/theme.manage.vue @@ -0,0 +1,105 @@ + + + diff --git a/packages/client/src/pages/settings/theme.vue b/packages/client/src/pages/settings/theme.vue new file mode 100644 index 000000000..a9cca40f3 --- /dev/null +++ b/packages/client/src/pages/settings/theme.vue @@ -0,0 +1,424 @@ + + + + + diff --git a/packages/client/src/pages/settings/update.vue b/packages/client/src/pages/settings/update.vue new file mode 100644 index 000000000..aa4050fe9 --- /dev/null +++ b/packages/client/src/pages/settings/update.vue @@ -0,0 +1,95 @@ + + + diff --git a/packages/client/src/pages/settings/word-mute.vue b/packages/client/src/pages/settings/word-mute.vue new file mode 100644 index 000000000..c2162bb1f --- /dev/null +++ b/packages/client/src/pages/settings/word-mute.vue @@ -0,0 +1,110 @@ + + + diff --git a/packages/client/src/pages/share.vue b/packages/client/src/pages/share.vue new file mode 100644 index 000000000..c0af44fdd --- /dev/null +++ b/packages/client/src/pages/share.vue @@ -0,0 +1,184 @@ + + + + + diff --git a/packages/client/src/pages/signup-complete.vue b/packages/client/src/pages/signup-complete.vue new file mode 100644 index 000000000..3bbc9938d --- /dev/null +++ b/packages/client/src/pages/signup-complete.vue @@ -0,0 +1,50 @@ + + + + + diff --git a/packages/client/src/pages/tag.vue b/packages/client/src/pages/tag.vue new file mode 100644 index 000000000..f4709659e --- /dev/null +++ b/packages/client/src/pages/tag.vue @@ -0,0 +1,57 @@ + + + diff --git a/packages/client/src/pages/test.vue b/packages/client/src/pages/test.vue new file mode 100644 index 000000000..9dd9ae5e0 --- /dev/null +++ b/packages/client/src/pages/test.vue @@ -0,0 +1,259 @@ + + + diff --git a/packages/client/src/pages/theme-editor.vue b/packages/client/src/pages/theme-editor.vue new file mode 100644 index 000000000..d1a892629 --- /dev/null +++ b/packages/client/src/pages/theme-editor.vue @@ -0,0 +1,306 @@ + + + + + diff --git a/packages/client/src/pages/timeline.tutorial.vue b/packages/client/src/pages/timeline.tutorial.vue new file mode 100644 index 000000000..4d6dd0af4 --- /dev/null +++ b/packages/client/src/pages/timeline.tutorial.vue @@ -0,0 +1,131 @@ + + + + + diff --git a/packages/client/src/pages/timeline.vue b/packages/client/src/pages/timeline.vue new file mode 100644 index 000000000..911d6f5c6 --- /dev/null +++ b/packages/client/src/pages/timeline.vue @@ -0,0 +1,225 @@ + + + + + diff --git a/packages/client/src/pages/user-ap-info.vue b/packages/client/src/pages/user-ap-info.vue new file mode 100644 index 000000000..6253faa24 --- /dev/null +++ b/packages/client/src/pages/user-ap-info.vue @@ -0,0 +1,124 @@ + + + diff --git a/packages/client/src/pages/user-info.vue b/packages/client/src/pages/user-info.vue new file mode 100644 index 000000000..b77d879a7 --- /dev/null +++ b/packages/client/src/pages/user-info.vue @@ -0,0 +1,245 @@ + + + + + diff --git a/packages/client/src/pages/user-list-timeline.vue b/packages/client/src/pages/user-list-timeline.vue new file mode 100644 index 000000000..2fc2476fb --- /dev/null +++ b/packages/client/src/pages/user-list-timeline.vue @@ -0,0 +1,147 @@ + + + + + diff --git a/packages/client/src/pages/user/clips.vue b/packages/client/src/pages/user/clips.vue new file mode 100644 index 000000000..2ec96d228 --- /dev/null +++ b/packages/client/src/pages/user/clips.vue @@ -0,0 +1,50 @@ + + + + + diff --git a/packages/client/src/pages/user/follow-list.vue b/packages/client/src/pages/user/follow-list.vue new file mode 100644 index 000000000..fec443141 --- /dev/null +++ b/packages/client/src/pages/user/follow-list.vue @@ -0,0 +1,65 @@ + + + + + diff --git a/packages/client/src/pages/user/gallery.vue b/packages/client/src/pages/user/gallery.vue new file mode 100644 index 000000000..fb99cdff1 --- /dev/null +++ b/packages/client/src/pages/user/gallery.vue @@ -0,0 +1,56 @@ + + + + + diff --git a/packages/client/src/pages/user/index.activity.vue b/packages/client/src/pages/user/index.activity.vue new file mode 100644 index 000000000..e51d6c609 --- /dev/null +++ b/packages/client/src/pages/user/index.activity.vue @@ -0,0 +1,34 @@ + + + diff --git a/packages/client/src/pages/user/index.photos.vue b/packages/client/src/pages/user/index.photos.vue new file mode 100644 index 000000000..4c52dceae --- /dev/null +++ b/packages/client/src/pages/user/index.photos.vue @@ -0,0 +1,107 @@ + + + + + diff --git a/packages/client/src/pages/user/index.timeline.vue b/packages/client/src/pages/user/index.timeline.vue new file mode 100644 index 000000000..eff38ec3c --- /dev/null +++ b/packages/client/src/pages/user/index.timeline.vue @@ -0,0 +1,68 @@ + + + + + diff --git a/packages/client/src/pages/user/index.vue b/packages/client/src/pages/user/index.vue new file mode 100644 index 000000000..d2531c0d1 --- /dev/null +++ b/packages/client/src/pages/user/index.vue @@ -0,0 +1,829 @@ + + + + + diff --git a/packages/client/src/pages/user/pages.vue b/packages/client/src/pages/user/pages.vue new file mode 100644 index 000000000..0bf925d7d --- /dev/null +++ b/packages/client/src/pages/user/pages.vue @@ -0,0 +1,49 @@ + + + + + diff --git a/packages/client/src/pages/user/reactions.vue b/packages/client/src/pages/user/reactions.vue new file mode 100644 index 000000000..3ca3b2aac --- /dev/null +++ b/packages/client/src/pages/user/reactions.vue @@ -0,0 +1,81 @@ + + + + + diff --git a/packages/client/src/pages/v.vue b/packages/client/src/pages/v.vue new file mode 100644 index 000000000..3b1bb2086 --- /dev/null +++ b/packages/client/src/pages/v.vue @@ -0,0 +1,29 @@ + + + diff --git a/packages/client/src/pages/welcome.entrance.a.vue b/packages/client/src/pages/welcome.entrance.a.vue new file mode 100644 index 000000000..2e0c520bc --- /dev/null +++ b/packages/client/src/pages/welcome.entrance.a.vue @@ -0,0 +1,320 @@ + + + + + diff --git a/packages/client/src/pages/welcome.entrance.b.vue b/packages/client/src/pages/welcome.entrance.b.vue new file mode 100644 index 000000000..efb8b0936 --- /dev/null +++ b/packages/client/src/pages/welcome.entrance.b.vue @@ -0,0 +1,236 @@ + + + + + diff --git a/packages/client/src/pages/welcome.entrance.c.vue b/packages/client/src/pages/welcome.entrance.c.vue new file mode 100644 index 000000000..2b0ff7a31 --- /dev/null +++ b/packages/client/src/pages/welcome.entrance.c.vue @@ -0,0 +1,305 @@ + + + + + diff --git a/packages/client/src/pages/welcome.setup.vue b/packages/client/src/pages/welcome.setup.vue new file mode 100644 index 000000000..8c88720cf --- /dev/null +++ b/packages/client/src/pages/welcome.setup.vue @@ -0,0 +1,102 @@ + + + + + diff --git a/packages/client/src/pages/welcome.timeline.vue b/packages/client/src/pages/welcome.timeline.vue new file mode 100644 index 000000000..46e3dbb5e --- /dev/null +++ b/packages/client/src/pages/welcome.timeline.vue @@ -0,0 +1,99 @@ + + + + + diff --git a/packages/client/src/pages/welcome.vue b/packages/client/src/pages/welcome.vue new file mode 100644 index 000000000..4c038b511 --- /dev/null +++ b/packages/client/src/pages/welcome.vue @@ -0,0 +1,38 @@ + + + diff --git a/src/client/pizzax.ts b/packages/client/src/pizzax.ts similarity index 100% rename from src/client/pizzax.ts rename to packages/client/src/pizzax.ts diff --git a/packages/client/src/plugin.ts b/packages/client/src/plugin.ts new file mode 100644 index 000000000..c56ee1eb2 --- /dev/null +++ b/packages/client/src/plugin.ts @@ -0,0 +1,124 @@ +import { AiScript, utils, values } from '@syuilo/aiscript'; +import { deserialize } from '@syuilo/aiscript/built/serializer'; +import { jsToVal } from '@syuilo/aiscript/built/interpreter/util'; +import { createAiScriptEnv } from '@/scripts/aiscript/api'; +import { dialog } from '@/os'; +import { noteActions, notePostInterruptors, noteViewInterruptors, postFormActions, userActions } from '@/store'; + +const pluginContexts = new Map(); + +export function install(plugin) { + console.info('Plugin installed:', plugin.name, 'v' + plugin.version); + + const aiscript = new AiScript(createPluginEnv({ + plugin: plugin, + storageKey: 'plugins:' + plugin.id + }), { + in: (q) => { + return new Promise(ok => { + dialog({ + title: q, + input: {} + }).then(({ canceled, result: a }) => { + ok(a); + }); + }); + }, + out: (value) => { + console.log(value); + }, + log: (type, params) => { + }, + }); + + initPlugin({ plugin, aiscript }); + + aiscript.exec(deserialize(plugin.ast)); +} + +function createPluginEnv(opts) { + const config = new Map(); + for (const [k, v] of Object.entries(opts.plugin.config || {})) { + config.set(k, jsToVal(opts.plugin.configData.hasOwnProperty(k) ? opts.plugin.configData[k] : v.default)); + } + + return { + ...createAiScriptEnv({ ...opts, token: opts.plugin.token }), + //#region Deprecated + 'Mk:register_post_form_action': values.FN_NATIVE(([title, handler]) => { + registerPostFormAction({ pluginId: opts.plugin.id, title: title.value, handler }); + }), + 'Mk:register_user_action': values.FN_NATIVE(([title, handler]) => { + registerUserAction({ pluginId: opts.plugin.id, title: title.value, handler }); + }), + 'Mk:register_note_action': values.FN_NATIVE(([title, handler]) => { + registerNoteAction({ pluginId: opts.plugin.id, title: title.value, handler }); + }), + //#endregion + 'Plugin:register_post_form_action': values.FN_NATIVE(([title, handler]) => { + registerPostFormAction({ pluginId: opts.plugin.id, title: title.value, handler }); + }), + 'Plugin:register_user_action': values.FN_NATIVE(([title, handler]) => { + registerUserAction({ pluginId: opts.plugin.id, title: title.value, handler }); + }), + 'Plugin:register_note_action': values.FN_NATIVE(([title, handler]) => { + registerNoteAction({ pluginId: opts.plugin.id, title: title.value, handler }); + }), + 'Plugin:register_note_view_interruptor': values.FN_NATIVE(([handler]) => { + registerNoteViewInterruptor({ pluginId: opts.plugin.id, handler }); + }), + 'Plugin:register_note_post_interruptor': values.FN_NATIVE(([handler]) => { + registerNotePostInterruptor({ pluginId: opts.plugin.id, handler }); + }), + 'Plugin:open_url': values.FN_NATIVE(([url]) => { + window.open(url.value, '_blank'); + }), + 'Plugin:config': values.OBJ(config), + }; +} + +function initPlugin({ plugin, aiscript }) { + pluginContexts.set(plugin.id, aiscript); +} + +function registerPostFormAction({ pluginId, title, handler }) { + postFormActions.push({ + title, handler: (form, update) => { + pluginContexts.get(pluginId).execFn(handler, [utils.jsToVal(form), values.FN_NATIVE(([key, value]) => { + update(key.value, value.value); + })]); + } + }); +} + +function registerUserAction({ pluginId, title, handler }) { + userActions.push({ + title, handler: (user) => { + pluginContexts.get(pluginId).execFn(handler, [utils.jsToVal(user)]); + } + }); +} + +function registerNoteAction({ pluginId, title, handler }) { + noteActions.push({ + title, handler: (note) => { + pluginContexts.get(pluginId).execFn(handler, [utils.jsToVal(note)]); + } + }); +} + +function registerNoteViewInterruptor({ pluginId, handler }) { + noteViewInterruptors.push({ + handler: async (note) => { + return utils.valToJs(await pluginContexts.get(pluginId).execFn(handler, [utils.jsToVal(note)])); + } + }); +} + +function registerNotePostInterruptor({ pluginId, handler }) { + notePostInterruptors.push({ + handler: async (note) => { + return utils.valToJs(await pluginContexts.get(pluginId).execFn(handler, [utils.jsToVal(note)])); + } + }); +} diff --git a/packages/client/src/router.ts b/packages/client/src/router.ts new file mode 100644 index 000000000..9b4dd162f --- /dev/null +++ b/packages/client/src/router.ts @@ -0,0 +1,149 @@ +import { defineAsyncComponent, markRaw } from 'vue'; +import { createRouter, createWebHistory } from 'vue-router'; +import MkLoading from '@/pages/_loading_.vue'; +import MkError from '@/pages/_error_.vue'; +import MkTimeline from '@/pages/timeline.vue'; +import { $i } from './account'; +import { ui } from '@/config'; + +const page = (path: string, ui?: string) => defineAsyncComponent({ + loader: ui ? () => import(`./ui/${ui}/pages/${path}.vue`) : () => import(`./pages/${path}.vue`), + loadingComponent: MkLoading, + errorComponent: MkError, +}); + +let indexScrollPos = 0; + +const defaultRoutes = [ + // NOTE: MkTimelineをdynamic importするとAsyncComponentWrapperが間に入るせいでkeep-aliveのコンポーネント指定が効かなくなる + { path: '/', name: 'index', component: $i ? MkTimeline : page('welcome') }, + { path: '/@:acct/:page?', name: 'user', component: page('user/index'), props: route => ({ acct: route.params.acct, page: route.params.page || 'index' }) }, + { path: '/@:user/pages/:page', component: page('page'), props: route => ({ pageName: route.params.page, username: route.params.user }) }, + { path: '/@:user/pages/:pageName/view-source', component: page('page-editor/page-editor'), props: route => ({ initUser: route.params.user, initPageName: route.params.pageName }) }, + { path: '/@:acct/room', props: true, component: page('room/room') }, + { path: '/settings/:page(.*)?', name: 'settings', component: page('settings/index'), props: route => ({ initialPage: route.params.page || null }) }, + { path: '/reset-password/:token?', component: page('reset-password'), props: route => ({ token: route.params.token }) }, + { path: '/signup-complete/:code', component: page('signup-complete'), props: route => ({ code: route.params.code }) }, + { path: '/announcements', component: page('announcements') }, + { path: '/about', component: page('about') }, + { path: '/about-misskey', component: page('about-misskey') }, + { path: '/featured', component: page('featured') }, + { path: '/theme-editor', component: page('theme-editor') }, + { path: '/advanced-theme-editor', component: page('advanced-theme-editor') }, + { path: '/explore', component: page('explore') }, + { path: '/explore/tags/:tag', props: true, component: page('explore') }, + { path: '/federation', component: page('federation') }, + { path: '/emojis', component: page('emojis') }, + { path: '/search', component: page('search') }, + { path: '/pages', name: 'pages', component: page('pages') }, + { path: '/pages/new', component: page('page-editor/page-editor') }, + { path: '/pages/edit/:pageId', component: page('page-editor/page-editor'), props: route => ({ initPageId: route.params.pageId }) }, + { path: '/gallery', component: page('gallery/index') }, + { path: '/gallery/new', component: page('gallery/edit') }, + { path: '/gallery/:postId/edit', component: page('gallery/edit'), props: route => ({ postId: route.params.postId }) }, + { path: '/gallery/:postId', component: page('gallery/post'), props: route => ({ postId: route.params.postId }) }, + { path: '/channels', component: page('channels') }, + { path: '/channels/new', component: page('channel-editor') }, + { path: '/channels/:channelId/edit', component: page('channel-editor'), props: true }, + { path: '/channels/:channelId', component: page('channel'), props: route => ({ channelId: route.params.channelId }) }, + { path: '/clips/:clipId', component: page('clip'), props: route => ({ clipId: route.params.clipId }) }, + { path: '/timeline/list/:listId', component: page('user-list-timeline'), props: route => ({ listId: route.params.listId }) }, + { path: '/timeline/antenna/:antennaId', component: page('antenna-timeline'), props: route => ({ antennaId: route.params.antennaId }) }, + { path: '/my/notifications', component: page('notifications') }, + { path: '/my/favorites', component: page('favorites') }, + { path: '/my/messages', component: page('messages') }, + { path: '/my/mentions', component: page('mentions') }, + { path: '/my/messaging', name: 'messaging', component: page('messaging/index') }, + { path: '/my/messaging/:user', component: page('messaging/messaging-room'), props: route => ({ userAcct: route.params.user }) }, + { path: '/my/messaging/group/:group', component: page('messaging/messaging-room'), props: route => ({ groupId: route.params.group }) }, + { path: '/my/drive', name: 'drive', component: page('drive') }, + { path: '/my/drive/folder/:folder', component: page('drive') }, + { path: '/my/follow-requests', component: page('follow-requests') }, + { path: '/my/lists', component: page('my-lists/index') }, + { path: '/my/lists/:list', component: page('my-lists/list') }, + { path: '/my/groups', component: page('my-groups/index') }, + { path: '/my/groups/:group', component: page('my-groups/group'), props: route => ({ groupId: route.params.group }) }, + { path: '/my/antennas', component: page('my-antennas/index') }, + { path: '/my/antennas/create', component: page('my-antennas/create') }, + { path: '/my/antennas/:antennaId', component: page('my-antennas/edit'), props: true }, + { path: '/my/clips', component: page('my-clips/index') }, + { path: '/scratchpad', component: page('scratchpad') }, + { path: '/admin/:page(.*)?', component: page('admin/index'), props: route => ({ initialPage: route.params.page || null }) }, + { path: '/admin', component: page('admin/index') }, + { path: '/notes/:note', name: 'note', component: page('note'), props: route => ({ noteId: route.params.note }) }, + { path: '/tags/:tag', component: page('tag'), props: route => ({ tag: route.params.tag }) }, + { path: '/user-info/:user', component: page('user-info'), props: route => ({ userId: route.params.user }) }, + { path: '/user-ap-info/:user', component: page('user-ap-info'), props: route => ({ userId: route.params.user }) }, + { path: '/instance-info/:host', component: page('instance-info'), props: route => ({ host: route.params.host }) }, + { path: '/games/reversi', component: page('reversi/index') }, + { path: '/games/reversi/:gameId', component: page('reversi/game'), props: route => ({ gameId: route.params.gameId }) }, + { path: '/mfm-cheat-sheet', component: page('mfm-cheat-sheet') }, + { path: '/api-console', component: page('api-console') }, + { path: '/preview', component: page('preview') }, + { path: '/test', component: page('test') }, + { path: '/auth/:token', component: page('auth') }, + { path: '/miauth/:session', component: page('miauth') }, + { path: '/authorize-follow', component: page('follow') }, + { path: '/share', component: page('share') }, + { path: '/:catchAll(.*)', component: page('not-found') } +]; + +const chatRoutes = [ + { path: '/timeline', component: page('timeline', 'chat'), props: route => ({ src: 'home' }) }, + { path: '/timeline/home', component: page('timeline', 'chat'), props: route => ({ src: 'home' }) }, + { path: '/timeline/local', component: page('timeline', 'chat'), props: route => ({ src: 'local' }) }, + { path: '/timeline/social', component: page('timeline', 'chat'), props: route => ({ src: 'social' }) }, + { path: '/timeline/global', component: page('timeline', 'chat'), props: route => ({ src: 'global' }) }, + { path: '/channels/:channelId', component: page('channel', 'chat'), props: route => ({ channelId: route.params.channelId }) }, +]; + +function margeRoutes(routes: any[]) { + const result = defaultRoutes; + for (const route of routes) { + const found = result.findIndex(x => x.path === route.path); + if (found > -1) { + result[found] = route; + } else { + result.unshift(route); + } + } + return result; +} + +export const router = createRouter({ + history: createWebHistory(), + routes: margeRoutes(ui === 'chat' ? chatRoutes : []), + // なんかHacky + // 通常の使い方をすると scroll メソッドの behavior を設定できないため、自前で window.scroll するようにする + scrollBehavior(to) { + window._scroll = () => { // さらにHacky + if (to.name === 'index') { + window.scroll({ top: indexScrollPos, behavior: 'instant' }); + const i = setInterval(() => { + window.scroll({ top: indexScrollPos, behavior: 'instant' }); + }, 10); + setTimeout(() => { + clearInterval(i); + }, 500); + } else { + window.scroll({ top: 0, behavior: 'instant' }); + } + }; + } +}); + +router.afterEach((to, from) => { + if (from.name === 'index') { + indexScrollPos = window.scrollY; + } +}); + +export function resolve(path: string) { + const resolved = router.resolve(path); + const route = resolved.matched[0]; + return { + component: markRaw(route.components.default), + // TODO: route.propsには関数以外も入る可能性があるのでよしなにハンドリングする + props: route.props?.default ? route.props.default(resolved) : resolved.params + }; +} diff --git a/src/client/scripts/2fa.ts b/packages/client/src/scripts/2fa.ts similarity index 100% rename from src/client/scripts/2fa.ts rename to packages/client/src/scripts/2fa.ts diff --git a/packages/client/src/scripts/aiscript/api.ts b/packages/client/src/scripts/aiscript/api.ts new file mode 100644 index 000000000..20c15d809 --- /dev/null +++ b/packages/client/src/scripts/aiscript/api.ts @@ -0,0 +1,44 @@ +import { utils, values } from '@syuilo/aiscript'; +import * as os from '@/os'; +import { $i } from '@/account'; + +export function createAiScriptEnv(opts) { + let apiRequests = 0; + return { + USER_ID: $i ? values.STR($i.id) : values.NULL, + USER_NAME: $i ? values.STR($i.name) : values.NULL, + USER_USERNAME: $i ? values.STR($i.username) : values.NULL, + 'Mk:dialog': values.FN_NATIVE(async ([title, text, type]) => { + await os.dialog({ + type: type ? type.value : 'info', + title: title.value, + text: text.value, + }); + }), + 'Mk:confirm': values.FN_NATIVE(async ([title, text, type]) => { + const confirm = await os.dialog({ + type: type ? type.value : 'question', + showCancelButton: true, + title: title.value, + text: text.value, + }); + return confirm.canceled ? values.FALSE : values.TRUE; + }), + 'Mk:api': values.FN_NATIVE(async ([ep, param, token]) => { + if (token) utils.assertString(token); + apiRequests++; + if (apiRequests > 16) return values.NULL; + const res = await os.api(ep.value, utils.valToJs(param), token ? token.value : (opts.token || null)); + return utils.jsToVal(res); + }), + 'Mk:save': values.FN_NATIVE(([key, value]) => { + utils.assertString(key); + localStorage.setItem('aiscript:' + opts.storageKey + ':' + key.value, JSON.stringify(utils.valToJs(value))); + return values.NULL; + }), + 'Mk:load': values.FN_NATIVE(([key]) => { + utils.assertString(key); + return utils.jsToVal(JSON.parse(localStorage.getItem('aiscript:' + opts.storageKey + ':' + key.value))); + }), + }; +} diff --git a/src/prelude/array.ts b/packages/client/src/scripts/array.ts similarity index 100% rename from src/prelude/array.ts rename to packages/client/src/scripts/array.ts diff --git a/packages/client/src/scripts/autocomplete.ts b/packages/client/src/scripts/autocomplete.ts new file mode 100644 index 000000000..f2d580648 --- /dev/null +++ b/packages/client/src/scripts/autocomplete.ts @@ -0,0 +1,276 @@ +import { Ref, ref } from 'vue'; +import * as getCaretCoordinates from 'textarea-caret'; +import { toASCII } from 'punycode/'; +import { popup } from '@/os'; + +export class Autocomplete { + private suggestion: { + x: Ref; + y: Ref; + q: Ref; + close: Function; + } | null; + private textarea: any; + private vm: any; + private currentType: string; + private opts: { + model: string; + }; + private opening: boolean; + + private get text(): string { + return this.vm[this.opts.model]; + } + + private set text(text: string) { + this.vm[this.opts.model] = text; + } + + /** + * 対象のテキストエリアを与えてインスタンスを初期化します。 + */ + constructor(textarea, vm, opts) { + //#region BIND + this.onInput = this.onInput.bind(this); + this.complete = this.complete.bind(this); + this.close = this.close.bind(this); + //#endregion + + this.suggestion = null; + this.textarea = textarea; + this.vm = vm; + this.opts = opts; + this.opening = false; + + this.attach(); + } + + /** + * このインスタンスにあるテキストエリアの入力のキャプチャを開始します。 + */ + public attach() { + this.textarea.addEventListener('input', this.onInput); + } + + /** + * このインスタンスにあるテキストエリアの入力のキャプチャを解除します。 + */ + public detach() { + this.textarea.removeEventListener('input', this.onInput); + this.close(); + } + + /** + * テキスト入力時 + */ + private onInput() { + const caretPos = this.textarea.selectionStart; + const text = this.text.substr(0, caretPos).split('\n').pop()!; + + const mentionIndex = text.lastIndexOf('@'); + const hashtagIndex = text.lastIndexOf('#'); + const emojiIndex = text.lastIndexOf(':'); + const mfmTagIndex = text.lastIndexOf('$'); + + const max = Math.max( + mentionIndex, + hashtagIndex, + emojiIndex, + mfmTagIndex); + + if (max == -1) { + this.close(); + return; + } + + const isMention = mentionIndex != -1; + const isHashtag = hashtagIndex != -1; + const isMfmTag = mfmTagIndex != -1; + const isEmoji = emojiIndex != -1 && text.split(/:[a-z0-9_+\-]+:/).pop()!.includes(':'); + + let opened = false; + + if (isMention) { + const username = text.substr(mentionIndex + 1); + if (username != '' && username.match(/^[a-zA-Z0-9_]+$/)) { + this.open('user', username); + opened = true; + } else if (username === '') { + this.open('user', null); + opened = true; + } + } + + if (isHashtag && !opened) { + const hashtag = text.substr(hashtagIndex + 1); + if (!hashtag.includes(' ')) { + this.open('hashtag', hashtag); + opened = true; + } + } + + if (isEmoji && !opened) { + const emoji = text.substr(emojiIndex + 1); + if (!emoji.includes(' ')) { + this.open('emoji', emoji); + opened = true; + } + } + + if (isMfmTag && !opened) { + const mfmTag = text.substr(mfmTagIndex + 1); + if (!mfmTag.includes(' ')) { + this.open('mfmTag', mfmTag.replace('[', '')); + opened = true; + } + } + + if (!opened) { + this.close(); + } + } + + /** + * サジェストを提示します。 + */ + private async open(type: string, q: string | null) { + if (type != this.currentType) { + this.close(); + } + if (this.opening) return; + this.opening = true; + this.currentType = type; + + //#region サジェストを表示すべき位置を計算 + const caretPosition = getCaretCoordinates(this.textarea, this.textarea.selectionStart); + + const rect = this.textarea.getBoundingClientRect(); + + const x = rect.left + caretPosition.left - this.textarea.scrollLeft; + const y = rect.top + caretPosition.top - this.textarea.scrollTop; + //#endregion + + if (this.suggestion) { + this.suggestion.x.value = x; + this.suggestion.y.value = y; + this.suggestion.q.value = q; + + this.opening = false; + } else { + const _x = ref(x); + const _y = ref(y); + const _q = ref(q); + + const { dispose } = await popup(import('@/components/autocomplete.vue'), { + textarea: this.textarea, + close: this.close, + type: type, + q: _q, + x: _x, + y: _y, + }, { + done: (res) => { + this.complete(res); + } + }); + + this.suggestion = { + q: _q, + x: _x, + y: _y, + close: () => dispose(), + }; + + this.opening = false; + } + } + + /** + * サジェストを閉じます。 + */ + private close() { + if (this.suggestion == null) return; + + this.suggestion.close(); + this.suggestion = null; + + this.textarea.focus(); + } + + /** + * オートコンプリートする + */ + private complete({ type, value }) { + this.close(); + + const caret = this.textarea.selectionStart; + + if (type == 'user') { + const source = this.text; + + const before = source.substr(0, caret); + const trimmedBefore = before.substring(0, before.lastIndexOf('@')); + const after = source.substr(caret); + + const acct = value.host === null ? value.username : `${value.username}@${toASCII(value.host)}`; + + // 挿入 + this.text = `${trimmedBefore}@${acct} ${after}`; + + // キャレットを戻す + this.vm.$nextTick(() => { + this.textarea.focus(); + const pos = trimmedBefore.length + (acct.length + 2); + this.textarea.setSelectionRange(pos, pos); + }); + } else if (type == 'hashtag') { + const source = this.text; + + const before = source.substr(0, caret); + const trimmedBefore = before.substring(0, before.lastIndexOf('#')); + const after = source.substr(caret); + + // 挿入 + this.text = `${trimmedBefore}#${value} ${after}`; + + // キャレットを戻す + this.vm.$nextTick(() => { + this.textarea.focus(); + const pos = trimmedBefore.length + (value.length + 2); + this.textarea.setSelectionRange(pos, pos); + }); + } else if (type == 'emoji') { + const source = this.text; + + const before = source.substr(0, caret); + const trimmedBefore = before.substring(0, before.lastIndexOf(':')); + const after = source.substr(caret); + + // 挿入 + this.text = trimmedBefore + value + after; + + // キャレットを戻す + this.vm.$nextTick(() => { + this.textarea.focus(); + const pos = trimmedBefore.length + value.length; + this.textarea.setSelectionRange(pos, pos); + }); + } else if (type == 'mfmTag') { + const source = this.text; + + const before = source.substr(0, caret); + const trimmedBefore = before.substring(0, before.lastIndexOf('$')); + const after = source.substr(caret); + + // 挿入 + this.text = `${trimmedBefore}$[${value} ]${after}`; + + // キャレットを戻す + this.vm.$nextTick(() => { + this.textarea.focus(); + const pos = trimmedBefore.length + (value.length + 3); + this.textarea.setSelectionRange(pos, pos); + }); + } + } +} diff --git a/src/client/scripts/check-word-mute.ts b/packages/client/src/scripts/check-word-mute.ts similarity index 100% rename from src/client/scripts/check-word-mute.ts rename to packages/client/src/scripts/check-word-mute.ts diff --git a/src/client/scripts/collect-page-vars.ts b/packages/client/src/scripts/collect-page-vars.ts similarity index 100% rename from src/client/scripts/collect-page-vars.ts rename to packages/client/src/scripts/collect-page-vars.ts diff --git a/src/client/scripts/contains.ts b/packages/client/src/scripts/contains.ts similarity index 100% rename from src/client/scripts/contains.ts rename to packages/client/src/scripts/contains.ts diff --git a/src/client/scripts/copy-to-clipboard.ts b/packages/client/src/scripts/copy-to-clipboard.ts similarity index 100% rename from src/client/scripts/copy-to-clipboard.ts rename to packages/client/src/scripts/copy-to-clipboard.ts diff --git a/src/misc/emojilist.ts b/packages/client/src/scripts/emojilist.ts similarity index 100% rename from src/misc/emojilist.ts rename to packages/client/src/scripts/emojilist.ts diff --git a/src/client/scripts/extract-avg-color-from-blurhash.ts b/packages/client/src/scripts/extract-avg-color-from-blurhash.ts similarity index 100% rename from src/client/scripts/extract-avg-color-from-blurhash.ts rename to packages/client/src/scripts/extract-avg-color-from-blurhash.ts diff --git a/packages/client/src/scripts/extract-mentions.ts b/packages/client/src/scripts/extract-mentions.ts new file mode 100644 index 000000000..cc19b161a --- /dev/null +++ b/packages/client/src/scripts/extract-mentions.ts @@ -0,0 +1,11 @@ +// test is located in test/extract-mentions + +import * as mfm from 'mfm-js'; + +export function extractMentions(nodes: mfm.MfmNode[]): mfm.MfmMention['props'][] { + // TODO: 重複を削除 + const mentionNodes = mfm.extract(nodes, (node) => node.type === 'mention'); + const mentions = mentionNodes.map(x => x.props); + + return mentions; +} diff --git a/packages/client/src/scripts/extract-url-from-mfm.ts b/packages/client/src/scripts/extract-url-from-mfm.ts new file mode 100644 index 000000000..34e3eb6c1 --- /dev/null +++ b/packages/client/src/scripts/extract-url-from-mfm.ts @@ -0,0 +1,19 @@ +import * as mfm from 'mfm-js'; +import { unique } from '@/scripts/array'; + +// unique without hash +// [ http://a/#1, http://a/#2, http://b/#3 ] => [ http://a/#1, http://b/#3 ] +const removeHash = (x: string) => x.replace(/#[^#]*$/, ''); + +export function extractUrlFromMfm(nodes: mfm.MfmNode[], respectSilentFlag = true): string[] { + const urlNodes = mfm.extract(nodes, (node) => { + return (node.type === 'url') || (node.type === 'link' && (!respectSilentFlag || !node.props.silent)); + }); + const urls: string[] = unique(urlNodes.map(x => x.props.url)); + + return urls.reduce((array, url) => { + const urlWithoutHash = removeHash(url); + if (!array.map(x => removeHash(x)).includes(urlWithoutHash)) array.push(url); + return array; + }, [] as string[]); +} diff --git a/src/client/scripts/focus.ts b/packages/client/src/scripts/focus.ts similarity index 100% rename from src/client/scripts/focus.ts rename to packages/client/src/scripts/focus.ts diff --git a/src/client/scripts/form.ts b/packages/client/src/scripts/form.ts similarity index 100% rename from src/client/scripts/form.ts rename to packages/client/src/scripts/form.ts diff --git a/src/misc/format-time-string.ts b/packages/client/src/scripts/format-time-string.ts similarity index 100% rename from src/misc/format-time-string.ts rename to packages/client/src/scripts/format-time-string.ts diff --git a/packages/client/src/scripts/games/reversi/core.ts b/packages/client/src/scripts/games/reversi/core.ts new file mode 100644 index 000000000..0cb8922e1 --- /dev/null +++ b/packages/client/src/scripts/games/reversi/core.ts @@ -0,0 +1,263 @@ +import { count, concat } from '@/scripts/array'; + +// MISSKEY REVERSI ENGINE + +/** + * true ... 黒 + * false ... 白 + */ +export type Color = boolean; +const BLACK = true; +const WHITE = false; + +export type MapPixel = 'null' | 'empty'; + +export type Options = { + isLlotheo: boolean; + canPutEverywhere: boolean; + loopedBoard: boolean; +}; + +export type Undo = { + /** + * 色 + */ + color: Color; + + /** + * どこに打ったか + */ + pos: number; + + /** + * 反転した石の位置の配列 + */ + effects: number[]; + + /** + * ターン + */ + turn: Color | null; +}; + +/** + * リバーシエンジン + */ +export default class Reversi { + public map: MapPixel[]; + public mapWidth: number; + public mapHeight: number; + public board: (Color | null | undefined)[]; + public turn: Color | null = BLACK; + public opts: Options; + + public prevPos = -1; + public prevColor: Color | null = null; + + private logs: Undo[] = []; + + /** + * ゲームを初期化します + */ + constructor(map: string[], opts: Options) { + //#region binds + this.put = this.put.bind(this); + //#endregion + + //#region Options + this.opts = opts; + if (this.opts.isLlotheo == null) this.opts.isLlotheo = false; + if (this.opts.canPutEverywhere == null) this.opts.canPutEverywhere = false; + if (this.opts.loopedBoard == null) this.opts.loopedBoard = false; + //#endregion + + //#region Parse map data + this.mapWidth = map[0].length; + this.mapHeight = map.length; + const mapData = map.join(''); + + this.board = mapData.split('').map(d => d === '-' ? null : d === 'b' ? BLACK : d === 'w' ? WHITE : undefined); + + this.map = mapData.split('').map(d => d === '-' || d === 'b' || d === 'w' ? 'empty' : 'null'); + //#endregion + + // ゲームが始まった時点で片方の色の石しかないか、始まった時点で勝敗が決定するようなマップの場合がある + if (!this.canPutSomewhere(BLACK)) + this.turn = this.canPutSomewhere(WHITE) ? WHITE : null; + } + + /** + * 黒石の数 + */ + public get blackCount() { + return count(BLACK, this.board); + } + + /** + * 白石の数 + */ + public get whiteCount() { + return count(WHITE, this.board); + } + + public transformPosToXy(pos: number): number[] { + const x = pos % this.mapWidth; + const y = Math.floor(pos / this.mapWidth); + return [x, y]; + } + + public transformXyToPos(x: number, y: number): number { + return x + (y * this.mapWidth); + } + + /** + * 指定のマスに石を打ちます + * @param color 石の色 + * @param pos 位置 + */ + public put(color: Color, pos: number) { + this.prevPos = pos; + this.prevColor = color; + + this.board[pos] = color; + + // 反転させられる石を取得 + const effects = this.effects(color, pos); + + // 反転させる + for (const pos of effects) { + this.board[pos] = color; + } + + const turn = this.turn; + + this.logs.push({ + color, + pos, + effects, + turn + }); + + this.calcTurn(); + } + + private calcTurn() { + // ターン計算 + this.turn = + this.canPutSomewhere(!this.prevColor) ? !this.prevColor : + this.canPutSomewhere(this.prevColor!) ? this.prevColor : + null; + } + + public undo() { + const undo = this.logs.pop()!; + this.prevColor = undo.color; + this.prevPos = undo.pos; + this.board[undo.pos] = null; + for (const pos of undo.effects) { + const color = this.board[pos]; + this.board[pos] = !color; + } + this.turn = undo.turn; + } + + /** + * 指定した位置のマップデータのマスを取得します + * @param pos 位置 + */ + public mapDataGet(pos: number): MapPixel { + const [x, y] = this.transformPosToXy(pos); + return x < 0 || y < 0 || x >= this.mapWidth || y >= this.mapHeight ? 'null' : this.map[pos]; + } + + /** + * 打つことができる場所を取得します + */ + public puttablePlaces(color: Color): number[] { + return Array.from(this.board.keys()).filter(i => this.canPut(color, i)); + } + + /** + * 打つことができる場所があるかどうかを取得します + */ + public canPutSomewhere(color: Color): boolean { + return this.puttablePlaces(color).length > 0; + } + + /** + * 指定のマスに石を打つことができるかどうかを取得します + * @param color 自分の色 + * @param pos 位置 + */ + public canPut(color: Color, pos: number): boolean { + return ( + this.board[pos] !== null ? false : // 既に石が置いてある場所には打てない + this.opts.canPutEverywhere ? this.mapDataGet(pos) == 'empty' : // 挟んでなくても置けるモード + this.effects(color, pos).length !== 0); // 相手の石を1つでも反転させられるか + } + + /** + * 指定のマスに石を置いた時の、反転させられる石を取得します + * @param color 自分の色 + * @param initPos 位置 + */ + public effects(color: Color, initPos: number): number[] { + const enemyColor = !color; + + const diffVectors: [number, number][] = [ + [ 0, -1], // 上 + [ +1, -1], // 右上 + [ +1, 0], // 右 + [ +1, +1], // 右下 + [ 0, +1], // 下 + [ -1, +1], // 左下 + [ -1, 0], // 左 + [ -1, -1] // 左上 + ]; + + const effectsInLine = ([dx, dy]: [number, number]): number[] => { + const nextPos = (x: number, y: number): [number, number] => [x + dx, y + dy]; + + const found: number[] = []; // 挟めるかもしれない相手の石を入れておく配列 + let [x, y] = this.transformPosToXy(initPos); + while (true) { + [x, y] = nextPos(x, y); + + // 座標が指し示す位置がボード外に出たとき + if (this.opts.loopedBoard && this.transformXyToPos( + (x = ((x % this.mapWidth) + this.mapWidth) % this.mapWidth), + (y = ((y % this.mapHeight) + this.mapHeight) % this.mapHeight)) === initPos) + // 盤面の境界でループし、自分が石を置く位置に戻ってきたとき、挟めるようにしている (ref: Test4のマップ) + return found; + else if (x === -1 || y === -1 || x === this.mapWidth || y === this.mapHeight) + return []; // 挟めないことが確定 (盤面外に到達) + + const pos = this.transformXyToPos(x, y); + if (this.mapDataGet(pos) === 'null') return []; // 挟めないことが確定 (配置不可能なマスに到達) + const stone = this.board[pos]; + if (stone === null) return []; // 挟めないことが確定 (石が置かれていないマスに到達) + if (stone === enemyColor) found.push(pos); // 挟めるかもしれない (相手の石を発見) + if (stone === color) return found; // 挟めることが確定 (対となる自分の石を発見) + } + }; + + return concat(diffVectors.map(effectsInLine)); + } + + /** + * ゲームが終了したか否か + */ + public get isEnded(): boolean { + return this.turn === null; + } + + /** + * ゲームの勝者 (null = 引き分け) + */ + public get winner(): Color | null { + return this.isEnded ? + this.blackCount == this.whiteCount ? null : + this.opts.isLlotheo === this.blackCount > this.whiteCount ? WHITE : BLACK : + undefined as never; + } +} diff --git a/packages/client/src/scripts/games/reversi/maps.ts b/packages/client/src/scripts/games/reversi/maps.ts new file mode 100644 index 000000000..dc0d1bf9d --- /dev/null +++ b/packages/client/src/scripts/games/reversi/maps.ts @@ -0,0 +1,896 @@ +/** + * 組み込みマップ定義 + * + * データ値: + * (スペース) ... マス無し + * - ... マス + * b ... 初期配置される黒石 + * w ... 初期配置される白石 + */ + +export type Map = { + name?: string; + category?: string; + author?: string; + data: string[]; +}; + +export const fourfour: Map = { + name: '4x4', + category: '4x4', + data: [ + '----', + '-wb-', + '-bw-', + '----' + ] +}; + +export const sixsix: Map = { + name: '6x6', + category: '6x6', + data: [ + '------', + '------', + '--wb--', + '--bw--', + '------', + '------' + ] +}; + +export const roundedSixsix: Map = { + name: '6x6 rounded', + category: '6x6', + author: 'syuilo', + data: [ + ' ---- ', + '------', + '--wb--', + '--bw--', + '------', + ' ---- ' + ] +}; + +export const roundedSixsix2: Map = { + name: '6x6 rounded 2', + category: '6x6', + author: 'syuilo', + data: [ + ' -- ', + ' ---- ', + '--wb--', + '--bw--', + ' ---- ', + ' -- ' + ] +}; + +export const eighteight: Map = { + name: '8x8', + category: '8x8', + data: [ + '--------', + '--------', + '--------', + '---wb---', + '---bw---', + '--------', + '--------', + '--------' + ] +}; + +export const eighteightH1: Map = { + name: '8x8 handicap 1', + category: '8x8', + data: [ + 'b-------', + '--------', + '--------', + '---wb---', + '---bw---', + '--------', + '--------', + '--------' + ] +}; + +export const eighteightH2: Map = { + name: '8x8 handicap 2', + category: '8x8', + data: [ + 'b-------', + '--------', + '--------', + '---wb---', + '---bw---', + '--------', + '--------', + '-------b' + ] +}; + +export const eighteightH3: Map = { + name: '8x8 handicap 3', + category: '8x8', + data: [ + 'b------b', + '--------', + '--------', + '---wb---', + '---bw---', + '--------', + '--------', + '-------b' + ] +}; + +export const eighteightH4: Map = { + name: '8x8 handicap 4', + category: '8x8', + data: [ + 'b------b', + '--------', + '--------', + '---wb---', + '---bw---', + '--------', + '--------', + 'b------b' + ] +}; + +export const eighteightH28: Map = { + name: '8x8 handicap 28', + category: '8x8', + data: [ + 'bbbbbbbb', + 'b------b', + 'b------b', + 'b--wb--b', + 'b--bw--b', + 'b------b', + 'b------b', + 'bbbbbbbb' + ] +}; + +export const roundedEighteight: Map = { + name: '8x8 rounded', + category: '8x8', + author: 'syuilo', + data: [ + ' ------ ', + '--------', + '--------', + '---wb---', + '---bw---', + '--------', + '--------', + ' ------ ' + ] +}; + +export const roundedEighteight2: Map = { + name: '8x8 rounded 2', + category: '8x8', + author: 'syuilo', + data: [ + ' ---- ', + ' ------ ', + '--------', + '---wb---', + '---bw---', + '--------', + ' ------ ', + ' ---- ' + ] +}; + +export const roundedEighteight3: Map = { + name: '8x8 rounded 3', + category: '8x8', + author: 'syuilo', + data: [ + ' -- ', + ' ---- ', + ' ------ ', + '---wb---', + '---bw---', + ' ------ ', + ' ---- ', + ' -- ' + ] +}; + +export const eighteightWithNotch: Map = { + name: '8x8 with notch', + category: '8x8', + author: 'syuilo', + data: [ + '--- ---', + '--------', + '--------', + ' --wb-- ', + ' --bw-- ', + '--------', + '--------', + '--- ---' + ] +}; + +export const eighteightWithSomeHoles: Map = { + name: '8x8 with some holes', + category: '8x8', + author: 'syuilo', + data: [ + '--- ----', + '----- --', + '-- -----', + '---wb---', + '---bw- -', + ' -------', + '--- ----', + '--------' + ] +}; + +export const circle: Map = { + name: 'Circle', + category: '8x8', + author: 'syuilo', + data: [ + ' -- ', + ' ------ ', + ' ------ ', + '---wb---', + '---bw---', + ' ------ ', + ' ------ ', + ' -- ' + ] +}; + +export const smile: Map = { + name: 'Smile', + category: '8x8', + author: 'syuilo', + data: [ + ' ------ ', + '--------', + '-- -- --', + '---wb---', + '-- bw --', + '--- ---', + '--------', + ' ------ ' + ] +}; + +export const window: Map = { + name: 'Window', + category: '8x8', + author: 'syuilo', + data: [ + '--------', + '- -- -', + '- -- -', + '---wb---', + '---bw---', + '- -- -', + '- -- -', + '--------' + ] +}; + +export const reserved: Map = { + name: 'Reserved', + category: '8x8', + author: 'Aya', + data: [ + 'w------b', + '--------', + '--------', + '---wb---', + '---bw---', + '--------', + '--------', + 'b------w' + ] +}; + +export const x: Map = { + name: 'X', + category: '8x8', + author: 'Aya', + data: [ + 'w------b', + '-w----b-', + '--w--b--', + '---wb---', + '---bw---', + '--b--w--', + '-b----w-', + 'b------w' + ] +}; + +export const parallel: Map = { + name: 'Parallel', + category: '8x8', + author: 'Aya', + data: [ + '--------', + '--------', + '--------', + '---bb---', + '---ww---', + '--------', + '--------', + '--------' + ] +}; + +export const lackOfBlack: Map = { + name: 'Lack of Black', + category: '8x8', + data: [ + '--------', + '--------', + '--------', + '---w----', + '---bw---', + '--------', + '--------', + '--------' + ] +}; + +export const squareParty: Map = { + name: 'Square Party', + category: '8x8', + author: 'syuilo', + data: [ + '--------', + '-wwwbbb-', + '-w-wb-b-', + '-wwwbbb-', + '-bbbwww-', + '-b-bw-w-', + '-bbbwww-', + '--------' + ] +}; + +export const minesweeper: Map = { + name: 'Minesweeper', + category: '8x8', + author: 'syuilo', + data: [ + 'b-b--w-w', + '-w-wb-b-', + 'w-b--w-b', + '-b-wb-w-', + '-w-bw-b-', + 'b-w--b-w', + '-b-bw-w-', + 'w-w--b-b' + ] +}; + +export const tenthtenth: Map = { + name: '10x10', + category: '10x10', + data: [ + '----------', + '----------', + '----------', + '----------', + '----wb----', + '----bw----', + '----------', + '----------', + '----------', + '----------' + ] +}; + +export const hole: Map = { + name: 'The Hole', + category: '10x10', + author: 'syuilo', + data: [ + '----------', + '----------', + '--wb--wb--', + '--bw--bw--', + '---- ----', + '---- ----', + '--wb--wb--', + '--bw--bw--', + '----------', + '----------' + ] +}; + +export const grid: Map = { + name: 'Grid', + category: '10x10', + author: 'syuilo', + data: [ + '----------', + '- - -- - -', + '----------', + '- - -- - -', + '----wb----', + '----bw----', + '- - -- - -', + '----------', + '- - -- - -', + '----------' + ] +}; + +export const cross: Map = { + name: 'Cross', + category: '10x10', + author: 'Aya', + data: [ + ' ---- ', + ' ---- ', + ' ---- ', + '----------', + '----wb----', + '----bw----', + '----------', + ' ---- ', + ' ---- ', + ' ---- ' + ] +}; + +export const charX: Map = { + name: 'Char X', + category: '10x10', + author: 'syuilo', + data: [ + '--- ---', + '---- ----', + '----------', + ' -------- ', + ' --wb-- ', + ' --bw-- ', + ' -------- ', + '----------', + '---- ----', + '--- ---' + ] +}; + +export const charY: Map = { + name: 'Char Y', + category: '10x10', + author: 'syuilo', + data: [ + '--- ---', + '---- ----', + '----------', + ' -------- ', + ' --wb-- ', + ' --bw-- ', + ' ------ ', + ' ------ ', + ' ------ ', + ' ------ ' + ] +}; + +export const walls: Map = { + name: 'Walls', + category: '10x10', + author: 'Aya', + data: [ + ' bbbbbbbb ', + 'w--------w', + 'w--------w', + 'w--------w', + 'w---wb---w', + 'w---bw---w', + 'w--------w', + 'w--------w', + 'w--------w', + ' bbbbbbbb ' + ] +}; + +export const cpu: Map = { + name: 'CPU', + category: '10x10', + author: 'syuilo', + data: [ + ' b b b b ', + 'w--------w', + ' -------- ', + 'w--------w', + ' ---wb--- ', + ' ---bw--- ', + 'w--------w', + ' -------- ', + 'w--------w', + ' b b b b ' + ] +}; + +export const checker: Map = { + name: 'Checker', + category: '10x10', + author: 'Aya', + data: [ + '----------', + '----------', + '----------', + '---wbwb---', + '---bwbw---', + '---wbwb---', + '---bwbw---', + '----------', + '----------', + '----------' + ] +}; + +export const japaneseCurry: Map = { + name: 'Japanese curry', + category: '10x10', + author: 'syuilo', + data: [ + 'w-b-b-b-b-', + '-w-b-b-b-b', + 'w-w-b-b-b-', + '-w-w-b-b-b', + 'w-w-wwb-b-', + '-w-wbb-b-b', + 'w-w-w-b-b-', + '-w-w-w-b-b', + 'w-w-w-w-b-', + '-w-w-w-w-b' + ] +}; + +export const mosaic: Map = { + name: 'Mosaic', + category: '10x10', + author: 'syuilo', + data: [ + '- - - - - ', + ' - - - - -', + '- - - - - ', + ' - w w - -', + '- - b b - ', + ' - w w - -', + '- - b b - ', + ' - - - - -', + '- - - - - ', + ' - - - - -', + ] +}; + +export const arena: Map = { + name: 'Arena', + category: '10x10', + author: 'syuilo', + data: [ + '- - -- - -', + ' - - - - ', + '- ------ -', + ' -------- ', + '- --wb-- -', + '- --bw-- -', + ' -------- ', + '- ------ -', + ' - - - - ', + '- - -- - -' + ] +}; + +export const reactor: Map = { + name: 'Reactor', + category: '10x10', + author: 'syuilo', + data: [ + '-w------b-', + 'b- - - -w', + '- --wb-- -', + '---b w---', + '- b wb w -', + '- w bw b -', + '---w b---', + '- --bw-- -', + 'w- - - -b', + '-b------w-' + ] +}; + +export const sixeight: Map = { + name: '6x8', + category: 'Special', + data: [ + '------', + '------', + '------', + '--wb--', + '--bw--', + '------', + '------', + '------' + ] +}; + +export const spark: Map = { + name: 'Spark', + category: 'Special', + author: 'syuilo', + data: [ + ' - - ', + '----------', + ' -------- ', + ' -------- ', + ' ---wb--- ', + ' ---bw--- ', + ' -------- ', + ' -------- ', + '----------', + ' - - ' + ] +}; + +export const islands: Map = { + name: 'Islands', + category: 'Special', + author: 'syuilo', + data: [ + '-------- ', + '---wb--- ', + '---bw--- ', + '-------- ', + ' - - ', + ' - - ', + ' --------', + ' --------', + ' --------', + ' --------' + ] +}; + +export const galaxy: Map = { + name: 'Galaxy', + category: 'Special', + author: 'syuilo', + data: [ + ' ------ ', + ' --www--- ', + ' ------w--- ', + '---bbb--w---', + '--b---b-w-b-', + '-b--wwb-w-b-', + '-b-w-bww--b-', + '-b-w-b---b--', + '---w--bbb---', + ' ---w------ ', + ' ---www-- ', + ' ------ ' + ] +}; + +export const triangle: Map = { + name: 'Triangle', + category: 'Special', + author: 'syuilo', + data: [ + ' -- ', + ' -- ', + ' ---- ', + ' ---- ', + ' --wb-- ', + ' --bw-- ', + ' -------- ', + ' -------- ', + '----------', + '----------' + ] +}; + +export const iphonex: Map = { + name: 'iPhone X', + category: 'Special', + author: 'syuilo', + data: [ + ' -- -- ', + '--------', + '--------', + '--------', + '--------', + '---wb---', + '---bw---', + '--------', + '--------', + '--------', + '--------', + ' ------ ' + ] +}; + +export const dealWithIt: Map = { + name: 'Deal with it!', + category: 'Special', + author: 'syuilo', + data: [ + '------------', + '--w-b-------', + ' --b-w------', + ' --w-b---- ', + ' ------- ' + ] +}; + +export const experiment: Map = { + name: 'Let\'s experiment', + category: 'Special', + author: 'syuilo', + data: [ + ' ------------ ', + '------wb------', + '------bw------', + '--------------', + ' - - ', + '------ ------', + 'bbbbbb wwwwww', + 'bbbbbb wwwwww', + 'bbbbbb wwwwww', + 'bbbbbb wwwwww', + 'wwwwww bbbbbb' + ] +}; + +export const bigBoard: Map = { + name: 'Big board', + category: 'Special', + data: [ + '----------------', + '----------------', + '----------------', + '----------------', + '----------------', + '----------------', + '----------------', + '-------wb-------', + '-------bw-------', + '----------------', + '----------------', + '----------------', + '----------------', + '----------------', + '----------------', + '----------------' + ] +}; + +export const twoBoard: Map = { + name: 'Two board', + category: 'Special', + author: 'Aya', + data: [ + '-------- --------', + '-------- --------', + '-------- --------', + '---wb--- ---wb---', + '---bw--- ---bw---', + '-------- --------', + '-------- --------', + '-------- --------' + ] +}; + +export const test1: Map = { + name: 'Test1', + category: 'Test', + data: [ + '--------', + '---wb---', + '---bw---', + '--------' + ] +}; + +export const test2: Map = { + name: 'Test2', + category: 'Test', + data: [ + '------', + '------', + '-b--w-', + '-w--b-', + '-w--b-' + ] +}; + +export const test3: Map = { + name: 'Test3', + category: 'Test', + data: [ + '-w-', + '--w', + 'w--', + '-w-', + '--w', + 'w--', + '-w-', + '--w', + 'w--', + '-w-', + '---', + 'b--', + ] +}; + +export const test4: Map = { + name: 'Test4', + category: 'Test', + data: [ + '-w--b-', + '-w--b-', + '------', + '-w--b-', + '-w--b-' + ] +}; + +// 検証用: この盤面で藍(lv3)が黒で始めると何故か(?)A1に打ってしまう +export const test6: Map = { + name: 'Test6', + category: 'Test', + data: [ + '--wwwww-', + 'wwwwwwww', + 'wbbbwbwb', + 'wbbbbwbb', + 'wbwbbwbb', + 'wwbwbbbb', + '--wbbbbb', + '-wwwww--', + ] +}; + +// 検証用: この盤面で藍(lv3)が黒で始めると何故か(?)G7に打ってしまう +export const test7: Map = { + name: 'Test7', + category: 'Test', + data: [ + 'b--w----', + 'b-wwww--', + 'bwbwwwbb', + 'wbwwwwb-', + 'wwwwwww-', + '-wwbbwwb', + '--wwww--', + '--wwww--', + ] +}; + +// 検証用: この盤面で藍(lv5)が黒で始めると何故か(?)A1に打ってしまう +export const test8: Map = { + name: 'Test8', + category: 'Test', + data: [ + '--------', + '-----w--', + 'w--www--', + 'wwwwww--', + 'bbbbwww-', + 'wwwwww--', + '--www---', + '--ww----', + ] +}; diff --git a/packages/client/src/scripts/games/reversi/package.json b/packages/client/src/scripts/games/reversi/package.json new file mode 100644 index 000000000..a4415ad14 --- /dev/null +++ b/packages/client/src/scripts/games/reversi/package.json @@ -0,0 +1,18 @@ +{ + "name": "misskey-reversi", + "version": "0.0.5", + "description": "Misskey reversi engine", + "keywords": [ + "misskey" + ], + "author": "syuilo ", + "license": "MIT", + "repository": "https://github.com/misskey-dev/misskey.git", + "bugs": "https://github.com/misskey-dev/misskey/issues", + "main": "./built/core.js", + "types": "./built/core.d.ts", + "scripts": { + "build": "tsc" + }, + "dependencies": {} +} diff --git a/packages/client/src/scripts/games/reversi/tsconfig.json b/packages/client/src/scripts/games/reversi/tsconfig.json new file mode 100644 index 000000000..851fb6b7e --- /dev/null +++ b/packages/client/src/scripts/games/reversi/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "noEmitOnError": false, + "noImplicitAny": false, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "experimentalDecorators": true, + "declaration": true, + "sourceMap": false, + "target": "es2017", + "module": "commonjs", + "removeComments": false, + "noLib": false, + "outDir": "./built", + "rootDir": "./" + }, + "compileOnSave": false, + "include": [ + "./core.ts" + ] +} diff --git a/packages/client/src/scripts/gen-search-query.ts b/packages/client/src/scripts/gen-search-query.ts new file mode 100644 index 000000000..57a06c280 --- /dev/null +++ b/packages/client/src/scripts/gen-search-query.ts @@ -0,0 +1,31 @@ +import * as Acct from 'misskey-js/built/acct'; +import { host as localHost } from '@/config'; + +export async function genSearchQuery(v: any, q: string) { + let host: string; + let userId: string; + if (q.split(' ').some(x => x.startsWith('@'))) { + for (const at of q.split(' ').filter(x => x.startsWith('@')).map(x => x.substr(1))) { + if (at.includes('.')) { + if (at === localHost || at === '.') { + host = null; + } else { + host = at; + } + } else { + const user = await v.os.api('users/show', Acct.parse(at)).catch(x => null); + if (user) { + userId = user.id; + } else { + // todo: show error + } + } + } + + } + return { + query: q.split(' ').filter(x => !x.startsWith('/') && !x.startsWith('@')).join(' '), + host: host, + userId: userId + }; +} diff --git a/packages/client/src/scripts/get-account-from-id.ts b/packages/client/src/scripts/get-account-from-id.ts new file mode 100644 index 000000000..ba3adceec --- /dev/null +++ b/packages/client/src/scripts/get-account-from-id.ts @@ -0,0 +1,7 @@ +import { get } from '@/scripts/idb-proxy'; + +export async function getAccountFromId(id: string) { + const accounts = await get('accounts') as { token: string; id: string; }[]; + if (!accounts) console.log('Accounts are not recorded'); + return accounts.find(e => e.id === id); +} diff --git a/src/client/scripts/get-md5.ts b/packages/client/src/scripts/get-md5.ts similarity index 100% rename from src/client/scripts/get-md5.ts rename to packages/client/src/scripts/get-md5.ts diff --git a/packages/client/src/scripts/get-note-summary.ts b/packages/client/src/scripts/get-note-summary.ts new file mode 100644 index 000000000..bd394279c --- /dev/null +++ b/packages/client/src/scripts/get-note-summary.ts @@ -0,0 +1,55 @@ +import * as misskey from 'misskey-js'; +import { i18n } from '@/i18n'; + +/** + * 投稿を表す文字列を取得します。 + * @param {*} note (packされた)投稿 + */ +export const getNoteSummary = (note: misskey.entities.Note): string => { + if (note.deletedAt) { + return `(${i18n.locale.deletedNote})`; + } + + if (note.isHidden) { + return `(${i18n.locale.invisibleNote})`; + } + + let summary = ''; + + // 本文 + if (note.cw != null) { + summary += note.cw; + } else { + summary += note.text ? note.text : ''; + } + + // ファイルが添付されているとき + if ((note.files || []).length != 0) { + summary += ` (${i18n.t('withNFiles', { n: note.files.length })})`; + } + + // 投票が添付されているとき + if (note.poll) { + summary += ` (${i18n.locale.poll})`; + } + + // 返信のとき + if (note.replyId) { + if (note.reply) { + summary += `\n\nRE: ${getNoteSummary(note.reply)}`; + } else { + summary += '\n\nRE: ...'; + } + } + + // Renoteのとき + if (note.renoteId) { + if (note.renote) { + summary += `\n\nRN: ${getNoteSummary(note.renote)}`; + } else { + summary += '\n\nRN: ...'; + } + } + + return summary.trim(); +}; diff --git a/packages/client/src/scripts/get-static-image-url.ts b/packages/client/src/scripts/get-static-image-url.ts new file mode 100644 index 000000000..e9a3e87cc --- /dev/null +++ b/packages/client/src/scripts/get-static-image-url.ts @@ -0,0 +1,16 @@ +import { url as instanceUrl } from '@/config'; +import * as url from '@/scripts/url'; + +export function getStaticImageUrl(baseUrl: string): string { + const u = new URL(baseUrl); + if (u.href.startsWith(`${instanceUrl}/proxy/`)) { + // もう既にproxyっぽそうだったらsearchParams付けるだけ + u.searchParams.set('static', '1'); + return u.href; + } + const dummy = `${u.host}${u.pathname}`; // 拡張子がないとキャッシュしてくれないCDNがあるので + return `${instanceUrl}/proxy/${dummy}?${url.query({ + url: u.href, + static: '1' + })}`; +} diff --git a/packages/client/src/scripts/get-user-menu.ts b/packages/client/src/scripts/get-user-menu.ts new file mode 100644 index 000000000..8d767afa2 --- /dev/null +++ b/packages/client/src/scripts/get-user-menu.ts @@ -0,0 +1,205 @@ +import { i18n } from '@/i18n'; +import copyToClipboard from '@/scripts/copy-to-clipboard'; +import { host } from '@/config'; +import * as Acct from 'misskey-js/built/acct'; +import * as os from '@/os'; +import { userActions } from '@/store'; +import { router } from '@/router'; +import { $i } from '@/account'; + +export function getUserMenu(user) { + const meId = $i ? $i.id : null; + + async function pushList() { + const t = i18n.locale.selectList; // なぜか後で参照すると null になるので最初にメモリに確保しておく + const lists = await os.api('users/lists/list'); + if (lists.length === 0) { + os.dialog({ + type: 'error', + text: i18n.locale.youHaveNoLists + }); + return; + } + const { canceled, result: listId } = await os.dialog({ + type: null, + title: t, + select: { + items: lists.map(list => ({ + value: list.id, text: list.name + })) + }, + showCancelButton: true + }); + if (canceled) return; + os.apiWithDialog('users/lists/push', { + listId: listId, + userId: user.id + }); + } + + async function inviteGroup() { + const groups = await os.api('users/groups/owned'); + if (groups.length === 0) { + os.dialog({ + type: 'error', + text: i18n.locale.youHaveNoGroups + }); + return; + } + const { canceled, result: groupId } = await os.dialog({ + type: null, + title: i18n.locale.group, + select: { + items: groups.map(group => ({ + value: group.id, text: group.name + })) + }, + showCancelButton: true + }); + if (canceled) return; + os.apiWithDialog('users/groups/invite', { + groupId: groupId, + userId: user.id + }); + } + + async function toggleMute() { + os.apiWithDialog(user.isMuted ? 'mute/delete' : 'mute/create', { + userId: user.id + }).then(() => { + user.isMuted = !user.isMuted; + }); + } + + async function toggleBlock() { + if (!await getConfirmed(user.isBlocking ? i18n.locale.unblockConfirm : i18n.locale.blockConfirm)) return; + + os.apiWithDialog(user.isBlocking ? 'blocking/delete' : 'blocking/create', { + userId: user.id + }).then(() => { + user.isBlocking = !user.isBlocking; + }); + } + + async function toggleSilence() { + if (!await getConfirmed(i18n.t(user.isSilenced ? 'unsilenceConfirm' : 'silenceConfirm'))) return; + + os.apiWithDialog(user.isSilenced ? 'admin/unsilence-user' : 'admin/silence-user', { + userId: user.id + }).then(() => { + user.isSilenced = !user.isSilenced; + }); + } + + async function toggleSuspend() { + if (!await getConfirmed(i18n.t(user.isSuspended ? 'unsuspendConfirm' : 'suspendConfirm'))) return; + + os.apiWithDialog(user.isSuspended ? 'admin/unsuspend-user' : 'admin/suspend-user', { + userId: user.id + }).then(() => { + user.isSuspended = !user.isSuspended; + }); + } + + function reportAbuse() { + os.popup(import('@/components/abuse-report-window.vue'), { + user: user, + }, {}, 'closed'); + } + + async function getConfirmed(text: string): Promise { + const confirm = await os.dialog({ + type: 'warning', + showCancelButton: true, + title: 'confirm', + text, + }); + + return !confirm.canceled; + } + + let menu = [{ + icon: 'fas fa-at', + text: i18n.locale.copyUsername, + action: () => { + copyToClipboard(`@${user.username}@${user.host || host}`); + } + }, { + icon: 'fas fa-info-circle', + text: i18n.locale.info, + action: () => { + os.pageWindow(`/user-info/${user.id}`); + } + }, { + icon: 'fas fa-envelope', + text: i18n.locale.sendMessage, + action: () => { + os.post({ specified: user }); + } + }, meId != user.id ? { + type: 'link', + icon: 'fas fa-comments', + text: i18n.locale.startMessaging, + to: '/my/messaging/' + Acct.toString(user), + } : undefined, null, { + icon: 'fas fa-list-ul', + text: i18n.locale.addToList, + action: pushList + }, meId != user.id ? { + icon: 'fas fa-users', + text: i18n.locale.inviteToGroup, + action: inviteGroup + } : undefined] as any; + + if ($i && meId != user.id) { + menu = menu.concat([null, { + icon: user.isMuted ? 'fas fa-eye' : 'fas fa-eye-slash', + text: user.isMuted ? i18n.locale.unmute : i18n.locale.mute, + action: toggleMute + }, { + icon: 'fas fa-ban', + text: user.isBlocking ? i18n.locale.unblock : i18n.locale.block, + action: toggleBlock + }]); + + menu = menu.concat([null, { + icon: 'fas fa-exclamation-circle', + text: i18n.locale.reportAbuse, + action: reportAbuse + }]); + + if ($i && ($i.isAdmin || $i.isModerator)) { + menu = menu.concat([null, { + icon: 'fas fa-microphone-slash', + text: user.isSilenced ? i18n.locale.unsilence : i18n.locale.silence, + action: toggleSilence + }, { + icon: 'fas fa-snowflake', + text: user.isSuspended ? i18n.locale.unsuspend : i18n.locale.suspend, + action: toggleSuspend + }]); + } + } + + if ($i && meId === user.id) { + menu = menu.concat([null, { + icon: 'fas fa-pencil-alt', + text: i18n.locale.editProfile, + action: () => { + router.push('/settings/profile'); + } + }]); + } + + if (userActions.length > 0) { + menu = menu.concat([null, ...userActions.map(action => ({ + icon: 'fas fa-plug', + text: action.title, + action: () => { + action.handler(user); + } + }))]); + } + + return menu; +} diff --git a/src/client/scripts/hotkey.ts b/packages/client/src/scripts/hotkey.ts similarity index 100% rename from src/client/scripts/hotkey.ts rename to packages/client/src/scripts/hotkey.ts diff --git a/src/client/scripts/hpml/block.ts b/packages/client/src/scripts/hpml/block.ts similarity index 100% rename from src/client/scripts/hpml/block.ts rename to packages/client/src/scripts/hpml/block.ts diff --git a/packages/client/src/scripts/hpml/evaluator.ts b/packages/client/src/scripts/hpml/evaluator.ts new file mode 100644 index 000000000..20261d333 --- /dev/null +++ b/packages/client/src/scripts/hpml/evaluator.ts @@ -0,0 +1,234 @@ +import autobind from 'autobind-decorator'; +import { PageVar, envVarsDef, Fn, HpmlScope, HpmlError } from '.'; +import { version } from '@/config'; +import { AiScript, utils, values } from '@syuilo/aiscript'; +import { createAiScriptEnv } from '../aiscript/api'; +import { collectPageVars } from '../collect-page-vars'; +import { initHpmlLib, initAiLib } from './lib'; +import * as os from '@/os'; +import { markRaw, ref, Ref, unref } from 'vue'; +import { Expr, isLiteralValue, Variable } from './expr'; + +/** + * Hpml evaluator + */ +export class Hpml { + private variables: Variable[]; + private pageVars: PageVar[]; + private envVars: Record; + public aiscript?: AiScript; + public pageVarUpdatedCallback?: values.VFn; + public canvases: Record = {}; + public vars: Ref> = ref({}); + public page: Record; + + private opts: { + randomSeed: string; visitor?: any; url?: string; + enableAiScript: boolean; + }; + + constructor(page: Hpml['page'], opts: Hpml['opts']) { + this.page = page; + this.variables = this.page.variables; + this.pageVars = collectPageVars(this.page.content); + this.opts = opts; + + if (this.opts.enableAiScript) { + this.aiscript = markRaw(new AiScript({ ...createAiScriptEnv({ + storageKey: 'pages:' + this.page.id + }), ...initAiLib(this)}, { + in: (q) => { + return new Promise(ok => { + os.dialog({ + title: q, + input: {} + }).then(({ canceled, result: a }) => { + ok(a); + }); + }); + }, + out: (value) => { + console.log(value); + }, + log: (type, params) => { + }, + })); + + this.aiscript.scope.opts.onUpdated = (name, value) => { + this.eval(); + }; + } + + const date = new Date(); + + this.envVars = { + AI: 'kawaii', + VERSION: version, + URL: this.page ? `${opts.url}/@${this.page.user.username}/pages/${this.page.name}` : '', + LOGIN: opts.visitor != null, + NAME: opts.visitor ? opts.visitor.name || opts.visitor.username : '', + USERNAME: opts.visitor ? opts.visitor.username : '', + USERID: opts.visitor ? opts.visitor.id : '', + NOTES_COUNT: opts.visitor ? opts.visitor.notesCount : 0, + FOLLOWERS_COUNT: opts.visitor ? opts.visitor.followersCount : 0, + FOLLOWING_COUNT: opts.visitor ? opts.visitor.followingCount : 0, + IS_CAT: opts.visitor ? opts.visitor.isCat : false, + SEED: opts.randomSeed ? opts.randomSeed : '', + YMD: `${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate()}`, + AISCRIPT_DISABLED: !this.opts.enableAiScript, + NULL: null + }; + + this.eval(); + } + + @autobind + public eval() { + try { + this.vars.value = this.evaluateVars(); + } catch (e) { + //this.onError(e); + } + } + + @autobind + public interpolate(str: string) { + if (str == null) return null; + return str.replace(/{(.+?)}/g, match => { + const v = unref(this.vars)[match.slice(1, -1).trim()]; + return v == null ? 'NULL' : v.toString(); + }); + } + + @autobind + public callAiScript(fn: string) { + try { + if (this.aiscript) this.aiscript.execFn(this.aiscript.scope.get(fn), []); + } catch (e) {} + } + + @autobind + public registerCanvas(id: string, canvas: any) { + this.canvases[id] = canvas; + } + + @autobind + public updatePageVar(name: string, value: any) { + const pageVar = this.pageVars.find(v => v.name === name); + if (pageVar !== undefined) { + pageVar.value = value; + if (this.pageVarUpdatedCallback) { + if (this.aiscript) this.aiscript.execFn(this.pageVarUpdatedCallback, [values.STR(name), utils.jsToVal(value)]); + } + } else { + throw new HpmlError(`No such page var '${name}'`); + } + } + + @autobind + public updateRandomSeed(seed: string) { + this.opts.randomSeed = seed; + this.envVars.SEED = seed; + } + + @autobind + private _interpolateScope(str: string, scope: HpmlScope) { + return str.replace(/{(.+?)}/g, match => { + const v = scope.getState(match.slice(1, -1).trim()); + return v == null ? 'NULL' : v.toString(); + }); + } + + @autobind + public evaluateVars(): Record { + const values: Record = {}; + + for (const [k, v] of Object.entries(this.envVars)) { + values[k] = v; + } + + for (const v of this.pageVars) { + values[v.name] = v.value; + } + + for (const v of this.variables) { + values[v.name] = this.evaluate(v, new HpmlScope([values])); + } + + return values; + } + + @autobind + private evaluate(expr: Expr, scope: HpmlScope): any { + + if (isLiteralValue(expr)) { + if (expr.type === null) { + return null; + } + + if (expr.type === 'number') { + return parseInt((expr.value as any), 10); + } + + if (expr.type === 'text' || expr.type === 'multiLineText') { + return this._interpolateScope(expr.value || '', scope); + } + + if (expr.type === 'textList') { + return this._interpolateScope(expr.value || '', scope).trim().split('\n'); + } + + if (expr.type === 'ref') { + return scope.getState(expr.value); + } + + if (expr.type === 'aiScriptVar') { + if (this.aiscript) { + try { + return utils.valToJs(this.aiscript.scope.get(expr.value)); + } catch (e) { + return null; + } + } else { + return null; + } + } + + // Define user function + if (expr.type == 'fn') { + return { + slots: expr.value.slots.map(x => x.name), + exec: (slotArg: Record) => { + return this.evaluate(expr.value.expression, scope.createChildScope(slotArg, expr.id)); + } + } as Fn; + } + return; + } + + // Call user function + if (expr.type.startsWith('fn:')) { + const fnName = expr.type.split(':')[1]; + const fn = scope.getState(fnName); + const args = {} as Record; + for (let i = 0; i < fn.slots.length; i++) { + const name = fn.slots[i]; + args[name] = this.evaluate(expr.args[i], scope); + } + return fn.exec(args); + } + + if (expr.args === undefined) return null; + + const funcs = initHpmlLib(expr, scope, this.opts.randomSeed, this.opts.visitor); + + // Call function + const fnName = expr.type; + const fn = (funcs as any)[fnName]; + if (fn == null) { + throw new HpmlError(`No such function '${fnName}'`); + } else { + return fn(...expr.args.map(x => this.evaluate(x, scope))); + } + } +} diff --git a/src/client/scripts/hpml/expr.ts b/packages/client/src/scripts/hpml/expr.ts similarity index 100% rename from src/client/scripts/hpml/expr.ts rename to packages/client/src/scripts/hpml/expr.ts diff --git a/src/client/scripts/hpml/index.ts b/packages/client/src/scripts/hpml/index.ts similarity index 100% rename from src/client/scripts/hpml/index.ts rename to packages/client/src/scripts/hpml/index.ts diff --git a/src/client/scripts/hpml/lib.ts b/packages/client/src/scripts/hpml/lib.ts similarity index 100% rename from src/client/scripts/hpml/lib.ts rename to packages/client/src/scripts/hpml/lib.ts diff --git a/src/client/scripts/hpml/type-checker.ts b/packages/client/src/scripts/hpml/type-checker.ts similarity index 100% rename from src/client/scripts/hpml/type-checker.ts rename to packages/client/src/scripts/hpml/type-checker.ts diff --git a/packages/client/src/scripts/i18n.ts b/packages/client/src/scripts/i18n.ts new file mode 100644 index 000000000..4fa398763 --- /dev/null +++ b/packages/client/src/scripts/i18n.ts @@ -0,0 +1,29 @@ +export class I18n> { + public locale: T; + + constructor(locale: T) { + this.locale = locale; + + //#region BIND + this.t = this.t.bind(this); + //#endregion + } + + // string にしているのは、ドット区切りでのパス指定を許可するため + // なるべくこのメソッド使うよりもlocale直接参照の方がvueのキャッシュ効いてパフォーマンスが良いかも + public t(key: string, args?: Record): string { + try { + let str = key.split('.').reduce((o, i) => o[i], this.locale) as string; + + if (args) { + for (const [k, v] of Object.entries(args)) { + str = str.replace(`{${k}}`, v); + } + } + return str; + } catch (e) { + console.warn(`missing localization '${key}'`); + return key; + } + } +} diff --git a/src/client/scripts/idb-proxy.ts b/packages/client/src/scripts/idb-proxy.ts similarity index 100% rename from src/client/scripts/idb-proxy.ts rename to packages/client/src/scripts/idb-proxy.ts diff --git a/packages/client/src/scripts/initialize-sw.ts b/packages/client/src/scripts/initialize-sw.ts new file mode 100644 index 000000000..d6dbd5dbd --- /dev/null +++ b/packages/client/src/scripts/initialize-sw.ts @@ -0,0 +1,68 @@ +import { instance } from '@/instance'; +import { $i } from '@/account'; +import { api } from '@/os'; +import { lang } from '@/config'; + +export async function initializeSw() { + if (instance.swPublickey && + ('serviceWorker' in navigator) && + ('PushManager' in window) && + $i && $i.token) { + navigator.serviceWorker.register(`/sw.js`); + + navigator.serviceWorker.ready.then(registration => { + registration.active?.postMessage({ + msg: 'initialize', + lang, + }); + // SEE: https://developer.mozilla.org/en-US/docs/Web/API/PushManager/subscribe#Parameters + registration.pushManager.subscribe({ + userVisibleOnly: true, + applicationServerKey: urlBase64ToUint8Array(instance.swPublickey) + }).then(subscription => { + function encode(buffer: ArrayBuffer | null) { + return btoa(String.fromCharCode.apply(null, new Uint8Array(buffer))); + } + + // Register + api('sw/register', { + endpoint: subscription.endpoint, + auth: encode(subscription.getKey('auth')), + publickey: encode(subscription.getKey('p256dh')) + }); + }) + // When subscribe failed + .catch(async (err: Error) => { + // 通知が許可されていなかったとき + if (err.name === 'NotAllowedError') { + return; + } + + // 違うapplicationServerKey (または gcm_sender_id)のサブスクリプションが + // 既に存在していることが原因でエラーになった可能性があるので、 + // そのサブスクリプションを解除しておく + const subscription = await registration.pushManager.getSubscription(); + if (subscription) subscription.unsubscribe(); + }); + }); + } +} + +/** + * Convert the URL safe base64 string to a Uint8Array + * @param base64String base64 string + */ +function urlBase64ToUint8Array(base64String: string): Uint8Array { + const padding = '='.repeat((4 - base64String.length % 4) % 4); + const base64 = (base64String + padding) + .replace(/-/g, '+') + .replace(/_/g, '/'); + + const rawData = window.atob(base64); + const outputArray = new Uint8Array(rawData.length); + + for (let i = 0; i < rawData.length; ++i) { + outputArray[i] = rawData.charCodeAt(i); + } + return outputArray; +} diff --git a/src/client/scripts/is-device-darkmode.ts b/packages/client/src/scripts/is-device-darkmode.ts similarity index 100% rename from src/client/scripts/is-device-darkmode.ts rename to packages/client/src/scripts/is-device-darkmode.ts diff --git a/src/client/scripts/is-device-touch.ts b/packages/client/src/scripts/is-device-touch.ts similarity index 100% rename from src/client/scripts/is-device-touch.ts rename to packages/client/src/scripts/is-device-touch.ts diff --git a/src/client/scripts/is-mobile.ts b/packages/client/src/scripts/is-mobile.ts similarity index 100% rename from src/client/scripts/is-mobile.ts rename to packages/client/src/scripts/is-mobile.ts diff --git a/src/client/scripts/keycode.ts b/packages/client/src/scripts/keycode.ts similarity index 100% rename from src/client/scripts/keycode.ts rename to packages/client/src/scripts/keycode.ts diff --git a/src/client/scripts/loading.ts b/packages/client/src/scripts/loading.ts similarity index 100% rename from src/client/scripts/loading.ts rename to packages/client/src/scripts/loading.ts diff --git a/src/client/scripts/login-id.ts b/packages/client/src/scripts/login-id.ts similarity index 100% rename from src/client/scripts/login-id.ts rename to packages/client/src/scripts/login-id.ts diff --git a/packages/client/src/scripts/lookup-user.ts b/packages/client/src/scripts/lookup-user.ts new file mode 100644 index 000000000..174fa9f87 --- /dev/null +++ b/packages/client/src/scripts/lookup-user.ts @@ -0,0 +1,37 @@ +import * as Acct from 'misskey-js/built/acct'; +import { i18n } from '@/i18n'; +import * as os from '@/os'; + +export async function lookupUser() { + const { canceled, result } = await os.dialog({ + title: i18n.locale.usernameOrUserId, + input: true + }); + if (canceled) return; + + const show = (user) => { + os.pageWindow(`/user-info/${user.id}`); + }; + + const usernamePromise = os.api('users/show', Acct.parse(result)); + const idPromise = os.api('users/show', { userId: result }); + let _notFound = false; + const notFound = () => { + if (_notFound) { + os.dialog({ + type: 'error', + text: i18n.locale.noSuchUser + }); + } else { + _notFound = true; + } + }; + usernamePromise.then(show).catch(e => { + if (e.code === 'NO_SUCH_USER') { + notFound(); + } + }); + idPromise.then(show).catch(e => { + notFound(); + }); +} diff --git a/packages/client/src/scripts/mfm-tags.ts b/packages/client/src/scripts/mfm-tags.ts new file mode 100644 index 000000000..1b18210aa --- /dev/null +++ b/packages/client/src/scripts/mfm-tags.ts @@ -0,0 +1 @@ +export const MFM_TAGS = ['tada', 'jelly', 'twitch', 'shake', 'spin', 'jump', 'bounce', 'flip', 'x2', 'x3', 'x4', 'font', 'blur', 'rainbow', 'sparkle']; diff --git a/packages/client/src/scripts/paging.ts b/packages/client/src/scripts/paging.ts new file mode 100644 index 000000000..ef63ecc45 --- /dev/null +++ b/packages/client/src/scripts/paging.ts @@ -0,0 +1,246 @@ +import { markRaw } from 'vue'; +import * as os from '@/os'; +import { onScrollTop, isTopVisible, getScrollPosition, getScrollContainer } from './scroll'; + +const SECOND_FETCH_LIMIT = 30; + +// reversed: items 配列の中身を逆順にする(新しい方が最後) + +export default (opts) => ({ + emits: ['queue'], + + data() { + return { + items: [], + queue: [], + offset: 0, + fetching: true, + moreFetching: false, + inited: false, + more: false, + backed: false, // 遡り中か否か + isBackTop: false, + }; + }, + + computed: { + empty(): boolean { + return this.items.length === 0 && !this.fetching && this.inited; + }, + + error(): boolean { + return !this.fetching && !this.inited; + }, + }, + + watch: { + pagination: { + handler() { + this.init(); + }, + deep: true + }, + + queue: { + handler(a, b) { + if (a.length === 0 && b.length === 0) return; + this.$emit('queue', this.queue.length); + }, + deep: true + } + }, + + created() { + opts.displayLimit = opts.displayLimit || 30; + this.init(); + }, + + activated() { + this.isBackTop = false; + }, + + deactivated() { + this.isBackTop = window.scrollY === 0; + }, + + methods: { + reload() { + this.items = []; + this.init(); + }, + + replaceItem(finder, data) { + const i = this.items.findIndex(finder); + this.items[i] = data; + }, + + removeItem(finder) { + const i = this.items.findIndex(finder); + this.items.splice(i, 1); + }, + + async init() { + this.queue = []; + this.fetching = true; + if (opts.before) opts.before(this); + let params = typeof this.pagination.params === 'function' ? this.pagination.params(true) : this.pagination.params; + if (params && params.then) params = await params; + if (params === null) return; + const endpoint = typeof this.pagination.endpoint === 'function' ? this.pagination.endpoint() : this.pagination.endpoint; + await os.api(endpoint, { + ...params, + limit: this.pagination.noPaging ? (this.pagination.limit || 10) : (this.pagination.limit || 10) + 1, + }).then(items => { + for (let i = 0; i < items.length; i++) { + const item = items[i]; + markRaw(item); + if (this.pagination.reversed) { + if (i === items.length - 2) item._shouldInsertAd_ = true; + } else { + if (i === 3) item._shouldInsertAd_ = true; + } + } + if (!this.pagination.noPaging && (items.length > (this.pagination.limit || 10))) { + items.pop(); + this.items = this.pagination.reversed ? [...items].reverse() : items; + this.more = true; + } else { + this.items = this.pagination.reversed ? [...items].reverse() : items; + this.more = false; + } + this.offset = items.length; + this.inited = true; + this.fetching = false; + if (opts.after) opts.after(this, null); + }, e => { + this.fetching = false; + if (opts.after) opts.after(this, e); + }); + }, + + async fetchMore() { + if (!this.more || this.fetching || this.moreFetching || this.items.length === 0) return; + this.moreFetching = true; + this.backed = true; + let params = typeof this.pagination.params === 'function' ? this.pagination.params(false) : this.pagination.params; + if (params && params.then) params = await params; + const endpoint = typeof this.pagination.endpoint === 'function' ? this.pagination.endpoint() : this.pagination.endpoint; + await os.api(endpoint, { + ...params, + limit: SECOND_FETCH_LIMIT + 1, + ...(this.pagination.offsetMode ? { + offset: this.offset, + } : { + untilId: this.pagination.reversed ? this.items[0].id : this.items[this.items.length - 1].id, + }), + }).then(items => { + for (let i = 0; i < items.length; i++) { + const item = items[i]; + markRaw(item); + if (this.pagination.reversed) { + if (i === items.length - 9) item._shouldInsertAd_ = true; + } else { + if (i === 10) item._shouldInsertAd_ = true; + } + } + if (items.length > SECOND_FETCH_LIMIT) { + items.pop(); + this.items = this.pagination.reversed ? [...items].reverse().concat(this.items) : this.items.concat(items); + this.more = true; + } else { + this.items = this.pagination.reversed ? [...items].reverse().concat(this.items) : this.items.concat(items); + this.more = false; + } + this.offset += items.length; + this.moreFetching = false; + }, e => { + this.moreFetching = false; + }); + }, + + async fetchMoreFeature() { + if (!this.more || this.fetching || this.moreFetching || this.items.length === 0) return; + this.moreFetching = true; + let params = typeof this.pagination.params === 'function' ? this.pagination.params(false) : this.pagination.params; + if (params && params.then) params = await params; + const endpoint = typeof this.pagination.endpoint === 'function' ? this.pagination.endpoint() : this.pagination.endpoint; + await os.api(endpoint, { + ...params, + limit: SECOND_FETCH_LIMIT + 1, + ...(this.pagination.offsetMode ? { + offset: this.offset, + } : { + sinceId: this.pagination.reversed ? this.items[0].id : this.items[this.items.length - 1].id, + }), + }).then(items => { + for (const item of items) { + markRaw(item); + } + if (items.length > SECOND_FETCH_LIMIT) { + items.pop(); + this.items = this.pagination.reversed ? [...items].reverse().concat(this.items) : this.items.concat(items); + this.more = true; + } else { + this.items = this.pagination.reversed ? [...items].reverse().concat(this.items) : this.items.concat(items); + this.more = false; + } + this.offset += items.length; + this.moreFetching = false; + }, e => { + this.moreFetching = false; + }); + }, + + prepend(item) { + if (this.pagination.reversed) { + const container = getScrollContainer(this.$el); + const pos = getScrollPosition(this.$el); + const viewHeight = container.clientHeight; + const height = container.scrollHeight; + const isBottom = (pos + viewHeight > height - 32); + if (isBottom) { + // オーバーフローしたら古いアイテムは捨てる + if (this.items.length >= opts.displayLimit) { + // このやり方だとVue 3.2以降アニメーションが動かなくなる + //this.items = this.items.slice(-opts.displayLimit); + while (this.items.length >= opts.displayLimit) { + this.items.shift(); + } + this.more = true; + } + } + this.items.push(item); + // TODO + } else { + const isTop = this.isBackTop || (document.body.contains(this.$el) && isTopVisible(this.$el)); + + if (isTop) { + // Prepend the item + this.items.unshift(item); + + // オーバーフローしたら古いアイテムは捨てる + if (this.items.length >= opts.displayLimit) { + // このやり方だとVue 3.2以降アニメーションが動かなくなる + //this.items = this.items.slice(0, opts.displayLimit); + while (this.items.length >= opts.displayLimit) { + this.items.pop(); + } + this.more = true; + } + } else { + this.queue.push(item); + onScrollTop(this.$el, () => { + for (const item of this.queue) { + this.prepend(item); + } + this.queue = []; + }); + } + } + }, + + append(item) { + this.items.push(item); + }, + } +}); diff --git a/src/client/scripts/physics.ts b/packages/client/src/scripts/physics.ts similarity index 100% rename from src/client/scripts/physics.ts rename to packages/client/src/scripts/physics.ts diff --git a/packages/client/src/scripts/please-login.ts b/packages/client/src/scripts/please-login.ts new file mode 100644 index 000000000..928f6ec0f --- /dev/null +++ b/packages/client/src/scripts/please-login.ts @@ -0,0 +1,14 @@ +import { $i } from '@/account'; +import { i18n } from '@/i18n'; +import { dialog } from '@/os'; + +export function pleaseLogin() { + if ($i) return; + + dialog({ + title: i18n.locale.signinRequired, + text: null + }); + + throw new Error('signin required'); +} diff --git a/packages/client/src/scripts/popout.ts b/packages/client/src/scripts/popout.ts new file mode 100644 index 000000000..51b8d7286 --- /dev/null +++ b/packages/client/src/scripts/popout.ts @@ -0,0 +1,22 @@ +import * as config from '@/config'; + +export function popout(path: string, w?: HTMLElement) { + let url = path.startsWith('http://') || path.startsWith('https://') ? path : config.url + path; + url += '?zen'; // TODO: ちゃんとURLパースしてクエリ付ける + if (w) { + const position = w.getBoundingClientRect(); + const width = parseInt(getComputedStyle(w, '').width, 10); + const height = parseInt(getComputedStyle(w, '').height, 10); + const x = window.screenX + position.left; + const y = window.screenY + position.top; + window.open(url, url, + `width=${width}, height=${height}, top=${y}, left=${x}`); + } else { + const width = 400; + const height = 500; + const x = window.top.outerHeight / 2 + window.top.screenY - (height / 2); + const y = window.top.outerWidth / 2 + window.top.screenX - (width / 2); + window.open(url, url, + `width=${width}, height=${height}, top=${x}, left=${y}`); + } +} diff --git a/packages/client/src/scripts/reaction-picker.ts b/packages/client/src/scripts/reaction-picker.ts new file mode 100644 index 000000000..e923326ec --- /dev/null +++ b/packages/client/src/scripts/reaction-picker.ts @@ -0,0 +1,41 @@ +import { Ref, ref } from 'vue'; +import { popup } from '@/os'; + +class ReactionPicker { + private src: Ref = ref(null); + private manualShowing = ref(false); + private onChosen?: Function; + private onClosed?: Function; + + constructor() { + // nop + } + + public async init() { + await popup(import('@/components/emoji-picker-dialog.vue'), { + src: this.src, + asReactionPicker: true, + manualShowing: this.manualShowing + }, { + done: reaction => { + this.onChosen!(reaction); + }, + close: () => { + this.manualShowing.value = false; + }, + closed: () => { + this.src.value = null; + this.onClosed!(); + } + }); + } + + public show(src: HTMLElement, onChosen: Function, onClosed: Function) { + this.src.value = src; + this.manualShowing.value = true; + this.onChosen = onChosen; + this.onClosed = onClosed; + } +} + +export const reactionPicker = new ReactionPicker(); diff --git a/src/client/scripts/room/furniture.ts b/packages/client/src/scripts/room/furniture.ts similarity index 100% rename from src/client/scripts/room/furniture.ts rename to packages/client/src/scripts/room/furniture.ts diff --git a/src/client/scripts/room/furnitures.json5 b/packages/client/src/scripts/room/furnitures.json5 similarity index 100% rename from src/client/scripts/room/furnitures.json5 rename to packages/client/src/scripts/room/furnitures.json5 diff --git a/packages/client/src/scripts/room/room.ts b/packages/client/src/scripts/room/room.ts new file mode 100644 index 000000000..7e04bec64 --- /dev/null +++ b/packages/client/src/scripts/room/room.ts @@ -0,0 +1,775 @@ +import autobind from 'autobind-decorator'; +import { v4 as uuid } from 'uuid'; +import * as THREE from 'three'; +import { GLTFLoader, GLTF } from 'three/examples/jsm/loaders/GLTFLoader'; +import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'; +import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js'; +import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js'; +import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js'; +import { BloomPass } from 'three/examples/jsm/postprocessing/BloomPass.js'; +import { FXAAShader } from 'three/examples/jsm/shaders/FXAAShader.js'; +import { TransformControls } from 'three/examples/jsm/controls/TransformControls.js'; +import { Furniture, RoomInfo } from './furniture'; +import { query as urlQuery } from '@/scripts/url'; +const furnitureDefs = require('./furnitures.json5'); + +THREE.ImageUtils.crossOrigin = ''; + +type Options = { + graphicsQuality: Room['graphicsQuality']; + onChangeSelect: Room['onChangeSelect']; + useOrthographicCamera: boolean; +}; + +/** + * MisskeyRoom Core Engine + */ +export class Room { + private clock: THREE.Clock; + private scene: THREE.Scene; + private renderer: THREE.WebGLRenderer; + private camera: THREE.PerspectiveCamera | THREE.OrthographicCamera; + private controls: OrbitControls; + private composer: EffectComposer; + private mixers: THREE.AnimationMixer[] = []; + private furnitureControl: TransformControls; + private roomInfo: RoomInfo; + private graphicsQuality: 'cheep' | 'low' | 'medium' | 'high' | 'ultra'; + private roomObj: THREE.Object3D; + private objects: THREE.Object3D[] = []; + private selectedObject: THREE.Object3D = null; + private onChangeSelect: Function; + private isTransformMode = false; + private renderFrameRequestId: number; + + private get canvas(): HTMLCanvasElement { + return this.renderer.domElement; + } + + private get furnitures(): Furniture[] { + return this.roomInfo.furnitures; + } + + private set furnitures(furnitures: Furniture[]) { + this.roomInfo.furnitures = furnitures; + } + + private get enableShadow() { + return this.graphicsQuality != 'cheep'; + } + + private get usePostFXs() { + return this.graphicsQuality !== 'cheep' && this.graphicsQuality !== 'low'; + } + + private get shadowQuality() { + return ( + this.graphicsQuality === 'ultra' ? 16384 : + this.graphicsQuality === 'high' ? 8192 : + this.graphicsQuality === 'medium' ? 4096 : + this.graphicsQuality === 'low' ? 1024 : + 0); // cheep + } + + constructor(user, isMyRoom, roomInfo: RoomInfo, container: Element, options: Options) { + this.roomInfo = roomInfo; + this.graphicsQuality = options.graphicsQuality; + this.onChangeSelect = options.onChangeSelect; + + this.clock = new THREE.Clock(true); + + //#region Init a scene + this.scene = new THREE.Scene(); + + const width = container.clientWidth; + const height = container.clientHeight; + + //#region Init a renderer + this.renderer = new THREE.WebGLRenderer({ + antialias: false, + stencil: false, + alpha: false, + powerPreference: + this.graphicsQuality === 'ultra' ? 'high-performance' : + this.graphicsQuality === 'high' ? 'high-performance' : + this.graphicsQuality === 'medium' ? 'default' : + this.graphicsQuality === 'low' ? 'low-power' : + 'low-power' // cheep + }); + + this.renderer.setPixelRatio(window.devicePixelRatio); + this.renderer.setSize(width, height); + this.renderer.autoClear = false; + this.renderer.setClearColor(new THREE.Color(0x051f2d)); + this.renderer.shadowMap.enabled = this.enableShadow; + this.renderer.shadowMap.type = + this.graphicsQuality === 'ultra' ? THREE.PCFSoftShadowMap : + this.graphicsQuality === 'high' ? THREE.PCFSoftShadowMap : + this.graphicsQuality === 'medium' ? THREE.PCFShadowMap : + this.graphicsQuality === 'low' ? THREE.BasicShadowMap : + THREE.BasicShadowMap; // cheep + + container.insertBefore(this.canvas, container.firstChild); + //#endregion + + //#region Init a camera + this.camera = options.useOrthographicCamera + ? new THREE.OrthographicCamera( + width / - 2, width / 2, height / 2, height / - 2, -10, 10) + : new THREE.PerspectiveCamera(45, width / height); + + if (options.useOrthographicCamera) { + this.camera.position.x = 2; + this.camera.position.y = 2; + this.camera.position.z = 2; + this.camera.zoom = 100; + this.camera.updateProjectionMatrix(); + } else { + this.camera.position.x = 5; + this.camera.position.y = 2; + this.camera.position.z = 5; + } + + this.scene.add(this.camera); + //#endregion + + //#region AmbientLight + const ambientLight = new THREE.AmbientLight(0xffffff, 1); + this.scene.add(ambientLight); + //#endregion + + if (this.graphicsQuality !== 'cheep') { + //#region Room light + const roomLight = new THREE.SpotLight(0xffffff, 0.1); + + roomLight.position.set(0, 8, 0); + roomLight.castShadow = this.enableShadow; + roomLight.shadow.bias = -0.0001; + roomLight.shadow.mapSize.width = this.shadowQuality; + roomLight.shadow.mapSize.height = this.shadowQuality; + roomLight.shadow.camera.near = 0.1; + roomLight.shadow.camera.far = 9; + roomLight.shadow.camera.fov = 45; + + this.scene.add(roomLight); + //#endregion + } + + //#region Out light + const outLight1 = new THREE.SpotLight(0xffffff, 0.4); + outLight1.position.set(9, 3, -2); + outLight1.castShadow = this.enableShadow; + outLight1.shadow.bias = -0.001; // アクネ、アーチファクト対策 その代わりピーターパンが発生する可能性がある + outLight1.shadow.mapSize.width = this.shadowQuality; + outLight1.shadow.mapSize.height = this.shadowQuality; + outLight1.shadow.camera.near = 6; + outLight1.shadow.camera.far = 15; + outLight1.shadow.camera.fov = 45; + this.scene.add(outLight1); + + const outLight2 = new THREE.SpotLight(0xffffff, 0.2); + outLight2.position.set(-2, 3, 9); + outLight2.castShadow = false; + outLight2.shadow.bias = -0.001; // アクネ、アーチファクト対策 その代わりピーターパンが発生する可能性がある + outLight2.shadow.camera.near = 6; + outLight2.shadow.camera.far = 15; + outLight2.shadow.camera.fov = 45; + this.scene.add(outLight2); + //#endregion + + //#region Init a controller + this.controls = new OrbitControls(this.camera, this.canvas); + + this.controls.target.set(0, 1, 0); + this.controls.enableZoom = true; + this.controls.enablePan = isMyRoom; + this.controls.minPolarAngle = 0; + this.controls.maxPolarAngle = Math.PI / 2; + this.controls.minAzimuthAngle = 0; + this.controls.maxAzimuthAngle = Math.PI / 2; + this.controls.enableDamping = true; + this.controls.dampingFactor = 0.2; + //#endregion + + //#region POST FXs + if (!this.usePostFXs) { + this.composer = null; + } else { + const renderTarget = new THREE.WebGLRenderTarget(width, height, { + minFilter: THREE.LinearFilter, + magFilter: THREE.LinearFilter, + format: THREE.RGBFormat, + stencilBuffer: false, + }); + + const fxaa = new ShaderPass(FXAAShader); + fxaa.uniforms['resolution'].value = new THREE.Vector2(1 / width, 1 / height); + fxaa.renderToScreen = true; + + this.composer = new EffectComposer(this.renderer, renderTarget); + this.composer.addPass(new RenderPass(this.scene, this.camera)); + if (this.graphicsQuality === 'ultra') { + this.composer.addPass(new BloomPass(0.25, 30, 128.0, 512)); + } + this.composer.addPass(fxaa); + } + //#endregion + //#endregion + + //#region Label + //#region Avatar + const avatarUrl = `/proxy/?${urlQuery({ url: user.avatarUrl })}`; + + const textureLoader = new THREE.TextureLoader(); + textureLoader.crossOrigin = 'anonymous'; + + const iconTexture = textureLoader.load(avatarUrl); + iconTexture.wrapS = THREE.RepeatWrapping; + iconTexture.wrapT = THREE.RepeatWrapping; + iconTexture.anisotropy = 16; + + const avatarMaterial = new THREE.MeshBasicMaterial({ + map: iconTexture, + side: THREE.DoubleSide, + alphaTest: 0.5 + }); + + const iconGeometry = new THREE.PlaneGeometry(1, 1); + + const avatarObject = new THREE.Mesh(iconGeometry, avatarMaterial); + avatarObject.position.set(-3, 2.5, 2); + avatarObject.rotation.y = Math.PI / 2; + avatarObject.castShadow = false; + + this.scene.add(avatarObject); + //#endregion + + //#region Username + const name = user.username; + + new THREE.FontLoader().load('/assets/fonts/helvetiker_regular.typeface.json', font => { + const nameGeometry = new THREE.TextGeometry(name, { + size: 0.5, + height: 0, + curveSegments: 8, + font: font, + bevelThickness: 0, + bevelSize: 0, + bevelEnabled: false + }); + + const nameMaterial = new THREE.MeshLambertMaterial({ + color: 0xffffff + }); + + const nameObject = new THREE.Mesh(nameGeometry, nameMaterial); + nameObject.position.set(-3, 2.25, 1.25); + nameObject.rotation.y = Math.PI / 2; + nameObject.castShadow = false; + + this.scene.add(nameObject); + }); + //#endregion + //#endregion + + //#region Interaction + if (isMyRoom) { + this.furnitureControl = new TransformControls(this.camera, this.canvas); + this.scene.add(this.furnitureControl); + + // Hover highlight + this.canvas.onmousemove = this.onmousemove; + + // Click + this.canvas.onmousedown = this.onmousedown; + } + //#endregion + + //#region Init room + this.loadRoom(); + //#endregion + + //#region Load furnitures + for (const furniture of this.furnitures) { + this.loadFurniture(furniture).then(obj => { + this.scene.add(obj.scene); + this.objects.push(obj.scene); + }); + } + //#endregion + + // Start render + if (this.usePostFXs) { + this.renderWithPostFXs(); + } else { + this.renderWithoutPostFXs(); + } + } + + @autobind + private renderWithoutPostFXs() { + this.renderFrameRequestId = + window.requestAnimationFrame(this.renderWithoutPostFXs); + + // Update animations + const clock = this.clock.getDelta(); + for (const mixer of this.mixers) { + mixer.update(clock); + } + + this.controls.update(); + this.renderer.render(this.scene, this.camera); + } + + @autobind + private renderWithPostFXs() { + this.renderFrameRequestId = + window.requestAnimationFrame(this.renderWithPostFXs); + + // Update animations + const clock = this.clock.getDelta(); + for (const mixer of this.mixers) { + mixer.update(clock); + } + + this.controls.update(); + this.renderer.clear(); + this.composer.render(); + } + + @autobind + private loadRoom() { + const type = this.roomInfo.roomType; + new GLTFLoader().load(`/client-assets/room/rooms/${type}/${type}.glb`, gltf => { + gltf.scene.traverse(child => { + if (!(child instanceof THREE.Mesh)) return; + + child.receiveShadow = this.enableShadow; + + child.material = new THREE.MeshLambertMaterial({ + color: (child.material as THREE.MeshStandardMaterial).color, + map: (child.material as THREE.MeshStandardMaterial).map, + name: (child.material as THREE.MeshStandardMaterial).name, + }); + + // 異方性フィルタリング + if ((child.material as THREE.MeshLambertMaterial).map && this.graphicsQuality !== 'cheep') { + (child.material as THREE.MeshLambertMaterial).map.minFilter = THREE.LinearMipMapLinearFilter; + (child.material as THREE.MeshLambertMaterial).map.magFilter = THREE.LinearMipMapLinearFilter; + (child.material as THREE.MeshLambertMaterial).map.anisotropy = 8; + } + }); + + gltf.scene.position.set(0, 0, 0); + + this.scene.add(gltf.scene); + this.roomObj = gltf.scene; + if (this.roomInfo.roomType === 'default') { + this.applyCarpetColor(); + } + }); + } + + @autobind + private loadFurniture(furniture: Furniture) { + const def = furnitureDefs.find(d => d.id === furniture.type); + return new Promise((res, rej) => { + const loader = new GLTFLoader(); + loader.load(`/client-assets/room/furnitures/${furniture.type}/${furniture.type}.glb`, gltf => { + const model = gltf.scene; + + // Load animation + if (gltf.animations.length > 0) { + const mixer = new THREE.AnimationMixer(model); + this.mixers.push(mixer); + for (const clip of gltf.animations) { + mixer.clipAction(clip).play(); + } + } + + model.name = furniture.id; + model.position.x = furniture.position.x; + model.position.y = furniture.position.y; + model.position.z = furniture.position.z; + model.rotation.x = furniture.rotation.x; + model.rotation.y = furniture.rotation.y; + model.rotation.z = furniture.rotation.z; + + model.traverse(child => { + if (!(child instanceof THREE.Mesh)) return; + child.castShadow = this.enableShadow; + child.receiveShadow = this.enableShadow; + (child.material as THREE.MeshStandardMaterial).metalness = 0; + + // 異方性フィルタリング + if ((child.material as THREE.MeshStandardMaterial).map && this.graphicsQuality !== 'cheep') { + (child.material as THREE.MeshStandardMaterial).map.minFilter = THREE.LinearMipMapLinearFilter; + (child.material as THREE.MeshStandardMaterial).map.magFilter = THREE.LinearMipMapLinearFilter; + (child.material as THREE.MeshStandardMaterial).map.anisotropy = 8; + } + }); + + if (def.color) { // カスタムカラー + this.applyCustomColor(model); + } + + if (def.texture) { // カスタムテクスチャ + this.applyCustomTexture(model); + } + + res(gltf); + }, null, rej); + }); + } + + @autobind + private applyCarpetColor() { + this.roomObj.traverse(child => { + if (!(child instanceof THREE.Mesh)) return; + if (child.material && + (child.material as THREE.MeshStandardMaterial).name && + (child.material as THREE.MeshStandardMaterial).name === 'Carpet' + ) { + const colorHex = parseInt(this.roomInfo.carpetColor.substr(1), 16); + (child.material as THREE.MeshStandardMaterial).color.setHex(colorHex); + } + }); + } + + @autobind + private applyCustomColor(model: THREE.Object3D) { + const furniture = this.furnitures.find(furniture => furniture.id === model.name); + const def = furnitureDefs.find(d => d.id === furniture.type); + if (def.color == null) return; + model.traverse(child => { + if (!(child instanceof THREE.Mesh)) return; + for (const t of Object.keys(def.color)) { + if (!child.material || + !(child.material as THREE.MeshStandardMaterial).name || + (child.material as THREE.MeshStandardMaterial).name !== t + ) continue; + + const prop = def.color[t]; + const val = furniture.props ? furniture.props[prop] : undefined; + + if (val == null) continue; + + const colorHex = parseInt(val.substr(1), 16); + (child.material as THREE.MeshStandardMaterial).color.setHex(colorHex); + } + }); + } + + @autobind + private applyCustomTexture(model: THREE.Object3D) { + const furniture = this.furnitures.find(furniture => furniture.id === model.name); + const def = furnitureDefs.find(d => d.id === furniture.type); + if (def.texture == null) return; + + model.traverse(child => { + if (!(child instanceof THREE.Mesh)) return; + for (const t of Object.keys(def.texture)) { + if (child.name !== t) continue; + + const prop = def.texture[t].prop; + const val = furniture.props ? furniture.props[prop] : undefined; + + if (val == null) continue; + + const canvas = document.createElement('canvas'); + canvas.height = 1024; + canvas.width = 1024; + + child.material = new THREE.MeshLambertMaterial({ + emissive: 0x111111, + side: THREE.DoubleSide, + alphaTest: 0.5, + }); + + const img = new Image(); + img.crossOrigin = 'anonymous'; + img.onload = () => { + const uvInfo = def.texture[t].uv; + + const ctx = canvas.getContext('2d'); + ctx.drawImage(img, + 0, 0, img.width, img.height, + uvInfo.x, uvInfo.y, uvInfo.width, uvInfo.height); + + const texture = new THREE.Texture(canvas); + texture.wrapS = THREE.RepeatWrapping; + texture.wrapT = THREE.RepeatWrapping; + texture.anisotropy = 16; + texture.flipY = false; + + (child.material as THREE.MeshLambertMaterial).map = texture; + (child.material as THREE.MeshLambertMaterial).needsUpdate = true; + (child.material as THREE.MeshLambertMaterial).map.needsUpdate = true; + }; + img.src = val; + } + }); + } + + @autobind + private onmousemove(ev: MouseEvent) { + if (this.isTransformMode) return; + + const rect = (ev.target as HTMLElement).getBoundingClientRect(); + const x = ((ev.clientX - rect.left) / rect.width) * 2 - 1; + const y = -((ev.clientY - rect.top) / rect.height) * 2 + 1; + const pos = new THREE.Vector2(x, y); + + this.camera.updateMatrixWorld(); + + const raycaster = new THREE.Raycaster(); + raycaster.setFromCamera(pos, this.camera); + + const intersects = raycaster.intersectObjects(this.objects, true); + + for (const object of this.objects) { + if (this.isSelectedObject(object)) continue; + object.traverse(child => { + if (child instanceof THREE.Mesh) { + (child.material as THREE.MeshStandardMaterial).emissive.setHex(0x000000); + } + }); + } + + if (intersects.length > 0) { + const intersected = this.getRoot(intersects[0].object); + if (this.isSelectedObject(intersected)) return; + intersected.traverse(child => { + if (child instanceof THREE.Mesh) { + (child.material as THREE.MeshStandardMaterial).emissive.setHex(0x191919); + } + }); + } + } + + @autobind + private onmousedown(ev: MouseEvent) { + if (this.isTransformMode) return; + if (ev.target !== this.canvas || ev.button !== 0) return; + + const rect = (ev.target as HTMLElement).getBoundingClientRect(); + const x = ((ev.clientX - rect.left) / rect.width) * 2 - 1; + const y = -((ev.clientY - rect.top) / rect.height) * 2 + 1; + const pos = new THREE.Vector2(x, y); + + this.camera.updateMatrixWorld(); + + const raycaster = new THREE.Raycaster(); + raycaster.setFromCamera(pos, this.camera); + + const intersects = raycaster.intersectObjects(this.objects, true); + + for (const object of this.objects) { + object.traverse(child => { + if (child instanceof THREE.Mesh) { + (child.material as THREE.MeshStandardMaterial).emissive.setHex(0x000000); + } + }); + } + + if (intersects.length > 0) { + const selectedObj = this.getRoot(intersects[0].object); + this.selectFurniture(selectedObj); + } else { + this.selectedObject = null; + this.onChangeSelect(null); + } + } + + @autobind + private getRoot(obj: THREE.Object3D): THREE.Object3D { + let found = false; + let x = obj.parent; + while (!found) { + if (x.parent.parent == null) { + found = true; + } else { + x = x.parent; + } + } + return x; + } + + @autobind + private isSelectedObject(obj: THREE.Object3D): boolean { + if (this.selectedObject == null) { + return false; + } else { + return obj.name === this.selectedObject.name; + } + } + + @autobind + private selectFurniture(obj: THREE.Object3D) { + this.selectedObject = obj; + this.onChangeSelect(obj); + obj.traverse(child => { + if (child instanceof THREE.Mesh) { + (child.material as THREE.MeshStandardMaterial).emissive.setHex(0xff0000); + } + }); + } + + /** + * 家具の移動/回転モードにします + * @param type 移動か回転か + */ + @autobind + public enterTransformMode(type: 'translate' | 'rotate') { + this.isTransformMode = true; + this.furnitureControl.setMode(type); + this.furnitureControl.attach(this.selectedObject); + this.controls.enableRotate = false; + } + + /** + * 家具の移動/回転モードを終了します + */ + @autobind + public exitTransformMode() { + this.isTransformMode = false; + this.furnitureControl.detach(); + this.controls.enableRotate = true; + } + + /** + * 家具プロパティを更新します + * @param key プロパティ名 + * @param value 値 + */ + @autobind + public updateProp(key: string, value: any) { + const furniture = this.furnitures.find(furniture => furniture.id === this.selectedObject.name); + if (furniture.props == null) furniture.props = {}; + furniture.props[key] = value; + this.applyCustomColor(this.selectedObject); + this.applyCustomTexture(this.selectedObject); + } + + /** + * 部屋に家具を追加します + * @param type 家具の種類 + */ + @autobind + public addFurniture(type: string) { + const furniture = { + id: uuid(), + type: type, + position: { + x: 0, + y: 0, + z: 0, + }, + rotation: { + x: 0, + y: 0, + z: 0, + }, + }; + + this.furnitures.push(furniture); + + this.loadFurniture(furniture).then(obj => { + this.scene.add(obj.scene); + this.objects.push(obj.scene); + }); + } + + /** + * 現在選択されている家具を部屋から削除します + */ + @autobind + public removeFurniture() { + this.exitTransformMode(); + const obj = this.selectedObject; + this.scene.remove(obj); + this.objects = this.objects.filter(object => object.name !== obj.name); + this.furnitures = this.furnitures.filter(furniture => furniture.id !== obj.name); + this.selectedObject = null; + this.onChangeSelect(null); + } + + /** + * 全ての家具を部屋から削除します + */ + @autobind + public removeAllFurnitures() { + this.exitTransformMode(); + for (const obj of this.objects) { + this.scene.remove(obj); + } + this.objects = []; + this.furnitures = []; + this.selectedObject = null; + this.onChangeSelect(null); + } + + /** + * 部屋の床の色を変更します + * @param color 色 + */ + @autobind + public updateCarpetColor(color: string) { + this.roomInfo.carpetColor = color; + this.applyCarpetColor(); + } + + /** + * 部屋の種類を変更します + * @param type 種類 + */ + @autobind + public changeRoomType(type: string) { + this.roomInfo.roomType = type; + this.scene.remove(this.roomObj); + this.loadRoom(); + } + + /** + * 部屋データを取得します + */ + @autobind + public getRoomInfo() { + for (const obj of this.objects) { + const furniture = this.furnitures.find(f => f.id === obj.name); + furniture.position.x = obj.position.x; + furniture.position.y = obj.position.y; + furniture.position.z = obj.position.z; + furniture.rotation.x = obj.rotation.x; + furniture.rotation.y = obj.rotation.y; + furniture.rotation.z = obj.rotation.z; + } + + return this.roomInfo; + } + + /** + * 選択されている家具を取得します + */ + @autobind + public getSelectedObject() { + return this.selectedObject; + } + + @autobind + public findFurnitureById(id: string) { + return this.furnitures.find(furniture => furniture.id === id); + } + + /** + * レンダリングを終了します + */ + @autobind + public destroy() { + // Stop render loop + window.cancelAnimationFrame(this.renderFrameRequestId); + + this.controls.dispose(); + this.scene.dispose(); + } +} diff --git a/src/client/scripts/scroll.ts b/packages/client/src/scripts/scroll.ts similarity index 100% rename from src/client/scripts/scroll.ts rename to packages/client/src/scripts/scroll.ts diff --git a/packages/client/src/scripts/search.ts b/packages/client/src/scripts/search.ts new file mode 100644 index 000000000..b28cccfab --- /dev/null +++ b/packages/client/src/scripts/search.ts @@ -0,0 +1,64 @@ +import * as os from '@/os'; +import { i18n } from '@/i18n'; +import { router } from '@/router'; + +export async function search() { + const { canceled, result: query } = await os.dialog({ + title: i18n.locale.search, + input: true + }); + if (canceled || query == null || query === '') return; + + const q = query.trim(); + + if (q.startsWith('@') && !q.includes(' ')) { + router.push(`/${q}`); + return; + } + + if (q.startsWith('#')) { + router.push(`/tags/${encodeURIComponent(q.substr(1))}`); + return; + } + + // like 2018/03/12 + if (/^[0-9]{4}\/[0-9]{2}\/[0-9]{2}/.test(q.replace(/-/g, '/'))) { + const date = new Date(q.replace(/-/g, '/')); + + // 日付しか指定されてない場合、例えば 2018/03/12 ならユーザーは + // 2018/03/12 のコンテンツを「含む」結果になることを期待するはずなので + // 23時間59分進める(そのままだと 2018/03/12 00:00:00 「まで」の + // 結果になってしまい、2018/03/12 のコンテンツは含まれない) + if (q.replace(/-/g, '/').match(/^[0-9]{4}\/[0-9]{2}\/[0-9]{2}$/)) { + date.setHours(23, 59, 59, 999); + } + + // TODO + //v.$root.$emit('warp', date); + os.dialog({ + icon: 'fas fa-history', + iconOnly: true, autoClose: true + }); + return; + } + + if (q.startsWith('https://')) { + const promise = os.api('ap/show', { + uri: q + }); + + os.promiseDialog(promise, null, null, i18n.locale.fetchingAsApObject); + + const res = await promise; + + if (res.type === 'User') { + router.push(`/@${res.object.username}@${res.object.host}`); + } else if (res.type === 'Note') { + router.push(`/notes/${res.object.id}`); + } + + return; + } + + router.push(`/search?q=${encodeURIComponent(q)}`); +} diff --git a/packages/client/src/scripts/select-file.ts b/packages/client/src/scripts/select-file.ts new file mode 100644 index 000000000..5fbc545b2 --- /dev/null +++ b/packages/client/src/scripts/select-file.ts @@ -0,0 +1,89 @@ +import * as os from '@/os'; +import { i18n } from '@/i18n'; +import { defaultStore } from '@/store'; + +export function selectFile(src: any, label: string | null, multiple = false) { + return new Promise((res, rej) => { + const chooseFileFromPc = () => { + const input = document.createElement('input'); + input.type = 'file'; + input.multiple = multiple; + input.onchange = () => { + const promises = Array.from(input.files).map(file => os.upload(file, defaultStore.state.uploadFolder)); + + Promise.all(promises).then(driveFiles => { + res(multiple ? driveFiles : driveFiles[0]); + }).catch(e => { + os.dialog({ + type: 'error', + text: e + }); + }); + + // 一応廃棄 + (window as any).__misskey_input_ref__ = null; + }; + + // https://qiita.com/fukasawah/items/b9dc732d95d99551013d + // iOS Safari で正常に動かす為のおまじない + (window as any).__misskey_input_ref__ = input; + + input.click(); + }; + + const chooseFileFromDrive = () => { + os.selectDriveFile(multiple).then(files => { + res(files); + }); + }; + + const chooseFileFromUrl = () => { + os.dialog({ + title: i18n.locale.uploadFromUrl, + input: { + placeholder: i18n.locale.uploadFromUrlDescription + } + }).then(({ canceled, result: url }) => { + if (canceled) return; + + const marker = Math.random().toString(); // TODO: UUIDとか使う + + const connection = os.stream.useChannel('main'); + connection.on('urlUploadFinished', data => { + if (data.marker === marker) { + res(multiple ? [data.file] : data.file); + connection.dispose(); + } + }); + + os.api('drive/files/upload-from-url', { + url: url, + folderId: defaultStore.state.uploadFolder, + marker + }); + + os.dialog({ + title: i18n.locale.uploadFromUrlRequested, + text: i18n.locale.uploadFromUrlMayTakeTime + }); + }); + }; + + os.popupMenu([label ? { + text: label, + type: 'label' + } : undefined, { + text: i18n.locale.upload, + icon: 'fas fa-upload', + action: chooseFileFromPc + }, { + text: i18n.locale.fromDrive, + icon: 'fas fa-cloud', + action: chooseFileFromDrive + }, { + text: i18n.locale.fromUrl, + icon: 'fas fa-link', + action: chooseFileFromUrl + }], src); + }); +} diff --git a/packages/client/src/scripts/show-suspended-dialog.ts b/packages/client/src/scripts/show-suspended-dialog.ts new file mode 100644 index 000000000..3bc480003 --- /dev/null +++ b/packages/client/src/scripts/show-suspended-dialog.ts @@ -0,0 +1,10 @@ +import * as os from '@/os'; +import { i18n } from '@/i18n'; + +export function showSuspendedDialog() { + return os.dialog({ + type: 'error', + title: i18n.locale.yourAccountSuspendedTitle, + text: i18n.locale.yourAccountSuspendedDescription + }); +} diff --git a/packages/client/src/scripts/sound.ts b/packages/client/src/scripts/sound.ts new file mode 100644 index 000000000..2b8279b3d --- /dev/null +++ b/packages/client/src/scripts/sound.ts @@ -0,0 +1,34 @@ +import { ColdDeviceStorage } from '@/store'; + +const cache = new Map(); + +export function getAudio(file: string, useCache = true): HTMLAudioElement { + let audio: HTMLAudioElement; + if (useCache && cache.has(file)) { + audio = cache.get(file); + } else { + audio = new Audio(`/client-assets/sounds/${file}.mp3`); + if (useCache) cache.set(file, audio); + } + return audio; +} + +export function setVolume(audio: HTMLAudioElement, volume: number): HTMLAudioElement { + const masterVolume = ColdDeviceStorage.get('sound_masterVolume'); + audio.volume = masterVolume - ((1 - volume) * masterVolume); + return audio; +} + +export function play(type: string) { + const sound = ColdDeviceStorage.get('sound_' + type as any); + if (sound.type == null) return; + playFile(sound.type, sound.volume); +} + +export function playFile(file: string, volume: number) { + const masterVolume = ColdDeviceStorage.get('sound_masterVolume'); + if (masterVolume === 0) return; + + const audio = setVolume(getAudio(file), volume); + audio.play(); +} diff --git a/src/client/scripts/sticky-sidebar.ts b/packages/client/src/scripts/sticky-sidebar.ts similarity index 100% rename from src/client/scripts/sticky-sidebar.ts rename to packages/client/src/scripts/sticky-sidebar.ts diff --git a/src/client/scripts/theme-editor.ts b/packages/client/src/scripts/theme-editor.ts similarity index 100% rename from src/client/scripts/theme-editor.ts rename to packages/client/src/scripts/theme-editor.ts diff --git a/packages/client/src/scripts/theme.ts b/packages/client/src/scripts/theme.ts new file mode 100644 index 000000000..3b7f003d0 --- /dev/null +++ b/packages/client/src/scripts/theme.ts @@ -0,0 +1,127 @@ +import { globalEvents } from '@/events'; +import * as tinycolor from 'tinycolor2'; + +export type Theme = { + id: string; + name: string; + author: string; + desc?: string; + base?: 'dark' | 'light'; + props: Record; +}; + +export const lightTheme: Theme = require('@/themes/_light.json5'); +export const darkTheme: Theme = require('@/themes/_dark.json5'); + +export const themeProps = Object.keys(lightTheme.props).filter(key => !key.startsWith('X')); + +export const builtinThemes = [ + require('@/themes/l-light.json5'), + require('@/themes/l-apricot.json5'), + require('@/themes/l-rainy.json5'), + require('@/themes/l-vivid.json5'), + require('@/themes/l-sushi.json5'), + + require('@/themes/d-dark.json5'), + require('@/themes/d-persimmon.json5'), + require('@/themes/d-astro.json5'), + require('@/themes/d-future.json5'), + require('@/themes/d-botanical.json5'), + require('@/themes/d-pumpkin.json5'), + require('@/themes/d-black.json5'), +] as Theme[]; + +let timeout = null; + +export function applyTheme(theme: Theme, persist = true) { + if (timeout) clearTimeout(timeout); + + document.documentElement.classList.add('_themeChanging_'); + + timeout = setTimeout(() => { + document.documentElement.classList.remove('_themeChanging_'); + }, 1000); + + // Deep copy + const _theme = JSON.parse(JSON.stringify(theme)); + + if (_theme.base) { + const base = [lightTheme, darkTheme].find(x => x.id === _theme.base); + _theme.props = Object.assign({}, base.props, _theme.props); + } + + const props = compile(_theme); + + for (const tag of document.head.children) { + if (tag.tagName === 'META' && tag.getAttribute('name') === 'theme-color') { + tag.setAttribute('content', props['html']); + break; + } + } + + for (const [k, v] of Object.entries(props)) { + document.documentElement.style.setProperty(`--${k}`, v.toString()); + } + + if (persist) { + localStorage.setItem('theme', JSON.stringify(props)); + } + + // 色計算など再度行えるようにクライアント全体に通知 + globalEvents.emit('themeChanged'); +} + +function compile(theme: Theme): Record { + function getColor(val: string): tinycolor.Instance { + // ref (prop) + if (val[0] === '@') { + return getColor(theme.props[val.substr(1)]); + } + + // ref (const) + else if (val[0] === '$') { + return getColor(theme.props[val]); + } + + // func + else if (val[0] === ':') { + const parts = val.split('<'); + const func = parts.shift().substr(1); + const arg = parseFloat(parts.shift()); + const color = getColor(parts.join('<')); + + switch (func) { + case 'darken': return color.darken(arg); + case 'lighten': return color.lighten(arg); + case 'alpha': return color.setAlpha(arg); + case 'hue': return color.spin(arg); + case 'saturate': return color.saturate(arg); + } + } + + // other case + return tinycolor(val); + } + + const props = {}; + + for (const [k, v] of Object.entries(theme.props)) { + if (k.startsWith('$')) continue; // ignore const + + props[k] = v.startsWith('"') ? v.replace(/^"\s*/, '') : genValue(getColor(v)); + } + + return props; +} + +function genValue(c: tinycolor.Instance): string { + return c.toRgbString(); +} + +export function validateTheme(theme: Record): boolean { + if (theme.id == null || typeof theme.id !== 'string') return false; + if (theme.name == null || typeof theme.name !== 'string') return false; + if (theme.base == null || !['light', 'dark'].includes(theme.base)) return false; + if (theme.props == null || typeof theme.props !== 'object') return false; + return true; +} diff --git a/packages/client/src/scripts/time.ts b/packages/client/src/scripts/time.ts new file mode 100644 index 000000000..34e8b6b17 --- /dev/null +++ b/packages/client/src/scripts/time.ts @@ -0,0 +1,39 @@ +const dateTimeIntervals = { + 'day': 86400000, + 'hour': 3600000, + 'ms': 1, +}; + +export function dateUTC(time: number[]): Date { + const d = time.length === 2 ? Date.UTC(time[0], time[1]) + : time.length === 3 ? Date.UTC(time[0], time[1], time[2]) + : time.length === 4 ? Date.UTC(time[0], time[1], time[2], time[3]) + : time.length === 5 ? Date.UTC(time[0], time[1], time[2], time[3], time[4]) + : time.length === 6 ? Date.UTC(time[0], time[1], time[2], time[3], time[4], time[5]) + : time.length === 7 ? Date.UTC(time[0], time[1], time[2], time[3], time[4], time[5], time[6]) + : null; + + if (!d) throw 'wrong number of arguments'; + + return new Date(d); +} + +export function isTimeSame(a: Date, b: Date): boolean { + return a.getTime() === b.getTime(); +} + +export function isTimeBefore(a: Date, b: Date): boolean { + return (a.getTime() - b.getTime()) < 0; +} + +export function isTimeAfter(a: Date, b: Date): boolean { + return (a.getTime() - b.getTime()) > 0; +} + +export function addTime(x: Date, value: number, span: keyof typeof dateTimeIntervals = 'ms'): Date { + return new Date(x.getTime() + (value * dateTimeIntervals[span])); +} + +export function subtractTime(x: Date, value: number, span: keyof typeof dateTimeIntervals = 'ms'): Date { + return new Date(x.getTime() - (value * dateTimeIntervals[span])); +} diff --git a/src/misc/twemoji-base.ts b/packages/client/src/scripts/twemoji-base.ts similarity index 100% rename from src/misc/twemoji-base.ts rename to packages/client/src/scripts/twemoji-base.ts diff --git a/packages/client/src/scripts/unison-reload.ts b/packages/client/src/scripts/unison-reload.ts new file mode 100644 index 000000000..59af584c1 --- /dev/null +++ b/packages/client/src/scripts/unison-reload.ts @@ -0,0 +1,15 @@ +// SafariがBroadcastChannel未実装なのでライブラリを使う +import { BroadcastChannel } from 'broadcast-channel'; + +export const reloadChannel = new BroadcastChannel('reload'); + +// BroadcastChannelを用いて、クライアントが一斉にreloadするようにします。 +export function unisonReload(path?: string) { + if (path !== undefined) { + reloadChannel.postMessage(path); + location.href = path; + } else { + reloadChannel.postMessage(null); + location.reload(); + } +} diff --git a/src/prelude/url.ts b/packages/client/src/scripts/url.ts similarity index 100% rename from src/prelude/url.ts rename to packages/client/src/scripts/url.ts diff --git a/packages/client/src/scripts/use-tooltip.ts b/packages/client/src/scripts/use-tooltip.ts new file mode 100644 index 000000000..2c0c36400 --- /dev/null +++ b/packages/client/src/scripts/use-tooltip.ts @@ -0,0 +1,44 @@ +import { Ref, ref } from 'vue'; + +export function useTooltip(onShow: (showing: Ref) => void) { + let isHovering = false; + let timeoutId: number; + + let changeShowingState: (() => void) | null; + + const open = () => { + close(); + if (!isHovering) return; + + const showing = ref(true); + onShow(showing); + changeShowingState = () => { + showing.value = false; + }; + }; + + const close = () => { + if (changeShowingState != null) { + changeShowingState(); + changeShowingState = null; + } + }; + + const onMouseover = () => { + if (isHovering) return; + isHovering = true; + timeoutId = window.setTimeout(open, 300); + }; + + const onMouseleave = () => { + if (!isHovering) return; + isHovering = false; + window.clearTimeout(timeoutId); + close(); + }; + + return { + onMouseover, + onMouseleave, + }; +} diff --git a/packages/client/src/store.ts b/packages/client/src/store.ts new file mode 100644 index 000000000..955d94a07 --- /dev/null +++ b/packages/client/src/store.ts @@ -0,0 +1,318 @@ +import { markRaw, ref } from 'vue'; +import { Storage } from './pizzax'; +import { Theme } from './scripts/theme'; + +export const postFormActions = []; +export const userActions = []; +export const noteActions = []; +export const noteViewInterruptors = []; +export const notePostInterruptors = []; + +// TODO: それぞれいちいちwhereとかdefaultというキーを付けなきゃいけないの冗長なのでなんとかする(ただ型定義が面倒になりそう) +// あと、現行の定義の仕方なら「whereが何であるかに関わらずキー名の重複不可」という制約を付けられるメリットもあるからそのメリットを引き継ぐ方法も考えないといけない +export const defaultStore = markRaw(new Storage('base', { + tutorial: { + where: 'account', + default: 0 + }, + keepCw: { + where: 'account', + default: false + }, + showFullAcct: { + where: 'account', + default: false + }, + rememberNoteVisibility: { + where: 'account', + default: false + }, + defaultNoteVisibility: { + where: 'account', + default: 'public' + }, + defaultNoteLocalOnly: { + where: 'account', + default: false + }, + uploadFolder: { + where: 'account', + default: null as string | null + }, + pastedFileName: { + where: 'account', + default: 'yyyy-MM-dd HH-mm-ss [{{number}}]' + }, + memo: { + where: 'account', + default: null + }, + reactions: { + where: 'account', + default: ['👍', '❤️', '😆', '🤔', '😮', '🎉', '💢', '😥', '😇', '🍮'] + }, + mutedWords: { + where: 'account', + default: [] + }, + mutedAds: { + where: 'account', + default: [] as string[] + }, + + menu: { + where: 'deviceAccount', + default: [ + 'notifications', + 'messaging', + 'drive', + 'followRequests', + '-', + 'gallery', + 'featured', + 'explore', + 'announcements', + 'search', + '-', + 'ui', + ] + }, + visibility: { + where: 'deviceAccount', + default: 'public' as 'public' | 'home' | 'followers' | 'specified' + }, + localOnly: { + where: 'deviceAccount', + default: false + }, + widgets: { + where: 'deviceAccount', + default: [] as { + name: string; + id: string; + place: string | null; + data: Record; + }[] + }, + tl: { + where: 'deviceAccount', + default: { + src: 'home', + arg: null + } + }, + + serverDisconnectedBehavior: { + where: 'device', + default: 'quiet' as 'quiet' | 'reload' | 'dialog' + }, + nsfw: { + where: 'device', + default: 'respect' as 'respect' | 'force' | 'ignore' + }, + animation: { + where: 'device', + default: true + }, + animatedMfm: { + where: 'device', + default: true + }, + loadRawImages: { + where: 'device', + default: false + }, + imageNewTab: { + where: 'device', + default: false + }, + disableShowingAnimatedImages: { + where: 'device', + default: false + }, + disablePagesScript: { + where: 'device', + default: false + }, + useOsNativeEmojis: { + where: 'device', + default: false + }, + useBlurEffectForModal: { + where: 'device', + default: true + }, + useBlurEffect: { + where: 'device', + default: true + }, + showFixedPostForm: { + where: 'device', + default: false + }, + enableInfiniteScroll: { + where: 'device', + default: true + }, + useReactionPickerForContextMenu: { + where: 'device', + default: true + }, + showGapBetweenNotesInTimeline: { + where: 'device', + default: false + }, + darkMode: { + where: 'device', + default: false + }, + instanceTicker: { + where: 'device', + default: 'remote' as 'none' | 'remote' | 'always' + }, + reactionPickerWidth: { + where: 'device', + default: 1 + }, + reactionPickerHeight: { + where: 'device', + default: 1 + }, + recentlyUsedEmojis: { + where: 'device', + default: [] as string[] + }, + recentlyUsedUsers: { + where: 'device', + default: [] as string[] + }, + defaultSideView: { + where: 'device', + default: false + }, + menuDisplay: { + where: 'device', + default: 'sideFull' as 'sideFull' | 'sideIcon' | 'top' + }, + reportError: { + where: 'device', + default: false + }, + squareAvatars: { + where: 'device', + default: false + }, + postFormWithHashtags: { + where: 'device', + default: false + }, + postFormHashtags: { + where: 'device', + default: '' + }, + aiChanMode: { + where: 'device', + default: false + }, +})); + +// TODO: 他のタブと永続化されたstateを同期 + +const PREFIX = 'miux:'; + +type Plugin = { + id: string; + name: string; + active: boolean; + configData: Record; + token: string; + ast: any[]; +}; + +/** + * 常にメモリにロードしておく必要がないような設定情報を保管するストレージ(非リアクティブ) + */ +export class ColdDeviceStorage { + public static default = { + lightTheme: require('@/themes/l-light.json5') as Theme, + darkTheme: require('@/themes/d-dark.json5') as Theme, + syncDeviceDarkMode: true, + chatOpenBehavior: 'page' as 'page' | 'window' | 'popout', + plugins: [] as Plugin[], + mediaVolume: 0.5, + sound_masterVolume: 0.3, + sound_note: { type: 'syuilo/down', volume: 1 }, + sound_noteMy: { type: 'syuilo/up', volume: 1 }, + sound_notification: { type: 'syuilo/pope2', volume: 1 }, + sound_chat: { type: 'syuilo/pope1', volume: 1 }, + sound_chatBg: { type: 'syuilo/waon', volume: 1 }, + sound_antenna: { type: 'syuilo/triple', volume: 1 }, + sound_channel: { type: 'syuilo/square-pico', volume: 1 }, + sound_reversiPutBlack: { type: 'syuilo/kick', volume: 0.3 }, + sound_reversiPutWhite: { type: 'syuilo/snare', volume: 0.3 }, + roomGraphicsQuality: 'medium' as 'cheep' | 'low' | 'medium' | 'high' | 'ultra', + roomUseOrthographicCamera: true, + }; + + public static watchers = []; + + public static get(key: T): typeof ColdDeviceStorage.default[T] { + // TODO: indexedDBにする + // ただしその際はnullチェックではなくキー存在チェックにしないとダメ + // (indexedDBはnullを保存できるため、ユーザーが意図してnullを格納した可能性がある) + const value = localStorage.getItem(PREFIX + key); + if (value == null) { + return ColdDeviceStorage.default[key]; + } else { + return JSON.parse(value); + } + } + + public static set(key: T, value: typeof ColdDeviceStorage.default[T]): void { + localStorage.setItem(PREFIX + key, JSON.stringify(value)); + + for (const watcher of this.watchers) { + if (watcher.key === key) watcher.callback(value); + } + } + + public static watch(key, callback) { + this.watchers.push({ key, callback }); + } + + // TODO: VueのcustomRef使うと良い感じになるかも + public static ref(key: T) { + const v = ColdDeviceStorage.get(key); + const r = ref(v); + // TODO: このままではwatcherがリークするので開放する方法を考える + this.watch(key, v => { + r.value = v; + }); + return r; + } + + /** + * 特定のキーの、簡易的なgetter/setterを作ります + * 主にvue場で設定コントロールのmodelとして使う用 + */ + public static makeGetterSetter(key: K) { + // TODO: VueのcustomRef使うと良い感じになるかも + const valueRef = ColdDeviceStorage.ref(key); + return { + get: () => { + return valueRef.value; + }, + set: (value: unknown) => { + const val = value; + ColdDeviceStorage.set(key, val); + } + }; + } +} + +// このファイルに書きたくないけどここに書かないと何故かVeturが認識しない +declare module '@vue/runtime-core' { + interface ComponentCustomProperties { + $store: typeof defaultStore; + } +} diff --git a/packages/client/src/style.scss b/packages/client/src/style.scss new file mode 100644 index 000000000..951d5a14f --- /dev/null +++ b/packages/client/src/style.scss @@ -0,0 +1,562 @@ +@charset "utf-8"; + +:root { + --radius: 12px; + --marginFull: 16px; + --marginHalf: 10px; + + --margin: var(--marginFull); + + @media (max-width: 500px) { + --margin: var(--marginHalf); + } + + //--ad: rgb(255 169 0 / 10%); +} + +::selection { + color: #fff; + background-color: var(--accent); +} + +html { + touch-action: manipulation; + background-color: var(--bg); + background-attachment: fixed; + background-size: cover; + background-position: center; + color: var(--fg); + overflow: auto; + overflow-wrap: break-word; + font-family: "BIZ UDGothic", Roboto, HelveticaNeue, Arial, sans-serif; + line-height: 1.35; + text-size-adjust: 100%; + tab-size: 2; + + &, * { + scrollbar-color: var(--scrollbarHandle) inherit; + scrollbar-width: thin; + + &:hover { + scrollbar-color: var(--scrollbarHandleHover) inherit; + } + + &:active { + scrollbar-color: var(--accent) inherit; + } + + &::-webkit-scrollbar { + width: 6px; + height: 6px; + } + + &::-webkit-scrollbar-track { + background: inherit; + } + + &::-webkit-scrollbar-thumb { + background: var(--scrollbarHandle); + + &:hover { + background: var(--scrollbarHandleHover); + } + + &:active { + background: var(--accent); + } + } + } + + &.f-small { + font-size: 0.9em; + } + + &.f-large { + font-size: 1.1em; + } + + &.f-veryLarge { + font-size: 1.2em; + } + + &.useSystemFont { + font-family: sans-serif; + } +} + +html._themeChanging_ { + &, * { + transition: background 1s ease, border 1s ease !important; + } +} + +html, body { + margin: 0; + padding: 0; + scroll-behavior: smooth; +} + +a { + text-decoration: none; + cursor: pointer; + color: inherit; + tap-highlight-color: transparent; + -webkit-tap-highlight-color: transparent; + + &:hover { + text-decoration: underline; + } +} + +textarea, input { + tap-highlight-color: transparent; + -webkit-tap-highlight-color: transparent; +} + +optgroup, option { + background: var(--panel); + color: var(--fg); +} + +hr { + margin: var(--margin) 0 var(--margin) 0; + border: none; + height: 1px; + background: var(--divider); +} + +._noSelect { + user-select: none; + -webkit-user-select: none; + -webkit-touch-callout: none; +} + +._ghost { + &, * { + @extend ._noSelect; + pointer-events: none; + } +} + +._modalBg { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: var(--modalBg); + -webkit-backdrop-filter: var(--modalBgFilter); + backdrop-filter: var(--modalBgFilter); +} + +._shadow { + box-shadow: 0px 4px 32px var(--shadow) !important; +} + +._button { + appearance: none; + display: inline-block; + padding: 0; + margin: 0; // for Safari + background: none; + border: none; + cursor: pointer; + color: inherit; + touch-action: manipulation; + tap-highlight-color: transparent; + -webkit-tap-highlight-color: transparent; + font-size: 1em; + font-family: inherit; + line-height: inherit; + + &, * { + @extend ._noSelect; + } + + * { + pointer-events: none; + } + + &:focus-visible { + outline: none; + } + + &:disabled { + opacity: 0.5; + cursor: default; + } +} + +._buttonPrimary { + @extend ._button; + color: var(--fgOnAccent); + background: var(--accent); + + &:not(:disabled):hover { + background: var(--X8); + } + + &:not(:disabled):active { + background: var(--X9); + } +} + +._buttonGradate { + @extend ._buttonPrimary; + color: var(--fgOnAccent); + background: linear-gradient(90deg, var(--buttonGradateA), var(--buttonGradateB)); + + &:not(:disabled):hover { + background: linear-gradient(90deg, var(--X8), var(--X8)); + } + + &:not(:disabled):active { + background: linear-gradient(90deg, var(--X8), var(--X8)); + } +} + +._help { + color: var(--accent); + cursor: help +} + +._textButton { + @extend ._button; + color: var(--accent); + + &:not(:disabled):hover { + text-decoration: underline; + } +} + +._inputs { + display: flex; + margin: 32px 0; + + &:first-child { + margin-top: 8px; + } + + &:last-child { + margin-bottom: 8px; + } + + > * { + flex: 1; + margin: 0 !important; + + &:not(:first-child) { + margin-left: 8px !important; + } + + &:not(:last-child) { + margin-right: 8px !important; + } + } +} + +._panel { + background: var(--panel); + border-radius: var(--radius); + overflow: clip; +} + +._block { + @extend ._panel; + + & + ._block { + margin-top: var(--margin); + } +} + +._gap { + margin: var(--margin) 0; +} + +// TODO: 廃止 +._card { + @extend ._panel; + + // TODO: _cardTitle に + > ._title { + margin: 0; + padding: 22px 32px; + font-size: 1em; + border-bottom: solid 1px var(--panelHeaderDivider); + font-weight: bold; + background: var(--panelHeaderBg); + color: var(--panelHeaderFg); + + @media (max-width: 500px) { + padding: 16px; + font-size: 1em; + } + } + + // TODO: _cardContent に + > ._content { + padding: 32px; + + @media (max-width: 500px) { + padding: 16px; + } + + &._noPad { + padding: 0 !important; + } + + & + ._content { + border-top: solid 0.5px var(--divider); + } + } + + // TODO: _cardFooter に + > ._footer { + border-top: solid 0.5px var(--divider); + padding: 24px 32px; + + @media (max-width: 500px) { + padding: 16px; + } + } +} + +._borderButton { + @extend ._button; + display: block; + width: 100%; + padding: 10px; + box-sizing: border-box; + text-align: center; + border: solid 0.5px var(--divider); + border-radius: var(--radius); + + &:active { + border-color: var(--accent); + } +} + +._window { + background: var(--panel); + border-radius: var(--radius); + contain: content; +} + +._popup { + background: var(--popup); + border-radius: var(--radius); + contain: layout; // ふき出しがボックスから飛び出て表示されるようなデザインをする場合もあるので paint は contain することができない +} + +// TODO: 廃止 +._monolithic_ { + ._section:not(:empty) { + box-sizing: border-box; + padding: var(--root-margin, 32px); + + @media (max-width: 500px) { + --root-margin: 10px; + } + + & + ._section:not(:empty) { + border-top: solid 0.5px var(--divider); + } + } +} + +._narrow_ ._card { + > ._title { + padding: 16px; + font-size: 1em; + } + + > ._content { + padding: 16px; + } + + > ._footer { + padding: 16px; + } +} + +._acrylic { + background: var(--acrylicPanel); + -webkit-backdrop-filter: var(--blur, blur(15px)); + backdrop-filter: var(--blur, blur(15px)); +} + +._inputSplit { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); + grid-gap: 8px; + margin: 1em 0; + + > * { + margin: 0 !important; + } +} + +._formBlock { + margin: 20px 0; +} + +._formRoot { + > ._formBlock:first-child { + margin-top: 0; + } + + > ._formBlock:last-child { + margin-bottom: 0; + } +} + +._table { + > ._row { + display: flex; + + &:not(:last-child) { + margin-bottom: 16px; + + @media (max-width: 500px) { + margin-bottom: 8px; + } + } + + > ._cell { + flex: 1; + + > ._label { + font-size: 80%; + opacity: 0.7; + + > ._icon { + margin-right: 4px; + display: none; + } + } + } + } +} + +._fullinfo { + padding: 64px 32px; + text-align: center; + + > img { + vertical-align: bottom; + height: 128px; + margin-bottom: 16px; + border-radius: 16px; + } +} + +._keyValue { + display: flex; + + > * { + flex: 1; + } +} + +._link { + color: var(--link); +} + +._caption { + font-size: 0.8em; + opacity: 0.7; +} + +._monospace { + font-family: Fira code, Fira Mono, Consolas, Menlo, Courier, monospace !important; +} + +._code { + @extend ._monospace; + background: #2d2d2d; + color: #ccc; + font-size: 14px; + line-height: 1.5; + padding: 5px; +} + +.prism-editor__textarea:focus { + outline: none; +} + +._zoom { + transition-duration: 0.5s, 0.5s; + transition-property: opacity, transform; + transition-timing-function: cubic-bezier(0,.5,.5,1); +} + +.zoom-enter-active, .zoom-leave-active { + transition: opacity 0.5s, transform 0.5s !important; +} +.zoom-enter-from, .zoom-leave-to { + opacity: 0; + transform: scale(0.9); +} + +@keyframes blink { + 0% { opacity: 1; transform: scale(1); } + 30% { opacity: 1; transform: scale(1); } + 90% { opacity: 0; transform: scale(0.5); } +} + +@keyframes tada { + from { + transform: scale3d(1, 1, 1); + } + + 10%, + 20% { + transform: scale3d(0.9, 0.9, 0.9) rotate3d(0, 0, 1, -3deg); + } + + 30%, + 50%, + 70%, + 90% { + transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg); + } + + 40%, + 60%, + 80% { + transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg); + } + + to { + transform: scale3d(1, 1, 1); + } +} + +._anime_bounce { + will-change: transform; + animation: bounce ease 0.7s; + animation-iteration-count: 1; + transform-origin: 50% 50%; +} +._anime_bounce_ready { + will-change: transform; + transform: scaleX(0.90) scaleY(0.90) ; +} +._anime_bounce_standBy { + transition: transform 0.1s ease; +} + +@keyframes bounce{ + 0% { + transform: scaleX(0.90) scaleY(0.90) ; + } + 19% { + transform: scaleX(1.10) scaleY(1.10) ; + } + 48% { + transform: scaleX(0.95) scaleY(0.95) ; + } + 100% { + transform: scaleX(1.00) scaleY(1.00) ; + } +} diff --git a/packages/client/src/sw/compose-notification.ts b/packages/client/src/sw/compose-notification.ts new file mode 100644 index 000000000..0aed9610e --- /dev/null +++ b/packages/client/src/sw/compose-notification.ts @@ -0,0 +1,103 @@ +/** + * Notification composer of Service Worker + */ +declare var self: ServiceWorkerGlobalScope; + +import { getNoteSummary } from '@/scripts/get-note-summary'; +import * as misskey from 'misskey-js'; + +function getUserName(user: misskey.entities.User): string { + return user.name || user.username; +} + +export default async function(type, data, i18n): Promise<[string, NotificationOptions] | null | undefined> { + if (!i18n) { + console.log('no i18n'); + return; + } + + switch (type) { + case 'driveFileCreated': // TODO (Server Side) + return [i18n.t('_notification.fileUploaded'), { + body: data.name, + icon: data.url + }]; + case 'notification': + switch (data.type) { + case 'mention': + return [i18n.t('_notification.youGotMention', { name: getUserName(data.user) }), { + body: getNoteSummary(data.note, i18n.locale), + icon: data.user.avatarUrl + }]; + + case 'reply': + return [i18n.t('_notification.youGotReply', { name: getUserName(data.user) }), { + body: getNoteSummary(data.note, i18n.locale), + icon: data.user.avatarUrl + }]; + + case 'renote': + return [i18n.t('_notification.youRenoted', { name: getUserName(data.user) }), { + body: getNoteSummary(data.note, i18n.locale), + icon: data.user.avatarUrl + }]; + + case 'quote': + return [i18n.t('_notification.youGotQuote', { name: getUserName(data.user) }), { + body: getNoteSummary(data.note, i18n.locale), + icon: data.user.avatarUrl + }]; + + case 'reaction': + return [`${data.reaction} ${getUserName(data.user)}`, { + body: getNoteSummary(data.note, i18n.locale), + icon: data.user.avatarUrl + }]; + + case 'pollVote': + return [i18n.t('_notification.youGotPoll', { name: getUserName(data.user) }), { + body: getNoteSummary(data.note, i18n.locale), + icon: data.user.avatarUrl + }]; + + case 'follow': + return [i18n.t('_notification.youWereFollowed'), { + body: getUserName(data.user), + icon: data.user.avatarUrl + }]; + + case 'receiveFollowRequest': + return [i18n.t('_notification.youReceivedFollowRequest'), { + body: getUserName(data.user), + icon: data.user.avatarUrl + }]; + + case 'followRequestAccepted': + return [i18n.t('_notification.yourFollowRequestAccepted'), { + body: getUserName(data.user), + icon: data.user.avatarUrl + }]; + + case 'groupInvited': + return [i18n.t('_notification.youWereInvitedToGroup'), { + body: data.group.name + }]; + + default: + return null; + } + case 'unreadMessagingMessage': + if (data.groupId === null) { + return [i18n.t('_notification.youGotMessagingMessageFromUser', { name: getUserName(data.user) }), { + icon: data.user.avatarUrl, + tag: `messaging:user:${data.user.id}` + }]; + } + return [i18n.t('_notification.youGotMessagingMessageFromGroup', { name: data.group.name }), { + icon: data.user.avatarUrl, + tag: `messaging:group:${data.group.id}` + }]; + default: + return null; + } +} diff --git a/packages/client/src/sw/sw.ts b/packages/client/src/sw/sw.ts new file mode 100644 index 000000000..68c650c77 --- /dev/null +++ b/packages/client/src/sw/sw.ts @@ -0,0 +1,123 @@ +/** + * Service Worker + */ +declare var self: ServiceWorkerGlobalScope; + +import { get, set } from 'idb-keyval'; +import composeNotification from '@/sw/compose-notification'; +import { I18n } from '@/scripts/i18n'; + +//#region Variables +const version = _VERSION_; +const cacheName = `mk-cache-${version}`; + +let lang: string; +let i18n: I18n; +let pushesPool: any[] = []; +//#endregion + +//#region Startup +get('lang').then(async prelang => { + if (!prelang) return; + lang = prelang; + return fetchLocale(); +}); +//#endregion + +//#region Lifecycle: Install +self.addEventListener('install', ev => { + self.skipWaiting(); +}); +//#endregion + +//#region Lifecycle: Activate +self.addEventListener('activate', ev => { + ev.waitUntil( + caches.keys() + .then(cacheNames => Promise.all( + cacheNames + .filter((v) => v !== cacheName) + .map(name => caches.delete(name)) + )) + .then(() => self.clients.claim()) + ); +}); +//#endregion + +//#region When: Fetching +self.addEventListener('fetch', ev => { + // Nothing to do +}); +//#endregion + +//#region When: Caught Notification +self.addEventListener('push', ev => { + // クライアント取得 + ev.waitUntil(self.clients.matchAll({ + includeUncontrolled: true + }).then(async clients => { + // クライアントがあったらストリームに接続しているということなので通知しない + if (clients.length != 0) return; + + const { type, body } = ev.data?.json(); + + // localeを読み込めておらずi18nがundefinedだった場合はpushesPoolにためておく + if (!i18n) return pushesPool.push({ type, body }); + + const n = await composeNotification(type, body, i18n); + if (n) return self.registration.showNotification(...n); + })); +}); +//#endregion + +//#region When: Caught a message from the client +self.addEventListener('message', ev => { + switch(ev.data) { + case 'clear': + return; // TODO + default: + break; + } + + if (typeof ev.data === 'object') { + // E.g. '[object Array]' → 'array' + const otype = Object.prototype.toString.call(ev.data).slice(8, -1).toLowerCase(); + + if (otype === 'object') { + if (ev.data.msg === 'initialize') { + lang = ev.data.lang; + set('lang', lang); + fetchLocale(); + } + } + } +}); +//#endregion + +//#region Function: (Re)Load i18n instance +async function fetchLocale() { + //#region localeファイルの読み込み + // Service Workerは何度も起動しそのたびにlocaleを読み込むので、CacheStorageを使う + const localeUrl = `/assets/locales/${lang}.${version}.json`; + let localeRes = await caches.match(localeUrl); + + if (!localeRes) { + localeRes = await fetch(localeUrl); + const clone = localeRes?.clone(); + if (!clone?.clone().ok) return; + + caches.open(cacheName).then(cache => cache.put(localeUrl, clone)); + } + + i18n = new I18n(await localeRes.json()); + //#endregion + + //#region i18nをきちんと読み込んだ後にやりたい処理 + for (const { type, body } of pushesPool) { + const n = await composeNotification(type, body, i18n); + if (n) self.registration.showNotification(...n); + } + pushesPool = []; + //#endregion +} +//#endregion diff --git a/src/client/symbols.ts b/packages/client/src/symbols.ts similarity index 100% rename from src/client/symbols.ts rename to packages/client/src/symbols.ts diff --git a/packages/client/src/theme-store.ts b/packages/client/src/theme-store.ts new file mode 100644 index 000000000..e7962e7e8 --- /dev/null +++ b/packages/client/src/theme-store.ts @@ -0,0 +1,34 @@ +import { api } from '@/os'; +import { $i } from '@/account'; +import { Theme } from './scripts/theme'; + +const lsCacheKey = $i ? `themes:${$i.id}` : ''; + +export function getThemes(): Theme[] { + return JSON.parse(localStorage.getItem(lsCacheKey) || '[]'); +} + +export async function fetchThemes(): Promise { + if ($i == null) return; + + try { + const themes = await api('i/registry/get', { scope: ['client'], key: 'themes' }); + localStorage.setItem(lsCacheKey, JSON.stringify(themes)); + } catch (e) { + if (e.code === 'NO_SUCH_KEY') return; + throw e; + } +} + +export async function addTheme(theme: Theme): Promise { + await fetchThemes(); + const themes = getThemes().concat(theme); + await api('i/registry/set', { scope: ['client'], key: 'themes', value: themes }); + localStorage.setItem(lsCacheKey, JSON.stringify(themes)); +} + +export async function removeTheme(theme: Theme): Promise { + const themes = getThemes().filter(t => t.id != theme.id); + await api('i/registry/set', { scope: ['client'], key: 'themes', value: themes }); + localStorage.setItem(lsCacheKey, JSON.stringify(themes)); +} diff --git a/src/client/themes/_dark.json5 b/packages/client/src/themes/_dark.json5 similarity index 100% rename from src/client/themes/_dark.json5 rename to packages/client/src/themes/_dark.json5 diff --git a/src/client/themes/_light.json5 b/packages/client/src/themes/_light.json5 similarity index 100% rename from src/client/themes/_light.json5 rename to packages/client/src/themes/_light.json5 diff --git a/src/client/themes/d-astro.json5 b/packages/client/src/themes/d-astro.json5 similarity index 100% rename from src/client/themes/d-astro.json5 rename to packages/client/src/themes/d-astro.json5 diff --git a/src/client/themes/d-black.json5 b/packages/client/src/themes/d-black.json5 similarity index 100% rename from src/client/themes/d-black.json5 rename to packages/client/src/themes/d-black.json5 diff --git a/src/client/themes/d-botanical.json5 b/packages/client/src/themes/d-botanical.json5 similarity index 100% rename from src/client/themes/d-botanical.json5 rename to packages/client/src/themes/d-botanical.json5 diff --git a/src/client/themes/d-dark.json5 b/packages/client/src/themes/d-dark.json5 similarity index 100% rename from src/client/themes/d-dark.json5 rename to packages/client/src/themes/d-dark.json5 diff --git a/src/client/themes/d-future.json5 b/packages/client/src/themes/d-future.json5 similarity index 100% rename from src/client/themes/d-future.json5 rename to packages/client/src/themes/d-future.json5 diff --git a/src/client/themes/d-persimmon.json5 b/packages/client/src/themes/d-persimmon.json5 similarity index 100% rename from src/client/themes/d-persimmon.json5 rename to packages/client/src/themes/d-persimmon.json5 diff --git a/src/client/themes/d-pumpkin.json5 b/packages/client/src/themes/d-pumpkin.json5 similarity index 100% rename from src/client/themes/d-pumpkin.json5 rename to packages/client/src/themes/d-pumpkin.json5 diff --git a/src/client/themes/l-apricot.json5 b/packages/client/src/themes/l-apricot.json5 similarity index 100% rename from src/client/themes/l-apricot.json5 rename to packages/client/src/themes/l-apricot.json5 diff --git a/src/client/themes/l-light.json5 b/packages/client/src/themes/l-light.json5 similarity index 100% rename from src/client/themes/l-light.json5 rename to packages/client/src/themes/l-light.json5 diff --git a/src/client/themes/l-rainy.json5 b/packages/client/src/themes/l-rainy.json5 similarity index 100% rename from src/client/themes/l-rainy.json5 rename to packages/client/src/themes/l-rainy.json5 diff --git a/src/client/themes/l-sushi.json5 b/packages/client/src/themes/l-sushi.json5 similarity index 100% rename from src/client/themes/l-sushi.json5 rename to packages/client/src/themes/l-sushi.json5 diff --git a/src/client/themes/l-vivid.json5 b/packages/client/src/themes/l-vivid.json5 similarity index 100% rename from src/client/themes/l-vivid.json5 rename to packages/client/src/themes/l-vivid.json5 diff --git a/packages/client/src/ui/_common_/common.vue b/packages/client/src/ui/_common_/common.vue new file mode 100644 index 000000000..59e26c837 --- /dev/null +++ b/packages/client/src/ui/_common_/common.vue @@ -0,0 +1,89 @@ + + + + + diff --git a/packages/client/src/ui/_common_/sidebar.vue b/packages/client/src/ui/_common_/sidebar.vue new file mode 100644 index 000000000..9bbf1b3e3 --- /dev/null +++ b/packages/client/src/ui/_common_/sidebar.vue @@ -0,0 +1,388 @@ + + + + + diff --git a/packages/client/src/ui/_common_/stream-indicator.vue b/packages/client/src/ui/_common_/stream-indicator.vue new file mode 100644 index 000000000..8b1b4b567 --- /dev/null +++ b/packages/client/src/ui/_common_/stream-indicator.vue @@ -0,0 +1,70 @@ + + + + + diff --git a/packages/client/src/ui/_common_/upload.vue b/packages/client/src/ui/_common_/upload.vue new file mode 100644 index 000000000..0ca353e4e --- /dev/null +++ b/packages/client/src/ui/_common_/upload.vue @@ -0,0 +1,134 @@ + + + + + diff --git a/packages/client/src/ui/chat/date-separated-list.vue b/packages/client/src/ui/chat/date-separated-list.vue new file mode 100644 index 000000000..b21e425ab --- /dev/null +++ b/packages/client/src/ui/chat/date-separated-list.vue @@ -0,0 +1,163 @@ + + + + + diff --git a/packages/client/src/ui/chat/header-clock.vue b/packages/client/src/ui/chat/header-clock.vue new file mode 100644 index 000000000..3488289c2 --- /dev/null +++ b/packages/client/src/ui/chat/header-clock.vue @@ -0,0 +1,62 @@ + + + + + diff --git a/packages/client/src/ui/chat/index.vue b/packages/client/src/ui/chat/index.vue new file mode 100644 index 000000000..e8d15b2cf --- /dev/null +++ b/packages/client/src/ui/chat/index.vue @@ -0,0 +1,467 @@ + + + + + diff --git a/packages/client/src/ui/chat/note-header.vue b/packages/client/src/ui/chat/note-header.vue new file mode 100644 index 000000000..f0c9adee3 --- /dev/null +++ b/packages/client/src/ui/chat/note-header.vue @@ -0,0 +1,107 @@ + + + + + diff --git a/packages/client/src/ui/chat/note-preview.vue b/packages/client/src/ui/chat/note-preview.vue new file mode 100644 index 000000000..2a08a3d7f --- /dev/null +++ b/packages/client/src/ui/chat/note-preview.vue @@ -0,0 +1,112 @@ + + + + + diff --git a/packages/client/src/ui/chat/note.sub.vue b/packages/client/src/ui/chat/note.sub.vue new file mode 100644 index 000000000..75d9d9808 --- /dev/null +++ b/packages/client/src/ui/chat/note.sub.vue @@ -0,0 +1,137 @@ + + + + + diff --git a/packages/client/src/ui/chat/note.vue b/packages/client/src/ui/chat/note.vue new file mode 100644 index 000000000..c0b5cebd9 --- /dev/null +++ b/packages/client/src/ui/chat/note.vue @@ -0,0 +1,1144 @@ + + + + + diff --git a/packages/client/src/ui/chat/notes.vue b/packages/client/src/ui/chat/notes.vue new file mode 100644 index 000000000..9103f717e --- /dev/null +++ b/packages/client/src/ui/chat/notes.vue @@ -0,0 +1,94 @@ + + + diff --git a/packages/client/src/ui/chat/pages/channel.vue b/packages/client/src/ui/chat/pages/channel.vue new file mode 100644 index 000000000..5152af20f --- /dev/null +++ b/packages/client/src/ui/chat/pages/channel.vue @@ -0,0 +1,259 @@ + + + + + diff --git a/packages/client/src/ui/chat/pages/timeline.vue b/packages/client/src/ui/chat/pages/timeline.vue new file mode 100644 index 000000000..f4dfdf891 --- /dev/null +++ b/packages/client/src/ui/chat/pages/timeline.vue @@ -0,0 +1,221 @@ + + + + + diff --git a/packages/client/src/ui/chat/post-form.vue b/packages/client/src/ui/chat/post-form.vue new file mode 100644 index 000000000..62aa3a6aa --- /dev/null +++ b/packages/client/src/ui/chat/post-form.vue @@ -0,0 +1,770 @@ + + + + + diff --git a/packages/client/src/widgets/button.vue b/packages/client/src/widgets/button.vue new file mode 100644 index 000000000..3417181d0 --- /dev/null +++ b/packages/client/src/widgets/button.vue @@ -0,0 +1,95 @@ + + + + + diff --git a/packages/client/src/widgets/calendar.vue b/packages/client/src/widgets/calendar.vue new file mode 100644 index 000000000..545072e87 --- /dev/null +++ b/packages/client/src/widgets/calendar.vue @@ -0,0 +1,204 @@ + + + + + diff --git a/packages/client/src/widgets/clock.vue b/packages/client/src/widgets/clock.vue new file mode 100644 index 000000000..da0cd65c9 --- /dev/null +++ b/packages/client/src/widgets/clock.vue @@ -0,0 +1,55 @@ + + + + + diff --git a/packages/client/src/widgets/define.ts b/packages/client/src/widgets/define.ts new file mode 100644 index 000000000..08a346d97 --- /dev/null +++ b/packages/client/src/widgets/define.ts @@ -0,0 +1,75 @@ +import { defineComponent } from 'vue'; +import { throttle } from 'throttle-debounce'; +import { Form } from '@/scripts/form'; +import * as os from '@/os'; + +export default function (data: { + name: string; + props?: () => T; +}) { + return defineComponent({ + props: { + widget: { + type: Object, + required: false + }, + settingCallback: { + required: false + } + }, + + emits: ['updateProps'], + + data() { + return { + props: this.widget ? JSON.parse(JSON.stringify(this.widget.data)) : {}, + save: throttle(3000, () => { + this.$emit('updateProps', this.props); + }), + }; + }, + + computed: { + id(): string { + return this.widget ? this.widget.id : null; + }, + }, + + created() { + this.mergeProps(); + + this.$watch('props', () => { + this.mergeProps(); + }, { deep: true }); + + if (this.settingCallback) this.settingCallback(this.setting); + }, + + methods: { + mergeProps() { + if (data.props) { + const defaultProps = data.props(); + for (const prop of Object.keys(defaultProps)) { + if (this.props.hasOwnProperty(prop)) continue; + this.props[prop] = defaultProps[prop].default; + } + } + }, + + async setting() { + const form = data.props(); + for (const item of Object.keys(form)) { + form[item].default = this.props[item]; + } + const { canceled, result } = await os.form(data.name, form); + if (canceled) return; + + for (const key of Object.keys(result)) { + this.props[key] = result[key]; + } + + this.save(); + }, + } + }); +} diff --git a/packages/client/src/widgets/digital-clock.vue b/packages/client/src/widgets/digital-clock.vue new file mode 100644 index 000000000..9d32e8b9f --- /dev/null +++ b/packages/client/src/widgets/digital-clock.vue @@ -0,0 +1,79 @@ + + + + + diff --git a/packages/client/src/widgets/federation.vue b/packages/client/src/widgets/federation.vue new file mode 100644 index 000000000..85cfb8b84 --- /dev/null +++ b/packages/client/src/widgets/federation.vue @@ -0,0 +1,145 @@ + + + + + diff --git a/src/client/widgets/index.ts b/packages/client/src/widgets/index.ts similarity index 100% rename from src/client/widgets/index.ts rename to packages/client/src/widgets/index.ts diff --git a/packages/client/src/widgets/job-queue.vue b/packages/client/src/widgets/job-queue.vue new file mode 100644 index 000000000..ef440881e --- /dev/null +++ b/packages/client/src/widgets/job-queue.vue @@ -0,0 +1,183 @@ + + + + + diff --git a/packages/client/src/widgets/memo.vue b/packages/client/src/widgets/memo.vue new file mode 100644 index 000000000..100f1b293 --- /dev/null +++ b/packages/client/src/widgets/memo.vue @@ -0,0 +1,106 @@ + + + + + diff --git a/packages/client/src/widgets/notifications.vue b/packages/client/src/widgets/notifications.vue new file mode 100644 index 000000000..462f39a33 --- /dev/null +++ b/packages/client/src/widgets/notifications.vue @@ -0,0 +1,65 @@ + + + diff --git a/packages/client/src/widgets/online-users.vue b/packages/client/src/widgets/online-users.vue new file mode 100644 index 000000000..5b889f481 --- /dev/null +++ b/packages/client/src/widgets/online-users.vue @@ -0,0 +1,67 @@ + + + + + diff --git a/packages/client/src/widgets/photos.vue b/packages/client/src/widgets/photos.vue new file mode 100644 index 000000000..0c919526b --- /dev/null +++ b/packages/client/src/widgets/photos.vue @@ -0,0 +1,113 @@ + + + + + diff --git a/packages/client/src/widgets/post-form.vue b/packages/client/src/widgets/post-form.vue new file mode 100644 index 000000000..5ecaa67b5 --- /dev/null +++ b/packages/client/src/widgets/post-form.vue @@ -0,0 +1,23 @@ + + + diff --git a/packages/client/src/widgets/rss.vue b/packages/client/src/widgets/rss.vue new file mode 100644 index 000000000..235fce574 --- /dev/null +++ b/packages/client/src/widgets/rss.vue @@ -0,0 +1,89 @@ + + + + + diff --git a/src/client/widgets/server-metric/cpu-mem.vue b/packages/client/src/widgets/server-metric/cpu-mem.vue similarity index 100% rename from src/client/widgets/server-metric/cpu-mem.vue rename to packages/client/src/widgets/server-metric/cpu-mem.vue diff --git a/src/client/widgets/server-metric/cpu.vue b/packages/client/src/widgets/server-metric/cpu.vue similarity index 100% rename from src/client/widgets/server-metric/cpu.vue rename to packages/client/src/widgets/server-metric/cpu.vue diff --git a/packages/client/src/widgets/server-metric/disk.vue b/packages/client/src/widgets/server-metric/disk.vue new file mode 100644 index 000000000..650101b0e --- /dev/null +++ b/packages/client/src/widgets/server-metric/disk.vue @@ -0,0 +1,70 @@ + + + + + diff --git a/packages/client/src/widgets/server-metric/index.vue b/packages/client/src/widgets/server-metric/index.vue new file mode 100644 index 000000000..cfe3c15df --- /dev/null +++ b/packages/client/src/widgets/server-metric/index.vue @@ -0,0 +1,82 @@ + + + diff --git a/packages/client/src/widgets/server-metric/mem.vue b/packages/client/src/widgets/server-metric/mem.vue new file mode 100644 index 000000000..a6ca7b117 --- /dev/null +++ b/packages/client/src/widgets/server-metric/mem.vue @@ -0,0 +1,85 @@ + + + + + diff --git a/packages/client/src/widgets/server-metric/net.vue b/packages/client/src/widgets/server-metric/net.vue new file mode 100644 index 000000000..23c148eeb --- /dev/null +++ b/packages/client/src/widgets/server-metric/net.vue @@ -0,0 +1,148 @@ + + + + + diff --git a/src/client/widgets/server-metric/pie.vue b/packages/client/src/widgets/server-metric/pie.vue similarity index 100% rename from src/client/widgets/server-metric/pie.vue rename to packages/client/src/widgets/server-metric/pie.vue diff --git a/packages/client/src/widgets/slideshow.vue b/packages/client/src/widgets/slideshow.vue new file mode 100644 index 000000000..0909bda67 --- /dev/null +++ b/packages/client/src/widgets/slideshow.vue @@ -0,0 +1,167 @@ + + + + + diff --git a/packages/client/src/widgets/timeline.vue b/packages/client/src/widgets/timeline.vue new file mode 100644 index 000000000..0d0629abe --- /dev/null +++ b/packages/client/src/widgets/timeline.vue @@ -0,0 +1,116 @@ + + + diff --git a/packages/client/src/widgets/trends.vue b/packages/client/src/widgets/trends.vue new file mode 100644 index 000000000..dba339261 --- /dev/null +++ b/packages/client/src/widgets/trends.vue @@ -0,0 +1,111 @@ + + + + + diff --git a/packages/client/tsconfig.json b/packages/client/tsconfig.json new file mode 100644 index 000000000..b44cf2f89 --- /dev/null +++ b/packages/client/tsconfig.json @@ -0,0 +1,40 @@ +{ + "compilerOptions": { + "allowJs": true, + "noEmitOnError": false, + "noImplicitAny": false, + "noImplicitReturns": true, + "noUnusedParameters": false, + "noUnusedLocals": true, + "noFallthroughCasesInSwitch": true, + "declaration": false, + "sourceMap": false, + "target": "es2017", + "module": "esnext", + "moduleResolution": "node", + "removeComments": false, + "noLib": false, + "strict": true, + "strictNullChecks": true, + "experimentalDecorators": true, + "resolveJsonModule": true, + "baseUrl": ".", + "paths": { + "@/*": ["./src/*"], + }, + "typeRoots": [ + "node_modules/@types", + "@types", + ], + "lib": [ + "esnext", + "dom", + "webworker" + ] + }, + "compileOnSave": false, + "include": [ + "./**/*.ts", + "./**/*.vue" + ] +} diff --git a/packages/client/webpack.config.js b/packages/client/webpack.config.js new file mode 100644 index 000000000..7bcfdcb15 --- /dev/null +++ b/packages/client/webpack.config.js @@ -0,0 +1,192 @@ +/** + * webpack configuration + */ + +const fs = require('fs'); +const webpack = require('webpack'); +const { VueLoaderPlugin } = require('vue-loader'); + +class WebpackOnBuildPlugin { + constructor(callback) { + this.callback = callback; + } + + apply(compiler) { + compiler.hooks.done.tap('WebpackOnBuildPlugin', this.callback); + } +} + +const isProduction = process.env.NODE_ENV === 'production'; + +const locales = require('../../locales'); +const meta = require('../../package.json'); + +const postcss = { + loader: 'postcss-loader', + options: { + postcssOptions: { + plugins: [ + require('cssnano')({ + preset: 'default' + }) + ] + } + }, +}; + +module.exports = { + entry: { + app: './src/init.ts', + sw: './src/sw/sw.ts' + }, + module: { + rules: [{ + test: /\.vue$/, + exclude: /node_modules/, + use: [{ + loader: 'vue-loader', + options: { + cssSourceMap: false, + compilerOptions: { + preserveWhitespace: false + } + } + }] + }, { + test: /\.scss?$/, + exclude: /node_modules/, + oneOf: [{ + resourceQuery: /module/, + use: [{ + loader: 'vue-style-loader' + }, { + loader: 'css-loader', + options: { + modules: true, + esModule: false, // TODO: trueにすると壊れる。Vue3移行の折にはtrueにできるかもしれない + url: false, + } + }, postcss, { + loader: 'sass-loader', + options: { + implementation: require('sass'), + sassOptions: { + fiber: false + } + } + }] + }, { + use: [{ + loader: 'vue-style-loader' + }, { + loader: 'css-loader', + options: { + url: false, + esModule: false, // TODO: trueにすると壊れる。Vue3移行の折にはtrueにできるかもしれない + } + }, postcss, { + loader: 'sass-loader', + options: { + implementation: require('sass'), + sassOptions: { + fiber: false + } + } + }] + }] + }, { + test: /\.css$/, + oneOf: [{ + resourceQuery: /module/, + use: [{ + loader: 'vue-style-loader' + }, { + loader: 'css-loader', + options: { + modules: true, + esModule: false, // TODO: trueにすると壊れる。Vue3移行の折にはtrueにできるかもしれない + } + }, postcss] + }, { + use: [{ + loader: 'vue-style-loader' + }, { + loader: 'css-loader', + options: { + esModule: false, // TODO: trueにすると壊れる。Vue3移行の折にはtrueにできるかもしれない + } + }, postcss] + }] + }, { + test: /\.svg$/, + use: [ + 'vue-loader', + 'vue-svg-loader', + ], + }, { + test: /\.(eot|woff|woff2|svg|ttf)([?]?.*)$/, + type: 'asset/resource' + }, { + test: /\.json5$/, + loader: 'json5-loader', + options: { + esModule: false, + }, + type: 'javascript/auto' + }, { + test: /\.ts$/, + exclude: /node_modules/, + use: [{ + loader: 'ts-loader', + options: { + happyPackMode: true, + transpileOnly: true, + configFile: __dirname + '/tsconfig.json', + appendTsSuffixTo: [/\.vue$/] + } + }] + }] + }, + plugins: [ + new webpack.ProgressPlugin({}), + new webpack.DefinePlugin({ + _VERSION_: JSON.stringify(meta.version), + _LANGS_: JSON.stringify(Object.entries(locales).map(([k, v]) => [k, v._lang_])), + _ENV_: JSON.stringify(process.env.NODE_ENV), + _DEV_: process.env.NODE_ENV !== 'production', + _PERF_PREFIX_: JSON.stringify('Misskey:'), + _DATA_TRANSFER_DRIVE_FILE_: JSON.stringify('mk_drive_file'), + _DATA_TRANSFER_DRIVE_FOLDER_: JSON.stringify('mk_drive_folder'), + _DATA_TRANSFER_DECK_COLUMN_: JSON.stringify('mk_deck_column'), + __VUE_OPTIONS_API__: true, + __VUE_PROD_DEVTOOLS__: false, + }), + new VueLoaderPlugin(), + new WebpackOnBuildPlugin(() => { + fs.mkdirSync(__dirname + '/../../built', { recursive: true }); + fs.writeFileSync(__dirname + '/../../built/meta.json', JSON.stringify({ version: meta.version }), 'utf-8'); + }), + ], + output: { + path: __dirname + '/../../built/_client_dist_', + filename: `[name].${meta.version}.js`, + publicPath: `/assets/`, + pathinfo: false, + }, + resolve: { + extensions: [ + '.js', '.ts', '.json' + ], + alias: { + '@': __dirname + '/src/', + } + }, + resolveLoader: { + modules: ['node_modules'] + }, + experiments: { + topLevelAwait: true + }, + devtool: false, //'source-map', + mode: isProduction ? 'production' : 'development' +}; diff --git a/packages/client/yarn.lock b/packages/client/yarn.lock new file mode 100644 index 000000000..34b936c45 --- /dev/null +++ b/packages/client/yarn.lock @@ -0,0 +1,6711 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/code-frame@^7.0.0": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.13.tgz#dcfc826beef65e75c50e21d3837d7d95798dd658" + integrity sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g== + dependencies: + "@babel/highlight" "^7.12.13" + +"@babel/helper-validator-identifier@^7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed" + integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw== + +"@babel/highlight@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.12.13.tgz#8ab538393e00370b26271b01fa08f7f27f2e795c" + integrity sha512-kocDQvIbgMKlWxXe9fof3TQ+gkIPOUSEYhJjqUjvKMez3krV7vbzYCDq39Oj11UAVK7JqPVGQPlgE85dPNlQww== + dependencies: + "@babel/helper-validator-identifier" "^7.12.11" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@babel/parser@^7.15.0": + version "7.15.6" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.15.6.tgz#043b9aa3c303c0722e5377fef9197f4cf1796549" + integrity sha512-S/TSCcsRuCkmpUuoWijua0Snt+f3ewU/8spLo+4AXJCZfT0bVCzLD5MuOKdrx0mlAptbKzn5AdgEIIKXxXkz9Q== + +"@babel/parser@^7.6.0", "@babel/parser@^7.9.6": + version "7.13.9" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.13.9.tgz#ca34cb95e1c2dd126863a84465ae8ef66114be99" + integrity sha512-nEUfRiARCcaVo3ny3ZQjURjHQZUo/JkEw7rLlSZy/psWGnvwXFtPcr6jb7Yb41DVW5LTe6KRq9LGleRNsg1Frw== + +"@babel/runtime@^7.16.0": + version "7.16.3" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.3.tgz#b86f0db02a04187a3c17caa77de69840165d42d5" + integrity sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ== + dependencies: + regenerator-runtime "^0.13.4" + +"@babel/runtime@^7.6.2": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.13.tgz#0a21452352b02542db0ffb928ac2d3ca7cb6d66d" + integrity sha512-8+3UMPBrjFa/6TtKi/7sehPKqfAm4g6K+YQjyyFOLUTxzOngcRZTlAVY8sc2CORJYqdHQY8gRPHmn+qo15rCBw== + dependencies: + regenerator-runtime "^0.13.4" + +"@babel/types@^7.6.1", "@babel/types@^7.9.6": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.13.0.tgz#74424d2816f0171b4100f0ab34e9a374efdf7f80" + integrity sha512-hE+HE8rnG1Z6Wzo+MhaKE5lM5eMx71T4EHJgku2E3xIfaULhDcxiiRxUYgwX8qwP1BBSlag+TdGOt6JAidIZTA== + dependencies: + "@babel/helper-validator-identifier" "^7.12.11" + lodash "^4.17.19" + to-fast-properties "^2.0.0" + +"@cspotcode/source-map-consumer@0.8.0": + version "0.8.0" + resolved "https://registry.yarnpkg.com/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz#33bf4b7b39c178821606f669bbc447a6a629786b" + integrity sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg== + +"@cspotcode/source-map-support@0.7.0": + version "0.7.0" + resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz#4789840aa859e46d2f3173727ab707c66bf344f5" + integrity sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA== + dependencies: + "@cspotcode/source-map-consumer" "0.8.0" + +"@cypress/request@^2.88.6": + version "2.88.6" + resolved "https://registry.yarnpkg.com/@cypress/request/-/request-2.88.6.tgz#a970dd675befc6bdf8a8921576c01f51cc5798e9" + integrity sha512-z0UxBE/+qaESAHY9p9sM2h8Y4XqtsbDCt0/DPOrqA/RZgKi4PkxdpXyK4wCCnSk1xHqWHZZAE+gV6aDAR6+caQ== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.3" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.5.0" + tunnel-agent "^0.6.0" + uuid "^8.3.2" + +"@cypress/xvfb@^1.2.4": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@cypress/xvfb/-/xvfb-1.2.4.tgz#2daf42e8275b39f4aa53c14214e557bd14e7748a" + integrity sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q== + dependencies: + debug "^3.1.0" + lodash.once "^4.1.1" + +"@discordapp/twemoji@13.1.0": + version "13.1.0" + resolved "https://registry.yarnpkg.com/@discordapp/twemoji/-/twemoji-13.1.0.tgz#6b25f3958fa8fd68692248c87776bc737fd009a9" + integrity sha512-KEw/te+ylD2MHutzigafyptv0kdTU05Dbgxr9Y5J9IAQw8PbFz16nKtlPnJtA23BLp9fZQeNXzUmegkRi7fpDA== + dependencies: + fs-extra "^8.0.1" + jsonfile "^5.0.0" + twemoji-parser "13.1.0" + universalify "^0.1.2" + +"@discoveryjs/json-ext@^0.5.0": + version "0.5.2" + resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.2.tgz#8f03a22a04de437254e8ce8cc84ba39689288752" + integrity sha512-HyYEUDeIj5rRQU2Hk5HTB2uHsbRQpF70nvMhVzi+VJR0X+xNEhjPui4/kBf3VeH/wqD28PT4sVOm8qqLjBrSZg== + +"@elastic/elasticsearch@7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@elastic/elasticsearch/-/elasticsearch-7.11.0.tgz#e196243d0ed026742fc160d72cc5b4b5b6c7807d" + integrity sha512-AFVVuANIdbV1qYjuOi4hnsX/DehWYG+bbhQO4amq9K4/NnzU7mpGWOPgVlRQTiX+vBfBkx7SL6h4QEjIlM3ztA== + dependencies: + debug "^4.1.1" + hpagent "^0.1.1" + ms "^2.1.1" + pump "^3.0.0" + secure-json-parse "^2.1.0" + +"@eslint/eslintrc@^1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.0.4.tgz#dfe0ff7ba270848d10c5add0715e04964c034b31" + integrity sha512-h8Vx6MdxwWI2WM8/zREHMoqdgLNXEL4QX3MWSVMdyNJGvXVOs+6lp+m2hc3FnuMHDc4poxFNI20vCk0OmI4G0Q== + dependencies: + ajv "^6.12.4" + debug "^4.3.2" + espree "^9.0.0" + globals "^13.9.0" + ignore "^4.0.6" + import-fresh "^3.2.1" + js-yaml "^4.1.0" + minimatch "^3.0.4" + strip-json-comments "^3.1.1" + +"@hapi/hoek@^9.0.0": + version "9.2.0" + resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.2.0.tgz#f3933a44e365864f4dad5db94158106d511e8131" + integrity sha512-sqKVVVOe5ivCaXDWivIJYVSaEgdQK9ul7a4Kity5Iw7u9+wBAPbX1RMSnLLmp7O4Vzj0WOWwMAJsTL00xwaNug== + +"@hapi/topo@^5.0.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-5.1.0.tgz#dc448e332c6c6e37a4dc02fd84ba8d44b9afb012" + integrity sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg== + dependencies: + "@hapi/hoek" "^9.0.0" + +"@humanwhocodes/config-array@^0.6.0": + version "0.6.0" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.6.0.tgz#b5621fdb3b32309d2d16575456cbc277fa8f021a" + integrity sha512-JQlEKbcgEUjBFhLIF4iqM7u/9lwgHRBcpHrmUNCALK0Q3amXN6lxdoXLnF0sm11E9VqTmBALR87IlUg1bZ8A9A== + dependencies: + "@humanwhocodes/object-schema" "^1.2.0" + debug "^4.1.1" + minimatch "^3.0.4" + +"@humanwhocodes/object-schema@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz#87de7af9c231826fdd68ac7258f77c429e0e5fcf" + integrity sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w== + +"@jfonx/console-utils@^1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@jfonx/console-utils/-/console-utils-1.0.3.tgz#cbb7f911e4191a4a2fe1ba4807d29f100b5d099f" + integrity sha512-/XbnqjWc7yNZVLAJJO9rimfIz9DYte+cj3EF9hwhIv7vw6ok2t3cjl0huYsmD89srKH03vWjeqAcIH86CuYj3g== + dependencies: + colors "^1.3.3" + +"@jfonx/file-utils@^3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@jfonx/file-utils/-/file-utils-3.0.1.tgz#8d3d6e931a283420fe29802ea71c28dd397cd8d3" + integrity sha512-qwH0CuzWmghtTHGMyuPHj6SJPQgWeiXFJBfrxCWMbzxVCa3aLZPEfzSdlSnC/UABsk6feRkNdHXw59rVshNPqw== + dependencies: + "@jfonx/console-utils" "^1.0.3" + comment-json "^4.1.0" + find-up "^4.1.0" + +"@nodelib/fs.scandir@2.1.3": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz#3a582bdb53804c6ba6d146579c46e52130cf4a3b" + integrity sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw== + dependencies: + "@nodelib/fs.stat" "2.0.3" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.3", "@nodelib/fs.stat@^2.0.2": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz#34dc5f4cabbc720f4e60f75a747e7ecd6c175bd3" + integrity sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz#011b9202a70a6366e436ca5c065844528ab04976" + integrity sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ== + dependencies: + "@nodelib/fs.scandir" "2.1.3" + fastq "^1.6.0" + +"@redocly/ajv@^8.6.2": + version "8.6.2" + resolved "https://registry.yarnpkg.com/@redocly/ajv/-/ajv-8.6.2.tgz#8c4e485e72f7864f91fae40093bed548ec2619b2" + integrity sha512-tU8fQs0D76ZKhJ2cWtnfQthWqiZgGBx0gH0+5D8JvaBEBaqA8foPPBt3Nonwr3ygyv5xrw2IzKWgIY86BlGs+w== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + +"@redocly/openapi-core@1.0.0-beta.54": + version "1.0.0-beta.54" + resolved "https://registry.yarnpkg.com/@redocly/openapi-core/-/openapi-core-1.0.0-beta.54.tgz#42575a849c4dd54b9d0c6413fb8ca547e087cd11" + integrity sha512-uYs0N1Trjkh7u8IMIuCU2VxCXhMyGWSZUkP/WNdTR1OgBUtvNdF9C32zoQV+hyCIH4gVu42ROHkjisy333ZX+w== + dependencies: + "@redocly/ajv" "^8.6.2" + "@types/node" "^14.11.8" + colorette "^1.2.0" + js-levenshtein "^1.1.6" + js-yaml "^3.14.1" + lodash.isequal "^4.5.0" + minimatch "^3.0.4" + node-fetch "^2.6.1" + yaml-ast-parser "0.0.43" + +"@sentry/browser@5.29.2": + version "5.29.2" + resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-5.29.2.tgz#51adb4005511b1a4a70e4571880fc6653d651f91" + integrity sha512-uxZ7y7rp85tJll+RZtXRhXPbnFnOaxZqJEv05vJlXBtBNLQtlczV5iCtU9mZRLVHDtmZ5VVKUV8IKXntEqqDpQ== + dependencies: + "@sentry/core" "5.29.2" + "@sentry/types" "5.29.2" + "@sentry/utils" "5.29.2" + tslib "^1.9.3" + +"@sentry/core@5.29.2": + version "5.29.2" + resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.29.2.tgz#9e05fe197234161d57aabaf52fab336a7c520d81" + integrity sha512-7WYkoxB5IdlNEbwOwqSU64erUKH4laavPsM0/yQ+jojM76ErxlgEF0u//p5WaLPRzh3iDSt6BH+9TL45oNZeZw== + dependencies: + "@sentry/hub" "5.29.2" + "@sentry/minimal" "5.29.2" + "@sentry/types" "5.29.2" + "@sentry/utils" "5.29.2" + tslib "^1.9.3" + +"@sentry/hub@5.29.2": + version "5.29.2" + resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-5.29.2.tgz#208f10fe6674695575ad74182a1151f71d6df00a" + integrity sha512-LaAIo2hwUk9ykeh9RF0cwLy6IRw+DjEee8l1HfEaDFUM6TPGlNNGObMJNXb9/95jzWp7jWwOpQjoIE3jepdQJQ== + dependencies: + "@sentry/types" "5.29.2" + "@sentry/utils" "5.29.2" + tslib "^1.9.3" + +"@sentry/minimal@5.29.2": + version "5.29.2" + resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-5.29.2.tgz#420bebac8d03d30980fdb05c72d7b253d8aa541b" + integrity sha512-0aINSm8fGA1KyM7PavOBe1GDZDxrvnKt+oFnU0L+bTcw8Lr+of+v6Kwd97rkLRNOLw621xP076dL/7LSIzMuhw== + dependencies: + "@sentry/hub" "5.29.2" + "@sentry/types" "5.29.2" + tslib "^1.9.3" + +"@sentry/tracing@5.29.2": + version "5.29.2" + resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-5.29.2.tgz#6012788547d2ab7893799d82c4941bda145dcd47" + integrity sha512-iumYbVRpvoU3BUuIooxibydeaOOjl5ysc+mzsqhRs2NGW/C3uKAsFXdvyNfqt3bxtRQwJEhwJByLP2u3pLThpw== + dependencies: + "@sentry/hub" "5.29.2" + "@sentry/minimal" "5.29.2" + "@sentry/types" "5.29.2" + "@sentry/utils" "5.29.2" + tslib "^1.9.3" + +"@sentry/types@5.29.2": + version "5.29.2" + resolved "https://registry.yarnpkg.com/@sentry/types/-/types-5.29.2.tgz#ac87383df1222c2d9b9f8f9ed7a6b86ea41a098a" + integrity sha512-dM9wgt8wy4WRty75QkqQgrw9FV9F+BOMfmc0iaX13Qos7i6Qs2Q0dxtJ83SoR4YGtW8URaHzlDtWlGs5egBiMA== + +"@sentry/utils@5.29.2": + version "5.29.2" + resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-5.29.2.tgz#99a5cdda2ea19d34a41932f138d470adcb3ee673" + integrity sha512-nEwQIDjtFkeE4k6yIk4Ka5XjGRklNLThWLs2xfXlL7uwrYOH2B9UBBOOIRUraBm/g/Xrra3xsam/kRxuiwtXZQ== + dependencies: + "@sentry/types" "5.29.2" + tslib "^1.9.3" + +"@sideway/address@^4.1.0": + version "4.1.2" + resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.2.tgz#811b84333a335739d3969cfc434736268170cad1" + integrity sha512-idTz8ibqWFrPU8kMirL0CoPH/A29XOzzAzpyN3zQ4kAWnzmNfFmRaoMNN6VI8ske5M73HZyhIaW4OuSFIdM4oA== + dependencies: + "@hapi/hoek" "^9.0.0" + +"@sideway/formula@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@sideway/formula/-/formula-3.0.0.tgz#fe158aee32e6bd5de85044be615bc08478a0a13c" + integrity sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg== + +"@sideway/pinpoint@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@sideway/pinpoint/-/pinpoint-2.0.0.tgz#cff8ffadc372ad29fd3f78277aeb29e632cc70df" + integrity sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ== + +"@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== + +"@sinonjs/commons@^1.7.0": + version "1.7.2" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.7.2.tgz#505f55c74e0272b43f6c52d81946bed7058fc0e2" + integrity sha512-+DUO6pnp3udV/v2VfUWgaY5BIE1IfT7lLfeDzPVeMT1XKkaAp9LgSI9x5RtrFQoZ9Oi0PgXQQHPaoKu7dCjVxw== + 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== + dependencies: + "@sinonjs/commons" "^1.7.0" + +"@syuilo/aiscript@0.11.1": + version "0.11.1" + resolved "https://registry.yarnpkg.com/@syuilo/aiscript/-/aiscript-0.11.1.tgz#52c14692113c58d1d62e6ae696352ba49abdf2eb" + integrity sha512-chwOIA3yLUKvOB0G611hjLArKTeOWNmTm3lHERSaDW1d+dS6do56naX6Lkwy2UpnwWC0qzeNSgg35elk6t2gZg== + dependencies: + autobind-decorator "2.4.0" + chalk "4.0.0" + seedrandom "3.0.5" + stringz "2.1.0" + uuid "7.0.3" + +"@szmarczak/http-timer@^4.0.5": + version "4.0.5" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.5.tgz#bfbd50211e9dfa51ba07da58a14cdfd333205152" + integrity sha512-PyRA9sm1Yayuj5OIoJ1hGt2YISX45w9WcFbh6ddT0Z/0yaFxOtGLInr4jUfU1EAFVs0Yfyfev4RNwBlUaHdlDQ== + dependencies: + defer-to-connect "^2.0.0" + +"@trysound/sax@0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad" + integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA== + +"@tsconfig/node10@^1.0.7": + version "1.0.7" + resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.7.tgz#1eb1de36c73478a2479cc661ef5af1c16d86d606" + integrity sha512-aBvUmXLQbayM4w3A8TrjwrXs4DZ8iduJnuJLLRGdkWlyakCf1q6uHZJBzXoRA/huAEknG5tcUyQxN3A+In5euQ== + +"@tsconfig/node12@^1.0.7": + version "1.0.7" + resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.7.tgz#677bd9117e8164dc319987dd6ff5fc1ba6fbf18b" + integrity sha512-dgasobK/Y0wVMswcipr3k0HpevxFJLijN03A8mYfEPvWvOs14v0ZlYTR4kIgMx8g4+fTyTFv8/jLCIfRqLDJ4A== + +"@tsconfig/node14@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.0.tgz#5bd046e508b1ee90bc091766758838741fdefd6e" + integrity sha512-RKkL8eTdPv6t5EHgFKIVQgsDapugbuOptNd9OOunN/HAkzmmTnZELx1kNCK0rSdUYGmiFMM3rRQMAWiyp023LQ== + +"@tsconfig/node16@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.2.tgz#423c77877d0569db20e1fc80885ac4118314010e" + integrity sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA== + +"@types/anymatch@*": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-1.3.1.tgz#336badc1beecb9dacc38bea2cf32adf627a8421a" + integrity sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA== + +"@types/cacheable-request@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.1.tgz#5d22f3dded1fd3a84c0bbeb5039a7419c2c91976" + integrity sha512-ykFq2zmBGOCbpIXtoVbz4SKY5QriWPh3AjyU4G74RYbtt5yOc5OfaY75ftjg7mikMOla1CTGpX3lLbuJh8DTrQ== + dependencies: + "@types/http-cache-semantics" "*" + "@types/keyv" "*" + "@types/node" "*" + "@types/responselike" "*" + +"@types/color-name@^1.1.1": + version "1.1.1" + 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.0": + version "0.0.0" + resolved "https://registry.yarnpkg.com/@types/escape-regexp/-/escape-regexp-0.0.0.tgz#bff0225f9ef30d0dbdbe0e2a24283ee5342990c3" + integrity sha512-HTansGo4tJ7K7W9I9LBdQqnHtPB/Y7tlS+EMrkboaAQLsRPhRpHaqAHe01K1HVXM5e1u1IplRd8EBh+pJrp7Dg== + +"@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/estree@^0.0.50": + version "0.0.50" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.50.tgz#1e0caa9364d3fccd2931c3ed96fdbeaa5d4cca83" + integrity sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw== + +"@types/events@*": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" + integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g== + +"@types/expect@^1.20.4": + version "1.20.4" + resolved "https://registry.yarnpkg.com/@types/expect/-/expect-1.20.4.tgz#8288e51737bf7e3ab5d7c77bfa695883745264e5" + integrity sha512-Q5Vn3yjTDyCMV50TB6VRIbQNxSE4OmZR86VSbGaNpfUolm0iePBB4KdEEHmxoY5sT2+2DIvXW0rvMDP2nHZ4Mg== + +"@types/fluent-ffmpeg@2.1.17": + version "2.1.17" + resolved "https://registry.yarnpkg.com/@types/fluent-ffmpeg/-/fluent-ffmpeg-2.1.17.tgz#6958dda400fe1b33c21f3683db76905cb210d053" + integrity sha512-/bdvjKw/mtBHlJ2370d04nt4CsWqU5MrwS/NtO96V01jxitJ4+iq8OFNcqc5CegeV3TQOK3uueK02kvRK+zjUg== + dependencies: + "@types/node" "*" + +"@types/glob-stream@*": + version "6.1.0" + resolved "https://registry.yarnpkg.com/@types/glob-stream/-/glob-stream-6.1.0.tgz#7ede8a33e59140534f8d8adfb8ac9edfb31897bc" + integrity sha512-RHv6ZQjcTncXo3thYZrsbAVwoy4vSKosSWhuhuQxLOTv74OJuFQxXkmUuZCr3q9uNBEVCvIzmZL/FeRNbHZGUg== + dependencies: + "@types/glob" "*" + "@types/node" "*" + +"@types/glob@*": + version "7.1.1" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.1.tgz#aa59a1c6e3fbc421e07ccd31a944c30eba521575" + integrity sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w== + dependencies: + "@types/events" "*" + "@types/minimatch" "*" + "@types/node" "*" + +"@types/glob@7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb" + integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA== + dependencies: + "@types/minimatch" "*" + "@types/node" "*" + +"@types/gulp-rename@2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@types/gulp-rename/-/gulp-rename-2.0.1.tgz#c8228fc2c5c4a7500346ea9ce18f27fa988caef5" + integrity sha512-9ZjeS2RHEnmBmTcyi2+oeye3BgCsWhvi4uv3qCnAg8i6plOuRdaeNxjOves0ELysEXYLBl7bCl5fbVs7AZtgTA== + dependencies: + "@types/node" "*" + "@types/vinyl" "*" + +"@types/gulp@4.0.9": + version "4.0.9" + resolved "https://registry.yarnpkg.com/@types/gulp/-/gulp-4.0.9.tgz#a2f9667bcc26bc72b4899dd16216d6584a12346c" + integrity sha512-zzT+wfQ8uwoXjDhRK9Zkmmk09/fbLLmN/yDHFizJiEKIve85qutOnXcP/TM2sKPBTU+Jc16vfPbOMkORMUBN7Q== + dependencies: + "@types/undertaker" "*" + "@types/vinyl-fs" "*" + chokidar "^3.3.1" + +"@types/http-cache-semantics@*": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.0.tgz#9140779736aa2655635ee756e2467d787cfe8a2a" + integrity sha512-c3Xy026kOF7QOTn00hbIllV1dLR9hG9NkSrLQgCVs8NF6sBU+VGWjD3wLPhmh1TYAc7ugCFsvHYMN4VcBN1U1A== + +"@types/is-url@1.2.30": + version "1.2.30" + resolved "https://registry.yarnpkg.com/@types/is-url/-/is-url-1.2.30.tgz#85567e8bee4fee69202bc3448f9fb34b0d56c50a" + integrity sha512-AnlNFwjzC8XLda5VjRl4ItSd8qp8pSNowvsut0WwQyBWHpOxjxRJm8iO6uETWqEyLdYdb9/1j+Qd9gQ4l5I4fw== + +"@types/js-yaml@4.0.4": + version "4.0.4" + resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-4.0.4.tgz#cc38781257612581a1a0eb25f1709d2b06812fce" + integrity sha512-AuHubXUmg0AzkXH0Mx6sIxeY/1C110mm/EkE/gB1sTRz3h2dao2W/63q42SlVST+lICxz5Oki2hzYA6+KnnieQ== + +"@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" + integrity sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw== + +"@types/json-schema@^7.0.7": + version "7.0.8" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.8.tgz#edf1bf1dbf4e04413ca8e5b17b3b7d7d54b59818" + integrity sha512-YSBPTLTVm2e2OoQIDYx8HaeWJ5tTToLH67kXR7zYNGupXMEHa2++G8k+DczX2cFVgalypqtyZIcU19AFcmOpmg== + +"@types/json5@^0.0.29": + version "0.0.29" + resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" + integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= + +"@types/katex@0.11.1": + version "0.11.1" + resolved "https://registry.yarnpkg.com/@types/katex/-/katex-0.11.1.tgz#34de04477dcf79e2ef6c8d23b41a3d81f9ebeaf5" + integrity sha512-DUlIj2nk0YnJdlWgsFuVKcX27MLW0KbKmGVoUHmFr+74FYYNUDAaj9ZqTADvsbE8rfxuVmSFc7KczYn5Y09ozg== + +"@types/keyv@*": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.1.tgz#e45a45324fca9dab716ab1230ee249c9fb52cfa7" + integrity sha512-MPtoySlAZQ37VoLaPcTHCu1RWJ4llDkULYZIzOYxlhxBqYPB0RsRlmMU0R6tahtFe27mIdkHV+551ZWV4PLmVw== + dependencies: + "@types/node" "*" + +"@types/matter-js@0.17.6": + version "0.17.6" + resolved "https://registry.yarnpkg.com/@types/matter-js/-/matter-js-0.17.6.tgz#525bb33a7289105e1981ef51b987972fa9739011" + integrity sha512-i6WLNuM7/89SLqO2aOyaUkom9tc3B/qo4ekh7BD99xQ8+wOVVZO0F4RzKNYZCaFwr+xp3pK3oIb6sSVjLpz+pA== + +"@types/minimatch@*": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" + integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== + +"@types/mocha@8.2.3": + version "8.2.3" + resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-8.2.3.tgz#bbeb55fbc73f28ea6de601fbfa4613f58d785323" + integrity sha512-ekGvFhFgrc2zYQoX4JeZPmVzZxw6Dtllga7iGHzfbYIYkAMUx/sAFP2GdFpLff+vdHXu5fl7WX9AT+TtqYcsyw== + +"@types/node-fetch@2.5.12": + version "2.5.12" + resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.5.12.tgz#8a6f779b1d4e60b7a57fb6fd48d84fb545b9cc66" + integrity sha512-MKgC4dlq4kKNa/mYrwpKfzQMB5X3ee5U6fSprkKpToBqBmX4nFZL9cW5jl6sWn+xpRJ7ypWh2yyqqr8UUCstSw== + dependencies: + "@types/node" "*" + form-data "^3.0.0" + +"@types/node@*": + version "16.6.2" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.6.2.tgz#331b7b9f8621c638284787c5559423822fdffc50" + integrity sha512-LSw8TZt12ZudbpHc6EkIyDM3nHVWKYrAvGy6EAJfNfjusbwnThqjqxUKKRwuV3iWYeW/LYMzNgaq3MaLffQ2xA== + +"@types/node@16.11.7": + version "16.11.7" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.7.tgz#36820945061326978c42a01e56b61cd223dfdc42" + integrity sha512-QB5D2sqfSjCmTuWcBWyJ+/44bcjO7VbjSbOE0ucoVbAsSNQc4Lt6QkgkVXkTDwkL4z/beecZNDvVX15D4P8Jbw== + +"@types/node@^14.11.8", "@types/node@^14.14.31": + version "14.17.9" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.17.9.tgz#b97c057e6138adb7b720df2bd0264b03c9f504fd" + integrity sha512-CMjgRNsks27IDwI785YMY0KLt3co/c0cQ5foxHYv/shC2w8oOnVwz5Ubq1QG5KzrcW+AXk6gzdnxIkDnTvzu3g== + +"@types/nodemailer@6.4.4": + version "6.4.4" + resolved "https://registry.yarnpkg.com/@types/nodemailer/-/nodemailer-6.4.4.tgz#c265f7e7a51df587597b3a49a023acaf0c741f4b" + integrity sha512-Ksw4t7iliXeYGvIQcSIgWQ5BLuC/mljIEbjf615svhZL10PE9t+ei8O9gDaD3FPCasUJn9KTLwz2JFJyiiyuqw== + dependencies: + "@types/node" "*" + +"@types/nprogress@0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@types/nprogress/-/nprogress-0.2.0.tgz#86c593682d4199212a0509cc3c4d562bbbd6e45f" + integrity sha512-1cYJrqq9GezNFPsWTZpFut/d4CjpZqA0vhqDUPFWYKF1oIyBz5qnoYMzR+0C/T96t3ebLAC1SSnwrVOm5/j74A== + +"@types/oauth@0.9.1": + version "0.9.1" + resolved "https://registry.yarnpkg.com/@types/oauth/-/oauth-0.9.1.tgz#e17221e7f7936b0459ae7d006255dff61adca305" + integrity sha512-a1iY62/a3yhZ7qH7cNUsxoI3U/0Fe9+RnuFrpTKr+0WVOzbKlSLojShCKe20aOD1Sppv+i8Zlq0pLDuTJnwS4A== + dependencies: + "@types/node" "*" + +"@types/parse-json@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" + integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== + +"@types/parse5@6.0.2": + version "6.0.2" + resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-6.0.2.tgz#99f6b72d82e34cea03a4d8f2ed72114d909c1c61" + integrity sha512-+hQX+WyJAOne7Fh3zF5CxPemILIbuhNcqHHodzK9caYOLnC8pD5efmPleRnw0z++LfKUC/sVNMwk0Gap+B0baA== + +"@types/parsimmon@1.10.6": + version "1.10.6" + resolved "https://registry.yarnpkg.com/@types/parsimmon/-/parsimmon-1.10.6.tgz#8fcf95990514d2a7624aa5f630c13bf2427f9cdd" + integrity sha512-FwAQwMRbkhx0J6YELkwIpciVzCcgEqXEbIrIn3a2P5d3kGEHQ3wVhlN3YdVepYP+bZzCYO6OjmD4o9TGOZ40rA== + +"@types/portscanner@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@types/portscanner/-/portscanner-2.1.1.tgz#89d5094e16f3d941f20f3889dfa5d3a164b3dd3b" + integrity sha512-1NsVIbgBKvrqxwtMN0V6CLji1ERwKSI/RWz0J3y++CzSwYNGBStCfpIFgxV3ZwxsDR5PoZqoUWhwraDm+Ztn0Q== + +"@types/pug@2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@types/pug/-/pug-2.0.5.tgz#69bc700934dd473c7ab97270bd2dbacefe562231" + integrity sha512-LOnASQoeNZMkzexRuyqcBBDZ6rS+rQxUMkmj5A0PkhhiSZivLIuz6Hxyr1mkGoEZEkk66faROmpMi4fFkrKsBA== + +"@types/punycode@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@types/punycode/-/punycode-2.1.0.tgz#89e4f3d09b3f92e87a80505af19be7e0c31d4e83" + integrity sha512-PG5aLpW6PJOeV2fHRslP4IOMWn+G+Uq8CfnyJ+PDS8ndCbU+soO+fB3NKCKo0p/Jh2Y4aPaiQZsrOXFdzpcA6g== + +"@types/q@^1.5.1": + version "1.5.2" + resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.2.tgz#690a1475b84f2a884fd07cd797c00f5f31356ea8" + integrity sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw== + +"@types/qrcode@1.4.1": + version "1.4.1" + resolved "https://registry.yarnpkg.com/@types/qrcode/-/qrcode-1.4.1.tgz#0689f400c3a95d2db040c99c99834faa09ee9dc1" + integrity sha512-vxMyr7JM7tYPxu8vUE83NiosWX5DZieCyYeJRoOIg0pAkyofCBzknJ2ycUZkPGDFis2RS8GN/BeJLnRnAPxeCA== + dependencies: + "@types/node" "*" + +"@types/random-seed@0.3.3": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@types/random-seed/-/random-seed-0.3.3.tgz#7741f7b0a4513198a9396ce4ad25832f799a6727" + integrity sha512-kHsCbIRHNXJo6EN5W8EA5b4i1hdT6jaZke5crBPLUcLqaLdZ0QBq8QVMbafHzhjFF83Cl9qlee2dChD18d/kPg== + +"@types/rename@1.0.4": + version "1.0.4" + 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" + integrity sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA== + 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" + integrity sha512-SMA+fUwULwK7sd/ZJicUztiPs8F1yCPwF3O23Z9uQ32ME5Ha0NmDK9+QTsYE4O2tHXChzXomSWWeIhCnoN1LqA== + +"@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/sinonjs__fake-timers@^6.0.2": + version "6.0.3" + resolved "https://registry.yarnpkg.com/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.3.tgz#79df6f358ae8f79e628fe35a63608a0ea8e7cf08" + integrity sha512-E1dU4fzC9wN2QK2Cr1MLCfyHM8BoNnRFvuf45LYMPNDA+WqbNzC45S4UzPxvp1fFJ1rvSGU0bPvdd35VLmXG8g== + +"@types/sizzle@^2.3.2": + version "2.3.3" + resolved "https://registry.yarnpkg.com/@types/sizzle/-/sizzle-2.3.3.tgz#ff5e2f1902969d305225a047c8a0fd5c915cebef" + integrity sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ== + +"@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/speakeasy@2.0.6": + version "2.0.6" + resolved "https://registry.yarnpkg.com/@types/speakeasy/-/speakeasy-2.0.6.tgz#12540f7b64d08180393ae2c5c8c280866a85da61" + integrity sha512-2wIXZp5yJUddhsSZarYCZIakCvzwQgTVdtT29DYVdFzc0cHttanaQx9THRhtjY4kDqVaF2jhyFOEofozOioFdQ== + 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" + integrity sha512-5eQEtSCoESnh2FsiLTxE121IiE60hnMqcb435fShf4bpLRjEu1Eoekht23y6zXS9Ts3l+Szu3TARnTsA0GkOkQ== + +"@types/tinycolor2@1.4.3": + version "1.4.3" + resolved "https://registry.yarnpkg.com/@types/tinycolor2/-/tinycolor2-1.4.3.tgz#ed4a0901f954b126e6a914b4839c77462d56e706" + integrity sha512-Kf1w9NE5HEgGxCRyIcRXR/ZYtDv0V8FVPtYHwLxl0O+maGX0erE77pQlD0gpP+/KByMZ87mOA79SjifhSB3PjQ== + +"@types/tmp@0.2.2": + version "0.2.2" + resolved "https://registry.yarnpkg.com/@types/tmp/-/tmp-0.2.2.tgz#424537a3b91828cb26aaf697f21ae3cd1b69f7e7" + integrity sha512-MhSa0yylXtVMsyT8qFpHA1DLHj4DvQGH5ntxrhHSh8PxUVNi35Wk+P5hVgqbO2qZqOotqr9jaoPRL+iRjWYm/A== + +"@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/undertaker-registry@*": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@types/undertaker-registry/-/undertaker-registry-1.0.1.tgz#4306d4a03d7acedb974b66530832b90729e1d1da" + integrity sha512-Z4TYuEKn9+RbNVk1Ll2SS4x1JeLHecolIbM/a8gveaHsW0Hr+RQMraZACwTO2VD7JvepgA6UO1A1VrbktQrIbQ== + +"@types/undertaker@*": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@types/undertaker/-/undertaker-1.2.2.tgz#927da24d0d3279830af96386862b035e040ead74" + integrity sha512-j4iepCSuY2JGW/hShVtUBagic0klYNFIXP7VweavnYnNC2EjiKxJFeaS9uaJmAT0ty9sQSqTS1aagWMZMV0HyA== + dependencies: + "@types/undertaker-registry" "*" + +"@types/uuid@8.3.1": + version "8.3.1" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.1.tgz#1a32969cf8f0364b3d8c8af9cc3555b7805df14f" + integrity sha512-Y2mHTRAbqfFkpjldbkHGY8JIzRN6XqYRliG8/24FcHm2D2PwW24fl5xMRTVGdrb7iMrwCaIEbLWerGIkXuFWVg== + +"@types/vinyl-fs@*": + version "2.4.11" + resolved "https://registry.yarnpkg.com/@types/vinyl-fs/-/vinyl-fs-2.4.11.tgz#b98119b8bb2494141eaf649b09fbfeb311161206" + integrity sha512-2OzQSfIr9CqqWMGqmcERE6Hnd2KY3eBVtFaulVo3sJghplUcaeMdL9ZjEiljcQQeHjheWY9RlNmumjIAvsBNaA== + dependencies: + "@types/glob-stream" "*" + "@types/node" "*" + "@types/vinyl" "*" + +"@types/vinyl@*": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@types/vinyl/-/vinyl-2.0.4.tgz#9a7a8071c8d14d3a95d41ebe7135babe4ad5995a" + integrity sha512-2o6a2ixaVI2EbwBPg1QYLGQoHK56p/8X/sGfKbFC8N6sY9lfjsMf/GprtkQkSya0D4uRiutRZ2BWj7k3JvLsAQ== + dependencies: + "@types/expect" "^1.20.4" + "@types/node" "*" + +"@types/web-push@3.3.2": + version "3.3.2" + resolved "https://registry.yarnpkg.com/@types/web-push/-/web-push-3.3.2.tgz#8c32434147c0396415862e86405c9edc9c50fc15" + integrity sha512-JxWGVL/m7mWTIg4mRYO+A6s0jPmBkr4iJr39DqJpRJAc+jrPiEe1/asmkwerzRon8ZZDxaZJpsxpv0Z18Wo9gw== + 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== + dependencies: + "@types/node" "*" + +"@types/ws@8.2.0": + version "8.2.0" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.2.0.tgz#75faefbe2328f3b833cb8dc640658328990d04f3" + integrity sha512-cyeefcUCgJlEk+hk2h3N+MqKKsPViQgF5boi9TTHSK+PoR9KWBb/C5ccPcDyAqgsbAYHTwulch725DV84+pSpg== + dependencies: + "@types/node" "*" + +"@types/yauzl@^2.9.1": + version "2.9.2" + resolved "https://registry.yarnpkg.com/@types/yauzl/-/yauzl-2.9.2.tgz#c48e5d56aff1444409e39fa164b0b4d4552a7b7a" + integrity sha512-8uALY5LTvSuHgloDVUvWP3pIauILm+8/0pDMokuDYIoNsOkSwd5AiHBTSEJjKTDcZr5z8UpgOWZkxBF4iJftoA== + dependencies: + "@types/node" "*" + +"@typescript-eslint/parser@5.1.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.1.0.tgz#6c7f837d210d2bc0a811e7ea742af414f4e00908" + integrity sha512-vx1P+mhCtYw3+bRHmbalq/VKP2Y3gnzNgxGxfEWc6OFpuEL7iQdAeq11Ke3Rhy8NjgB+AHsIWEwni3e+Y7djKA== + dependencies: + "@typescript-eslint/scope-manager" "5.1.0" + "@typescript-eslint/types" "5.1.0" + "@typescript-eslint/typescript-estree" "5.1.0" + debug "^4.3.2" + +"@typescript-eslint/scope-manager@5.1.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.1.0.tgz#6f1f26ad66a8f71bbb33b635e74fec43f76b44df" + integrity sha512-yYlyVjvn5lvwCL37i4hPsa1s0ORsjkauhTqbb8MnpvUs7xykmcjGqwlNZ2Q5QpoqkJ1odlM2bqHqJwa28qV6Tw== + dependencies: + "@typescript-eslint/types" "5.1.0" + "@typescript-eslint/visitor-keys" "5.1.0" + +"@typescript-eslint/types@5.1.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.1.0.tgz#a8a75ddfc611660de6be17d3ad950302385607a9" + integrity sha512-sEwNINVxcB4ZgC6Fe6rUyMlvsB2jvVdgxjZEjQUQVlaSPMNamDOwO6/TB98kFt4sYYfNhdhTPBEQqNQZjMMswA== + +"@typescript-eslint/typescript-estree@5.1.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.1.0.tgz#132aea34372df09decda961cb42457433aa6e83d" + integrity sha512-SSz+l9YrIIsW4s0ZqaEfnjl156XQ4VRmJsbA0ZE1XkXrD3cRpzuZSVCyqeCMR3EBjF27IisWakbBDGhGNIOvfQ== + dependencies: + "@typescript-eslint/types" "5.1.0" + "@typescript-eslint/visitor-keys" "5.1.0" + debug "^4.3.2" + globby "^11.0.4" + is-glob "^4.0.3" + semver "^7.3.5" + tsutils "^3.21.0" + +"@typescript-eslint/visitor-keys@5.1.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.1.0.tgz#e01a01b27eb173092705ae983aa1451bd1842630" + integrity sha512-uqNXepKBg81JVwjuqAxYrXa1Ql/YDzM+8g/pS+TCPxba0wZttl8m5DkrasbfnmJGHs4lQ2jTbcZ5azGhI7kK+w== + dependencies: + "@typescript-eslint/types" "5.1.0" + eslint-visitor-keys "^3.0.0" + +"@ungap/promise-all-settled@1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" + integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== + +"@vue/compiler-core@3.2.21": + version "3.2.21" + resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.2.21.tgz#26566c32b2ad838199d471ef5df620a83846f24e" + integrity sha512-NhhiQZNG71KNq1h5pMW/fAXdTF7lJRaSI7LDm2edhHXVz1ROMICo8SreUmQnSf4Fet0UPBVqJ988eF4+936iDQ== + dependencies: + "@babel/parser" "^7.15.0" + "@vue/shared" "3.2.21" + estree-walker "^2.0.2" + source-map "^0.6.1" + +"@vue/compiler-dom@3.2.21": + version "3.2.21" + resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.2.21.tgz#d6f6c85364ef8888f9c4e9122bfba11e78fb398c" + integrity sha512-gsJD3DpYZSYquiA7UIPsMDSlAooYWDvHPq9VRsqzJEk2PZtFvLvHPb4aaMD8Ufd62xzYn32cnnkzsEOJhyGilA== + dependencies: + "@vue/compiler-core" "3.2.21" + "@vue/shared" "3.2.21" + +"@vue/compiler-sfc@3.2.21": + version "3.2.21" + resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.2.21.tgz#42639ee49e725afb7d8f1d1940e75dc17a56002c" + integrity sha512-+yDlUSebKpz/ovxM2vLRRx7w/gVfY767pOfYTgbIhAs+ogvIV2BsIt4fpxlThnlCNChJ+yE0ERUNoROv2kEGEQ== + dependencies: + "@babel/parser" "^7.15.0" + "@vue/compiler-core" "3.2.21" + "@vue/compiler-dom" "3.2.21" + "@vue/compiler-ssr" "3.2.21" + "@vue/ref-transform" "3.2.21" + "@vue/shared" "3.2.21" + estree-walker "^2.0.2" + magic-string "^0.25.7" + postcss "^8.1.10" + source-map "^0.6.1" + +"@vue/compiler-ssr@3.2.21": + version "3.2.21" + resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.2.21.tgz#37d124f89e8adef9fd56b85775de4b5310a0436e" + integrity sha512-eU+A0iWYy+1zAo2CRIJ0zSVlv1iuGAIbNRCnllSJ31pV1lX3jypJYzGbJlSRAbB7VP6E+tYveVT1Oq8JKewa3g== + dependencies: + "@vue/compiler-dom" "3.2.21" + "@vue/shared" "3.2.21" + +"@vue/reactivity@3.2.21": + version "3.2.21" + resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.2.21.tgz#073ad144192ed78a07e151e95a3baa515e4099a2" + integrity sha512-7C57zFm/5E3SSTUhVuYj1InDwuJ+GIVQ/z+H43C9sST85gIThGXVhksl1yWTAadf8Yz4T5lSbqi5Ds8U/ueWcw== + dependencies: + "@vue/shared" "3.2.21" + +"@vue/ref-transform@3.2.21": + version "3.2.21" + resolved "https://registry.yarnpkg.com/@vue/ref-transform/-/ref-transform-3.2.21.tgz#b0c554c9f640c3f005f77e676066aa0faba90984" + integrity sha512-uiEWWBsrGeun9O7dQExYWzXO3rHm/YdtFNXDVqCSoPypzOVxWxdiL+8hHeWzxMB58fVuV2sT80aUtIVyaBVZgQ== + dependencies: + "@babel/parser" "^7.15.0" + "@vue/compiler-core" "3.2.21" + "@vue/shared" "3.2.21" + estree-walker "^2.0.2" + magic-string "^0.25.7" + +"@vue/runtime-core@3.2.21": + version "3.2.21" + resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.2.21.tgz#e12dac8c3893b7aebfc37e32066718d8aa686ac5" + integrity sha512-7oOxKaU0D2IunOAMOOHZgJVrHg63xwng8BZx3fbgmakqEIMwHhQcp+5GV1sOg/sWW7R4UhaRDIUCukO2GRVK2Q== + dependencies: + "@vue/reactivity" "3.2.21" + "@vue/shared" "3.2.21" + +"@vue/runtime-dom@3.2.21": + version "3.2.21" + resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.2.21.tgz#33dd15bc85281e773177a30dc6931c294bd77aa1" + integrity sha512-apBdriD6QsI4ywbllY8kjr9/0scGuStDuvLbJULPQkFPtHzntd51bP5PQTQVAEIc9kwnTozmj6x6ZdX/cwo7xA== + dependencies: + "@vue/runtime-core" "3.2.21" + "@vue/shared" "3.2.21" + csstype "^2.6.8" + +"@vue/server-renderer@3.2.21": + version "3.2.21" + resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.2.21.tgz#887d0a44de76f72313cff2686a24c0315231d634" + integrity sha512-QBgYqVgI7XCSBCqGa4LduV9vpfQFdZBOodFmq5Txk5W/v1KrJ1LoOh2Q0RHiRgtoK/UR9uyvRVcYqOmwHkZNEg== + dependencies: + "@vue/compiler-ssr" "3.2.21" + "@vue/shared" "3.2.21" + +"@vue/shared@3.2.21": + version "3.2.21" + resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.2.21.tgz#4cd80c0e62cf65a7adab2449e86b6f0cb33a130b" + integrity sha512-5EQmIPK6gw4UVYUbM959B0uPsJ58+xoMESCZs3N89XyvJ9e+fX4pqEPrOGV8OroIk3SbEvJcC+eYc8BH9JQrHA== + +"@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/ast@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7" + integrity sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw== + dependencies: + "@webassemblyjs/helper-numbers" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + +"@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/floating-point-hex-parser@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz#f6c61a705f0fd7a6aecaa4e8198f23d9dc179e4f" + integrity sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ== + +"@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-api-error@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz#1a63192d8788e5c012800ba6a7a46c705288fd16" + integrity sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg== + +"@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-buffer@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz#832a900eb444884cde9a7cad467f81500f5e5ab5" + integrity sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA== + +"@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-numbers@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz#64d81da219fbbba1e3bd1bfc74f6e8c4e10a62ae" + integrity sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ== + dependencies: + "@webassemblyjs/floating-point-hex-parser" "1.11.1" + "@webassemblyjs/helper-api-error" "1.11.1" + "@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-bytecode@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz#f328241e41e7b199d0b20c18e88429c4433295e1" + integrity sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q== + +"@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/helper-wasm-section@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz#21ee065a7b635f319e738f0dd73bfbda281c097a" + integrity sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + +"@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/ieee754@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz#963929e9bbd05709e7e12243a099180812992614" + integrity sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ== + 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/leb128@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.1.tgz#ce814b45574e93d76bae1fb2644ab9cdd9527aa5" + integrity sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw== + 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/utf8@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.1.tgz#d1f8b764369e7c6e6bae350e854dec9a59f0a3ff" + integrity sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ== + +"@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-edit@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz#ad206ebf4bf95a058ce9880a8c092c5dec8193d6" + integrity sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/helper-wasm-section" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + "@webassemblyjs/wasm-opt" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + "@webassemblyjs/wast-printer" "1.11.1" + +"@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-gen@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz#86c5ea304849759b7d88c47a32f4f039ae3c8f76" + integrity sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/ieee754" "1.11.1" + "@webassemblyjs/leb128" "1.11.1" + "@webassemblyjs/utf8" "1.11.1" + +"@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-opt@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz#657b4c2202f4cf3b345f8a4c6461c8c2418985f2" + integrity sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + +"@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/wasm-parser@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz#86ca734534f417e9bd3c67c7a1c75d8be41fb199" + integrity sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-api-error" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/ieee754" "1.11.1" + "@webassemblyjs/leb128" "1.11.1" + "@webassemblyjs/utf8" "1.11.1" + +"@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" + +"@webassemblyjs/wast-printer@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz#d0c73beda8eec5426f10ae8ef55cee5e7084c2f0" + integrity sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@xtuc/long" "4.2.2" + +"@webpack-cli/configtest@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-1.1.0.tgz#8342bef0badfb7dfd3b576f2574ab80c725be043" + integrity sha512-ttOkEkoalEHa7RaFYpM0ErK1xc4twg3Am9hfHhL7MVqlHebnkYd2wuI/ZqTDj0cVzZho6PdinY0phFZV3O0Mzg== + +"@webpack-cli/info@^1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.4.0.tgz#b9179c3227ab09cbbb149aa733475fcf99430223" + integrity sha512-F6b+Man0rwE4n0409FyAJHStYA5OIZERxmnUfLVwv0mc0V1wLad3V7jqRlMkgKBeAq07jUvglacNaa6g9lOpuw== + dependencies: + envinfo "^7.7.3" + +"@webpack-cli/serve@^1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.6.0.tgz#2c275aa05c895eccebbfc34cfb223c6e8bd591a2" + integrity sha512-ZkVeqEmRpBV2GHvjjUZqEai2PpUbuq8Bqd//vEYsp63J8WyexI8ppCqVS3Zs0QADf6aWuPdU+0XsPI647PVlQA== + +"@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== + +abort-controller@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" + integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== + dependencies: + event-target-shim "^5.0.0" + +acorn-import-assertions@^1.7.6: + version "1.7.6" + resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.7.6.tgz#580e3ffcae6770eebeec76c3b9723201e9d01f78" + integrity sha512-FlVvVFA1TX6l3lp8VjDnYYq7R1nyW6x3svAt4nDgrWQ9SBaSh9CnbwgSUTasgfNfOG5HlM1ehugCvM+hjo56LA== + +acorn-jsx@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b" + integrity sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng== + +acorn-walk@^8.1.1: + version "8.1.1" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.1.1.tgz#3ddab7f84e4a7e2313f6c414c5b7dac85f4e3ebc" + integrity sha512-FbJdceMlPHEAWJOILDk1fXD8lnTlEIWFkqtfk+MvmL5q/qlHfN7GEHcsFZWt/Tea9jRNPWUZG4G976nqAAmU9w== + +acorn@^7.1.1: + version "7.4.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.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.5.0: + version "8.5.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.5.0.tgz#4512ccb99b3698c752591e9bb4472e38ad43cee2" + integrity sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q== + +agent-base@6: + version "6.0.2" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== + dependencies: + debug "4" + +aggregate-error@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" + integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== + dependencies: + clean-stack "^2.0.0" + indent-string "^4.0.0" + +ajv-keywords@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" + integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== + +ajv@^6.10.0, ajv@^6.12.4, ajv@^6.12.5, ajv@^6.5.5: + version "6.12.5" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.5.tgz#19b0e8bae8f476e5ba666300387775fb1a00a4da" + integrity sha512-lRF8RORchjpKG50/WFf8xmg7sgCLFiYNNnqdKflk63whMQcWR5ngGjiSXkL9bjxy6B2npOK2HSMN49jEBMSkag== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +alphanum-sort@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" + integrity sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM= + +ansi-colors@4.1.1, ansi-colors@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== + +ansi-escapes@^4.3.0: + version "4.3.2" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== + dependencies: + type-fest "^0.21.3" + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= + +ansi-regex@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" + integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== + +ansi-regex@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" + integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^3.2.0, ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359" + integrity sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA== + dependencies: + "@types/color-name" "^1.1.1" + color-convert "^2.0.1" + +anymatch@~3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" + integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +arch@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/arch/-/arch-2.2.0.tgz#1bc47818f305764f23ab3306b0bfc086c5a29d11" + integrity sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ== + +arg@^4.1.0: + version "4.1.3" + resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" + integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +array-timsort@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-timsort/-/array-timsort-1.0.3.tgz#3c9e4199e54fb2b9c3fe5976396a21614ef0d926" + integrity sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ== + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + +asap@~2.0.3: + version "2.0.6" + resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" + integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= + +asn1.js@^5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-5.3.0.tgz#439099fe9174e09cff5a54a9dda70260517e8689" + integrity sha512-WHnQJFcOrIWT1RLOkFFBQkFVvyt9BPOOrH+Dp152Zk4R993rSzXUGPmkybIcUFhHE2d/iHH+nCaOWVCDbO8fgA== + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + safer-buffer "^2.1.0" + +asn1@~0.2.3: + version "0.2.4" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" + integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== + dependencies: + safer-buffer "~2.1.0" + +assert-never@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/assert-never/-/assert-never-1.2.1.tgz#11f0e363bf146205fb08193b5c7b90f4d1cf44fe" + integrity sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw== + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= + +astral-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" + integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== + +async@^2.6.0: + version "2.6.3" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" + integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== + dependencies: + lodash "^4.17.14" + +async@^3.2.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.1.tgz#d3274ec66d107a47476a4c49136aacdb00665fc8" + integrity sha512-XdD5lRO/87udXCMC9meWdYiR+Nq6ZjUfXidViUZGu2F1MO4T3XwZ1et0hb2++BgLfhyJwy44BGB/yx80ABx8hg== + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + +at-least-node@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" + integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== + +autobind-decorator@2.4.0, autobind-decorator@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/autobind-decorator/-/autobind-decorator-2.4.0.tgz#ea9e1c98708cf3b5b356f7cf9f10f265ff18239c" + integrity sha512-OGYhWUO72V6DafbF8PM8rm3EPbfuyMZcJhtm5/n26IDwO18pohE4eNazLoCGhPiXOCD0gEGmrbU3849QvM8bbw== + +autosize@4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/autosize/-/autosize-4.0.4.tgz#924f13853a466b633b9309330833936d8bccce03" + integrity sha512-5yxLQ22O0fCRGoxGfeLSNt3J8LB1v+umtpMnPW6XjkTWXKoN0AmXAIhelJcDtFT/Y/wYWmfE+oqU10Q0b8FhaQ== + +autwh@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/autwh/-/autwh-0.1.0.tgz#24a5300923309d105133401a2568f9c8ab7d7e03" + integrity sha512-IkGZ4kjVlZMkEmDiVtZpGG3lDGHPqsMBIh4IpQKN7idYOJ5EGedqKPO+ychNqh8zrJEEqYsN0NcBkcmoE2uFAw== + dependencies: + oauth "0.9.15" + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= + +aws4@^1.8.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.9.1.tgz#7e33d8f7d449b3f673cd72deb9abdc552dbe528e" + integrity sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug== + +axios@^0.21.1: + version "0.21.1" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.1.tgz#22563481962f4d6bde9a76d516ef0e5d3c09b2b8" + integrity sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA== + dependencies: + follow-redirects "^1.10.0" + +babel-walk@3.0.0-canary-5: + version "3.0.0-canary-5" + resolved "https://registry.yarnpkg.com/babel-walk/-/babel-walk-3.0.0-canary-5.tgz#f66ecd7298357aee44955f235a6ef54219104b11" + integrity sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw== + dependencies: + "@babel/types" "^7.9.6" + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + +base32.js@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/base32.js/-/base32.js-0.0.1.tgz#d045736a57b1f6c139f0c7df42518a84e91bb2ba" + integrity sha1-0EVzalex9sE58MffQlGKhOkbsro= + +base64-js@^1.0.2: + version "1.3.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" + integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== + +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= + dependencies: + tweetnacl "^0.14.3" + +big-integer@^1.6.16: + version "1.6.48" + resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.48.tgz#8fd88bd1632cba4a1c8c3e3d7159f08bb95b4b9e" + integrity sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w== + +big.js@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" + integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== + +binary-extensions@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.0.0.tgz#23c0df14f6a88077f5f986c0d167ec03c3d5537c" + integrity sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow== + +blob-util@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/blob-util/-/blob-util-2.0.2.tgz#3b4e3c281111bb7f11128518006cdc60b403a1eb" + integrity sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ== + +bluebird@3.7.2, bluebird@^3.7.2: + version "3.7.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== + +blurhash@1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/blurhash/-/blurhash-1.1.4.tgz#a7010ceb3019cd2c9809b17c910ebf6175d29244" + integrity sha512-MXIPz6zwYUKayju+Uidf83KhH0vodZfeRl6Ich8Gu+KGl0JgKiFq9LsfqV7cVU5fKD/AotmduZqvOfrGKOfTaA== + +bn.js@^4.0.0: + version "4.11.8" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" + integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== + +boolbase@^1.0.0, boolbase@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^3.0.1, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +broadcast-channel@4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/broadcast-channel/-/broadcast-channel-4.5.0.tgz#d4717c493e219908fcb7f2f9078fe0baf95b77c1" + integrity sha512-jp+VPlQ1HyR0CM3uIYUrdpXupBvhTMFRkjR6mEmt5W4HaGDPFEzrO2Jqvi2PZ6zCC4zwLeco7CC5EUJPrVH8Tw== + dependencies: + "@babel/runtime" "^7.16.0" + detect-node "^2.1.0" + microseconds "0.2.0" + nano-time "1.0.0" + oblivious-set "1.0.0" + rimraf "3.0.2" + unload "2.3.1" + +browser-stdout@1.3.1: + version "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.0.0, 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" + +browserslist@^4.16.0: + version "4.16.4" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.4.tgz#7ebf913487f40caf4637b892b268069951c35d58" + integrity sha512-d7rCxYV8I9kj41RH8UKYnvDYCRENUlHRgyXy/Rhr/1BaeLGfiCptEdFE8MIrvGfWbBFNjVYx76SQWvNX1j+/cQ== + dependencies: + caniuse-lite "^1.0.30001208" + colorette "^1.2.2" + electron-to-chromium "^1.3.712" + escalade "^3.1.1" + node-releases "^1.1.71" + +browserslist@^4.16.6: + version "4.16.6" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.6.tgz#d7901277a5a88e554ed305b183ec9b0c08f66fa2" + integrity sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ== + dependencies: + caniuse-lite "^1.0.30001219" + colorette "^1.2.2" + electron-to-chromium "^1.3.723" + escalade "^3.1.1" + node-releases "^1.1.71" + +buffer-alloc-unsafe@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" + integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== + +buffer-alloc@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" + integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== + dependencies: + buffer-alloc-unsafe "^1.1.0" + buffer-fill "^1.0.0" + +buffer-crc32@~0.2.3: + version "0.2.13" + resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" + integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI= + +buffer-equal-constant-time@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" + integrity sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk= + +buffer-fill@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" + integrity sha1-+PeLdniYiO858gXNY39o5wISKyw= + +buffer-from@^1.0.0, buffer-from@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== + +buffer@^5.4.3: + version "5.6.0" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.6.0.tgz#a31749dc7d81d84db08abf937b6b8c4033f62786" + integrity sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + +bufferutil@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.1.tgz#3a177e8e5819a1243fe16b63a199951a7ad8d4a7" + integrity sha512-xowrxvpxojqkagPcWRQVXZl0YXhRhAtBEIq3VoER1NH5Mw1n1o0ojdspp+GS2J//2gCVyrzQDApQ4unGF+QOoA== + dependencies: + node-gyp-build "~3.7.0" + +cacheable-lookup@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.3.tgz#049fdc59dffdd4fc285e8f4f82936591bd59fec3" + integrity sha512-W+JBqF9SWe18A72XFzN/V/CULFzPm7sBXzzR6ekkE+3tLG72wFZrBiBZhrZuDoYexop4PHJVdFAKb/Nj9+tm9w== + +cacheable-request@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.1.tgz#062031c2856232782ed694a257fa35da93942a58" + integrity sha512-lt0mJ6YAnsrBErpTMWeu5kl/tg9xMAWjavYTN6VQXM1A/teBITuNcccXsCxF0tDQQJf9DfAaX5O4e0zp0KlfZw== + dependencies: + clone-response "^1.0.2" + get-stream "^5.1.0" + http-cache-semantics "^4.0.0" + keyv "^4.0.0" + lowercase-keys "^2.0.0" + normalize-url "^4.1.0" + responselike "^2.0.0" + +cachedir@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/cachedir/-/cachedir-2.3.0.tgz#0c75892a052198f0b21c7c1804d8331edfcae0e8" + integrity sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw== + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +camelcase@^5.0.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +camelcase@^6.0.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809" + integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== + +caniuse-api@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0" + integrity sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw== + dependencies: + browserslist "^4.0.0" + caniuse-lite "^1.0.0" + lodash.memoize "^4.1.2" + lodash.uniq "^4.5.0" + +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001181, caniuse-lite@^1.0.30001208, caniuse-lite@^1.0.30001219: + version "1.0.30001279" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001279.tgz" + integrity sha512-VfEHpzHEXj6/CxggTwSFoZBBYGQfQv9Cf42KPlO79sWXCD1QNKWKsKzFeWL7QpZHJQYAvocqV6Rty1yJMkqWLQ== + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= + +chalk@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.0.0.tgz#6e98081ed2d17faab615eb52ac66ec1fe6209e72" + integrity sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chalk@^2.0.0, chalk@^2.4.1: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^4.0.0, chalk@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" + integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +char-regex@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" + integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== + +character-parser@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/character-parser/-/character-parser-2.2.0.tgz#c7ce28f36d4bcd9744e5ffc2c5fcde1c73261fc0" + integrity sha1-x84o821LzZdE5f/CxfzeHHMmH8A= + dependencies: + is-regex "^1.0.3" + +chart.js@3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-3.6.0.tgz#a87fce8431d4e7c5523d721f487f53aada1e42fe" + integrity sha512-iOzzDKePL+bj+ccIsVAgWQehCXv8xOKGbaU2fO/myivH736zcx535PGJzQGanvcSGVOqX6yuLZsN3ygcQ35UgQ== + +chartjs-adapter-date-fns@2.0.0: + version "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-zoom@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/chartjs-plugin-zoom/-/chartjs-plugin-zoom-1.1.1.tgz#8a28923a17fcb5eb57a0dc94c5113bf402677647" + integrity sha512-1q54WOzK7FtAjkbemQeqvmFUV0btNYIQny2HbQ6Awq9wUtCz7Zmj6vIgp3C1DYMQwN0nqgpC3vnApqiwI7cSdQ== + dependencies: + hammerjs "^2.0.8" + +check-more-types@2.24.0, check-more-types@^2.24.0: + version "2.24.0" + resolved "https://registry.yarnpkg.com/check-more-types/-/check-more-types-2.24.0.tgz#1420ffb10fd444dcfc79b43891bbfffd32a84600" + integrity sha1-FCD/sQ/URNz8ebQ4kbv//TKoRgA= + +chokidar@3.5.1, "chokidar@>=3.0.0 <4.0.0", chokidar@^3.3.1, chokidar@^3.5.0: + version "3.3.1" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.3.1.tgz#c84e5b3d18d9a4d77558fef466b1bf16bbeb3450" + integrity sha512-4QYCEWOcK3OJrxwvyyAOxFuhpvOVCYkr33LPfFNBjAD/w3sEzWsp2BUOkI4l9bHvWioAd0rc6NlHUOEaWkTeqg== + dependencies: + anymatch "~3.1.1" + braces "~3.0.2" + glob-parent "~5.1.0" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.3.0" + optionalDependencies: + fsevents "~2.1.2" + +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" + +ci-info@^3.1.1: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.2.0.tgz#2876cb948a498797b5236f0095bc057d0dca38b6" + integrity sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A== + +clean-stack@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" + integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== + +cli-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" + integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== + dependencies: + restore-cursor "^3.1.0" + +cli-table3@~0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.0.tgz#b7b1bc65ca8e7b5cef9124e13dc2b21e2ce4faee" + integrity sha512-gnB85c3MGC7Nm9I/FkiasNBOKjOiO1RNuXXarQms37q4QMpWdlbBgD/VnOStA2faG1dpXMv31RFApjX1/QdgWQ== + dependencies: + object-assign "^4.1.0" + string-width "^4.2.0" + optionalDependencies: + colors "^1.1.2" + +cli-truncate@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-2.1.0.tgz#c39e28bf05edcde5be3b98992a22deed5a2b93c7" + integrity sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg== + dependencies: + slice-ansi "^3.0.0" + string-width "^4.2.0" + +cliui@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" + integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== + dependencies: + string-width "^3.1.0" + strip-ansi "^5.2.0" + wrap-ansi "^5.1.0" + +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + +clone-deep@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" + integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== + dependencies: + is-plain-object "^2.0.4" + kind-of "^6.0.2" + shallow-clone "^3.0.0" + +clone-response@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" + integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws= + dependencies: + mimic-response "^1.0.0" + +coa@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/coa/-/coa-2.0.2.tgz#43f6c21151b4ef2bf57187db0d73de229e3e7ec3" + integrity sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA== + dependencies: + "@types/q" "^1.5.1" + chalk "^2.4.1" + q "^1.1.2" + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +colord@^2.9.1: + version "2.9.1" + resolved "https://registry.yarnpkg.com/colord/-/colord-2.9.1.tgz#c961ea0efeb57c9f0f4834458f26cb9cc4a3f90e" + integrity sha512-4LBMSt09vR0uLnPVkOUBnmxgoaeN4ewRbx801wY/bXcltXfpR/G46OdWn96XpYmCWuYvO46aBZP4NgX8HpNAcw== + +colorette@^1.2.0, colorette@^1.2.1, colorette@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" + integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w== + +colorette@^2.0.14: + version "2.0.15" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.15.tgz#8e634aa0429b110d24be82eac4d42f5ea65ab2d5" + integrity sha512-lIFQhufWaVvwi4wOlX9Gx5b0Nmw3XAZ8HzHNH9dfxhe+JaKNTmX6QLk4o7UHyI+tUY8ClvyfaHUm5bf61O3psA== + +colors@^1.1.2, colors@^1.3.3: + version "1.4.0" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" + integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== + +combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +commander@^2.20.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== + +commander@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae" + integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg== + +commander@^6.0.0, commander@^6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" + integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== + +commander@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-7.0.0.tgz#3e2bbfd8bb6724760980988fb5b22b7ee6b71ab2" + integrity sha512-ovx/7NkTrnPuIV8sqk/GjUIIM1+iUQeqA3ye2VNpq9sVoiZsooObWlQy+OPWGI17GDaEoybuAGJm6U8yC077BA== + +commander@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" + integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== + +comment-json@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/comment-json/-/comment-json-4.1.1.tgz#49df4948704bebb1cc0ffa6910e25669b668b7c5" + integrity sha512-v8gmtPvxhBlhdRBLwdHSjGy9BgA23t9H1FctdQKyUrErPjSrJcdDMqBq9B4Irtm7w3TNYLQJNH6ARKnpyag1sA== + dependencies: + array-timsort "^1.0.3" + core-util-is "^1.0.2" + esprima "^4.0.1" + has-own-prop "^2.0.0" + repeat-string "^1.6.1" + +common-tags@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.0.tgz#8e3153e542d4a39e9b10554434afaaf98956a937" + integrity sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw== + +compare-versions@3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-3.6.0.tgz#1a5689913685e5a87637b8d3ffca75514ec41d62" + integrity sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +concurrently@6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-6.3.0.tgz#63128cb4a6ed54d3c0ed8528728590a5fe54582a" + integrity sha512-k4k1jQGHHKsfbqzkUszVf29qECBrkvBKkcPJEUDTyVR7tZd1G/JOfnst4g1sYbFvJ4UjHZisj1aWQR8yLKpGPw== + dependencies: + chalk "^4.1.0" + date-fns "^2.16.1" + lodash "^4.17.21" + rxjs "^6.6.3" + spawn-command "^0.0.2-1" + supports-color "^8.1.0" + tree-kill "^1.2.2" + yargs "^16.2.0" + +constantinople@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/constantinople/-/constantinople-4.0.1.tgz#0def113fa0e4dc8de83331a5cf79c8b325213151" + integrity sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw== + dependencies: + "@babel/parser" "^7.6.0" + "@babel/types" "^7.6.1" + +content-disposition@0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" + integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== + dependencies: + safe-buffer "5.1.2" + +core-util-is@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + +core-util-is@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + +cosmiconfig@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.0.tgz#ef9b44d773959cae63ddecd122de23853b60f8d3" + integrity sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA== + dependencies: + "@types/parse-json" "^4.0.0" + import-fresh "^3.2.1" + parse-json "^5.0.0" + path-type "^4.0.0" + yaml "^1.10.0" + +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== + dependencies: + exit-on-epipe "~1.0.1" + printj "~1.1.0" + +create-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" + integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== + +cross-env@7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf" + integrity sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw== + dependencies: + cross-spawn "^7.0.1" + +cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +css-color-names@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-1.0.1.tgz#6ff7ee81a823ad46e020fa2fd6ab40a887e2ba67" + integrity sha512-/loXYOch1qU1biStIFsHH8SxTmOseh1IJqFvy8IujXOm1h+QjUdDhkzOrR5HG8K8mlxREj0yfi8ewCHx0eMxzA== + +css-declaration-sorter@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.0.3.tgz#9dfd8ea0df4cc7846827876fafb52314890c21a9" + integrity sha512-52P95mvW1SMzuRZegvpluT6yEv0FqQusydKQPZsNN5Q7hh8EwQvN8E2nwuJ16BBvNN6LcoIZXu/Bk58DAhrrxw== + dependencies: + timsort "^0.3.0" + +css-loader@6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.5.1.tgz#0c43d4fbe0d97f699c91e9818cb585759091d1b1" + integrity sha512-gEy2w9AnJNnD9Kuo4XAP9VflW/ujKoS9c/syO+uWMlm5igc7LysKzPXaDoR2vroROkSwsTS2tGr1yGGEbZOYZQ== + dependencies: + icss-utils "^5.1.0" + postcss "^8.2.15" + postcss-modules-extract-imports "^3.0.0" + postcss-modules-local-by-default "^4.0.0" + postcss-modules-scope "^3.0.0" + postcss-modules-values "^4.0.0" + postcss-value-parser "^4.1.0" + semver "^7.3.5" + +css-select-base-adapter@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz#3b2ff4972cc362ab88561507a95408a1432135d7" + integrity sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w== + +css-select@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-2.1.0.tgz#6a34653356635934a81baca68d0255432105dbef" + integrity sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ== + dependencies: + boolbase "^1.0.0" + css-what "^3.2.1" + domutils "^1.7.0" + nth-check "^1.0.2" + +css-select@^4.1.3: + version "4.1.3" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.1.3.tgz#a70440f70317f2669118ad74ff105e65849c7067" + integrity sha512-gT3wBNd9Nj49rAbmtFHj1cljIAOLYSX1nZ8CB7TBO3INYckygm5B7LISU/szY//YmdiSLbJvDLOx9VnMVpMBxA== + dependencies: + boolbase "^1.0.0" + css-what "^5.0.0" + domhandler "^4.2.0" + domutils "^2.6.0" + nth-check "^2.0.0" + +css-tree@1.0.0-alpha.37: + version "1.0.0-alpha.37" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.37.tgz#98bebd62c4c1d9f960ec340cf9f7522e30709a22" + integrity sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg== + dependencies: + mdn-data "2.0.4" + source-map "^0.6.1" + +css-tree@1.0.0-alpha.39: + version "1.0.0-alpha.39" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.39.tgz#2bff3ffe1bb3f776cf7eefd91ee5cba77a149eeb" + integrity sha512-7UvkEYgBAHRG9Nt980lYxjsTrCyHFN53ky3wVsDkiMdVqylqRt+Zc+jm5qw7/qyOvN2dHSYtX0e4MbCCExSvnA== + dependencies: + mdn-data "2.0.6" + source-map "^0.6.1" + +css-tree@^1.1.2, css-tree@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d" + integrity sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q== + dependencies: + mdn-data "2.0.14" + source-map "^0.6.1" + +css-what@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.2.1.tgz#f4a8f12421064621b456755e34a03a2c22df5da1" + integrity sha512-WwOrosiQTvyms+Ti5ZC5vGEK0Vod3FTt1ca+payZqvKuGJF+dq7bG63DstxtN0dpm6FxY27a/zS3Wten+gEtGw== + +css-what@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-5.1.0.tgz#3f7b707aadf633baf62c2ceb8579b545bb40f7fe" + integrity sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw== + +cssesc@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" + integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== + +cssnano-preset-default@^5.1.6: + version "5.1.6" + resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-5.1.6.tgz#1bdb83be6a6b1fee6dc5e9ec2e61286bcadcc7a6" + integrity sha512-X2nDeNGBXc0486oHjT2vSj+TdeyVsxRvJUxaOH50hOM6vSDLkKd0+59YXpSZRInJ4sNtBOykS4KsPfhdrU/35w== + dependencies: + css-declaration-sorter "^6.0.3" + cssnano-utils "^2.0.1" + postcss-calc "^8.0.0" + postcss-colormin "^5.2.1" + postcss-convert-values "^5.0.2" + postcss-discard-comments "^5.0.1" + postcss-discard-duplicates "^5.0.1" + postcss-discard-empty "^5.0.1" + postcss-discard-overridden "^5.0.1" + postcss-merge-longhand "^5.0.3" + postcss-merge-rules "^5.0.2" + postcss-minify-font-values "^5.0.1" + postcss-minify-gradients "^5.0.3" + postcss-minify-params "^5.0.1" + postcss-minify-selectors "^5.1.0" + postcss-normalize-charset "^5.0.1" + postcss-normalize-display-values "^5.0.1" + postcss-normalize-positions "^5.0.1" + postcss-normalize-repeat-style "^5.0.1" + postcss-normalize-string "^5.0.1" + postcss-normalize-timing-functions "^5.0.1" + postcss-normalize-unicode "^5.0.1" + postcss-normalize-url "^5.0.2" + postcss-normalize-whitespace "^5.0.1" + postcss-ordered-values "^5.0.2" + postcss-reduce-initial "^5.0.1" + postcss-reduce-transforms "^5.0.1" + postcss-svgo "^5.0.3" + postcss-unique-selectors "^5.0.1" + +cssnano-utils@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/cssnano-utils/-/cssnano-utils-2.0.1.tgz#8660aa2b37ed869d2e2f22918196a9a8b6498ce2" + integrity sha512-i8vLRZTnEH9ubIyfdZCAdIdgnHAUeQeByEeQ2I7oTilvP9oHO6RScpeq3GsFUVqeB8uZgOQ9pw8utofNn32hhQ== + +cssnano@5.0.10: + version "5.0.10" + resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-5.0.10.tgz#92207eb7c9c6dc08d318050726f9fad0adf7220b" + integrity sha512-YfNhVJJ04imffOpbPbXP2zjIoByf0m8E2c/s/HnvSvjXgzXMfgopVjAEGvxYOjkOpWuRQDg/OZFjO7WW94Ri8w== + dependencies: + cssnano-preset-default "^5.1.6" + is-resolvable "^1.1.0" + lilconfig "^2.0.3" + yaml "^1.10.2" + +csso@^4.0.2: + version "4.0.3" + resolved "https://registry.yarnpkg.com/csso/-/csso-4.0.3.tgz#0d9985dc852c7cc2b2cacfbbe1079014d1a8e903" + integrity sha512-NL3spysxUkcrOgnpsT4Xdl2aiEiBG6bXswAABQVHcMrfjjBisFOKwLDOmf4wf32aPdcJws1zds2B0Rg+jqMyHQ== + dependencies: + css-tree "1.0.0-alpha.39" + +csso@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/csso/-/csso-4.2.0.tgz#ea3a561346e8dc9f546d6febedd50187cf389529" + integrity sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA== + dependencies: + css-tree "^1.1.2" + +csstype@^2.6.8: + version "2.6.13" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.13.tgz#a6893015b90e84dd6e85d0e3b442a1e84f2dbe0f" + integrity sha512-ul26pfSQTZW8dcOnD2iiJssfXw0gdNVX9IJDH/X3K5DGPfj+fUYe3kB+swUY6BF3oZDxaID3AJt+9/ojSAE05A== + +cypress@8.5.0: + version "8.5.0" + resolved "https://registry.yarnpkg.com/cypress/-/cypress-8.5.0.tgz#5712ca170913f8344bf167301205c4217c1eb9bd" + integrity sha512-MMkXIS+Ro2KETn4gAlG3tIc/7FiljuuCZP0zpd9QsRG6MZSyZW/l1J3D4iQM6WHsVxuX4rFChn5jPFlC2tNSvQ== + dependencies: + "@cypress/request" "^2.88.6" + "@cypress/xvfb" "^1.2.4" + "@types/node" "^14.14.31" + "@types/sinonjs__fake-timers" "^6.0.2" + "@types/sizzle" "^2.3.2" + arch "^2.2.0" + blob-util "^2.0.2" + bluebird "^3.7.2" + cachedir "^2.3.0" + chalk "^4.1.0" + check-more-types "^2.24.0" + cli-cursor "^3.1.0" + cli-table3 "~0.6.0" + commander "^5.1.0" + common-tags "^1.8.0" + dayjs "^1.10.4" + debug "^4.3.2" + enquirer "^2.3.6" + eventemitter2 "^6.4.3" + execa "4.1.0" + executable "^4.1.1" + extract-zip "2.0.1" + figures "^3.2.0" + fs-extra "^9.1.0" + getos "^3.2.1" + is-ci "^3.0.0" + is-installed-globally "~0.4.0" + lazy-ass "^1.6.0" + listr2 "^3.8.3" + lodash "^4.17.21" + log-symbols "^4.0.0" + minimist "^1.2.5" + ospath "^1.2.2" + pretty-bytes "^5.6.0" + proxy-from-env "1.0.0" + ramda "~0.27.1" + request-progress "^3.0.0" + 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: + version "1.0.1" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" + integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== + dependencies: + es5-ext "^0.10.50" + type "^1.0.1" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= + dependencies: + assert-plus "^1.0.0" + +date-fns@2.25.0: + version "2.25.0" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.25.0.tgz#8c5c8f1d958be3809a9a03f4b742eba894fc5680" + integrity sha512-ovYRFnTrbGPD4nqaEqescPEv1mNwvt+UTqI3Ay9SzNtey9NZnYu6E2qCcBBgJ6/2VF1zGGygpyTDITqpQQ5e+w== + +date-fns@^2.16.1: + version "2.19.0" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.19.0.tgz#65193348635a28d5d916c43ec7ce6fbd145059e1" + integrity sha512-X3bf2iTPgCAQp9wvjOQytnf5vO5rESYRXlPIVcgSbtT5OTScPcsf9eZU+B/YIkKAtYr5WeCii58BgATrNitlWg== + +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== + +dayjs@^1.10.4: + version "1.10.6" + resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.10.6.tgz#288b2aa82f2d8418a6c9d4df5898c0737ad02a63" + integrity sha512-AztC/IOW4L1Q41A86phW5Thhcrco3xuAA+YX/BLpLWWjRcTj5TOt/QImBLmCKlrF7u7k47arTnOyL6GnbG8Hvw== + +debug@2, debug@^2.2.0, debug@^2.5.2: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@4, debug@4.3.1, debug@^4.1.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" + integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== + dependencies: + ms "2.1.2" + +debug@4.3.2, debug@^4.3.2: + version "4.3.2" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" + integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== + dependencies: + ms "2.1.2" + +debug@^3.1.0: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + +debug@^3.2.6: + version "3.2.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== + dependencies: + ms "^2.1.1" + +decamelize@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + +decamelize@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" + integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== + +decompress-response@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" + integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== + dependencies: + mimic-response "^3.1.0" + +deep-is@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= + +defer-to-connect@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.0.tgz#83d6b199db041593ac84d781b5222308ccf4c2c1" + integrity sha512-bYL2d05vOSf1JEZNx5vSAtPuBMkX8K9EUutg7zlKvTqKXHt7RhWJFbmd7qakVuf13i+IkGmp6FwSsONOf6VYIg== + +define-properties@^1.1.2, define-properties@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + +detect-file@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7" + integrity sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc= + +detect-node@2.1.0, detect-node@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" + integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== + +diff@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" + integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== + +diff@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + +dijkstrajs@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/dijkstrajs/-/dijkstrajs-1.0.1.tgz#d3cd81221e3ea40742cfcde556d4e99e98ddc71b" + integrity sha1-082BIh4+pAdCz83lVtTpnpjdxxs= + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + +doctypes@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/doctypes/-/doctypes-1.1.0.tgz#ea80b106a87538774e8a3a4a5afe293de489e0a9" + integrity sha1-6oCxBqh1OHdOijpKWv4pPeSJ4Kk= + +dom-serializer@0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51" + integrity sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g== + dependencies: + domelementtype "^2.0.1" + entities "^2.0.0" + +dom-serializer@^1.0.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.3.1.tgz#d845a1565d7c041a95e5dab62184ab41e3a519be" + integrity sha512-Pv2ZluG5ife96udGgEDovOOOA5UELkltfJpnIExPrAk1LTvecolUGn6lIaoLh86d83GiB86CjzciMd9BuRB71Q== + dependencies: + domelementtype "^2.0.1" + domhandler "^4.0.0" + entities "^2.0.0" + +domelementtype@1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" + integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== + +domelementtype@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.0.1.tgz#1f8bdfe91f5a78063274e803b4bdcedf6e94f94d" + integrity sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ== + +domelementtype@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57" + integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A== + +domhandler@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.1.0.tgz#c1d8d494d5ec6db22de99e46a149c2a4d23ddd43" + integrity sha512-/6/kmsGlMY4Tup/nGVutdrK9yQi4YjWVcVeoQmixpzjOUK1U7pQkvAPHBJeUxOgxF0J8f8lwCJSlCfD0V4CMGQ== + dependencies: + domelementtype "^2.2.0" + +domhandler@^4.2.0: + version "4.2.2" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.2.2.tgz#e825d721d19a86b8c201a35264e226c678ee755f" + integrity sha512-PzE9aBMsdZO8TK4BnuJwH0QT41wgMbRzuZrHUcpYncEjmQazq8QEaBWgLG7ZyC/DAZKEgglpIA6j4Qn/HmxS3w== + dependencies: + domelementtype "^2.2.0" + +domutils@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" + integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg== + dependencies: + dom-serializer "0" + domelementtype "1" + +domutils@^2.6.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135" + integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A== + dependencies: + dom-serializer "^1.0.1" + domelementtype "^2.2.0" + domhandler "^4.2.0" + +duplexer@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" + integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== + +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + +ecdsa-sig-formatter@1.0.11: + version "1.0.11" + resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf" + integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ== + dependencies: + safe-buffer "^5.0.1" + +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== + +electron-to-chromium@^1.3.712: + version "1.3.717" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.717.tgz#78d4c857070755fb58ab64bcc173db1d51cbc25f" + integrity sha512-OfzVPIqD1MkJ7fX+yTl2nKyOE4FReeVfMCzzxQS+Kp43hZYwHwThlGP+EGIZRXJsxCM7dqo8Y65NOX/HP12iXQ== + +electron-to-chromium@^1.3.723: + version "1.3.742" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.742.tgz#7223215acbbd3a5284962ebcb6df85d88b95f200" + integrity sha512-ihL14knI9FikJmH2XUIDdZFWJxvr14rPSdOhJ7PpS27xbz8qmaRwCwyg/bmFwjWKmWK9QyamiCZVCvXm5CH//Q== + +emoji-regex@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +emojis-list@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" + integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== + +end-of-stream@^1.1.0: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + +enhanced-resolve@^5.0.0: + version "5.8.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.8.0.tgz#d9deae58f9d3773b6a111a5a46831da5be5c9ac0" + integrity sha512-Sl3KRpJA8OpprrtaIswVki3cWPiPKxXuFxJXBp+zNb6s6VwNWwFRUdtmzd2ReUut8n+sCPx7QCtQ7w5wfJhSgQ== + dependencies: + 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" + +enhanced-resolve@^5.8.3: + version "5.8.3" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz#6d552d465cce0423f5b3d718511ea53826a7b2f0" + integrity sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" + +enquirer@^2.3.5, enquirer@^2.3.6: + version "2.3.6" + resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" + integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== + dependencies: + ansi-colors "^4.1.1" + +entities@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.0.tgz#68d6084cab1b079767540d80e56a39b423e4abf4" + integrity sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw== + +envinfo@^7.7.3: + version "7.7.3" + resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.7.3.tgz#4b2d8622e3e7366afb8091b23ed95569ea0208cc" + integrity sha512-46+j5QxbPWza0PB1i15nZx0xQ4I/EfQxg9J8Had3b408SV63nEtor2e+oiY63amTo9KTuh2a3XLObNwduxYwwA== + +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +es-abstract@^1.17.0-next.1, es-abstract@^1.17.2, es-abstract@^1.17.5: + version "1.17.5" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.5.tgz#d8c9d1d66c8981fb9200e2251d799eee92774ae9" + integrity sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg== + dependencies: + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + is-callable "^1.1.5" + is-regex "^1.0.5" + object-inspect "^1.7.0" + object-keys "^1.1.1" + object.assign "^4.1.0" + string.prototype.trimleft "^2.1.1" + string.prototype.trimright "^2.1.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-module-lexer@^0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.0.tgz#fe4c4621977bc668e285c5f1f70ca3b451095fda" + integrity sha512-qU2eN/XHsrl3E4y7mK1wdWnyy5c8gXtCbfP6Xcsemm7fPUR1PIV1JhZfP7ojcN0Fzp69CfrS3u76h2tusvfKiQ== + +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" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + +es5-ext@^0.10.35, es5-ext@^0.10.50: + version "0.10.53" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.53.tgz#93c5a3acfdbef275220ad72644ad02ee18368de1" + integrity sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q== + dependencies: + es6-iterator "~2.0.3" + es6-symbol "~3.1.3" + next-tick "~1.0.0" + +es6-iterator@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c= + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + +es6-symbol@^3.1.1, es6-symbol@~3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" + integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== + dependencies: + d "^1.0.1" + ext "^1.1.2" + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-regexp@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/escape-regexp/-/escape-regexp-0.0.1.tgz#f44bda12d45bbdf9cb7f862ee7e4827b3dd32254" + integrity sha1-9EvaEtRbvfnLf4Yu5+SCez3TIlQ= + +escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +eslint-plugin-vue@8.0.3: + version "8.0.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-vue/-/eslint-plugin-vue-8.0.3.tgz#791cc4543940319e612ea61a1d779e8c87cf749a" + integrity sha512-Rlhhy5ltzde0sRwSkqHuNePTXLMMaJ5+qsQubM4RYloYsQ8cXlnJT5MDaCzSirkGADipOHtmQXIbbPFAzUrADg== + dependencies: + eslint-utils "^3.0.0" + natural-compare "^1.4.0" + semver "^7.3.5" + vue-eslint-parser "^8.0.1" + +eslint-scope@5.1.1, eslint-scope@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + +eslint-scope@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-6.0.0.tgz#9cf45b13c5ac8f3d4c50f46a5121f61b3e318978" + integrity sha512-uRDL9MWmQCkaFus8RF5K9/L/2fn+80yoW3jkD53l4shjCh26fCtvJGasxjUqP5OT87SYTxCVA3BwTUzuELx9kA== + dependencies: + esrecurse "^4.3.0" + estraverse "^5.2.0" + +eslint-utils@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672" + integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== + dependencies: + eslint-visitor-keys "^2.0.0" + +eslint-visitor-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz#21fdc8fbcd9c795cc0321f0563702095751511a8" + integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ== + +eslint-visitor-keys@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.0.0.tgz#e32e99c6cdc2eb063f204eda5db67bfe58bb4186" + integrity sha512-mJOZa35trBTb3IyRmo8xmKBZlxf+N7OnUl4+ZhJHs/r+0770Wh/LEACE2pqMGMe27G/4y8P2bYGk4J70IC5k1Q== + +eslint@8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.2.0.tgz#44d3fb506d0f866a506d97a0fc0e90ee6d06a815" + integrity sha512-erw7XmM+CLxTOickrimJ1SiF55jiNlVSp2qqm0NuBWPtHYQCegD5ZMaW0c3i5ytPqL+SSLaCxdvQXFPLJn+ABw== + dependencies: + "@eslint/eslintrc" "^1.0.4" + "@humanwhocodes/config-array" "^0.6.0" + ajv "^6.10.0" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.3.2" + doctrine "^3.0.0" + enquirer "^2.3.5" + escape-string-regexp "^4.0.0" + eslint-scope "^6.0.0" + eslint-utils "^3.0.0" + eslint-visitor-keys "^3.0.0" + espree "^9.0.0" + esquery "^1.4.0" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" + functional-red-black-tree "^1.0.1" + glob-parent "^6.0.1" + globals "^13.6.0" + ignore "^4.0.6" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + js-yaml "^4.1.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash.merge "^4.6.2" + minimatch "^3.0.4" + natural-compare "^1.4.0" + optionator "^0.9.1" + progress "^2.0.0" + regexpp "^3.2.0" + semver "^7.2.1" + strip-ansi "^6.0.1" + strip-json-comments "^3.1.0" + text-table "^0.2.0" + v8-compile-cache "^2.0.3" + +espree@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.0.0.tgz#e90a2965698228502e771c7a58489b1a9d107090" + integrity sha512-r5EQJcYZ2oaGbeR0jR0fFVijGOcwai07/690YRXLINuhmVeRY4UKSAsQPe/0BNuDgwP7Ophoc1PRsr2E3tkbdQ== + dependencies: + acorn "^8.5.0" + acorn-jsx "^5.3.1" + eslint-visitor-keys "^3.0.0" + +esprima@^4.0.0, esprima@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esquery@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" + integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== + dependencies: + estraverse "^5.1.0" + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.1.0.tgz#374309d39fd935ae500e7b92e8a6b4c720e59642" + integrity sha512-FyohXK+R0vE+y1nHLoBM7ZTyqRpqAlhdZHCWIWEviFLiGB8b04H6bQs8G+XTthacvT8VuwvteiP7RJSxMs8UEw== + +estraverse@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" + integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== + +estree-walker@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" + integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +event-stream@=3.3.4: + version "3.3.4" + resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-3.3.4.tgz#4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571" + integrity sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE= + dependencies: + duplexer "~0.1.1" + from "~0" + map-stream "~0.1.0" + pause-stream "0.0.11" + split "0.3" + stream-combiner "~0.0.4" + through "~2.3.1" + +event-target-shim@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" + integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== + +eventemitter2@^6.4.3: + version "6.4.4" + resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-6.4.4.tgz#aa96e8275c4dbeb017a5d0e03780c65612a1202b" + integrity sha512-HLU3NDY6wARrLCEwyGKRBvuWYyvW6mHYv72SJJAH3iJN3a6eVUvkjFkcxah1bcTgGVBBrFdIopBJPhCQFMLyXw== + +eventemitter3@4.0.7, eventemitter3@^4.0.7: + version "4.0.7" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== + +events@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.2.0.tgz#93b87c18f8efcd4202a461aec4dfc0556b639379" + integrity sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg== + +execa@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-4.1.0.tgz#4e5491ad1572f2f17a77d388c6c857135b22847a" + integrity sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA== + dependencies: + cross-spawn "^7.0.0" + get-stream "^5.0.0" + human-signals "^1.1.1" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.0" + onetime "^5.1.0" + signal-exit "^3.0.2" + strip-final-newline "^2.0.0" + +execa@5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + +execa@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.0.0.tgz#4029b0007998a841fbd1032e5f4de86a3c1e3376" + integrity sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + +executable@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/executable/-/executable-4.1.1.tgz#41532bff361d3e57af4d763b70582db18f5d133c" + integrity sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg== + dependencies: + pify "^2.2.0" + +exit-on-epipe@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz#0bdd92e87d5285d267daa8171d0eb06159689692" + integrity sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw== + +expand-tilde@^2.0.0, expand-tilde@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" + integrity sha1-l+gBqgUt8CRU3kawK/YhZCzchQI= + dependencies: + homedir-polyfill "^1.0.1" + +ext@^1.1.2: + version "1.4.0" + resolved "https://registry.yarnpkg.com/ext/-/ext-1.4.0.tgz#89ae7a07158f79d35517882904324077e4379244" + integrity sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A== + dependencies: + type "^2.0.0" + +extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +extract-zip@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-2.0.1.tgz#663dca56fe46df890d5f131ef4a06d22bb8ba13a" + integrity sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg== + dependencies: + debug "^4.1.1" + get-stream "^5.1.0" + yauzl "^2.10.0" + optionalDependencies: + "@types/yauzl" "^2.9.1" + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= + +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= + +fast-deep-equal@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4" + integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA== + +fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-glob@^3.1.1: + version "3.2.4" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.4.tgz#d20aefbf99579383e7f3cc66529158c9b98554d3" + integrity sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.0" + merge2 "^1.3.0" + micromatch "^4.0.2" + picomatch "^2.2.1" + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + +fast-xml-parser@^3.19.0: + version "3.19.0" + resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-3.19.0.tgz#cb637ec3f3999f51406dd8ff0e6fc4d83e520d01" + integrity sha512-4pXwmBplsCPv8FOY1WRakF970TjNGnGnfbOnLqjlYvMiF1SR3yOHyxMR/YCXpPTOspNF5gwudqktIP4VsWkvBg== + +fastest-levenshtein@^1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz#9990f7d3a88cc5a9ffd1f1745745251700d497e2" + integrity sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow== + +fastq@^1.6.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.8.0.tgz#550e1f9f59bbc65fe185cb6a9b4d95357107f481" + integrity sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q== + dependencies: + reusify "^1.0.4" + +fd-slicer@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" + integrity sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4= + dependencies: + pend "~1.2.0" + +feed@4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/feed/-/feed-4.2.2.tgz#865783ef6ed12579e2c44bbef3c9113bc4956a7e" + integrity sha512-u5/sxGfiMfZNtJ3OvQpXcvotFpYkL0n9u9mM2vkui2nGo8b4wvDkJ8gAkYqbA8QpGyFCv3RK0Z+Iv+9veCS9bQ== + dependencies: + xml-js "^1.6.11" + +figures@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" + integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== + dependencies: + escape-string-regexp "^1.0.5" + +file-entry-cache@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== + dependencies: + flat-cache "^3.0.4" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +find-node-modules@^2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/find-node-modules/-/find-node-modules-2.1.2.tgz#57565a3455baf671b835bc6b2134a9b938b9c53c" + integrity sha512-x+3P4mbtRPlSiVE1Qco0Z4YLU8WFiFcuWTf3m75OV9Uzcfs2Bg+O9N+r/K0AnmINBW06KpfqKwYJbFlFq4qNug== + dependencies: + findup-sync "^4.0.0" + merge "^2.1.0" + +find-up@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + +find-up@^4.0.0, find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +findup-sync@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-4.0.0.tgz#956c9cdde804052b881b428512905c4a5f2cdef0" + integrity sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ== + dependencies: + detect-file "^1.0.0" + is-glob "^4.0.0" + micromatch "^4.0.2" + resolve-dir "^1.0.1" + +flat-cache@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" + integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== + dependencies: + flatted "^3.1.0" + rimraf "^3.0.2" + +flat@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" + integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== + +flatted@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.1.0.tgz#a5d06b4a8b01e3a63771daa5cb7a1903e2e57067" + integrity sha512-tW+UkmtNg/jv9CSofAKvgVcO7c2URjhTdW1ZTkcAritblu8tajiYy7YisnIflEwtKssCtOxpnBRoCB7iap0/TA== + +follow-redirects@^1.10.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.1.tgz#d9114ded0a1cfdd334e164e6662ad02bfd91ff43" + integrity sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg== + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= + +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== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + +form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + +from@~0: + version "0.1.7" + resolved "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe" + integrity sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4= + +fs-extra@^8.0.1: + version "8.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" + integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-extra@^9.1.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" + integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== + dependencies: + at-least-node "^1.0.0" + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fsevents@~2.1.2: + version "2.1.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" + integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= + +get-caller-file@^2.0.1, get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-stream@^5.0.0, get-stream@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" + integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== + dependencies: + pump "^3.0.0" + +get-stream@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.0.tgz#3e0012cb6827319da2706e601a1583e8629a6718" + integrity sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg== + +getos@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/getos/-/getos-3.2.1.tgz#0134d1f4e00eb46144c5a9c0ac4dc087cbb27dc5" + integrity sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q== + dependencies: + async "^3.2.0" + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= + dependencies: + assert-plus "^1.0.0" + +glob-parent@^5.1.0, glob-parent@~5.1.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" + integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ== + dependencies: + is-glob "^4.0.1" + +glob-parent@^6.0.1: + version "6.0.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== + 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: + version "7.1.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" + integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +global-dirs@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-3.0.0.tgz#70a76fe84ea315ab37b1f5576cbde7d48ef72686" + integrity sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA== + dependencies: + ini "2.0.0" + +global-modules@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" + integrity sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg== + dependencies: + global-prefix "^1.0.1" + is-windows "^1.0.1" + resolve-dir "^1.0.0" + +global-prefix@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe" + integrity sha1-2/dDxsFJklk8ZVVoy2btMsASLr4= + dependencies: + expand-tilde "^2.0.2" + homedir-polyfill "^1.0.1" + ini "^1.3.4" + is-windows "^1.0.1" + which "^1.2.14" + +globals@^13.6.0: + version "13.7.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.7.0.tgz#aed3bcefd80ad3ec0f0be2cf0c895110c0591795" + integrity sha512-Aipsz6ZKRxa/xQkZhNg0qIWXT6x6rD46f6x/PCnBomlttdIyAPak4YD9jTmKpZ72uROSMU87qJtcgpgHaVchiA== + dependencies: + type-fest "^0.20.2" + +globals@^13.9.0: + version "13.9.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.9.0.tgz#4bf2bf635b334a173fb1daf7c5e6b218ecdc06cb" + integrity sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA== + dependencies: + type-fest "^0.20.2" + +globby@^11.0.2, globby@^11.0.4: + version "11.0.4" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.4.tgz#2cbaff77c2f2a62e71e9b2813a67b97a3a3001a5" + integrity sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.1.1" + ignore "^5.1.4" + merge2 "^1.3.0" + slash "^3.0.0" + +got@11.8.2: + version "11.8.2" + resolved "https://registry.yarnpkg.com/got/-/got-11.8.2.tgz#7abb3959ea28c31f3576f1576c1effce23f33599" + integrity sha512-D0QywKgIe30ODs+fm8wMZiAcZjypcCodPNuMz5H9Mny7RJ+IjJ10BdmGW7OM7fHXP+O7r6ZwapQ/YQmMSvB0UQ== + dependencies: + "@sindresorhus/is" "^4.0.0" + "@szmarczak/http-timer" "^4.0.5" + "@types/cacheable-request" "^6.0.1" + "@types/responselike" "^1.0.0" + cacheable-lookup "^5.0.3" + cacheable-request "^7.0.1" + decompress-response "^6.0.0" + http2-wrapper "^1.0.0-beta.5.2" + lowercase-keys "^2.0.0" + p-cancelable "^2.0.0" + responselike "^2.0.0" + +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.4: + version "4.2.4" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" + integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== + +graceful-fs@^4.2.0: + version "4.2.8" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a" + integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg== + +growl@1.10.5: + version "1.10.5" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" + integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== + +hammerjs@^2.0.8: + version "2.0.8" + resolved "https://registry.yarnpkg.com/hammerjs/-/hammerjs-2.0.8.tgz#04ef77862cff2bb79d30f7692095930222bf60f1" + integrity sha1-BO93hiz/K7edMPdpIJWTAiK/YPE= + +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= + +har-validator@~5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" + integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== + dependencies: + ajv "^6.5.5" + har-schema "^2.0.0" + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-own-prop@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-own-prop/-/has-own-prop-2.0.0.tgz#f0f95d58f65804f5d218db32563bb85b8e0417af" + integrity sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ== + +has-symbols@^1.0.0, has-symbols@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" + integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +hash-sum@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/hash-sum/-/hash-sum-1.0.2.tgz#33b40777754c6432573c120cc3808bbd10d47f04" + integrity sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ= + +hash-sum@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/hash-sum/-/hash-sum-2.0.0.tgz#81d01bb5de8ea4a214ad5d6ead1b523460b0b45a" + integrity sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg== + +he@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +homedir-polyfill@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8" + integrity sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA== + dependencies: + parse-passwd "^1.0.0" + +hpagent@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/hpagent/-/hpagent-0.1.1.tgz#66f67f16e5c7a8b59a068e40c2658c2c749ad5e2" + integrity sha512-IxJWQiY0vmEjetHdoE9HZjD4Cx+mYTr25tR7JCxXaiI3QxW0YqYyM11KyZbHufoa/piWhMb2+D3FGpMgmA2cFQ== + +http-cache-semantics@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" + integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== + +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.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.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" + integrity sha512-bptAfCDdPJxOs5zYSe7Y3lpr772s1G346R4Td5LgRUeCwIGpCGDUTJxRrhTNcAXbx37spge0kWEIH7QAYWNTlA== + dependencies: + urlsafe-base64 "~1.0.0" + +https-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" + integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA== + dependencies: + agent-base "6" + debug "4" + +human-signals@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" + integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== + +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + +iconv-lite@^0.4.4: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +icss-utils@^5.0.0, icss-utils@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" + integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== + +idb-keyval@5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/idb-keyval/-/idb-keyval-5.1.3.tgz#6ef5dff371897c23f144322dc6374eadd6a345d9" + integrity sha512-N9HbCK/FaXSRVI+k6Xq4QgWxbcZRUv+SfG1y7HJ28JdV8yEJu6k+C/YLea7npGckX2DQJeEVuMc4bKOBeU/2LQ== + dependencies: + safari-14-idb-fix "^1.0.4" + +ieee754@^1.1.4: + version "1.1.13" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" + integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== + +ignore@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== + +ignore@^5.1.4: + version "5.1.8" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" + integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== + +import-fresh@^3.0.0, import-fresh@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66" + integrity sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +import-local@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.0.2.tgz#a8cfd0431d1de4a2199703d003e3e62364fa6db6" + integrity sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA== + dependencies: + pkg-dir "^4.2.0" + resolve-cwd "^3.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + +indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== + +indexes-of@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" + integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc= + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@^2.0.1: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +ini@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ini/-/ini-2.0.0.tgz#e5fd556ecdd5726be978fa1001862eacb0a94bc5" + integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA== + +ini@^1.3.4: + version "1.3.7" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.7.tgz#a09363e1911972ea16d7a8851005d84cf09a9a84" + integrity sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ== + +insert-text-at-cursor@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/insert-text-at-cursor/-/insert-text-at-cursor-0.3.0.tgz#1819607680ec1570618347c4cd475e791faa25da" + integrity sha512-/nPtyeX9xPUvxZf+r0518B7uqNKlP+LqNJqSiXFEaa2T71rWIwTVXGH7hB9xO/EVdwa5/pWlFCPwShOW81XIxQ== + +interpret@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" + integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== + +ip-address@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/ip-address/-/ip-address-7.1.0.tgz#4a9c699e75b51cbeb18b38de8ed216efa1a490c5" + integrity sha512-V9pWC/VJf2lsXqP7IWJ+pe3P1/HCYGBMZrrnT62niLGjAfCbeiwXMUxaeHvnVlz19O27pvXP4azs+Pj/A0x+SQ== + dependencies: + jsbn "1.1.0" + sprintf-js "1.1.2" + +ip-cidr@3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/ip-cidr/-/ip-cidr-3.0.4.tgz#a915c47e00f47ea8d5f8ed662ea6161471c44375" + integrity sha512-pKNiqmBlTvEkhaLAa3+FOmYSY0/jjADVxxjA3NbujZZTT8mjLI90Q+6mwg6kd0fNm0RuAOkWJ1u1a/ETmlrPNQ== + dependencies: + ip-address "^7.1.0" + jsbn "^1.1.0" + +ip-regex@^4.0.0, ip-regex@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-4.3.0.tgz#687275ab0f57fa76978ff8f4dddc8a23d5990db5" + integrity sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q== + +ipaddr.js@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.0.1.tgz#eca256a7a877e917aeb368b0a7497ddf42ef81c0" + integrity sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng== + +is-absolute-url@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-3.0.3.tgz#96c6a22b6a23929b11ea0afb1836c36ad4a5d698" + integrity sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q== + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-callable@^1.1.4, is-callable@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.5.tgz#f7e46b596890456db74e7f6e976cb3273d06faab" + integrity sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q== + +is-ci@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-3.0.0.tgz#c7e7be3c9d8eef7d0fa144390bd1e4b88dc4c994" + integrity sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ== + dependencies: + ci-info "^3.1.1" + +is-core-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.0.0.tgz#58531b70aed1db7c0e8d4eb1a0a2d1ddd64bd12d" + integrity sha512-jq1AH6C8MuteOoBPwkxHafmByhL9j5q4OaPGdbuD+ZtQJVzH+i6E3BJDQcBA09k57i2Hh2yQbEG8yObZ0jdlWw== + dependencies: + has "^1.0.3" + +is-core-module@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.2.0.tgz#97037ef3d52224d85163f5597b2b63d9afed981a" + integrity sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ== + dependencies: + has "^1.0.3" + +is-date-object@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" + integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== + +is-expression@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-expression/-/is-expression-4.0.0.tgz#c33155962abf21d0afd2552514d67d2ec16fd2ab" + integrity sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A== + dependencies: + acorn "^7.1.1" + object-assign "^4.1.1" + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== + dependencies: + is-extglob "^2.1.1" + +is-glob@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-installed-globally@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.4.0.tgz#9a0fd407949c30f86eb6959ef1b7994ed0b7b520" + integrity sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ== + dependencies: + global-dirs "^3.0.0" + is-path-inside "^3.0.2" + +is-ip@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-ip/-/is-ip-3.1.0.tgz#2ae5ddfafaf05cb8008a62093cf29734f657c5d8" + integrity sha512-35vd5necO7IitFPjd/YBeqwWnyDWbuLH9ZXQdMfDA8TEo7pv5X8yfrvVO3xbJbLUlERCMvf6X0hTUamQxCYJ9Q== + dependencies: + ip-regex "^4.0.0" + +is-number-like@^1.0.3: + version "1.0.8" + resolved "https://registry.yarnpkg.com/is-number-like/-/is-number-like-1.0.8.tgz#2e129620b50891042e44e9bbbb30593e75cfbbe3" + integrity sha512-6rZi3ezCyFcn5L71ywzz2bS5b2Igl1En3eTlZlvKjpz1n3IZLAYMbKYAIQgFmEu0GENg92ziU/faEOA/aixjbA== + dependencies: + lodash.isfinite "^3.3.2" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-path-inside@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + +is-plain-obj@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" + integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== + +is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-promise@^2.0.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.2.2.tgz#39ab959ccbf9a774cf079f7b40c7a26f763135f1" + integrity sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ== + +is-regex@^1.0.3, is-regex@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae" + integrity sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ== + dependencies: + has "^1.0.3" + +is-resolvable@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" + integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg== + +is-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" + integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== + +is-svg@4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-4.3.1.tgz#8c63ec8c67c8c7f0a8de0a71c8c7d58eccf4406b" + integrity sha512-h2CGs+yPUyvkgTJQS9cJzo9lYK06WgRiXUqBBHtglSzVKAuH4/oWsqk7LGfbSa1hGk9QcZ0SyQtVggvBA8LZXA== + dependencies: + fast-xml-parser "^3.19.0" + +is-symbol@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" + integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ== + dependencies: + has-symbols "^1.0.1" + +is-typedarray@^1.0.0, is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + +is-unicode-supported@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" + integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== + +is-windows@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== + +isarray@^2.0.1: + version "2.0.5" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" + integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= + +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" + +jest-worker@^27.0.2: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.0.6.tgz#a5fdb1e14ad34eb228cfe162d9f729cdbfa28aed" + integrity sha512-qupxcj/dRuA3xHPMUd40gr2EaAurFbkwzOh7wfPaeE9id7hyjURRQoqNfHifHK3XjJU6YJJUQKILGUnwGPEOCA== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +joi@^17.4.0: + version "17.4.2" + resolved "https://registry.yarnpkg.com/joi/-/joi-17.4.2.tgz#02f4eb5cf88e515e614830239379dcbbe28ce7f7" + integrity sha512-Lm56PP+n0+Z2A2rfRvsfWVDXGEWjXxatPopkQ8qQ5mxCEhwHG+Ettgg5o98FFaxilOxozoa14cFhrE/hOzh/Nw== + dependencies: + "@hapi/hoek" "^9.0.0" + "@hapi/topo" "^5.0.0" + "@sideway/address" "^4.1.0" + "@sideway/formula" "^3.0.0" + "@sideway/pinpoint" "^2.0.0" + +jpeg-js@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.4.1.tgz#937a3ae911eb6427f151760f8123f04c8bfe6ef7" + integrity sha512-jA55yJiB5tCXEddos8JBbvW+IMrqY0y1tjjx9KNVtA+QPmu7ND5j0zkKopClpUTsaETL135uOM2XfcYG4XRjmw== + +js-levenshtein@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.6.tgz#c6cee58eb3550372df8deb85fad5ce66ce01d59d" + integrity sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g== + +js-stringify@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/js-stringify/-/js-stringify-1.0.2.tgz#1736fddfd9724f28a3682adc6230ae7e4e9679db" + integrity sha1-Fzb939lyTyijaCrcYjCufk6Weds= + +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.0.0.tgz#f426bc0ff4b4051926cd588c71113183409a121f" + integrity sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q== + dependencies: + argparse "^2.0.1" + +js-yaml@4.1.0, js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + +js-yaml@^3.13.1, js-yaml@^3.14.1: + version "3.14.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jsbn@1.1.0, jsbn@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-1.1.0.tgz#b01307cb29b618a1ed26ec79e911f803c4da0040" + integrity sha1-sBMHyym2GKHtJux56RH4A8TaAEA= + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= + +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-parse-even-better-errors@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + +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" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + +json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= + +json5-loader@4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/json5-loader/-/json5-loader-4.0.1.tgz#6d17a1181e8f3c3d9204dca2a4ce4627306c8498" + integrity sha512-c9viNZlZTz0MTIcf/4qvek5Dz1/PU3DNCB4PwUhlEZIV3qb1bSD6vQQymlV17/Wm6ncra1aCvmIPsuRj+KfEEg== + dependencies: + json5 "^2.1.3" + loader-utils "^2.0.0" + schema-utils "^3.0.0" + +json5@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" + integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA== + dependencies: + minimist "^1.2.5" + +json5@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" + integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== + dependencies: + minimist "^1.2.0" + +json5@^2.1.2, json5@^2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43" + integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA== + dependencies: + minimist "^1.2.5" + +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= + optionalDependencies: + graceful-fs "^4.1.6" + +jsonfile@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-5.0.0.tgz#e6b718f73da420d612823996fdf14a03f6ff6922" + integrity sha512-NQRZ5CRo74MhMMC3/3r5g2k4fjodJ/wh8MxjFbCViWKFjxrnudWSY5vomh+23ZaXzAS7J3fBZIR2dV6WbmfM0w== + dependencies: + universalify "^0.1.2" + optionalDependencies: + graceful-fs "^4.1.6" + +jsonfile@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" + integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== + dependencies: + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + +jstransformer@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/jstransformer/-/jstransformer-1.0.0.tgz#ed8bf0921e2f3f1ed4d5c1a44f68709ed24722c3" + integrity sha1-7Yvwkh4vPx7U1cGkT2hwntJHIsM= + dependencies: + is-promise "^2.0.0" + promise "^7.0.1" + +jwa@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/jwa/-/jwa-2.0.0.tgz#a7e9c3f29dae94027ebcaf49975c9345593410fc" + integrity sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA== + dependencies: + buffer-equal-constant-time "1.0.1" + ecdsa-sig-formatter "1.0.11" + safe-buffer "^5.0.1" + +jws@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jws/-/jws-4.0.0.tgz#2d4e8cf6a318ffaa12615e9dec7e86e6c97310f4" + integrity sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg== + dependencies: + jwa "^2.0.0" + safe-buffer "^5.0.1" + +katex@0.13.18: + version "0.13.18" + resolved "https://registry.yarnpkg.com/katex/-/katex-0.13.18.tgz#ba89e8e4b70cc2325e25e019a62b9fe71e5c2931" + integrity sha512-a3dC4NSVSDU3O1WZbTnOiA8rVNJ2lSiomOl0kmckCIGObccIHXof7gAseIY0o1gjEspe+34ZeSEX2D1ChFKIvA== + dependencies: + commander "^6.0.0" + +keyv@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.0.3.tgz#4f3aa98de254803cafcd2896734108daa35e4254" + integrity sha512-zdGa2TOpSZPq5mU6iowDARnMBZgtCqJ11dJROFi6tg6kTn4nuUdU09lFyLFSaHrWqpIJ+EBq4E8/Dc0Vx5vLdA== + dependencies: + json-buffer "3.0.1" + +kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +klona@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.4.tgz#7bb1e3affb0cb8624547ef7e8f6708ea2e39dfc0" + integrity sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA== + +langmap@0.0.16: + version "0.0.16" + resolved "https://registry.yarnpkg.com/langmap/-/langmap-0.0.16.tgz#2fe3e98a531fec0fec546624ebe168c2855bab56" + integrity sha512-AtYvBK7BsDvWwnSfmO7CfgeUy7GUT1wK3QX8eKH/Ey/eXodqoHuAtvdQ82hmWD9QVFVKnuiNjym9fGY4qSJeLA== + +lazy-ass@1.6.0, lazy-ass@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/lazy-ass/-/lazy-ass-1.6.0.tgz#7999655e8646c17f089fdd187d150d3324d54513" + integrity sha1-eZllXoZGwX8In90YfRUNMyTVRRM= + +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + +lilconfig@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.0.3.tgz#68f3005e921dafbd2a2afb48379986aa6d2579fd" + integrity sha512-EHKqr/+ZvdKCifpNrJCKxBTgk5XupZA3y/aCPY9mxfgBzmgh93Mt/WqjjQ38oMxXuvDokaKiM3lAgvSH2sjtHg== + +lines-and-columns@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" + integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= + +listr2@^3.8.3: + version "3.11.0" + resolved "https://registry.yarnpkg.com/listr2/-/listr2-3.11.0.tgz#9771b02407875aa78e73d6e0ff6541bbec0aaee9" + integrity sha512-XLJVe2JgXCyQTa3FbSv11lkKExYmEyA4jltVo8z4FX10Vt1Yj8IMekBfwim0BSOM9uj1QMTJvDQQpHyuPbB/dQ== + dependencies: + cli-truncate "^2.1.0" + colorette "^1.2.2" + log-update "^4.0.0" + p-map "^4.0.0" + rxjs "^6.6.7" + through "^2.3.8" + wrap-ansi "^7.0.0" + +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@^1.0.2: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613" + integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^1.0.1" + +loader-utils@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.0.tgz#e4cace5b816d425a166b5f097e10cd12b36064b0" + integrity sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^2.1.2" + +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +lodash.isequal@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" + integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA= + +lodash.isfinite@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/lodash.isfinite/-/lodash.isfinite-3.3.2.tgz#fb89b65a9a80281833f0b7478b3a5104f898ebb3" + integrity sha1-+4m2WpqAKBgz8LdHizpRBPiY67M= + +lodash.memoize@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" + integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= + +lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + +lodash.once@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" + integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w= + +lodash.uniq@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" + integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= + +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== + +log-symbols@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.0.0.tgz#69b3cc46d20f448eccdb75ea1fa733d9e821c920" + integrity sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA== + dependencies: + chalk "^4.0.0" + +log-symbols@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" + integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== + dependencies: + chalk "^4.1.0" + is-unicode-supported "^0.1.0" + +log-update@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/log-update/-/log-update-4.0.0.tgz#589ecd352471f2a1c0c570287543a64dfd20e0a1" + integrity sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg== + dependencies: + ansi-escapes "^4.3.0" + cli-cursor "^3.1.0" + slice-ansi "^4.0.0" + wrap-ansi "^6.2.0" + +lowercase-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" + integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +magic-string@^0.25.7: + version "0.25.7" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.7.tgz#3f497d6fd34c669c6798dcb821f2ef31f5445051" + integrity sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA== + dependencies: + sourcemap-codec "^1.4.4" + +make-error@^1.1.1: + version "1.3.6" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + +map-stream@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.1.0.tgz#e56aa94c4c8055a16404a0674b78f215f7c8e194" + integrity sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ= + +matter-js@0.17.1: + version "0.17.1" + resolved "https://registry.yarnpkg.com/matter-js/-/matter-js-0.17.1.tgz#b30ac4c708116258fbcaacd2efd8a94e34a91c7f" + integrity sha512-pSquoENJgvSAlQGcA0s5UkmEohGXZaUww2g3B6qG87x0iEcVf+aigMXn5UkFPdnh6w3B+C4vXSLaYqhHwKrOLA== + +mdn-data@2.0.14: + version "2.0.14" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50" + integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow== + +mdn-data@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.4.tgz#699b3c38ac6f1d728091a64650b65d388502fd5b" + integrity sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA== + +mdn-data@2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.6.tgz#852dc60fcaa5daa2e8cf6c9189c440ed3e042978" + integrity sha512-rQvjv71olwNHgiTbfPZFkJtjNMciWgswYeciZhtvWLO8bmX3TnhyA62I6sTWOyZssWHJJjY6/KiWwqQsWWsqOA== + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +merge2@^1.3.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +merge@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/merge/-/merge-2.1.1.tgz#59ef4bf7e0b3e879186436e8481c06a6c162ca98" + integrity sha512-jz+Cfrg9GWOZbQAnDQ4hlVnQky+341Yk5ru8bZSe6sIDTCIg8n9i/u7hSQGSVOF3C7lH6mGtqjkiT9G4wFLL0w== + +mfm-js@0.20.0: + version "0.20.0" + resolved "https://registry.yarnpkg.com/mfm-js/-/mfm-js-0.20.0.tgz#3afdcd7959461fd825aa8af9b9e8a57cdbddc290" + integrity sha512-1+3tV3nWUKQNh/ztX3wXu5iLBtdsg6q3wUhl+XyOhc2H3sQdG+sih/w2c0nR9TIawjN+Z1/pvgGzxMJHfmKQmA== + dependencies: + twemoji-parser "13.1.x" + +micromatch@^4.0.0, micromatch@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259" + integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q== + dependencies: + braces "^3.0.1" + picomatch "^2.0.5" + +microseconds@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/microseconds/-/microseconds-0.2.0.tgz#233b25f50c62a65d861f978a4a4f8ec18797dc39" + integrity sha512-n7DHHMjR1avBbSpsTBj6fmMGh2AGrifVV4e+WYc3Q9lO+xnSZ3NyhcBND3vzzatt05LFhoKFRxrIyklmLlUtyA== + +mime-db@1.44.0: + version "1.44.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" + integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== + +mime-types@^2.1.12, mime-types@^2.1.27, mime-types@~2.1.19: + version "2.1.27" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" + integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== + dependencies: + mime-db "1.44.0" + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +mimic-response@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" + integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== + +mimic-response@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" + integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== + +minimalistic-assert@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimatch@3.0.4, minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimist@^1.2.0, minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + +misskey-js@0.0.10: + version "0.0.10" + resolved "https://registry.yarnpkg.com/misskey-js/-/misskey-js-0.0.10.tgz#f305dd37cecfbaeb7a277d5e0c769ca12c6eb9a6" + integrity sha512-2rdqFrCOwggMKYitsUPyupesqCNpNooqEHQQRfdjttbhiqLbNFJE1UuWQ04ffmiJ08UJt+1ZN2kVAYNEN3HRsg== + dependencies: + autobind-decorator "^2.4.0" + eventemitter3 "^4.0.7" + reconnecting-websocket "^4.4.0" + +mkdirp@~0.5.1: + version "0.5.5" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== + dependencies: + minimist "^1.2.5" + +mocha@8.4.0: + version "8.4.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-8.4.0.tgz#677be88bf15980a3cae03a73e10a0fc3997f0cff" + integrity sha512-hJaO0mwDXmZS4ghXsvPVriOhsxQ7ofcpQdm8dE+jISUOKopitvnXFQmpRR7jd2K6VBG6E26gU3IAbXXGIbu4sQ== + dependencies: + "@ungap/promise-all-settled" "1.1.2" + ansi-colors "4.1.1" + browser-stdout "1.3.1" + chokidar "3.5.1" + debug "4.3.1" + diff "5.0.0" + escape-string-regexp "4.0.0" + find-up "5.0.0" + glob "7.1.6" + growl "1.10.5" + he "1.2.0" + js-yaml "4.0.0" + log-symbols "4.0.0" + minimatch "3.0.4" + ms "2.1.3" + nanoid "3.1.20" + serialize-javascript "5.0.1" + strip-json-comments "3.1.1" + supports-color "8.1.1" + which "2.0.2" + wide-align "1.1.3" + workerpool "6.1.0" + yargs "16.2.0" + yargs-parser "20.2.4" + yargs-unparser "2.0.0" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@2.1.3, ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +nano-time@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/nano-time/-/nano-time-1.0.0.tgz#b0554f69ad89e22d0907f7a12b0993a5d96137ef" + integrity sha1-sFVPaa2J4i0JB/ehKwmTpdlhN+8= + dependencies: + big-integer "^1.6.16" + +nanoid@3.1.20, nanoid@^3.1.20: + version "3.1.20" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.20.tgz#badc263c6b1dcf14b71efaa85f6ab4c1d6cfc788" + integrity sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw== + +nanoid@^3.1.23: + version "3.1.23" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.23.tgz#f744086ce7c2bc47ee0a8472574d5c78e4183a81" + integrity sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw== + +nanoid@^3.1.30: + version "3.1.30" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.30.tgz#63f93cc548d2a113dc5dfbc63bfa09e2b9b64362" + integrity sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ== + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + +needle@^2.5.2: + version "2.5.2" + resolved "https://registry.yarnpkg.com/needle/-/needle-2.5.2.tgz#cf1a8fce382b5a280108bba90a14993c00e4010a" + integrity sha512-LbRIwS9BfkPvNwNHlsA41Q29kL2L/6VaOJ0qisM5lLWsTV3nP15abO5ITL6L81zqFhzjRKDAYjpcBcwM0AVvLQ== + dependencies: + debug "^3.2.6" + iconv-lite "^0.4.4" + sax "^1.2.4" + +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" + integrity sha512-yFehXNWRs4cM0+dz7QxCd06hTbWbSkV0ISsqBfkntU6TOY4Qm3Q88fRRLOddkGh2Qq6dZvnKVAahfhjcUvLnyA== + +netmask@^2.0.2: + version "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" + integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= + +node-fetch@2.6.1, node-fetch@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" + integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== + +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" + integrity sha512-L/Eg02Epx6Si2NXmedx+Okg+4UHqmaf3TNcxd50SF9NQGcJaON3AtU++kax69XV7YWz4tUspqZSAsVofhFKG2w== + +node-releases@^1.1.70, node-releases@^1.1.71: + version "1.1.71" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.71.tgz#cb1334b179896b1c89ecfdd4b725fb7bbdfc7dbb" + integrity sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg== + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +normalize-url@^4.1.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129" + integrity sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ== + +normalize-url@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" + integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== + +npm-run-path@^4.0.0, npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + +nth-check@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" + integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg== + dependencies: + boolbase "~1.0.0" + +nth-check@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.0.0.tgz#1bb4f6dac70072fc313e8c9cd1417b5074c0a125" + integrity sha512-i4sc/Kj8htBrAiH1viZ0TgU8Y5XqCaV/FziYK6TBczxmeKm3AEFWqqF3195yKudrarqy7Zu80Ra5dobFjn9X/Q== + dependencies: + boolbase "^1.0.0" + +oauth@0.9.15: + version "0.9.15" + resolved "https://registry.yarnpkg.com/oauth/-/oauth-0.9.15.tgz#bd1fefaf686c96b75475aed5196412ff60cfb9c1" + integrity sha1-vR/vr2hslrdUda7VGWQS/2DPucE= + +object-assign@^4.1.0, object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +object-inspect@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67" + integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw== + +object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object.assign@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" + integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== + dependencies: + define-properties "^1.1.2" + function-bind "^1.1.1" + has-symbols "^1.0.0" + object-keys "^1.0.11" + +object.getownpropertydescriptors@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz#369bf1f9592d8ab89d712dced5cb81c7c5352649" + integrity sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0-next.1" + +object.values@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.1.tgz#68a99ecde356b7e9295a3c5e0ce31dc8c953de5e" + integrity sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0-next.1" + function-bind "^1.1.1" + has "^1.0.3" + +oblivious-set@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/oblivious-set/-/oblivious-set-1.0.0.tgz#c8316f2c2fb6ff7b11b6158db3234c49f733c566" + integrity sha512-z+pI07qxo4c2CulUHCDf9lcqDlMSo72N/4rLUpRXf6fu+q8vjt8y0xS+Tlf8NTJDdTXHbdeO1n3MlbctwEoXZw== + +once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +onetime@^5.1.0, onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +opentype.js@^0.4.3: + version "0.4.11" + resolved "https://registry.yarnpkg.com/opentype.js/-/opentype.js-0.4.11.tgz#281a2390639cc15931c955d8d63c14a7c7772b41" + integrity sha1-KBojkGOcwVkxyVXY1jwUp8d3K0E= + +optionator@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" + integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== + dependencies: + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + word-wrap "^1.2.3" + +ospath@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/ospath/-/ospath-1.2.2.tgz#1276639774a3f8ef2572f7fe4280e0ea4550c07b" + integrity sha1-EnZjl3Sj+O8lcvf+QoDg6kVQwHs= + +p-cancelable@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.0.0.tgz#4a3740f5bdaf5ed5d7c3e34882c6fb5d6b266a6e" + integrity sha512-wvPXDmbMmu2ksjkB4Z3nZWTSkJEb9lqVdMaCKpZUGJG9TMiNp9XcbG3fn9fPKjem04fJMJnXoyFPk2FmgiaiNg== + +p-limit@^2.0.0, p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-limit@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.0.2.tgz#1664e010af3cadc681baafd3e2a437be7b0fb5fe" + integrity sha512-iwqZSOoWIW+Ew4kAGUlN16J4M7OB3ysMLSZtnhmqx7njIHFPlxWBX8xo3lVTyFVq6mI/lL9qt2IsN1sHwaxJkg== + 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@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + +p-map@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" + integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== + dependencies: + aggregate-error "^3.0.0" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +parse-json@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.1.0.tgz#f96088cdf24a8faa9aea9a009f2d9d942c999646" + integrity sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-even-better-errors "^2.3.0" + lines-and-columns "^1.1.6" + +parse-passwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" + integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY= + +parse5@6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" + integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" + integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +pause-stream@0.0.11: + version "0.0.11" + resolved "https://registry.yarnpkg.com/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445" + integrity sha1-/lo0sMvOErWqaitAPuLnO2AvFEU= + dependencies: + through "~2.3" + +pend@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" + integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA= + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= + +"photoswipe@git://github.com/dimsemenov/photoswipe#v5-beta": + version "5.1.7" + resolved "git://github.com/dimsemenov/photoswipe#60040164333bd257409669e715e4327afdb3aec7" + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.0.7, picomatch@^2.2.1: + version "2.2.2" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" + integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== + +pify@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= + +pkg-dir@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + +pngjs@^3.3.0, pngjs@^3.3.1: + version "3.4.0" + resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-3.4.0.tgz#99ca7d725965fb655814eaf65f38f12bbdbf555f" + integrity sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w== + +portscanner@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/portscanner/-/portscanner-2.2.0.tgz#6059189b3efa0965c9d96a56b958eb9508411cf1" + integrity sha512-IFroCz/59Lqa2uBvzK3bKDbDDIEaAY8XJ1jFxcLWTqosrsc32//P4VuSB2vZXoHiHqOmx8B5L5hnKOxL/7FlPw== + dependencies: + async "^2.6.0" + is-number-like "^1.0.3" + +postcss-calc@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-8.0.0.tgz#a05b87aacd132740a5db09462a3612453e5df90a" + integrity sha512-5NglwDrcbiy8XXfPM11F3HeC6hoT9W7GUH/Zi5U/p7u3Irv4rHhdDcIZwG0llHXV4ftsBjpfWMXAnXNl4lnt8g== + dependencies: + postcss-selector-parser "^6.0.2" + postcss-value-parser "^4.0.2" + +postcss-colormin@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-5.2.1.tgz#6e444a806fd3c578827dbad022762df19334414d" + integrity sha512-VVwMrEYLcHYePUYV99Ymuoi7WhKrMGy/V9/kTS0DkCoJYmmjdOMneyhzYUxcNgteKDVbrewOkSM7Wje/MFwxzA== + dependencies: + browserslist "^4.16.6" + caniuse-api "^3.0.0" + colord "^2.9.1" + postcss-value-parser "^4.1.0" + +postcss-convert-values@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-5.0.2.tgz#879b849dc3677c7d6bc94b6a2c1a3f0808798059" + integrity sha512-KQ04E2yadmfa1LqXm7UIDwW1ftxU/QWZmz6NKnHnUvJ3LEYbbcX6i329f/ig+WnEByHegulocXrECaZGLpL8Zg== + dependencies: + postcss-value-parser "^4.1.0" + +postcss-discard-comments@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-5.0.1.tgz#9eae4b747cf760d31f2447c27f0619d5718901fe" + integrity sha512-lgZBPTDvWrbAYY1v5GYEv8fEO/WhKOu/hmZqmCYfrpD6eyDWWzAOsl2rF29lpvziKO02Gc5GJQtlpkTmakwOWg== + +postcss-discard-duplicates@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-5.0.1.tgz#68f7cc6458fe6bab2e46c9f55ae52869f680e66d" + integrity sha512-svx747PWHKOGpAXXQkCc4k/DsWo+6bc5LsVrAsw+OU+Ibi7klFZCyX54gjYzX4TH+f2uzXjRviLARxkMurA2bA== + +postcss-discard-empty@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-5.0.1.tgz#ee136c39e27d5d2ed4da0ee5ed02bc8a9f8bf6d8" + integrity sha512-vfU8CxAQ6YpMxV2SvMcMIyF2LX1ZzWpy0lqHDsOdaKKLQVQGVP1pzhrI9JlsO65s66uQTfkQBKBD/A5gp9STFw== + +postcss-discard-overridden@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-5.0.1.tgz#454b41f707300b98109a75005ca4ab0ff2743ac6" + integrity sha512-Y28H7y93L2BpJhrdUR2SR2fnSsT+3TVx1NmVQLbcnZWwIUpJ7mfcTC6Za9M2PG6w8j7UQRfzxqn8jU2VwFxo3Q== + +postcss-loader@6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-6.2.0.tgz#714370a3f567141cf4cadcdf9575f5234d186bc5" + integrity sha512-H9hv447QjQJVDbHj3OUdciyAXY3v5+UDduzEytAlZCVHCpNAAg/mCSwhYYqZr9BiGYhmYspU8QXxZwiHTLn3yA== + dependencies: + cosmiconfig "^7.0.0" + klona "^2.0.4" + semver "^7.3.5" + +postcss-merge-longhand@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-5.0.3.tgz#42194a5ffbaa5513edbf606ef79c44958564658b" + integrity sha512-kmB+1TjMTj/bPw6MCDUiqSA5e/x4fvLffiAdthra3a0m2/IjTrWsTmD3FdSskzUjEwkj5ZHBDEbv5dOcqD7CMQ== + dependencies: + css-color-names "^1.0.1" + postcss-value-parser "^4.1.0" + stylehacks "^5.0.1" + +postcss-merge-rules@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-5.0.2.tgz#d6e4d65018badbdb7dcc789c4f39b941305d410a" + integrity sha512-5K+Md7S3GwBewfB4rjDeol6V/RZ8S+v4B66Zk2gChRqLTCC8yjnHQ601omj9TKftS19OPGqZ/XzoqpzNQQLwbg== + dependencies: + browserslist "^4.16.6" + caniuse-api "^3.0.0" + cssnano-utils "^2.0.1" + postcss-selector-parser "^6.0.5" + vendors "^1.0.3" + +postcss-minify-font-values@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-5.0.1.tgz#a90cefbfdaa075bd3dbaa1b33588bb4dc268addf" + integrity sha512-7JS4qIsnqaxk+FXY1E8dHBDmraYFWmuL6cgt0T1SWGRO5bzJf8sUoelwa4P88LEWJZweHevAiDKxHlofuvtIoA== + dependencies: + postcss-value-parser "^4.1.0" + +postcss-minify-gradients@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-5.0.3.tgz#f970a11cc71e08e9095e78ec3a6b34b91c19550e" + integrity sha512-Z91Ol22nB6XJW+5oe31+YxRsYooxOdFKcbOqY/V8Fxse1Y3vqlNRpi1cxCqoACZTQEhl+xvt4hsbWiV5R+XI9Q== + dependencies: + colord "^2.9.1" + cssnano-utils "^2.0.1" + postcss-value-parser "^4.1.0" + +postcss-minify-params@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-5.0.1.tgz#371153ba164b9d8562842fdcd929c98abd9e5b6c" + integrity sha512-4RUC4k2A/Q9mGco1Z8ODc7h+A0z7L7X2ypO1B6V8057eVK6mZ6xwz6QN64nHuHLbqbclkX1wyzRnIrdZehTEHw== + dependencies: + alphanum-sort "^1.0.2" + browserslist "^4.16.0" + cssnano-utils "^2.0.1" + postcss-value-parser "^4.1.0" + uniqs "^2.0.0" + +postcss-minify-selectors@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-5.1.0.tgz#4385c845d3979ff160291774523ffa54eafd5a54" + integrity sha512-NzGBXDa7aPsAcijXZeagnJBKBPMYLaJJzB8CQh6ncvyl2sIndLVWfbcDi0SBjRWk5VqEjXvf8tYwzoKf4Z07og== + dependencies: + alphanum-sort "^1.0.2" + postcss-selector-parser "^6.0.5" + +postcss-modules-extract-imports@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz#cda1f047c0ae80c97dbe28c3e76a43b88025741d" + integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw== + +postcss-modules-local-by-default@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz#ebbb54fae1598eecfdf691a02b3ff3b390a5a51c" + integrity sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ== + dependencies: + icss-utils "^5.0.0" + postcss-selector-parser "^6.0.2" + postcss-value-parser "^4.1.0" + +postcss-modules-scope@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz#9ef3151456d3bbfa120ca44898dfca6f2fa01f06" + integrity sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg== + dependencies: + postcss-selector-parser "^6.0.4" + +postcss-modules-values@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz#d7c5e7e68c3bb3c9b27cbf48ca0bb3ffb4602c9c" + integrity sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ== + dependencies: + icss-utils "^5.0.0" + +postcss-normalize-charset@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-5.0.1.tgz#121559d1bebc55ac8d24af37f67bd4da9efd91d0" + integrity sha512-6J40l6LNYnBdPSk+BHZ8SF+HAkS4q2twe5jnocgd+xWpz/mx/5Sa32m3W1AA8uE8XaXN+eg8trIlfu8V9x61eg== + +postcss-normalize-display-values@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-5.0.1.tgz#62650b965981a955dffee83363453db82f6ad1fd" + integrity sha512-uupdvWk88kLDXi5HEyI9IaAJTE3/Djbcrqq8YgjvAVuzgVuqIk3SuJWUisT2gaJbZm1H9g5k2w1xXilM3x8DjQ== + dependencies: + cssnano-utils "^2.0.1" + postcss-value-parser "^4.1.0" + +postcss-normalize-positions@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-5.0.1.tgz#868f6af1795fdfa86fbbe960dceb47e5f9492fe5" + integrity sha512-rvzWAJai5xej9yWqlCb1OWLd9JjW2Ex2BCPzUJrbaXmtKtgfL8dBMOOMTX6TnvQMtjk3ei1Lswcs78qKO1Skrg== + dependencies: + postcss-value-parser "^4.1.0" + +postcss-normalize-repeat-style@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.0.1.tgz#cbc0de1383b57f5bb61ddd6a84653b5e8665b2b5" + integrity sha512-syZ2itq0HTQjj4QtXZOeefomckiV5TaUO6ReIEabCh3wgDs4Mr01pkif0MeVwKyU/LHEkPJnpwFKRxqWA/7O3w== + dependencies: + cssnano-utils "^2.0.1" + postcss-value-parser "^4.1.0" + +postcss-normalize-string@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-5.0.1.tgz#d9eafaa4df78c7a3b973ae346ef0e47c554985b0" + integrity sha512-Ic8GaQ3jPMVl1OEn2U//2pm93AXUcF3wz+OriskdZ1AOuYV25OdgS7w9Xu2LO5cGyhHCgn8dMXh9bO7vi3i9pA== + dependencies: + postcss-value-parser "^4.1.0" + +postcss-normalize-timing-functions@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.0.1.tgz#8ee41103b9130429c6cbba736932b75c5e2cb08c" + integrity sha512-cPcBdVN5OsWCNEo5hiXfLUnXfTGtSFiBU9SK8k7ii8UD7OLuznzgNRYkLZow11BkQiiqMcgPyh4ZqXEEUrtQ1Q== + dependencies: + cssnano-utils "^2.0.1" + postcss-value-parser "^4.1.0" + +postcss-normalize-unicode@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-5.0.1.tgz#82d672d648a411814aa5bf3ae565379ccd9f5e37" + integrity sha512-kAtYD6V3pK0beqrU90gpCQB7g6AOfP/2KIPCVBKJM2EheVsBQmx/Iof+9zR9NFKLAx4Pr9mDhogB27pmn354nA== + dependencies: + browserslist "^4.16.0" + postcss-value-parser "^4.1.0" + +postcss-normalize-url@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-5.0.2.tgz#ddcdfb7cede1270740cf3e4dfc6008bd96abc763" + integrity sha512-k4jLTPUxREQ5bpajFQZpx8bCF2UrlqOTzP9kEqcEnOfwsRshWs2+oAFIHfDQB8GO2PaUaSE0NlTAYtbluZTlHQ== + dependencies: + is-absolute-url "^3.0.3" + normalize-url "^6.0.1" + postcss-value-parser "^4.1.0" + +postcss-normalize-whitespace@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.0.1.tgz#b0b40b5bcac83585ff07ead2daf2dcfbeeef8e9a" + integrity sha512-iPklmI5SBnRvwceb/XH568yyzK0qRVuAG+a1HFUsFRf11lEJTiQQa03a4RSCQvLKdcpX7XsI1Gen9LuLoqwiqA== + dependencies: + postcss-value-parser "^4.1.0" + +postcss-ordered-values@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-5.0.2.tgz#1f351426977be00e0f765b3164ad753dac8ed044" + integrity sha512-8AFYDSOYWebJYLyJi3fyjl6CqMEG/UVworjiyK1r573I56kb3e879sCJLGvR3merj+fAdPpVplXKQZv+ey6CgQ== + dependencies: + cssnano-utils "^2.0.1" + postcss-value-parser "^4.1.0" + +postcss-reduce-initial@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-5.0.1.tgz#9d6369865b0f6f6f6b165a0ef5dc1a4856c7e946" + integrity sha512-zlCZPKLLTMAqA3ZWH57HlbCjkD55LX9dsRyxlls+wfuRfqCi5mSlZVan0heX5cHr154Dq9AfbH70LyhrSAezJw== + dependencies: + browserslist "^4.16.0" + caniuse-api "^3.0.0" + +postcss-reduce-transforms@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-5.0.1.tgz#93c12f6a159474aa711d5269923e2383cedcf640" + integrity sha512-a//FjoPeFkRuAguPscTVmRQUODP+f3ke2HqFNgGPwdYnpeC29RZdCBvGRGTsKpMURb/I3p6jdKoBQ2zI+9Q7kA== + dependencies: + cssnano-utils "^2.0.1" + postcss-value-parser "^4.1.0" + +postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4: + version "6.0.4" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.4.tgz#56075a1380a04604c38b063ea7767a129af5c2b3" + integrity sha512-gjMeXBempyInaBqpp8gODmwZ52WaYsVOsfr4L4lDQ7n3ncD6mEyySiDtgzCT+NYC0mmeOLvtsF8iaEf0YT6dBw== + dependencies: + cssesc "^3.0.0" + indexes-of "^1.0.1" + uniq "^1.0.1" + util-deprecate "^1.0.2" + +postcss-selector-parser@^6.0.5: + version "6.0.6" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz#2c5bba8174ac2f6981ab631a42ab0ee54af332ea" + integrity sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg== + dependencies: + cssesc "^3.0.0" + util-deprecate "^1.0.2" + +postcss-svgo@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-5.0.3.tgz#d945185756e5dfaae07f9edb0d3cae7ff79f9b30" + integrity sha512-41XZUA1wNDAZrQ3XgWREL/M2zSw8LJPvb5ZWivljBsUQAGoEKMYm6okHsTjJxKYI4M75RQEH4KYlEM52VwdXVA== + dependencies: + postcss-value-parser "^4.1.0" + svgo "^2.7.0" + +postcss-unique-selectors@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-5.0.1.tgz#3be5c1d7363352eff838bd62b0b07a0abad43bfc" + integrity sha512-gwi1NhHV4FMmPn+qwBNuot1sG1t2OmacLQ/AX29lzyggnjd+MnVD5uqQmpXO3J17KGL2WAxQruj1qTd3H0gG/w== + dependencies: + alphanum-sort "^1.0.2" + postcss-selector-parser "^6.0.5" + uniqs "^2.0.0" + +postcss-value-parser@^4.0.2, postcss-value-parser@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb" + integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ== + +postcss@8.3.11: + version "8.3.11" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.3.11.tgz#c3beca7ea811cd5e1c4a3ec6d2e7599ef1f8f858" + integrity sha512-hCmlUAIlUiav8Xdqw3Io4LcpA1DOt7h3LSTAC4G6JGHFFaWzI6qvFt9oilvl8BmkbBRX1IhM90ZAmpk68zccQA== + dependencies: + nanoid "^3.1.30" + picocolors "^1.0.0" + source-map-js "^0.6.2" + +postcss@^8.1.10: + version "8.2.8" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.8.tgz#0b90f9382efda424c4f0f69a2ead6f6830d08ece" + integrity sha512-1F0Xb2T21xET7oQV9eKuctbM9S7BC0fetoHCc4H13z0PT6haiRLP4T0ZY4XWh7iLP0usgqykT6p9B2RtOf4FPw== + dependencies: + colorette "^1.2.2" + nanoid "^3.1.20" + source-map "^0.6.1" + +postcss@^8.2.15: + version "8.3.0" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.3.0.tgz#b1a713f6172ca427e3f05ef1303de8b65683325f" + integrity sha512-+ogXpdAjWGa+fdYY5BQ96V/6tAo+TdSSIMP5huJBIygdWwKtVoB5JWZ7yUd4xZ8r+8Kvvx4nyg/PQ071H4UtcQ== + dependencies: + colorette "^1.2.2" + nanoid "^3.1.23" + source-map-js "^0.6.2" + +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== + +pretty-bytes@^5.6.0: + version "5.6.0" + resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb" + integrity sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg== + +printj@~1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/printj/-/printj-1.1.2.tgz#d90deb2975a8b9f600fb3a1c94e3f4c53c78a222" + integrity sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ== + +prismjs@1.25.0: + version "1.25.0" + resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.25.0.tgz#6f822df1bdad965734b310b315a23315cf999756" + integrity sha512-WCjJHl1KEWbnkQom1+SzftbtXMKQoezOCYs5rECqMN+jP+apI7ftoflyqigqzopSO3hMhTEb0mFClA8lkolgEg== + +private-ip@2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/private-ip/-/private-ip-2.3.3.tgz#1e80ff8443e5ac78f555631aec3ea6ff027fa6aa" + integrity sha512-5zyFfekIVUOTVbL92hc8LJOtE/gyGHeREHkJ2yTyByP8Q2YZVoBqLg3EfYLeF0oVvGqtaEX2t2Qovja0/gStXw== + dependencies: + ip-regex "^4.3.0" + ipaddr.js "^2.0.1" + is-ip "^3.1.0" + netmask "^2.0.2" + +probe-image-size@7.2.1: + version "7.2.1" + resolved "https://registry.yarnpkg.com/probe-image-size/-/probe-image-size-7.2.1.tgz#df0c924e67e247bc94f8fcb0fad7f0081061fc44" + integrity sha512-d+6L3NvQBCNt4peRDoEfA7r9bPm6/qy18FnLKwg4NWBC5JrJm0pMLRg1kF4XNsPe1bUdt3WIMonPJzQWN2HXjQ== + dependencies: + lodash.merge "^4.6.2" + needle "^2.5.2" + stream-parser "~0.3.1" + +progress@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + +promise-limit@2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/promise-limit/-/promise-limit-2.7.0.tgz#eb5737c33342a030eaeaecea9b3d3a93cb592b26" + integrity sha512-7nJ6v5lnJsXwGprnGXga4wx6d1POjvi5Qmf1ivTRxTjH4Z/9Czja/UCMLVmB9N93GeWOU93XaFaEt6jbuoagNw== + +promise@^7.0.1: + version "7.3.1" + resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" + integrity sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg== + dependencies: + asap "~2.0.3" + +proxy-from-env@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.0.0.tgz#33c50398f70ea7eb96d21f7b817630a55791c7ee" + integrity sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4= + +ps-tree@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/ps-tree/-/ps-tree-1.2.0.tgz#5e7425b89508736cdd4f2224d028f7bb3f722ebd" + integrity sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA== + dependencies: + event-stream "=3.3.4" + +psl@^1.1.28: + version "1.8.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" + integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== + +pug-attrs@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pug-attrs/-/pug-attrs-3.0.0.tgz#b10451e0348165e31fad1cc23ebddd9dc7347c41" + integrity sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA== + dependencies: + constantinople "^4.0.1" + js-stringify "^1.0.2" + pug-runtime "^3.0.0" + +pug-code-gen@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/pug-code-gen/-/pug-code-gen-3.0.2.tgz#ad190f4943133bf186b60b80de483100e132e2ce" + integrity sha512-nJMhW16MbiGRiyR4miDTQMRWDgKplnHyeLvioEJYbk1RsPI3FuA3saEP8uwnTb2nTJEKBU90NFVWJBk4OU5qyg== + dependencies: + constantinople "^4.0.1" + doctypes "^1.1.0" + js-stringify "^1.0.2" + pug-attrs "^3.0.0" + pug-error "^2.0.0" + pug-runtime "^3.0.0" + void-elements "^3.1.0" + with "^7.0.0" + +pug-error@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pug-error/-/pug-error-2.0.0.tgz#5c62173cb09c34de2a2ce04f17b8adfec74d8ca5" + integrity sha512-sjiUsi9M4RAGHktC1drQfCr5C5eriu24Lfbt4s+7SykztEOwVZtbFk1RRq0tzLxcMxMYTBR+zMQaG07J/btayQ== + +pug-filters@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/pug-filters/-/pug-filters-4.0.0.tgz#d3e49af5ba8472e9b7a66d980e707ce9d2cc9b5e" + integrity sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A== + dependencies: + constantinople "^4.0.1" + jstransformer "1.0.0" + pug-error "^2.0.0" + pug-walk "^2.0.0" + resolve "^1.15.1" + +pug-lexer@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/pug-lexer/-/pug-lexer-5.0.1.tgz#ae44628c5bef9b190b665683b288ca9024b8b0d5" + integrity sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w== + dependencies: + character-parser "^2.2.0" + is-expression "^4.0.0" + pug-error "^2.0.0" + +pug-linker@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/pug-linker/-/pug-linker-4.0.0.tgz#12cbc0594fc5a3e06b9fc59e6f93c146962a7708" + integrity sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw== + dependencies: + pug-error "^2.0.0" + pug-walk "^2.0.0" + +pug-load@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pug-load/-/pug-load-3.0.0.tgz#9fd9cda52202b08adb11d25681fb9f34bd41b662" + integrity sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ== + dependencies: + object-assign "^4.1.1" + pug-walk "^2.0.0" + +pug-parser@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/pug-parser/-/pug-parser-6.0.0.tgz#a8fdc035863a95b2c1dc5ebf4ecf80b4e76a1260" + integrity sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw== + dependencies: + pug-error "^2.0.0" + token-stream "1.0.0" + +pug-runtime@^3.0.0, pug-runtime@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/pug-runtime/-/pug-runtime-3.0.1.tgz#f636976204723f35a8c5f6fad6acda2a191b83d7" + integrity sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg== + +pug-strip-comments@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pug-strip-comments/-/pug-strip-comments-2.0.0.tgz#f94b07fd6b495523330f490a7f554b4ff876303e" + integrity sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ== + dependencies: + pug-error "^2.0.0" + +pug-walk@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pug-walk/-/pug-walk-2.0.0.tgz#417aabc29232bb4499b5b5069a2b2d2a24d5f5fe" + integrity sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ== + +pug@3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/pug/-/pug-3.0.2.tgz#f35c7107343454e43bc27ae0ff76c731b78ea535" + integrity sha512-bp0I/hiK1D1vChHh6EfDxtndHji55XP/ZJKwsRqrz6lRia6ZC2OZbdAymlxdVFwd1L70ebrVJw4/eZ79skrIaw== + dependencies: + pug-code-gen "^3.0.2" + pug-filters "^4.0.0" + pug-lexer "^5.0.1" + pug-linker "^4.0.0" + pug-load "^3.0.0" + pug-parser "^6.0.0" + pug-runtime "^3.0.1" + pug-strip-comments "^2.0.0" + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +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.1, punycode@^2.1.0, punycode@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +pureimage@0.3.5: + version "0.3.5" + resolved "https://registry.yarnpkg.com/pureimage/-/pureimage-0.3.5.tgz#cd5e91f7b6409fcf4880297aaa3e7fc0afc24d5e" + integrity sha512-+CFUEpoX6GemlKlHihI7Ii4IqKqF5KZjd682sAxwzbc4t4zU4Gwhxd4W3UMZW94nJzf0n4nA9zJrwTR4jZB4TA== + dependencies: + jpeg-js "^0.4.1" + opentype.js "^0.4.3" + pngjs "^3.3.1" + +q@^1.1.2: + version "1.5.1" + resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" + integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= + +qrcode@1.4.4: + version "1.4.4" + resolved "https://registry.yarnpkg.com/qrcode/-/qrcode-1.4.4.tgz#f0c43568a7e7510a55efc3b88d9602f71963ea83" + integrity sha512-oLzEC5+NKFou9P0bMj5+v6Z40evexeE29Z9cummZXZ9QXyMr3lphkURzxjXgPJC5azpxcshoDWV1xE46z+/c3Q== + dependencies: + buffer "^5.4.3" + buffer-alloc "^1.2.0" + buffer-from "^1.1.1" + dijkstrajs "^1.0.1" + isarray "^2.0.1" + pngjs "^3.3.0" + yargs "^13.2.4" + +qs@~6.5.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" + integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== + +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= + +quick-lru@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" + integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== + +ramda@~0.27.1: + version "0.27.1" + resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.27.1.tgz#66fc2df3ef873874ffc2da6aa8984658abacf5c9" + integrity sha512-PgIdVpn5y5Yns8vqb8FzBUEYn98V3xcPgawAkkgj0YJ0qDsnHCiNmZYfOGMgOvoB0eWFLpYbhxUR3mxfDIMvpw== + +random-seed@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/random-seed/-/random-seed-0.3.0.tgz#d945f2e1f38f49e8d58913431b8bf6bb937556cd" + integrity sha1-2UXy4fOPSejViRNDG4v2u5N1Vs0= + dependencies: + json-stringify-safe "^5.0.1" + +randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +rangestr@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/rangestr/-/rangestr-0.0.1.tgz#f72ff9246f10f2a7d7c16e14616f617be2c2635a" + integrity sha1-9y/5JG8Q8qfXwW4UYW9he+LCY1o= + +ratelimiter@3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/ratelimiter/-/ratelimiter-3.4.1.tgz#fa69e94937413382a926aaa17aaeaa6263af4659" + integrity sha512-5FJbRW/Jkkdk29ksedAfWFkQkhbUrMx3QJGwMKAypeIiQf4yrLW+gtPKZiaWt4zPrtw1uGufOjGO7UGM6VllsQ== + +readdirp@~3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.3.0.tgz#984458d13a1e42e2e9f5841b129e162f369aff17" + integrity sha512-zz0pAkSPOXXm1viEwygWIPSPkcBYjW1xU5j/JBh5t9bGCJwa6f9+BJa6VaB2g+b55yVrmXzqkyLf4xaWYM0IkQ== + dependencies: + picomatch "^2.0.7" + +rechoir@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.7.0.tgz#32650fd52c21ab252aa5d65b19310441c7e03aca" + integrity sha512-ADsDEH2bvbjltXEP+hTIAmeFekTFK0V2BTxMkok6qILyAJEXV0AFfoWcAq4yfll5VdIMd/RVXq0lR+wQi5ZU3Q== + dependencies: + resolve "^1.9.0" + +reconnecting-websocket@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/reconnecting-websocket/-/reconnecting-websocket-4.4.0.tgz#3b0e5b96ef119e78a03135865b8bb0af1b948783" + integrity sha512-D2E33ceRPga0NvTDhJmphEgJ7FUYF0v4lr1ki0csq06OdlxKfugGzN0dSkxM/NfqCxYELK4KcaTOUOjTV6Dcng== + +reflect-metadata@0.1.13: + version "0.1.13" + resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08" + integrity sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg== + +regenerator-runtime@^0.13.4: + version "0.13.7" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55" + integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew== + +regexpp@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" + integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== + +rename@1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/rename/-/rename-1.0.4.tgz#a0f25078fa4195e650f73050c7c12ccf689f430b" + integrity sha1-oPJQePpBleZQ9zBQx8Esz2ifQws= + dependencies: + debug "^2.5.2" + +repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= + +request-progress@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/request-progress/-/request-progress-3.0.0.tgz#4ca754081c7fec63f505e4faa825aa06cd669dbe" + integrity sha1-TKdUCBx/7GP1BeT6qCWqBs1mnb4= + 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" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + +require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + +require-main-filename@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" + integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== + +resolve-alpn@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.0.0.tgz#745ad60b3d6aff4b4a48e01b8c0bdc70959e0e8c" + integrity sha512-rTuiIEqFmGxne4IovivKSDzld2lWW9QCjqv80SYjPgf+gS35eaCAjaP54CCwGAwBtnCsvNLYtqxe1Nw+i6JEmA== + +resolve-cwd@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" + integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== + dependencies: + resolve-from "^5.0.0" + +resolve-dir@^1.0.0, resolve-dir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" + integrity sha1-eaQGRMNivoLybv/nOcm7U4IEb0M= + dependencies: + expand-tilde "^2.0.0" + global-modules "^1.0.0" + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +resolve@^1.15.1: + version "1.20.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" + integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== + dependencies: + is-core-module "^2.2.0" + path-parse "^1.0.6" + +resolve@^1.9.0: + version "1.18.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.18.1.tgz#018fcb2c5b207d2a6424aee361c5a266da8f4130" + integrity sha512-lDfCPaMKfOJXjy0dPayzPdF1phampNWr3qFCjAu+rw/qbQmr5jWH5xN2hwh9QKfw9E5v4hwV7A+jrCmL8yjjqA== + dependencies: + is-core-module "^2.0.0" + path-parse "^1.0.6" + +responselike@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.0.tgz#26391bcc3174f750f9a79eacc40a12a5c42d7723" + integrity sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw== + dependencies: + lowercase-keys "^2.0.0" + +restore-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" + integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== + dependencies: + onetime "^5.1.0" + signal-exit "^3.0.2" + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rimraf@3.0.2, rimraf@^3.0.0, rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +rndstr@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/rndstr/-/rndstr-1.0.0.tgz#77e66fa8f9b4836853fdd91e50719591bb67d349" + integrity sha1-d+ZvqPm0g2hT/dkeUHGVkbtn00k= + dependencies: + rangestr "0.0.1" + seedrandom "2.4.2" + +run-parallel@^1.1.9: + version "1.1.9" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.9.tgz#c9dd3a7cf9f4b2c4b6244e173a6ed866e61dd679" + integrity sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q== + +rxjs@^6.6.3: + version "6.6.6" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.6.tgz#14d8417aa5a07c5e633995b525e1e3c0dec03b70" + integrity sha512-/oTwee4N4iWzAMAL9xdGKjkEHmIwupR3oXbQjCKywF1BeFohswF3vZdogbmEF6pZkOsXTzWkrZszrWpQTByYVg== + dependencies: + tslib "^1.9.0" + +rxjs@^6.6.7: + version "6.6.7" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9" + integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ== + dependencies: + tslib "^1.9.0" + +rxjs@^7.1.0: + version "7.3.0" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.3.0.tgz#39fe4f3461dc1e50be1475b2b85a0a88c1e938c6" + integrity sha512-p2yuGIg9S1epc3vrjKf6iVb3RCaAYjYskkO+jHIaV0IjOPlJop4UnodOoFb2xeNwlguqLYvGw1b1McillYb5Gw== + dependencies: + tslib "~2.1.0" + +s-age@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/s-age/-/s-age-1.1.2.tgz#c0cf15233ccc93f41de92ea42c36d957977d1ea2" + integrity sha512-aSN2TlF39WLoZA/6cgYSJZhKt63kJ4EaadejPWjWY9/h4rksIqvfWY3gfd+3uAegSM1IXsA9aWeEhJtkxkFQtA== + +safari-14-idb-fix@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/safari-14-idb-fix/-/safari-14-idb-fix-1.0.4.tgz#5c68ba63e2a8ae0d89a0aa1e13fe89e3aef7da19" + integrity sha512-4+Y2baQdgJpzu84d0QjySl70Kyygzf0pepVg8NVg4NnQEPpfC91fAn0baNvtStlCjUUxxiu0BOMiafa98fRRuA== + +safe-buffer@5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2: + version "5.2.0" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" + integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== + +"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +sass-loader@12.3.0: + version "12.3.0" + resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-12.3.0.tgz#93278981c189c36a58cbfc37d4b9cef0cdc02871" + integrity sha512-6l9qwhdOb7qSrtOu96QQ81LVl8v6Dp9j1w3akOm0aWHyrTYtagDt5+kS32N4yq4hHk3M+rdqoRMH+lIdqvW6HA== + dependencies: + klona "^2.0.4" + neo-async "^2.6.2" + +sass@1.43.4: + version "1.43.4" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.43.4.tgz#68c7d6a1b004bef49af0d9caf750e9b252105d1f" + integrity sha512-/ptG7KE9lxpGSYiXn7Ar+lKOv37xfWsZRtFYal2QHNigyVQDx685VFT/h7ejVr+R8w7H4tmUgtulsKl5YpveOg== + dependencies: + chokidar ">=3.0.0 <4.0.0" + +sax@^1.2.4, sax@~1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + +schema-utils@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.0.0.tgz#67502f6aa2b66a2d4032b4279a2944978a0913ef" + integrity sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA== + dependencies: + "@types/json-schema" "^7.0.6" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + +schema-utils@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.0.tgz#95986eb604f66daadeed56e379bfe7a7f963cdb9" + integrity sha512-tTEaeYkyIhEZ9uWgAjDerWov3T9MgX8dhhy2r0IGeeX4W8ngtGl1++dUve/RUqzuaASSh7shwCDJjEzthxki8w== + dependencies: + "@types/json-schema" "^7.0.7" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + +secure-json-parse@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/secure-json-parse/-/secure-json-parse-2.1.0.tgz#ae76f5624256b5c497af887090a5d9e156c9fb20" + integrity sha512-GckO+MS/wT4UogDyoI/H/S1L0MCcKS1XX/vp48wfmU7Nw4woBmb8mIpu4zPBQjKlRT88/bt9xdoV4111jPpNJA== + +seedrandom@2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/seedrandom/-/seedrandom-2.4.2.tgz#18d78c41287d13aff8eadb29e235938b248aa9ff" + integrity sha1-GNeMQSh9E6/46tsp4jWTiySKqf8= + +seedrandom@3.0.5: + version "3.0.5" + resolved "https://registry.yarnpkg.com/seedrandom/-/seedrandom-3.0.5.tgz#54edc85c95222525b0c7a6f6b3543d8e0b3aa0a7" + integrity sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg== + +semver@^7.2.1, semver@^7.3.2, semver@^7.3.4: + version "7.3.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.4.tgz#27aaa7d2e4ca76452f98d3add093a72c943edc97" + integrity sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw== + dependencies: + lru-cache "^6.0.0" + +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== + dependencies: + lru-cache "^6.0.0" + +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== + dependencies: + randombytes "^2.1.0" + +serialize-javascript@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" + integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== + dependencies: + randombytes "^2.1.0" + +set-blocking@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + +shallow-clone@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" + integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== + dependencies: + kind-of "^6.0.2" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +signal-exit@^3.0.2, signal-exit@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" + integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +slice-ansi@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-3.0.0.tgz#31ddc10930a1b7e0b67b08c96c2f49b77a789787" + integrity sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ== + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + +slice-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" + integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + +sortablejs@1.10.2: + version "1.10.2" + resolved "https://registry.yarnpkg.com/sortablejs/-/sortablejs-1.10.2.tgz#6e40364d913f98b85a14f6678f92b5c1221f5290" + integrity sha512-YkPGufevysvfwn5rfdlGyrGjt7/CRHwvRPogD/lC+TnvcN29jDpCifKP+rBqf+LRldfXSTh+0CGLcSg0VIxq3A== + +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: + 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== + +sourcemap-codec@^1.4.4: + version "1.4.8" + resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" + integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== + +spawn-command@^0.0.2-1: + version "0.0.2-1" + resolved "https://registry.yarnpkg.com/spawn-command/-/spawn-command-0.0.2-1.tgz#62f5e9466981c1b796dc5929937e11c9c6921bd0" + integrity sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A= + +speakeasy@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/speakeasy/-/speakeasy-2.0.0.tgz#85c91a071b09a5cb8642590d983566165f57613a" + integrity sha1-hckaBxsJpcuGQlkNmDVmFl9XYTo= + dependencies: + base32.js "0.0.1" + +split@0.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/split/-/split-0.3.3.tgz#cd0eea5e63a211dfff7eb0f091c4133e2d0dd28f" + integrity sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8= + dependencies: + through "2" + +sprintf-js@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.2.tgz#da1765262bf8c0f571749f2ad6c26300207ae673" + integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug== + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +sshpk@^1.7.0: + version "1.16.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" + integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + +stable@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" + integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== + +start-server-and-test@1.14.0: + version "1.14.0" + resolved "https://registry.yarnpkg.com/start-server-and-test/-/start-server-and-test-1.14.0.tgz#c57f04f73eac15dd51733b551d775b40837fdde3" + integrity sha512-on5ELuxO2K0t8EmNj9MtVlFqwBMxfWOhu4U7uZD1xccVpFlOQKR93CSe0u98iQzfNxRyaNTb/CdadbNllplTsw== + dependencies: + bluebird "3.7.2" + check-more-types "2.24.0" + debug "4.3.2" + execa "5.1.1" + lazy-ass "1.6.0" + ps-tree "1.2.0" + wait-on "6.0.0" + +stream-combiner@~0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.0.4.tgz#4d5e433c185261dde623ca3f44c586bcf5c4ad14" + integrity sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ= + dependencies: + duplexer "~0.1.1" + +stream-parser@~0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/stream-parser/-/stream-parser-0.3.1.tgz#1618548694420021a1182ff0af1911c129761773" + integrity sha1-FhhUhpRCACGhGC/wrxkRwSl2F3M= + dependencies: + debug "2" + +strict-event-emitter-types@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strict-event-emitter-types/-/strict-event-emitter-types-2.0.0.tgz#05e15549cb4da1694478a53543e4e2f4abcf277f" + integrity sha512-Nk/brWYpD85WlOgzw5h173aci0Teyv8YdIAEtV+N88nDB0dLlazZyJMIsN6eo1/AR61l+p6CJTG1JIyFaoNEEA== + +"string-width@^1.0.2 || 2": + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string-width@^3.0.0, string-width@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" + integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== + dependencies: + emoji-regex "^7.0.1" + is-fullwidth-code-point "^2.0.0" + strip-ansi "^5.1.0" + +string-width@^4.1.0, string-width@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" + integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.0" + +string.prototype.trimend@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz#85812a6b847ac002270f5808146064c995fb6913" + integrity sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" + +string.prototype.trimleft@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz#4408aa2e5d6ddd0c9a80739b087fbc067c03b3cc" + integrity sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" + string.prototype.trimstart "^1.0.0" + +string.prototype.trimright@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz#c76f1cef30f21bbad8afeb8db1511496cfb0f2a3" + integrity sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" + string.prototype.trimend "^1.0.0" + +string.prototype.trimstart@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz#14af6d9f34b053f7cfc89b72f8f2ee14b9039a54" + integrity sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" + +stringz@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/stringz/-/stringz-2.1.0.tgz#5896b4713eac31157556040fb90258fb02c1630c" + integrity sha512-KlywLT+MZ+v0IRepfMxRtnSvDCMc3nR1qqCs3m/qIbSOWkNZYT8XHQA31rS3TnKp0c5xjZu3M4GY/2aRKSi/6A== + dependencies: + char-regex "^1.0.2" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= + dependencies: + ansi-regex "^3.0.0" + +strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" + integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== + dependencies: + ansi-regex "^4.1.0" + +strip-ansi@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" + integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== + dependencies: + ansi-regex "^5.0.0" + +strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= + +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + +strip-json-comments@3.1.1, strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +style-loader@3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.3.1.tgz#057dfa6b3d4d7c7064462830f9113ed417d38575" + integrity sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ== + +stylehacks@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-5.0.1.tgz#323ec554198520986806388c7fdaebc38d2c06fb" + integrity sha512-Es0rVnHIqbWzveU1b24kbw92HsebBepxfcqe5iix7t9j0PQqhs0IxXVXv0pY2Bxa08CgMkzD6OWql7kbGOuEdA== + dependencies: + browserslist "^4.16.0" + postcss-selector-parser "^6.0.4" + +supports-color@8.1.1, supports-color@^8.0.0, supports-color@^8.1.0, supports-color@^8.1.1: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.0.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== + dependencies: + has-flag "^4.0.0" + +svgo@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.3.2.tgz#b6dc511c063346c9e415b81e43401145b96d4167" + integrity sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw== + dependencies: + chalk "^2.4.1" + coa "^2.0.2" + css-select "^2.0.0" + css-select-base-adapter "^0.1.1" + css-tree "1.0.0-alpha.37" + csso "^4.0.2" + js-yaml "^3.13.1" + mkdirp "~0.5.1" + object.values "^1.1.0" + sax "~1.2.4" + stable "^0.1.8" + unquote "~1.1.1" + util.promisify "~1.0.0" + +svgo@^2.7.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/svgo/-/svgo-2.8.0.tgz#4ff80cce6710dc2795f0c7c74101e6764cfccd24" + integrity sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg== + dependencies: + "@trysound/sax" "0.2.0" + commander "^7.2.0" + css-select "^4.1.3" + css-tree "^1.1.3" + csso "^4.2.0" + picocolors "^1.0.0" + stable "^0.1.8" + +syuilo-password-strength@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/syuilo-password-strength/-/syuilo-password-strength-0.0.1.tgz#08f71a8f0ecb77db649f3d9a6424510d9d945f52" + integrity sha1-CPcajw7Ld9tknz2aZCRRDZ2UX1I= + +tapable@^2.1.1, tapable@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.0.tgz#5c373d281d9c672848213d0e037d1c4165ab426b" + integrity sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw== + +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-webpack-plugin@^5.1.3: + version "5.1.4" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.1.4.tgz#c369cf8a47aa9922bd0d8a94fe3d3da11a7678a1" + integrity sha512-C2WkFwstHDhVEmsmlCxrXUtVklS+Ir1A7twrYzrDrQQOIMOaVAYykaoo/Aq1K0QRkMoY2hhvDQY1cm4jnIMFwA== + dependencies: + jest-worker "^27.0.2" + p-limit "^3.1.0" + schema-utils "^3.0.0" + serialize-javascript "^6.0.0" + source-map "^0.6.1" + terser "^5.7.0" + +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" + +terser@^5.7.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.7.1.tgz#2dc7a61009b66bb638305cb2a824763b116bf784" + integrity sha512-b3e+d5JbHAe/JSjwsC3Zn55wsBIM7AsHLjKxT31kGCldgbpFePaFo+PiddtO6uwRZWRw7sPXmAN8dTW61xmnSg== + 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" + integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= + +textarea-caret@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/textarea-caret/-/textarea-caret-3.1.0.tgz#5d5a35bb035fd06b2ff0e25d5359e97f2655087f" + integrity sha512-cXAvzO9pP5CGa6NKx0WYHl+8CHKZs8byMkt3PCJBCmq2a34YA9pO1NrQET5pzeqnBjBdToF5No4rrmkDUgQC2Q== + +three@0.117.1: + version "0.117.1" + resolved "https://registry.yarnpkg.com/three/-/three-0.117.1.tgz#a49bcb1a6ddea2f250003e42585dc3e78e92b9d3" + integrity sha512-t4zeJhlNzUIj9+ub0l6nICVimSuRTZJOqvk3Rmlu+YGdTOJ49Wna8p7aumpkXJakJfITiybfpYE1XN1o1Z34UQ== + +throttle-debounce@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/throttle-debounce/-/throttle-debounce-3.0.1.tgz#32f94d84dfa894f786c9a1f290e7a645b6a19abb" + integrity sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg== + +throttleit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-1.0.0.tgz#9e785836daf46743145a5984b6268d828528ac6c" + integrity sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw= + +through@2, through@^2.3.8, through@~2.3, through@~2.3.1: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= + +timsort@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4" + integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q= + +tinycolor2@1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.4.2.tgz#3f6a4d1071ad07676d7fa472e1fac40a719d8803" + integrity sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA== + +tmp@0.2.1, tmp@~0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" + integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== + dependencies: + rimraf "^3.0.0" + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +token-stream@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/token-stream/-/token-stream-1.0.0.tgz#cc200eab2613f4166d27ff9afc7ca56d49df6eb4" + integrity sha1-zCAOqyYT9BZtJ/+a/HylbUnfbrQ= + +tough-cookie@~2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + +tree-kill@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" + integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== + +ts-loader@9.2.6: + version "9.2.6" + resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.2.6.tgz#9937c4dd0a1e3dbbb5e433f8102a6601c6615d74" + integrity sha512-QMTC4UFzHmu9wU2VHZEmWWE9cUajjfcdcws+Gh7FhiO+Dy0RnR1bNz0YCHqhI0yRowCE9arVnNxYHqELOy9Hjw== + dependencies: + chalk "^4.1.0" + enhanced-resolve "^5.0.0" + micromatch "^4.0.0" + semver "^7.3.4" + +ts-node@10.4.0: + version "10.4.0" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.4.0.tgz#680f88945885f4e6cf450e7f0d6223dd404895f7" + integrity sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A== + dependencies: + "@cspotcode/source-map-support" "0.7.0" + "@tsconfig/node10" "^1.0.7" + "@tsconfig/node12" "^1.0.7" + "@tsconfig/node14" "^1.0.0" + "@tsconfig/node16" "^1.0.2" + acorn "^8.4.1" + acorn-walk "^8.1.1" + arg "^4.1.0" + create-require "^1.1.0" + diff "^4.0.1" + make-error "^1.1.1" + yn "3.1.1" + +tsc-alias@1.3.10: + version "1.3.10" + resolved "https://registry.yarnpkg.com/tsc-alias/-/tsc-alias-1.3.10.tgz#6ccf81c644092387ab9be3a3a75549a95eeffd80" + integrity sha512-7SF56qiV7Oh/bON+XjF/uAzEFqbmwCuEIHQyoTyVJAK80WnxaIyhO9TBwD/x8InIMU8lnvExQBOrgKkRPsHH+w== + dependencies: + "@jfonx/console-utils" "^1.0.3" + "@jfonx/file-utils" "^3.0.1" + chokidar "^3.5.0" + commander "^6.2.1" + find-node-modules "^2.1.0" + globby "^11.0.2" + normalize-path "^3.0.0" + +tsconfig-paths@3.11.0: + version "3.11.0" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz#954c1fe973da6339c78e06b03ce2e48810b65f36" + integrity sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA== + dependencies: + "@types/json5" "^0.0.29" + json5 "^1.0.1" + minimist "^1.2.0" + strip-bom "^3.0.0" + +tslib@^1.8.1, tslib@^1.9.0: + version "1.11.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35" + integrity sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA== + +tslib@^1.9.3: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + +tslib@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a" + integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A== + +tsutils@^3.21.0: + version "3.21.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" + integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== + dependencies: + tslib "^1.8.1" + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= + +twemoji-parser@13.1.0, twemoji-parser@13.1.x: + version "13.1.0" + resolved "https://registry.yarnpkg.com/twemoji-parser/-/twemoji-parser-13.1.0.tgz#65e7e449c59258791b22ac0b37077349127e3ea4" + integrity sha512-AQOzLJpYlpWMy8n+0ATyKKZzWlZBJN+G0C+5lhX7Ftc2PeEVdUU/7ns2Pn2vVje26AIZ/OHwFoUbdv6YYD/wGg== + +type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== + dependencies: + prelude-ls "^1.2.1" + +type-detect@4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== + +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + +type-fest@^0.21.3: + version "0.21.3" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== + +type@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" + integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== + +type@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/type/-/type-2.0.0.tgz#5f16ff6ef2eb44f260494dae271033b29c09a9c3" + integrity sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow== + +typedarray-to-buffer@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== + dependencies: + is-typedarray "^1.0.0" + +typescript@4.4.4: + version "4.4.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.4.4.tgz#2cd01a1a1f160704d3101fd5a58ff0f9fcb8030c" + integrity sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA== + +uniq@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" + integrity sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8= + +uniqs@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/uniqs/-/uniqs-2.0.0.tgz#ffede4b36b25290696e6e165d4a59edb998e6b02" + integrity sha1-/+3ks2slKQaW5uFl1KWe25mOawI= + +universalify@^0.1.0, universalify@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +universalify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" + integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== + +unload@2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/unload/-/unload-2.3.1.tgz#9d16862d372a5ce5cb630ad1309c2fd6e35dacfe" + integrity sha512-MUZEiDqvAN9AIDRbbBnVYVvfcR6DrjCqeU2YQMmliFZl9uaBUjTkhuDQkBiyAy8ad5bx1TXVbqZ3gg7namsWjA== + dependencies: + "@babel/runtime" "^7.6.2" + detect-node "2.1.0" + +unquote@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unquote/-/unquote-1.1.1.tgz#8fded7324ec6e88a0ff8b905e7c098cdc086d544" + integrity sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ= + +untildify@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" + integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== + +uri-js@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" + integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== + dependencies: + punycode "^2.1.0" + +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" + +urlsafe-base64@^1.0.0, urlsafe-base64@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/urlsafe-base64/-/urlsafe-base64-1.0.0.tgz#23f89069a6c62f46cf3a1d3b00169cefb90be0c6" + integrity sha1-I/iQaabGL0bPOh07ABac77kL4MY= + +utf-8-validate@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.2.tgz#63cfbccd85dc1f2b66cf7a1d0eebc08ed056bfb3" + integrity sha512-SwV++i2gTD5qh2XqaPzBnNX88N6HdyhQrNNRykvcS0QKvItV9u3vPEJr+X5Hhfb1JC0r0e1alL0iB09rY8+nmw== + dependencies: + node-gyp-build "~3.7.0" + +util-deprecate@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +util.promisify@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.1.tgz#6baf7774b80eeb0f7520d8b81d07982a59abbaee" + integrity sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.2" + has-symbols "^1.0.1" + object.getownpropertydescriptors "^2.1.0" + +uuid@7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-7.0.3.tgz#c5c9f2c8cf25dc0a372c4df1441c41f5bd0c680b" + integrity sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg== + +uuid@8.3.2, uuid@^8.3.2: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + +v-debounce@0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/v-debounce/-/v-debounce-0.1.2.tgz#cab75df7def2783215bf449ef85c69c2decf0a55" + integrity sha1-yrdd997yeDIVv0Se+Fxpwt7PClU= + +v8-compile-cache@^2.0.3: + version "2.2.0" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz#9471efa3ef9128d2f7c6a7ca39c4dd6b5055b132" + integrity sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q== + +vanilla-tilt@1.7.2: + version "1.7.2" + resolved "https://registry.yarnpkg.com/vanilla-tilt/-/vanilla-tilt-1.7.2.tgz#59a5565d9f1f6d392a36969f223fb600dd101a81" + integrity sha512-arf2wY2Y65rP6Zxve9PnUUnRl9nQ1KenPNae6QRaVq/PEvaIto2bC4jYirNJ19U7nLkzI1H9O+nYtcQlX7BTsA== + +vendors@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.4.tgz#e2b800a53e7a29b93506c3cf41100d16c4c4ad8e" + integrity sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w== + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +void-elements@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-3.1.0.tgz#614f7fbf8d801f0bb5f0661f5b2f5785750e4f09" + integrity sha1-YU9/v42AHwu18GYfWy9XhXUOTwk= + +vue-eslint-parser@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-8.0.1.tgz#25e08b20a414551531f3e19f999902e1ecf45f13" + integrity sha512-lhWjDXJhe3UZw2uu3ztX51SJAPGPey1Tff2RK3TyZURwbuI4vximQLzz4nQfCv8CZq4xx7uIiogHMMoSJPr33A== + dependencies: + debug "^4.3.2" + eslint-scope "^6.0.0" + eslint-visitor-keys "^3.0.0" + espree "^9.0.0" + esquery "^1.4.0" + lodash "^4.17.21" + semver "^7.3.5" + +vue-loader@16.7.0: + version "16.7.0" + resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-16.7.0.tgz#ee161b2f6c27b0b459264c3c23d34068b471d574" + integrity sha512-43I0grWtwSCE8fiH/hAwFK+6sNlmvDuHhXScYH8HVSVAMS81IM66tgUOcxbPCeqhhz/1BE51YPxX59eZKGallQ== + dependencies: + chalk "^4.1.0" + hash-sum "^2.0.0" + loader-utils "^2.0.0" + +vue-prism-editor@2.0.0-alpha.2: + version "2.0.0-alpha.2" + resolved "https://registry.yarnpkg.com/vue-prism-editor/-/vue-prism-editor-2.0.0-alpha.2.tgz#aa53a88efaaed628027cbb282c2b1d37fc7c5c69" + integrity sha512-Gu42ba9nosrE+gJpnAEuEkDMqG9zSUysIR8SdXUw8MQKDjBnnNR9lHC18uOr/ICz7yrA/5c7jHJr9lpElODC7w== + +vue-router@4.0.5: + version "4.0.5" + resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-4.0.5.tgz#dd0a4134bc950c37aef64b973e9ee1008428d8fa" + integrity sha512-AQq+pllb6FCc7rS6vh4PPcce3XA1jgK3hKNkQ4hXHwoVN7jOeAOMKCnX7XAX3etV9rmN7iNW8iIwgPk95ckBjw== + +vue-style-loader@4.1.3: + version "4.1.3" + resolved "https://registry.yarnpkg.com/vue-style-loader/-/vue-style-loader-4.1.3.tgz#6d55863a51fa757ab24e89d9371465072aa7bc35" + integrity sha512-sFuh0xfbtpRlKfm39ss/ikqs9AbKCoXZBpHeVZ8Tx650o0k0q/YCM7FRvigtxpACezfq6af+a7JeqVTWvncqDg== + dependencies: + hash-sum "^1.0.2" + loader-utils "^1.0.2" + +vue-svg-loader@0.17.0-beta.2: + version "0.17.0-beta.2" + resolved "https://registry.yarnpkg.com/vue-svg-loader/-/vue-svg-loader-0.17.0-beta.2.tgz#954b2a08b5488998dd81ec371ab5fb5ea4182ef7" + integrity sha512-iMUGJTKEcuNAG8VXOchjA8443IqEmEi2Aw6EVIHWma2cC4TUQ7Oet5Yry9IFfqXQXXvyzXz5EyttVvfRGTNH4Q== + dependencies: + loader-utils "^2.0.0" + semver "^7.3.2" + svgo "^1.3.2" + +vue@3.2.21: + version "3.2.21" + resolved "https://registry.yarnpkg.com/vue/-/vue-3.2.21.tgz#55f5665172d95cf97e806b9aad0a375180be23a1" + integrity sha512-jpy7ckXdyclfRzqLjL4mtq81AkzQleE54KjZsJg/9OorNVurAxdlU5XpD49GpjKdnftuffKUvx2C5jDOrgc/zg== + dependencies: + "@vue/compiler-dom" "3.2.21" + "@vue/compiler-sfc" "3.2.21" + "@vue/runtime-dom" "3.2.21" + "@vue/server-renderer" "3.2.21" + "@vue/shared" "3.2.21" + +vuedraggable@4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/vuedraggable/-/vuedraggable-4.0.1.tgz#3bcaab0808b7944030b7d9a29f9a63d59dfa12c5" + integrity sha512-7qN5jhB1SLfx5P+HCm3JUW+pvgA1bSLgYLSVOeLWBDH9z+zbaEH0OlyZBVMLOxFR+JUHJjwDD0oy7T4r9TEgDA== + dependencies: + sortablejs "1.10.2" + +wait-on@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/wait-on/-/wait-on-6.0.0.tgz#7e9bf8e3d7fe2daecbb7a570ac8ca41e9311c7e7" + integrity sha512-tnUJr9p5r+bEYXPUdRseolmz5XqJTTj98JgOsfBn7Oz2dxfE2g3zw1jE+Mo8lopM3j3et/Mq1yW7kKX6qw7RVw== + dependencies: + axios "^0.21.1" + joi "^17.4.0" + lodash "^4.17.21" + minimist "^1.2.5" + rxjs "^7.1.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== + dependencies: + glob-to-regexp "^0.4.1" + graceful-fs "^4.1.2" + +watchpack@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.2.0.tgz#47d78f5415fe550ecd740f99fe2882323a58b1ce" + integrity sha512-up4YAn/XHgZHIxFBVCdlMiWDj6WaLKpwVeGQk2I5thdYxF/KmF0aaz6TfJZ/hfl1h/XlcDr7k1KH7ThDagpFaA== + dependencies: + glob-to-regexp "^0.4.1" + graceful-fs "^4.1.2" + +web-push@3.4.5: + version "3.4.5" + resolved "https://registry.yarnpkg.com/web-push/-/web-push-3.4.5.tgz#f94074ff150538872c7183e4d8881c8305920cf1" + integrity sha512-2njbTqZ6Q7ZqqK14YpK1GGmaZs3NmuGYF5b7abCXulUIWFSlSYcZ3NBJQRFcMiQDceD7vQknb8FUuvI1F7Qe/g== + dependencies: + asn1.js "^5.3.0" + http_ece "1.1.0" + https-proxy-agent "^5.0.0" + jws "^4.0.0" + minimist "^1.2.5" + urlsafe-base64 "^1.0.0" + +webpack-cli@4.9.1: + version "4.9.1" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.9.1.tgz#b64be825e2d1b130f285c314caa3b1ba9a4632b3" + integrity sha512-JYRFVuyFpzDxMDB+v/nanUdQYcZtqFPGzmlW4s+UkPMFhSpfRNmf1z4AwYcHJVdvEFAM7FFCQdNTpsBYhDLusQ== + dependencies: + "@discoveryjs/json-ext" "^0.5.0" + "@webpack-cli/configtest" "^1.1.0" + "@webpack-cli/info" "^1.4.0" + "@webpack-cli/serve" "^1.6.0" + colorette "^2.0.14" + commander "^7.0.0" + execa "^5.0.0" + fastest-levenshtein "^1.0.12" + import-local "^3.0.2" + interpret "^2.2.0" + rechoir "^0.7.0" + webpack-merge "^5.7.3" + +webpack-merge@^5.7.3: + version "5.7.3" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.7.3.tgz#2a0754e1877a25a8bbab3d2475ca70a052708213" + integrity sha512-6/JUQv0ELQ1igjGDzHkXbVDRxkfA57Zw7PfiupdLFJYrgFqY5ZP8xxbpp2lU3EPwYx89ht5Z/aDkD40hFCm5AA== + dependencies: + clone-deep "^4.0.1" + wildcard "^2.0.0" + +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-sources@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.0.tgz#b16973bcf844ebcdb3afde32eda1c04d0b90f89d" + integrity sha512-fahN08Et7P9trej8xz/Z7eRu8ltyiygEo/hnRi9KqBUs80KeDcnf96ZJo++ewWd84fEf3xSX9bp4ZS9hbw0OBw== + +webpack@5.63.0: + version "5.63.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.63.0.tgz#4b074115800e0526d85112985e46c64b95e04aaf" + integrity sha512-HYrw6bkj/MDmphAXvqLEvn2fVoDZsYu6O638WjK6lSNgIpjb5jl/KtOrqJyU9EC/ZV9mLUmZW5h4mASB+CVA4A== + dependencies: + "@types/eslint-scope" "^3.7.0" + "@types/estree" "^0.0.50" + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/wasm-edit" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + acorn "^8.4.1" + acorn-import-assertions "^1.7.6" + browserslist "^4.14.5" + chrome-trace-event "^1.0.2" + enhanced-resolve "^5.8.3" + es-module-lexer "^0.9.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.1.0" + tapable "^2.1.1" + terser-webpack-plugin "^5.1.3" + watchpack "^2.2.0" + webpack-sources "^3.2.0" + +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" + +websocket@1.0.34: + version "1.0.34" + resolved "https://registry.yarnpkg.com/websocket/-/websocket-1.0.34.tgz#2bdc2602c08bf2c82253b730655c0ef7dcab3111" + integrity sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ== + dependencies: + bufferutil "^4.0.1" + debug "^2.2.0" + es5-ext "^0.10.50" + typedarray-to-buffer "^3.1.5" + utf-8-validate "^5.0.2" + yaeti "^0.0.6" + +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= + +which@2.0.2, which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +which@^1.2.14: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +wide-align@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== + dependencies: + string-width "^1.0.2 || 2" + +wildcard@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.0.tgz#a77d20e5200c6faaac979e4b3aadc7b3dd7f8fec" + integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw== + +with@^7.0.0: + version "7.0.2" + resolved "https://registry.yarnpkg.com/with/-/with-7.0.2.tgz#ccee3ad542d25538a7a7a80aad212b9828495bac" + integrity sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w== + dependencies: + "@babel/parser" "^7.9.6" + "@babel/types" "^7.9.6" + assert-never "^1.2.1" + babel-walk "3.0.0-canary-5" + +word-wrap@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + +workerpool@6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.1.0.tgz#a8e038b4c94569596852de7a8ea4228eefdeb37b" + integrity sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg== + +wrap-ansi@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" + integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== + dependencies: + ansi-styles "^3.2.0" + string-width "^3.0.0" + strip-ansi "^5.0.0" + +wrap-ansi@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" + integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +ws@8.2.3: + version "8.2.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.2.3.tgz#63a56456db1b04367d0b721a0b80cae6d8becbba" + integrity sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA== + +xml-js@^1.6.11: + version "1.6.11" + resolved "https://registry.yarnpkg.com/xml-js/-/xml-js-1.6.11.tgz#927d2f6947f7f1c19a316dd8eea3614e8b18f8e9" + integrity sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g== + dependencies: + sax "^1.2.4" + +y18n@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.1.tgz#8db2b83c31c5d75099bb890b23f3094891e247d4" + integrity sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ== + +y18n@^5.0.5: + version "5.0.5" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.5.tgz#8769ec08d03b1ea2df2500acef561743bbb9ab18" + integrity sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg== + +yaeti@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/yaeti/-/yaeti-0.0.6.tgz#f26f484d72684cf42bedfb76970aa1608fbf9577" + integrity sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc= + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yaml-ast-parser@0.0.43: + version "0.0.43" + resolved "https://registry.yarnpkg.com/yaml-ast-parser/-/yaml-ast-parser-0.0.43.tgz#e8a23e6fb4c38076ab92995c5dca33f3d3d7c9bb" + integrity sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A== + +yaml@^1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.0.tgz#3b593add944876077d4d683fee01081bd9fff31e" + integrity sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg== + +yaml@^1.10.2: + version "1.10.2" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" + integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== + +yargs-parser@20.2.4, yargs-parser@^20.2.2: + version "20.2.4" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" + integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== + +yargs-parser@^13.1.2: + version "13.1.2" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" + integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs-unparser@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" + integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== + dependencies: + camelcase "^6.0.0" + decamelize "^4.0.0" + flat "^5.0.2" + is-plain-obj "^2.1.0" + +yargs@16.2.0, yargs@^16.2.0: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + +yargs@^13.2.4: + version "13.3.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" + integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw== + dependencies: + cliui "^5.0.0" + find-up "^3.0.0" + get-caller-file "^2.0.1" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^3.0.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^13.1.2" + +yauzl@^2.10.0: + version "2.10.0" + resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" + integrity sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk= + dependencies: + buffer-crc32 "~0.2.3" + fd-slicer "~1.1.0" + +yn@3.1.1: + version "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== diff --git a/src/meta.json b/packages/meta.json similarity index 100% rename from src/meta.json rename to packages/meta.json diff --git a/scripts/build.js b/scripts/build.js new file mode 100644 index 000000000..6d4bb6c6e --- /dev/null +++ b/scripts/build.js @@ -0,0 +1,33 @@ +const execa = require('execa'); + +(async () => { + console.log('building packages/backend ...'); + + await execa('npm', ['run', 'build'], { + cwd: __dirname + '/../packages/backend', + stdout: process.stdout, + stderr: process.stderr, + }); + + console.log('building packages/client ...'); + + await execa('npm', ['run', 'build'], { + cwd: __dirname + '/../packages/client', + stdout: process.stdout, + stderr: process.stderr, + }); + + await execa('npm', ['run', 'build'], { + cwd: __dirname + '/../packages/client', + stdout: process.stdout, + stderr: process.stderr, + }); + + console.log('build finishing ...'); + + await execa('npm', ['run', 'gulp'], { + cwd: __dirname + '/../', + stdout: process.stdout, + stderr: process.stderr, + }); +})(); diff --git a/scripts/clean.js b/scripts/clean.js new file mode 100644 index 000000000..1dca10605 --- /dev/null +++ b/scripts/clean.js @@ -0,0 +1,13 @@ +const fs = require('fs'); +const execa = require('execa'); + +(async () => { + fs.rmSync(__dirname + '/../packages/backend/built', { recursive: true, force: true }); + fs.rmSync(__dirname + '/../packages/backend/node_modules', { recursive: true, force: true }); + + fs.rmSync(__dirname + '/../packages/client/built', { recursive: true, force: true }); + fs.rmSync(__dirname + '/../packages/client/node_modules', { recursive: true, force: true }); + + fs.rmSync(__dirname + '/../built', { recursive: true, force: true }); + fs.rmSync(__dirname + '/../node_modules', { recursive: true, force: true }); +})(); diff --git a/scripts/install-packages.js b/scripts/install-packages.js new file mode 100644 index 000000000..c25063b29 --- /dev/null +++ b/scripts/install-packages.js @@ -0,0 +1,19 @@ +const execa = require('execa'); + +(async () => { + console.log('installing dependencies of packages/backend ...'); + + await execa('yarn', ['install'], { + cwd: __dirname + '/../packages/backend', + stdout: process.stdout, + stderr: process.stderr, + }); + + console.log('installing dependencies of packages/client ...'); + + await execa('yarn', ['install'], { + cwd: __dirname + '/../packages/client', + stdout: process.stdout, + stderr: process.stderr, + }); +})(); diff --git a/scripts/lint.js b/scripts/lint.js new file mode 100644 index 000000000..6df076563 --- /dev/null +++ b/scripts/lint.js @@ -0,0 +1,9 @@ +const execa = require('execa'); + +(async () => { + await execa('npm', ['run', 'lint'], { + cwd: __dirname + '/../packages/backend', + stdout: process.stdout, + stderr: process.stderr, + }); +})(); diff --git a/src/.eslintrc b/src/.eslintrc deleted file mode 100644 index d54e20f6b..000000000 --- a/src/.eslintrc +++ /dev/null @@ -1,6 +0,0 @@ -{ - "env": { - "node": true, - "commonjs": true - } -} diff --git a/src/@types/jsrsasign.d.ts b/src/@types/jsrsasign.d.ts deleted file mode 100644 index bc9d746f7..000000000 --- a/src/@types/jsrsasign.d.ts +++ /dev/null @@ -1,800 +0,0 @@ -// Attention: Partial Type Definition - -declare module 'jsrsasign' { - //// HELPER TYPES - - /** - * Attention: The value might be changed by the function. - */ - type Mutable = T; - - /** - * Deprecated: The function might be deleted in future release. - */ - type Deprecated = T; - - //// COMMON TYPES - - /** - * byte number - */ - type ByteNumber = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255; - - /** - * hexadecimal string /[0-9A-F]/ - */ - type HexString = string; - - /** - * binary string /[01]/ - */ - type BinString = string; - - /** - * base64 string /[A-Za-z0-9+/]=+/ - */ - type Base64String = string; - - /** - * base64 URL encoded string /[A-Za-z0-9_-]/ - */ - type Base64URLString = string; - - /** - * time value (ex. "151231235959Z") - */ - type TimeValue = string; - - /** - * OID string (ex. '1.2.3.4.567') - */ - type OID = string; - - /** - * OID name - */ - type OIDName = string; - - /** - * PEM formatted string - */ - type PEM = string; - - //// ASN1 TYPES - - class ASN1Object { - public isModified: boolean; - - public hTLV: ASN1TLV; - - public hT: ASN1T; - - public hL: ASN1L; - - public hV: ASN1V; - - public getLengthHexFromValue(): HexString; - - public getEncodedHex(): ASN1TLV; - - public getValueHex(): ASN1V; - - public getFreshValueHex(): ASN1V; - } - - class DERAbstractStructured extends ASN1Object { - constructor(params?: Partial>); - - public setByASN1ObjectArray(asn1ObjectArray: ASN1Object[]): void; - - public appendASN1Object(asn1Object: ASN1Object): void; - } - - class DERSequence extends DERAbstractStructured { - constructor(params?: Partial>); - - public getFreshValueHex(): ASN1V; - } - - //// ASN1HEX TYPES - - /** - * ASN.1 DER encoded data (hexadecimal string) - */ - type ASN1S = HexString; - - /** - * index of something - */ - type Idx = ASN1S extends { [idx: string]: unknown } ? string : ASN1S extends { [idx: number]: unknown } ? number : never; - - /** - * byte length of something - */ - type ByteLength = T['length']; - - /** - * ASN.1 L(length) (hexadecimal string) - */ - type ASN1L = HexString; - - /** - * ASN.1 T(tag) (hexadecimal string) - */ - type ASN1T = HexString; - - /** - * ASN.1 V(value) (hexadecimal string) - */ - type ASN1V = HexString; - - /** - * ASN.1 TLV (hexadecimal string) - */ - type ASN1TLV = HexString; - - /** - * ASN.1 object string - */ - type ASN1ObjectString = string; - - /** - * nth - */ - type Nth = number; - - /** - * ASN.1 DER encoded OID value (hexadecimal string) - */ - type ASN1OIDV = HexString; - - class ASN1HEX { - public static getLblen(s: ASN1S, idx: Idx): ByteLength; - - public static getL(s: ASN1S, idx: Idx): ASN1L; - - public static getVblen(s: ASN1S, idx: Idx): ByteLength; - - public static getVidx(s: ASN1S, idx: Idx): Idx; - - public static getV(s: ASN1S, idx: Idx): ASN1V; - - public static getTLV(s: ASN1S, idx: Idx): ASN1TLV; - - public static getNextSiblingIdx(s: ASN1S, idx: Idx): Idx; - - public static getChildIdx(h: ASN1S, pos: Idx): Idx[]; - - public static getNthChildIdx(h: ASN1S, idx: Idx, nth: Nth): Idx; - - public static getIdxbyList(h: ASN1S, currentIndex: Idx, nthList: Mutable, checkingTag?: string): Idx>; - - public static getTLVbyList(h: ASN1S, currentIndex: Idx, nthList: Mutable, checkingTag?: string): ASN1TLV; - - // tslint:disable-next-line:bool-param-default - public static getVbyList(h: ASN1S, currentIndex: Idx, nthList: Mutable, checkingTag?: string, removeUnusedbits?: boolean): ASN1V; - - public static hextooidstr(hex: ASN1OIDV): OID; - - public static dump(hexOrObj: ASN1S | ASN1Object, flags?: Record, idx?: Idx, indent?: string): string; - - public static isASN1HEX(hex: string): hex is HexString; - - public static oidname(oidDotOrHex: OID | ASN1OIDV): OIDName; - } - - //// BIG INTEGER TYPES (PARTIAL) - - class BigInteger { - constructor(a: null); - - constructor(a: number, b: SecureRandom); - - constructor(a: number, b: number, c: SecureRandom); - - constructor(a: unknown); - - constructor(a: string, b: number); - - public am(i: number, x: number, w: number, j: number, c: number, n: number): number; - - public DB: number; - - public DM: number; - - public DV: number; - - public FV: number; - - public F1: number; - - public F2: number; - - protected copyTo(r: Mutable): void; - - protected fromInt(x: number): void; - - protected fromString(s: string, b: number): void; - - protected clamp(): void; - - public toString(b: number): string; - - public negate(): BigInteger; - - public abs(): BigInteger; - - public compareTo(a: BigInteger): number; - - public bitLength(): number; - - protected dlShiftTo(n: number, r: Mutable): void; - - protected drShiftTo(n: number, r: Mutable): void; - - protected lShiftTo(n: number, r: Mutable): void; - - protected rShiftTo(n: number, r: Mutable): void; - - protected subTo(a: BigInteger, r: Mutable): void; - - protected multiplyTo(a: BigInteger, r: Mutable): void; - - protected squareTo(r: Mutable): void; - - protected divRemTo(m: BigInteger, q: Mutable, r: Mutable): void; - - public mod(a: BigInteger): BigInteger; - - protected invDigit(): number; - - protected isEven(): boolean; - - protected exp(e: number, z: Classic | Montgomery): BigInteger; - - public modPowInt(e: number, m: BigInteger): BigInteger; - - public static ZERO: BigInteger; - - public static ONE: BigInteger; - } - - class Classic { - constructor(m: BigInteger); - - public convert(x: BigInteger): BigInteger; - - public revert(x: BigInteger): BigInteger; - - public reduce(x: Mutable): void; - - public mulTo(x: BigInteger, r: Mutable): void; - - public sqrTo(x: BigInteger, y: BigInteger, r: Mutable): void; - } - - class Montgomery { - constructor(m: BigInteger); - - public convert(x: BigInteger): BigInteger; - - public revert(x: BigInteger): BigInteger; - - public reduce(x: Mutable): void; - - public mulTo(x: BigInteger, r: Mutable): void; - - public sqrTo(x: BigInteger, y: BigInteger, r: Mutable): void; - } - - //// KEYUTIL TYPES - - type DecryptAES = (dataHex: HexString, keyHex: HexString, ivHex: HexString) => HexString; - - type Decrypt3DES = (dataHex: HexString, keyHex: HexString, ivHex: HexString) => HexString; - - type DecryptDES = (dataHex: HexString, keyHex: HexString, ivHex: HexString) => HexString; - - type EncryptAES = (dataHex: HexString, keyHex: HexString, ivHex: HexString) => HexString; - - type Encrypt3DES = (dataHex: HexString, keyHex: HexString, ivHex: HexString) => HexString; - - type EncryptDES = (dataHex: HexString, keyHex: HexString, ivHex: HexString) => HexString; - - type AlgList = { - 'AES-256-CBC': { 'proc': DecryptAES; 'eproc': EncryptAES; keylen: 32; ivlen: 16; }; - 'AES-192-CBC': { 'proc': DecryptAES; 'eproc': EncryptAES; keylen: 24; ivlen: 16; }; - 'AES-128-CBC': { 'proc': DecryptAES; 'eproc': EncryptAES; keylen: 16; ivlen: 16; }; - 'DES-EDE3-CBC': { 'proc': Decrypt3DES; 'eproc': Encrypt3DES; keylen: 24; ivlen: 8; }; - 'DES-CBC': { 'proc': DecryptDES; 'eproc': EncryptDES; keylen: 8; ivlen: 8; }; - }; - - type AlgName = keyof AlgList; - - type PEMHeadAlgName = 'RSA' | 'EC' | 'DSA'; - - type GetKeyRSAParam = RSAKey | { - n: BigInteger; - e: number; - } | Record<'n' | 'e', HexString> | Record<'n' | 'e', HexString> & Record<'d' | 'p' | 'q' | 'dp' | 'dq' | 'co', HexString | null> | { - n: BigInteger; - e: number; - d: BigInteger; - } | { - kty: 'RSA'; - } & Record<'n' | 'e', Base64URLString> | { - kty: 'RSA'; - } & Record<'n' | 'e' | 'd' | 'p' | 'q' | 'dp' | 'dq' | 'qi', Base64URLString> | { - kty: 'RSA'; - } & Record<'n' | 'e' | 'd', Base64URLString>; - - type GetKeyECDSAParam = KJUR.crypto.ECDSA | { - curve: KJUR.crypto.CurveName; - xy: HexString; - } | { - curve: KJUR.crypto.CurveName; - d: HexString; - } | { - kty: 'EC'; - crv: KJUR.crypto.CurveName; - x: Base64URLString; - y: Base64URLString; - } | { - kty: 'EC'; - crv: KJUR.crypto.CurveName; - x: Base64URLString; - y: Base64URLString; - d: Base64URLString; - }; - - type GetKeyDSAParam = KJUR.crypto.DSA | Record<'p' | 'q' | 'g', BigInteger> & Record<'y', BigInteger | null> | Record<'p' | 'q' | 'g' | 'x', BigInteger> & Record<'y', BigInteger | null>; - - type GetKeyParam = GetKeyRSAParam | GetKeyECDSAParam | GetKeyDSAParam | string; - - class KEYUTIL { - public version: '1.0.0'; - - public parsePKCS5PEM(sPKCS5PEM: PEM): Partial> & (Record<'cipher' | 'ivsalt', string> | Record<'cipher' | 'ivsalt', undefined>); - - public getKeyAndUnusedIvByPasscodeAndIvsalt(algName: AlgName, passcode: string, ivsaltHex: HexString): Record<'keyhex' | 'ivhex', HexString>; - - public decryptKeyB64(privateKeyB64: Base64String, sharedKeyAlgName: AlgName, sharedKeyHex: HexString, ivsaltHex: HexString): Base64String; - - public getDecryptedKeyHex(sEncryptedPEM: PEM, passcode: string): HexString; - - public getEncryptedPKCS5PEMFromPrvKeyHex(pemHeadAlg: PEMHeadAlgName, hPrvKey: string, passcode: string, sharedKeyAlgName?: AlgName | null, ivsaltHex?: HexString | null): PEM; - - public parseHexOfEncryptedPKCS8(sHEX: HexString): { - ciphertext: ASN1V; - encryptionSchemeAlg: 'TripleDES'; - encryptionSchemeIV: ASN1V; - pbkdf2Salt: ASN1V; - pbkdf2Iter: number; - }; - - public getPBKDF2KeyHexFromParam(info: ReturnType, passcode: string): HexString; - - private _getPlainPKCS8HexFromEncryptedPKCS8PEM(pkcs8PEM: PEM, passcode: string): HexString; - - public getKeyFromEncryptedPKCS8PEM(prvKeyHex: HexString): ReturnType; - - public parsePlainPrivatePKCS8Hex(pkcs8PrvHex: HexString): { - algparam: ASN1V | null; - algoid: ASN1V; - keyidx: Idx; - }; - - public getKeyFromPlainPrivatePKCS8PEM(prvKeyHex: HexString): ReturnType; - - public getKeyFromPlainPrivatePKCS8Hex(prvKeyHex: HexString): RSAKey | KJUR.crypto.DSA | KJUR.crypto.ECDSA; - - private _getKeyFromPublicPKCS8Hex(h: HexString): RSAKey | KJUR.crypto.DSA | KJUR.crypto.ECDSA; - - public parsePublicRawRSAKeyHex(pubRawRSAHex: HexString): Record<'n' | 'e', ASN1V>; - - public parsePublicPKCS8Hex(pkcs8PubHex: HexString): { - algparam: ASN1V | Record<'p' | 'q' | 'g', ASN1V> | null; - algoid: ASN1V; - key: ASN1V; - }; - - public static getKey(param: GetKeyRSAParam): RSAKey; - - public static getKey(param: GetKeyECDSAParam): KJUR.crypto.ECDSA; - - public static getKey(param: GetKeyDSAParam): KJUR.crypto.DSA; - - public static getKey(param: string, passcode?: string, hextype?: string): RSAKey | KJUR.crypto.ECDSA | KJUR.crypto.DSA; - - public static generateKeypair(alg: 'RSA', keylen: number): Record<'prvKeyObj' | 'pubKeyObj', RSAKey>; - - public static generateKeypair(alg: 'EC', curve: KJUR.crypto.CurveName): Record<'prvKeyObj' | 'pubKeyObj', KJUR.crypto.ECDSA>; - - public static getPEM(keyObjOrHex: RSAKey | KJUR.crypto.ECDSA | KJUR.crypto.DSA, formatType?: 'PKCS1PRV' | 'PKCS5PRV' | 'PKCS8PRV', passwd?: string, encAlg?: 'DES-CBC' | 'DES-EDE3-CBC' | 'AES-128-CBC' | 'AES-192-CBC' | 'AES-256-CBC', hexType?: string, ivsaltHex?: HexString): object; // To Do - - public static getKeyFromCSRPEM(csrPEM: PEM): RSAKey | KJUR.crypto.ECDSA | KJUR.crypto.DSA; - - public static getKeyFromCSRHex(csrHex: HexString): RSAKey | KJUR.crypto.ECDSA | KJUR.crypto.DSA; - - public static parseCSRHex(csrHex: HexString): Record<'p8pubkeyhex', ASN1TLV>; - - public static getJWKFromKey(keyObj: RSAKey): { - kty: 'RSA'; - } & Record<'n' | 'e' | 'd' | 'p' | 'q' | 'dp' | 'dq' | 'qi', Base64URLString> | { - kty: 'RSA'; - } & Record<'n' | 'e', Base64URLString>; - - public static getJWKFromKey(keyObj: KJUR.crypto.ECDSA): { - kty: 'EC'; - crv: KJUR.crypto.CurveName; - x: Base64URLString; - y: Base64URLString; - d: Base64URLString; - } | { - kty: 'EC'; - crv: KJUR.crypto.CurveName; - x: Base64URLString; - y: Base64URLString; - }; - } - - //// KJUR NAMESPACE (PARTIAL) - - namespace KJUR { - namespace crypto { - type CurveName = 'secp128r1' | 'secp160k1' | 'secp160r1' | 'secp192k1' | 'secp192r1' | 'secp224r1' | 'secp256k1' | 'secp256r1' | 'secp384r1' | 'secp521r1'; - - class DSA { - public p: BigInteger | null; - - public q: BigInteger | null; - - public g: BigInteger | null; - - public y: BigInteger | null; - - public x: BigInteger | null; - - public type: 'DSA'; - - public isPrivate: boolean; - - public isPublic: boolean; - - public setPrivate(p: BigInteger, q: BigInteger, g: BigInteger, y: BigInteger | null, x: BigInteger): void; - - public setPrivateHex(hP: HexString, hQ: HexString, hG: HexString, hY: HexString | null, hX: HexString): void; - - public setPublic(p: BigInteger, q: BigInteger, g: BigInteger, y: BigInteger): void; - - public setPublicHex(hP: HexString, hQ: HexString, hG: HexString, hY: HexString): void; - - public signWithMessageHash(sHashHex: HexString): HexString; - - public verifyWithMessageHash(sHashHex: HexString, hSigVal: HexString): boolean; - - public parseASN1Signature(hSigVal: HexString): [BigInteger, BigInteger]; - - public readPKCS5PrvKeyHex(h: HexString): void; - - public readPKCS8PrvKeyHex(h: HexString): void; - - public readPKCS8PubKeyHex(h: HexString): void; - - public readCertPubKeyHex(h: HexString, nthPKI: number): void; - } - - class ECDSA { - constructor(params?: { - curve?: CurveName; - prv?: HexString; - pub?: HexString; - }); - - public p: BigInteger | null; - - public q: BigInteger | null; - - public g: BigInteger | null; - - public y: BigInteger | null; - - public x: BigInteger | null; - - public type: 'EC'; - - public isPrivate: boolean; - - public isPublic: boolean; - - public getBigRandom(limit: BigInteger): BigInteger; - - public setNamedCurve(curveName: CurveName): void; - - public setPrivateKeyHex(prvKeyHex: HexString): void; - - public setPublicKeyHex(pubKeyHex: HexString): void; - - public getPublicKeyXYHex(): Record<'x' | 'y', HexString>; - - public getShortNISTPCurveName(): 'P-256' | 'P-384' | null; - - public generateKeyPairHex(): Record<'ecprvhex' | 'ecpubhex', HexString>; - - public signWithMessageHash(hashHex: HexString): HexString; - - public signHex(hashHex: HexString, privHex: HexString): HexString; - - public verifyWithMessageHash(sHashHex: HexString, hSigVal: HexString): boolean; - - public parseASN1Signature(hSigVal: HexString): [BigInteger, BigInteger]; - - public readPKCS5PrvKeyHex(h: HexString): void; - - public readPKCS8PrvKeyHex(h: HexString): void; - - public readPKCS8PubKeyHex(h: HexString): void; - - public readCertPubKeyHex(h: HexString, nthPKI: number): void; - - public static parseSigHex(sigHex: HexString): Record<'r' | 's', BigInteger>; - - public static parseSigHexInHexRS(sigHex: HexString): Record<'r' | 's', ASN1V>; - - public static asn1SigToConcatSig(asn1Sig: HexString): HexString; - - public static concatSigToASN1Sig(concatSig: HexString): ASN1TLV; - - public static hexRSSigToASN1Sig(hR: HexString, hS: HexString): ASN1TLV; - - public static biRSSigToASN1Sig(biR: BigInteger, biS: BigInteger): ASN1TLV; - - public static getName(s: CurveName | HexString): 'secp256r1' | 'secp256k1' | 'secp384r1' | null; - } - - class Signature { - constructor(params?: ({ - alg: string; - prov?: string; - } | {}) & ({ - psssaltlen: number; - } | {}) & ({ - prvkeypem: PEM; - prvkeypas?: never; - } | {})); - - private _setAlgNames(): void; - - private _zeroPaddingOfSignature(hex: HexString, bitLength: number): HexString; - - public setAlgAndProvider(alg: string, prov: string): void; - - public init(key: GetKeyParam, pass?: string): void; - - public updateString(str: string): void; - - public updateHex(hex: HexString): void; - - public sign(): HexString; - - public signString(str: string): HexString; - - public signHex(hex: HexString): HexString; - - public verify(hSigVal: string): boolean | 0; - } - } - } - - //// RSAKEY TYPES - - class RSAKey { - public n: BigInteger | null; - - public e: number; - - public d: BigInteger | null; - - public p: BigInteger | null; - - public q: BigInteger | null; - - public dmp1: BigInteger | null; - - public dmq1: BigInteger | null; - - public coeff: BigInteger | null; - - public type: 'RSA'; - - public isPrivate?: boolean; - - public isPublic?: boolean; - - //// RSA PUBLIC - - protected doPublic(x: BigInteger): BigInteger; - - public setPublic(N: BigInteger, E: number): void; - - public setPublic(N: HexString, E: HexString): void; - - public encrypt(text: string): HexString | null; - - public encryptOAEP(text: string, hash?: string | ((s: string) => string), hashLen?: number): HexString | null; - - //// RSA PRIVATE - - protected doPrivate(x: BigInteger): BigInteger; - - public setPrivate(N: BigInteger, E: number, D: BigInteger): void; - - public setPrivate(N: HexString, E: HexString, D: HexString): void; - - public setPrivateEx(N: HexString, E: HexString, D?: HexString | null, P?: HexString | null, Q?: HexString | null, DP?: HexString | null, DQ?: HexString | null, C?: HexString | null): void; - - public generate(B: number, E: HexString): void; - - public decrypt(ctext: HexString): string; - - public decryptOAEP(ctext: HexString, hash?: string | ((s: string) => string), hashLen?: number): string | null; - - //// RSA PEM - - public getPosArrayOfChildrenFromHex(hPrivateKey: PEM): Idx[]; - - public getHexValueArrayOfChildrenFromHex(hPrivateKey: PEM): Idx[]; - - public readPrivateKeyFromPEMString(keyPEM: PEM): void; - - public readPKCS5PrvKeyHex(h: HexString): void; - - public readPKCS8PrvKeyHex(h: HexString): void; - - public readPKCS5PubKeyHex(h: HexString): void; - - public readPKCS8PubKeyHex(h: HexString): void; - - public readCertPubKeyHex(h: HexString, nthPKI: Nth): void; - - //// RSA SIGN - - public sign(s: string, hashAlg: string): HexString; - - public signWithMessageHash(sHashHex: HexString, hashAlg: string): HexString; - - public signPSS(s: string, hashAlg: string, sLen: number): HexString; - - public signWithMessageHashPSS(hHash: HexString, hashAlg: string, sLen: number): HexString; - - public verify(sMsg: string, hSig: HexString): boolean | 0; - - public verifyWithMessageHash(sHashHex: HexString, hSig: HexString): boolean | 0; - - public verifyPSS(sMsg: string, hSig: HexString, hashAlg: string, sLen: number): boolean; - - public verifyWithMessageHashPSS(hHash: HexString, hSig: HexString, hashAlg: string, sLen: number): boolean; - - public static SALT_LEN_HLEN: -1; - - public static SALT_LEN_MAX: -2; - - public static SALT_LEN_RECOVER: -2; - } - - /// RNG TYPES - class SecureRandom { - public nextBytes(ba: Mutable): void; - } - - //// X509 TYPES - - type ExtInfo = { - critical: boolean; - oid: OID; - vidx: Idx; - }; - - type ExtAIAInfo = Record<'ocsp' | 'caissuer', string>; - - type ExtCertificatePolicy = { - id: OIDName; - } & Partial<{ - cps: string; - } | { - unotice: string; - }>; - - class X509 { - public hex: HexString | null; - - public version: number; - - public foffset: number; - - public aExtInfo: null; - - public getVersion(): number; - - public getSerialNumberHex(): ASN1V; - - public getSignatureAlgorithmField(): OIDName; - - public getIssuerHex(): ASN1TLV; - - public getIssuerString(): HexString; - - public getSubjectHex(): ASN1TLV; - - public getSubjectString(): HexString; - - public getNotBefore(): TimeValue; - - public getNotAfter(): TimeValue; - - public getPublicKeyHex(): ASN1TLV; - - public getPublicKeyIdx(): Idx>; - - public getPublicKeyContentIdx(): Idx>; - - public getPublicKey(): RSAKey | KJUR.crypto.ECDSA | KJUR.crypto.DSA; - - public getSignatureAlgorithmName(): OIDName; - - public getSignatureValueHex(): ASN1V; - - public verifySignature(pubKey: GetKeyParam): boolean | 0; - - public parseExt(): void; - - public getExtInfo(oidOrName: OID | string): ExtInfo | undefined; - - public getExtBasicConstraints(): ExtInfo | {} | { - cA: true; - pathLen?: number; - }; - - public getExtKeyUsageBin(): BinString; - - public getExtKeyUsageString(): string; - - public getExtSubjectKeyIdentifier(): ASN1V | undefined; - - public getExtAuthorityKeyIdentifier(): { - kid: ASN1V; - } | undefined; - - public getExtExtKeyUsageName(): OIDName[] | undefined; - - public getExtSubjectAltName(): Deprecated; - - public getExtSubjectAltName2(): ['MAIL' | 'DNS' | 'DN' | 'URI' | 'IP', string][] | undefined; - - public getExtCRLDistributionPointsURI(): string[] | undefined; - - public getExtAIAInfo(): ExtAIAInfo | undefined; - - public getExtCertificatePolicies(): ExtCertificatePolicy[] | undefined; - - public readCertPEM(sCertPEM: PEM): void; - - public readCertHex(sCertHex: HexString): void; - - public getInfo(): string; - - public static hex2dn(hex: HexString, idx?: Idx): string; - - public static hex2rdn(hex: HexString, idx?: Idx): string; - - public static hex2attrTypeValue(hex: HexString, idx?: Idx): string; - - public static getPublicKeyFromCertPEM(sCertPEM: PEM): RSAKey | KJUR.crypto.ECDSA | KJUR.crypto.DSA; - - public static getPublicKeyInfoPropOfCertPEM(sCertPEM: PEM): { - algparam: ASN1V | null; - leyhex: ASN1V; - algoid: ASN1V; - }; - } -} diff --git a/src/@types/ms.d.ts b/src/@types/ms.d.ts deleted file mode 100644 index 2f0156d10..000000000 --- a/src/@types/ms.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -declare module 'ms' { - interface IMSOptions { - long: boolean; - } - - function ms(value: string): number; - function ms(value: number, options?: IMSOptions): string; - - namespace ms {} // Hack - - export = ms; -} diff --git a/src/boot/index.ts b/src/boot/index.ts deleted file mode 100644 index cb4c8536d..000000000 --- a/src/boot/index.ts +++ /dev/null @@ -1,79 +0,0 @@ -import * as cluster from 'cluster'; -import * as chalk from 'chalk'; -import Xev from 'xev'; - -import Logger from '@/services/logger'; -import { envOption } from '../env'; - -// for typeorm -import 'reflect-metadata'; -import { masterMain } from './master'; -import { workerMain } from './worker'; - -const logger = new Logger('core', 'cyan'); -const clusterLogger = logger.createSubLogger('cluster', 'orange', false); -const ev = new Xev(); - -/** - * Init process - */ -export default async function() { - process.title = `Misskey (${cluster.isMaster ? 'master' : 'worker'})`; - - if (cluster.isMaster || envOption.disableClustering) { - await masterMain(); - - if (cluster.isMaster) { - ev.mount(); - } - } - - if (cluster.isWorker || envOption.disableClustering) { - await workerMain(); - } - - // ユニットテスト時にMisskeyが子プロセスで起動された時のため - // それ以外のときは process.send は使えないので弾く - if (process.send) { - process.send('ok'); - } -} - -//#region Events - -// Listen new workers -cluster.on('fork', worker => { - clusterLogger.debug(`Process forked: [${worker.id}]`); -}); - -// Listen online workers -cluster.on('online', worker => { - clusterLogger.debug(`Process is now online: [${worker.id}]`); -}); - -// Listen for dying workers -cluster.on('exit', worker => { - // Replace the dead worker, - // we're not sentimental - clusterLogger.error(chalk.red(`[${worker.id}] died :(`)); - cluster.fork(); -}); - -// Display detail of unhandled promise rejection -if (!envOption.quiet) { - process.on('unhandledRejection', console.dir); -} - -// Display detail of uncaught exception -process.on('uncaughtException', err => { - try { - logger.error(err); - } catch { } -}); - -// Dying away... -process.on('exit', code => { - logger.info(`The process is going to exit with code ${code}`); -}); - -//#endregion diff --git a/src/boot/master.ts b/src/boot/master.ts deleted file mode 100644 index 071b37b76..000000000 --- a/src/boot/master.ts +++ /dev/null @@ -1,194 +0,0 @@ -import * as fs from 'fs'; -import { fileURLToPath } from 'url'; -import { dirname } from 'path'; -import * as os from 'os'; -import * as cluster from 'cluster'; -import * as chalk from 'chalk'; -import * as portscanner from 'portscanner'; -import { getConnection } from 'typeorm'; - -import Logger from '@/services/logger'; -import loadConfig from '@/config/load'; -import { Config } from '@/config/types'; -import { lessThan } from '@/prelude/array'; -import { envOption } from '../env'; -import { showMachineInfo } from '@/misc/show-machine-info'; -import { initDb } from '../db/postgre'; - -//const _filename = fileURLToPath(import.meta.url); -const _filename = __filename; -const _dirname = dirname(_filename); - -const meta = JSON.parse(fs.readFileSync(`${_dirname}/../meta.json`, 'utf-8')); - -const logger = new Logger('core', 'cyan'); -const bootLogger = logger.createSubLogger('boot', 'magenta', false); - -function greet() { - if (!envOption.quiet) { - //#region Misskey logo - const v = `v${meta.version}`; - console.log(' _____ _ _ '); - console.log(' | |_|___ ___| |_ ___ _ _ '); - console.log(' | | | | |_ -|_ -| \'_| -_| | |'); - console.log(' |_|_|_|_|___|___|_,_|___|_ |'); - console.log(' ' + chalk.gray(v) + (' |___|\n'.substr(v.length))); - //#endregion - - console.log(' Misskey is an open-source decentralized microblogging platform.'); - console.log(chalk.keyword('orange')(' If you like Misskey, please donate to support development. https://www.patreon.com/syuilo')); - - console.log(''); - console.log(chalk`--- ${os.hostname()} {gray (PID: ${process.pid.toString()})} ---`); - } - - bootLogger.info('Welcome to Misskey!'); - bootLogger.info(`Misskey v${meta.version}`, null, true); -} - -function isRoot() { - // maybe process.getuid will be undefined under not POSIX environment (e.g. Windows) - return process.getuid != null && process.getuid() === 0; -} - -/** - * Init master process - */ -export async function masterMain() { - let config!: Config; - - // initialize app - try { - greet(); - showEnvironment(); - await showMachineInfo(bootLogger); - showNodejsVersion(); - config = loadConfigBoot(); - await connectDb(); - await validatePort(config); - } catch (e) { - bootLogger.error('Fatal error occurred during initialization', null, true); - process.exit(1); - } - - bootLogger.succ('Misskey initialized'); - - if (!envOption.disableClustering) { - await spawnWorkers(config.clusterLimit); - } - - bootLogger.succ(`Now listening on port ${config.port} on ${config.url}`, null, true); - - if (!envOption.noDaemons) { - require('../daemons/server-stats').default(); - require('../daemons/queue-stats').default(); - require('../daemons/janitor').default(); - } -} - -const runningNodejsVersion = process.version.slice(1).split('.').map(x => parseInt(x, 10)); -const requiredNodejsVersion = [11, 7, 0]; -const satisfyNodejsVersion = !lessThan(runningNodejsVersion, requiredNodejsVersion); - -function showEnvironment(): void { - const env = process.env.NODE_ENV; - const logger = bootLogger.createSubLogger('env'); - logger.info(typeof env === 'undefined' ? 'NODE_ENV is not set' : `NODE_ENV: ${env}`); - - if (env !== 'production') { - logger.warn('The environment is not in production mode.'); - logger.warn('DO NOT USE FOR PRODUCTION PURPOSE!', null, true); - } - - logger.info(`You ${isRoot() ? '' : 'do not '}have root privileges`); -} - -function showNodejsVersion(): void { - const nodejsLogger = bootLogger.createSubLogger('nodejs'); - - nodejsLogger.info(`Version ${runningNodejsVersion.join('.')}`); - - if (!satisfyNodejsVersion) { - nodejsLogger.error(`Node.js version is less than ${requiredNodejsVersion.join('.')}. Please upgrade it.`, null, true); - process.exit(1); - } -} - -function loadConfigBoot(): Config { - const configLogger = bootLogger.createSubLogger('config'); - let config; - - try { - config = loadConfig(); - } catch (exception) { - if (typeof exception === 'string') { - configLogger.error(exception); - process.exit(1); - } - if (exception.code === 'ENOENT') { - configLogger.error('Configuration file not found', null, true); - process.exit(1); - } - throw exception; - } - - configLogger.succ('Loaded'); - - return config; -} - -async function connectDb(): Promise { - const dbLogger = bootLogger.createSubLogger('db'); - - // Try to connect to DB - try { - dbLogger.info('Connecting...'); - await initDb(); - const v = await getConnection().query('SHOW server_version').then(x => x[0].server_version); - dbLogger.succ(`Connected: v${v}`); - } catch (e) { - dbLogger.error('Cannot connect', null, true); - dbLogger.error(e); - process.exit(1); - } -} - -async function validatePort(config: Config): Promise { - const isWellKnownPort = (port: number) => port < 1024; - - async function isPortAvailable(port: number): Promise { - return await portscanner.checkPortStatus(port, '127.0.0.1') === 'closed'; - } - - if (config.port == null || Number.isNaN(config.port)) { - bootLogger.error('The port is not configured. Please configure port.', null, true); - process.exit(1); - } - - if (process.platform === 'linux' && isWellKnownPort(config.port) && !isRoot()) { - bootLogger.error('You need root privileges to listen on well-known port on Linux', null, true); - process.exit(1); - } - - if (!await isPortAvailable(config.port)) { - bootLogger.error(`Port ${config.port} is already in use`, null, true); - process.exit(1); - } -} - -async function spawnWorkers(limit: number = 1) { - const workers = Math.min(limit, os.cpus().length); - bootLogger.info(`Starting ${workers} worker${workers === 1 ? '' : 's'}...`); - await Promise.all([...Array(workers)].map(spawnWorker)); - bootLogger.succ('All workers started'); -} - -function spawnWorker(): Promise { - return new Promise(res => { - const worker = cluster.fork(); - worker.on('message', message => { - if (message !== 'ready') return; - res(); - }); - }); -} diff --git a/src/client/.eslintrc b/src/client/.eslintrc deleted file mode 100644 index fffa28d9e..000000000 --- a/src/client/.eslintrc +++ /dev/null @@ -1,32 +0,0 @@ -{ - "env": { - "node": false, - }, - "extends": [ - "eslint:recommended", - "plugin:vue/recommended" - ], - "rules": { - "vue/require-v-for-key": 0, - "vue/max-attributes-per-line": 0, - "vue/html-indent": 0, - "vue/html-self-closing": 0, - "vue/no-unused-vars": 0, - "vue/attributes-order": 0, - "vue/require-prop-types": 0, - "vue/require-default-prop": 0, - "vue/html-closing-bracket-spacing": 0, - "vue/singleline-html-element-content-newline": 0, - "vue/no-v-html": 0 - }, - "globals": { - "_DEV_": false, - "_LANGS_": false, - "_VERSION_": false, - "_ENV_": false, - "_PERF_PREFIX_": false, - "_DATA_TRANSFER_DRIVE_FILE_": false, - "_DATA_TRANSFER_DRIVE_FOLDER_": false, - "_DATA_TRANSFER_DECK_COLUMN_": false - } -} diff --git a/src/client/@types/global.d.ts b/src/client/@types/global.d.ts deleted file mode 100644 index 84dde63b2..000000000 --- a/src/client/@types/global.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -declare const _LANGS_: string[][]; -declare const _VERSION_: string; -declare const _ENV_: string; -declare const _DEV_: boolean; -declare const _PERF_PREFIX_: string; -declare const _DATA_TRANSFER_DRIVE_FILE_: string; -declare const _DATA_TRANSFER_DRIVE_FOLDER_: string; -declare const _DATA_TRANSFER_DECK_COLUMN_: string; diff --git a/src/client/account.ts b/src/client/account.ts deleted file mode 100644 index a3fe082a2..000000000 --- a/src/client/account.ts +++ /dev/null @@ -1,209 +0,0 @@ -import { del, get, set } from '@client/scripts/idb-proxy'; -import { reactive } from 'vue'; -import { apiUrl } from '@client/config'; -import { waiting, api, popup, popupMenu, success } from '@client/os'; -import { unisonReload, reloadChannel } from '@client/scripts/unison-reload'; -import { showSuspendedDialog } from './scripts/show-suspended-dialog'; -import { i18n } from './i18n'; - -// TODO: 他のタブと永続化されたstateを同期 - -type Account = { - id: string; - token: string; - isModerator: boolean; - isAdmin: boolean; - isDeleted: boolean; -}; - -const data = localStorage.getItem('account'); - -// TODO: 外部からはreadonlyに -export const $i = data ? reactive(JSON.parse(data) as Account) : null; - -export async function signout() { - waiting(); - localStorage.removeItem('account'); - - //#region Remove account - const accounts = await getAccounts(); - accounts.splice(accounts.findIndex(x => x.id === $i.id), 1); - - if (accounts.length > 0) await set('accounts', accounts); - else await del('accounts'); - //#endregion - - //#region Remove service worker registration - try { - if (navigator.serviceWorker.controller) { - const registration = await navigator.serviceWorker.ready; - const push = await registration.pushManager.getSubscription(); - if (push) { - await fetch(`${apiUrl}/sw/unregister`, { - method: 'POST', - body: JSON.stringify({ - i: $i.token, - endpoint: push.endpoint, - }), - }); - } - } - - if (accounts.length === 0) { - await navigator.serviceWorker.getRegistrations() - .then(registrations => { - return Promise.all(registrations.map(registration => registration.unregister())); - }); - } - } catch (e) {} - //#endregion - - document.cookie = `igi=; path=/`; - - if (accounts.length > 0) login(accounts[0].token); - else unisonReload(); -} - -export async function getAccounts(): Promise<{ id: Account['id'], token: Account['token'] }[]> { - return (await get('accounts')) || []; -} - -export async function addAccount(id: Account['id'], token: Account['token']) { - const accounts = await getAccounts(); - if (!accounts.some(x => x.id === id)) { - await set('accounts', accounts.concat([{ id, token }])); - } -} - -function fetchAccount(token): Promise { - return new Promise((done, fail) => { - // Fetch user - fetch(`${apiUrl}/i`, { - method: 'POST', - body: JSON.stringify({ - i: token - }) - }) - .then(res => res.json()) - .then(res => { - if (res.error) { - if (res.error.id === 'a8c724b3-6e9c-4b46-b1a8-bc3ed6258370') { - showSuspendedDialog().then(() => { - signout(); - }); - } else { - signout(); - } - } else { - res.token = token; - done(res); - } - }) - .catch(fail); - }); -} - -export function updateAccount(data) { - for (const [key, value] of Object.entries(data)) { - $i[key] = value; - } - localStorage.setItem('account', JSON.stringify($i)); -} - -export function refreshAccount() { - return fetchAccount($i.token).then(updateAccount); -} - -export async function login(token: Account['token'], redirect?: string) { - waiting(); - if (_DEV_) console.log('logging as token ', token); - const me = await fetchAccount(token); - localStorage.setItem('account', JSON.stringify(me)); - await addAccount(me.id, token); - - if (redirect) { - reloadChannel.postMessage('reload'); - location.href = redirect; - return; - } - - unisonReload(); -} - -export async function openAccountMenu(ev: MouseEvent) { - function showSigninDialog() { - popup(import('@client/components/signin-dialog.vue'), {}, { - done: res => { - addAccount(res.id, res.i); - success(); - }, - }, 'closed'); - } - - function createAccount() { - popup(import('@client/components/signup-dialog.vue'), {}, { - done: res => { - addAccount(res.id, res.i); - switchAccountWithToken(res.i); - }, - }, 'closed'); - } - - async function switchAccount(account: any) { - const storedAccounts = await getAccounts(); - const token = storedAccounts.find(x => x.id === account.id).token; - switchAccountWithToken(token); - } - - function switchAccountWithToken(token: string) { - login(token); - } - - const storedAccounts = await getAccounts().then(accounts => accounts.filter(x => x.id !== $i.id)); - const accountsPromise = api('users/show', { userIds: storedAccounts.map(x => x.id) }); - - const accountItemPromises = storedAccounts.map(a => new Promise(res => { - accountsPromise.then(accounts => { - const account = accounts.find(x => x.id === a.id); - if (account == null) return res(null); - res({ - type: 'user', - user: account, - action: () => { switchAccount(account); } - }); - }); - })); - - popupMenu([...[{ - type: 'link', - text: i18n.locale.profile, - to: `/@${ $i.username }`, - avatar: $i, - }, null, ...accountItemPromises, { - icon: 'fas fa-plus', - text: i18n.locale.addAccount, - action: () => { - popupMenu([{ - text: i18n.locale.existingAccount, - action: () => { showSigninDialog(); }, - }, { - text: i18n.locale.createAccount, - action: () => { createAccount(); }, - }], ev.currentTarget || ev.target); - }, - }, { - type: 'link', - icon: 'fas fa-users', - text: i18n.locale.manageAccounts, - to: `/settings/accounts`, - }]], ev.currentTarget || ev.target, { - align: 'left' - }); -} - -// このファイルに書きたくないけどここに書かないと何故かVeturが認識しない -declare module '@vue/runtime-core' { - interface ComponentCustomProperties { - $i: typeof $i; - } -} diff --git a/src/client/components/abuse-report-window.vue b/src/client/components/abuse-report-window.vue deleted file mode 100644 index 21a19385a..000000000 --- a/src/client/components/abuse-report-window.vue +++ /dev/null @@ -1,79 +0,0 @@ - - - - - diff --git a/src/client/components/autocomplete.vue b/src/client/components/autocomplete.vue deleted file mode 100644 index e621b2622..000000000 --- a/src/client/components/autocomplete.vue +++ /dev/null @@ -1,502 +0,0 @@ - - - - - diff --git a/src/client/components/avatars.vue b/src/client/components/avatars.vue deleted file mode 100644 index da862967d..000000000 --- a/src/client/components/avatars.vue +++ /dev/null @@ -1,30 +0,0 @@ - - - diff --git a/src/client/components/channel-follow-button.vue b/src/client/components/channel-follow-button.vue deleted file mode 100644 index bd8627f6e..000000000 --- a/src/client/components/channel-follow-button.vue +++ /dev/null @@ -1,140 +0,0 @@ - - - - - diff --git a/src/client/components/chart.vue b/src/client/components/chart.vue deleted file mode 100644 index ae9a5e79b..000000000 --- a/src/client/components/chart.vue +++ /dev/null @@ -1,691 +0,0 @@ - - - - - diff --git a/src/client/components/cw-button.vue b/src/client/components/cw-button.vue deleted file mode 100644 index 3a172f5d5..000000000 --- a/src/client/components/cw-button.vue +++ /dev/null @@ -1,70 +0,0 @@ - - - - - diff --git a/src/client/components/date-separated-list.vue b/src/client/components/date-separated-list.vue deleted file mode 100644 index fa0b6d669..000000000 --- a/src/client/components/date-separated-list.vue +++ /dev/null @@ -1,188 +0,0 @@ - - - diff --git a/src/client/components/debobigego/pagination.vue b/src/client/components/debobigego/pagination.vue deleted file mode 100644 index 2166f5065..000000000 --- a/src/client/components/debobigego/pagination.vue +++ /dev/null @@ -1,42 +0,0 @@ - - - - - diff --git a/src/client/components/debobigego/radios.vue b/src/client/components/debobigego/radios.vue deleted file mode 100644 index 071c013af..000000000 --- a/src/client/components/debobigego/radios.vue +++ /dev/null @@ -1,112 +0,0 @@ - - - diff --git a/src/client/components/debobigego/suspense.vue b/src/client/components/debobigego/suspense.vue deleted file mode 100644 index e59e0ba12..000000000 --- a/src/client/components/debobigego/suspense.vue +++ /dev/null @@ -1,101 +0,0 @@ - - - - - diff --git a/src/client/components/dialog.vue b/src/client/components/dialog.vue deleted file mode 100644 index dd4932f61..000000000 --- a/src/client/components/dialog.vue +++ /dev/null @@ -1,212 +0,0 @@ - - - - - diff --git a/src/client/components/drive-file-thumbnail.vue b/src/client/components/drive-file-thumbnail.vue deleted file mode 100644 index 2cb1d9861..000000000 --- a/src/client/components/drive-file-thumbnail.vue +++ /dev/null @@ -1,108 +0,0 @@ - - - - - diff --git a/src/client/components/drive-select-dialog.vue b/src/client/components/drive-select-dialog.vue deleted file mode 100644 index ce6e2fa78..000000000 --- a/src/client/components/drive-select-dialog.vue +++ /dev/null @@ -1,70 +0,0 @@ - - - diff --git a/src/client/components/drive-window.vue b/src/client/components/drive-window.vue deleted file mode 100644 index 30b04091b..000000000 --- a/src/client/components/drive-window.vue +++ /dev/null @@ -1,44 +0,0 @@ - - - diff --git a/src/client/components/drive.file.vue b/src/client/components/drive.file.vue deleted file mode 100644 index b1be3d0ca..000000000 --- a/src/client/components/drive.file.vue +++ /dev/null @@ -1,374 +0,0 @@ - - - - - diff --git a/src/client/components/drive.folder.vue b/src/client/components/drive.folder.vue deleted file mode 100644 index 4c09e7775..000000000 --- a/src/client/components/drive.folder.vue +++ /dev/null @@ -1,326 +0,0 @@ - - - - - diff --git a/src/client/components/drive.nav-folder.vue b/src/client/components/drive.nav-folder.vue deleted file mode 100644 index 913a1b5f9..000000000 --- a/src/client/components/drive.nav-folder.vue +++ /dev/null @@ -1,135 +0,0 @@ - - - - - diff --git a/src/client/components/drive.vue b/src/client/components/drive.vue deleted file mode 100644 index 5dadf9a11..000000000 --- a/src/client/components/drive.vue +++ /dev/null @@ -1,784 +0,0 @@ - - - - - diff --git a/src/client/components/emoji-picker-dialog.vue b/src/client/components/emoji-picker-dialog.vue deleted file mode 100644 index aa17b8b25..000000000 --- a/src/client/components/emoji-picker-dialog.vue +++ /dev/null @@ -1,76 +0,0 @@ - - - - - diff --git a/src/client/components/emoji-picker-window.vue b/src/client/components/emoji-picker-window.vue deleted file mode 100644 index b7b884565..000000000 --- a/src/client/components/emoji-picker-window.vue +++ /dev/null @@ -1,197 +0,0 @@ - - - - - diff --git a/src/client/components/emoji-picker.section.vue b/src/client/components/emoji-picker.section.vue deleted file mode 100644 index 0ea376142..000000000 --- a/src/client/components/emoji-picker.section.vue +++ /dev/null @@ -1,50 +0,0 @@ - - - - - diff --git a/src/client/components/emoji-picker.vue b/src/client/components/emoji-picker.vue deleted file mode 100644 index 85a12a08e..000000000 --- a/src/client/components/emoji-picker.vue +++ /dev/null @@ -1,501 +0,0 @@ - - - - - diff --git a/src/client/components/featured-photos.vue b/src/client/components/featured-photos.vue deleted file mode 100644 index c992a5d1f..000000000 --- a/src/client/components/featured-photos.vue +++ /dev/null @@ -1,32 +0,0 @@ - - - - - diff --git a/src/client/components/file-type-icon.vue b/src/client/components/file-type-icon.vue deleted file mode 100644 index 95200b98c..000000000 --- a/src/client/components/file-type-icon.vue +++ /dev/null @@ -1,28 +0,0 @@ - - - diff --git a/src/client/components/follow-button.vue b/src/client/components/follow-button.vue deleted file mode 100644 index 5eba9b1f6..000000000 --- a/src/client/components/follow-button.vue +++ /dev/null @@ -1,210 +0,0 @@ - - - - - diff --git a/src/client/components/forgot-password.vue b/src/client/components/forgot-password.vue deleted file mode 100644 index 7fcf9aa72..000000000 --- a/src/client/components/forgot-password.vue +++ /dev/null @@ -1,84 +0,0 @@ - - - - - diff --git a/src/client/components/form-dialog.vue b/src/client/components/form-dialog.vue deleted file mode 100644 index 6353b7287..000000000 --- a/src/client/components/form-dialog.vue +++ /dev/null @@ -1,125 +0,0 @@ - - - - - diff --git a/src/client/components/form/input.vue b/src/client/components/form/input.vue deleted file mode 100644 index 591eda9ed..000000000 --- a/src/client/components/form/input.vue +++ /dev/null @@ -1,315 +0,0 @@ - - - - - diff --git a/src/client/components/form/select.vue b/src/client/components/form/select.vue deleted file mode 100644 index 363b3515f..000000000 --- a/src/client/components/form/select.vue +++ /dev/null @@ -1,312 +0,0 @@ - - - - - diff --git a/src/client/components/form/textarea.vue b/src/client/components/form/textarea.vue deleted file mode 100644 index 048e9032d..000000000 --- a/src/client/components/form/textarea.vue +++ /dev/null @@ -1,252 +0,0 @@ - - - - - diff --git a/src/client/components/formula-core.vue b/src/client/components/formula-core.vue deleted file mode 100644 index 6e35295ff..000000000 --- a/src/client/components/formula-core.vue +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - diff --git a/src/client/components/formula.vue b/src/client/components/formula.vue deleted file mode 100644 index 6722ce38a..000000000 --- a/src/client/components/formula.vue +++ /dev/null @@ -1,23 +0,0 @@ - - - diff --git a/src/client/components/gallery-post-preview.vue b/src/client/components/gallery-post-preview.vue deleted file mode 100644 index 5c3bdb134..000000000 --- a/src/client/components/gallery-post-preview.vue +++ /dev/null @@ -1,126 +0,0 @@ - - - - - diff --git a/src/client/components/global/a.vue b/src/client/components/global/a.vue deleted file mode 100644 index 952dfb184..000000000 --- a/src/client/components/global/a.vue +++ /dev/null @@ -1,138 +0,0 @@ - - - diff --git a/src/client/components/global/acct.vue b/src/client/components/global/acct.vue deleted file mode 100644 index 70f2954cb..000000000 --- a/src/client/components/global/acct.vue +++ /dev/null @@ -1,38 +0,0 @@ - - - - - diff --git a/src/client/components/global/ad.vue b/src/client/components/global/ad.vue deleted file mode 100644 index 8397b2229..000000000 --- a/src/client/components/global/ad.vue +++ /dev/null @@ -1,200 +0,0 @@ - - - - - diff --git a/src/client/components/global/avatar.vue b/src/client/components/global/avatar.vue deleted file mode 100644 index 395ed5d8c..000000000 --- a/src/client/components/global/avatar.vue +++ /dev/null @@ -1,163 +0,0 @@ - - - - - diff --git a/src/client/components/global/emoji.vue b/src/client/components/global/emoji.vue deleted file mode 100644 index f92e35c38..000000000 --- a/src/client/components/global/emoji.vue +++ /dev/null @@ -1,125 +0,0 @@ - - - - - diff --git a/src/client/components/global/error.vue b/src/client/components/global/error.vue deleted file mode 100644 index 05a508a65..000000000 --- a/src/client/components/global/error.vue +++ /dev/null @@ -1,46 +0,0 @@ - - - - - diff --git a/src/client/components/global/header.vue b/src/client/components/global/header.vue deleted file mode 100644 index 526db07fd..000000000 --- a/src/client/components/global/header.vue +++ /dev/null @@ -1,360 +0,0 @@ - - - - - diff --git a/src/client/components/global/misskey-flavored-markdown.vue b/src/client/components/global/misskey-flavored-markdown.vue deleted file mode 100644 index c4f75bee9..000000000 --- a/src/client/components/global/misskey-flavored-markdown.vue +++ /dev/null @@ -1,157 +0,0 @@ - - - - - - - diff --git a/src/client/components/global/url.vue b/src/client/components/global/url.vue deleted file mode 100644 index 218729882..000000000 --- a/src/client/components/global/url.vue +++ /dev/null @@ -1,142 +0,0 @@ - - - - - diff --git a/src/client/components/google.vue b/src/client/components/google.vue deleted file mode 100644 index be724f038..000000000 --- a/src/client/components/google.vue +++ /dev/null @@ -1,64 +0,0 @@ - - - - - diff --git a/src/client/components/image-viewer.vue b/src/client/components/image-viewer.vue deleted file mode 100644 index 7701ae926..000000000 --- a/src/client/components/image-viewer.vue +++ /dev/null @@ -1,85 +0,0 @@ - - - - - diff --git a/src/client/components/index.ts b/src/client/components/index.ts deleted file mode 100644 index 2340b228f..000000000 --- a/src/client/components/index.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { App } from 'vue'; - -import mfm from './global/misskey-flavored-markdown.vue'; -import a from './global/a.vue'; -import acct from './global/acct.vue'; -import avatar from './global/avatar.vue'; -import emoji from './global/emoji.vue'; -import userName from './global/user-name.vue'; -import ellipsis from './global/ellipsis.vue'; -import time from './global/time.vue'; -import url from './global/url.vue'; -import i18n from './global/i18n'; -import loading from './global/loading.vue'; -import error from './global/error.vue'; -import ad from './global/ad.vue'; -import header from './global/header.vue'; -import spacer from './global/spacer.vue'; -import stickyContainer from './global/sticky-container.vue'; - -export default function(app: App) { - app.component('I18n', i18n); - app.component('Mfm', mfm); - app.component('MkA', a); - app.component('MkAcct', acct); - app.component('MkAvatar', avatar); - app.component('MkEmoji', emoji); - app.component('MkUserName', userName); - app.component('MkEllipsis', ellipsis); - app.component('MkTime', time); - app.component('MkUrl', url); - app.component('MkLoading', loading); - app.component('MkError', error); - app.component('MkAd', ad); - app.component('MkHeader', header); - app.component('MkSpacer', spacer); - app.component('MkStickyContainer', stickyContainer); -} diff --git a/src/client/components/instance-stats.vue b/src/client/components/instance-stats.vue deleted file mode 100644 index fd0b75609..000000000 --- a/src/client/components/instance-stats.vue +++ /dev/null @@ -1,80 +0,0 @@ - - - - - diff --git a/src/client/components/instance-ticker.vue b/src/client/components/instance-ticker.vue deleted file mode 100644 index 567417455..000000000 --- a/src/client/components/instance-ticker.vue +++ /dev/null @@ -1,62 +0,0 @@ - - - - - diff --git a/src/client/components/launch-pad.vue b/src/client/components/launch-pad.vue deleted file mode 100644 index 6f97d4d3a..000000000 --- a/src/client/components/launch-pad.vue +++ /dev/null @@ -1,152 +0,0 @@ - - - - - diff --git a/src/client/components/link.vue b/src/client/components/link.vue deleted file mode 100644 index a88741033..000000000 --- a/src/client/components/link.vue +++ /dev/null @@ -1,92 +0,0 @@ - - - - - diff --git a/src/client/components/media-banner.vue b/src/client/components/media-banner.vue deleted file mode 100644 index 34065557b..000000000 --- a/src/client/components/media-banner.vue +++ /dev/null @@ -1,107 +0,0 @@ - - - - - diff --git a/src/client/components/media-caption.vue b/src/client/components/media-caption.vue deleted file mode 100644 index b35b101d0..000000000 --- a/src/client/components/media-caption.vue +++ /dev/null @@ -1,260 +0,0 @@ - - - - - diff --git a/src/client/components/media-image.vue b/src/client/components/media-image.vue deleted file mode 100644 index fd5e0b5f9..000000000 --- a/src/client/components/media-image.vue +++ /dev/null @@ -1,155 +0,0 @@ - - - - - diff --git a/src/client/components/media-list.vue b/src/client/components/media-list.vue deleted file mode 100644 index c499525d8..000000000 --- a/src/client/components/media-list.vue +++ /dev/null @@ -1,167 +0,0 @@ - - - - - diff --git a/src/client/components/media-video.vue b/src/client/components/media-video.vue deleted file mode 100644 index 4d4a55165..000000000 --- a/src/client/components/media-video.vue +++ /dev/null @@ -1,97 +0,0 @@ - - - - - diff --git a/src/client/components/mention.vue b/src/client/components/mention.vue deleted file mode 100644 index da13dcddd..000000000 --- a/src/client/components/mention.vue +++ /dev/null @@ -1,86 +0,0 @@ - - - - - diff --git a/src/client/components/mfm.ts b/src/client/components/mfm.ts deleted file mode 100644 index f3411cadc..000000000 --- a/src/client/components/mfm.ts +++ /dev/null @@ -1,320 +0,0 @@ -import { VNode, defineComponent, h } from 'vue'; -import * as mfm from 'mfm-js'; -import MkUrl from '@client/components/global/url.vue'; -import MkLink from '@client/components/link.vue'; -import MkMention from '@client/components/mention.vue'; -import MkEmoji from '@client/components/global/emoji.vue'; -import { concat } from '@client/../prelude/array'; -import MkFormula from '@client/components/formula.vue'; -import MkCode from '@client/components/code.vue'; -import MkGoogle from '@client/components/google.vue'; -import MkSparkle from '@client/components/sparkle.vue'; -import MkA from '@client/components/global/a.vue'; -import { host } from '@client/config'; - -export default defineComponent({ - props: { - text: { - type: String, - required: true - }, - plain: { - type: Boolean, - default: false - }, - nowrap: { - type: Boolean, - default: false - }, - author: { - type: Object, - default: null - }, - i: { - type: Object, - default: null - }, - customEmojis: { - required: false, - }, - isNote: { - type: Boolean, - default: true - }, - }, - - render() { - if (this.text == null || this.text == '') return; - - const ast = (this.plain ? mfm.parsePlain : mfm.parse)(this.text); - - const validTime = (t: string | null | undefined) => { - if (t == null) return null; - return t.match(/^[0-9.]+s$/) ? t : null; - }; - - const genEl = (ast: mfm.MfmNode[]) => concat(ast.map((token): VNode[] => { - switch (token.type) { - case 'text': { - const text = token.props.text.replace(/(\r\n|\n|\r)/g, '\n'); - - if (!this.plain) { - const res = []; - for (const t of text.split('\n')) { - res.push(h('br')); - res.push(t); - } - res.shift(); - return res; - } else { - return [text.replace(/\n/g, ' ')]; - } - } - - case 'bold': { - return [h('b', genEl(token.children))]; - } - - case 'strike': { - return [h('del', genEl(token.children))]; - } - - case 'italic': { - return h('i', { - style: 'font-style: oblique;' - }, genEl(token.children)); - } - - case 'fn': { - // TODO: CSSを文字列で組み立てていくと token.props.args.~~~ 経由でCSSインジェクションできるのでよしなにやる - let style; - switch (token.props.name) { - case 'tada': { - style = `font-size: 150%;` + (this.$store.state.animatedMfm ? 'animation: tada 1s linear infinite both;' : ''); - break; - } - case 'jelly': { - const speed = validTime(token.props.args.speed) || '1s'; - style = (this.$store.state.animatedMfm ? `animation: mfm-rubberBand ${speed} linear infinite both;` : ''); - break; - } - case 'twitch': { - const speed = validTime(token.props.args.speed) || '0.5s'; - style = this.$store.state.animatedMfm ? `animation: mfm-twitch ${speed} ease infinite;` : ''; - break; - } - case 'shake': { - const speed = validTime(token.props.args.speed) || '0.5s'; - style = this.$store.state.animatedMfm ? `animation: mfm-shake ${speed} ease infinite;` : ''; - break; - } - case 'spin': { - const direction = - token.props.args.left ? 'reverse' : - token.props.args.alternate ? 'alternate' : - 'normal'; - const anime = - token.props.args.x ? 'mfm-spinX' : - token.props.args.y ? 'mfm-spinY' : - 'mfm-spin'; - const speed = validTime(token.props.args.speed) || '1.5s'; - style = this.$store.state.animatedMfm ? `animation: ${anime} ${speed} linear infinite; animation-direction: ${direction};` : ''; - break; - } - case 'jump': { - style = this.$store.state.animatedMfm ? 'animation: mfm-jump 0.75s linear infinite;' : ''; - break; - } - case 'bounce': { - style = this.$store.state.animatedMfm ? 'animation: mfm-bounce 0.75s linear infinite; transform-origin: center bottom;' : ''; - break; - } - case 'flip': { - const transform = - (token.props.args.h && token.props.args.v) ? 'scale(-1, -1)' : - token.props.args.v ? 'scaleY(-1)' : - 'scaleX(-1)'; - style = `transform: ${transform};`; - break; - } - case 'x2': { - style = `font-size: 200%;`; - break; - } - case 'x3': { - style = `font-size: 400%;`; - break; - } - case 'x4': { - style = `font-size: 600%;`; - break; - } - case 'font': { - const family = - token.props.args.serif ? 'serif' : - token.props.args.monospace ? 'monospace' : - token.props.args.cursive ? 'cursive' : - token.props.args.fantasy ? 'fantasy' : - token.props.args.emoji ? 'emoji' : - token.props.args.math ? 'math' : - null; - if (family) style = `font-family: ${family};`; - break; - } - case 'blur': { - return h('span', { - class: '_mfm_blur_', - }, genEl(token.children)); - } - case 'rainbow': { - style = this.$store.state.animatedMfm ? 'animation: mfm-rainbow 1s linear infinite;' : ''; - break; - } - case 'sparkle': { - if (!this.$store.state.animatedMfm) { - return genEl(token.children); - } - let count = token.props.args.count ? parseInt(token.props.args.count) : 10; - if (count > 100) { - count = 100; - } - const speed = token.props.args.speed ? parseFloat(token.props.args.speed) : 1; - return h(MkSparkle, { - count, speed, - }, genEl(token.children)); - } - } - if (style == null) { - return h('span', {}, ['$[', token.props.name, ' ', ...genEl(token.children), ']']); - } else { - return h('span', { - style: 'display: inline-block;' + style, - }, genEl(token.children)); - } - } - - case 'small': { - return [h('small', { - style: 'opacity: 0.7;' - }, genEl(token.children))]; - } - - case 'center': { - return [h('div', { - style: 'text-align:center;' - }, genEl(token.children))]; - } - - case 'url': { - return [h(MkUrl, { - key: Math.random(), - url: token.props.url, - rel: 'nofollow noopener', - })]; - } - - case 'link': { - return [h(MkLink, { - key: Math.random(), - url: token.props.url, - rel: 'nofollow noopener', - }, genEl(token.children))]; - } - - case 'mention': { - return [h(MkMention, { - key: Math.random(), - host: (token.props.host == null && this.author && this.author.host != null ? this.author.host : token.props.host) || host, - username: token.props.username - })]; - } - - case 'hashtag': { - return [h(MkA, { - key: Math.random(), - to: this.isNote ? `/tags/${encodeURIComponent(token.props.hashtag)}` : `/explore/tags/${encodeURIComponent(token.props.hashtag)}`, - style: 'color:var(--hashtag);' - }, `#${token.props.hashtag}`)]; - } - - case 'blockCode': { - return [h(MkCode, { - key: Math.random(), - code: token.props.code, - lang: token.props.lang, - })]; - } - - case 'inlineCode': { - return [h(MkCode, { - key: Math.random(), - code: token.props.code, - inline: true - })]; - } - - case 'quote': { - if (!this.nowrap) { - return [h('div', { - class: 'quote' - }, genEl(token.children))]; - } else { - return [h('span', { - class: 'quote' - }, genEl(token.children))]; - } - } - - case 'emojiCode': { - return [h(MkEmoji, { - key: Math.random(), - emoji: `:${token.props.name}:`, - customEmojis: this.customEmojis, - normal: this.plain - })]; - } - - case 'unicodeEmoji': { - return [h(MkEmoji, { - key: Math.random(), - emoji: token.props.emoji, - customEmojis: this.customEmojis, - normal: this.plain - })]; - } - - case 'mathInline': { - return [h(MkFormula, { - key: Math.random(), - formula: token.props.formula, - block: false - })]; - } - - case 'mathBlock': { - return [h(MkFormula, { - key: Math.random(), - formula: token.props.formula, - block: true - })]; - } - - case 'search': { - return [h(MkGoogle, { - key: Math.random(), - q: token.props.query - })]; - } - - default: { - console.error('unrecognized ast type:', token.type); - - return []; - } - } - })); - - // Parse ast to DOM - return h('span', genEl(ast)); - } -}); diff --git a/src/client/components/mini-chart.vue b/src/client/components/mini-chart.vue deleted file mode 100644 index 0d01e4e4b..000000000 --- a/src/client/components/mini-chart.vue +++ /dev/null @@ -1,90 +0,0 @@ - - - diff --git a/src/client/components/modal-page-window.vue b/src/client/components/modal-page-window.vue deleted file mode 100644 index e47d3dc62..000000000 --- a/src/client/components/modal-page-window.vue +++ /dev/null @@ -1,223 +0,0 @@ - - - - - diff --git a/src/client/components/note-detailed.vue b/src/client/components/note-detailed.vue deleted file mode 100644 index 568a2360d..000000000 --- a/src/client/components/note-detailed.vue +++ /dev/null @@ -1,1229 +0,0 @@ - - - - - diff --git a/src/client/components/note-header.vue b/src/client/components/note-header.vue deleted file mode 100644 index 80bfea9b0..000000000 --- a/src/client/components/note-header.vue +++ /dev/null @@ -1,115 +0,0 @@ - - - - - diff --git a/src/client/components/note-simple.vue b/src/client/components/note-simple.vue deleted file mode 100644 index 406a475cd..000000000 --- a/src/client/components/note-simple.vue +++ /dev/null @@ -1,113 +0,0 @@ - - - - - diff --git a/src/client/components/note.sub.vue b/src/client/components/note.sub.vue deleted file mode 100644 index 157b65ec5..000000000 --- a/src/client/components/note.sub.vue +++ /dev/null @@ -1,146 +0,0 @@ - - - - - diff --git a/src/client/components/note.vue b/src/client/components/note.vue deleted file mode 100644 index 681e819a2..000000000 --- a/src/client/components/note.vue +++ /dev/null @@ -1,1228 +0,0 @@ - - - - - diff --git a/src/client/components/notes.vue b/src/client/components/notes.vue deleted file mode 100644 index 919cb2995..000000000 --- a/src/client/components/notes.vue +++ /dev/null @@ -1,130 +0,0 @@ - - - - - diff --git a/src/client/components/notification-setting-window.vue b/src/client/components/notification-setting-window.vue deleted file mode 100644 index 14e0b76cc..000000000 --- a/src/client/components/notification-setting-window.vue +++ /dev/null @@ -1,99 +0,0 @@ - - - diff --git a/src/client/components/notification.vue b/src/client/components/notification.vue deleted file mode 100644 index 8c2787cf3..000000000 --- a/src/client/components/notification.vue +++ /dev/null @@ -1,288 +0,0 @@ - - - - - diff --git a/src/client/components/notifications.vue b/src/client/components/notifications.vue deleted file mode 100644 index 78c1cce0c..000000000 --- a/src/client/components/notifications.vue +++ /dev/null @@ -1,159 +0,0 @@ - - - - - diff --git a/src/client/components/number-diff.vue b/src/client/components/number-diff.vue deleted file mode 100644 index 690f89dd5..000000000 --- a/src/client/components/number-diff.vue +++ /dev/null @@ -1,47 +0,0 @@ - - - - - diff --git a/src/client/components/page-preview.vue b/src/client/components/page-preview.vue deleted file mode 100644 index 090c4a6a6..000000000 --- a/src/client/components/page-preview.vue +++ /dev/null @@ -1,162 +0,0 @@ - - - - - diff --git a/src/client/components/page-window.vue b/src/client/components/page-window.vue deleted file mode 100644 index bc7c5b7a1..000000000 --- a/src/client/components/page-window.vue +++ /dev/null @@ -1,167 +0,0 @@ - - - - - diff --git a/src/client/components/page/page.block.vue b/src/client/components/page/page.block.vue deleted file mode 100644 index ffd9ce89f..000000000 --- a/src/client/components/page/page.block.vue +++ /dev/null @@ -1,44 +0,0 @@ - - - diff --git a/src/client/components/page/page.button.vue b/src/client/components/page/page.button.vue deleted file mode 100644 index c6ae67521..000000000 --- a/src/client/components/page/page.button.vue +++ /dev/null @@ -1,66 +0,0 @@ - - - - - diff --git a/src/client/components/page/page.canvas.vue b/src/client/components/page/page.canvas.vue deleted file mode 100644 index e26db597f..000000000 --- a/src/client/components/page/page.canvas.vue +++ /dev/null @@ -1,49 +0,0 @@ - - - - - diff --git a/src/client/components/page/page.counter.vue b/src/client/components/page/page.counter.vue deleted file mode 100644 index dad7ac3da..000000000 --- a/src/client/components/page/page.counter.vue +++ /dev/null @@ -1,52 +0,0 @@ - - - - - diff --git a/src/client/components/page/page.if.vue b/src/client/components/page/page.if.vue deleted file mode 100644 index a70525e07..000000000 --- a/src/client/components/page/page.if.vue +++ /dev/null @@ -1,31 +0,0 @@ - - - diff --git a/src/client/components/page/page.image.vue b/src/client/components/page/page.image.vue deleted file mode 100644 index 14dedc98a..000000000 --- a/src/client/components/page/page.image.vue +++ /dev/null @@ -1,40 +0,0 @@ - - - - - diff --git a/src/client/components/page/page.note.vue b/src/client/components/page/page.note.vue deleted file mode 100644 index 7a3f88bb1..000000000 --- a/src/client/components/page/page.note.vue +++ /dev/null @@ -1,47 +0,0 @@ - - - - - diff --git a/src/client/components/page/page.number-input.vue b/src/client/components/page/page.number-input.vue deleted file mode 100644 index 5d9168f13..000000000 --- a/src/client/components/page/page.number-input.vue +++ /dev/null @@ -1,55 +0,0 @@ - - - - - diff --git a/src/client/components/page/page.post.vue b/src/client/components/page/page.post.vue deleted file mode 100644 index c20d7cade..000000000 --- a/src/client/components/page/page.post.vue +++ /dev/null @@ -1,109 +0,0 @@ - - - - - diff --git a/src/client/components/page/page.radio-button.vue b/src/client/components/page/page.radio-button.vue deleted file mode 100644 index 590e59d70..000000000 --- a/src/client/components/page/page.radio-button.vue +++ /dev/null @@ -1,45 +0,0 @@ - - - diff --git a/src/client/components/page/page.section.vue b/src/client/components/page/page.section.vue deleted file mode 100644 index 81cab1250..000000000 --- a/src/client/components/page/page.section.vue +++ /dev/null @@ -1,60 +0,0 @@ - - - - - diff --git a/src/client/components/page/page.switch.vue b/src/client/components/page/page.switch.vue deleted file mode 100644 index 4d74e5df3..000000000 --- a/src/client/components/page/page.switch.vue +++ /dev/null @@ -1,55 +0,0 @@ - - - - - diff --git a/src/client/components/page/page.text-input.vue b/src/client/components/page/page.text-input.vue deleted file mode 100644 index 6e9ac0b54..000000000 --- a/src/client/components/page/page.text-input.vue +++ /dev/null @@ -1,55 +0,0 @@ - - - - - diff --git a/src/client/components/page/page.text.vue b/src/client/components/page/page.text.vue deleted file mode 100644 index 580c5a93b..000000000 --- a/src/client/components/page/page.text.vue +++ /dev/null @@ -1,68 +0,0 @@ - - - - - diff --git a/src/client/components/page/page.textarea-input.vue b/src/client/components/page/page.textarea-input.vue deleted file mode 100644 index dfcb39893..000000000 --- a/src/client/components/page/page.textarea-input.vue +++ /dev/null @@ -1,47 +0,0 @@ - - - diff --git a/src/client/components/page/page.textarea.vue b/src/client/components/page/page.textarea.vue deleted file mode 100644 index cf953bf04..000000000 --- a/src/client/components/page/page.textarea.vue +++ /dev/null @@ -1,39 +0,0 @@ - - - diff --git a/src/client/components/page/page.vue b/src/client/components/page/page.vue deleted file mode 100644 index f125365c3..000000000 --- a/src/client/components/page/page.vue +++ /dev/null @@ -1,86 +0,0 @@ - - - - - diff --git a/src/client/components/poll-editor.vue b/src/client/components/poll-editor.vue deleted file mode 100644 index b28a1c8ba..000000000 --- a/src/client/components/poll-editor.vue +++ /dev/null @@ -1,251 +0,0 @@ - - - - - diff --git a/src/client/components/poll.vue b/src/client/components/poll.vue deleted file mode 100644 index b5d430f93..000000000 --- a/src/client/components/poll.vue +++ /dev/null @@ -1,174 +0,0 @@ - - - - - diff --git a/src/client/components/post-form-attaches.vue b/src/client/components/post-form-attaches.vue deleted file mode 100644 index 936536565..000000000 --- a/src/client/components/post-form-attaches.vue +++ /dev/null @@ -1,193 +0,0 @@ - - - - - diff --git a/src/client/components/post-form-dialog.vue b/src/client/components/post-form-dialog.vue deleted file mode 100644 index aa23e3891..000000000 --- a/src/client/components/post-form-dialog.vue +++ /dev/null @@ -1,19 +0,0 @@ - - - diff --git a/src/client/components/post-form.vue b/src/client/components/post-form.vue deleted file mode 100644 index 816a69e73..000000000 --- a/src/client/components/post-form.vue +++ /dev/null @@ -1,980 +0,0 @@ - - - - - diff --git a/src/client/pages/messaging/messaging-room.message.vue b/src/client/pages/messaging/messaging-room.message.vue deleted file mode 100644 index a2740c0bd..000000000 --- a/src/client/pages/messaging/messaging-room.message.vue +++ /dev/null @@ -1,350 +0,0 @@ - - - - - diff --git a/src/client/pages/messaging/messaging-room.vue b/src/client/pages/messaging/messaging-room.vue deleted file mode 100644 index 76e58d5bc..000000000 --- a/src/client/pages/messaging/messaging-room.vue +++ /dev/null @@ -1,470 +0,0 @@ - - - - - diff --git a/src/client/pages/mfm-cheat-sheet.vue b/src/client/pages/mfm-cheat-sheet.vue deleted file mode 100644 index 5ff431762..000000000 --- a/src/client/pages/mfm-cheat-sheet.vue +++ /dev/null @@ -1,365 +0,0 @@ - - - - - diff --git a/src/client/pages/miauth.vue b/src/client/pages/miauth.vue deleted file mode 100644 index 39cd83283..000000000 --- a/src/client/pages/miauth.vue +++ /dev/null @@ -1,100 +0,0 @@ - - - - - diff --git a/src/client/pages/my-antennas/create.vue b/src/client/pages/my-antennas/create.vue deleted file mode 100644 index d4762411e..000000000 --- a/src/client/pages/my-antennas/create.vue +++ /dev/null @@ -1,51 +0,0 @@ - - - - - diff --git a/src/client/pages/my-antennas/edit.vue b/src/client/pages/my-antennas/edit.vue deleted file mode 100644 index 9deafb423..000000000 --- a/src/client/pages/my-antennas/edit.vue +++ /dev/null @@ -1,56 +0,0 @@ - - - - - diff --git a/src/client/pages/my-antennas/editor.vue b/src/client/pages/my-antennas/editor.vue deleted file mode 100644 index 93ab64003..000000000 --- a/src/client/pages/my-antennas/editor.vue +++ /dev/null @@ -1,190 +0,0 @@ - - - - - diff --git a/src/client/pages/my-antennas/index.vue b/src/client/pages/my-antennas/index.vue deleted file mode 100644 index c27bb2c15..000000000 --- a/src/client/pages/my-antennas/index.vue +++ /dev/null @@ -1,71 +0,0 @@ - - - - - diff --git a/src/client/pages/my-clips/index.vue b/src/client/pages/my-clips/index.vue deleted file mode 100644 index c4ca47474..000000000 --- a/src/client/pages/my-clips/index.vue +++ /dev/null @@ -1,104 +0,0 @@ - - - - - diff --git a/src/client/pages/my-groups/group.vue b/src/client/pages/my-groups/group.vue deleted file mode 100644 index bd5537cbf..000000000 --- a/src/client/pages/my-groups/group.vue +++ /dev/null @@ -1,184 +0,0 @@ - - - - - diff --git a/src/client/pages/my-groups/index.vue b/src/client/pages/my-groups/index.vue deleted file mode 100644 index 34f82f8a7..000000000 --- a/src/client/pages/my-groups/index.vue +++ /dev/null @@ -1,121 +0,0 @@ - - - - - diff --git a/src/client/pages/my-lists/index.vue b/src/client/pages/my-lists/index.vue deleted file mode 100644 index 687e9e630..000000000 --- a/src/client/pages/my-lists/index.vue +++ /dev/null @@ -1,88 +0,0 @@ - - - - - diff --git a/src/client/pages/my-lists/list.vue b/src/client/pages/my-lists/list.vue deleted file mode 100644 index 049d370b4..000000000 --- a/src/client/pages/my-lists/list.vue +++ /dev/null @@ -1,170 +0,0 @@ - - - - - diff --git a/src/client/pages/not-found.vue b/src/client/pages/not-found.vue deleted file mode 100644 index 5e7fe17f7..000000000 --- a/src/client/pages/not-found.vue +++ /dev/null @@ -1,25 +0,0 @@ - - - diff --git a/src/client/pages/note.vue b/src/client/pages/note.vue deleted file mode 100644 index 8e95430d6..000000000 --- a/src/client/pages/note.vue +++ /dev/null @@ -1,209 +0,0 @@ - - - - - diff --git a/src/client/pages/notifications.vue b/src/client/pages/notifications.vue deleted file mode 100644 index 8d6adec48..000000000 --- a/src/client/pages/notifications.vue +++ /dev/null @@ -1,88 +0,0 @@ - - - - - diff --git a/src/client/pages/page-editor/els/page-editor.el.button.vue b/src/client/pages/page-editor/els/page-editor.el.button.vue deleted file mode 100644 index 85e9d7e71..000000000 --- a/src/client/pages/page-editor/els/page-editor.el.button.vue +++ /dev/null @@ -1,84 +0,0 @@ - - - - - diff --git a/src/client/pages/page-editor/els/page-editor.el.canvas.vue b/src/client/pages/page-editor/els/page-editor.el.canvas.vue deleted file mode 100644 index c40d69a7c..000000000 --- a/src/client/pages/page-editor/els/page-editor.el.canvas.vue +++ /dev/null @@ -1,50 +0,0 @@ - - - diff --git a/src/client/pages/page-editor/els/page-editor.el.counter.vue b/src/client/pages/page-editor/els/page-editor.el.counter.vue deleted file mode 100644 index de7994e3b..000000000 --- a/src/client/pages/page-editor/els/page-editor.el.counter.vue +++ /dev/null @@ -1,46 +0,0 @@ - - - diff --git a/src/client/pages/page-editor/els/page-editor.el.if.vue b/src/client/pages/page-editor/els/page-editor.el.if.vue deleted file mode 100644 index 52f4dac22..000000000 --- a/src/client/pages/page-editor/els/page-editor.el.if.vue +++ /dev/null @@ -1,84 +0,0 @@ - - - - - diff --git a/src/client/pages/page-editor/els/page-editor.el.image.vue b/src/client/pages/page-editor/els/page-editor.el.image.vue deleted file mode 100644 index d96879f50..000000000 --- a/src/client/pages/page-editor/els/page-editor.el.image.vue +++ /dev/null @@ -1,72 +0,0 @@ - - - - - diff --git a/src/client/pages/page-editor/els/page-editor.el.note.vue b/src/client/pages/page-editor/els/page-editor.el.note.vue deleted file mode 100644 index 9feec395b..000000000 --- a/src/client/pages/page-editor/els/page-editor.el.note.vue +++ /dev/null @@ -1,65 +0,0 @@ - - - diff --git a/src/client/pages/page-editor/els/page-editor.el.number-input.vue b/src/client/pages/page-editor/els/page-editor.el.number-input.vue deleted file mode 100644 index 57b139782..000000000 --- a/src/client/pages/page-editor/els/page-editor.el.number-input.vue +++ /dev/null @@ -1,46 +0,0 @@ - - - diff --git a/src/client/pages/page-editor/els/page-editor.el.post.vue b/src/client/pages/page-editor/els/page-editor.el.post.vue deleted file mode 100644 index e21ccfd34..000000000 --- a/src/client/pages/page-editor/els/page-editor.el.post.vue +++ /dev/null @@ -1,43 +0,0 @@ - - - diff --git a/src/client/pages/page-editor/els/page-editor.el.radio-button.vue b/src/client/pages/page-editor/els/page-editor.el.radio-button.vue deleted file mode 100644 index 62fb231f7..000000000 --- a/src/client/pages/page-editor/els/page-editor.el.radio-button.vue +++ /dev/null @@ -1,50 +0,0 @@ - - - diff --git a/src/client/pages/page-editor/els/page-editor.el.section.vue b/src/client/pages/page-editor/els/page-editor.el.section.vue deleted file mode 100644 index 75bdf120c..000000000 --- a/src/client/pages/page-editor/els/page-editor.el.section.vue +++ /dev/null @@ -1,96 +0,0 @@ - - - - - diff --git a/src/client/pages/page-editor/els/page-editor.el.switch.vue b/src/client/pages/page-editor/els/page-editor.el.switch.vue deleted file mode 100644 index cf15f58c8..000000000 --- a/src/client/pages/page-editor/els/page-editor.el.switch.vue +++ /dev/null @@ -1,46 +0,0 @@ - - - - - diff --git a/src/client/pages/page-editor/els/page-editor.el.text-input.vue b/src/client/pages/page-editor/els/page-editor.el.text-input.vue deleted file mode 100644 index 210199bef..000000000 --- a/src/client/pages/page-editor/els/page-editor.el.text-input.vue +++ /dev/null @@ -1,39 +0,0 @@ - - - diff --git a/src/client/pages/page-editor/els/page-editor.el.text.vue b/src/client/pages/page-editor/els/page-editor.el.text.vue deleted file mode 100644 index 668dd5f52..000000000 --- a/src/client/pages/page-editor/els/page-editor.el.text.vue +++ /dev/null @@ -1,57 +0,0 @@ - - - - - diff --git a/src/client/pages/page-editor/els/page-editor.el.textarea-input.vue b/src/client/pages/page-editor/els/page-editor.el.textarea-input.vue deleted file mode 100644 index 14f36db2a..000000000 --- a/src/client/pages/page-editor/els/page-editor.el.textarea-input.vue +++ /dev/null @@ -1,40 +0,0 @@ - - - diff --git a/src/client/pages/page-editor/els/page-editor.el.textarea.vue b/src/client/pages/page-editor/els/page-editor.el.textarea.vue deleted file mode 100644 index a29d5bd3f..000000000 --- a/src/client/pages/page-editor/els/page-editor.el.textarea.vue +++ /dev/null @@ -1,57 +0,0 @@ - - - - - diff --git a/src/client/pages/page-editor/page-editor.blocks.vue b/src/client/pages/page-editor/page-editor.blocks.vue deleted file mode 100644 index c27162a26..000000000 --- a/src/client/pages/page-editor/page-editor.blocks.vue +++ /dev/null @@ -1,78 +0,0 @@ - - - diff --git a/src/client/pages/page-editor/page-editor.script-block.vue b/src/client/pages/page-editor/page-editor.script-block.vue deleted file mode 100644 index 3313fc1ba..000000000 --- a/src/client/pages/page-editor/page-editor.script-block.vue +++ /dev/null @@ -1,281 +0,0 @@ - - - - - diff --git a/src/client/pages/page-editor/page-editor.vue b/src/client/pages/page-editor/page-editor.vue deleted file mode 100644 index aefcc1456..000000000 --- a/src/client/pages/page-editor/page-editor.vue +++ /dev/null @@ -1,561 +0,0 @@ - - - - - diff --git a/src/client/pages/page.vue b/src/client/pages/page.vue deleted file mode 100644 index 3ea687a35..000000000 --- a/src/client/pages/page.vue +++ /dev/null @@ -1,311 +0,0 @@ - - - - - diff --git a/src/client/pages/pages.vue b/src/client/pages/pages.vue deleted file mode 100644 index 696368259..000000000 --- a/src/client/pages/pages.vue +++ /dev/null @@ -1,96 +0,0 @@ - - - - - diff --git a/src/client/pages/preview.vue b/src/client/pages/preview.vue deleted file mode 100644 index 3df446e67..000000000 --- a/src/client/pages/preview.vue +++ /dev/null @@ -1,32 +0,0 @@ - - - - - diff --git a/src/client/pages/reset-password.vue b/src/client/pages/reset-password.vue deleted file mode 100644 index 6dd9f2425..000000000 --- a/src/client/pages/reset-password.vue +++ /dev/null @@ -1,69 +0,0 @@ - - - - - diff --git a/src/client/pages/reversi/game.board.vue b/src/client/pages/reversi/game.board.vue deleted file mode 100644 index 0dd36face..000000000 --- a/src/client/pages/reversi/game.board.vue +++ /dev/null @@ -1,528 +0,0 @@ - - - - - diff --git a/src/client/pages/reversi/game.setting.vue b/src/client/pages/reversi/game.setting.vue deleted file mode 100644 index eb6f24e4a..000000000 --- a/src/client/pages/reversi/game.setting.vue +++ /dev/null @@ -1,390 +0,0 @@ - - - - - diff --git a/src/client/pages/reversi/game.vue b/src/client/pages/reversi/game.vue deleted file mode 100644 index ae10b45b5..000000000 --- a/src/client/pages/reversi/game.vue +++ /dev/null @@ -1,76 +0,0 @@ - - - diff --git a/src/client/pages/reversi/index.vue b/src/client/pages/reversi/index.vue deleted file mode 100644 index cedfd1208..000000000 --- a/src/client/pages/reversi/index.vue +++ /dev/null @@ -1,279 +0,0 @@ - - - - - diff --git a/src/client/pages/room/preview.vue b/src/client/pages/room/preview.vue deleted file mode 100644 index 0cb6bcf04..000000000 --- a/src/client/pages/room/preview.vue +++ /dev/null @@ -1,107 +0,0 @@ - - - diff --git a/src/client/pages/room/room.vue b/src/client/pages/room/room.vue deleted file mode 100644 index 671dca357..000000000 --- a/src/client/pages/room/room.vue +++ /dev/null @@ -1,285 +0,0 @@ - - - - - diff --git a/src/client/pages/scratchpad.vue b/src/client/pages/scratchpad.vue deleted file mode 100644 index 99164ec51..000000000 --- a/src/client/pages/scratchpad.vue +++ /dev/null @@ -1,149 +0,0 @@ - - - - - diff --git a/src/client/pages/search.vue b/src/client/pages/search.vue deleted file mode 100644 index 8cf4d32a8..000000000 --- a/src/client/pages/search.vue +++ /dev/null @@ -1,53 +0,0 @@ - - - diff --git a/src/client/pages/settings/2fa.vue b/src/client/pages/settings/2fa.vue deleted file mode 100644 index 386e7c635..000000000 --- a/src/client/pages/settings/2fa.vue +++ /dev/null @@ -1,247 +0,0 @@ - - - diff --git a/src/client/pages/settings/account-info.vue b/src/client/pages/settings/account-info.vue deleted file mode 100644 index 16ce91b12..000000000 --- a/src/client/pages/settings/account-info.vue +++ /dev/null @@ -1,185 +0,0 @@ - - - diff --git a/src/client/pages/settings/accounts.vue b/src/client/pages/settings/accounts.vue deleted file mode 100644 index d2966cc21..000000000 --- a/src/client/pages/settings/accounts.vue +++ /dev/null @@ -1,149 +0,0 @@ - - - - - diff --git a/src/client/pages/settings/api.vue b/src/client/pages/settings/api.vue deleted file mode 100644 index 5c7496e2f..000000000 --- a/src/client/pages/settings/api.vue +++ /dev/null @@ -1,65 +0,0 @@ - - - diff --git a/src/client/pages/settings/apps.vue b/src/client/pages/settings/apps.vue deleted file mode 100644 index da4f672ad..000000000 --- a/src/client/pages/settings/apps.vue +++ /dev/null @@ -1,113 +0,0 @@ - - - - - diff --git a/src/client/pages/settings/custom-css.vue b/src/client/pages/settings/custom-css.vue deleted file mode 100644 index fd473a11f..000000000 --- a/src/client/pages/settings/custom-css.vue +++ /dev/null @@ -1,73 +0,0 @@ - - - diff --git a/src/client/pages/settings/deck.vue b/src/client/pages/settings/deck.vue deleted file mode 100644 index e4b5c697c..000000000 --- a/src/client/pages/settings/deck.vue +++ /dev/null @@ -1,107 +0,0 @@ - - - diff --git a/src/client/pages/settings/delete-account.vue b/src/client/pages/settings/delete-account.vue deleted file mode 100644 index 6bac214e0..000000000 --- a/src/client/pages/settings/delete-account.vue +++ /dev/null @@ -1,68 +0,0 @@ - - - diff --git a/src/client/pages/settings/drive.vue b/src/client/pages/settings/drive.vue deleted file mode 100644 index 2d73eb4df..000000000 --- a/src/client/pages/settings/drive.vue +++ /dev/null @@ -1,147 +0,0 @@ - - - - - diff --git a/src/client/pages/settings/email-address.vue b/src/client/pages/settings/email-address.vue deleted file mode 100644 index f98b22ada..000000000 --- a/src/client/pages/settings/email-address.vue +++ /dev/null @@ -1,70 +0,0 @@ - - - diff --git a/src/client/pages/settings/email-notification.vue b/src/client/pages/settings/email-notification.vue deleted file mode 100644 index 1b78621c3..000000000 --- a/src/client/pages/settings/email-notification.vue +++ /dev/null @@ -1,91 +0,0 @@ - - - diff --git a/src/client/pages/settings/email.vue b/src/client/pages/settings/email.vue deleted file mode 100644 index adc62133a..000000000 --- a/src/client/pages/settings/email.vue +++ /dev/null @@ -1,66 +0,0 @@ - - - diff --git a/src/client/pages/settings/experimental-features.vue b/src/client/pages/settings/experimental-features.vue deleted file mode 100644 index 971c45a62..000000000 --- a/src/client/pages/settings/experimental-features.vue +++ /dev/null @@ -1,52 +0,0 @@ - - - diff --git a/src/client/pages/settings/general.vue b/src/client/pages/settings/general.vue deleted file mode 100644 index 59dd25194..000000000 --- a/src/client/pages/settings/general.vue +++ /dev/null @@ -1,223 +0,0 @@ - - - diff --git a/src/client/pages/settings/import-export.vue b/src/client/pages/settings/import-export.vue deleted file mode 100644 index eeaa1f160..000000000 --- a/src/client/pages/settings/import-export.vue +++ /dev/null @@ -1,112 +0,0 @@ - - - - - diff --git a/src/client/pages/settings/index.vue b/src/client/pages/settings/index.vue deleted file mode 100644 index cf053dbe6..000000000 --- a/src/client/pages/settings/index.vue +++ /dev/null @@ -1,326 +0,0 @@ - - - - - diff --git a/src/client/pages/settings/integration.vue b/src/client/pages/settings/integration.vue deleted file mode 100644 index 7f398dde9..000000000 --- a/src/client/pages/settings/integration.vue +++ /dev/null @@ -1,141 +0,0 @@ - - - diff --git a/src/client/pages/settings/menu.vue b/src/client/pages/settings/menu.vue deleted file mode 100644 index 31472eb0c..000000000 --- a/src/client/pages/settings/menu.vue +++ /dev/null @@ -1,117 +0,0 @@ - - - diff --git a/src/client/pages/settings/mute-block.vue b/src/client/pages/settings/mute-block.vue deleted file mode 100644 index 18b2fc0af..000000000 --- a/src/client/pages/settings/mute-block.vue +++ /dev/null @@ -1,85 +0,0 @@ - - - diff --git a/src/client/pages/settings/notifications.vue b/src/client/pages/settings/notifications.vue deleted file mode 100644 index 5f8434947..000000000 --- a/src/client/pages/settings/notifications.vue +++ /dev/null @@ -1,77 +0,0 @@ - - - diff --git a/src/client/pages/settings/other.vue b/src/client/pages/settings/other.vue deleted file mode 100644 index 2eb922453..000000000 --- a/src/client/pages/settings/other.vue +++ /dev/null @@ -1,97 +0,0 @@ - - - diff --git a/src/client/pages/settings/plugin.install.vue b/src/client/pages/settings/plugin.install.vue deleted file mode 100644 index 709ef11ab..000000000 --- a/src/client/pages/settings/plugin.install.vue +++ /dev/null @@ -1,147 +0,0 @@ - - - diff --git a/src/client/pages/settings/plugin.manage.vue b/src/client/pages/settings/plugin.manage.vue deleted file mode 100644 index f1c27f1e3..000000000 --- a/src/client/pages/settings/plugin.manage.vue +++ /dev/null @@ -1,115 +0,0 @@ - - - - - diff --git a/src/client/pages/settings/plugin.vue b/src/client/pages/settings/plugin.vue deleted file mode 100644 index 23f263bbb..000000000 --- a/src/client/pages/settings/plugin.vue +++ /dev/null @@ -1,44 +0,0 @@ - - - - - diff --git a/src/client/pages/settings/privacy.vue b/src/client/pages/settings/privacy.vue deleted file mode 100644 index 2a60ae1f4..000000000 --- a/src/client/pages/settings/privacy.vue +++ /dev/null @@ -1,108 +0,0 @@ - - - diff --git a/src/client/pages/settings/profile.vue b/src/client/pages/settings/profile.vue deleted file mode 100644 index b993b5fc7..000000000 --- a/src/client/pages/settings/profile.vue +++ /dev/null @@ -1,281 +0,0 @@ - - - - - diff --git a/src/client/pages/settings/reaction.vue b/src/client/pages/settings/reaction.vue deleted file mode 100644 index a5ff46097..000000000 --- a/src/client/pages/settings/reaction.vue +++ /dev/null @@ -1,152 +0,0 @@ - - - - - diff --git a/src/client/pages/settings/registry.keys.vue b/src/client/pages/settings/registry.keys.vue deleted file mode 100644 index d99002e50..000000000 --- a/src/client/pages/settings/registry.keys.vue +++ /dev/null @@ -1,114 +0,0 @@ - - - diff --git a/src/client/pages/settings/registry.value.vue b/src/client/pages/settings/registry.value.vue deleted file mode 100644 index 06be5737e..000000000 --- a/src/client/pages/settings/registry.value.vue +++ /dev/null @@ -1,149 +0,0 @@ - - - diff --git a/src/client/pages/settings/registry.vue b/src/client/pages/settings/registry.vue deleted file mode 100644 index e4fb230d5..000000000 --- a/src/client/pages/settings/registry.vue +++ /dev/null @@ -1,90 +0,0 @@ - - - diff --git a/src/client/pages/settings/security.vue b/src/client/pages/settings/security.vue deleted file mode 100644 index e051685a8..000000000 --- a/src/client/pages/settings/security.vue +++ /dev/null @@ -1,158 +0,0 @@ - - - - - diff --git a/src/client/pages/settings/sounds.vue b/src/client/pages/settings/sounds.vue deleted file mode 100644 index 07310619c..000000000 --- a/src/client/pages/settings/sounds.vue +++ /dev/null @@ -1,155 +0,0 @@ - - - diff --git a/src/client/pages/settings/theme.install.vue b/src/client/pages/settings/theme.install.vue deleted file mode 100644 index 9fbb28929..000000000 --- a/src/client/pages/settings/theme.install.vue +++ /dev/null @@ -1,105 +0,0 @@ - - - diff --git a/src/client/pages/settings/theme.manage.vue b/src/client/pages/settings/theme.manage.vue deleted file mode 100644 index 1a11a664f..000000000 --- a/src/client/pages/settings/theme.manage.vue +++ /dev/null @@ -1,105 +0,0 @@ - - - diff --git a/src/client/pages/settings/theme.vue b/src/client/pages/settings/theme.vue deleted file mode 100644 index c6be42251..000000000 --- a/src/client/pages/settings/theme.vue +++ /dev/null @@ -1,424 +0,0 @@ - - - - - diff --git a/src/client/pages/settings/update.vue b/src/client/pages/settings/update.vue deleted file mode 100644 index 8bc459e93..000000000 --- a/src/client/pages/settings/update.vue +++ /dev/null @@ -1,95 +0,0 @@ - - - diff --git a/src/client/pages/settings/word-mute.vue b/src/client/pages/settings/word-mute.vue deleted file mode 100644 index 53948b1b1..000000000 --- a/src/client/pages/settings/word-mute.vue +++ /dev/null @@ -1,110 +0,0 @@ - - - diff --git a/src/client/pages/share.vue b/src/client/pages/share.vue deleted file mode 100644 index 70a9661dd..000000000 --- a/src/client/pages/share.vue +++ /dev/null @@ -1,184 +0,0 @@ - - - - - diff --git a/src/client/pages/signup-complete.vue b/src/client/pages/signup-complete.vue deleted file mode 100644 index dada92031..000000000 --- a/src/client/pages/signup-complete.vue +++ /dev/null @@ -1,50 +0,0 @@ - - - - - diff --git a/src/client/pages/tag.vue b/src/client/pages/tag.vue deleted file mode 100644 index 3ca9fe5c0..000000000 --- a/src/client/pages/tag.vue +++ /dev/null @@ -1,57 +0,0 @@ - - - diff --git a/src/client/pages/test.vue b/src/client/pages/test.vue deleted file mode 100644 index fbab0112e..000000000 --- a/src/client/pages/test.vue +++ /dev/null @@ -1,259 +0,0 @@ - - - diff --git a/src/client/pages/theme-editor.vue b/src/client/pages/theme-editor.vue deleted file mode 100644 index 3b10396ab..000000000 --- a/src/client/pages/theme-editor.vue +++ /dev/null @@ -1,306 +0,0 @@ - - - - - diff --git a/src/client/pages/timeline.tutorial.vue b/src/client/pages/timeline.tutorial.vue deleted file mode 100644 index 620994c0d..000000000 --- a/src/client/pages/timeline.tutorial.vue +++ /dev/null @@ -1,131 +0,0 @@ - - - - - diff --git a/src/client/pages/timeline.vue b/src/client/pages/timeline.vue deleted file mode 100644 index 7b17d585f..000000000 --- a/src/client/pages/timeline.vue +++ /dev/null @@ -1,225 +0,0 @@ - - - - - diff --git a/src/client/pages/user-ap-info.vue b/src/client/pages/user-ap-info.vue deleted file mode 100644 index cbdff874e..000000000 --- a/src/client/pages/user-ap-info.vue +++ /dev/null @@ -1,124 +0,0 @@ - - - diff --git a/src/client/pages/user-info.vue b/src/client/pages/user-info.vue deleted file mode 100644 index bf67fc853..000000000 --- a/src/client/pages/user-info.vue +++ /dev/null @@ -1,245 +0,0 @@ - - - - - diff --git a/src/client/pages/user-list-timeline.vue b/src/client/pages/user-list-timeline.vue deleted file mode 100644 index b5e37d484..000000000 --- a/src/client/pages/user-list-timeline.vue +++ /dev/null @@ -1,147 +0,0 @@ - - - - - diff --git a/src/client/pages/user/clips.vue b/src/client/pages/user/clips.vue deleted file mode 100644 index 53ee55438..000000000 --- a/src/client/pages/user/clips.vue +++ /dev/null @@ -1,50 +0,0 @@ - - - - - diff --git a/src/client/pages/user/follow-list.vue b/src/client/pages/user/follow-list.vue deleted file mode 100644 index 1f5ab5993..000000000 --- a/src/client/pages/user/follow-list.vue +++ /dev/null @@ -1,65 +0,0 @@ - - - - - diff --git a/src/client/pages/user/gallery.vue b/src/client/pages/user/gallery.vue deleted file mode 100644 index c21b3e642..000000000 --- a/src/client/pages/user/gallery.vue +++ /dev/null @@ -1,56 +0,0 @@ - - - - - diff --git a/src/client/pages/user/index.activity.vue b/src/client/pages/user/index.activity.vue deleted file mode 100644 index be85c252e..000000000 --- a/src/client/pages/user/index.activity.vue +++ /dev/null @@ -1,34 +0,0 @@ - - - diff --git a/src/client/pages/user/index.photos.vue b/src/client/pages/user/index.photos.vue deleted file mode 100644 index 5029c3fee..000000000 --- a/src/client/pages/user/index.photos.vue +++ /dev/null @@ -1,107 +0,0 @@ - - - - - diff --git a/src/client/pages/user/index.timeline.vue b/src/client/pages/user/index.timeline.vue deleted file mode 100644 index c3444f26f..000000000 --- a/src/client/pages/user/index.timeline.vue +++ /dev/null @@ -1,68 +0,0 @@ - - - - - diff --git a/src/client/pages/user/index.vue b/src/client/pages/user/index.vue deleted file mode 100644 index 04585f3fd..000000000 --- a/src/client/pages/user/index.vue +++ /dev/null @@ -1,829 +0,0 @@ - - - - - diff --git a/src/client/pages/user/pages.vue b/src/client/pages/user/pages.vue deleted file mode 100644 index ece418cf6..000000000 --- a/src/client/pages/user/pages.vue +++ /dev/null @@ -1,49 +0,0 @@ - - - - - diff --git a/src/client/pages/user/reactions.vue b/src/client/pages/user/reactions.vue deleted file mode 100644 index 5ac7e0102..000000000 --- a/src/client/pages/user/reactions.vue +++ /dev/null @@ -1,81 +0,0 @@ - - - - - diff --git a/src/client/pages/v.vue b/src/client/pages/v.vue deleted file mode 100644 index 4440e8070..000000000 --- a/src/client/pages/v.vue +++ /dev/null @@ -1,29 +0,0 @@ - - - diff --git a/src/client/pages/welcome.entrance.a.vue b/src/client/pages/welcome.entrance.a.vue deleted file mode 100644 index 13f099379..000000000 --- a/src/client/pages/welcome.entrance.a.vue +++ /dev/null @@ -1,320 +0,0 @@ - - - - - diff --git a/src/client/pages/welcome.entrance.b.vue b/src/client/pages/welcome.entrance.b.vue deleted file mode 100644 index 163fc1e35..000000000 --- a/src/client/pages/welcome.entrance.b.vue +++ /dev/null @@ -1,236 +0,0 @@ - - - - - diff --git a/src/client/pages/welcome.entrance.c.vue b/src/client/pages/welcome.entrance.c.vue deleted file mode 100644 index bf1c9b199..000000000 --- a/src/client/pages/welcome.entrance.c.vue +++ /dev/null @@ -1,305 +0,0 @@ - - - - - diff --git a/src/client/pages/welcome.setup.vue b/src/client/pages/welcome.setup.vue deleted file mode 100644 index dfefecc8f..000000000 --- a/src/client/pages/welcome.setup.vue +++ /dev/null @@ -1,102 +0,0 @@ - - - - - diff --git a/src/client/pages/welcome.timeline.vue b/src/client/pages/welcome.timeline.vue deleted file mode 100644 index bd07ac78d..000000000 --- a/src/client/pages/welcome.timeline.vue +++ /dev/null @@ -1,99 +0,0 @@ - - - - - diff --git a/src/client/pages/welcome.vue b/src/client/pages/welcome.vue deleted file mode 100644 index b6a715830..000000000 --- a/src/client/pages/welcome.vue +++ /dev/null @@ -1,38 +0,0 @@ - - - diff --git a/src/client/plugin.ts b/src/client/plugin.ts deleted file mode 100644 index 6bdc4fe4d..000000000 --- a/src/client/plugin.ts +++ /dev/null @@ -1,124 +0,0 @@ -import { AiScript, utils, values } from '@syuilo/aiscript'; -import { deserialize } from '@syuilo/aiscript/built/serializer'; -import { jsToVal } from '@syuilo/aiscript/built/interpreter/util'; -import { createAiScriptEnv } from '@client/scripts/aiscript/api'; -import { dialog } from '@client/os'; -import { noteActions, notePostInterruptors, noteViewInterruptors, postFormActions, userActions } from '@client/store'; - -const pluginContexts = new Map(); - -export function install(plugin) { - console.info('Plugin installed:', plugin.name, 'v' + plugin.version); - - const aiscript = new AiScript(createPluginEnv({ - plugin: plugin, - storageKey: 'plugins:' + plugin.id - }), { - in: (q) => { - return new Promise(ok => { - dialog({ - title: q, - input: {} - }).then(({ canceled, result: a }) => { - ok(a); - }); - }); - }, - out: (value) => { - console.log(value); - }, - log: (type, params) => { - }, - }); - - initPlugin({ plugin, aiscript }); - - aiscript.exec(deserialize(plugin.ast)); -} - -function createPluginEnv(opts) { - const config = new Map(); - for (const [k, v] of Object.entries(opts.plugin.config || {})) { - config.set(k, jsToVal(opts.plugin.configData.hasOwnProperty(k) ? opts.plugin.configData[k] : v.default)); - } - - return { - ...createAiScriptEnv({ ...opts, token: opts.plugin.token }), - //#region Deprecated - 'Mk:register_post_form_action': values.FN_NATIVE(([title, handler]) => { - registerPostFormAction({ pluginId: opts.plugin.id, title: title.value, handler }); - }), - 'Mk:register_user_action': values.FN_NATIVE(([title, handler]) => { - registerUserAction({ pluginId: opts.plugin.id, title: title.value, handler }); - }), - 'Mk:register_note_action': values.FN_NATIVE(([title, handler]) => { - registerNoteAction({ pluginId: opts.plugin.id, title: title.value, handler }); - }), - //#endregion - 'Plugin:register_post_form_action': values.FN_NATIVE(([title, handler]) => { - registerPostFormAction({ pluginId: opts.plugin.id, title: title.value, handler }); - }), - 'Plugin:register_user_action': values.FN_NATIVE(([title, handler]) => { - registerUserAction({ pluginId: opts.plugin.id, title: title.value, handler }); - }), - 'Plugin:register_note_action': values.FN_NATIVE(([title, handler]) => { - registerNoteAction({ pluginId: opts.plugin.id, title: title.value, handler }); - }), - 'Plugin:register_note_view_interruptor': values.FN_NATIVE(([handler]) => { - registerNoteViewInterruptor({ pluginId: opts.plugin.id, handler }); - }), - 'Plugin:register_note_post_interruptor': values.FN_NATIVE(([handler]) => { - registerNotePostInterruptor({ pluginId: opts.plugin.id, handler }); - }), - 'Plugin:open_url': values.FN_NATIVE(([url]) => { - window.open(url.value, '_blank'); - }), - 'Plugin:config': values.OBJ(config), - }; -} - -function initPlugin({ plugin, aiscript }) { - pluginContexts.set(plugin.id, aiscript); -} - -function registerPostFormAction({ pluginId, title, handler }) { - postFormActions.push({ - title, handler: (form, update) => { - pluginContexts.get(pluginId).execFn(handler, [utils.jsToVal(form), values.FN_NATIVE(([key, value]) => { - update(key.value, value.value); - })]); - } - }); -} - -function registerUserAction({ pluginId, title, handler }) { - userActions.push({ - title, handler: (user) => { - pluginContexts.get(pluginId).execFn(handler, [utils.jsToVal(user)]); - } - }); -} - -function registerNoteAction({ pluginId, title, handler }) { - noteActions.push({ - title, handler: (note) => { - pluginContexts.get(pluginId).execFn(handler, [utils.jsToVal(note)]); - } - }); -} - -function registerNoteViewInterruptor({ pluginId, handler }) { - noteViewInterruptors.push({ - handler: async (note) => { - return utils.valToJs(await pluginContexts.get(pluginId).execFn(handler, [utils.jsToVal(note)])); - } - }); -} - -function registerNotePostInterruptor({ pluginId, handler }) { - notePostInterruptors.push({ - handler: async (note) => { - return utils.valToJs(await pluginContexts.get(pluginId).execFn(handler, [utils.jsToVal(note)])); - } - }); -} diff --git a/src/client/router.ts b/src/client/router.ts deleted file mode 100644 index f588bb04f..000000000 --- a/src/client/router.ts +++ /dev/null @@ -1,151 +0,0 @@ -import { defineAsyncComponent, markRaw } from 'vue'; -import { createRouter, createWebHistory } from 'vue-router'; -import MkLoading from '@client/pages/_loading_.vue'; -import MkError from '@client/pages/_error_.vue'; -import MkTimeline from '@client/pages/timeline.vue'; -import { $i } from './account'; -import { ui } from '@client/config'; - -const page = (path: string, ui?: string) => defineAsyncComponent({ - loader: ui ? () => import(`./ui/${ui}/pages/${path}.vue`) : () => import(`./pages/${path}.vue`), - loadingComponent: MkLoading, - errorComponent: MkError, -}); - -let indexScrollPos = 0; - -const defaultRoutes = [ - // NOTE: MkTimelineをdynamic importするとAsyncComponentWrapperが間に入るせいでkeep-aliveのコンポーネント指定が効かなくなる - { path: '/', name: 'index', component: $i ? MkTimeline : page('welcome') }, - { path: '/@:acct/:page?', name: 'user', component: page('user/index'), props: route => ({ acct: route.params.acct, page: route.params.page || 'index' }) }, - { path: '/@:user/pages/:page', component: page('page'), props: route => ({ pageName: route.params.page, username: route.params.user }) }, - { path: '/@:user/pages/:pageName/view-source', component: page('page-editor/page-editor'), props: route => ({ initUser: route.params.user, initPageName: route.params.pageName }) }, - { path: '/@:acct/room', props: true, component: page('room/room') }, - { path: '/settings/:page(.*)?', name: 'settings', component: page('settings/index'), props: route => ({ initialPage: route.params.page || null }) }, - { path: '/reset-password/:token?', component: page('reset-password'), props: route => ({ token: route.params.token }) }, - { path: '/signup-complete/:code', component: page('signup-complete'), props: route => ({ code: route.params.code }) }, - { path: '/announcements', component: page('announcements') }, - { path: '/about', component: page('about') }, - { path: '/about-misskey', component: page('about-misskey') }, - { path: '/featured', component: page('featured') }, - { path: '/docs', component: page('docs') }, - { path: '/theme-editor', component: page('theme-editor') }, - { path: '/advanced-theme-editor', component: page('advanced-theme-editor') }, - { path: '/docs/:doc(.*)', component: page('doc'), props: route => ({ doc: route.params.doc }) }, - { path: '/explore', component: page('explore') }, - { path: '/explore/tags/:tag', props: true, component: page('explore') }, - { path: '/federation', component: page('federation') }, - { path: '/emojis', component: page('emojis') }, - { path: '/search', component: page('search') }, - { path: '/pages', name: 'pages', component: page('pages') }, - { path: '/pages/new', component: page('page-editor/page-editor') }, - { path: '/pages/edit/:pageId', component: page('page-editor/page-editor'), props: route => ({ initPageId: route.params.pageId }) }, - { path: '/gallery', component: page('gallery/index') }, - { path: '/gallery/new', component: page('gallery/edit') }, - { path: '/gallery/:postId/edit', component: page('gallery/edit'), props: route => ({ postId: route.params.postId }) }, - { path: '/gallery/:postId', component: page('gallery/post'), props: route => ({ postId: route.params.postId }) }, - { path: '/channels', component: page('channels') }, - { path: '/channels/new', component: page('channel-editor') }, - { path: '/channels/:channelId/edit', component: page('channel-editor'), props: true }, - { path: '/channels/:channelId', component: page('channel'), props: route => ({ channelId: route.params.channelId }) }, - { path: '/clips/:clipId', component: page('clip'), props: route => ({ clipId: route.params.clipId }) }, - { path: '/timeline/list/:listId', component: page('user-list-timeline'), props: route => ({ listId: route.params.listId }) }, - { path: '/timeline/antenna/:antennaId', component: page('antenna-timeline'), props: route => ({ antennaId: route.params.antennaId }) }, - { path: '/my/notifications', component: page('notifications') }, - { path: '/my/favorites', component: page('favorites') }, - { path: '/my/messages', component: page('messages') }, - { path: '/my/mentions', component: page('mentions') }, - { path: '/my/messaging', name: 'messaging', component: page('messaging/index') }, - { path: '/my/messaging/:user', component: page('messaging/messaging-room'), props: route => ({ userAcct: route.params.user }) }, - { path: '/my/messaging/group/:group', component: page('messaging/messaging-room'), props: route => ({ groupId: route.params.group }) }, - { path: '/my/drive', name: 'drive', component: page('drive') }, - { path: '/my/drive/folder/:folder', component: page('drive') }, - { path: '/my/follow-requests', component: page('follow-requests') }, - { path: '/my/lists', component: page('my-lists/index') }, - { path: '/my/lists/:list', component: page('my-lists/list') }, - { path: '/my/groups', component: page('my-groups/index') }, - { path: '/my/groups/:group', component: page('my-groups/group'), props: route => ({ groupId: route.params.group }) }, - { path: '/my/antennas', component: page('my-antennas/index') }, - { path: '/my/antennas/create', component: page('my-antennas/create') }, - { path: '/my/antennas/:antennaId', component: page('my-antennas/edit'), props: true }, - { path: '/my/clips', component: page('my-clips/index') }, - { path: '/scratchpad', component: page('scratchpad') }, - { path: '/admin/:page(.*)?', component: page('admin/index'), props: route => ({ initialPage: route.params.page || null }) }, - { path: '/admin', component: page('admin/index') }, - { path: '/notes/:note', name: 'note', component: page('note'), props: route => ({ noteId: route.params.note }) }, - { path: '/tags/:tag', component: page('tag'), props: route => ({ tag: route.params.tag }) }, - { path: '/user-info/:user', component: page('user-info'), props: route => ({ userId: route.params.user }) }, - { path: '/user-ap-info/:user', component: page('user-ap-info'), props: route => ({ userId: route.params.user }) }, - { path: '/instance-info/:host', component: page('instance-info'), props: route => ({ host: route.params.host }) }, - { path: '/games/reversi', component: page('reversi/index') }, - { path: '/games/reversi/:gameId', component: page('reversi/game'), props: route => ({ gameId: route.params.gameId }) }, - { path: '/mfm-cheat-sheet', component: page('mfm-cheat-sheet') }, - { path: '/api-console', component: page('api-console') }, - { path: '/preview', component: page('preview') }, - { path: '/test', component: page('test') }, - { path: '/auth/:token', component: page('auth') }, - { path: '/miauth/:session', component: page('miauth') }, - { path: '/authorize-follow', component: page('follow') }, - { path: '/share', component: page('share') }, - { path: '/:catchAll(.*)', component: page('not-found') } -]; - -const chatRoutes = [ - { path: '/timeline', component: page('timeline', 'chat'), props: route => ({ src: 'home' }) }, - { path: '/timeline/home', component: page('timeline', 'chat'), props: route => ({ src: 'home' }) }, - { path: '/timeline/local', component: page('timeline', 'chat'), props: route => ({ src: 'local' }) }, - { path: '/timeline/social', component: page('timeline', 'chat'), props: route => ({ src: 'social' }) }, - { path: '/timeline/global', component: page('timeline', 'chat'), props: route => ({ src: 'global' }) }, - { path: '/channels/:channelId', component: page('channel', 'chat'), props: route => ({ channelId: route.params.channelId }) }, -]; - -function margeRoutes(routes: any[]) { - const result = defaultRoutes; - for (const route of routes) { - const found = result.findIndex(x => x.path === route.path); - if (found > -1) { - result[found] = route; - } else { - result.unshift(route); - } - } - return result; -} - -export const router = createRouter({ - history: createWebHistory(), - routes: margeRoutes(ui === 'chat' ? chatRoutes : []), - // なんかHacky - // 通常の使い方をすると scroll メソッドの behavior を設定できないため、自前で window.scroll するようにする - scrollBehavior(to) { - window._scroll = () => { // さらにHacky - if (to.name === 'index') { - window.scroll({ top: indexScrollPos, behavior: 'instant' }); - const i = setInterval(() => { - window.scroll({ top: indexScrollPos, behavior: 'instant' }); - }, 10); - setTimeout(() => { - clearInterval(i); - }, 500); - } else { - window.scroll({ top: 0, behavior: 'instant' }); - } - }; - } -}); - -router.afterEach((to, from) => { - if (from.name === 'index') { - indexScrollPos = window.scrollY; - } -}); - -export function resolve(path: string) { - const resolved = router.resolve(path); - const route = resolved.matched[0]; - return { - component: markRaw(route.components.default), - // TODO: route.propsには関数以外も入る可能性があるのでよしなにハンドリングする - props: route.props?.default ? route.props.default(resolved) : resolved.params - }; -} diff --git a/src/client/scripts/aiscript/api.ts b/src/client/scripts/aiscript/api.ts deleted file mode 100644 index 5dd08f34a..000000000 --- a/src/client/scripts/aiscript/api.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { utils, values } from '@syuilo/aiscript'; -import * as os from '@client/os'; -import { $i } from '@client/account'; - -export function createAiScriptEnv(opts) { - let apiRequests = 0; - return { - USER_ID: $i ? values.STR($i.id) : values.NULL, - USER_NAME: $i ? values.STR($i.name) : values.NULL, - USER_USERNAME: $i ? values.STR($i.username) : values.NULL, - 'Mk:dialog': values.FN_NATIVE(async ([title, text, type]) => { - await os.dialog({ - type: type ? type.value : 'info', - title: title.value, - text: text.value, - }); - }), - 'Mk:confirm': values.FN_NATIVE(async ([title, text, type]) => { - const confirm = await os.dialog({ - type: type ? type.value : 'question', - showCancelButton: true, - title: title.value, - text: text.value, - }); - return confirm.canceled ? values.FALSE : values.TRUE; - }), - 'Mk:api': values.FN_NATIVE(async ([ep, param, token]) => { - if (token) utils.assertString(token); - apiRequests++; - if (apiRequests > 16) return values.NULL; - const res = await os.api(ep.value, utils.valToJs(param), token ? token.value : (opts.token || null)); - return utils.jsToVal(res); - }), - 'Mk:save': values.FN_NATIVE(([key, value]) => { - utils.assertString(key); - localStorage.setItem('aiscript:' + opts.storageKey + ':' + key.value, JSON.stringify(utils.valToJs(value))); - return values.NULL; - }), - 'Mk:load': values.FN_NATIVE(([key]) => { - utils.assertString(key); - return utils.jsToVal(JSON.parse(localStorage.getItem('aiscript:' + opts.storageKey + ':' + key.value))); - }), - }; -} diff --git a/src/client/scripts/autocomplete.ts b/src/client/scripts/autocomplete.ts deleted file mode 100644 index c0c33b2c7..000000000 --- a/src/client/scripts/autocomplete.ts +++ /dev/null @@ -1,276 +0,0 @@ -import { Ref, ref } from 'vue'; -import * as getCaretCoordinates from 'textarea-caret'; -import { toASCII } from 'punycode/'; -import { popup } from '@client/os'; - -export class Autocomplete { - private suggestion: { - x: Ref; - y: Ref; - q: Ref; - close: Function; - } | null; - private textarea: any; - private vm: any; - private currentType: string; - private opts: { - model: string; - }; - private opening: boolean; - - private get text(): string { - return this.vm[this.opts.model]; - } - - private set text(text: string) { - this.vm[this.opts.model] = text; - } - - /** - * 対象のテキストエリアを与えてインスタンスを初期化します。 - */ - constructor(textarea, vm, opts) { - //#region BIND - this.onInput = this.onInput.bind(this); - this.complete = this.complete.bind(this); - this.close = this.close.bind(this); - //#endregion - - this.suggestion = null; - this.textarea = textarea; - this.vm = vm; - this.opts = opts; - this.opening = false; - - this.attach(); - } - - /** - * このインスタンスにあるテキストエリアの入力のキャプチャを開始します。 - */ - public attach() { - this.textarea.addEventListener('input', this.onInput); - } - - /** - * このインスタンスにあるテキストエリアの入力のキャプチャを解除します。 - */ - public detach() { - this.textarea.removeEventListener('input', this.onInput); - this.close(); - } - - /** - * テキスト入力時 - */ - private onInput() { - const caretPos = this.textarea.selectionStart; - const text = this.text.substr(0, caretPos).split('\n').pop()!; - - const mentionIndex = text.lastIndexOf('@'); - const hashtagIndex = text.lastIndexOf('#'); - const emojiIndex = text.lastIndexOf(':'); - const mfmTagIndex = text.lastIndexOf('$'); - - const max = Math.max( - mentionIndex, - hashtagIndex, - emojiIndex, - mfmTagIndex); - - if (max == -1) { - this.close(); - return; - } - - const isMention = mentionIndex != -1; - const isHashtag = hashtagIndex != -1; - const isMfmTag = mfmTagIndex != -1; - const isEmoji = emojiIndex != -1 && text.split(/:[a-z0-9_+\-]+:/).pop()!.includes(':'); - - let opened = false; - - if (isMention) { - const username = text.substr(mentionIndex + 1); - if (username != '' && username.match(/^[a-zA-Z0-9_]+$/)) { - this.open('user', username); - opened = true; - } else if (username === '') { - this.open('user', null); - opened = true; - } - } - - if (isHashtag && !opened) { - const hashtag = text.substr(hashtagIndex + 1); - if (!hashtag.includes(' ')) { - this.open('hashtag', hashtag); - opened = true; - } - } - - if (isEmoji && !opened) { - const emoji = text.substr(emojiIndex + 1); - if (!emoji.includes(' ')) { - this.open('emoji', emoji); - opened = true; - } - } - - if (isMfmTag && !opened) { - const mfmTag = text.substr(mfmTagIndex + 1); - if (!mfmTag.includes(' ')) { - this.open('mfmTag', mfmTag.replace('[', '')); - opened = true; - } - } - - if (!opened) { - this.close(); - } - } - - /** - * サジェストを提示します。 - */ - private async open(type: string, q: string | null) { - if (type != this.currentType) { - this.close(); - } - if (this.opening) return; - this.opening = true; - this.currentType = type; - - //#region サジェストを表示すべき位置を計算 - const caretPosition = getCaretCoordinates(this.textarea, this.textarea.selectionStart); - - const rect = this.textarea.getBoundingClientRect(); - - const x = rect.left + caretPosition.left - this.textarea.scrollLeft; - const y = rect.top + caretPosition.top - this.textarea.scrollTop; - //#endregion - - if (this.suggestion) { - this.suggestion.x.value = x; - this.suggestion.y.value = y; - this.suggestion.q.value = q; - - this.opening = false; - } else { - const _x = ref(x); - const _y = ref(y); - const _q = ref(q); - - const { dispose } = await popup(import('@client/components/autocomplete.vue'), { - textarea: this.textarea, - close: this.close, - type: type, - q: _q, - x: _x, - y: _y, - }, { - done: (res) => { - this.complete(res); - } - }); - - this.suggestion = { - q: _q, - x: _x, - y: _y, - close: () => dispose(), - }; - - this.opening = false; - } - } - - /** - * サジェストを閉じます。 - */ - private close() { - if (this.suggestion == null) return; - - this.suggestion.close(); - this.suggestion = null; - - this.textarea.focus(); - } - - /** - * オートコンプリートする - */ - private complete({ type, value }) { - this.close(); - - const caret = this.textarea.selectionStart; - - if (type == 'user') { - const source = this.text; - - const before = source.substr(0, caret); - const trimmedBefore = before.substring(0, before.lastIndexOf('@')); - const after = source.substr(caret); - - const acct = value.host === null ? value.username : `${value.username}@${toASCII(value.host)}`; - - // 挿入 - this.text = `${trimmedBefore}@${acct} ${after}`; - - // キャレットを戻す - this.vm.$nextTick(() => { - this.textarea.focus(); - const pos = trimmedBefore.length + (acct.length + 2); - this.textarea.setSelectionRange(pos, pos); - }); - } else if (type == 'hashtag') { - const source = this.text; - - const before = source.substr(0, caret); - const trimmedBefore = before.substring(0, before.lastIndexOf('#')); - const after = source.substr(caret); - - // 挿入 - this.text = `${trimmedBefore}#${value} ${after}`; - - // キャレットを戻す - this.vm.$nextTick(() => { - this.textarea.focus(); - const pos = trimmedBefore.length + (value.length + 2); - this.textarea.setSelectionRange(pos, pos); - }); - } else if (type == 'emoji') { - const source = this.text; - - const before = source.substr(0, caret); - const trimmedBefore = before.substring(0, before.lastIndexOf(':')); - const after = source.substr(caret); - - // 挿入 - this.text = trimmedBefore + value + after; - - // キャレットを戻す - this.vm.$nextTick(() => { - this.textarea.focus(); - const pos = trimmedBefore.length + value.length; - this.textarea.setSelectionRange(pos, pos); - }); - } else if (type == 'mfmTag') { - const source = this.text; - - const before = source.substr(0, caret); - const trimmedBefore = before.substring(0, before.lastIndexOf('$')); - const after = source.substr(caret); - - // 挿入 - this.text = `${trimmedBefore}$[${value} ]${after}`; - - // キャレットを戻す - this.vm.$nextTick(() => { - this.textarea.focus(); - const pos = trimmedBefore.length + (value.length + 3); - this.textarea.setSelectionRange(pos, pos); - }); - } - } -} diff --git a/src/client/scripts/gen-search-query.ts b/src/client/scripts/gen-search-query.ts deleted file mode 100644 index cafb3cccf..000000000 --- a/src/client/scripts/gen-search-query.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { parseAcct } from '@/misc/acct'; -import { host as localHost } from '@client/config'; - -export async function genSearchQuery(v: any, q: string) { - let host: string; - let userId: string; - if (q.split(' ').some(x => x.startsWith('@'))) { - for (const at of q.split(' ').filter(x => x.startsWith('@')).map(x => x.substr(1))) { - if (at.includes('.')) { - if (at === localHost || at === '.') { - host = null; - } else { - host = at; - } - } else { - const user = await v.os.api('users/show', parseAcct(at)).catch(x => null); - if (user) { - userId = user.id; - } else { - // todo: show error - } - } - } - - } - return { - query: q.split(' ').filter(x => !x.startsWith('/') && !x.startsWith('@')).join(' '), - host: host, - userId: userId - }; -} diff --git a/src/client/scripts/get-account-from-id.ts b/src/client/scripts/get-account-from-id.ts deleted file mode 100644 index 065b41118..000000000 --- a/src/client/scripts/get-account-from-id.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { get } from '@client/scripts/idb-proxy'; - -export async function getAccountFromId(id: string) { - const accounts = await get('accounts') as { token: string; id: string; }[]; - if (!accounts) console.log('Accounts are not recorded'); - return accounts.find(e => e.id === id); -} diff --git a/src/client/scripts/get-static-image-url.ts b/src/client/scripts/get-static-image-url.ts deleted file mode 100644 index 92c31914c..000000000 --- a/src/client/scripts/get-static-image-url.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { url as instanceUrl } from '@client/config'; -import * as url from '../../prelude/url'; - -export function getStaticImageUrl(baseUrl: string): string { - const u = new URL(baseUrl); - if (u.href.startsWith(`${instanceUrl}/proxy/`)) { - // もう既にproxyっぽそうだったらsearchParams付けるだけ - u.searchParams.set('static', '1'); - return u.href; - } - const dummy = `${u.host}${u.pathname}`; // 拡張子がないとキャッシュしてくれないCDNがあるので - return `${instanceUrl}/proxy/${dummy}?${url.query({ - url: u.href, - static: '1' - })}`; -} diff --git a/src/client/scripts/get-user-menu.ts b/src/client/scripts/get-user-menu.ts deleted file mode 100644 index 3689a93b4..000000000 --- a/src/client/scripts/get-user-menu.ts +++ /dev/null @@ -1,205 +0,0 @@ -import { i18n } from '@client/i18n'; -import copyToClipboard from '@client/scripts/copy-to-clipboard'; -import { host } from '@client/config'; -import { getAcct } from '@/misc/acct'; -import * as os from '@client/os'; -import { userActions } from '@client/store'; -import { router } from '@client/router'; -import { $i } from '@client/account'; - -export function getUserMenu(user) { - const meId = $i ? $i.id : null; - - async function pushList() { - const t = i18n.locale.selectList; // なぜか後で参照すると null になるので最初にメモリに確保しておく - const lists = await os.api('users/lists/list'); - if (lists.length === 0) { - os.dialog({ - type: 'error', - text: i18n.locale.youHaveNoLists - }); - return; - } - const { canceled, result: listId } = await os.dialog({ - type: null, - title: t, - select: { - items: lists.map(list => ({ - value: list.id, text: list.name - })) - }, - showCancelButton: true - }); - if (canceled) return; - os.apiWithDialog('users/lists/push', { - listId: listId, - userId: user.id - }); - } - - async function inviteGroup() { - const groups = await os.api('users/groups/owned'); - if (groups.length === 0) { - os.dialog({ - type: 'error', - text: i18n.locale.youHaveNoGroups - }); - return; - } - const { canceled, result: groupId } = await os.dialog({ - type: null, - title: i18n.locale.group, - select: { - items: groups.map(group => ({ - value: group.id, text: group.name - })) - }, - showCancelButton: true - }); - if (canceled) return; - os.apiWithDialog('users/groups/invite', { - groupId: groupId, - userId: user.id - }); - } - - async function toggleMute() { - os.apiWithDialog(user.isMuted ? 'mute/delete' : 'mute/create', { - userId: user.id - }).then(() => { - user.isMuted = !user.isMuted; - }); - } - - async function toggleBlock() { - if (!await getConfirmed(user.isBlocking ? i18n.locale.unblockConfirm : i18n.locale.blockConfirm)) return; - - os.apiWithDialog(user.isBlocking ? 'blocking/delete' : 'blocking/create', { - userId: user.id - }).then(() => { - user.isBlocking = !user.isBlocking; - }); - } - - async function toggleSilence() { - if (!await getConfirmed(i18n.t(user.isSilenced ? 'unsilenceConfirm' : 'silenceConfirm'))) return; - - os.apiWithDialog(user.isSilenced ? 'admin/unsilence-user' : 'admin/silence-user', { - userId: user.id - }).then(() => { - user.isSilenced = !user.isSilenced; - }); - } - - async function toggleSuspend() { - if (!await getConfirmed(i18n.t(user.isSuspended ? 'unsuspendConfirm' : 'suspendConfirm'))) return; - - os.apiWithDialog(user.isSuspended ? 'admin/unsuspend-user' : 'admin/suspend-user', { - userId: user.id - }).then(() => { - user.isSuspended = !user.isSuspended; - }); - } - - function reportAbuse() { - os.popup(import('@client/components/abuse-report-window.vue'), { - user: user, - }, {}, 'closed'); - } - - async function getConfirmed(text: string): Promise { - const confirm = await os.dialog({ - type: 'warning', - showCancelButton: true, - title: 'confirm', - text, - }); - - return !confirm.canceled; - } - - let menu = [{ - icon: 'fas fa-at', - text: i18n.locale.copyUsername, - action: () => { - copyToClipboard(`@${user.username}@${user.host || host}`); - } - }, { - icon: 'fas fa-info-circle', - text: i18n.locale.info, - action: () => { - os.pageWindow(`/user-info/${user.id}`); - } - }, { - icon: 'fas fa-envelope', - text: i18n.locale.sendMessage, - action: () => { - os.post({ specified: user }); - } - }, meId != user.id ? { - type: 'link', - icon: 'fas fa-comments', - text: i18n.locale.startMessaging, - to: '/my/messaging/' + getAcct(user), - } : undefined, null, { - icon: 'fas fa-list-ul', - text: i18n.locale.addToList, - action: pushList - }, meId != user.id ? { - icon: 'fas fa-users', - text: i18n.locale.inviteToGroup, - action: inviteGroup - } : undefined] as any; - - if ($i && meId != user.id) { - menu = menu.concat([null, { - icon: user.isMuted ? 'fas fa-eye' : 'fas fa-eye-slash', - text: user.isMuted ? i18n.locale.unmute : i18n.locale.mute, - action: toggleMute - }, { - icon: 'fas fa-ban', - text: user.isBlocking ? i18n.locale.unblock : i18n.locale.block, - action: toggleBlock - }]); - - menu = menu.concat([null, { - icon: 'fas fa-exclamation-circle', - text: i18n.locale.reportAbuse, - action: reportAbuse - }]); - - if ($i && ($i.isAdmin || $i.isModerator)) { - menu = menu.concat([null, { - icon: 'fas fa-microphone-slash', - text: user.isSilenced ? i18n.locale.unsilence : i18n.locale.silence, - action: toggleSilence - }, { - icon: 'fas fa-snowflake', - text: user.isSuspended ? i18n.locale.unsuspend : i18n.locale.suspend, - action: toggleSuspend - }]); - } - } - - if ($i && meId === user.id) { - menu = menu.concat([null, { - icon: 'fas fa-pencil-alt', - text: i18n.locale.editProfile, - action: () => { - router.push('/settings/profile'); - } - }]); - } - - if (userActions.length > 0) { - menu = menu.concat([null, ...userActions.map(action => ({ - icon: 'fas fa-plug', - text: action.title, - action: () => { - action.handler(user); - } - }))]); - } - - return menu; -} diff --git a/src/client/scripts/hpml/evaluator.ts b/src/client/scripts/hpml/evaluator.ts deleted file mode 100644 index 68d140ff5..000000000 --- a/src/client/scripts/hpml/evaluator.ts +++ /dev/null @@ -1,234 +0,0 @@ -import autobind from 'autobind-decorator'; -import { PageVar, envVarsDef, Fn, HpmlScope, HpmlError } from '.'; -import { version } from '@client/config'; -import { AiScript, utils, values } from '@syuilo/aiscript'; -import { createAiScriptEnv } from '../aiscript/api'; -import { collectPageVars } from '../collect-page-vars'; -import { initHpmlLib, initAiLib } from './lib'; -import * as os from '@client/os'; -import { markRaw, ref, Ref, unref } from 'vue'; -import { Expr, isLiteralValue, Variable } from './expr'; - -/** - * Hpml evaluator - */ -export class Hpml { - private variables: Variable[]; - private pageVars: PageVar[]; - private envVars: Record; - public aiscript?: AiScript; - public pageVarUpdatedCallback?: values.VFn; - public canvases: Record = {}; - public vars: Ref> = ref({}); - public page: Record; - - private opts: { - randomSeed: string; visitor?: any; url?: string; - enableAiScript: boolean; - }; - - constructor(page: Hpml['page'], opts: Hpml['opts']) { - this.page = page; - this.variables = this.page.variables; - this.pageVars = collectPageVars(this.page.content); - this.opts = opts; - - if (this.opts.enableAiScript) { - this.aiscript = markRaw(new AiScript({ ...createAiScriptEnv({ - storageKey: 'pages:' + this.page.id - }), ...initAiLib(this)}, { - in: (q) => { - return new Promise(ok => { - os.dialog({ - title: q, - input: {} - }).then(({ canceled, result: a }) => { - ok(a); - }); - }); - }, - out: (value) => { - console.log(value); - }, - log: (type, params) => { - }, - })); - - this.aiscript.scope.opts.onUpdated = (name, value) => { - this.eval(); - }; - } - - const date = new Date(); - - this.envVars = { - AI: 'kawaii', - VERSION: version, - URL: this.page ? `${opts.url}/@${this.page.user.username}/pages/${this.page.name}` : '', - LOGIN: opts.visitor != null, - NAME: opts.visitor ? opts.visitor.name || opts.visitor.username : '', - USERNAME: opts.visitor ? opts.visitor.username : '', - USERID: opts.visitor ? opts.visitor.id : '', - NOTES_COUNT: opts.visitor ? opts.visitor.notesCount : 0, - FOLLOWERS_COUNT: opts.visitor ? opts.visitor.followersCount : 0, - FOLLOWING_COUNT: opts.visitor ? opts.visitor.followingCount : 0, - IS_CAT: opts.visitor ? opts.visitor.isCat : false, - SEED: opts.randomSeed ? opts.randomSeed : '', - YMD: `${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate()}`, - AISCRIPT_DISABLED: !this.opts.enableAiScript, - NULL: null - }; - - this.eval(); - } - - @autobind - public eval() { - try { - this.vars.value = this.evaluateVars(); - } catch (e) { - //this.onError(e); - } - } - - @autobind - public interpolate(str: string) { - if (str == null) return null; - return str.replace(/{(.+?)}/g, match => { - const v = unref(this.vars)[match.slice(1, -1).trim()]; - return v == null ? 'NULL' : v.toString(); - }); - } - - @autobind - public callAiScript(fn: string) { - try { - if (this.aiscript) this.aiscript.execFn(this.aiscript.scope.get(fn), []); - } catch (e) {} - } - - @autobind - public registerCanvas(id: string, canvas: any) { - this.canvases[id] = canvas; - } - - @autobind - public updatePageVar(name: string, value: any) { - const pageVar = this.pageVars.find(v => v.name === name); - if (pageVar !== undefined) { - pageVar.value = value; - if (this.pageVarUpdatedCallback) { - if (this.aiscript) this.aiscript.execFn(this.pageVarUpdatedCallback, [values.STR(name), utils.jsToVal(value)]); - } - } else { - throw new HpmlError(`No such page var '${name}'`); - } - } - - @autobind - public updateRandomSeed(seed: string) { - this.opts.randomSeed = seed; - this.envVars.SEED = seed; - } - - @autobind - private _interpolateScope(str: string, scope: HpmlScope) { - return str.replace(/{(.+?)}/g, match => { - const v = scope.getState(match.slice(1, -1).trim()); - return v == null ? 'NULL' : v.toString(); - }); - } - - @autobind - public evaluateVars(): Record { - const values: Record = {}; - - for (const [k, v] of Object.entries(this.envVars)) { - values[k] = v; - } - - for (const v of this.pageVars) { - values[v.name] = v.value; - } - - for (const v of this.variables) { - values[v.name] = this.evaluate(v, new HpmlScope([values])); - } - - return values; - } - - @autobind - private evaluate(expr: Expr, scope: HpmlScope): any { - - if (isLiteralValue(expr)) { - if (expr.type === null) { - return null; - } - - if (expr.type === 'number') { - return parseInt((expr.value as any), 10); - } - - if (expr.type === 'text' || expr.type === 'multiLineText') { - return this._interpolateScope(expr.value || '', scope); - } - - if (expr.type === 'textList') { - return this._interpolateScope(expr.value || '', scope).trim().split('\n'); - } - - if (expr.type === 'ref') { - return scope.getState(expr.value); - } - - if (expr.type === 'aiScriptVar') { - if (this.aiscript) { - try { - return utils.valToJs(this.aiscript.scope.get(expr.value)); - } catch (e) { - return null; - } - } else { - return null; - } - } - - // Define user function - if (expr.type == 'fn') { - return { - slots: expr.value.slots.map(x => x.name), - exec: (slotArg: Record) => { - return this.evaluate(expr.value.expression, scope.createChildScope(slotArg, expr.id)); - } - } as Fn; - } - return; - } - - // Call user function - if (expr.type.startsWith('fn:')) { - const fnName = expr.type.split(':')[1]; - const fn = scope.getState(fnName); - const args = {} as Record; - for (let i = 0; i < fn.slots.length; i++) { - const name = fn.slots[i]; - args[name] = this.evaluate(expr.args[i], scope); - } - return fn.exec(args); - } - - if (expr.args === undefined) return null; - - const funcs = initHpmlLib(expr, scope, this.opts.randomSeed, this.opts.visitor); - - // Call function - const fnName = expr.type; - const fn = (funcs as any)[fnName]; - if (fn == null) { - throw new HpmlError(`No such function '${fnName}'`); - } else { - return fn(...expr.args.map(x => this.evaluate(x, scope))); - } - } -} diff --git a/src/client/scripts/initialize-sw.ts b/src/client/scripts/initialize-sw.ts deleted file mode 100644 index 6f1874572..000000000 --- a/src/client/scripts/initialize-sw.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { instance } from '@client/instance'; -import { $i } from '@client/account'; -import { api } from '@client/os'; -import { lang } from '@client/config'; - -export async function initializeSw() { - if (instance.swPublickey && - ('serviceWorker' in navigator) && - ('PushManager' in window) && - $i && $i.token) { - navigator.serviceWorker.register(`/sw.js`); - - navigator.serviceWorker.ready.then(registration => { - registration.active?.postMessage({ - msg: 'initialize', - lang, - }); - // SEE: https://developer.mozilla.org/en-US/docs/Web/API/PushManager/subscribe#Parameters - registration.pushManager.subscribe({ - userVisibleOnly: true, - applicationServerKey: urlBase64ToUint8Array(instance.swPublickey) - }).then(subscription => { - function encode(buffer: ArrayBuffer | null) { - return btoa(String.fromCharCode.apply(null, new Uint8Array(buffer))); - } - - // Register - api('sw/register', { - endpoint: subscription.endpoint, - auth: encode(subscription.getKey('auth')), - publickey: encode(subscription.getKey('p256dh')) - }); - }) - // When subscribe failed - .catch(async (err: Error) => { - // 通知が許可されていなかったとき - if (err.name === 'NotAllowedError') { - return; - } - - // 違うapplicationServerKey (または gcm_sender_id)のサブスクリプションが - // 既に存在していることが原因でエラーになった可能性があるので、 - // そのサブスクリプションを解除しておく - const subscription = await registration.pushManager.getSubscription(); - if (subscription) subscription.unsubscribe(); - }); - }); - } -} - -/** - * Convert the URL safe base64 string to a Uint8Array - * @param base64String base64 string - */ -function urlBase64ToUint8Array(base64String: string): Uint8Array { - const padding = '='.repeat((4 - base64String.length % 4) % 4); - const base64 = (base64String + padding) - .replace(/-/g, '+') - .replace(/_/g, '/'); - - const rawData = window.atob(base64); - const outputArray = new Uint8Array(rawData.length); - - for (let i = 0; i < rawData.length; ++i) { - outputArray[i] = rawData.charCodeAt(i); - } - return outputArray; -} diff --git a/src/client/scripts/lookup-user.ts b/src/client/scripts/lookup-user.ts deleted file mode 100644 index c393472ae..000000000 --- a/src/client/scripts/lookup-user.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { parseAcct } from '@/misc/acct'; -import { i18n } from '@client/i18n'; -import * as os from '@client/os'; - -export async function lookupUser() { - const { canceled, result } = await os.dialog({ - title: i18n.locale.usernameOrUserId, - input: true - }); - if (canceled) return; - - const show = (user) => { - os.pageWindow(`/user-info/${user.id}`); - }; - - const usernamePromise = os.api('users/show', parseAcct(result)); - const idPromise = os.api('users/show', { userId: result }); - let _notFound = false; - const notFound = () => { - if (_notFound) { - os.dialog({ - type: 'error', - text: i18n.locale.noSuchUser - }); - } else { - _notFound = true; - } - }; - usernamePromise.then(show).catch(e => { - if (e.code === 'NO_SUCH_USER') { - notFound(); - } - }); - idPromise.then(show).catch(e => { - notFound(); - }); -} diff --git a/src/client/scripts/paging.ts b/src/client/scripts/paging.ts deleted file mode 100644 index 1da518efa..000000000 --- a/src/client/scripts/paging.ts +++ /dev/null @@ -1,246 +0,0 @@ -import { markRaw } from 'vue'; -import * as os from '@client/os'; -import { onScrollTop, isTopVisible, getScrollPosition, getScrollContainer } from './scroll'; - -const SECOND_FETCH_LIMIT = 30; - -// reversed: items 配列の中身を逆順にする(新しい方が最後) - -export default (opts) => ({ - emits: ['queue'], - - data() { - return { - items: [], - queue: [], - offset: 0, - fetching: true, - moreFetching: false, - inited: false, - more: false, - backed: false, // 遡り中か否か - isBackTop: false, - }; - }, - - computed: { - empty(): boolean { - return this.items.length === 0 && !this.fetching && this.inited; - }, - - error(): boolean { - return !this.fetching && !this.inited; - }, - }, - - watch: { - pagination: { - handler() { - this.init(); - }, - deep: true - }, - - queue: { - handler(a, b) { - if (a.length === 0 && b.length === 0) return; - this.$emit('queue', this.queue.length); - }, - deep: true - } - }, - - created() { - opts.displayLimit = opts.displayLimit || 30; - this.init(); - }, - - activated() { - this.isBackTop = false; - }, - - deactivated() { - this.isBackTop = window.scrollY === 0; - }, - - methods: { - reload() { - this.items = []; - this.init(); - }, - - replaceItem(finder, data) { - const i = this.items.findIndex(finder); - this.items[i] = data; - }, - - removeItem(finder) { - const i = this.items.findIndex(finder); - this.items.splice(i, 1); - }, - - async init() { - this.queue = []; - this.fetching = true; - if (opts.before) opts.before(this); - let params = typeof this.pagination.params === 'function' ? this.pagination.params(true) : this.pagination.params; - if (params && params.then) params = await params; - if (params === null) return; - const endpoint = typeof this.pagination.endpoint === 'function' ? this.pagination.endpoint() : this.pagination.endpoint; - await os.api(endpoint, { - ...params, - limit: this.pagination.noPaging ? (this.pagination.limit || 10) : (this.pagination.limit || 10) + 1, - }).then(items => { - for (let i = 0; i < items.length; i++) { - const item = items[i]; - markRaw(item); - if (this.pagination.reversed) { - if (i === items.length - 2) item._shouldInsertAd_ = true; - } else { - if (i === 3) item._shouldInsertAd_ = true; - } - } - if (!this.pagination.noPaging && (items.length > (this.pagination.limit || 10))) { - items.pop(); - this.items = this.pagination.reversed ? [...items].reverse() : items; - this.more = true; - } else { - this.items = this.pagination.reversed ? [...items].reverse() : items; - this.more = false; - } - this.offset = items.length; - this.inited = true; - this.fetching = false; - if (opts.after) opts.after(this, null); - }, e => { - this.fetching = false; - if (opts.after) opts.after(this, e); - }); - }, - - async fetchMore() { - if (!this.more || this.fetching || this.moreFetching || this.items.length === 0) return; - this.moreFetching = true; - this.backed = true; - let params = typeof this.pagination.params === 'function' ? this.pagination.params(false) : this.pagination.params; - if (params && params.then) params = await params; - const endpoint = typeof this.pagination.endpoint === 'function' ? this.pagination.endpoint() : this.pagination.endpoint; - await os.api(endpoint, { - ...params, - limit: SECOND_FETCH_LIMIT + 1, - ...(this.pagination.offsetMode ? { - offset: this.offset, - } : { - untilId: this.pagination.reversed ? this.items[0].id : this.items[this.items.length - 1].id, - }), - }).then(items => { - for (let i = 0; i < items.length; i++) { - const item = items[i]; - markRaw(item); - if (this.pagination.reversed) { - if (i === items.length - 9) item._shouldInsertAd_ = true; - } else { - if (i === 10) item._shouldInsertAd_ = true; - } - } - if (items.length > SECOND_FETCH_LIMIT) { - items.pop(); - this.items = this.pagination.reversed ? [...items].reverse().concat(this.items) : this.items.concat(items); - this.more = true; - } else { - this.items = this.pagination.reversed ? [...items].reverse().concat(this.items) : this.items.concat(items); - this.more = false; - } - this.offset += items.length; - this.moreFetching = false; - }, e => { - this.moreFetching = false; - }); - }, - - async fetchMoreFeature() { - if (!this.more || this.fetching || this.moreFetching || this.items.length === 0) return; - this.moreFetching = true; - let params = typeof this.pagination.params === 'function' ? this.pagination.params(false) : this.pagination.params; - if (params && params.then) params = await params; - const endpoint = typeof this.pagination.endpoint === 'function' ? this.pagination.endpoint() : this.pagination.endpoint; - await os.api(endpoint, { - ...params, - limit: SECOND_FETCH_LIMIT + 1, - ...(this.pagination.offsetMode ? { - offset: this.offset, - } : { - sinceId: this.pagination.reversed ? this.items[0].id : this.items[this.items.length - 1].id, - }), - }).then(items => { - for (const item of items) { - markRaw(item); - } - if (items.length > SECOND_FETCH_LIMIT) { - items.pop(); - this.items = this.pagination.reversed ? [...items].reverse().concat(this.items) : this.items.concat(items); - this.more = true; - } else { - this.items = this.pagination.reversed ? [...items].reverse().concat(this.items) : this.items.concat(items); - this.more = false; - } - this.offset += items.length; - this.moreFetching = false; - }, e => { - this.moreFetching = false; - }); - }, - - prepend(item) { - if (this.pagination.reversed) { - const container = getScrollContainer(this.$el); - const pos = getScrollPosition(this.$el); - const viewHeight = container.clientHeight; - const height = container.scrollHeight; - const isBottom = (pos + viewHeight > height - 32); - if (isBottom) { - // オーバーフローしたら古いアイテムは捨てる - if (this.items.length >= opts.displayLimit) { - // このやり方だとVue 3.2以降アニメーションが動かなくなる - //this.items = this.items.slice(-opts.displayLimit); - while (this.items.length >= opts.displayLimit) { - this.items.shift(); - } - this.more = true; - } - } - this.items.push(item); - // TODO - } else { - const isTop = this.isBackTop || (document.body.contains(this.$el) && isTopVisible(this.$el)); - - if (isTop) { - // Prepend the item - this.items.unshift(item); - - // オーバーフローしたら古いアイテムは捨てる - if (this.items.length >= opts.displayLimit) { - // このやり方だとVue 3.2以降アニメーションが動かなくなる - //this.items = this.items.slice(0, opts.displayLimit); - while (this.items.length >= opts.displayLimit) { - this.items.pop(); - } - this.more = true; - } - } else { - this.queue.push(item); - onScrollTop(this.$el, () => { - for (const item of this.queue) { - this.prepend(item); - } - this.queue = []; - }); - } - } - }, - - append(item) { - this.items.push(item); - }, - } -}); diff --git a/src/client/scripts/please-login.ts b/src/client/scripts/please-login.ts deleted file mode 100644 index a584e9fa9..000000000 --- a/src/client/scripts/please-login.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { $i } from '@client/account'; -import { i18n } from '@client/i18n'; -import { dialog } from '@client/os'; - -export function pleaseLogin() { - if ($i) return; - - dialog({ - title: i18n.locale.signinRequired, - text: null - }); - - throw new Error('signin required'); -} diff --git a/src/client/scripts/popout.ts b/src/client/scripts/popout.ts deleted file mode 100644 index 6d92af4a0..000000000 --- a/src/client/scripts/popout.ts +++ /dev/null @@ -1,22 +0,0 @@ -import * as config from '@client/config'; - -export function popout(path: string, w?: HTMLElement) { - let url = path.startsWith('http://') || path.startsWith('https://') ? path : config.url + path; - url += '?zen'; // TODO: ちゃんとURLパースしてクエリ付ける - if (w) { - const position = w.getBoundingClientRect(); - const width = parseInt(getComputedStyle(w, '').width, 10); - const height = parseInt(getComputedStyle(w, '').height, 10); - const x = window.screenX + position.left; - const y = window.screenY + position.top; - window.open(url, url, - `width=${width}, height=${height}, top=${y}, left=${x}`); - } else { - const width = 400; - const height = 500; - const x = window.top.outerHeight / 2 + window.top.screenY - (height / 2); - const y = window.top.outerWidth / 2 + window.top.screenX - (width / 2); - window.open(url, url, - `width=${width}, height=${height}, top=${x}, left=${y}`); - } -} diff --git a/src/client/scripts/reaction-picker.ts b/src/client/scripts/reaction-picker.ts deleted file mode 100644 index 38699c097..000000000 --- a/src/client/scripts/reaction-picker.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { Ref, ref } from 'vue'; -import { popup } from '@client/os'; - -class ReactionPicker { - private src: Ref = ref(null); - private manualShowing = ref(false); - private onChosen?: Function; - private onClosed?: Function; - - constructor() { - // nop - } - - public async init() { - await popup(import('@client/components/emoji-picker-dialog.vue'), { - src: this.src, - asReactionPicker: true, - manualShowing: this.manualShowing - }, { - done: reaction => { - this.onChosen!(reaction); - }, - close: () => { - this.manualShowing.value = false; - }, - closed: () => { - this.src.value = null; - this.onClosed!(); - } - }); - } - - public show(src: HTMLElement, onChosen: Function, onClosed: Function) { - this.src.value = src; - this.manualShowing.value = true; - this.onChosen = onChosen; - this.onClosed = onClosed; - } -} - -export const reactionPicker = new ReactionPicker(); diff --git a/src/client/scripts/room/room.ts b/src/client/scripts/room/room.ts deleted file mode 100644 index 4450210c6..000000000 --- a/src/client/scripts/room/room.ts +++ /dev/null @@ -1,775 +0,0 @@ -import autobind from 'autobind-decorator'; -import { v4 as uuid } from 'uuid'; -import * as THREE from 'three'; -import { GLTFLoader, GLTF } from 'three/examples/jsm/loaders/GLTFLoader'; -import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'; -import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js'; -import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js'; -import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js'; -import { BloomPass } from 'three/examples/jsm/postprocessing/BloomPass.js'; -import { FXAAShader } from 'three/examples/jsm/shaders/FXAAShader.js'; -import { TransformControls } from 'three/examples/jsm/controls/TransformControls.js'; -import { Furniture, RoomInfo } from './furniture'; -import { query as urlQuery } from '../../../prelude/url'; -const furnitureDefs = require('./furnitures.json5'); - -THREE.ImageUtils.crossOrigin = ''; - -type Options = { - graphicsQuality: Room['graphicsQuality']; - onChangeSelect: Room['onChangeSelect']; - useOrthographicCamera: boolean; -}; - -/** - * MisskeyRoom Core Engine - */ -export class Room { - private clock: THREE.Clock; - private scene: THREE.Scene; - private renderer: THREE.WebGLRenderer; - private camera: THREE.PerspectiveCamera | THREE.OrthographicCamera; - private controls: OrbitControls; - private composer: EffectComposer; - private mixers: THREE.AnimationMixer[] = []; - private furnitureControl: TransformControls; - private roomInfo: RoomInfo; - private graphicsQuality: 'cheep' | 'low' | 'medium' | 'high' | 'ultra'; - private roomObj: THREE.Object3D; - private objects: THREE.Object3D[] = []; - private selectedObject: THREE.Object3D = null; - private onChangeSelect: Function; - private isTransformMode = false; - private renderFrameRequestId: number; - - private get canvas(): HTMLCanvasElement { - return this.renderer.domElement; - } - - private get furnitures(): Furniture[] { - return this.roomInfo.furnitures; - } - - private set furnitures(furnitures: Furniture[]) { - this.roomInfo.furnitures = furnitures; - } - - private get enableShadow() { - return this.graphicsQuality != 'cheep'; - } - - private get usePostFXs() { - return this.graphicsQuality !== 'cheep' && this.graphicsQuality !== 'low'; - } - - private get shadowQuality() { - return ( - this.graphicsQuality === 'ultra' ? 16384 : - this.graphicsQuality === 'high' ? 8192 : - this.graphicsQuality === 'medium' ? 4096 : - this.graphicsQuality === 'low' ? 1024 : - 0); // cheep - } - - constructor(user, isMyRoom, roomInfo: RoomInfo, container: Element, options: Options) { - this.roomInfo = roomInfo; - this.graphicsQuality = options.graphicsQuality; - this.onChangeSelect = options.onChangeSelect; - - this.clock = new THREE.Clock(true); - - //#region Init a scene - this.scene = new THREE.Scene(); - - const width = container.clientWidth; - const height = container.clientHeight; - - //#region Init a renderer - this.renderer = new THREE.WebGLRenderer({ - antialias: false, - stencil: false, - alpha: false, - powerPreference: - this.graphicsQuality === 'ultra' ? 'high-performance' : - this.graphicsQuality === 'high' ? 'high-performance' : - this.graphicsQuality === 'medium' ? 'default' : - this.graphicsQuality === 'low' ? 'low-power' : - 'low-power' // cheep - }); - - this.renderer.setPixelRatio(window.devicePixelRatio); - this.renderer.setSize(width, height); - this.renderer.autoClear = false; - this.renderer.setClearColor(new THREE.Color(0x051f2d)); - this.renderer.shadowMap.enabled = this.enableShadow; - this.renderer.shadowMap.type = - this.graphicsQuality === 'ultra' ? THREE.PCFSoftShadowMap : - this.graphicsQuality === 'high' ? THREE.PCFSoftShadowMap : - this.graphicsQuality === 'medium' ? THREE.PCFShadowMap : - this.graphicsQuality === 'low' ? THREE.BasicShadowMap : - THREE.BasicShadowMap; // cheep - - container.insertBefore(this.canvas, container.firstChild); - //#endregion - - //#region Init a camera - this.camera = options.useOrthographicCamera - ? new THREE.OrthographicCamera( - width / - 2, width / 2, height / 2, height / - 2, -10, 10) - : new THREE.PerspectiveCamera(45, width / height); - - if (options.useOrthographicCamera) { - this.camera.position.x = 2; - this.camera.position.y = 2; - this.camera.position.z = 2; - this.camera.zoom = 100; - this.camera.updateProjectionMatrix(); - } else { - this.camera.position.x = 5; - this.camera.position.y = 2; - this.camera.position.z = 5; - } - - this.scene.add(this.camera); - //#endregion - - //#region AmbientLight - const ambientLight = new THREE.AmbientLight(0xffffff, 1); - this.scene.add(ambientLight); - //#endregion - - if (this.graphicsQuality !== 'cheep') { - //#region Room light - const roomLight = new THREE.SpotLight(0xffffff, 0.1); - - roomLight.position.set(0, 8, 0); - roomLight.castShadow = this.enableShadow; - roomLight.shadow.bias = -0.0001; - roomLight.shadow.mapSize.width = this.shadowQuality; - roomLight.shadow.mapSize.height = this.shadowQuality; - roomLight.shadow.camera.near = 0.1; - roomLight.shadow.camera.far = 9; - roomLight.shadow.camera.fov = 45; - - this.scene.add(roomLight); - //#endregion - } - - //#region Out light - const outLight1 = new THREE.SpotLight(0xffffff, 0.4); - outLight1.position.set(9, 3, -2); - outLight1.castShadow = this.enableShadow; - outLight1.shadow.bias = -0.001; // アクネ、アーチファクト対策 その代わりピーターパンが発生する可能性がある - outLight1.shadow.mapSize.width = this.shadowQuality; - outLight1.shadow.mapSize.height = this.shadowQuality; - outLight1.shadow.camera.near = 6; - outLight1.shadow.camera.far = 15; - outLight1.shadow.camera.fov = 45; - this.scene.add(outLight1); - - const outLight2 = new THREE.SpotLight(0xffffff, 0.2); - outLight2.position.set(-2, 3, 9); - outLight2.castShadow = false; - outLight2.shadow.bias = -0.001; // アクネ、アーチファクト対策 その代わりピーターパンが発生する可能性がある - outLight2.shadow.camera.near = 6; - outLight2.shadow.camera.far = 15; - outLight2.shadow.camera.fov = 45; - this.scene.add(outLight2); - //#endregion - - //#region Init a controller - this.controls = new OrbitControls(this.camera, this.canvas); - - this.controls.target.set(0, 1, 0); - this.controls.enableZoom = true; - this.controls.enablePan = isMyRoom; - this.controls.minPolarAngle = 0; - this.controls.maxPolarAngle = Math.PI / 2; - this.controls.minAzimuthAngle = 0; - this.controls.maxAzimuthAngle = Math.PI / 2; - this.controls.enableDamping = true; - this.controls.dampingFactor = 0.2; - //#endregion - - //#region POST FXs - if (!this.usePostFXs) { - this.composer = null; - } else { - const renderTarget = new THREE.WebGLRenderTarget(width, height, { - minFilter: THREE.LinearFilter, - magFilter: THREE.LinearFilter, - format: THREE.RGBFormat, - stencilBuffer: false, - }); - - const fxaa = new ShaderPass(FXAAShader); - fxaa.uniforms['resolution'].value = new THREE.Vector2(1 / width, 1 / height); - fxaa.renderToScreen = true; - - this.composer = new EffectComposer(this.renderer, renderTarget); - this.composer.addPass(new RenderPass(this.scene, this.camera)); - if (this.graphicsQuality === 'ultra') { - this.composer.addPass(new BloomPass(0.25, 30, 128.0, 512)); - } - this.composer.addPass(fxaa); - } - //#endregion - //#endregion - - //#region Label - //#region Avatar - const avatarUrl = `/proxy/?${urlQuery({ url: user.avatarUrl })}`; - - const textureLoader = new THREE.TextureLoader(); - textureLoader.crossOrigin = 'anonymous'; - - const iconTexture = textureLoader.load(avatarUrl); - iconTexture.wrapS = THREE.RepeatWrapping; - iconTexture.wrapT = THREE.RepeatWrapping; - iconTexture.anisotropy = 16; - - const avatarMaterial = new THREE.MeshBasicMaterial({ - map: iconTexture, - side: THREE.DoubleSide, - alphaTest: 0.5 - }); - - const iconGeometry = new THREE.PlaneGeometry(1, 1); - - const avatarObject = new THREE.Mesh(iconGeometry, avatarMaterial); - avatarObject.position.set(-3, 2.5, 2); - avatarObject.rotation.y = Math.PI / 2; - avatarObject.castShadow = false; - - this.scene.add(avatarObject); - //#endregion - - //#region Username - const name = user.username; - - new THREE.FontLoader().load('/assets/fonts/helvetiker_regular.typeface.json', font => { - const nameGeometry = new THREE.TextGeometry(name, { - size: 0.5, - height: 0, - curveSegments: 8, - font: font, - bevelThickness: 0, - bevelSize: 0, - bevelEnabled: false - }); - - const nameMaterial = new THREE.MeshLambertMaterial({ - color: 0xffffff - }); - - const nameObject = new THREE.Mesh(nameGeometry, nameMaterial); - nameObject.position.set(-3, 2.25, 1.25); - nameObject.rotation.y = Math.PI / 2; - nameObject.castShadow = false; - - this.scene.add(nameObject); - }); - //#endregion - //#endregion - - //#region Interaction - if (isMyRoom) { - this.furnitureControl = new TransformControls(this.camera, this.canvas); - this.scene.add(this.furnitureControl); - - // Hover highlight - this.canvas.onmousemove = this.onmousemove; - - // Click - this.canvas.onmousedown = this.onmousedown; - } - //#endregion - - //#region Init room - this.loadRoom(); - //#endregion - - //#region Load furnitures - for (const furniture of this.furnitures) { - this.loadFurniture(furniture).then(obj => { - this.scene.add(obj.scene); - this.objects.push(obj.scene); - }); - } - //#endregion - - // Start render - if (this.usePostFXs) { - this.renderWithPostFXs(); - } else { - this.renderWithoutPostFXs(); - } - } - - @autobind - private renderWithoutPostFXs() { - this.renderFrameRequestId = - window.requestAnimationFrame(this.renderWithoutPostFXs); - - // Update animations - const clock = this.clock.getDelta(); - for (const mixer of this.mixers) { - mixer.update(clock); - } - - this.controls.update(); - this.renderer.render(this.scene, this.camera); - } - - @autobind - private renderWithPostFXs() { - this.renderFrameRequestId = - window.requestAnimationFrame(this.renderWithPostFXs); - - // Update animations - const clock = this.clock.getDelta(); - for (const mixer of this.mixers) { - mixer.update(clock); - } - - this.controls.update(); - this.renderer.clear(); - this.composer.render(); - } - - @autobind - private loadRoom() { - const type = this.roomInfo.roomType; - new GLTFLoader().load(`/static-assets/client/room/rooms/${type}/${type}.glb`, gltf => { - gltf.scene.traverse(child => { - if (!(child instanceof THREE.Mesh)) return; - - child.receiveShadow = this.enableShadow; - - child.material = new THREE.MeshLambertMaterial({ - color: (child.material as THREE.MeshStandardMaterial).color, - map: (child.material as THREE.MeshStandardMaterial).map, - name: (child.material as THREE.MeshStandardMaterial).name, - }); - - // 異方性フィルタリング - if ((child.material as THREE.MeshLambertMaterial).map && this.graphicsQuality !== 'cheep') { - (child.material as THREE.MeshLambertMaterial).map.minFilter = THREE.LinearMipMapLinearFilter; - (child.material as THREE.MeshLambertMaterial).map.magFilter = THREE.LinearMipMapLinearFilter; - (child.material as THREE.MeshLambertMaterial).map.anisotropy = 8; - } - }); - - gltf.scene.position.set(0, 0, 0); - - this.scene.add(gltf.scene); - this.roomObj = gltf.scene; - if (this.roomInfo.roomType === 'default') { - this.applyCarpetColor(); - } - }); - } - - @autobind - private loadFurniture(furniture: Furniture) { - const def = furnitureDefs.find(d => d.id === furniture.type); - return new Promise((res, rej) => { - const loader = new GLTFLoader(); - loader.load(`/static-assets/client/room/furnitures/${furniture.type}/${furniture.type}.glb`, gltf => { - const model = gltf.scene; - - // Load animation - if (gltf.animations.length > 0) { - const mixer = new THREE.AnimationMixer(model); - this.mixers.push(mixer); - for (const clip of gltf.animations) { - mixer.clipAction(clip).play(); - } - } - - model.name = furniture.id; - model.position.x = furniture.position.x; - model.position.y = furniture.position.y; - model.position.z = furniture.position.z; - model.rotation.x = furniture.rotation.x; - model.rotation.y = furniture.rotation.y; - model.rotation.z = furniture.rotation.z; - - model.traverse(child => { - if (!(child instanceof THREE.Mesh)) return; - child.castShadow = this.enableShadow; - child.receiveShadow = this.enableShadow; - (child.material as THREE.MeshStandardMaterial).metalness = 0; - - // 異方性フィルタリング - if ((child.material as THREE.MeshStandardMaterial).map && this.graphicsQuality !== 'cheep') { - (child.material as THREE.MeshStandardMaterial).map.minFilter = THREE.LinearMipMapLinearFilter; - (child.material as THREE.MeshStandardMaterial).map.magFilter = THREE.LinearMipMapLinearFilter; - (child.material as THREE.MeshStandardMaterial).map.anisotropy = 8; - } - }); - - if (def.color) { // カスタムカラー - this.applyCustomColor(model); - } - - if (def.texture) { // カスタムテクスチャ - this.applyCustomTexture(model); - } - - res(gltf); - }, null, rej); - }); - } - - @autobind - private applyCarpetColor() { - this.roomObj.traverse(child => { - if (!(child instanceof THREE.Mesh)) return; - if (child.material && - (child.material as THREE.MeshStandardMaterial).name && - (child.material as THREE.MeshStandardMaterial).name === 'Carpet' - ) { - const colorHex = parseInt(this.roomInfo.carpetColor.substr(1), 16); - (child.material as THREE.MeshStandardMaterial).color.setHex(colorHex); - } - }); - } - - @autobind - private applyCustomColor(model: THREE.Object3D) { - const furniture = this.furnitures.find(furniture => furniture.id === model.name); - const def = furnitureDefs.find(d => d.id === furniture.type); - if (def.color == null) return; - model.traverse(child => { - if (!(child instanceof THREE.Mesh)) return; - for (const t of Object.keys(def.color)) { - if (!child.material || - !(child.material as THREE.MeshStandardMaterial).name || - (child.material as THREE.MeshStandardMaterial).name !== t - ) continue; - - const prop = def.color[t]; - const val = furniture.props ? furniture.props[prop] : undefined; - - if (val == null) continue; - - const colorHex = parseInt(val.substr(1), 16); - (child.material as THREE.MeshStandardMaterial).color.setHex(colorHex); - } - }); - } - - @autobind - private applyCustomTexture(model: THREE.Object3D) { - const furniture = this.furnitures.find(furniture => furniture.id === model.name); - const def = furnitureDefs.find(d => d.id === furniture.type); - if (def.texture == null) return; - - model.traverse(child => { - if (!(child instanceof THREE.Mesh)) return; - for (const t of Object.keys(def.texture)) { - if (child.name !== t) continue; - - const prop = def.texture[t].prop; - const val = furniture.props ? furniture.props[prop] : undefined; - - if (val == null) continue; - - const canvas = document.createElement('canvas'); - canvas.height = 1024; - canvas.width = 1024; - - child.material = new THREE.MeshLambertMaterial({ - emissive: 0x111111, - side: THREE.DoubleSide, - alphaTest: 0.5, - }); - - const img = new Image(); - img.crossOrigin = 'anonymous'; - img.onload = () => { - const uvInfo = def.texture[t].uv; - - const ctx = canvas.getContext('2d'); - ctx.drawImage(img, - 0, 0, img.width, img.height, - uvInfo.x, uvInfo.y, uvInfo.width, uvInfo.height); - - const texture = new THREE.Texture(canvas); - texture.wrapS = THREE.RepeatWrapping; - texture.wrapT = THREE.RepeatWrapping; - texture.anisotropy = 16; - texture.flipY = false; - - (child.material as THREE.MeshLambertMaterial).map = texture; - (child.material as THREE.MeshLambertMaterial).needsUpdate = true; - (child.material as THREE.MeshLambertMaterial).map.needsUpdate = true; - }; - img.src = val; - } - }); - } - - @autobind - private onmousemove(ev: MouseEvent) { - if (this.isTransformMode) return; - - const rect = (ev.target as HTMLElement).getBoundingClientRect(); - const x = ((ev.clientX - rect.left) / rect.width) * 2 - 1; - const y = -((ev.clientY - rect.top) / rect.height) * 2 + 1; - const pos = new THREE.Vector2(x, y); - - this.camera.updateMatrixWorld(); - - const raycaster = new THREE.Raycaster(); - raycaster.setFromCamera(pos, this.camera); - - const intersects = raycaster.intersectObjects(this.objects, true); - - for (const object of this.objects) { - if (this.isSelectedObject(object)) continue; - object.traverse(child => { - if (child instanceof THREE.Mesh) { - (child.material as THREE.MeshStandardMaterial).emissive.setHex(0x000000); - } - }); - } - - if (intersects.length > 0) { - const intersected = this.getRoot(intersects[0].object); - if (this.isSelectedObject(intersected)) return; - intersected.traverse(child => { - if (child instanceof THREE.Mesh) { - (child.material as THREE.MeshStandardMaterial).emissive.setHex(0x191919); - } - }); - } - } - - @autobind - private onmousedown(ev: MouseEvent) { - if (this.isTransformMode) return; - if (ev.target !== this.canvas || ev.button !== 0) return; - - const rect = (ev.target as HTMLElement).getBoundingClientRect(); - const x = ((ev.clientX - rect.left) / rect.width) * 2 - 1; - const y = -((ev.clientY - rect.top) / rect.height) * 2 + 1; - const pos = new THREE.Vector2(x, y); - - this.camera.updateMatrixWorld(); - - const raycaster = new THREE.Raycaster(); - raycaster.setFromCamera(pos, this.camera); - - const intersects = raycaster.intersectObjects(this.objects, true); - - for (const object of this.objects) { - object.traverse(child => { - if (child instanceof THREE.Mesh) { - (child.material as THREE.MeshStandardMaterial).emissive.setHex(0x000000); - } - }); - } - - if (intersects.length > 0) { - const selectedObj = this.getRoot(intersects[0].object); - this.selectFurniture(selectedObj); - } else { - this.selectedObject = null; - this.onChangeSelect(null); - } - } - - @autobind - private getRoot(obj: THREE.Object3D): THREE.Object3D { - let found = false; - let x = obj.parent; - while (!found) { - if (x.parent.parent == null) { - found = true; - } else { - x = x.parent; - } - } - return x; - } - - @autobind - private isSelectedObject(obj: THREE.Object3D): boolean { - if (this.selectedObject == null) { - return false; - } else { - return obj.name === this.selectedObject.name; - } - } - - @autobind - private selectFurniture(obj: THREE.Object3D) { - this.selectedObject = obj; - this.onChangeSelect(obj); - obj.traverse(child => { - if (child instanceof THREE.Mesh) { - (child.material as THREE.MeshStandardMaterial).emissive.setHex(0xff0000); - } - }); - } - - /** - * 家具の移動/回転モードにします - * @param type 移動か回転か - */ - @autobind - public enterTransformMode(type: 'translate' | 'rotate') { - this.isTransformMode = true; - this.furnitureControl.setMode(type); - this.furnitureControl.attach(this.selectedObject); - this.controls.enableRotate = false; - } - - /** - * 家具の移動/回転モードを終了します - */ - @autobind - public exitTransformMode() { - this.isTransformMode = false; - this.furnitureControl.detach(); - this.controls.enableRotate = true; - } - - /** - * 家具プロパティを更新します - * @param key プロパティ名 - * @param value 値 - */ - @autobind - public updateProp(key: string, value: any) { - const furniture = this.furnitures.find(furniture => furniture.id === this.selectedObject.name); - if (furniture.props == null) furniture.props = {}; - furniture.props[key] = value; - this.applyCustomColor(this.selectedObject); - this.applyCustomTexture(this.selectedObject); - } - - /** - * 部屋に家具を追加します - * @param type 家具の種類 - */ - @autobind - public addFurniture(type: string) { - const furniture = { - id: uuid(), - type: type, - position: { - x: 0, - y: 0, - z: 0, - }, - rotation: { - x: 0, - y: 0, - z: 0, - }, - }; - - this.furnitures.push(furniture); - - this.loadFurniture(furniture).then(obj => { - this.scene.add(obj.scene); - this.objects.push(obj.scene); - }); - } - - /** - * 現在選択されている家具を部屋から削除します - */ - @autobind - public removeFurniture() { - this.exitTransformMode(); - const obj = this.selectedObject; - this.scene.remove(obj); - this.objects = this.objects.filter(object => object.name !== obj.name); - this.furnitures = this.furnitures.filter(furniture => furniture.id !== obj.name); - this.selectedObject = null; - this.onChangeSelect(null); - } - - /** - * 全ての家具を部屋から削除します - */ - @autobind - public removeAllFurnitures() { - this.exitTransformMode(); - for (const obj of this.objects) { - this.scene.remove(obj); - } - this.objects = []; - this.furnitures = []; - this.selectedObject = null; - this.onChangeSelect(null); - } - - /** - * 部屋の床の色を変更します - * @param color 色 - */ - @autobind - public updateCarpetColor(color: string) { - this.roomInfo.carpetColor = color; - this.applyCarpetColor(); - } - - /** - * 部屋の種類を変更します - * @param type 種類 - */ - @autobind - public changeRoomType(type: string) { - this.roomInfo.roomType = type; - this.scene.remove(this.roomObj); - this.loadRoom(); - } - - /** - * 部屋データを取得します - */ - @autobind - public getRoomInfo() { - for (const obj of this.objects) { - const furniture = this.furnitures.find(f => f.id === obj.name); - furniture.position.x = obj.position.x; - furniture.position.y = obj.position.y; - furniture.position.z = obj.position.z; - furniture.rotation.x = obj.rotation.x; - furniture.rotation.y = obj.rotation.y; - furniture.rotation.z = obj.rotation.z; - } - - return this.roomInfo; - } - - /** - * 選択されている家具を取得します - */ - @autobind - public getSelectedObject() { - return this.selectedObject; - } - - @autobind - public findFurnitureById(id: string) { - return this.furnitures.find(furniture => furniture.id === id); - } - - /** - * レンダリングを終了します - */ - @autobind - public destroy() { - // Stop render loop - window.cancelAnimationFrame(this.renderFrameRequestId); - - this.controls.dispose(); - this.scene.dispose(); - } -} diff --git a/src/client/scripts/search.ts b/src/client/scripts/search.ts deleted file mode 100644 index 2221f5f27..000000000 --- a/src/client/scripts/search.ts +++ /dev/null @@ -1,64 +0,0 @@ -import * as os from '@client/os'; -import { i18n } from '@client/i18n'; -import { router } from '@client/router'; - -export async function search() { - const { canceled, result: query } = await os.dialog({ - title: i18n.locale.search, - input: true - }); - if (canceled || query == null || query === '') return; - - const q = query.trim(); - - if (q.startsWith('@') && !q.includes(' ')) { - router.push(`/${q}`); - return; - } - - if (q.startsWith('#')) { - router.push(`/tags/${encodeURIComponent(q.substr(1))}`); - return; - } - - // like 2018/03/12 - if (/^[0-9]{4}\/[0-9]{2}\/[0-9]{2}/.test(q.replace(/-/g, '/'))) { - const date = new Date(q.replace(/-/g, '/')); - - // 日付しか指定されてない場合、例えば 2018/03/12 ならユーザーは - // 2018/03/12 のコンテンツを「含む」結果になることを期待するはずなので - // 23時間59分進める(そのままだと 2018/03/12 00:00:00 「まで」の - // 結果になってしまい、2018/03/12 のコンテンツは含まれない) - if (q.replace(/-/g, '/').match(/^[0-9]{4}\/[0-9]{2}\/[0-9]{2}$/)) { - date.setHours(23, 59, 59, 999); - } - - // TODO - //v.$root.$emit('warp', date); - os.dialog({ - icon: 'fas fa-history', - iconOnly: true, autoClose: true - }); - return; - } - - if (q.startsWith('https://')) { - const promise = os.api('ap/show', { - uri: q - }); - - os.promiseDialog(promise, null, null, i18n.locale.fetchingAsApObject); - - const res = await promise; - - if (res.type === 'User') { - router.push(`/@${res.object.username}@${res.object.host}`); - } else if (res.type === 'Note') { - router.push(`/notes/${res.object.id}`); - } - - return; - } - - router.push(`/search?q=${encodeURIComponent(q)}`); -} diff --git a/src/client/scripts/select-file.ts b/src/client/scripts/select-file.ts deleted file mode 100644 index f7b971e11..000000000 --- a/src/client/scripts/select-file.ts +++ /dev/null @@ -1,89 +0,0 @@ -import * as os from '@client/os'; -import { i18n } from '@client/i18n'; -import { defaultStore } from '@client/store'; - -export function selectFile(src: any, label: string | null, multiple = false) { - return new Promise((res, rej) => { - const chooseFileFromPc = () => { - const input = document.createElement('input'); - input.type = 'file'; - input.multiple = multiple; - input.onchange = () => { - const promises = Array.from(input.files).map(file => os.upload(file, defaultStore.state.uploadFolder)); - - Promise.all(promises).then(driveFiles => { - res(multiple ? driveFiles : driveFiles[0]); - }).catch(e => { - os.dialog({ - type: 'error', - text: e - }); - }); - - // 一応廃棄 - (window as any).__misskey_input_ref__ = null; - }; - - // https://qiita.com/fukasawah/items/b9dc732d95d99551013d - // iOS Safari で正常に動かす為のおまじない - (window as any).__misskey_input_ref__ = input; - - input.click(); - }; - - const chooseFileFromDrive = () => { - os.selectDriveFile(multiple).then(files => { - res(files); - }); - }; - - const chooseFileFromUrl = () => { - os.dialog({ - title: i18n.locale.uploadFromUrl, - input: { - placeholder: i18n.locale.uploadFromUrlDescription - } - }).then(({ canceled, result: url }) => { - if (canceled) return; - - const marker = Math.random().toString(); // TODO: UUIDとか使う - - const connection = os.stream.useChannel('main'); - connection.on('urlUploadFinished', data => { - if (data.marker === marker) { - res(multiple ? [data.file] : data.file); - connection.dispose(); - } - }); - - os.api('drive/files/upload-from-url', { - url: url, - folderId: defaultStore.state.uploadFolder, - marker - }); - - os.dialog({ - title: i18n.locale.uploadFromUrlRequested, - text: i18n.locale.uploadFromUrlMayTakeTime - }); - }); - }; - - os.popupMenu([label ? { - text: label, - type: 'label' - } : undefined, { - text: i18n.locale.upload, - icon: 'fas fa-upload', - action: chooseFileFromPc - }, { - text: i18n.locale.fromDrive, - icon: 'fas fa-cloud', - action: chooseFileFromDrive - }, { - text: i18n.locale.fromUrl, - icon: 'fas fa-link', - action: chooseFileFromUrl - }], src); - }); -} diff --git a/src/client/scripts/show-suspended-dialog.ts b/src/client/scripts/show-suspended-dialog.ts deleted file mode 100644 index dde829cda..000000000 --- a/src/client/scripts/show-suspended-dialog.ts +++ /dev/null @@ -1,10 +0,0 @@ -import * as os from '@client/os'; -import { i18n } from '@client/i18n'; - -export function showSuspendedDialog() { - return os.dialog({ - type: 'error', - title: i18n.locale.yourAccountSuspendedTitle, - text: i18n.locale.yourAccountSuspendedDescription - }); -} diff --git a/src/client/scripts/sound.ts b/src/client/scripts/sound.ts deleted file mode 100644 index c51fa8f21..000000000 --- a/src/client/scripts/sound.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { ColdDeviceStorage } from '@client/store'; - -const cache = new Map(); - -export function getAudio(file: string, useCache = true): HTMLAudioElement { - let audio: HTMLAudioElement; - if (useCache && cache.has(file)) { - audio = cache.get(file); - } else { - audio = new Audio(`/static-assets/client/sounds/${file}.mp3`); - if (useCache) cache.set(file, audio); - } - return audio; -} - -export function setVolume(audio: HTMLAudioElement, volume: number): HTMLAudioElement { - const masterVolume = ColdDeviceStorage.get('sound_masterVolume'); - audio.volume = masterVolume - ((1 - volume) * masterVolume); - return audio; -} - -export function play(type: string) { - const sound = ColdDeviceStorage.get('sound_' + type as any); - if (sound.type == null) return; - playFile(sound.type, sound.volume); -} - -export function playFile(file: string, volume: number) { - const masterVolume = ColdDeviceStorage.get('sound_masterVolume'); - if (masterVolume === 0) return; - - const audio = setVolume(getAudio(file), volume); - audio.play(); -} diff --git a/src/client/scripts/theme.ts b/src/client/scripts/theme.ts deleted file mode 100644 index 8b6382129..000000000 --- a/src/client/scripts/theme.ts +++ /dev/null @@ -1,127 +0,0 @@ -import { globalEvents } from '@client/events'; -import * as tinycolor from 'tinycolor2'; - -export type Theme = { - id: string; - name: string; - author: string; - desc?: string; - base?: 'dark' | 'light'; - props: Record; -}; - -export const lightTheme: Theme = require('@client/themes/_light.json5'); -export const darkTheme: Theme = require('@client/themes/_dark.json5'); - -export const themeProps = Object.keys(lightTheme.props).filter(key => !key.startsWith('X')); - -export const builtinThemes = [ - require('@client/themes/l-light.json5'), - require('@client/themes/l-apricot.json5'), - require('@client/themes/l-rainy.json5'), - require('@client/themes/l-vivid.json5'), - require('@client/themes/l-sushi.json5'), - - require('@client/themes/d-dark.json5'), - require('@client/themes/d-persimmon.json5'), - require('@client/themes/d-astro.json5'), - require('@client/themes/d-future.json5'), - require('@client/themes/d-botanical.json5'), - require('@client/themes/d-pumpkin.json5'), - require('@client/themes/d-black.json5'), -] as Theme[]; - -let timeout = null; - -export function applyTheme(theme: Theme, persist = true) { - if (timeout) clearTimeout(timeout); - - document.documentElement.classList.add('_themeChanging_'); - - timeout = setTimeout(() => { - document.documentElement.classList.remove('_themeChanging_'); - }, 1000); - - // Deep copy - const _theme = JSON.parse(JSON.stringify(theme)); - - if (_theme.base) { - const base = [lightTheme, darkTheme].find(x => x.id === _theme.base); - _theme.props = Object.assign({}, base.props, _theme.props); - } - - const props = compile(_theme); - - for (const tag of document.head.children) { - if (tag.tagName === 'META' && tag.getAttribute('name') === 'theme-color') { - tag.setAttribute('content', props['html']); - break; - } - } - - for (const [k, v] of Object.entries(props)) { - document.documentElement.style.setProperty(`--${k}`, v.toString()); - } - - if (persist) { - localStorage.setItem('theme', JSON.stringify(props)); - } - - // 色計算など再度行えるようにクライアント全体に通知 - globalEvents.emit('themeChanged'); -} - -function compile(theme: Theme): Record { - function getColor(val: string): tinycolor.Instance { - // ref (prop) - if (val[0] === '@') { - return getColor(theme.props[val.substr(1)]); - } - - // ref (const) - else if (val[0] === '$') { - return getColor(theme.props[val]); - } - - // func - else if (val[0] === ':') { - const parts = val.split('<'); - const func = parts.shift().substr(1); - const arg = parseFloat(parts.shift()); - const color = getColor(parts.join('<')); - - switch (func) { - case 'darken': return color.darken(arg); - case 'lighten': return color.lighten(arg); - case 'alpha': return color.setAlpha(arg); - case 'hue': return color.spin(arg); - case 'saturate': return color.saturate(arg); - } - } - - // other case - return tinycolor(val); - } - - const props = {}; - - for (const [k, v] of Object.entries(theme.props)) { - if (k.startsWith('$')) continue; // ignore const - - props[k] = v.startsWith('"') ? v.replace(/^"\s*/, '') : genValue(getColor(v)); - } - - return props; -} - -function genValue(c: tinycolor.Instance): string { - return c.toRgbString(); -} - -export function validateTheme(theme: Record): boolean { - if (theme.id == null || typeof theme.id !== 'string') return false; - if (theme.name == null || typeof theme.name !== 'string') return false; - if (theme.base == null || !['light', 'dark'].includes(theme.base)) return false; - if (theme.props == null || typeof theme.props !== 'object') return false; - return true; -} diff --git a/src/client/scripts/unison-reload.ts b/src/client/scripts/unison-reload.ts deleted file mode 100644 index 92556aefa..000000000 --- a/src/client/scripts/unison-reload.ts +++ /dev/null @@ -1,10 +0,0 @@ -// SafariがBroadcastChannel未実装なのでライブラリを使う -import { BroadcastChannel } from 'broadcast-channel'; - -export const reloadChannel = new BroadcastChannel<'reload'>('reload'); - -// BroadcastChannelを用いて、クライアントが一斉にreloadするようにします。 -export function unisonReload() { - reloadChannel.postMessage('reload'); - location.reload(); -} diff --git a/src/client/store.ts b/src/client/store.ts deleted file mode 100644 index eea3955fa..000000000 --- a/src/client/store.ts +++ /dev/null @@ -1,318 +0,0 @@ -import { markRaw, ref } from 'vue'; -import { Storage } from './pizzax'; -import { Theme } from './scripts/theme'; - -export const postFormActions = []; -export const userActions = []; -export const noteActions = []; -export const noteViewInterruptors = []; -export const notePostInterruptors = []; - -// TODO: それぞれいちいちwhereとかdefaultというキーを付けなきゃいけないの冗長なのでなんとかする(ただ型定義が面倒になりそう) -// あと、現行の定義の仕方なら「whereが何であるかに関わらずキー名の重複不可」という制約を付けられるメリットもあるからそのメリットを引き継ぐ方法も考えないといけない -export const defaultStore = markRaw(new Storage('base', { - tutorial: { - where: 'account', - default: 0 - }, - keepCw: { - where: 'account', - default: false - }, - showFullAcct: { - where: 'account', - default: false - }, - rememberNoteVisibility: { - where: 'account', - default: false - }, - defaultNoteVisibility: { - where: 'account', - default: 'public' - }, - defaultNoteLocalOnly: { - where: 'account', - default: false - }, - uploadFolder: { - where: 'account', - default: null as string | null - }, - pastedFileName: { - where: 'account', - default: 'yyyy-MM-dd HH-mm-ss [{{number}}]' - }, - memo: { - where: 'account', - default: null - }, - reactions: { - where: 'account', - default: ['👍', '❤️', '😆', '🤔', '😮', '🎉', '💢', '😥', '😇', '🍮'] - }, - mutedWords: { - where: 'account', - default: [] - }, - mutedAds: { - where: 'account', - default: [] as string[] - }, - - menu: { - where: 'deviceAccount', - default: [ - 'notifications', - 'messaging', - 'drive', - 'followRequests', - '-', - 'gallery', - 'featured', - 'explore', - 'announcements', - 'search', - '-', - 'ui', - ] - }, - visibility: { - where: 'deviceAccount', - default: 'public' as 'public' | 'home' | 'followers' | 'specified' - }, - localOnly: { - where: 'deviceAccount', - default: false - }, - widgets: { - where: 'deviceAccount', - default: [] as { - name: string; - id: string; - place: string | null; - data: Record; - }[] - }, - tl: { - where: 'deviceAccount', - default: { - src: 'home', - arg: null - } - }, - - serverDisconnectedBehavior: { - where: 'device', - default: 'quiet' as 'quiet' | 'reload' | 'dialog' - }, - nsfw: { - where: 'device', - default: 'respect' as 'respect' | 'force' | 'ignore' - }, - animation: { - where: 'device', - default: true - }, - animatedMfm: { - where: 'device', - default: true - }, - loadRawImages: { - where: 'device', - default: false - }, - imageNewTab: { - where: 'device', - default: false - }, - disableShowingAnimatedImages: { - where: 'device', - default: false - }, - disablePagesScript: { - where: 'device', - default: false - }, - useOsNativeEmojis: { - where: 'device', - default: false - }, - useBlurEffectForModal: { - where: 'device', - default: true - }, - useBlurEffect: { - where: 'device', - default: true - }, - showFixedPostForm: { - where: 'device', - default: false - }, - enableInfiniteScroll: { - where: 'device', - default: true - }, - useReactionPickerForContextMenu: { - where: 'device', - default: true - }, - showGapBetweenNotesInTimeline: { - where: 'device', - default: false - }, - darkMode: { - where: 'device', - default: false - }, - instanceTicker: { - where: 'device', - default: 'remote' as 'none' | 'remote' | 'always' - }, - reactionPickerWidth: { - where: 'device', - default: 1 - }, - reactionPickerHeight: { - where: 'device', - default: 1 - }, - recentlyUsedEmojis: { - where: 'device', - default: [] as string[] - }, - recentlyUsedUsers: { - where: 'device', - default: [] as string[] - }, - defaultSideView: { - where: 'device', - default: false - }, - menuDisplay: { - where: 'device', - default: 'sideFull' as 'sideFull' | 'sideIcon' | 'top' - }, - reportError: { - where: 'device', - default: false - }, - squareAvatars: { - where: 'device', - default: false - }, - postFormWithHashtags: { - where: 'device', - default: false - }, - postFormHashtags: { - where: 'device', - default: '' - }, - aiChanMode: { - where: 'device', - default: false - }, -})); - -// TODO: 他のタブと永続化されたstateを同期 - -const PREFIX = 'miux:'; - -type Plugin = { - id: string; - name: string; - active: boolean; - configData: Record; - token: string; - ast: any[]; -}; - -/** - * 常にメモリにロードしておく必要がないような設定情報を保管するストレージ(非リアクティブ) - */ -export class ColdDeviceStorage { - public static default = { - lightTheme: require('@client/themes/l-light.json5') as Theme, - darkTheme: require('@client/themes/d-dark.json5') as Theme, - syncDeviceDarkMode: true, - chatOpenBehavior: 'page' as 'page' | 'window' | 'popout', - plugins: [] as Plugin[], - mediaVolume: 0.5, - sound_masterVolume: 0.3, - sound_note: { type: 'syuilo/down', volume: 1 }, - sound_noteMy: { type: 'syuilo/up', volume: 1 }, - sound_notification: { type: 'syuilo/pope2', volume: 1 }, - sound_chat: { type: 'syuilo/pope1', volume: 1 }, - sound_chatBg: { type: 'syuilo/waon', volume: 1 }, - sound_antenna: { type: 'syuilo/triple', volume: 1 }, - sound_channel: { type: 'syuilo/square-pico', volume: 1 }, - sound_reversiPutBlack: { type: 'syuilo/kick', volume: 0.3 }, - sound_reversiPutWhite: { type: 'syuilo/snare', volume: 0.3 }, - roomGraphicsQuality: 'medium' as 'cheep' | 'low' | 'medium' | 'high' | 'ultra', - roomUseOrthographicCamera: true, - }; - - public static watchers = []; - - public static get(key: T): typeof ColdDeviceStorage.default[T] { - // TODO: indexedDBにする - // ただしその際はnullチェックではなくキー存在チェックにしないとダメ - // (indexedDBはnullを保存できるため、ユーザーが意図してnullを格納した可能性がある) - const value = localStorage.getItem(PREFIX + key); - if (value == null) { - return ColdDeviceStorage.default[key]; - } else { - return JSON.parse(value); - } - } - - public static set(key: T, value: typeof ColdDeviceStorage.default[T]): void { - localStorage.setItem(PREFIX + key, JSON.stringify(value)); - - for (const watcher of this.watchers) { - if (watcher.key === key) watcher.callback(value); - } - } - - public static watch(key, callback) { - this.watchers.push({ key, callback }); - } - - // TODO: VueのcustomRef使うと良い感じになるかも - public static ref(key: T) { - const v = ColdDeviceStorage.get(key); - const r = ref(v); - // TODO: このままではwatcherがリークするので開放する方法を考える - this.watch(key, v => { - r.value = v; - }); - return r; - } - - /** - * 特定のキーの、簡易的なgetter/setterを作ります - * 主にvue場で設定コントロールのmodelとして使う用 - */ - public static makeGetterSetter(key: K) { - // TODO: VueのcustomRef使うと良い感じになるかも - const valueRef = ColdDeviceStorage.ref(key); - return { - get: () => { - return valueRef.value; - }, - set: (value: unknown) => { - const val = value; - ColdDeviceStorage.set(key, val); - } - }; - } -} - -// このファイルに書きたくないけどここに書かないと何故かVeturが認識しない -declare module '@vue/runtime-core' { - interface ComponentCustomProperties { - $store: typeof defaultStore; - } -} diff --git a/src/client/style.scss b/src/client/style.scss deleted file mode 100644 index d77cdacf7..000000000 --- a/src/client/style.scss +++ /dev/null @@ -1,562 +0,0 @@ -@charset "utf-8"; - -:root { - --radius: 12px; - --marginFull: 16px; - --marginHalf: 10px; - - --margin: var(--marginFull); - - @media (max-width: 500px) { - --margin: var(--marginHalf); - } - - //--ad: rgb(255 169 0 / 10%); -} - -::selection { - color: #fff; - background-color: var(--accent); -} - -html { - touch-action: manipulation; - background-color: var(--bg); - background-attachment: fixed; - background-size: cover; - background-position: center; - color: var(--fg); - overflow: auto; - overflow-wrap: break-word; - font-family: "BIZ UDGothic", Roboto, HelveticaNeue, Arial, sans-serif; - line-height: 1.35; - text-size-adjust: 100%; - tab-size: 2; - - &, * { - scrollbar-color: var(--scrollbarHandle) inherit; - scrollbar-width: thin; - - &:hover { - scrollbar-color: var(--scrollbarHandleHover) inherit; - } - - &:active { - scrollbar-color: var(--accent) inherit; - } - - &::-webkit-scrollbar { - width: 6px; - height: 6px; - } - - &::-webkit-scrollbar-track { - background: inherit; - } - - &::-webkit-scrollbar-thumb { - background: var(--scrollbarHandle); - - &:hover { - background: var(--scrollbarHandleHover); - } - - &:active { - background: var(--accent); - } - } - } - - &.f-small { - font-size: 0.9em; - } - - &.f-large { - font-size: 1.1em; - } - - &.f-veryLarge { - font-size: 1.2em; - } - - &.useSystemFont { - font-family: sans-serif; - } -} - -html._themeChanging_ { - &, * { - transition: background 1s ease, border 1s ease !important; - } -} - -html, body { - margin: 0; - padding: 0; - scroll-behavior: smooth; -} - -a { - text-decoration: none; - cursor: pointer; - color: inherit; - tap-highlight-color: transparent; - -webkit-tap-highlight-color: transparent; - - &:hover { - text-decoration: underline; - } -} - -textarea, input { - tap-highlight-color: transparent; - -webkit-tap-highlight-color: transparent; -} - -optgroup, option { - background: var(--panel); - color: var(--fg); -} - -hr { - margin: var(--margin) 0 var(--margin) 0; - border: none; - height: 1px; - background: var(--divider); -} - -._noSelect { - user-select: none; - -webkit-user-select: none; - -webkit-touch-callout: none; -} - -._ghost { - &, * { - @extend ._noSelect; - pointer-events: none; - } -} - -._modalBg { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: var(--modalBg); - -webkit-backdrop-filter: var(--modalBgFilter); - backdrop-filter: var(--modalBgFilter); -} - -._shadow { - box-shadow: 0px 4px 32px var(--shadow) !important; -} - -._button { - appearance: none; - display: inline-block; - padding: 0; - margin: 0; // for Safari - background: none; - border: none; - cursor: pointer; - color: inherit; - touch-action: manipulation; - tap-highlight-color: transparent; - -webkit-tap-highlight-color: transparent; - font-size: 1em; - font-family: inherit; - line-height: inherit; - - &, * { - @extend ._noSelect; - } - - * { - pointer-events: none; - } - - &:focus-visible { - outline: none; - } - - &:disabled { - opacity: 0.5; - cursor: default; - } -} - -._buttonPrimary { - @extend ._button; - color: var(--fgOnAccent); - background: var(--accent); - - &:not(:disabled):hover { - background: var(--X8); - } - - &:not(:disabled):active { - background: var(--X9); - } -} - -._buttonGradate { - @extend ._buttonPrimary; - color: var(--fgOnAccent); - background: linear-gradient(90deg, var(--buttonGradateA), var(--buttonGradateB)); - - &:not(:disabled):hover { - background: linear-gradient(90deg, var(--X8), var(--X8)); - } - - &:not(:disabled):active { - background: linear-gradient(90deg, var(--X8), var(--X8)); - } -} - -._help { - color: var(--accent); - cursor: help -} - -._textButton { - @extend ._button; - color: var(--accent); - - &:not(:disabled):hover { - text-decoration: underline; - } -} - -._inputs { - display: flex; - margin: 32px 0; - - &:first-child { - margin-top: 8px; - } - - &:last-child { - margin-bottom: 8px; - } - - > * { - flex: 1; - margin: 0 !important; - - &:not(:first-child) { - margin-left: 8px !important; - } - - &:not(:last-child) { - margin-right: 8px !important; - } - } -} - -._panel { - background: var(--panel); - border-radius: var(--radius); - overflow: clip; -} - -._block { - @extend ._panel; - - & + ._block { - margin-top: var(--margin); - } -} - -._gap { - margin: var(--margin) 0; -} - -// TODO: 廃止 -._card { - @extend ._panel; - - // TODO: _cardTitle に - > ._title { - margin: 0; - padding: 22px 32px; - font-size: 1em; - border-bottom: solid 1px var(--panelHeaderDivider); - font-weight: bold; - background: var(--panelHeaderBg); - color: var(--panelHeaderFg); - - @media (max-width: 500px) { - padding: 16px; - font-size: 1em; - } - } - - // TODO: _cardContent に - > ._content { - padding: 32px; - - @media (max-width: 500px) { - padding: 16px; - } - - &._noPad { - padding: 0 !important; - } - - & + ._content { - border-top: solid 0.5px var(--divider); - } - } - - // TODO: _cardFooter に - > ._footer { - border-top: solid 0.5px var(--divider); - padding: 24px 32px; - - @media (max-width: 500px) { - padding: 16px; - } - } -} - -._borderButton { - @extend ._button; - display: block; - width: 100%; - padding: 10px; - box-sizing: border-box; - text-align: center; - border: solid 0.5px var(--divider); - border-radius: var(--radius); - - &:active { - border-color: var(--accent); - } -} - -._window { - background: var(--panel); - border-radius: var(--radius); - contain: content; -} - -._popup { - background: var(--popup); - border-radius: var(--radius); - contain: layout; // ふき出しがボックスから飛び出て表示されるようなデザインをする場合もあるので paint は contain することができない -} - -// TODO: 廃止 -._monolithic_ { - ._section:not(:empty) { - box-sizing: border-box; - padding: var(--root-margin, 32px); - - @media (max-width: 500px) { - --root-margin: 10px; - } - - & + ._section:not(:empty) { - border-top: solid 0.5px var(--divider); - } - } -} - -._narrow_ ._card { - > ._title { - padding: 16px; - font-size: 1em; - } - - > ._content { - padding: 16px; - } - - > ._footer { - padding: 16px; - } -} - -._acrylic { - background: var(--acrylicPanel); - -webkit-backdrop-filter: var(--blur, blur(15px)); - backdrop-filter: var(--blur, blur(15px)); -} - -._inputSplit { - display: grid; - grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); - grid-gap: 8px; - margin: 1em 0; - - > * { - margin: 0 !important; - } -} - -._formBlock { - margin: 20px 0; -} - -._formRoot { - > ._formBlock:first-child { - margin-top: 0; - } - - > ._formBlock:last-child { - margin-bottom: 0; - } -} - -._table { - > ._row { - display: flex; - - &:not(:last-child) { - margin-bottom: 16px; - - @media (max-width: 500px) { - margin-bottom: 8px; - } - } - - > ._cell { - flex: 1; - - > ._label { - font-size: 80%; - opacity: 0.7; - - > ._icon { - margin-right: 4px; - display: none; - } - } - } - } -} - -._fullinfo { - padding: 64px 32px; - text-align: center; - - > img { - vertical-align: bottom; - height: 128px; - margin-bottom: 16px; - border-radius: 16px; - } -} - -._keyValue { - display: flex; - - > * { - flex: 1; - } -} - -._link { - color: var(--link); -} - -._caption { - font-size: 0.8em; - opacity: 0.7; -} - -._monospace { - font-family: Fira code, Fira Mono, Consolas, Menlo, Courier, monospace !important; -} - -._code { - @extend ._monospace; - background: #2d2d2d; - color: #ccc; - font-size: 14px; - line-height: 1.5; - padding: 5px; -} - -.prism-editor__textarea:focus-visible { - outline: none; -} - -._zoom { - transition-duration: 0.5s, 0.5s; - transition-property: opacity, transform; - transition-timing-function: cubic-bezier(0,.5,.5,1); -} - -.zoom-enter-active, .zoom-leave-active { - transition: opacity 0.5s, transform 0.5s !important; -} -.zoom-enter-from, .zoom-leave-to { - opacity: 0; - transform: scale(0.9); -} - -@keyframes blink { - 0% { opacity: 1; transform: scale(1); } - 30% { opacity: 1; transform: scale(1); } - 90% { opacity: 0; transform: scale(0.5); } -} - -@keyframes tada { - from { - transform: scale3d(1, 1, 1); - } - - 10%, - 20% { - transform: scale3d(0.9, 0.9, 0.9) rotate3d(0, 0, 1, -3deg); - } - - 30%, - 50%, - 70%, - 90% { - transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg); - } - - 40%, - 60%, - 80% { - transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg); - } - - to { - transform: scale3d(1, 1, 1); - } -} - -._anime_bounce { - will-change: transform; - animation: bounce ease 0.7s; - animation-iteration-count: 1; - transform-origin: 50% 50%; -} -._anime_bounce_ready { - will-change: transform; - transform: scaleX(0.90) scaleY(0.90) ; -} -._anime_bounce_standBy { - transition: transform 0.1s ease; -} - -@keyframes bounce{ - 0% { - transform: scaleX(0.90) scaleY(0.90) ; - } - 19% { - transform: scaleX(1.10) scaleY(1.10) ; - } - 48% { - transform: scaleX(0.95) scaleY(0.95) ; - } - 100% { - transform: scaleX(1.00) scaleY(1.00) ; - } -} diff --git a/src/client/sw/compose-notification.ts b/src/client/sw/compose-notification.ts deleted file mode 100644 index 7ed0a9535..000000000 --- a/src/client/sw/compose-notification.ts +++ /dev/null @@ -1,99 +0,0 @@ -/** - * Notification composer of Service Worker - */ -declare var self: ServiceWorkerGlobalScope; - -import { getNoteSummary } from '@/misc/get-note-summary'; -import getUserName from '@/misc/get-user-name'; - -export default async function(type, data, i18n): Promise<[string, NotificationOptions] | null | undefined> { - if (!i18n) { - console.log('no i18n'); - return; - } - - switch (type) { - case 'driveFileCreated': // TODO (Server Side) - return [i18n.t('_notification.fileUploaded'), { - body: data.name, - icon: data.url - }]; - case 'notification': - switch (data.type) { - case 'mention': - return [i18n.t('_notification.youGotMention', { name: getUserName(data.user) }), { - body: getNoteSummary(data.note, i18n.locale), - icon: data.user.avatarUrl - }]; - - case 'reply': - return [i18n.t('_notification.youGotReply', { name: getUserName(data.user) }), { - body: getNoteSummary(data.note, i18n.locale), - icon: data.user.avatarUrl - }]; - - case 'renote': - return [i18n.t('_notification.youRenoted', { name: getUserName(data.user) }), { - body: getNoteSummary(data.note, i18n.locale), - icon: data.user.avatarUrl - }]; - - case 'quote': - return [i18n.t('_notification.youGotQuote', { name: getUserName(data.user) }), { - body: getNoteSummary(data.note, i18n.locale), - icon: data.user.avatarUrl - }]; - - case 'reaction': - return [`${data.reaction} ${getUserName(data.user)}`, { - body: getNoteSummary(data.note, i18n.locale), - icon: data.user.avatarUrl - }]; - - case 'pollVote': - return [i18n.t('_notification.youGotPoll', { name: getUserName(data.user) }), { - body: getNoteSummary(data.note, i18n.locale), - icon: data.user.avatarUrl - }]; - - case 'follow': - return [i18n.t('_notification.youWereFollowed'), { - body: getUserName(data.user), - icon: data.user.avatarUrl - }]; - - case 'receiveFollowRequest': - return [i18n.t('_notification.youReceivedFollowRequest'), { - body: getUserName(data.user), - icon: data.user.avatarUrl - }]; - - case 'followRequestAccepted': - return [i18n.t('_notification.yourFollowRequestAccepted'), { - body: getUserName(data.user), - icon: data.user.avatarUrl - }]; - - case 'groupInvited': - return [i18n.t('_notification.youWereInvitedToGroup'), { - body: data.group.name - }]; - - default: - return null; - } - case 'unreadMessagingMessage': - if (data.groupId === null) { - return [i18n.t('_notification.youGotMessagingMessageFromUser', { name: getUserName(data.user) }), { - icon: data.user.avatarUrl, - tag: `messaging:user:${data.user.id}` - }]; - } - return [i18n.t('_notification.youGotMessagingMessageFromGroup', { name: data.group.name }), { - icon: data.user.avatarUrl, - tag: `messaging:group:${data.group.id}` - }]; - default: - return null; - } -} diff --git a/src/client/sw/sw.ts b/src/client/sw/sw.ts deleted file mode 100644 index 5be4eb977..000000000 --- a/src/client/sw/sw.ts +++ /dev/null @@ -1,123 +0,0 @@ -/** - * Service Worker - */ -declare var self: ServiceWorkerGlobalScope; - -import { get, set } from 'idb-keyval'; -import composeNotification from '@client/sw/compose-notification'; -import { I18n } from '@/misc/i18n'; - -//#region Variables -const version = _VERSION_; -const cacheName = `mk-cache-${version}`; - -let lang: string; -let i18n: I18n; -let pushesPool: any[] = []; -//#endregion - -//#region Startup -get('lang').then(async prelang => { - if (!prelang) return; - lang = prelang; - return fetchLocale(); -}); -//#endregion - -//#region Lifecycle: Install -self.addEventListener('install', ev => { - self.skipWaiting(); -}); -//#endregion - -//#region Lifecycle: Activate -self.addEventListener('activate', ev => { - ev.waitUntil( - caches.keys() - .then(cacheNames => Promise.all( - cacheNames - .filter((v) => v !== cacheName) - .map(name => caches.delete(name)) - )) - .then(() => self.clients.claim()) - ); -}); -//#endregion - -//#region When: Fetching -self.addEventListener('fetch', ev => { - // Nothing to do -}); -//#endregion - -//#region When: Caught Notification -self.addEventListener('push', ev => { - // クライアント取得 - ev.waitUntil(self.clients.matchAll({ - includeUncontrolled: true - }).then(async clients => { - // クライアントがあったらストリームに接続しているということなので通知しない - if (clients.length != 0) return; - - const { type, body } = ev.data?.json(); - - // localeを読み込めておらずi18nがundefinedだった場合はpushesPoolにためておく - if (!i18n) return pushesPool.push({ type, body }); - - const n = await composeNotification(type, body, i18n); - if (n) return self.registration.showNotification(...n); - })); -}); -//#endregion - -//#region When: Caught a message from the client -self.addEventListener('message', ev => { - switch(ev.data) { - case 'clear': - return; // TODO - default: - break; - } - - if (typeof ev.data === 'object') { - // E.g. '[object Array]' → 'array' - const otype = Object.prototype.toString.call(ev.data).slice(8, -1).toLowerCase(); - - if (otype === 'object') { - if (ev.data.msg === 'initialize') { - lang = ev.data.lang; - set('lang', lang); - fetchLocale(); - } - } - } -}); -//#endregion - -//#region Function: (Re)Load i18n instance -async function fetchLocale() { - //#region localeファイルの読み込み - // Service Workerは何度も起動しそのたびにlocaleを読み込むので、CacheStorageを使う - const localeUrl = `/assets/locales/${lang}.${version}.json`; - let localeRes = await caches.match(localeUrl); - - if (!localeRes) { - localeRes = await fetch(localeUrl); - const clone = localeRes?.clone(); - if (!clone?.clone().ok) return; - - caches.open(cacheName).then(cache => cache.put(localeUrl, clone)); - } - - i18n = new I18n(await localeRes.json()); - //#endregion - - //#region i18nをきちんと読み込んだ後にやりたい処理 - for (const { type, body } of pushesPool) { - const n = await composeNotification(type, body, i18n); - if (n) self.registration.showNotification(...n); - } - pushesPool = []; - //#endregion -} -//#endregion diff --git a/src/client/theme-store.ts b/src/client/theme-store.ts deleted file mode 100644 index f29106969..000000000 --- a/src/client/theme-store.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { api } from '@client/os'; -import { $i } from '@client/account'; -import { Theme } from './scripts/theme'; - -const lsCacheKey = $i ? `themes:${$i.id}` : ''; - -export function getThemes(): Theme[] { - return JSON.parse(localStorage.getItem(lsCacheKey) || '[]'); -} - -export async function fetchThemes(): Promise { - if ($i == null) return; - - try { - const themes = await api('i/registry/get', { scope: ['client'], key: 'themes' }); - localStorage.setItem(lsCacheKey, JSON.stringify(themes)); - } catch (e) { - if (e.code === 'NO_SUCH_KEY') return; - throw e; - } -} - -export async function addTheme(theme: Theme): Promise { - await fetchThemes(); - const themes = getThemes().concat(theme); - await api('i/registry/set', { scope: ['client'], key: 'themes', value: themes }); - localStorage.setItem(lsCacheKey, JSON.stringify(themes)); -} - -export async function removeTheme(theme: Theme): Promise { - const themes = getThemes().filter(t => t.id != theme.id); - await api('i/registry/set', { scope: ['client'], key: 'themes', value: themes }); - localStorage.setItem(lsCacheKey, JSON.stringify(themes)); -} diff --git a/src/client/tsconfig.json b/src/client/tsconfig.json deleted file mode 100644 index 7a26047dd..000000000 --- a/src/client/tsconfig.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "compilerOptions": { - "allowJs": true, - "noEmitOnError": false, - "noImplicitAny": false, - "noImplicitReturns": true, - "noUnusedParameters": false, - "noUnusedLocals": true, - "noFallthroughCasesInSwitch": true, - "declaration": false, - "sourceMap": false, - "target": "es2017", - "module": "esnext", - "moduleResolution": "node", - "removeComments": false, - "noLib": false, - "strict": true, - "strictNullChecks": true, - "experimentalDecorators": true, - "resolveJsonModule": true, - "baseUrl": ".", - "paths": { - "@/*": ["../*"], - "@client/*": ["./*"], - "@lib/*": ["../../lib/*"], - }, - "typeRoots": [ - "node_modules/@types", - "src/@types", - "src/client/@types" - ], - "lib": [ - "esnext", - "dom", - "webworker" - ] - }, - "compileOnSave": false, - "include": [ - "./**/*.ts" - ] -} diff --git a/src/client/ui/_common_/common.vue b/src/client/ui/_common_/common.vue deleted file mode 100644 index 8da19a098..000000000 --- a/src/client/ui/_common_/common.vue +++ /dev/null @@ -1,89 +0,0 @@ - - - - - diff --git a/src/client/ui/_common_/sidebar.vue b/src/client/ui/_common_/sidebar.vue deleted file mode 100644 index cd78b6ae4..000000000 --- a/src/client/ui/_common_/sidebar.vue +++ /dev/null @@ -1,388 +0,0 @@ - - - - - diff --git a/src/client/ui/_common_/stream-indicator.vue b/src/client/ui/_common_/stream-indicator.vue deleted file mode 100644 index 23f2357d8..000000000 --- a/src/client/ui/_common_/stream-indicator.vue +++ /dev/null @@ -1,70 +0,0 @@ - - - - - diff --git a/src/client/ui/_common_/upload.vue b/src/client/ui/_common_/upload.vue deleted file mode 100644 index 25a807cd3..000000000 --- a/src/client/ui/_common_/upload.vue +++ /dev/null @@ -1,134 +0,0 @@ - - - - - diff --git a/src/client/ui/chat/date-separated-list.vue b/src/client/ui/chat/date-separated-list.vue deleted file mode 100644 index 12638cd23..000000000 --- a/src/client/ui/chat/date-separated-list.vue +++ /dev/null @@ -1,163 +0,0 @@ - - - - - diff --git a/src/client/ui/chat/header-clock.vue b/src/client/ui/chat/header-clock.vue deleted file mode 100644 index 69ec3cb64..000000000 --- a/src/client/ui/chat/header-clock.vue +++ /dev/null @@ -1,62 +0,0 @@ - - - - - diff --git a/src/client/ui/chat/index.vue b/src/client/ui/chat/index.vue deleted file mode 100644 index 4c068b0d9..000000000 --- a/src/client/ui/chat/index.vue +++ /dev/null @@ -1,467 +0,0 @@ - - - - - diff --git a/src/client/ui/chat/note-header.vue b/src/client/ui/chat/note-header.vue deleted file mode 100644 index e40f22f58..000000000 --- a/src/client/ui/chat/note-header.vue +++ /dev/null @@ -1,112 +0,0 @@ - - - - - diff --git a/src/client/ui/chat/note-preview.vue b/src/client/ui/chat/note-preview.vue deleted file mode 100644 index beb38de64..000000000 --- a/src/client/ui/chat/note-preview.vue +++ /dev/null @@ -1,112 +0,0 @@ - - - - - diff --git a/src/client/ui/chat/note.sub.vue b/src/client/ui/chat/note.sub.vue deleted file mode 100644 index a284ba2bf..000000000 --- a/src/client/ui/chat/note.sub.vue +++ /dev/null @@ -1,137 +0,0 @@ - - - - - diff --git a/src/client/ui/chat/note.vue b/src/client/ui/chat/note.vue deleted file mode 100644 index 0a054d105..000000000 --- a/src/client/ui/chat/note.vue +++ /dev/null @@ -1,1144 +0,0 @@ - - - - - diff --git a/src/client/ui/chat/notes.vue b/src/client/ui/chat/notes.vue deleted file mode 100644 index 6690baf58..000000000 --- a/src/client/ui/chat/notes.vue +++ /dev/null @@ -1,94 +0,0 @@ - - - diff --git a/src/client/ui/chat/pages/channel.vue b/src/client/ui/chat/pages/channel.vue deleted file mode 100644 index d11d40b21..000000000 --- a/src/client/ui/chat/pages/channel.vue +++ /dev/null @@ -1,259 +0,0 @@ - - - - - diff --git a/src/client/ui/chat/pages/timeline.vue b/src/client/ui/chat/pages/timeline.vue deleted file mode 100644 index 0f9cd7f11..000000000 --- a/src/client/ui/chat/pages/timeline.vue +++ /dev/null @@ -1,221 +0,0 @@ - - - - - diff --git a/src/client/ui/chat/post-form.vue b/src/client/ui/chat/post-form.vue deleted file mode 100644 index 64b8d08cb..000000000 --- a/src/client/ui/chat/post-form.vue +++ /dev/null @@ -1,773 +0,0 @@ - - - - - diff --git a/src/client/widgets/button.vue b/src/client/widgets/button.vue deleted file mode 100644 index af6718c50..000000000 --- a/src/client/widgets/button.vue +++ /dev/null @@ -1,95 +0,0 @@ - - - - - diff --git a/src/client/widgets/calendar.vue b/src/client/widgets/calendar.vue deleted file mode 100644 index fe39145f0..000000000 --- a/src/client/widgets/calendar.vue +++ /dev/null @@ -1,204 +0,0 @@ - - - - - diff --git a/src/client/widgets/clock.vue b/src/client/widgets/clock.vue deleted file mode 100644 index d960c3809..000000000 --- a/src/client/widgets/clock.vue +++ /dev/null @@ -1,55 +0,0 @@ - - - - - diff --git a/src/client/widgets/define.ts b/src/client/widgets/define.ts deleted file mode 100644 index 22b7fb30a..000000000 --- a/src/client/widgets/define.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { defineComponent } from 'vue'; -import { throttle } from 'throttle-debounce'; -import { Form } from '@client/scripts/form'; -import * as os from '@client/os'; - -export default function (data: { - name: string; - props?: () => T; -}) { - return defineComponent({ - props: { - widget: { - type: Object, - required: false - }, - settingCallback: { - required: false - } - }, - - emits: ['updateProps'], - - data() { - return { - props: this.widget ? JSON.parse(JSON.stringify(this.widget.data)) : {}, - save: throttle(3000, () => { - this.$emit('updateProps', this.props); - }), - }; - }, - - computed: { - id(): string { - return this.widget ? this.widget.id : null; - }, - }, - - created() { - this.mergeProps(); - - this.$watch('props', () => { - this.mergeProps(); - }, { deep: true }); - - if (this.settingCallback) this.settingCallback(this.setting); - }, - - methods: { - mergeProps() { - if (data.props) { - const defaultProps = data.props(); - for (const prop of Object.keys(defaultProps)) { - if (this.props.hasOwnProperty(prop)) continue; - this.props[prop] = defaultProps[prop].default; - } - } - }, - - async setting() { - const form = data.props(); - for (const item of Object.keys(form)) { - form[item].default = this.props[item]; - } - const { canceled, result } = await os.form(data.name, form); - if (canceled) return; - - for (const key of Object.keys(result)) { - this.props[key] = result[key]; - } - - this.save(); - }, - } - }); -} diff --git a/src/client/widgets/digital-clock.vue b/src/client/widgets/digital-clock.vue deleted file mode 100644 index 2202c9ed4..000000000 --- a/src/client/widgets/digital-clock.vue +++ /dev/null @@ -1,79 +0,0 @@ - - - - - diff --git a/src/client/widgets/federation.vue b/src/client/widgets/federation.vue deleted file mode 100644 index 8ab7f594a..000000000 --- a/src/client/widgets/federation.vue +++ /dev/null @@ -1,145 +0,0 @@ - - - - - diff --git a/src/client/widgets/job-queue.vue b/src/client/widgets/job-queue.vue deleted file mode 100644 index 327d8ede6..000000000 --- a/src/client/widgets/job-queue.vue +++ /dev/null @@ -1,183 +0,0 @@ - - - - - diff --git a/src/client/widgets/memo.vue b/src/client/widgets/memo.vue deleted file mode 100644 index 3f11e6409..000000000 --- a/src/client/widgets/memo.vue +++ /dev/null @@ -1,106 +0,0 @@ - - - - - diff --git a/src/client/widgets/notifications.vue b/src/client/widgets/notifications.vue deleted file mode 100644 index 5e2648f5b..000000000 --- a/src/client/widgets/notifications.vue +++ /dev/null @@ -1,65 +0,0 @@ - - - diff --git a/src/client/widgets/online-users.vue b/src/client/widgets/online-users.vue deleted file mode 100644 index 37060fca4..000000000 --- a/src/client/widgets/online-users.vue +++ /dev/null @@ -1,67 +0,0 @@ - - - - - diff --git a/src/client/widgets/photos.vue b/src/client/widgets/photos.vue deleted file mode 100644 index 25365d6b8..000000000 --- a/src/client/widgets/photos.vue +++ /dev/null @@ -1,113 +0,0 @@ - - - - - diff --git a/src/client/widgets/post-form.vue b/src/client/widgets/post-form.vue deleted file mode 100644 index 1f260c20d..000000000 --- a/src/client/widgets/post-form.vue +++ /dev/null @@ -1,23 +0,0 @@ - - - diff --git a/src/client/widgets/rss.vue b/src/client/widgets/rss.vue deleted file mode 100644 index 6d19a86df..000000000 --- a/src/client/widgets/rss.vue +++ /dev/null @@ -1,89 +0,0 @@ - - - - - diff --git a/src/client/widgets/server-metric/disk.vue b/src/client/widgets/server-metric/disk.vue deleted file mode 100644 index a3f5d0376..000000000 --- a/src/client/widgets/server-metric/disk.vue +++ /dev/null @@ -1,70 +0,0 @@ - - - - - diff --git a/src/client/widgets/server-metric/index.vue b/src/client/widgets/server-metric/index.vue deleted file mode 100644 index 45cd8cebf..000000000 --- a/src/client/widgets/server-metric/index.vue +++ /dev/null @@ -1,82 +0,0 @@ - - - diff --git a/src/client/widgets/server-metric/mem.vue b/src/client/widgets/server-metric/mem.vue deleted file mode 100644 index 92c0aa0c7..000000000 --- a/src/client/widgets/server-metric/mem.vue +++ /dev/null @@ -1,85 +0,0 @@ - - - - - diff --git a/src/client/widgets/server-metric/net.vue b/src/client/widgets/server-metric/net.vue deleted file mode 100644 index 569c15b58..000000000 --- a/src/client/widgets/server-metric/net.vue +++ /dev/null @@ -1,148 +0,0 @@ - - - - - diff --git a/src/client/widgets/slideshow.vue b/src/client/widgets/slideshow.vue deleted file mode 100644 index 2f079e0d4..000000000 --- a/src/client/widgets/slideshow.vue +++ /dev/null @@ -1,167 +0,0 @@ - - - - - diff --git a/src/client/widgets/timeline.vue b/src/client/widgets/timeline.vue deleted file mode 100644 index bd951d856..000000000 --- a/src/client/widgets/timeline.vue +++ /dev/null @@ -1,116 +0,0 @@ - - - diff --git a/src/client/widgets/trends.vue b/src/client/widgets/trends.vue deleted file mode 100644 index 8511bc718..000000000 --- a/src/client/widgets/trends.vue +++ /dev/null @@ -1,111 +0,0 @@ - - - - - diff --git a/src/config/load.ts b/src/config/load.ts deleted file mode 100644 index c7965e6c4..000000000 --- a/src/config/load.ts +++ /dev/null @@ -1,61 +0,0 @@ -/** - * Config loader - */ - -import * as fs from 'fs'; -import { fileURLToPath } from 'url'; -import { dirname } from 'path'; -import * as yaml from 'js-yaml'; -import { Source, Mixin } from './types'; - -//const _filename = fileURLToPath(import.meta.url); -const _filename = __filename; -const _dirname = dirname(_filename); - -/** - * Path of configuration directory - */ -const dir = `${_dirname}/../../.config`; - -/** - * Path of configuration file - */ -const path = process.env.NODE_ENV === 'test' - ? `${dir}/test.yml` - : `${dir}/default.yml`; - -export default function load() { - const meta = JSON.parse(fs.readFileSync(`${_dirname}/../meta.json`, 'utf-8')); - const config = yaml.load(fs.readFileSync(path, 'utf-8')) as Source; - - const mixin = {} as Mixin; - - const url = tryCreateUrl(config.url); - - config.url = url.origin; - - config.port = config.port || parseInt(process.env.PORT || '', 10); - - mixin.version = meta.version; - mixin.host = url.host; - mixin.hostname = url.hostname; - mixin.scheme = url.protocol.replace(/:$/, ''); - mixin.wsScheme = mixin.scheme.replace('http', 'ws'); - mixin.wsUrl = `${mixin.wsScheme}://${mixin.host}`; - mixin.apiUrl = `${mixin.scheme}://${mixin.host}/api`; - mixin.authUrl = `${mixin.scheme}://${mixin.host}/auth`; - mixin.driveUrl = `${mixin.scheme}://${mixin.host}/files`; - mixin.userAgent = `Misskey/${meta.version} (${config.url})`; - - if (!config.redis.prefix) config.redis.prefix = mixin.host; - - return Object.assign(config, mixin); -} - -function tryCreateUrl(url: string) { - try { - return new URL(url); - } catch (e) { - throw `url="${url}" is not a valid URL.`; - } -} diff --git a/src/db/postgre.ts b/src/db/postgre.ts deleted file mode 100644 index f52c2ab72..000000000 --- a/src/db/postgre.ts +++ /dev/null @@ -1,225 +0,0 @@ -// https://github.com/typeorm/typeorm/issues/2400 -const types = require('pg').types; -types.setTypeParser(20, Number); - -import { createConnection, Logger, getConnection } from 'typeorm'; -import config from '@/config/index'; -import { entities as charts } from '@/services/chart/entities'; -import { dbLogger } from './logger'; -import * as highlight from 'cli-highlight'; - -import { User } from '@/models/entities/user'; -import { DriveFile } from '@/models/entities/drive-file'; -import { DriveFolder } from '@/models/entities/drive-folder'; -import { AccessToken } from '@/models/entities/access-token'; -import { App } from '@/models/entities/app'; -import { PollVote } from '@/models/entities/poll-vote'; -import { Note } from '@/models/entities/note'; -import { NoteReaction } from '@/models/entities/note-reaction'; -import { NoteWatching } from '@/models/entities/note-watching'; -import { NoteThreadMuting } from '@/models/entities/note-thread-muting'; -import { NoteUnread } from '@/models/entities/note-unread'; -import { Notification } from '@/models/entities/notification'; -import { Meta } from '@/models/entities/meta'; -import { Following } from '@/models/entities/following'; -import { Instance } from '@/models/entities/instance'; -import { Muting } from '@/models/entities/muting'; -import { SwSubscription } from '@/models/entities/sw-subscription'; -import { Blocking } from '@/models/entities/blocking'; -import { UserList } from '@/models/entities/user-list'; -import { UserListJoining } from '@/models/entities/user-list-joining'; -import { UserGroup } from '@/models/entities/user-group'; -import { UserGroupJoining } from '@/models/entities/user-group-joining'; -import { UserGroupInvitation } from '@/models/entities/user-group-invitation'; -import { Hashtag } from '@/models/entities/hashtag'; -import { NoteFavorite } from '@/models/entities/note-favorite'; -import { AbuseUserReport } from '@/models/entities/abuse-user-report'; -import { RegistrationTicket } from '@/models/entities/registration-tickets'; -import { MessagingMessage } from '@/models/entities/messaging-message'; -import { Signin } from '@/models/entities/signin'; -import { AuthSession } from '@/models/entities/auth-session'; -import { FollowRequest } from '@/models/entities/follow-request'; -import { Emoji } from '@/models/entities/emoji'; -import { ReversiGame } from '@/models/entities/games/reversi/game'; -import { ReversiMatching } from '@/models/entities/games/reversi/matching'; -import { UserNotePining } from '@/models/entities/user-note-pining'; -import { Poll } from '@/models/entities/poll'; -import { UserKeypair } from '@/models/entities/user-keypair'; -import { UserPublickey } from '@/models/entities/user-publickey'; -import { UserProfile } from '@/models/entities/user-profile'; -import { UserSecurityKey } from '@/models/entities/user-security-key'; -import { AttestationChallenge } from '@/models/entities/attestation-challenge'; -import { Page } from '@/models/entities/page'; -import { PageLike } from '@/models/entities/page-like'; -import { GalleryPost } from '@/models/entities/gallery-post'; -import { GalleryLike } from '@/models/entities/gallery-like'; -import { ModerationLog } from '@/models/entities/moderation-log'; -import { UsedUsername } from '@/models/entities/used-username'; -import { Announcement } from '@/models/entities/announcement'; -import { AnnouncementRead } from '@/models/entities/announcement-read'; -import { Clip } from '@/models/entities/clip'; -import { ClipNote } from '@/models/entities/clip-note'; -import { Antenna } from '@/models/entities/antenna'; -import { AntennaNote } from '@/models/entities/antenna-note'; -import { PromoNote } from '@/models/entities/promo-note'; -import { PromoRead } from '@/models/entities/promo-read'; -import { envOption } from '../env'; -import { Relay } from '@/models/entities/relay'; -import { MutedNote } from '@/models/entities/muted-note'; -import { Channel } from '@/models/entities/channel'; -import { ChannelFollowing } from '@/models/entities/channel-following'; -import { ChannelNotePining } from '@/models/entities/channel-note-pining'; -import { RegistryItem } from '@/models/entities/registry-item'; -import { Ad } from '@/models/entities/ad'; -import { PasswordResetRequest } from '@/models/entities/password-reset-request'; -import { UserPending } from '@/models/entities/user-pending'; - -const sqlLogger = dbLogger.createSubLogger('sql', 'white', false); - -class MyCustomLogger implements Logger { - private highlight(sql: string) { - return highlight.highlight(sql, { - language: 'sql', ignoreIllegals: true, - }); - } - - public logQuery(query: string, parameters?: any[]) { - if (envOption.verbose) { - sqlLogger.info(this.highlight(query)); - } - } - - public logQueryError(error: string, query: string, parameters?: any[]) { - sqlLogger.error(this.highlight(query)); - } - - public logQuerySlow(time: number, query: string, parameters?: any[]) { - sqlLogger.warn(this.highlight(query)); - } - - public logSchemaBuild(message: string) { - sqlLogger.info(message); - } - - public log(message: string) { - sqlLogger.info(message); - } - - public logMigration(message: string) { - sqlLogger.info(message); - } -} - -export const entities = [ - Announcement, - AnnouncementRead, - Meta, - Instance, - App, - AuthSession, - AccessToken, - User, - UserProfile, - UserKeypair, - UserPublickey, - UserList, - UserListJoining, - UserGroup, - UserGroupJoining, - UserGroupInvitation, - UserNotePining, - UserSecurityKey, - UsedUsername, - AttestationChallenge, - Following, - FollowRequest, - Muting, - Blocking, - Note, - NoteFavorite, - NoteReaction, - NoteWatching, - NoteThreadMuting, - NoteUnread, - Page, - PageLike, - GalleryPost, - GalleryLike, - DriveFile, - DriveFolder, - Poll, - PollVote, - Notification, - Emoji, - Hashtag, - SwSubscription, - AbuseUserReport, - RegistrationTicket, - MessagingMessage, - Signin, - ModerationLog, - Clip, - ClipNote, - Antenna, - AntennaNote, - PromoNote, - PromoRead, - ReversiGame, - ReversiMatching, - Relay, - MutedNote, - Channel, - ChannelFollowing, - ChannelNotePining, - RegistryItem, - Ad, - PasswordResetRequest, - UserPending, - ...charts as any -]; - -export function initDb(justBorrow = false, sync = false, forceRecreate = false) { - if (!forceRecreate) { - try { - const conn = getConnection(); - return Promise.resolve(conn); - } catch (e) {} - } - - const log = process.env.NODE_ENV != 'production'; - - return createConnection({ - type: 'postgres', - host: config.db.host, - port: config.db.port, - username: config.db.user, - password: config.db.pass, - database: config.db.db, - extra: config.db.extra, - synchronize: process.env.NODE_ENV === 'test' || sync, - dropSchema: process.env.NODE_ENV === 'test' && !justBorrow, - cache: !config.db.disableCache ? { - type: 'redis', - options: { - host: config.redis.host, - port: config.redis.port, - password: config.redis.pass, - prefix: `${config.redis.prefix}:query:`, - db: config.redis.db || 0 - } - } : false, - logging: log, - logger: log ? new MyCustomLogger() : undefined, - entities: entities - }); -} - -export async function resetDb() { - const conn = await getConnection(); - const tables = await conn.query(`SELECT relname AS "table" - FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace) - WHERE nspname NOT IN ('pg_catalog', 'information_schema') - AND C.relkind = 'r' - AND nspname !~ '^pg_toast';`); - await Promise.all(tables.map(t => t.table).map(x => conn.query(`DELETE FROM "${x}" CASCADE`))); -} diff --git a/src/docs/ar-SA/admin/disable-timelines.md b/src/docs/ar-SA/admin/disable-timelines.md deleted file mode 100644 index b081e35ab..000000000 --- a/src/docs/ar-SA/admin/disable-timelines.md +++ /dev/null @@ -1,8 +0,0 @@ -# LTL/STL/GTLの無効化 -Misskeyでは、LTL/STL/GTLをそれぞれ無効化することができます。有効/無効を切り替えるには、インスタンスコントロールパネルで設定します。 - -LTLやSTLは、そのインスタンス全員の投稿が見れるため、新規のユーザーにとってはユーザーを探す必要がなくなり、興味のあるユーザーを見つけやすいという利点があります。 しかし同時に、フォロー機能が活用されなくなったり、不適切な投稿が目につきやすくなったり、チャットのようになることで内輪感が生じて逆に新規ユーザーが参加しにくくなるといったデメリットも持ち合わせています。 サーバーによってメリット/デメリットどちらが優勢かは異なるので、オプションとして無効にできるようになっています。 もしデメリットの方が上回っていると感じたら、それらのタイムラインを無効化することも検討してください。 - -
⚠️ 無効化を行うと、ユーザーが困惑し、短期的に見て利用者が減る可能性があります。そのため、無効化の際は影響を慎重に検討し、事前に説明してフォローを整える期間を一定程度設けることを推奨します。
- -なお、管理者/モデレーターは、これらのタイムラインの無効化状態は適用されず、引き続き利用することが可能です。 diff --git a/src/docs/ar-SA/admin/faq.md b/src/docs/ar-SA/admin/faq.md deleted file mode 100644 index 317b4e065..000000000 --- a/src/docs/ar-SA/admin/faq.md +++ /dev/null @@ -1,5 +0,0 @@ -# よくある質問 -ここでは、サーバー管理者向けのよくある質問を掲載しています。 - -## デフォルトテーマを設定したい -現在、デフォルトテーマ設定機能は実装されていません。 diff --git a/src/docs/ar-SA/advanced/aiscript.md b/src/docs/ar-SA/advanced/aiscript.md deleted file mode 100644 index 604d17daa..000000000 --- a/src/docs/ar-SA/advanced/aiscript.md +++ /dev/null @@ -1,7 +0,0 @@ -# AiScript -AiScriptは、Misskeyで使用できるスクリプト言語です。 - -
ℹ️ AiScript実装はMisskeyとは別リポジトリで、オープンソースで公開されています。
- -## 使い方 -AiScriptの構文や組み込み関数などのドキュメントは、[こちら](https://github.com/syuilo/aiscript/tree/master/docs)で公開されています。 diff --git a/src/docs/ar-SA/advanced/api.md b/src/docs/ar-SA/advanced/api.md deleted file mode 100644 index 76019b614..000000000 --- a/src/docs/ar-SA/advanced/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス、Bot等(以下「アプリケーション」と呼びます)を開発できます。 ストリーミングAPIもあるので、リアルタイム性のあるアプリケーションを作ることも可能です。 - -APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。 - -## アクセストークンの取得 -基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。 - -* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む -* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む - -### 自分自身のアクセストークンを手動発行する -「設定 > API」で、自分のアクセストークンを発行できます。 - -[「APIの使い方」へ進む](#APIの使い方) - -### アプリケーション利用者にアクセストークンの発行をリクエストする -アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。 - -#### Step 1 - -UUIDを生成する。以後これをセッションIDと呼びます。 - -> このセッションIDは毎回生成し、使いまわさないようにしてください。 - -#### Step 2 - -`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。 -> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます: -* `name` ... アプリケーション名 - * > 例: `MissDeck` -* `icon` ... アプリケーションのアイコン画像URL - * > 例: `https://missdeck.example.com/icon.png` -* `callback` ... 認証が終わった後にリダイレクトするURL - * > 例: `https://missdeck.example.com/callback` - * リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます -* `permission` ... アプリケーションが要求する権限 - * > 例: `write:notes,write:following,read:drive` - * 要求する権限を`,`で区切って列挙します - * どのような権限があるかは[APIリファレンス](/api-doc)で確認できます - -#### Step 3 -ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。 - -レスポンスに含まれるプロパティ: -* `token` ... ユーザーのアクセストークン -* `user` ... ユーザーの情報 - -[「APIの使い方」へ進む](#APIの使い方) - -## APIの使い方 -**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。 - -* [APIリファレンス](/api-doc) -* [ストリーミングAPI](./stream) diff --git a/src/docs/ar-SA/advanced/create-plugin.md b/src/docs/ar-SA/advanced/create-plugin.md deleted file mode 100644 index a6cba6388..000000000 --- a/src/docs/ar-SA/advanced/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# プラグインの作成 -Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。 - -## البيانات الوصفية -プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。 - -### name -プラグイン名 - -### author -プラグイン作者 - -### version -プラグインバージョン。数値を指定してください。 - -### description -プラグインの説明 - -### permissions -プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。 - -### config -プラグインの設定情報を表すオブジェクト。 キーに設定名、値に以下のプロパティを含めます。 - -#### type -設定値の種類を表す文字列。以下から選択します。 string number boolean - -#### label -ユーザーに表示する設定名 - -#### description -設定の説明 - -#### default -設定のデフォルト値 - -## APIリファレンス -AiScript標準で組み込まれているAPIは掲載しません。 - -### Mk:dialog(title text type) -ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。 - -### Mk:confirm(title text type) -確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。 - -### Mk:api(endpoint params) -Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。 - -### Mk:save(key value) -任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。 - -### Mk:load(key) -Mk:saveで永続化した指定の名前の値を読み取ります。 - -### Plugin:register_post_form_action(title fn) -投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。 - -### Plugin:register_note_action(title fn) -ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 - -### Plugin:register_user_action(title fn) -ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。 - -### Plugin:register_note_view_interruptor(fn) -UIに表示されるノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:register_note_post_interruptor(fn) -ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:open_url(url) -第一引数に渡されたURLをブラウザの新しいタブで開きます。 - -### Plugin:config -プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。 diff --git a/src/docs/ar-SA/advanced/develop-bot.md b/src/docs/ar-SA/advanced/develop-bot.md deleted file mode 100644 index 7f825e9bc..000000000 --- a/src/docs/ar-SA/advanced/develop-bot.md +++ /dev/null @@ -1,6 +0,0 @@ -# Botの作成 -[Misskey API](./api)を利用してBotの開発が可能です。 また、いくつかのBot実装が公開されているため、ぜひ参考にしてください。 - -- [syuilo/ai](https://github.com/syuilo/ai) ... Node.js上で動く、TypeScript製Bot実装 - -Botを作成したときは、プロフィール設定からBotフラグをオンにしておくことを強くおすすめします。 diff --git a/src/docs/ar-SA/advanced/reversi-bot.md b/src/docs/ar-SA/advanced/reversi-bot.md deleted file mode 100644 index 7ab2a7212..000000000 --- a/src/docs/ar-SA/advanced/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# MisskeyリバーシBotの開発 -Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。 - -1. `games/reversi`ストリームに以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - -2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる - * イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている - -3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する - -4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - * `game`: `game`の`id` - -5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う - -6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する - -7. ゲームが開始すると、`started`イベントが流れてくる - * イベントの中身にはゲーム情報が含まれている - -8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述) - -9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる - * `color`として石の色が含まれている - * `pos`として位置情報が含まれている - -## 位置の計算法 -8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### X,Y座標 から インデックス に変換する -``` -pos = x + (y * mapWidth) -``` -`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます: -``` -mapWidth = map[0].length -``` - -### インデックス から X,Y座標 に変換する -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## マップ情報 -マップ情報は、ゲーム情報の`map`に入っています。 文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 それをもとにマップのデザインを知る事が出来ます: -* `(スペース)` ... マス無し -* `-` ... マス -* `b` ... 初期配置される黒石 -* `w` ... 初期配置される白石 - -例えば、4*4の次のような単純なマップがあるとします: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -この場合、マップデータはこのようになります: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## ユーザーにフォームを提示して対話可能Botを作成する -ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。 - -フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します: -```javascript -{ - type: 'init-form', - body: [フォームコントロールの配列] -} -``` - -フォームコントロールの配列については今から説明します。 フォームコントロールは、次のようなオブジェクトです: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... コントロールのID。 `type` ... コントロールの種類。後述します。 `label` ... コントロールと一緒に表記するテキスト。 `value` ... コントロールのデフォルト値。 - -### フォームの操作を受け取る -ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### フォームコントロールの種類 -#### スイッチ -type: `switch` スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。 - -##### プロパティ -`label` ... スイッチに表記するテキスト。 - -#### ラジオボタン -type: `radio` ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。 - -##### プロパティ -`items` ... ラジオボタンの選択肢。例: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '強', - value: 3 -}] -``` - -#### スライダー -type: `slider` スライダーを表示します。 - -##### プロパティ -`min` ... スライダーの下限。 `max` ... スライダーの上限。 `step` ... 入力欄で刻むステップ値。 - -#### テキストボックス -type: `textbox` テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。 - -## ユーザーにメッセージを表示する -設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 メッセージを表示するには、次のメッセージをストリームに送信します: -```javascript -{ - type: 'message', - body: { - text: 'メッセージ内容', - type: 'メッセージの種類' - } -} -``` -メッセージの種類: `success`, `info`, `warning`, `error`。 - -## 投了する -投了をするには、このエンドポイントにリクエストします。 diff --git a/src/docs/ar-SA/advanced/share-page.md b/src/docs/ar-SA/advanced/share-page.md deleted file mode 100644 index 57485b66b..000000000 --- a/src/docs/ar-SA/advanced/share-page.md +++ /dev/null @@ -1,54 +0,0 @@ -# シェアページ -`/share`を開くと、共有用の投稿フォームを開くことができます。 ここではシェアページで利用できるクエリ文字列の一覧を示します。 - -## クエリ文字列一覧 -### 文字 - -
-
title
-
タイトルです。本文の先頭に[ … ]と挿入されます。
-
text
-
本文です。
-
url
-
URLです。末尾に挿入されます。
-
- -### リプライ情報 -以下のいずれか - -
-
replyId
-
リプライ先のノートid
-
replyUri
-
リプライ先のUrl(リモートのノートオブジェクトを指定)
-
- -### Renote情報 -以下のいずれか - -
-
renoteId
-
Renote先のノートid
-
renoteUri
-
Renote先のUrl(リモートのノートオブジェクトを指定)
-
- -### الظهور -※specifiedに相当する値はvisibility=specifiedとvisibleAccts/visibleUserIdsで指定する - -
-
visibility
-
公開範囲 ['public' | 'home' | 'followers' | 'specified']
-
localOnly
-
0(false) or 1(true)
-
visibleUserIds
-
specified時のダイレクト先のユーザーid カンマ区切りで
-
visibleAccts
-
specified時のダイレクト先のacct(@?username[@host]) カンマ区切りで
-
- -### الملفات -
-
fileIds
-
添付したいファイルのid(カンマ区切りで)
-
diff --git a/src/docs/ar-SA/advanced/stream.md b/src/docs/ar-SA/advanced/stream.md deleted file mode 100644 index a74aafb63..000000000 --- a/src/docs/ar-SA/advanced/stream.md +++ /dev/null @@ -1,350 +0,0 @@ -# ストリーミングAPI - -ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。 - -## ストリームに接続する - -ストリーミングAPIを利用するには、まずMisskeyサーバーに**websocket**接続する必要があります。 - -以下のURLに、`i`というパラメータ名で認証情報を含めて、websocket接続してください。例: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。 - -
ℹ️ 認証情報の取得については、こちらのドキュメントをご確認ください。
- ---- - -認証情報は省略することもできますが、その場合非ログインでの利用ということになり、受信できる情報や可能な操作は限られます。例: - -``` -%WS_URL%/streaming -``` - ---- - -ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。 - -**ストリームでのやり取りはすべてJSONです。** - -## القنوات -MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。 - -ひとつのストリーム上で、同時に複数のチャンネルに接続することができます。 - -### チャンネルに接続する -チャンネルに接続するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -ここで、 -* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。 -* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。 -* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。 - -
ℹ️ IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。
- -### チャンネルからのメッセージを受け取る -例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。 - -チャンネルがメッセージを発すると、次のようなデータがJSONでストリームに流れてきます: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。 -* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。 -* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。 - -### チャンネルに向けてメッセージを送信する -チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。 - -チャンネルにメッセージを送信するには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。 -* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。 -* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。 - -### チャンネルから切断する -チャンネルから切断するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。 - -## ストリームを経由してAPIリクエストする - -ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。 - -ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -ここで、 -* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 -* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 -* `data`には、エンドポイントのパラメータを含めます。 - -
ℹ️ APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。
- -### レスポンスの受信 - -APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。 - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -ここで、 -* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 -* `body`には、レスポンスが含まれています。 - -## 投稿のキャプチャ - -Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。 - -例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。 - -しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。 - -この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。 - -### 投稿をキャプチャする - -投稿をキャプチャするには、ストリームに次のようなメッセージを送信します: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャしたい投稿の`id`を設定します。 - -このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 - -例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -ここで、 -* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。 -* `body`内の`type`に、イベントの種類が設定されます。 -* `body`内の`body`に、イベントの詳細が設定されます。 - -#### イベントの種類 - -##### `reacted` -その投稿にリアクションがされた時に発生します。 - -* `reaction`に、リアクションの種類が設定されます。 -* `userId`に、リアクションを行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -その投稿が削除された時に発生します。 - -* `deletedAt`に、削除日時が設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -その投稿に添付されたアンケートに投票された時に発生します。 - -* `choice`に、選択肢IDが設定されます。 -* `userId`に、投票を行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### 投稿のキャプチャを解除する - -その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。 - -次のメッセージを送信します: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャを解除したい投稿の`id`を設定します。 - -このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 - -# チャンネル一覧 -## `main` -アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `renote` -自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。 - -#### `mention` -誰かからメンションされたときに発生するイベントです。 - -#### `readAllNotifications` -自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。 - -#### `meUpdated` -自分の情報が更新されたことを表すイベントです。 - -#### `follow` -自分が誰かをフォローしたときに発生するイベントです。 - -#### `unfollow` -自分が誰かのフォローを解除したときに発生するイベントです。 - -#### `followed` -自分が誰かにフォローされたときに発生するイベントです。 - -## `homeTimeline` -ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -タイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `localTimeline` -ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `hybridTimeline` -ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ソーシャルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `globalTimeline` -グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 diff --git a/src/docs/ar-SA/aiscript.md b/src/docs/ar-SA/aiscript.md deleted file mode 100644 index edce733a8..000000000 --- a/src/docs/ar-SA/aiscript.md +++ /dev/null @@ -1,4 +0,0 @@ -# AiScript - -## وظائف -デフォルトで値渡しです。 diff --git a/src/docs/ar-SA/api.md b/src/docs/ar-SA/api.md deleted file mode 100644 index 76019b614..000000000 --- a/src/docs/ar-SA/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス、Bot等(以下「アプリケーション」と呼びます)を開発できます。 ストリーミングAPIもあるので、リアルタイム性のあるアプリケーションを作ることも可能です。 - -APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。 - -## アクセストークンの取得 -基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。 - -* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む -* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む - -### 自分自身のアクセストークンを手動発行する -「設定 > API」で、自分のアクセストークンを発行できます。 - -[「APIの使い方」へ進む](#APIの使い方) - -### アプリケーション利用者にアクセストークンの発行をリクエストする -アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。 - -#### Step 1 - -UUIDを生成する。以後これをセッションIDと呼びます。 - -> このセッションIDは毎回生成し、使いまわさないようにしてください。 - -#### Step 2 - -`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。 -> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます: -* `name` ... アプリケーション名 - * > 例: `MissDeck` -* `icon` ... アプリケーションのアイコン画像URL - * > 例: `https://missdeck.example.com/icon.png` -* `callback` ... 認証が終わった後にリダイレクトするURL - * > 例: `https://missdeck.example.com/callback` - * リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます -* `permission` ... アプリケーションが要求する権限 - * > 例: `write:notes,write:following,read:drive` - * 要求する権限を`,`で区切って列挙します - * どのような権限があるかは[APIリファレンス](/api-doc)で確認できます - -#### Step 3 -ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。 - -レスポンスに含まれるプロパティ: -* `token` ... ユーザーのアクセストークン -* `user` ... ユーザーの情報 - -[「APIの使い方」へ進む](#APIの使い方) - -## APIの使い方 -**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。 - -* [APIリファレンス](/api-doc) -* [ストリーミングAPI](./stream) diff --git a/src/docs/ar-SA/create-plugin.md b/src/docs/ar-SA/create-plugin.md deleted file mode 100644 index a6cba6388..000000000 --- a/src/docs/ar-SA/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# プラグインの作成 -Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。 - -## البيانات الوصفية -プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。 - -### name -プラグイン名 - -### author -プラグイン作者 - -### version -プラグインバージョン。数値を指定してください。 - -### description -プラグインの説明 - -### permissions -プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。 - -### config -プラグインの設定情報を表すオブジェクト。 キーに設定名、値に以下のプロパティを含めます。 - -#### type -設定値の種類を表す文字列。以下から選択します。 string number boolean - -#### label -ユーザーに表示する設定名 - -#### description -設定の説明 - -#### default -設定のデフォルト値 - -## APIリファレンス -AiScript標準で組み込まれているAPIは掲載しません。 - -### Mk:dialog(title text type) -ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。 - -### Mk:confirm(title text type) -確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。 - -### Mk:api(endpoint params) -Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。 - -### Mk:save(key value) -任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。 - -### Mk:load(key) -Mk:saveで永続化した指定の名前の値を読み取ります。 - -### Plugin:register_post_form_action(title fn) -投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。 - -### Plugin:register_note_action(title fn) -ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 - -### Plugin:register_user_action(title fn) -ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。 - -### Plugin:register_note_view_interruptor(fn) -UIに表示されるノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:register_note_post_interruptor(fn) -ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:open_url(url) -第一引数に渡されたURLをブラウザの新しいタブで開きます。 - -### Plugin:config -プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。 diff --git a/src/docs/ar-SA/custom-emoji.md b/src/docs/ar-SA/custom-emoji.md deleted file mode 100644 index b86b191d1..000000000 --- a/src/docs/ar-SA/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# إيموجي مخصص -カスタム絵文字は、インスタンスで用意された画像を絵文字のように使える機能です。 ノート、リアクション、チャット、自己紹介、名前などの場所で使うことができます。 カスタム絵文字をそれらの場所で使うには、絵文字ピッカーボタン(ある場合)を押すか、`:`を入力して絵文字サジェストを表示します。 テキスト内に`:foo:`のような形式の文字列が見つかると、`foo`の部分がカスタム絵文字名と解釈され、表示時には対応したカスタム絵文字に置き換わります。 diff --git a/src/docs/ar-SA/deck.md b/src/docs/ar-SA/deck.md deleted file mode 100644 index 8057e262f..000000000 --- a/src/docs/ar-SA/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# デッキ - -デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。 - -## カラムの追加 -デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。 - -## カラムの移動 -カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。 - -## カラムの水平分割 -カラムは左右だけでなく、上下に並べることもできます。 カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 上下分割を解除するには、カラムメニューの「右に出す」を選択します。 - -## カラムの設定 -カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。 - -## デッキの設定 -デッキに関する設定は、[settings/deck](/settings/deck)で行えます。 diff --git a/src/docs/ar-SA/features/antenna.md b/src/docs/ar-SA/features/antenna.md deleted file mode 100644 index 0cb6db82c..000000000 --- a/src/docs/ar-SA/features/antenna.md +++ /dev/null @@ -1,4 +0,0 @@ -# الهوائيات -アンテナは、自由に条件を設定して、合致するノートを自動で収集することができる機能です。 - -条件を設定したアンテナが作成された状態で、条件に合致するノートが投稿されると、リアルタイムでそのアンテナのタイムラインにノートが追加されます。 diff --git a/src/docs/ar-SA/features/custom-emoji.md b/src/docs/ar-SA/features/custom-emoji.md deleted file mode 100644 index b86b191d1..000000000 --- a/src/docs/ar-SA/features/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# إيموجي مخصص -カスタム絵文字は、インスタンスで用意された画像を絵文字のように使える機能です。 ノート、リアクション、チャット、自己紹介、名前などの場所で使うことができます。 カスタム絵文字をそれらの場所で使うには、絵文字ピッカーボタン(ある場合)を押すか、`:`を入力して絵文字サジェストを表示します。 テキスト内に`:foo:`のような形式の文字列が見つかると、`foo`の部分がカスタム絵文字名と解釈され、表示時には対応したカスタム絵文字に置き換わります。 diff --git a/src/docs/ar-SA/features/deck.md b/src/docs/ar-SA/features/deck.md deleted file mode 100644 index 8057e262f..000000000 --- a/src/docs/ar-SA/features/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# デッキ - -デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。 - -## カラムの追加 -デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。 - -## カラムの移動 -カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。 - -## カラムの水平分割 -カラムは左右だけでなく、上下に並べることもできます。 カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 上下分割を解除するには、カラムメニューの「右に出す」を選択します。 - -## カラムの設定 -カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。 - -## デッキの設定 -デッキに関する設定は、[settings/deck](/settings/deck)で行えます。 diff --git a/src/docs/ar-SA/features/drive.md b/src/docs/ar-SA/features/drive.md deleted file mode 100644 index f107cb8c5..000000000 --- a/src/docs/ar-SA/features/drive.md +++ /dev/null @@ -1,17 +0,0 @@ -# قرص التخرين -ドライブは、Misskey上でファイルを管理できる機能です。 - -[ドライブのページ](/my/drive)から任意のファイルをアップロードできるほか、アバターに設定した画像や、ノートに添付したファイルなどもすべてドライブにアップロードされます。 - -
⚠️ ドライブからファイルを削除すると、そのファイルが添付されたノートも消えます。
- -ドライブにアップロードされたファイルは、いつでもダウンロードすることができるほか、ノート作成時に「ドライブからファイルを添付」することでファイルを再利用することもできます。 - -ドライブ内にフォルダを作り、複数のファイルをまとめて整理することもできます。 - -## 閲覧注意 (NSFW) -
ℹ️ この項目が閲覧注意なわけではありません
- -閲覧注意またはNSFW (Not safe for work) は、ドライブのファイルに設定することができるフラグです。 閲覧注意フラグを設定されたファイルは、表示される際に閲覧者の操作なしには表示されなくなります。 このフラグは、例えば職場や公共の場で閲覧するのに適切でないと思われる画像などに設定し、そのような画像が突然表示されてしまうことを防ぐ目的で使われます。 - -このフラグは手動でオンオフを切り替えられるほか、モデレーターの判断で設定される場合もあります。 diff --git a/src/docs/ar-SA/features/favorite.md b/src/docs/ar-SA/features/favorite.md deleted file mode 100644 index 1554291f1..000000000 --- a/src/docs/ar-SA/features/favorite.md +++ /dev/null @@ -1,4 +0,0 @@ -# إضافة إلى المفضلة -[ノート](./node)をお気に入りとして登録できる機能です。 お気に入り登録したノートは、[お気に入りページ](./my/favorites)で一覧することができます。 お気に入りに登録したことは相手に通知されず、お気に入りは自分しか見ることができません。 - -ノートをお気に入り登録するには、ノートメニューの「お気に入り」を押します。お気に入り解除するには、ノートメニューの「お気に入り解除」を押します。 diff --git a/src/docs/ar-SA/features/follow.md b/src/docs/ar-SA/features/follow.md deleted file mode 100644 index 9b6562be9..000000000 --- a/src/docs/ar-SA/features/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# المتابَعون -ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。 diff --git a/src/docs/ar-SA/features/keyboard-shortcut.md b/src/docs/ar-SA/features/keyboard-shortcut.md deleted file mode 100644 index 3c73013c0..000000000 --- a/src/docs/ar-SA/features/keyboard-shortcut.md +++ /dev/null @@ -1,66 +0,0 @@ -# キーボードショートカット - -## الشامل -これらのショートカットは基本的にどこでも使えます。 - - - - - - - - - - - -
ショートカット効果由来
P, N新規投稿Post, New, Note
Tタイムラインの最も新しい投稿にフォーカスTimeline, Top
Shift + N通知を表示/隠すNotifications
SالبحثSearch
H, ?ヘルプを表示Help
- -## 投稿にフォーカスされた状態 - - - - - - - - - - - - - - - - - - -
ショートカット効果由来
, K, Shift + Tab上の投稿にフォーカスを移動-
, J, Tab下の投稿にフォーカスを移動-
R返信フォームを開くReply
QRenoteフォームを開くQuote
Ctrl + Q即刻Renoteする(フォームを開かずに)-
E, A, +リアクションフォームを開くEmote, reAction
0~9数字に対応したリアクションをする(対応については後述)-
F, Bお気に入りに登録Favorite, Bookmark
Del, Ctrl + D投稿を削除Delete
M, O投稿に対するメニューを開くMore, Other
SCWで隠された部分を表示 or 隠すShow, See
Escフォーカスを外す-
- -## Renoteフォーム - - - - - - - - - -
ショートカット効果由来
EnterRenoteする-
Qフォームを展開するQuote
Escフォームを閉じる-
- -## リアクションフォーム -デフォルトで「👍」にフォーカスが当たっている状態です。 - - - - - - - - - - - - - -
ショートカット効果由来
, K上のリアクションにフォーカスを移動-
, J下のリアクションにフォーカスを移動-
, H, Shift + Tab左のリアクションにフォーカスを移動-
, L, Tab右のリアクションにフォーカスを移動-
Enter, Space, +リアクション確定-
0~9数字に対応したリアクションで確定-
Escリアクションするのをやめる-
diff --git a/src/docs/ar-SA/features/mfm.md b/src/docs/ar-SA/features/mfm.md deleted file mode 100644 index 5be2df4f3..000000000 --- a/src/docs/ar-SA/features/mfm.md +++ /dev/null @@ -1,12 +0,0 @@ -# MFM -MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます。 - -## MFMが使用可能な場所の例 -- ノート本文 -- CW注釈 -- ユーザーの名前 -- ユーザーの自己紹介 - -## 開発者向け情報 -MFMのパーサー実装はライブラリとして公開されており、簡単にクライアントにMFMを組み込むことが可能です。 -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptパーサー実装 diff --git a/src/docs/ar-SA/features/mute-and-block.md b/src/docs/ar-SA/features/mute-and-block.md deleted file mode 100644 index 932d2d27d..000000000 --- a/src/docs/ar-SA/features/mute-and-block.md +++ /dev/null @@ -1,41 +0,0 @@ -# تم كتمها / تم حجبها -好みではないユーザーがいる場合は、ミュートを行うことでそのユーザーが自分から見えないようにすることができます。 また、より強力な措置として、ブロックを行うことでそのユーザーから自分のコンテンツが見えないようになるほか、自分に対して関わることができないようにすることができます。 ミュートされていることは相手は分かりませんが、ブロックされていることは相手に分かります。どちらを選ぶかはご自身の判断で行ってください。 - -
ℹ️ ミュートとブロックは併用できます。
- -
⚠️ 利用規約に違反するような、迷惑なユーザーがいる場合は運営者に報告することも検討してください。
- -設定>ミュートとブロック から、自分がミュートまたはブロックしているユーザー一覧を確認することができます。 - -## اكتم -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -- タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -- そのユーザーからの通知 -- メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 -- など - -ユーザーをミュートするには、対象のユーザーのユーザーページのメニューを開き、「ミュート」ボタンを押します。 - -
ℹ️ ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。
- -## احجب -ユーザーをブロックすると、そのユーザーからあなたのコンテンツが見えないようになり、またあなたに対して以下のようなアクションをすることができなくなります。 - -- フォローする -- ユーザーリストに追加する -- 返信する、Renoteする -- リアクションする、アンケートに投票する -- メッセージを送信する -- など - -また、 - -- ブロックする際に既にそのユーザーからフォローされていた場合はフォローが解除されます。 -- ブロックする際に既にそのユーザーがあなたをユーザーリストに入れていた場合はそのリストからあなたが削除されます。 - -ユーザーをブロックするには、対象のユーザーのユーザーページのメニューを開き、「ブロック」ボタンを押します。 - -
⚠️ ブロックを行ったこと自体は相手に通知されませんが、フォローを行ったりなどの上記のアクションが行えなくなるので間接的にブロックされていることは分かります。
- -
⚠️ 相手から自分のコンテンツが見えなくなりますが、相手がアカウントを切り替えたりログアウト状態になれば見ることができます。あくまで簡易的、補助的なものとしてお考えください。
diff --git a/src/docs/ar-SA/features/mute.md b/src/docs/ar-SA/features/mute.md deleted file mode 100644 index c04ebcfd7..000000000 --- a/src/docs/ar-SA/features/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# اكتم - -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -* タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -* そのユーザーからの通知 -* メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 - -ユーザーをミュートするには、対象のユーザーのユーザーページに表示されている「ミュート」ボタンを押します。 - -ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。 - -設定>ミュート から、自分がミュートしているユーザー一覧を確認することができます。 diff --git a/src/docs/ar-SA/features/note.md b/src/docs/ar-SA/features/note.md deleted file mode 100644 index b9dcb13c3..000000000 --- a/src/docs/ar-SA/features/note.md +++ /dev/null @@ -1,54 +0,0 @@ -# الملاحظات -ノートは、Misskeyに投稿される、文章、ファイル、アンケートなどを含むコンテンツで、Misskeyの中心的概念です。また、そのノートを作成する行為自体もノートと呼ばれます。 - -ノートが作成されると、[タイムライン](./timeline)に追加され、自分の[フォロワー](./follow)やサーバーのユーザーが見れるようになります。 - -ノートには、[リアクション](./reaction)を行うことができます。また、返信や引用もできます。 - -ノートを[お気に入り](./favorite)登録することで、後で簡単に見返すことができます。 - -## ノートを作成する -ノートを作成するには、画面上にある鉛筆マークのボタンを押して、作成フォームを開きます。作成フォームに内容を入力し、「ノート」ボタンを押すことでノートが作成されます。 ノートには、画像、動画など任意のファイルや、[アンケート](./poll)を添付することができます。また、本文中には[MFM](./mfm)が使用でき、[メンション](./mention)や[ハッシュタグ](./hashtag)を含めることもできます。 他にも、CWや公開範囲といった設定も行えます(詳細は後述)。 -
ℹ️ コンピューターのクリップボードに画像データがある状態で、フォーム内のテキストボックスにペーストするとその画像を添付することができます。
-
ℹ️ テキストボックス内でCtrl + Enterを押すことでも投稿できます。
- -## أعد النشر -既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノートをRenoteと呼びます。 自分がフォローしているユーザーの、気に入ったノートを自分のフォロワーに共有したい場合や、過去の自分のノートを再度共有したい場合に使います。 同じノートに対して無制限にRenoteを行うことができますが、あまり連続して使用すると迷惑になる場合もあるので、注意しましょう。 -
⚠️ 公開範囲がフォロワーやダイレクトのノートはRenoteできません
- -Renoteを削除するには、Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 - -## CW -Contents Warningの略で、ノートの内容を、閲覧者の操作なしには表示しないようにできる機能です。主に長大な内容を隠すためや、ネタバレ防止などに使うことができます。 設定するには、フォームの「内容を隠す」ボタン(目のアイコン)を押します。すると新しい入力エリアが表れるので、そこに内容の要約を記入します。 - -## الظهور -ノートごとに、そのノートが公開される範囲を設定することができます。フォームの「ノート」ボタンの左にあるアイコンを押すと公開範囲を以下から選択できます。 - -### للعامة -全ての人に対してノートが公開されるほか、サーバーの全てのタイムライン(ホームタイムライン、ローカルタイムライン、ソーシャルタイムライン、グローバルタイムライン)にノートが流れます。 -
⚠️ アカウントがサイレンス状態の時は、この公開範囲は使用できません。
- -### الرئيسي -全ての人に対してノートが公開されますが、フォロワー以外のローカルタイムライン、ソーシャルタイムライン、グローバルタイムラインにはノートは流れません。 - -### المتابِعين -自分のフォロワーに対してのみノートを公開します。フォロワーの全てのタイムラインに流れます。 - -### مباشرة -指定したユーザーに対してのみノートを公開します。指定したユーザーの全てのタイムラインに流れます。 - -### 「ローカルのみ」オプション -このオプションを有効にすると、リモートにノートを連合しなくなります。 - -### 公開範囲の比較 - - - - -
للعامةالرئيسيالمتابِعينمباشرة
フォロワーのLTL/STL/GTL
非フォロワーのLTL/STL/GTL
- -## دبّسها على الصفحة الشخصية -ノートをピン留めすると、ユーザーページに常にそのノートを表示しておくことができます。 ノートのメニューを開き、「ピン留め」を選択してピン留めできます。 複数のノートをピン留めできます。 - -## راقب -ノートをウォッチすると、自分以外のノートへのリアクションや返信などの通知を受け取ることができます。 ノートのメニューを開き、「ウォッチ」を選択してウォッチできます。 diff --git a/src/docs/ar-SA/features/pages.md b/src/docs/ar-SA/features/pages.md deleted file mode 100644 index a7311b95e..000000000 --- a/src/docs/ar-SA/features/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# Pages - -## 変数 -変数を使うことで動的なページを作成できます。テキスト内で { 変数名 } と書くとそこに変数の値を埋め込めます。例えば Hello { thing } world! というテキストで、変数(thing)の値が ai だった場合、テキストは Hello ai world! になります。 - -変数の評価(値を算出すること)は上から下に行われるので、ある変数の中で自分より下の変数を参照することはできません。例えば上から A、B、C と3つの変数を定義したとき、Cの中でABを参照することはできますが、Aの中でBCを参照することはできません。 - -ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。 - -関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。 diff --git a/src/docs/ar-SA/features/reaction.md b/src/docs/ar-SA/features/reaction.md deleted file mode 100644 index 305bfd25e..000000000 --- a/src/docs/ar-SA/features/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# تفاعل -他の人のノートに、絵文字を付けて簡単にあなたの反応を伝えられる機能です。 リアクションするには、ノートの + アイコンをクリックしてピッカーを表示し、絵文字を選択します。 リアクションには[カスタム絵文字](./custom-emoji)も使用できます。 - -## リアクションピッカーのカスタマイズ -ピッカーに表示される絵文字を自分好みにカスタマイズすることができます。 設定の「リアクション」で設定します。 - -## リモート投稿へのリアクションについて -リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。 - -## リモートからのリアクションについて -リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。 diff --git a/src/docs/ar-SA/features/silence.md b/src/docs/ar-SA/features/silence.md deleted file mode 100644 index 617ba64dc..000000000 --- a/src/docs/ar-SA/features/silence.md +++ /dev/null @@ -1,6 +0,0 @@ -# اكتم -サイレンスは、アカウントに設定される状態のひとつです。 - -アカウントがサイレンス状態になると、ノートの公開範囲をパブリックにできなくなります。 ホーム、フォロワー、ダイレクトは選択可能なため、サイレンスを受けた場合でもフォロワーやあなたのユーザーページを直接訪れた場合は投稿を閲覧できますが、GTL(連合タイムライン)やLTL(ローカルタイムライン)には投稿が流れません。 - -アカウントのサイレンス状態は、サーバーのモデレーターによって有効化/無効化されます。 diff --git a/src/docs/ar-SA/features/theme.md b/src/docs/ar-SA/features/theme.md deleted file mode 100644 index 59b582fa2..000000000 --- a/src/docs/ar-SA/features/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# المظهر - -テーマを設定して、Misskeyクライアントの見た目を変更できます。 - -## テーマの設定 -設定 > テーマ - -## テーマを作成する -テーマコードはJSON5で記述されたテーマオブジェクトです。 テーマは以下のようなオブジェクトです。 -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... テーマの一意なID。UUIDをおすすめします。 -* `name` ... テーマ名 -* `author` ... テーマの作者 -* `desc` ... テーマの説明(オプション) -* `base` ... 明るいテーマか、暗いテーマか - * `light`にすると明るいテーマになり、`dark`にすると暗いテーマになります。 - * テーマはここで設定されたベーステーマを継承します。 -* `props` ... テーマのスタイル定義。これから説明します。 - -### テーマのスタイル定義 -`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 - -#### バリューで使える構文 -* 16進数で表された色 - * 例: `#00ff00` -* `rgb(r, g, b)`形式で表された色 - * 例: `rgb(0, 255, 0)` -* `rgb(r, g, b, a)`形式で表された透明度を含む色 - * 例: `rgba(0, 255, 0, 0.5)` -* 他のキーの値の参照 - * `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。 - * 例: `@panel` -* 定数(後述)の参照 - * `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。 - * 例: `$main` -* 関数(後述) - * `:{関数名}<{引数}<{色}` - -#### 定数 -「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 キー名を`$`で始めると、そのキーはCSS変数として出力されません。 - -#### 関数 -wip diff --git a/src/docs/ar-SA/features/timeline.md b/src/docs/ar-SA/features/timeline.md deleted file mode 100644 index b280e3dcd..000000000 --- a/src/docs/ar-SA/features/timeline.md +++ /dev/null @@ -1,31 +0,0 @@ -# الخيط الزمني -タイムラインは、[ノート](./note)が時系列で表示される機能です。 タイムラインには以下で示す種類があり、種類によって表示されるノートも異なります。 なお、タイムラインの種類によってはサーバーにより無効になっている場合があります。 - -## الرئيسي -自分のフォローしているユーザーの投稿が流れます。HTLと略されます。 - -## المحلي -全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。LTLと略されます。 - -## الاجتماعي -自分のフォローしているユーザーの投稿と、全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。STLと略されます。 - -## الشامل -全てのローカルユーザーの「ホーム」指定されていない投稿と、サーバーに届いた全てのリモートユーザーの「ホーム」指定されていない投稿が流れます。GTLと略されます。 - -## مقارنة -| ソース | | | الخيط الزمني | | | -| ------------ | ---------- | ------- | ------------ | --------- | ------ | -| المستخدمون | الظهور | الرئيسي | المحلي | الاجتماعي | الشامل | -| ローカル (フォロー) | 公開 | ✔ | ✔ | ✔ | ✔ | -| | الرئيسي | ✔ | | ✔ | | -| | المتابِعين | ✔ | ✔ | ✔ | ✔ | -| リモート (フォロー) | 公開 | ✔ | | ✔ | ✔ | -| | الرئيسي | ✔ | | ✔ | | -| | المتابِعين | ✔ | | ✔ | ✔ | -| ローカル (未フォロー) | 公開 | | ✔ | ✔ | ✔ | -| | الرئيسي | | | | | -| | المتابِعين | | | | | -| リモート (未フォロー) | 公開 | | | | ✔ | -| | الرئيسي | | | | | -| | المتابِعين | | | | | diff --git a/src/docs/ar-SA/features/widgets.md b/src/docs/ar-SA/features/widgets.md deleted file mode 100644 index a7c2c1d1d..000000000 --- a/src/docs/ar-SA/features/widgets.md +++ /dev/null @@ -1,7 +0,0 @@ -# ウィジェット -ウィジェットは、MisskeyのUI上に設置できる小型の情報表示、操作が行えるパーツです。 - -ウィジェットを編集するには、ウィジェット編集モードに切り替えます。切り替え方法はUIによって異なります。 ウィジェット編集モードでは、ウィジェットの追加、削除、並び替え、およびそれぞれのウィジェットの設定を行えます。 - -## 利用可能なウィジェット一覧 -todo diff --git a/src/docs/ar-SA/features/word-mute.md b/src/docs/ar-SA/features/word-mute.md deleted file mode 100644 index fa4d14346..000000000 --- a/src/docs/ar-SA/features/word-mute.md +++ /dev/null @@ -1,20 +0,0 @@ -# ワードミュート -ワードミュートの設定をすると、条件に合致したノートが表示されなくなります。 - -ワードミュートには、ソフトワードミュートとハードワードミュートの2種類があります。それぞれについて設定の方法と挙動を説明します。 - -## ソフトワードミュート -ソフトワードミュートは、クライアント(アプリ)側でミュートを判断するワードミュートです。 - -ノートが設定した条件に合致すると、「(ユーザー名)が何かを言いました」という表示で隠れます。 -クリックすると元の通りに表示されます。 - -## ハードワードミュート -ハードワードミュートは、アンテナのようにサーバーが新しいノートの本文に対して条件に合致するかどうか判断し、タイムラインから対象となったノートを除外します。 - -つまり、ハードワードミュートには、以下のような特徴があります。 - -* 条件設定後、新しい投稿のみがミュートの対象になります。 -* 条件を変更しても、過去にハードミュートされたノートはミュートされたままになります。 -* 「○○が何かを言いました」でタイムラインが埋まることがありません。 -* ソフトミュートに非対応のアプリでも、ハードミュートは適用されます。 diff --git a/src/docs/ar-SA/follow.md b/src/docs/ar-SA/follow.md deleted file mode 100644 index 9b6562be9..000000000 --- a/src/docs/ar-SA/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# المتابَعون -ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。 diff --git a/src/docs/ar-SA/general/apps.md b/src/docs/ar-SA/general/apps.md deleted file mode 100644 index 81f99f281..000000000 --- a/src/docs/ar-SA/general/apps.md +++ /dev/null @@ -1,6 +0,0 @@ -# サードパーティアプリのリスト -## العملاء -todo - -## الخدمات المترابطة -todo diff --git a/src/docs/ar-SA/general/changelog.md b/src/docs/ar-SA/general/changelog.md deleted file mode 100644 index 6766a63b2..000000000 --- a/src/docs/ar-SA/general/changelog.md +++ /dev/null @@ -1,5 +0,0 @@ -# 更新履歴 -
ℹ️ このサーバーの更新履歴です。Misskeyの最新のリリースについては、GitHubをご確認ください。
- - - diff --git a/src/docs/ar-SA/general/faq.md b/src/docs/ar-SA/general/faq.md deleted file mode 100644 index c272b2ad4..000000000 --- a/src/docs/ar-SA/general/faq.md +++ /dev/null @@ -1,28 +0,0 @@ -# よくある質問 -ここでは利用上のよくある質問について掲載しています。 Misskeyのプロジェクト自体についてのよくある質問は[こちら](./misskey)に掲載されています。 - -## iOS/Androidのアプリはありますか? -公式にはそういったOSのネイティブアプリを開発していませんが、サードパーティ製のアプリがいくつかあります。 詳しくは[こちら](./apps)をご覧ください。 - -ただ、サードパーティ製アプリはどうしても機能への対応が遅れてしまうため、とくに拘りがなければ公式のWebクライアントの利用をおすすめします。 なお、MisskeyのWebクライアントはPWAに対応しているので、ネイティブアプリのように動作させることも可能です。 詳しくは[こちら](todo)をご覧ください。 - -## Mastodonクライアントでログインできないのですが? -MisskeyはMastodonのAPIと互換性がないため、一部を除きMastodonクライアントでMisskeyを利用することはできません。 - -## 他のサーバーのユーザーをフォローするときは? -メニューから検索を選び、ユーザー名をホスト込みで入力します。例: `@syuilo@misskey.io` - -## Renoteを削除するには? -Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 Renoteについては[こちら](../features/note)をご確認ください。 - -## URLのプレビューを表示させたくない -MFMには、そのURLのプレビューを無効にする構文があります。詳細は[MFMチートシート](/mfm-cheat-sheet)をご確認ください。 - -## カスタム絵文字を追加したい -運営者のみがカスタム絵文字を追加、編集、削除できます。それらを希望する場合は運営者に依頼してください。 - -## Botを開発したい -Misskey APIを利用してBotの開発が可能です。[こちら](../advanced/develop-bot)をご確認ください。 - -## ノートの翻訳機能はどのサービスを使用していますか? -[DeepL](https://www.deepl.com/)を使用しています。 diff --git a/src/docs/ar-SA/general/glossary.md b/src/docs/ar-SA/general/glossary.md deleted file mode 100644 index 0534c8d7c..000000000 --- a/src/docs/ar-SA/general/glossary.md +++ /dev/null @@ -1,89 +0,0 @@ -# 用語集 -Misskeyに関する用語集です。 - -## ActivityPub -(読み: あくてぃびてぃぱぶ) 分散型を実現するために用いられるプロトコル(仕様)。このプロトコルに則ってサーバー同士通信を行うことで、連合が行われ、Fediverseを形成しています。 - -## AiScript -(読み: あいすくりぷと) Misskey上で使用できるプログラミング言語です。詳細は[こちら。](../advanced/aiscript) - -## API -(読み: えーぴーあい) Misskeyのサーバーが公開している、プログラムからMisskeyを扱うためのインターフェース。詳細は[こちら。](../advanced/api) - -## Bot -(読み: ぼっと) プログラムによって動作しているアカウント。 - -## CW -(読み: こんてんつわーにんぐ) Contents Warningの略。ノートの内容を、操作なしには表示しないようにできる機能。主に長大な内容を隠すためや、ネタバレ防止などに使われます。 - -## Fediverse -(読み: ふぇでぃばーす) Misskeyを含む様々な分散型ソフトウェアのサーバーで構成されたネットワーク。 - -## GTL -グローバルタイムライン(Global TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## HTL -ホームタイムライン(Home TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## LTL -ローカルタイムライン(Local TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## MFM -(読み: えむえふえむ) Misskey Flavored Markdownの略で、Misskey上で使用できるマークアップ言語です。詳細は[こちら。](../features/mfm) - -## NSFW -(読み: のっとせーふふぉーわーく) Not Safe For Workの略。画像を「閲覧注意」扱いにし、操作なしには表示しないようにすることができる機能。 - -## أعد النشر -(読み: りのーと) 既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノート。詳細は[こちら。](../features/note) - -## STL -ソーシャルタイムライン(Social TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## 藍 -(読み: あい) Misskeyの看板娘(公式キャラクター)です。 - -## アクティブユーザー -インスタンスにアカウントを作っているユーザーのうち、現在も実際にサービスを利用しているユーザーのこと。 - -## مثيل الخادم -todo - -## إيموجي مخصص -サーバーで用意された絵文字。カスタム絵文字ではない通常の絵文字は「Unicode絵文字」と区別して呼ばれる。 - -## コントロールパネル -インスタンスの設定画面のこと。 - -## サーバー -todo - -## اكتم -ノートをパブリックな公開範囲で投稿できなくされている状態。モデレーターの判断でユーザーごとに設定されます。詳細は[こちら。](../features/silence) - -## قائمة الانتظار -アクティビティ配送などを順番に行うためのシステム。 - -## علِق -アカウントが使用不可に設定されている状態。 - -## قرص التخرين -Misskeyにアップロードしたファイルを管理する機能。詳細は[こちら。](../features/drive) - -## الملاحظات -Misskeyに投稿される、文章、ファイル、アンケートなどを含めることができるコンテンツ。詳細は[こちら。](../features/note) - -## ミスキスト -Misskeyを使う人のこと。 - -## مشرِف -スパムの凍結およびサイレンスや不適切な投稿の削除など、コミュニティ運営に関する権限を持つユーザー。 - -## بُعدي -他サーバーのことを指します。リモートユーザーといったように接頭辞としても使われます。ローカルの逆です。 - -## الفديرالية -サーバー上で作成された情報が他のサーバーに伝わること。 - -## المحلي -自サーバーのことを指します。ローカルユーザー、ローカルタイムラインといったように接頭辞としても使われます。リモートの逆です。 diff --git a/src/docs/ar-SA/general/links.md b/src/docs/ar-SA/general/links.md deleted file mode 100644 index 2943015c9..000000000 --- a/src/docs/ar-SA/general/links.md +++ /dev/null @@ -1,12 +0,0 @@ -# リンク集 - -## Webサイト -- [Official Discord](https://discord.gg/Wp8gVStHW3) - Misskey公式Discordサーバー -- [Misskey Forum](https://forum.misskey.io/) - Misskeyに関する話題を扱うフォーラム - -## الحسابات -- [@repo@misskey.io](https://misskey.io/@repo) - Misskeyのリポジトリの更新を投稿するbot - -## ライブラリ -- [misskey-dev/misskey.js](https://github.com/misskey-dev/misskey.js) - JavaScriptのMisskey SDK -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptのMFMパーサー実装 diff --git a/src/docs/ar-SA/general/misskey.md b/src/docs/ar-SA/general/misskey.md deleted file mode 100644 index 5c27323d7..000000000 --- a/src/docs/ar-SA/general/misskey.md +++ /dev/null @@ -1,87 +0,0 @@ -# عن Misskey - -Misskeyはオープンソースの分散型マイクロブログプラットフォームプロジェクトです。 開発は日本でsyuiloによって2014年から開始されました。 ドライブ、リアクションなどの豊富な機能や、高いカスタマイズ性を備えたUIを持つことが特徴です。 - -## 歴史 -開発当初は掲示板がメインのサービスでしたが、ユーザーが短文を投稿し、それを時系列で流れるタイムライン機能を追加したところ人気が高まり、徐々にそれがメインとして開発が進むようになりました。 当初は分散型ではありませんでしたが、2018年にActivityPubを実装し分散型になったことで、より多くの方に認知され利用されるサービスになり、現在に至ります。 -
ℹ️ Misskeyという名前は、syuiloが当時聴いていたMay'nというアーティストの楽曲、Brain Diverの歌詞に由来します。
- -誰でも開発に参加することができ、現在でも活発に開発が続いています。 - -## 分散型とは何か? - -分散(distributed)型とは、非中央集権(decentralized)とも呼ばれ、コミュニティが多数のサーバーに分散して存在し、それらが相互に通信(連合、federation)することでコンテンツ共有ネットワーク(Fediverse)を形成していることが特徴のサービスです。 単一のサーバーしか存在しない、もしくは複数存在しても互いに独立している場合は中央集権なサービスと言われ、例えばTwitterやFacebookなどほとんどのサービスがそれに該当します。 分散型のメリットは、自分に合った運営者やテーマのサーバーを選択できることです。自分でサーバーを作成することもできます。連合するおかげで、どのサーバーを選んでも、同じコミュニティにアクセスできます。 - -## 常にオープンソース -Misskeyはこれまでもこれからも、オープンソースであり続けます。オープンソースとは、簡単に言うとソフトウェアのソースコード(プログラム)が公開されていることです。ソースコードの修正や再配布が可能であることを定義に含めることもあります。 Misskeyのすべてのソースコードは[AGPL](https://github.com/misskey-dev/misskey/blob/develop/LICENSE)というオープンソースライセンスの下に[公開](https://github.com/misskey-dev)されていて、誰でも自由に閲覧、使用、修正、改変、再配布をすることができます。 オープンソースは、自分で好きなように変えたり、有害な処理が含まれていないことを確認することができたり、誰でも開発に参加できるなどの、様々なメリットがあります。 上述の分散型を実現するためにも、オープンソースであるということは必要不可欠な要素です。 再び引き合いに出しますが、TwitterやFacebookなどの利益を得ているほとんどのサービスはオープンソースではありません。 - -
ℹ️ 技術的に言うと、MisskeyのソースコードはGitで管理されていて、リポジトリはGitHub上でホスティングされています。
- -## 開発に参加する、プロジェクトを支援する -Misskeyを気に入っていただけたら、ぜひプロジェクトを支援してください。プロジェクトに貢献するには、以下で紹介するようにいろいろな方法があります。方法によっては開発のスキルは不要なので、誰でも気軽に参加し貢献することができます。いつでもお待ちしています。 - -### 機能を追加したり、バグを修正する -ソフトウェアエンジニアのスキルをお持ちの方であれば、ソースコードを編集する形でプロジェクトに貢献することができます。 貢献についてのガイドは[こちら](https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md)です。 - -### 議論に参加する -新しい機能、または既存の機能について意見を述べたり、不具合を報告したりすることでも貢献できます。 そのようなディスカッションは[GitHub](https://github.com/misskey-dev)上か、[フォーラム](https://forum.misskey.io/)等で行われます。 - -### テキストを翻訳する -Misskeyは様々な言語に対応しています(i18n -internationalizationの略- と呼ばれます)。元の言語は基本的に日本語ですが、有志によって他の言語へと翻訳されています。 その翻訳作業に加わっていただくことでもMisskeyに貢献できます。 Misskeyは[Crowdinというサービスを使用して翻訳の管理を行っています。](https://crowdin.com/project/misskey) - -### 感想を投稿する -不具合報告等だけではなく、Misskeyの良い点、楽しい点といったポジティブな意見もぜひ共有してください。開発の励みになり、それは間接的ですがプロジェクトへの貢献です。 - -### ミスキストを増やす -ミスキストとは、Misskeyを使用する人のことです。 知り合いに紹介するなどしてMisskeyを広めていただければ、ミスキストが増え開発のモチベーションが上がります。 - -### 寄付をする -Misskeyはビジネスではなく、利用は無料であるため、収益は皆様からの寄付のみです。(インスタンスによっては広告収入を得ているような場合もありますが、それは運営者の収入であり直接開発者への収入にはなりません) 寄付をしていただければ、今後も開発を続けることが可能になり、プロジェクトへの貢献になります。 寄付は基本的には[Patreon](https://www.patreon.com/syuilo)で受け付けています。 一定額寄付していただけると、Misskeyの[情報ページ](/about-misskey)に名前を記載することができます。 - -また、サーバーの運営者も、基本的には収益を得ていません。サーバーの運営にはコストがかかるので、運営者の支援をすることもご検討ください。 開発には直接関係しませんが、サーバーがあってこそのプロジェクトなので、運営が維持されるというのは開発と同じくらい重要なことです。 - -## クレジット -Misskeyの開発者や、Misskeyに寄付をしてくださった方の一覧は[こちら](/about-misskey)で見ることができます。 - -## よくある質問 -### プロジェクトは何を目指していますか? -強いて言うと、漠然的になりますが広く使われる汎用的なプラットフォームになることを目指しています。 Misskeyは他のプロジェクトとは違い、何らかの思想(例えば、反中央集権)やビジョンに基づいて開発が行われているわけではなく、その点ではフラットです。 それが逆に、特定の方向性に縛られないフレキシブルさを生み出すことに繋がっていると感じています。 - - -### 企業によって開発されていますか? -いいえ。Misskeyの開発は個人で行われており、商業的でもないため、特定の企業の関りはありません。 開発メンバーも基本的にはボランティアです。 また、開発に対し企業のスポンサーがつくこともありますが、その場合でもやはり開発は個人のコミュニティが主体です。 - -### 誰が運営していますか? -Misskeyは分散型なため、各サーバーにそれぞれ異なった運営者がいます。従って、特定の個人や企業によって、Misskeyの全てが運営されているわけではありません。 また、開発チームが運営を行うわけでもないため、運営に関する連絡は、お使いのサーバーの運営者に行ってください。 サーバーの運営者は、[このページ](/about)で確認することができます。 あなたがサーバーを作成すれば、あなたが運営者になります。 - -### どのサーバーを選べばいいですか? -[サーバー一覧が公開されています。](https://join.misskey.page/ja-JP/instances) サーバーによってコミュニティのテーマ(特定のこと、ものが好き 等)が決められている場合があるので、自分に合ったテーマのサーバーがあれば、そこを選ぶと良いかもしれません。 他にも、サーバーの規模、ユーザー層、国および言語、運営者が信頼できるかどうか、などの観点があります。 なお、Misskey公式のサーバーというものはありません。自身で新しくサーバーを作成するという選択肢もあります。 - -基本的にどのサーバーを選んだとしても、他の全てのサーバーのユーザーと繋がることができます。 - -### サーバーを建てるにはどうしたらいいですか? -Misskeyサーバーの作成に興味を持っていただきありがとうございます。 2021年現在、Misskeyのホスティングサービスは存在しないため、サーバーの作成にはある程度の知識が必要です。 サーバーの作成方法については[こちら](todo)をご覧ください。 - -### どのような技術を使用していますか? -Misskeyは開発が進むにつれ使用する技術も大きく変わってきました。開発当初はMySQL + PHP + jQueryといった構成でしたが、現在は以下のようになっています。 -- サーバーサイド: Node.js -- データベース: PostgreSQL、Redis -- UIフレームワーク: Vue.js -- プログラミング言語: TypeScript - -また、MFMやAiScriptなどの、Misskeyから派生して独自の技術も開発しています。 - -### Mastodonのフォークですか? -いいえ。MisskeyはMastodonやその他のプロジェクトとは全く別のプロジェクトです。 開発に関しても、Misskeyの方が昔から開発されています。ただし、分散型になったのはMastodonの登場より後です。 同じActivityPubという分散のためのプロトコルを実装しているという点以外、両者に特に関りがあるわけでもありません。 - -### iOS/Androidのアプリはありますか? -公式にはそういったOSのネイティブアプリを開発していませんが、サードパーティ製のアプリがいくつかあります。 詳しくは[こちら](./apps)をご覧ください。 - -ただ、サードパーティ製アプリはどうしても機能への対応が遅れてしまうため、とくに拘りがなければ公式のWebクライアントの利用をおすすめします。 なお、MisskeyのWebクライアントはPWAに対応しているので、ネイティブアプリのように動作させることも可能です。 詳しくは[こちら](todo)をご覧ください。 - -### Misskeyのロゴ、アイコンはどこで入手できますか? -(準備中) - -### 時折目にする猫耳の可愛い女の子は? -Misskeyの守り神、藍ちゃんです。アイチャンカワイイヤッター! -
ℹ️ 藍ちゃんについてはこちらです。
diff --git a/src/docs/ar-SA/general/report-issue.md b/src/docs/ar-SA/general/report-issue.md deleted file mode 100644 index 63527e32a..000000000 --- a/src/docs/ar-SA/general/report-issue.md +++ /dev/null @@ -1,8 +0,0 @@ -# 不具合の報告 -不具合と思われる状況に遭遇したときは、まず[トラブルシューティング](./troubleshooting)をご一読ください。 それでも問題が解決しないときは、以下の情報を含めて[フォーラム](https://forum.misskey.io/)に投稿してください。 投稿することで、解決策が見つかったり、不具合と判断されれば開発チームによって修正が行われます。 - -## 含める情報 -- Misskeyのバージョン([情報ページ](/about)で確認できます) -- お使いのブラウザの種類とバージョン -- お使いのOSの種類とバージョン -- 問題の再現手順 diff --git a/src/docs/ar-SA/general/troubleshooting.md b/src/docs/ar-SA/general/troubleshooting.md deleted file mode 100644 index f895b4984..000000000 --- a/src/docs/ar-SA/general/troubleshooting.md +++ /dev/null @@ -1,40 +0,0 @@ -# トラブルシューティング -
ℹ️ よくある質問も合わせてお役立てください。
- -問題が発生したときは、まずこちらをご確認ください。 該当する項目が無い、もしくは手順を試しても効果がない場合は、サーバーの管理者に連絡するか[不具合を報告](./report-issue)してください。 - -## クライアントが起動しない -ほとんどの場合、お使いのブラウザまたはOSのバージョンが古いことが原因です。 ブラウザおよびOSのバージョンを最新のものに更新してから、再度試してみてください。 - -これは稀ですが、それでも起動しない場合は、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。 - -## ページが読み込めない -クライアントが起動するもののページが読み込めないというエラーが出る場合は、ネットワークに問題がないか確認してください。また、サーバーがダウンしていないか確認してください。 - -これは稀ですが、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。 - -まだ問題がある場合は、サーバーの問題と思われるのでサーバーの管理者に連絡してください。 - -## クライアントの動作が遅い -以下を試してみてください: - -- クライアント設定で「UIのアニメーションを減らす」を有効にする -- クライアント設定で「モーダルにぼかし効果を使用」を無効にする -- お使いのブラウザの設定でハードウェアアクセラレーションを有効にする -- お使いのデバイスのスペックを上げる - -## UIの一部の表示がおかしい(背景が透明になっている等) -アップデートによりUIの改修が行われたときに、テーマのキャッシュシステムの影響でそのような表示になることがあります。 クライアントの設定の「キャッシュをクリア」すると直ります。 -
⚠️ 「クライアントの」キャッシュクリアです。「ブラウザの」キャッシュクリアは行わないでください。
- -## 通知やアンテナ等の点滅が消えない -点滅は、未読のコンテンツがあることを示しています。通常点滅が消えない場合は、コンテンツを遡ると未読なコンテンツが残っています。 すべて既読にしたと思われるのに、それでもなお点滅が続く場合(おそらく不具合と思われます)は設定から強制的にすべて既読扱いにすることができます。 - -## Renoteができない -フォロワー限定のノートはRenoteすることはできません。 - -## UI上で特定の要素が表示されない -広告ブロッカーを使用しているとそのような不具合が発生することがあります。Misskeyではオフにしてご利用ください。 - -## UI上で未翻訳の部分がある -ほとんどの場合、単に翻訳が間に合っていないだけで、不具合ではありません。翻訳が終わるまでお待ちください。 [翻訳に参加](./misskey)していただくことも可能です。 diff --git a/src/docs/ar-SA/keyboard-shortcut.md b/src/docs/ar-SA/keyboard-shortcut.md deleted file mode 100644 index 8ca24ad41..000000000 --- a/src/docs/ar-SA/keyboard-shortcut.md +++ /dev/null @@ -1,68 +0,0 @@ -# キーボードショートカット - -## الشامل -これらのショートカットは基本的にどこでも使えます。 - - - - - - - - - - - -
ショートカット効果由来
P, N新規投稿Post, New, Note
Tタイムラインの最も新しい投稿にフォーカスTimeline, Top
Shift + N通知を表示/隠すNotifications
SالبحثSearch
H, ?ヘルプを表示Help
- -## 投稿にフォーカスされた状態 - - - - - - - - - - - - - - - - - - - -
ショートカット効果由来
, K, Shift + Tab上の投稿にフォーカスを移動-
, J, Tab下の投稿にフォーカスを移動-
R返信フォームを開くReply
QRenoteフォームを開くQuote
Ctrl + Q即刻Renoteする(フォームを開かずに)-
E, A, +リアクションフォームを開くEmote, reAction
0~9数字に対応したリアクションをする(対応については後述)-
F, Bお気に入りに登録Favorite, Bookmark
Del, Ctrl + D投稿を削除Delete
M, O投稿に対するメニューを開くMore, Other
SCWで隠された部分を表示 or 隠すShow, See
Escフォーカスを外す-
- -## Renoteフォーム - - - - - - - - - - -
ショートカット効果由来
EnterRenoteする-
Qフォームを展開するQuote
Escフォームを閉じる-
- -## リアクションフォーム -デフォルトで「👍」にフォーカスが当たっている状態です。 - - - - - - - - - - - - - -
ショートカット効果由来
, K上のリアクションにフォーカスを移動-
, J下のリアクションにフォーカスを移動-
, H, Shift + Tab左のリアクションにフォーカスを移動-
, L, Tab右のリアクションにフォーカスを移動-
Enter, Space, +リアクション確定-
0~9数字に対応したリアクションで確定-
Escリアクションするのをやめる-
diff --git a/src/docs/ar-SA/mfm.md b/src/docs/ar-SA/mfm.md deleted file mode 100644 index e237287ac..000000000 --- a/src/docs/ar-SA/mfm.md +++ /dev/null @@ -1,2 +0,0 @@ -# MFM -MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます。 diff --git a/src/docs/ar-SA/mute.md b/src/docs/ar-SA/mute.md deleted file mode 100644 index c04ebcfd7..000000000 --- a/src/docs/ar-SA/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# اكتم - -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -* タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -* そのユーザーからの通知 -* メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 - -ユーザーをミュートするには、対象のユーザーのユーザーページに表示されている「ミュート」ボタンを押します。 - -ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。 - -設定>ミュート から、自分がミュートしているユーザー一覧を確認することができます。 diff --git a/src/docs/ar-SA/pages.md b/src/docs/ar-SA/pages.md deleted file mode 100644 index a7311b95e..000000000 --- a/src/docs/ar-SA/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# Pages - -## 変数 -変数を使うことで動的なページを作成できます。テキスト内で { 変数名 } と書くとそこに変数の値を埋め込めます。例えば Hello { thing } world! というテキストで、変数(thing)の値が ai だった場合、テキストは Hello ai world! になります。 - -変数の評価(値を算出すること)は上から下に行われるので、ある変数の中で自分より下の変数を参照することはできません。例えば上から A、B、C と3つの変数を定義したとき、Cの中でABを参照することはできますが、Aの中でBCを参照することはできません。 - -ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。 - -関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。 diff --git a/src/docs/ar-SA/reaction.md b/src/docs/ar-SA/reaction.md deleted file mode 100644 index bd096799e..000000000 --- a/src/docs/ar-SA/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# تفاعل -他の人のノートに、絵文字を付けて簡単にあなたの反応を伝えられる機能です。 リアクションするには、ノートの + アイコンをクリックしてピッカーを表示し、絵文字を選択します。 リアクションには[カスタム絵文字](./custom-emoji)も使用できます。 - -## リアクションピッカーのカスタマイズ -ピッカーに表示される絵文字を自分好みにカスタマイズすることができます。 設定の「リアクション」で設定します。 - -## リモート投稿へのリアクションについて -リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。 また、相手がMisskeyであったとしても、カスタム絵文字リアクションは伝わらず、自動的に「👍」等にフォールバックされます。 - -## リモートからのリアクションについて -リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。 diff --git a/src/docs/ar-SA/reversi-bot.md b/src/docs/ar-SA/reversi-bot.md deleted file mode 100644 index 7ab2a7212..000000000 --- a/src/docs/ar-SA/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# MisskeyリバーシBotの開発 -Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。 - -1. `games/reversi`ストリームに以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - -2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる - * イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている - -3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する - -4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - * `game`: `game`の`id` - -5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う - -6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する - -7. ゲームが開始すると、`started`イベントが流れてくる - * イベントの中身にはゲーム情報が含まれている - -8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述) - -9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる - * `color`として石の色が含まれている - * `pos`として位置情報が含まれている - -## 位置の計算法 -8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### X,Y座標 から インデックス に変換する -``` -pos = x + (y * mapWidth) -``` -`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます: -``` -mapWidth = map[0].length -``` - -### インデックス から X,Y座標 に変換する -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## マップ情報 -マップ情報は、ゲーム情報の`map`に入っています。 文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 それをもとにマップのデザインを知る事が出来ます: -* `(スペース)` ... マス無し -* `-` ... マス -* `b` ... 初期配置される黒石 -* `w` ... 初期配置される白石 - -例えば、4*4の次のような単純なマップがあるとします: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -この場合、マップデータはこのようになります: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## ユーザーにフォームを提示して対話可能Botを作成する -ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。 - -フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します: -```javascript -{ - type: 'init-form', - body: [フォームコントロールの配列] -} -``` - -フォームコントロールの配列については今から説明します。 フォームコントロールは、次のようなオブジェクトです: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... コントロールのID。 `type` ... コントロールの種類。後述します。 `label` ... コントロールと一緒に表記するテキスト。 `value` ... コントロールのデフォルト値。 - -### フォームの操作を受け取る -ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### フォームコントロールの種類 -#### スイッチ -type: `switch` スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。 - -##### プロパティ -`label` ... スイッチに表記するテキスト。 - -#### ラジオボタン -type: `radio` ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。 - -##### プロパティ -`items` ... ラジオボタンの選択肢。例: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '強', - value: 3 -}] -``` - -#### スライダー -type: `slider` スライダーを表示します。 - -##### プロパティ -`min` ... スライダーの下限。 `max` ... スライダーの上限。 `step` ... 入力欄で刻むステップ値。 - -#### テキストボックス -type: `textbox` テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。 - -## ユーザーにメッセージを表示する -設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 メッセージを表示するには、次のメッセージをストリームに送信します: -```javascript -{ - type: 'message', - body: { - text: 'メッセージ内容', - type: 'メッセージの種類' - } -} -``` -メッセージの種類: `success`, `info`, `warning`, `error`。 - -## 投了する -投了をするには、このエンドポイントにリクエストします。 diff --git a/src/docs/ar-SA/stream.md b/src/docs/ar-SA/stream.md deleted file mode 100644 index 9011c37c5..000000000 --- a/src/docs/ar-SA/stream.md +++ /dev/null @@ -1,354 +0,0 @@ -# ストリーミングAPI - -ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。 - -## ストリームに接続する - -ストリーミングAPIを利用するには、まずMisskeyサーバーに**websocket**接続する必要があります。 - -以下のURLに、`i`というパラメータ名で認証情報を含めて、websocket接続してください。例: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。 - -
-

認証情報の取得については、こちらのドキュメントをご確認ください。

-
- ---- - -認証情報は省略することもできますが、その場合非ログインでの利用ということになり、受信できる情報や可能な操作は限られます。例: - -``` -%WS_URL%/streaming -``` - ---- - -ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。 - -**ストリームでのやり取りはすべてJSONです。** - -## チャンネル -MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。 - -### チャンネルに接続する -チャンネルに接続するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -ここで、 -* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。 -* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。 -* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。 - -
-

IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。

-
- -### チャンネルからのメッセージを受け取る -例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。 - -チャンネルがメッセージを発すると、次のようなデータがJSONでストリームに流れてきます: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。 -* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。 -* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。 - -### チャンネルに向けてメッセージを送信する -チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。 - -チャンネルにメッセージを送信するには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。 -* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。 -* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。 - -### チャンネルから切断する -チャンネルから切断するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。 - -## ストリームを経由してAPIリクエストする - -ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。 - -ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -ここで、 -* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 -* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 -* `data`には、エンドポイントのパラメータを含めます。 - -
-

APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。

-
- -### レスポンスの受信 - -APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。 - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -ここで、 -* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 -* `body`には、レスポンスが含まれています。 - -## 投稿のキャプチャ - -Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。 - -例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。 - -しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。 - -この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。 - -### 投稿をキャプチャする - -投稿をキャプチャするには、ストリームに次のようなメッセージを送信します: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャしたい投稿の`id`を設定します。 - -このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 - -例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -ここで、 -* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。 -* `body`内の`type`に、イベントの種類が設定されます。 -* `body`内の`body`に、イベントの詳細が設定されます。 - -#### イベントの種類 - -##### `reacted` -その投稿にリアクションがされた時に発生します。 - -* `reaction`に、リアクションの種類が設定されます。 -* `userId`に、リアクションを行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -その投稿が削除された時に発生します。 - -* `deletedAt`に、削除日時が設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -その投稿に添付されたアンケートに投票された時に発生します。 - -* `choice`に、選択肢IDが設定されます。 -* `userId`に、投票を行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### 投稿のキャプチャを解除する - -その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。 - -次のメッセージを送信します: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャを解除したい投稿の`id`を設定します。 - -このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 - -# チャンネル一覧 -## `main` -アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `renote` -自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。 - -#### `mention` -誰かからメンションされたときに発生するイベントです。 - -#### `readAllNotifications` -自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。 - -#### `meUpdated` -自分の情報が更新されたことを表すイベントです。 - -#### `follow` -自分が誰かをフォローしたときに発生するイベントです。 - -#### `unfollow` -自分が誰かのフォローを解除したときに発生するイベントです。 - -#### `followed` -自分が誰かにフォローされたときに発生するイベントです。 - -## `homeTimeline` -ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -タイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `localTimeline` -ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `hybridTimeline` -ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ソーシャルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `globalTimeline` -グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 diff --git a/src/docs/ar-SA/theme.md b/src/docs/ar-SA/theme.md deleted file mode 100644 index 59b582fa2..000000000 --- a/src/docs/ar-SA/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# المظهر - -テーマを設定して、Misskeyクライアントの見た目を変更できます。 - -## テーマの設定 -設定 > テーマ - -## テーマを作成する -テーマコードはJSON5で記述されたテーマオブジェクトです。 テーマは以下のようなオブジェクトです。 -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... テーマの一意なID。UUIDをおすすめします。 -* `name` ... テーマ名 -* `author` ... テーマの作者 -* `desc` ... テーマの説明(オプション) -* `base` ... 明るいテーマか、暗いテーマか - * `light`にすると明るいテーマになり、`dark`にすると暗いテーマになります。 - * テーマはここで設定されたベーステーマを継承します。 -* `props` ... テーマのスタイル定義。これから説明します。 - -### テーマのスタイル定義 -`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 - -#### バリューで使える構文 -* 16進数で表された色 - * 例: `#00ff00` -* `rgb(r, g, b)`形式で表された色 - * 例: `rgb(0, 255, 0)` -* `rgb(r, g, b, a)`形式で表された透明度を含む色 - * 例: `rgba(0, 255, 0, 0.5)` -* 他のキーの値の参照 - * `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。 - * 例: `@panel` -* 定数(後述)の参照 - * `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。 - * 例: `$main` -* 関数(後述) - * `:{関数名}<{引数}<{色}` - -#### 定数 -「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 キー名を`$`で始めると、そのキーはCSS変数として出力されません。 - -#### 関数 -wip diff --git a/src/docs/ar-SA/timelines.md b/src/docs/ar-SA/timelines.md deleted file mode 100644 index 1a1b34b87..000000000 --- a/src/docs/ar-SA/timelines.md +++ /dev/null @@ -1,15 +0,0 @@ -# مقارنة الجدول الزمني - -https://docs.google.com/spreadsheets/d/1lxQ2ugKrhz58Bg96HTDK_2F98BUritkMyIiBkOByjHA/edit?usp=sharing - -## الواجهة الرئيسية -مشاركات المستخدمين الذين تتابعهم - -## المحلي -جميع مشاركات المستخدمين المحليين التي لم يتم وضع علامة عليها على أنها "صفحة رئيسية فقط " - -## إجتماعي -مشاركات المستخدمين الذين تتابعهم بالإضافة إلى جميع مشاركات المستخدمين المحليين التي لم يتم وضع علامة عليها كـ "الصفحة الرئيسية فقط" - -## عالمي -全てのローカルユーザーの「ホーム」指定されていない投稿と、サーバーに届いた全てのリモートユーザーの「ホーム」指定されていない投稿 diff --git a/src/docs/cs-CZ/admin/disable-timelines.md b/src/docs/cs-CZ/admin/disable-timelines.md deleted file mode 100644 index b081e35ab..000000000 --- a/src/docs/cs-CZ/admin/disable-timelines.md +++ /dev/null @@ -1,8 +0,0 @@ -# LTL/STL/GTLの無効化 -Misskeyでは、LTL/STL/GTLをそれぞれ無効化することができます。有効/無効を切り替えるには、インスタンスコントロールパネルで設定します。 - -LTLやSTLは、そのインスタンス全員の投稿が見れるため、新規のユーザーにとってはユーザーを探す必要がなくなり、興味のあるユーザーを見つけやすいという利点があります。 しかし同時に、フォロー機能が活用されなくなったり、不適切な投稿が目につきやすくなったり、チャットのようになることで内輪感が生じて逆に新規ユーザーが参加しにくくなるといったデメリットも持ち合わせています。 サーバーによってメリット/デメリットどちらが優勢かは異なるので、オプションとして無効にできるようになっています。 もしデメリットの方が上回っていると感じたら、それらのタイムラインを無効化することも検討してください。 - -
⚠️ 無効化を行うと、ユーザーが困惑し、短期的に見て利用者が減る可能性があります。そのため、無効化の際は影響を慎重に検討し、事前に説明してフォローを整える期間を一定程度設けることを推奨します。
- -なお、管理者/モデレーターは、これらのタイムラインの無効化状態は適用されず、引き続き利用することが可能です。 diff --git a/src/docs/cs-CZ/admin/faq.md b/src/docs/cs-CZ/admin/faq.md deleted file mode 100644 index 317b4e065..000000000 --- a/src/docs/cs-CZ/admin/faq.md +++ /dev/null @@ -1,5 +0,0 @@ -# よくある質問 -ここでは、サーバー管理者向けのよくある質問を掲載しています。 - -## デフォルトテーマを設定したい -現在、デフォルトテーマ設定機能は実装されていません。 diff --git a/src/docs/cs-CZ/advanced/aiscript.md b/src/docs/cs-CZ/advanced/aiscript.md deleted file mode 100644 index 604d17daa..000000000 --- a/src/docs/cs-CZ/advanced/aiscript.md +++ /dev/null @@ -1,7 +0,0 @@ -# AiScript -AiScriptは、Misskeyで使用できるスクリプト言語です。 - -
ℹ️ AiScript実装はMisskeyとは別リポジトリで、オープンソースで公開されています。
- -## 使い方 -AiScriptの構文や組み込み関数などのドキュメントは、[こちら](https://github.com/syuilo/aiscript/tree/master/docs)で公開されています。 diff --git a/src/docs/cs-CZ/advanced/api.md b/src/docs/cs-CZ/advanced/api.md deleted file mode 100644 index 76019b614..000000000 --- a/src/docs/cs-CZ/advanced/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス、Bot等(以下「アプリケーション」と呼びます)を開発できます。 ストリーミングAPIもあるので、リアルタイム性のあるアプリケーションを作ることも可能です。 - -APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。 - -## アクセストークンの取得 -基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。 - -* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む -* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む - -### 自分自身のアクセストークンを手動発行する -「設定 > API」で、自分のアクセストークンを発行できます。 - -[「APIの使い方」へ進む](#APIの使い方) - -### アプリケーション利用者にアクセストークンの発行をリクエストする -アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。 - -#### Step 1 - -UUIDを生成する。以後これをセッションIDと呼びます。 - -> このセッションIDは毎回生成し、使いまわさないようにしてください。 - -#### Step 2 - -`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。 -> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます: -* `name` ... アプリケーション名 - * > 例: `MissDeck` -* `icon` ... アプリケーションのアイコン画像URL - * > 例: `https://missdeck.example.com/icon.png` -* `callback` ... 認証が終わった後にリダイレクトするURL - * > 例: `https://missdeck.example.com/callback` - * リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます -* `permission` ... アプリケーションが要求する権限 - * > 例: `write:notes,write:following,read:drive` - * 要求する権限を`,`で区切って列挙します - * どのような権限があるかは[APIリファレンス](/api-doc)で確認できます - -#### Step 3 -ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。 - -レスポンスに含まれるプロパティ: -* `token` ... ユーザーのアクセストークン -* `user` ... ユーザーの情報 - -[「APIの使い方」へ進む](#APIの使い方) - -## APIの使い方 -**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。 - -* [APIリファレンス](/api-doc) -* [ストリーミングAPI](./stream) diff --git a/src/docs/cs-CZ/advanced/create-plugin.md b/src/docs/cs-CZ/advanced/create-plugin.md deleted file mode 100644 index ec17b9518..000000000 --- a/src/docs/cs-CZ/advanced/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# プラグインの作成 -Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。 - -## Metadata -プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。 - -### name -プラグイン名 - -### author -プラグイン作者 - -### version -プラグインバージョン。数値を指定してください。 - -### description -プラグインの説明 - -### permissions -プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。 - -### config -プラグインの設定情報を表すオブジェクト。 キーに設定名、値に以下のプロパティを含めます。 - -#### type -設定値の種類を表す文字列。以下から選択します。 string number boolean - -#### label -ユーザーに表示する設定名 - -#### description -設定の説明 - -#### default -設定のデフォルト値 - -## APIリファレンス -AiScript標準で組み込まれているAPIは掲載しません。 - -### Mk:dialog(title text type) -ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。 - -### Mk:confirm(title text type) -確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。 - -### Mk:api(endpoint params) -Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。 - -### Mk:save(key value) -任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。 - -### Mk:load(key) -Mk:saveで永続化した指定の名前の値を読み取ります。 - -### Plugin:register_post_form_action(title fn) -投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。 - -### Plugin:register_note_action(title fn) -ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 - -### Plugin:register_user_action(title fn) -ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。 - -### Plugin:register_note_view_interruptor(fn) -UIに表示されるノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:register_note_post_interruptor(fn) -ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:open_url(url) -第一引数に渡されたURLをブラウザの新しいタブで開きます。 - -### Plugin:config -プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。 diff --git a/src/docs/cs-CZ/advanced/develop-bot.md b/src/docs/cs-CZ/advanced/develop-bot.md deleted file mode 100644 index 7f825e9bc..000000000 --- a/src/docs/cs-CZ/advanced/develop-bot.md +++ /dev/null @@ -1,6 +0,0 @@ -# Botの作成 -[Misskey API](./api)を利用してBotの開発が可能です。 また、いくつかのBot実装が公開されているため、ぜひ参考にしてください。 - -- [syuilo/ai](https://github.com/syuilo/ai) ... Node.js上で動く、TypeScript製Bot実装 - -Botを作成したときは、プロフィール設定からBotフラグをオンにしておくことを強くおすすめします。 diff --git a/src/docs/cs-CZ/advanced/reversi-bot.md b/src/docs/cs-CZ/advanced/reversi-bot.md deleted file mode 100644 index 7ab2a7212..000000000 --- a/src/docs/cs-CZ/advanced/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# MisskeyリバーシBotの開発 -Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。 - -1. `games/reversi`ストリームに以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - -2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる - * イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている - -3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する - -4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - * `game`: `game`の`id` - -5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う - -6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する - -7. ゲームが開始すると、`started`イベントが流れてくる - * イベントの中身にはゲーム情報が含まれている - -8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述) - -9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる - * `color`として石の色が含まれている - * `pos`として位置情報が含まれている - -## 位置の計算法 -8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### X,Y座標 から インデックス に変換する -``` -pos = x + (y * mapWidth) -``` -`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます: -``` -mapWidth = map[0].length -``` - -### インデックス から X,Y座標 に変換する -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## マップ情報 -マップ情報は、ゲーム情報の`map`に入っています。 文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 それをもとにマップのデザインを知る事が出来ます: -* `(スペース)` ... マス無し -* `-` ... マス -* `b` ... 初期配置される黒石 -* `w` ... 初期配置される白石 - -例えば、4*4の次のような単純なマップがあるとします: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -この場合、マップデータはこのようになります: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## ユーザーにフォームを提示して対話可能Botを作成する -ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。 - -フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します: -```javascript -{ - type: 'init-form', - body: [フォームコントロールの配列] -} -``` - -フォームコントロールの配列については今から説明します。 フォームコントロールは、次のようなオブジェクトです: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... コントロールのID。 `type` ... コントロールの種類。後述します。 `label` ... コントロールと一緒に表記するテキスト。 `value` ... コントロールのデフォルト値。 - -### フォームの操作を受け取る -ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### フォームコントロールの種類 -#### スイッチ -type: `switch` スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。 - -##### プロパティ -`label` ... スイッチに表記するテキスト。 - -#### ラジオボタン -type: `radio` ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。 - -##### プロパティ -`items` ... ラジオボタンの選択肢。例: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '強', - value: 3 -}] -``` - -#### スライダー -type: `slider` スライダーを表示します。 - -##### プロパティ -`min` ... スライダーの下限。 `max` ... スライダーの上限。 `step` ... 入力欄で刻むステップ値。 - -#### テキストボックス -type: `textbox` テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。 - -## ユーザーにメッセージを表示する -設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 メッセージを表示するには、次のメッセージをストリームに送信します: -```javascript -{ - type: 'message', - body: { - text: 'メッセージ内容', - type: 'メッセージの種類' - } -} -``` -メッセージの種類: `success`, `info`, `warning`, `error`。 - -## 投了する -投了をするには、このエンドポイントにリクエストします。 diff --git a/src/docs/cs-CZ/advanced/share-page.md b/src/docs/cs-CZ/advanced/share-page.md deleted file mode 100644 index e3d37c2d0..000000000 --- a/src/docs/cs-CZ/advanced/share-page.md +++ /dev/null @@ -1,54 +0,0 @@ -# シェアページ -`/share`を開くと、共有用の投稿フォームを開くことができます。 ここではシェアページで利用できるクエリ文字列の一覧を示します。 - -## クエリ文字列一覧 -### 文字 - -
-
title
-
タイトルです。本文の先頭に[ … ]と挿入されます。
-
text
-
本文です。
-
url
-
URLです。末尾に挿入されます。
-
- -### リプライ情報 -以下のいずれか - -
-
replyId
-
リプライ先のノートid
-
replyUri
-
リプライ先のUrl(リモートのノートオブジェクトを指定)
-
- -### Renote情報 -以下のいずれか - -
-
renoteId
-
Renote先のノートid
-
renoteUri
-
Renote先のUrl(リモートのノートオブジェクトを指定)
-
- -### 公開範囲 -※specifiedに相当する値はvisibility=specifiedとvisibleAccts/visibleUserIdsで指定する - -
-
visibility
-
公開範囲 ['public' | 'home' | 'followers' | 'specified']
-
localOnly
-
0(false) or 1(true)
-
visibleUserIds
-
specified時のダイレクト先のユーザーid カンマ区切りで
-
visibleAccts
-
specified時のダイレクト先のacct(@?username[@host]) カンマ区切りで
-
- -### Soubor(ů) -
-
fileIds
-
添付したいファイルのid(カンマ区切りで)
-
diff --git a/src/docs/cs-CZ/advanced/stream.md b/src/docs/cs-CZ/advanced/stream.md deleted file mode 100644 index 0e5edd2b0..000000000 --- a/src/docs/cs-CZ/advanced/stream.md +++ /dev/null @@ -1,350 +0,0 @@ -# ストリーミングAPI - -ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。 - -## ストリームに接続する - -ストリーミングAPIを利用するには、まずMisskeyサーバーに**websocket**接続する必要があります。 - -以下のURLに、`i`というパラメータ名で認証情報を含めて、websocket接続してください。例: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。 - -
ℹ️ 認証情報の取得については、こちらのドキュメントをご確認ください。
- ---- - -認証情報は省略することもできますが、その場合非ログインでの利用ということになり、受信できる情報や可能な操作は限られます。例: - -``` -%WS_URL%/streaming -``` - ---- - -ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。 - -**ストリームでのやり取りはすべてJSONです。** - -## チャンネル -MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。 - -ひとつのストリーム上で、同時に複数のチャンネルに接続することができます。 - -### チャンネルに接続する -チャンネルに接続するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -ここで、 -* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。 -* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。 -* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。 - -
ℹ️ IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。
- -### チャンネルからのメッセージを受け取る -例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。 - -チャンネルがメッセージを発すると、次のようなデータがJSONでストリームに流れてきます: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。 -* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。 -* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。 - -### チャンネルに向けてメッセージを送信する -チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。 - -チャンネルにメッセージを送信するには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。 -* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。 -* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。 - -### チャンネルから切断する -チャンネルから切断するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。 - -## ストリームを経由してAPIリクエストする - -ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。 - -ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -ここで、 -* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 -* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 -* `data`には、エンドポイントのパラメータを含めます。 - -
ℹ️ APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。
- -### レスポンスの受信 - -APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。 - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -ここで、 -* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 -* `body`には、レスポンスが含まれています。 - -## 投稿のキャプチャ - -Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。 - -例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。 - -しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。 - -この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。 - -### 投稿をキャプチャする - -投稿をキャプチャするには、ストリームに次のようなメッセージを送信します: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャしたい投稿の`id`を設定します。 - -このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 - -例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -ここで、 -* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。 -* `body`内の`type`に、イベントの種類が設定されます。 -* `body`内の`body`に、イベントの詳細が設定されます。 - -#### イベントの種類 - -##### `reacted` -その投稿にリアクションがされた時に発生します。 - -* `reaction`に、リアクションの種類が設定されます。 -* `userId`に、リアクションを行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -その投稿が削除された時に発生します。 - -* `deletedAt`に、削除日時が設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -その投稿に添付されたアンケートに投票された時に発生します。 - -* `choice`に、選択肢IDが設定されます。 -* `userId`に、投票を行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### 投稿のキャプチャを解除する - -その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。 - -次のメッセージを送信します: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャを解除したい投稿の`id`を設定します。 - -このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 - -# チャンネル一覧 -## `main` -アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `renote` -自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。 - -#### `mention` -誰かからメンションされたときに発生するイベントです。 - -#### `readAllNotifications` -自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。 - -#### `meUpdated` -自分の情報が更新されたことを表すイベントです。 - -#### `follow` -自分が誰かをフォローしたときに発生するイベントです。 - -#### `unfollow` -自分が誰かのフォローを解除したときに発生するイベントです。 - -#### `followed` -自分が誰かにフォローされたときに発生するイベントです。 - -## `homeTimeline` -ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -タイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `localTimeline` -ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `hybridTimeline` -ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ソーシャルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `globalTimeline` -グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 diff --git a/src/docs/cs-CZ/aiscript.md b/src/docs/cs-CZ/aiscript.md deleted file mode 100644 index a153268ea..000000000 --- a/src/docs/cs-CZ/aiscript.md +++ /dev/null @@ -1,4 +0,0 @@ -# AiScript - -## Funkce -デフォルトで値渡しです。 diff --git a/src/docs/cs-CZ/api.md b/src/docs/cs-CZ/api.md deleted file mode 100644 index 76019b614..000000000 --- a/src/docs/cs-CZ/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス、Bot等(以下「アプリケーション」と呼びます)を開発できます。 ストリーミングAPIもあるので、リアルタイム性のあるアプリケーションを作ることも可能です。 - -APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。 - -## アクセストークンの取得 -基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。 - -* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む -* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む - -### 自分自身のアクセストークンを手動発行する -「設定 > API」で、自分のアクセストークンを発行できます。 - -[「APIの使い方」へ進む](#APIの使い方) - -### アプリケーション利用者にアクセストークンの発行をリクエストする -アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。 - -#### Step 1 - -UUIDを生成する。以後これをセッションIDと呼びます。 - -> このセッションIDは毎回生成し、使いまわさないようにしてください。 - -#### Step 2 - -`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。 -> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます: -* `name` ... アプリケーション名 - * > 例: `MissDeck` -* `icon` ... アプリケーションのアイコン画像URL - * > 例: `https://missdeck.example.com/icon.png` -* `callback` ... 認証が終わった後にリダイレクトするURL - * > 例: `https://missdeck.example.com/callback` - * リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます -* `permission` ... アプリケーションが要求する権限 - * > 例: `write:notes,write:following,read:drive` - * 要求する権限を`,`で区切って列挙します - * どのような権限があるかは[APIリファレンス](/api-doc)で確認できます - -#### Step 3 -ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。 - -レスポンスに含まれるプロパティ: -* `token` ... ユーザーのアクセストークン -* `user` ... ユーザーの情報 - -[「APIの使い方」へ進む](#APIの使い方) - -## APIの使い方 -**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。 - -* [APIリファレンス](/api-doc) -* [ストリーミングAPI](./stream) diff --git a/src/docs/cs-CZ/create-plugin.md b/src/docs/cs-CZ/create-plugin.md deleted file mode 100644 index ec17b9518..000000000 --- a/src/docs/cs-CZ/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# プラグインの作成 -Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。 - -## Metadata -プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。 - -### name -プラグイン名 - -### author -プラグイン作者 - -### version -プラグインバージョン。数値を指定してください。 - -### description -プラグインの説明 - -### permissions -プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。 - -### config -プラグインの設定情報を表すオブジェクト。 キーに設定名、値に以下のプロパティを含めます。 - -#### type -設定値の種類を表す文字列。以下から選択します。 string number boolean - -#### label -ユーザーに表示する設定名 - -#### description -設定の説明 - -#### default -設定のデフォルト値 - -## APIリファレンス -AiScript標準で組み込まれているAPIは掲載しません。 - -### Mk:dialog(title text type) -ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。 - -### Mk:confirm(title text type) -確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。 - -### Mk:api(endpoint params) -Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。 - -### Mk:save(key value) -任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。 - -### Mk:load(key) -Mk:saveで永続化した指定の名前の値を読み取ります。 - -### Plugin:register_post_form_action(title fn) -投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。 - -### Plugin:register_note_action(title fn) -ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 - -### Plugin:register_user_action(title fn) -ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。 - -### Plugin:register_note_view_interruptor(fn) -UIに表示されるノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:register_note_post_interruptor(fn) -ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:open_url(url) -第一引数に渡されたURLをブラウザの新しいタブで開きます。 - -### Plugin:config -プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。 diff --git a/src/docs/cs-CZ/custom-emoji.md b/src/docs/cs-CZ/custom-emoji.md deleted file mode 100644 index 39f490037..000000000 --- a/src/docs/cs-CZ/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# Vlastní emoji -カスタム絵文字は、インスタンスで用意された画像を絵文字のように使える機能です。 ノート、リアクション、チャット、自己紹介、名前などの場所で使うことができます。 カスタム絵文字をそれらの場所で使うには、絵文字ピッカーボタン(ある場合)を押すか、`:`を入力して絵文字サジェストを表示します。 テキスト内に`:foo:`のような形式の文字列が見つかると、`foo`の部分がカスタム絵文字名と解釈され、表示時には対応したカスタム絵文字に置き換わります。 diff --git a/src/docs/cs-CZ/deck.md b/src/docs/cs-CZ/deck.md deleted file mode 100644 index 8057e262f..000000000 --- a/src/docs/cs-CZ/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# デッキ - -デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。 - -## カラムの追加 -デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。 - -## カラムの移動 -カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。 - -## カラムの水平分割 -カラムは左右だけでなく、上下に並べることもできます。 カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 上下分割を解除するには、カラムメニューの「右に出す」を選択します。 - -## カラムの設定 -カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。 - -## デッキの設定 -デッキに関する設定は、[settings/deck](/settings/deck)で行えます。 diff --git a/src/docs/cs-CZ/features/antenna.md b/src/docs/cs-CZ/features/antenna.md deleted file mode 100644 index 395327fd5..000000000 --- a/src/docs/cs-CZ/features/antenna.md +++ /dev/null @@ -1,4 +0,0 @@ -# Antény -アンテナは、自由に条件を設定して、合致するノートを自動で収集することができる機能です。 - -条件を設定したアンテナが作成された状態で、条件に合致するノートが投稿されると、リアルタイムでそのアンテナのタイムラインにノートが追加されます。 diff --git a/src/docs/cs-CZ/features/custom-emoji.md b/src/docs/cs-CZ/features/custom-emoji.md deleted file mode 100644 index 39f490037..000000000 --- a/src/docs/cs-CZ/features/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# Vlastní emoji -カスタム絵文字は、インスタンスで用意された画像を絵文字のように使える機能です。 ノート、リアクション、チャット、自己紹介、名前などの場所で使うことができます。 カスタム絵文字をそれらの場所で使うには、絵文字ピッカーボタン(ある場合)を押すか、`:`を入力して絵文字サジェストを表示します。 テキスト内に`:foo:`のような形式の文字列が見つかると、`foo`の部分がカスタム絵文字名と解釈され、表示時には対応したカスタム絵文字に置き換わります。 diff --git a/src/docs/cs-CZ/features/deck.md b/src/docs/cs-CZ/features/deck.md deleted file mode 100644 index 8057e262f..000000000 --- a/src/docs/cs-CZ/features/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# デッキ - -デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。 - -## カラムの追加 -デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。 - -## カラムの移動 -カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。 - -## カラムの水平分割 -カラムは左右だけでなく、上下に並べることもできます。 カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 上下分割を解除するには、カラムメニューの「右に出す」を選択します。 - -## カラムの設定 -カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。 - -## デッキの設定 -デッキに関する設定は、[settings/deck](/settings/deck)で行えます。 diff --git a/src/docs/cs-CZ/features/drive.md b/src/docs/cs-CZ/features/drive.md deleted file mode 100644 index a09eb0384..000000000 --- a/src/docs/cs-CZ/features/drive.md +++ /dev/null @@ -1,17 +0,0 @@ -# Úložiště -ドライブは、Misskey上でファイルを管理できる機能です。 - -[ドライブのページ](/my/drive)から任意のファイルをアップロードできるほか、アバターに設定した画像や、ノートに添付したファイルなどもすべてドライブにアップロードされます。 - -
⚠️ ドライブからファイルを削除すると、そのファイルが添付されたノートも消えます。
- -ドライブにアップロードされたファイルは、いつでもダウンロードすることができるほか、ノート作成時に「ドライブからファイルを添付」することでファイルを再利用することもできます。 - -ドライブ内にフォルダを作り、複数のファイルをまとめて整理することもできます。 - -## 閲覧注意 (NSFW) -
ℹ️ この項目が閲覧注意なわけではありません
- -閲覧注意またはNSFW (Not safe for work) は、ドライブのファイルに設定することができるフラグです。 閲覧注意フラグを設定されたファイルは、表示される際に閲覧者の操作なしには表示されなくなります。 このフラグは、例えば職場や公共の場で閲覧するのに適切でないと思われる画像などに設定し、そのような画像が突然表示されてしまうことを防ぐ目的で使われます。 - -このフラグは手動でオンオフを切り替えられるほか、モデレーターの判断で設定される場合もあります。 diff --git a/src/docs/cs-CZ/features/favorite.md b/src/docs/cs-CZ/features/favorite.md deleted file mode 100644 index b5134ffaa..000000000 --- a/src/docs/cs-CZ/features/favorite.md +++ /dev/null @@ -1,4 +0,0 @@ -# Oblíbené -[ノート](./node)をお気に入りとして登録できる機能です。 お気に入り登録したノートは、[お気に入りページ](./my/favorites)で一覧することができます。 お気に入りに登録したことは相手に通知されず、お気に入りは自分しか見ることができません。 - -ノートをお気に入り登録するには、ノートメニューの「お気に入り」を押します。お気に入り解除するには、ノートメニューの「お気に入り解除」を押します。 diff --git a/src/docs/cs-CZ/features/follow.md b/src/docs/cs-CZ/features/follow.md deleted file mode 100644 index 61acb2895..000000000 --- a/src/docs/cs-CZ/features/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# Sledovaní -ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。 diff --git a/src/docs/cs-CZ/features/keyboard-shortcut.md b/src/docs/cs-CZ/features/keyboard-shortcut.md deleted file mode 100644 index 22b179783..000000000 --- a/src/docs/cs-CZ/features/keyboard-shortcut.md +++ /dev/null @@ -1,66 +0,0 @@ -# キーボードショートカット - -## グローバル -これらのショートカットは基本的にどこでも使えます。 - - - - - - - - - - - -
ショートカット効果由来
P, N新規投稿Post, New, Note
Tタイムラインの最も新しい投稿にフォーカスTimeline, Top
Shift + N通知を表示/隠すNotifications
SVyhledáváníSearch
H, ?ヘルプを表示Help
- -## 投稿にフォーカスされた状態 - - - - - - - - - - - - - - - - - - -
ショートカット効果由来
, K, Shift + Tab上の投稿にフォーカスを移動-
, J, Tab下の投稿にフォーカスを移動-
R返信フォームを開くReply
QRenoteフォームを開くQuote
Ctrl + Q即刻Renoteする(フォームを開かずに)-
E, A, +リアクションフォームを開くEmote, reAction
0~9数字に対応したリアクションをする(対応については後述)-
F, Bお気に入りに登録Favorite, Bookmark
Del, Ctrl + D投稿を削除Delete
M, O投稿に対するメニューを開くMore, Other
SCWで隠された部分を表示 or 隠すShow, See
Escフォーカスを外す-
- -## Renoteフォーム - - - - - - - - - -
ショートカット効果由来
EnterRenoteする-
Qフォームを展開するQuote
Escフォームを閉じる-
- -## リアクションフォーム -デフォルトで「👍」にフォーカスが当たっている状態です。 - - - - - - - - - - - - - -
ショートカット効果由来
, K上のリアクションにフォーカスを移動-
, J下のリアクションにフォーカスを移動-
, H, Shift + Tab左のリアクションにフォーカスを移動-
, L, Tab右のリアクションにフォーカスを移動-
Enter, Space, +リアクション確定-
0~9数字に対応したリアクションで確定-
Escリアクションするのをやめる-
diff --git a/src/docs/cs-CZ/features/mfm.md b/src/docs/cs-CZ/features/mfm.md deleted file mode 100644 index 5be2df4f3..000000000 --- a/src/docs/cs-CZ/features/mfm.md +++ /dev/null @@ -1,12 +0,0 @@ -# MFM -MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます。 - -## MFMが使用可能な場所の例 -- ノート本文 -- CW注釈 -- ユーザーの名前 -- ユーザーの自己紹介 - -## 開発者向け情報 -MFMのパーサー実装はライブラリとして公開されており、簡単にクライアントにMFMを組み込むことが可能です。 -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptパーサー実装 diff --git a/src/docs/cs-CZ/features/mute-and-block.md b/src/docs/cs-CZ/features/mute-and-block.md deleted file mode 100644 index 4f0931eea..000000000 --- a/src/docs/cs-CZ/features/mute-and-block.md +++ /dev/null @@ -1,41 +0,0 @@ -# ミュートとブロック -好みではないユーザーがいる場合は、ミュートを行うことでそのユーザーが自分から見えないようにすることができます。 また、より強力な措置として、ブロックを行うことでそのユーザーから自分のコンテンツが見えないようになるほか、自分に対して関わることができないようにすることができます。 ミュートされていることは相手は分かりませんが、ブロックされていることは相手に分かります。どちらを選ぶかはご自身の判断で行ってください。 - -
ℹ️ ミュートとブロックは併用できます。
- -
⚠️ 利用規約に違反するような、迷惑なユーザーがいる場合は運営者に報告することも検討してください。
- -設定>ミュートとブロック から、自分がミュートまたはブロックしているユーザー一覧を確認することができます。 - -## Ztlumit -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -- タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -- そのユーザーからの通知 -- メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 -- など - -ユーザーをミュートするには、対象のユーザーのユーザーページのメニューを開き、「ミュート」ボタンを押します。 - -
ℹ️ ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。
- -## Zablokovat -ユーザーをブロックすると、そのユーザーからあなたのコンテンツが見えないようになり、またあなたに対して以下のようなアクションをすることができなくなります。 - -- フォローする -- ユーザーリストに追加する -- 返信する、Renoteする -- リアクションする、アンケートに投票する -- メッセージを送信する -- など - -また、 - -- ブロックする際に既にそのユーザーからフォローされていた場合はフォローが解除されます。 -- ブロックする際に既にそのユーザーがあなたをユーザーリストに入れていた場合はそのリストからあなたが削除されます。 - -ユーザーをブロックするには、対象のユーザーのユーザーページのメニューを開き、「ブロック」ボタンを押します。 - -
⚠️ ブロックを行ったこと自体は相手に通知されませんが、フォローを行ったりなどの上記のアクションが行えなくなるので間接的にブロックされていることは分かります。
- -
⚠️ 相手から自分のコンテンツが見えなくなりますが、相手がアカウントを切り替えたりログアウト状態になれば見ることができます。あくまで簡易的、補助的なものとしてお考えください。
diff --git a/src/docs/cs-CZ/features/mute.md b/src/docs/cs-CZ/features/mute.md deleted file mode 100644 index fb4ef68d5..000000000 --- a/src/docs/cs-CZ/features/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# Ztlumit - -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -* タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -* そのユーザーからの通知 -* メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 - -ユーザーをミュートするには、対象のユーザーのユーザーページに表示されている「ミュート」ボタンを押します。 - -ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。 - -設定>ミュート から、自分がミュートしているユーザー一覧を確認することができます。 diff --git a/src/docs/cs-CZ/features/note.md b/src/docs/cs-CZ/features/note.md deleted file mode 100644 index 0ff99d9d0..000000000 --- a/src/docs/cs-CZ/features/note.md +++ /dev/null @@ -1,54 +0,0 @@ -# Poznámky -ノートは、Misskeyに投稿される、文章、ファイル、アンケートなどを含むコンテンツで、Misskeyの中心的概念です。また、そのノートを作成する行為自体もノートと呼ばれます。 - -ノートが作成されると、[タイムライン](./timeline)に追加され、自分の[フォロワー](./follow)やサーバーのユーザーが見れるようになります。 - -ノートには、[リアクション](./reaction)を行うことができます。また、返信や引用もできます。 - -ノートを[お気に入り](./favorite)登録することで、後で簡単に見返すことができます。 - -## ノートを作成する -ノートを作成するには、画面上にある鉛筆マークのボタンを押して、作成フォームを開きます。作成フォームに内容を入力し、「ノート」ボタンを押すことでノートが作成されます。 ノートには、画像、動画など任意のファイルや、[アンケート](./poll)を添付することができます。また、本文中には[MFM](./mfm)が使用でき、[メンション](./mention)や[ハッシュタグ](./hashtag)を含めることもできます。 他にも、CWや公開範囲といった設定も行えます(詳細は後述)。 -
ℹ️ コンピューターのクリップボードに画像データがある状態で、フォーム内のテキストボックスにペーストするとその画像を添付することができます。
-
ℹ️ テキストボックス内でCtrl + Enterを押すことでも投稿できます。
- -## Přeposlat -既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノートをRenoteと呼びます。 自分がフォローしているユーザーの、気に入ったノートを自分のフォロワーに共有したい場合や、過去の自分のノートを再度共有したい場合に使います。 同じノートに対して無制限にRenoteを行うことができますが、あまり連続して使用すると迷惑になる場合もあるので、注意しましょう。 -
⚠️ 公開範囲がフォロワーやダイレクトのノートはRenoteできません
- -Renoteを削除するには、Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 - -## CW -Contents Warningの略で、ノートの内容を、閲覧者の操作なしには表示しないようにできる機能です。主に長大な内容を隠すためや、ネタバレ防止などに使うことができます。 設定するには、フォームの「内容を隠す」ボタン(目のアイコン)を押します。すると新しい入力エリアが表れるので、そこに内容の要約を記入します。 - -## 公開範囲 -ノートごとに、そのノートが公開される範囲を設定することができます。フォームの「ノート」ボタンの左にあるアイコンを押すと公開範囲を以下から選択できます。 - -### パブリック -全ての人に対してノートが公開されるほか、サーバーの全てのタイムライン(ホームタイムライン、ローカルタイムライン、ソーシャルタイムライン、グローバルタイムライン)にノートが流れます。 -
⚠️ アカウントがサイレンス状態の時は、この公開範囲は使用できません。
- -### Domů -全ての人に対してノートが公開されますが、フォロワー以外のローカルタイムライン、ソーシャルタイムライン、グローバルタイムラインにはノートは流れません。 - -### Sledující -自分のフォロワーに対してのみノートを公開します。フォロワーの全てのタイムラインに流れます。 - -### ダイレクト -指定したユーザーに対してのみノートを公開します。指定したユーザーの全てのタイムラインに流れます。 - -### 「ローカルのみ」オプション -このオプションを有効にすると、リモートにノートを連合しなくなります。 - -### 公開範囲の比較 - - - - -
パブリックDomůSledujícíダイレクト
フォロワーのLTL/STL/GTL
非フォロワーのLTL/STL/GTL
- -## Připnout -ノートをピン留めすると、ユーザーページに常にそのノートを表示しておくことができます。 ノートのメニューを開き、「ピン留め」を選択してピン留めできます。 複数のノートをピン留めできます。 - -## Sledovat -ノートをウォッチすると、自分以外のノートへのリアクションや返信などの通知を受け取ることができます。 ノートのメニューを開き、「ウォッチ」を選択してウォッチできます。 diff --git a/src/docs/cs-CZ/features/pages.md b/src/docs/cs-CZ/features/pages.md deleted file mode 100644 index a7311b95e..000000000 --- a/src/docs/cs-CZ/features/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# Pages - -## 変数 -変数を使うことで動的なページを作成できます。テキスト内で { 変数名 } と書くとそこに変数の値を埋め込めます。例えば Hello { thing } world! というテキストで、変数(thing)の値が ai だった場合、テキストは Hello ai world! になります。 - -変数の評価(値を算出すること)は上から下に行われるので、ある変数の中で自分より下の変数を参照することはできません。例えば上から A、B、C と3つの変数を定義したとき、Cの中でABを参照することはできますが、Aの中でBCを参照することはできません。 - -ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。 - -関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。 diff --git a/src/docs/cs-CZ/features/reaction.md b/src/docs/cs-CZ/features/reaction.md deleted file mode 100644 index 91bec9b9b..000000000 --- a/src/docs/cs-CZ/features/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# Reakce -他の人のノートに、絵文字を付けて簡単にあなたの反応を伝えられる機能です。 リアクションするには、ノートの + アイコンをクリックしてピッカーを表示し、絵文字を選択します。 リアクションには[カスタム絵文字](./custom-emoji)も使用できます。 - -## リアクションピッカーのカスタマイズ -ピッカーに表示される絵文字を自分好みにカスタマイズすることができます。 設定の「リアクション」で設定します。 - -## リモート投稿へのリアクションについて -リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。 - -## リモートからのリアクションについて -リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。 diff --git a/src/docs/cs-CZ/features/silence.md b/src/docs/cs-CZ/features/silence.md deleted file mode 100644 index 7e26feab0..000000000 --- a/src/docs/cs-CZ/features/silence.md +++ /dev/null @@ -1,6 +0,0 @@ -# サイレンス -サイレンスは、アカウントに設定される状態のひとつです。 - -アカウントがサイレンス状態になると、ノートの公開範囲をパブリックにできなくなります。 ホーム、フォロワー、ダイレクトは選択可能なため、サイレンスを受けた場合でもフォロワーやあなたのユーザーページを直接訪れた場合は投稿を閲覧できますが、GTL(連合タイムライン)やLTL(ローカルタイムライン)には投稿が流れません。 - -アカウントのサイレンス状態は、サーバーのモデレーターによって有効化/無効化されます。 diff --git a/src/docs/cs-CZ/features/theme.md b/src/docs/cs-CZ/features/theme.md deleted file mode 100644 index f8827662e..000000000 --- a/src/docs/cs-CZ/features/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# Vzhled - -テーマを設定して、Misskeyクライアントの見た目を変更できます。 - -## テーマの設定 -設定 > テーマ - -## テーマを作成する -テーマコードはJSON5で記述されたテーマオブジェクトです。 テーマは以下のようなオブジェクトです。 -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... テーマの一意なID。UUIDをおすすめします。 -* `name` ... テーマ名 -* `author` ... テーマの作者 -* `desc` ... テーマの説明(オプション) -* `base` ... 明るいテーマか、暗いテーマか - * `light`にすると明るいテーマになり、`dark`にすると暗いテーマになります。 - * テーマはここで設定されたベーステーマを継承します。 -* `props` ... テーマのスタイル定義。これから説明します。 - -### テーマのスタイル定義 -`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 - -#### バリューで使える構文 -* 16進数で表された色 - * 例: `#00ff00` -* `rgb(r, g, b)`形式で表された色 - * 例: `rgb(0, 255, 0)` -* `rgb(r, g, b, a)`形式で表された透明度を含む色 - * 例: `rgba(0, 255, 0, 0.5)` -* 他のキーの値の参照 - * `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。 - * 例: `@panel` -* 定数(後述)の参照 - * `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。 - * 例: `$main` -* 関数(後述) - * `:{関数名}<{引数}<{色}` - -#### 定数 -「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 キー名を`$`で始めると、そのキーはCSS変数として出力されません。 - -#### 関数 -wip diff --git a/src/docs/cs-CZ/features/timeline.md b/src/docs/cs-CZ/features/timeline.md deleted file mode 100644 index f7381f12a..000000000 --- a/src/docs/cs-CZ/features/timeline.md +++ /dev/null @@ -1,31 +0,0 @@ -# Časová osa -タイムラインは、[ノート](./note)が時系列で表示される機能です。 タイムラインには以下で示す種類があり、種類によって表示されるノートも異なります。 なお、タイムラインの種類によってはサーバーにより無効になっている場合があります。 - -## Domů -自分のフォローしているユーザーの投稿が流れます。HTLと略されます。 - -## ローカル -全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。LTLと略されます。 - -## ソーシャル -自分のフォローしているユーザーの投稿と、全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。STLと略されます。 - -## グローバル -全てのローカルユーザーの「ホーム」指定されていない投稿と、サーバーに届いた全てのリモートユーザーの「ホーム」指定されていない投稿が流れます。GTLと略されます。 - -## 比較 -| ソース | | | Časová osa | | | -| ------------ | --------- | ---- | ---------- | ----- | ----- | -| Uživatelé | 公開範囲 | Domů | ローカル | ソーシャル | グローバル | -| ローカル (フォロー) | 公開 | ✔ | ✔ | ✔ | ✔ | -| | Domů | ✔ | | ✔ | | -| | Sledující | ✔ | ✔ | ✔ | ✔ | -| リモート (フォロー) | 公開 | ✔ | | ✔ | ✔ | -| | Domů | ✔ | | ✔ | | -| | Sledující | ✔ | | ✔ | ✔ | -| ローカル (未フォロー) | 公開 | | ✔ | ✔ | ✔ | -| | Domů | | | | | -| | Sledující | | | | | -| リモート (未フォロー) | 公開 | | | | ✔ | -| | Domů | | | | | -| | Sledující | | | | | diff --git a/src/docs/cs-CZ/features/widgets.md b/src/docs/cs-CZ/features/widgets.md deleted file mode 100644 index a7c2c1d1d..000000000 --- a/src/docs/cs-CZ/features/widgets.md +++ /dev/null @@ -1,7 +0,0 @@ -# ウィジェット -ウィジェットは、MisskeyのUI上に設置できる小型の情報表示、操作が行えるパーツです。 - -ウィジェットを編集するには、ウィジェット編集モードに切り替えます。切り替え方法はUIによって異なります。 ウィジェット編集モードでは、ウィジェットの追加、削除、並び替え、およびそれぞれのウィジェットの設定を行えます。 - -## 利用可能なウィジェット一覧 -todo diff --git a/src/docs/cs-CZ/features/word-mute.md b/src/docs/cs-CZ/features/word-mute.md deleted file mode 100644 index fa4d14346..000000000 --- a/src/docs/cs-CZ/features/word-mute.md +++ /dev/null @@ -1,20 +0,0 @@ -# ワードミュート -ワードミュートの設定をすると、条件に合致したノートが表示されなくなります。 - -ワードミュートには、ソフトワードミュートとハードワードミュートの2種類があります。それぞれについて設定の方法と挙動を説明します。 - -## ソフトワードミュート -ソフトワードミュートは、クライアント(アプリ)側でミュートを判断するワードミュートです。 - -ノートが設定した条件に合致すると、「(ユーザー名)が何かを言いました」という表示で隠れます。 -クリックすると元の通りに表示されます。 - -## ハードワードミュート -ハードワードミュートは、アンテナのようにサーバーが新しいノートの本文に対して条件に合致するかどうか判断し、タイムラインから対象となったノートを除外します。 - -つまり、ハードワードミュートには、以下のような特徴があります。 - -* 条件設定後、新しい投稿のみがミュートの対象になります。 -* 条件を変更しても、過去にハードミュートされたノートはミュートされたままになります。 -* 「○○が何かを言いました」でタイムラインが埋まることがありません。 -* ソフトミュートに非対応のアプリでも、ハードミュートは適用されます。 diff --git a/src/docs/cs-CZ/follow.md b/src/docs/cs-CZ/follow.md deleted file mode 100644 index 61acb2895..000000000 --- a/src/docs/cs-CZ/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# Sledovaní -ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。 diff --git a/src/docs/cs-CZ/general/apps.md b/src/docs/cs-CZ/general/apps.md deleted file mode 100644 index 1f4c85fe8..000000000 --- a/src/docs/cs-CZ/general/apps.md +++ /dev/null @@ -1,6 +0,0 @@ -# サードパーティアプリのリスト -## クライアント -todo - -## 連携サービス -todo diff --git a/src/docs/cs-CZ/general/changelog.md b/src/docs/cs-CZ/general/changelog.md deleted file mode 100644 index 6766a63b2..000000000 --- a/src/docs/cs-CZ/general/changelog.md +++ /dev/null @@ -1,5 +0,0 @@ -# 更新履歴 -
ℹ️ このサーバーの更新履歴です。Misskeyの最新のリリースについては、GitHubをご確認ください。
- - - diff --git a/src/docs/cs-CZ/general/faq.md b/src/docs/cs-CZ/general/faq.md deleted file mode 100644 index c272b2ad4..000000000 --- a/src/docs/cs-CZ/general/faq.md +++ /dev/null @@ -1,28 +0,0 @@ -# よくある質問 -ここでは利用上のよくある質問について掲載しています。 Misskeyのプロジェクト自体についてのよくある質問は[こちら](./misskey)に掲載されています。 - -## iOS/Androidのアプリはありますか? -公式にはそういったOSのネイティブアプリを開発していませんが、サードパーティ製のアプリがいくつかあります。 詳しくは[こちら](./apps)をご覧ください。 - -ただ、サードパーティ製アプリはどうしても機能への対応が遅れてしまうため、とくに拘りがなければ公式のWebクライアントの利用をおすすめします。 なお、MisskeyのWebクライアントはPWAに対応しているので、ネイティブアプリのように動作させることも可能です。 詳しくは[こちら](todo)をご覧ください。 - -## Mastodonクライアントでログインできないのですが? -MisskeyはMastodonのAPIと互換性がないため、一部を除きMastodonクライアントでMisskeyを利用することはできません。 - -## 他のサーバーのユーザーをフォローするときは? -メニューから検索を選び、ユーザー名をホスト込みで入力します。例: `@syuilo@misskey.io` - -## Renoteを削除するには? -Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 Renoteについては[こちら](../features/note)をご確認ください。 - -## URLのプレビューを表示させたくない -MFMには、そのURLのプレビューを無効にする構文があります。詳細は[MFMチートシート](/mfm-cheat-sheet)をご確認ください。 - -## カスタム絵文字を追加したい -運営者のみがカスタム絵文字を追加、編集、削除できます。それらを希望する場合は運営者に依頼してください。 - -## Botを開発したい -Misskey APIを利用してBotの開発が可能です。[こちら](../advanced/develop-bot)をご確認ください。 - -## ノートの翻訳機能はどのサービスを使用していますか? -[DeepL](https://www.deepl.com/)を使用しています。 diff --git a/src/docs/cs-CZ/general/glossary.md b/src/docs/cs-CZ/general/glossary.md deleted file mode 100644 index f1d189a4c..000000000 --- a/src/docs/cs-CZ/general/glossary.md +++ /dev/null @@ -1,89 +0,0 @@ -# 用語集 -Misskeyに関する用語集です。 - -## ActivityPub -(読み: あくてぃびてぃぱぶ) 分散型を実現するために用いられるプロトコル(仕様)。このプロトコルに則ってサーバー同士通信を行うことで、連合が行われ、Fediverseを形成しています。 - -## AiScript -(読み: あいすくりぷと) Misskey上で使用できるプログラミング言語です。詳細は[こちら。](../advanced/aiscript) - -## API -(読み: えーぴーあい) Misskeyのサーバーが公開している、プログラムからMisskeyを扱うためのインターフェース。詳細は[こちら。](../advanced/api) - -## Bot -(読み: ぼっと) プログラムによって動作しているアカウント。 - -## CW -(読み: こんてんつわーにんぐ) Contents Warningの略。ノートの内容を、操作なしには表示しないようにできる機能。主に長大な内容を隠すためや、ネタバレ防止などに使われます。 - -## Fediverse -(読み: ふぇでぃばーす) Misskeyを含む様々な分散型ソフトウェアのサーバーで構成されたネットワーク。 - -## GTL -グローバルタイムライン(Global TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## HTL -ホームタイムライン(Home TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## LTL -ローカルタイムライン(Local TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## MFM -(読み: えむえふえむ) Misskey Flavored Markdownの略で、Misskey上で使用できるマークアップ言語です。詳細は[こちら。](../features/mfm) - -## NSFW -(読み: のっとせーふふぉーわーく) Not Safe For Workの略。画像を「閲覧注意」扱いにし、操作なしには表示しないようにすることができる機能。 - -## Přeposlat -(読み: りのーと) 既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノート。詳細は[こちら。](../features/note) - -## STL -ソーシャルタイムライン(Social TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## 藍 -(読み: あい) Misskeyの看板娘(公式キャラクター)です。 - -## アクティブユーザー -インスタンスにアカウントを作っているユーザーのうち、現在も実際にサービスを利用しているユーザーのこと。 - -## Instance -todo - -## Vlastní emoji -サーバーで用意された絵文字。カスタム絵文字ではない通常の絵文字は「Unicode絵文字」と区別して呼ばれる。 - -## コントロールパネル -インスタンスの設定画面のこと。 - -## サーバー -todo - -## サイレンス -ノートをパブリックな公開範囲で投稿できなくされている状態。モデレーターの判断でユーザーごとに設定されます。詳細は[こちら。](../features/silence) - -## Fronta úloh -アクティビティ配送などを順番に行うためのシステム。 - -## Zmrazit -アカウントが使用不可に設定されている状態。 - -## Úložiště -Misskeyにアップロードしたファイルを管理する機能。詳細は[こちら。](../features/drive) - -## Poznámky -Misskeyに投稿される、文章、ファイル、アンケートなどを含めることができるコンテンツ。詳細は[こちら。](../features/note) - -## ミスキスト -Misskeyを使う人のこと。 - -## Moderátor -スパムの凍結およびサイレンスや不適切な投稿の削除など、コミュニティ運営に関する権限を持つユーザー。 - -## リモート -他サーバーのことを指します。リモートユーザーといったように接頭辞としても使われます。ローカルの逆です。 - -## 連合 -サーバー上で作成された情報が他のサーバーに伝わること。 - -## ローカル -自サーバーのことを指します。ローカルユーザー、ローカルタイムラインといったように接頭辞としても使われます。リモートの逆です。 diff --git a/src/docs/cs-CZ/general/links.md b/src/docs/cs-CZ/general/links.md deleted file mode 100644 index 5ce5e1ddb..000000000 --- a/src/docs/cs-CZ/general/links.md +++ /dev/null @@ -1,12 +0,0 @@ -# リンク集 - -## Webサイト -- [Official Discord](https://discord.gg/Wp8gVStHW3) - Misskey公式Discordサーバー -- [Misskey Forum](https://forum.misskey.io/) - Misskeyに関する話題を扱うフォーラム - -## アカウント -- [@repo@misskey.io](https://misskey.io/@repo) - Misskeyのリポジトリの更新を投稿するbot - -## ライブラリ -- [misskey-dev/misskey.js](https://github.com/misskey-dev/misskey.js) - JavaScriptのMisskey SDK -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptのMFMパーサー実装 diff --git a/src/docs/cs-CZ/general/misskey.md b/src/docs/cs-CZ/general/misskey.md deleted file mode 100644 index 65ac31f86..000000000 --- a/src/docs/cs-CZ/general/misskey.md +++ /dev/null @@ -1,87 +0,0 @@ -# O Misskey - -Misskeyはオープンソースの分散型マイクロブログプラットフォームプロジェクトです。 開発は日本でsyuiloによって2014年から開始されました。 ドライブ、リアクションなどの豊富な機能や、高いカスタマイズ性を備えたUIを持つことが特徴です。 - -## 歴史 -開発当初は掲示板がメインのサービスでしたが、ユーザーが短文を投稿し、それを時系列で流れるタイムライン機能を追加したところ人気が高まり、徐々にそれがメインとして開発が進むようになりました。 当初は分散型ではありませんでしたが、2018年にActivityPubを実装し分散型になったことで、より多くの方に認知され利用されるサービスになり、現在に至ります。 -
ℹ️ Misskeyという名前は、syuiloが当時聴いていたMay'nというアーティストの楽曲、Brain Diverの歌詞に由来します。
- -誰でも開発に参加することができ、現在でも活発に開発が続いています。 - -## 分散型とは何か? - -分散(distributed)型とは、非中央集権(decentralized)とも呼ばれ、コミュニティが多数のサーバーに分散して存在し、それらが相互に通信(連合、federation)することでコンテンツ共有ネットワーク(Fediverse)を形成していることが特徴のサービスです。 単一のサーバーしか存在しない、もしくは複数存在しても互いに独立している場合は中央集権なサービスと言われ、例えばTwitterやFacebookなどほとんどのサービスがそれに該当します。 分散型のメリットは、自分に合った運営者やテーマのサーバーを選択できることです。自分でサーバーを作成することもできます。連合するおかげで、どのサーバーを選んでも、同じコミュニティにアクセスできます。 - -## 常にオープンソース -Misskeyはこれまでもこれからも、オープンソースであり続けます。オープンソースとは、簡単に言うとソフトウェアのソースコード(プログラム)が公開されていることです。ソースコードの修正や再配布が可能であることを定義に含めることもあります。 Misskeyのすべてのソースコードは[AGPL](https://github.com/misskey-dev/misskey/blob/develop/LICENSE)というオープンソースライセンスの下に[公開](https://github.com/misskey-dev)されていて、誰でも自由に閲覧、使用、修正、改変、再配布をすることができます。 オープンソースは、自分で好きなように変えたり、有害な処理が含まれていないことを確認することができたり、誰でも開発に参加できるなどの、様々なメリットがあります。 上述の分散型を実現するためにも、オープンソースであるということは必要不可欠な要素です。 再び引き合いに出しますが、TwitterやFacebookなどの利益を得ているほとんどのサービスはオープンソースではありません。 - -
ℹ️ 技術的に言うと、MisskeyのソースコードはGitで管理されていて、リポジトリはGitHub上でホスティングされています。
- -## 開発に参加する、プロジェクトを支援する -Misskeyを気に入っていただけたら、ぜひプロジェクトを支援してください。プロジェクトに貢献するには、以下で紹介するようにいろいろな方法があります。方法によっては開発のスキルは不要なので、誰でも気軽に参加し貢献することができます。いつでもお待ちしています。 - -### 機能を追加したり、バグを修正する -ソフトウェアエンジニアのスキルをお持ちの方であれば、ソースコードを編集する形でプロジェクトに貢献することができます。 貢献についてのガイドは[こちら](https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md)です。 - -### 議論に参加する -新しい機能、または既存の機能について意見を述べたり、不具合を報告したりすることでも貢献できます。 そのようなディスカッションは[GitHub](https://github.com/misskey-dev)上か、[フォーラム](https://forum.misskey.io/)等で行われます。 - -### テキストを翻訳する -Misskeyは様々な言語に対応しています(i18n -internationalizationの略- と呼ばれます)。元の言語は基本的に日本語ですが、有志によって他の言語へと翻訳されています。 その翻訳作業に加わっていただくことでもMisskeyに貢献できます。 Misskeyは[Crowdinというサービスを使用して翻訳の管理を行っています。](https://crowdin.com/project/misskey) - -### 感想を投稿する -不具合報告等だけではなく、Misskeyの良い点、楽しい点といったポジティブな意見もぜひ共有してください。開発の励みになり、それは間接的ですがプロジェクトへの貢献です。 - -### ミスキストを増やす -ミスキストとは、Misskeyを使用する人のことです。 知り合いに紹介するなどしてMisskeyを広めていただければ、ミスキストが増え開発のモチベーションが上がります。 - -### 寄付をする -Misskeyはビジネスではなく、利用は無料であるため、収益は皆様からの寄付のみです。(インスタンスによっては広告収入を得ているような場合もありますが、それは運営者の収入であり直接開発者への収入にはなりません) 寄付をしていただければ、今後も開発を続けることが可能になり、プロジェクトへの貢献になります。 寄付は基本的には[Patreon](https://www.patreon.com/syuilo)で受け付けています。 一定額寄付していただけると、Misskeyの[情報ページ](/about-misskey)に名前を記載することができます。 - -また、サーバーの運営者も、基本的には収益を得ていません。サーバーの運営にはコストがかかるので、運営者の支援をすることもご検討ください。 開発には直接関係しませんが、サーバーがあってこそのプロジェクトなので、運営が維持されるというのは開発と同じくらい重要なことです。 - -## クレジット -Misskeyの開発者や、Misskeyに寄付をしてくださった方の一覧は[こちら](/about-misskey)で見ることができます。 - -## よくある質問 -### プロジェクトは何を目指していますか? -強いて言うと、漠然的になりますが広く使われる汎用的なプラットフォームになることを目指しています。 Misskeyは他のプロジェクトとは違い、何らかの思想(例えば、反中央集権)やビジョンに基づいて開発が行われているわけではなく、その点ではフラットです。 それが逆に、特定の方向性に縛られないフレキシブルさを生み出すことに繋がっていると感じています。 - - -### 企業によって開発されていますか? -いいえ。Misskeyの開発は個人で行われており、商業的でもないため、特定の企業の関りはありません。 開発メンバーも基本的にはボランティアです。 また、開発に対し企業のスポンサーがつくこともありますが、その場合でもやはり開発は個人のコミュニティが主体です。 - -### 誰が運営していますか? -Misskeyは分散型なため、各サーバーにそれぞれ異なった運営者がいます。従って、特定の個人や企業によって、Misskeyの全てが運営されているわけではありません。 また、開発チームが運営を行うわけでもないため、運営に関する連絡は、お使いのサーバーの運営者に行ってください。 サーバーの運営者は、[このページ](/about)で確認することができます。 あなたがサーバーを作成すれば、あなたが運営者になります。 - -### どのサーバーを選べばいいですか? -[サーバー一覧が公開されています。](https://join.misskey.page/ja-JP/instances) サーバーによってコミュニティのテーマ(特定のこと、ものが好き 等)が決められている場合があるので、自分に合ったテーマのサーバーがあれば、そこを選ぶと良いかもしれません。 他にも、サーバーの規模、ユーザー層、国および言語、運営者が信頼できるかどうか、などの観点があります。 なお、Misskey公式のサーバーというものはありません。自身で新しくサーバーを作成するという選択肢もあります。 - -基本的にどのサーバーを選んだとしても、他の全てのサーバーのユーザーと繋がることができます。 - -### サーバーを建てるにはどうしたらいいですか? -Misskeyサーバーの作成に興味を持っていただきありがとうございます。 2021年現在、Misskeyのホスティングサービスは存在しないため、サーバーの作成にはある程度の知識が必要です。 サーバーの作成方法については[こちら](todo)をご覧ください。 - -### どのような技術を使用していますか? -Misskeyは開発が進むにつれ使用する技術も大きく変わってきました。開発当初はMySQL + PHP + jQueryといった構成でしたが、現在は以下のようになっています。 -- サーバーサイド: Node.js -- データベース: PostgreSQL、Redis -- UIフレームワーク: Vue.js -- プログラミング言語: TypeScript - -また、MFMやAiScriptなどの、Misskeyから派生して独自の技術も開発しています。 - -### Mastodonのフォークですか? -いいえ。MisskeyはMastodonやその他のプロジェクトとは全く別のプロジェクトです。 開発に関しても、Misskeyの方が昔から開発されています。ただし、分散型になったのはMastodonの登場より後です。 同じActivityPubという分散のためのプロトコルを実装しているという点以外、両者に特に関りがあるわけでもありません。 - -### iOS/Androidのアプリはありますか? -公式にはそういったOSのネイティブアプリを開発していませんが、サードパーティ製のアプリがいくつかあります。 詳しくは[こちら](./apps)をご覧ください。 - -ただ、サードパーティ製アプリはどうしても機能への対応が遅れてしまうため、とくに拘りがなければ公式のWebクライアントの利用をおすすめします。 なお、MisskeyのWebクライアントはPWAに対応しているので、ネイティブアプリのように動作させることも可能です。 詳しくは[こちら](todo)をご覧ください。 - -### Misskeyのロゴ、アイコンはどこで入手できますか? -(準備中) - -### 時折目にする猫耳の可愛い女の子は? -Misskeyの守り神、藍ちゃんです。アイチャンカワイイヤッター! -
ℹ️ 藍ちゃんについてはこちらです。
diff --git a/src/docs/cs-CZ/general/report-issue.md b/src/docs/cs-CZ/general/report-issue.md deleted file mode 100644 index 63527e32a..000000000 --- a/src/docs/cs-CZ/general/report-issue.md +++ /dev/null @@ -1,8 +0,0 @@ -# 不具合の報告 -不具合と思われる状況に遭遇したときは、まず[トラブルシューティング](./troubleshooting)をご一読ください。 それでも問題が解決しないときは、以下の情報を含めて[フォーラム](https://forum.misskey.io/)に投稿してください。 投稿することで、解決策が見つかったり、不具合と判断されれば開発チームによって修正が行われます。 - -## 含める情報 -- Misskeyのバージョン([情報ページ](/about)で確認できます) -- お使いのブラウザの種類とバージョン -- お使いのOSの種類とバージョン -- 問題の再現手順 diff --git a/src/docs/cs-CZ/general/troubleshooting.md b/src/docs/cs-CZ/general/troubleshooting.md deleted file mode 100644 index f895b4984..000000000 --- a/src/docs/cs-CZ/general/troubleshooting.md +++ /dev/null @@ -1,40 +0,0 @@ -# トラブルシューティング -
ℹ️ よくある質問も合わせてお役立てください。
- -問題が発生したときは、まずこちらをご確認ください。 該当する項目が無い、もしくは手順を試しても効果がない場合は、サーバーの管理者に連絡するか[不具合を報告](./report-issue)してください。 - -## クライアントが起動しない -ほとんどの場合、お使いのブラウザまたはOSのバージョンが古いことが原因です。 ブラウザおよびOSのバージョンを最新のものに更新してから、再度試してみてください。 - -これは稀ですが、それでも起動しない場合は、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。 - -## ページが読み込めない -クライアントが起動するもののページが読み込めないというエラーが出る場合は、ネットワークに問題がないか確認してください。また、サーバーがダウンしていないか確認してください。 - -これは稀ですが、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。 - -まだ問題がある場合は、サーバーの問題と思われるのでサーバーの管理者に連絡してください。 - -## クライアントの動作が遅い -以下を試してみてください: - -- クライアント設定で「UIのアニメーションを減らす」を有効にする -- クライアント設定で「モーダルにぼかし効果を使用」を無効にする -- お使いのブラウザの設定でハードウェアアクセラレーションを有効にする -- お使いのデバイスのスペックを上げる - -## UIの一部の表示がおかしい(背景が透明になっている等) -アップデートによりUIの改修が行われたときに、テーマのキャッシュシステムの影響でそのような表示になることがあります。 クライアントの設定の「キャッシュをクリア」すると直ります。 -
⚠️ 「クライアントの」キャッシュクリアです。「ブラウザの」キャッシュクリアは行わないでください。
- -## 通知やアンテナ等の点滅が消えない -点滅は、未読のコンテンツがあることを示しています。通常点滅が消えない場合は、コンテンツを遡ると未読なコンテンツが残っています。 すべて既読にしたと思われるのに、それでもなお点滅が続く場合(おそらく不具合と思われます)は設定から強制的にすべて既読扱いにすることができます。 - -## Renoteができない -フォロワー限定のノートはRenoteすることはできません。 - -## UI上で特定の要素が表示されない -広告ブロッカーを使用しているとそのような不具合が発生することがあります。Misskeyではオフにしてご利用ください。 - -## UI上で未翻訳の部分がある -ほとんどの場合、単に翻訳が間に合っていないだけで、不具合ではありません。翻訳が終わるまでお待ちください。 [翻訳に参加](./misskey)していただくことも可能です。 diff --git a/src/docs/cs-CZ/keyboard-shortcut.md b/src/docs/cs-CZ/keyboard-shortcut.md deleted file mode 100644 index 62382eca6..000000000 --- a/src/docs/cs-CZ/keyboard-shortcut.md +++ /dev/null @@ -1,68 +0,0 @@ -# Klávesové zkratky - -## Globální -Tyto zkratky lze použít prakticky kdekoliv. - - - - - - - - - - - -
ZkratkaEfekt由来
P, NNový příspěvekPost, New, Note
TZaměřit se na nejnovější příspěvek ve feedu.Timeline, Top
Shift + NZobrazit/schovat notifikaceNotifications
SVyhledáváníSearch
H, ?Zobrazit nápověduHelp
- -## Zkratky pro příspěvky - - - - - - - - - - - - - - - - - - - -
ZkratkaEfekt由来
, K, Shift + Tab上の投稿にフォーカスを移動-
, J, Tab下の投稿にフォーカスを移動-
R返信フォームを開くReply
QRenoteフォームを開くQuote
Ctrl + Q即刻Renoteする(フォームを開かずに)-
E, A, +リアクションフォームを開くEmote, reAction
0~9数字に対応したリアクションをする(対応については後述)-
F, Bお気に入りに登録Favorite, Bookmark
Del, Ctrl + D投稿を削除Delete
M, O投稿に対するメニューを開くMore, Other
SCWで隠された部分を表示 or 隠すShow, See
Escフォーカスを外す-
- -## Renoteフォーム - - - - - - - - - - -
ZkratkaEfekt由来
EnterRenoteする-
Qフォームを展開するQuote
Escフォームを閉じる-
- -## リアクションフォーム -デフォルトで「👍」にフォーカスが当たっている状態です。 - - - - - - - - - - - - - -
ZkratkaEfekt由来
, K上のリアクションにフォーカスを移動-
, J下のリアクションにフォーカスを移動-
, H, Shift + Tab左のリアクションにフォーカスを移動-
, L, Tab右のリアクションにフォーカスを移動-
Enter, Space, +リアクション確定-
0~9数字に対応したリアクションで確定-
Escリアクションするのをやめる-
diff --git a/src/docs/cs-CZ/mfm.md b/src/docs/cs-CZ/mfm.md deleted file mode 100644 index 3ce8200cb..000000000 --- a/src/docs/cs-CZ/mfm.md +++ /dev/null @@ -1,2 +0,0 @@ -# MFM -MFM je zkratka pro "Misskey Flavored Markdown". Speciální markup, který může být použit na mnoha místech v Misskey. Syntaxi můžete vidět na [MFM taháku](/mfm-cheat-sheet). diff --git a/src/docs/cs-CZ/mute.md b/src/docs/cs-CZ/mute.md deleted file mode 100644 index fb4ef68d5..000000000 --- a/src/docs/cs-CZ/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# Ztlumit - -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -* タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -* そのユーザーからの通知 -* メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 - -ユーザーをミュートするには、対象のユーザーのユーザーページに表示されている「ミュート」ボタンを押します。 - -ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。 - -設定>ミュート から、自分がミュートしているユーザー一覧を確認することができます。 diff --git a/src/docs/cs-CZ/pages.md b/src/docs/cs-CZ/pages.md deleted file mode 100644 index 7edfafe68..000000000 --- a/src/docs/cs-CZ/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# Stránky - -## Proměnná -変数を使うことで動的なページを作成できます。テキスト内で { 変数名 } と書くとそこに変数の値を埋め込めます。例えば Hello { thing } world! というテキストで、変数(thing)の値が ai だった場合、テキストは Hello ai world! になります。 - -変数の評価(値を算出すること)は上から下に行われるので、ある変数の中で自分より下の変数を参照することはできません。例えば上から A、B、C と3つの変数を定義したとき、Cの中でABを参照することはできますが、Aの中でBCを参照することはできません。 - -ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。 - -関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。 diff --git a/src/docs/cs-CZ/reaction.md b/src/docs/cs-CZ/reaction.md deleted file mode 100644 index 02ccda571..000000000 --- a/src/docs/cs-CZ/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# Reakce -他の人のノートに、絵文字を付けて簡単にあなたの反応を伝えられる機能です。 リアクションするには、ノートの + アイコンをクリックしてピッカーを表示し、絵文字を選択します。 リアクションには[カスタム絵文字](./custom-emoji)も使用できます。 - -## リアクションピッカーのカスタマイズ -ピッカーに表示される絵文字を自分好みにカスタマイズすることができます。 設定の「リアクション」で設定します。 - -## リモート投稿へのリアクションについて -リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。 また、相手がMisskeyであったとしても、カスタム絵文字リアクションは伝わらず、自動的に「👍」等にフォールバックされます。 - -## リモートからのリアクションについて -リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。 diff --git a/src/docs/cs-CZ/reversi-bot.md b/src/docs/cs-CZ/reversi-bot.md deleted file mode 100644 index 7ab2a7212..000000000 --- a/src/docs/cs-CZ/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# MisskeyリバーシBotの開発 -Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。 - -1. `games/reversi`ストリームに以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - -2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる - * イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている - -3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する - -4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - * `game`: `game`の`id` - -5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う - -6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する - -7. ゲームが開始すると、`started`イベントが流れてくる - * イベントの中身にはゲーム情報が含まれている - -8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述) - -9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる - * `color`として石の色が含まれている - * `pos`として位置情報が含まれている - -## 位置の計算法 -8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### X,Y座標 から インデックス に変換する -``` -pos = x + (y * mapWidth) -``` -`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます: -``` -mapWidth = map[0].length -``` - -### インデックス から X,Y座標 に変換する -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## マップ情報 -マップ情報は、ゲーム情報の`map`に入っています。 文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 それをもとにマップのデザインを知る事が出来ます: -* `(スペース)` ... マス無し -* `-` ... マス -* `b` ... 初期配置される黒石 -* `w` ... 初期配置される白石 - -例えば、4*4の次のような単純なマップがあるとします: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -この場合、マップデータはこのようになります: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## ユーザーにフォームを提示して対話可能Botを作成する -ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。 - -フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します: -```javascript -{ - type: 'init-form', - body: [フォームコントロールの配列] -} -``` - -フォームコントロールの配列については今から説明します。 フォームコントロールは、次のようなオブジェクトです: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... コントロールのID。 `type` ... コントロールの種類。後述します。 `label` ... コントロールと一緒に表記するテキスト。 `value` ... コントロールのデフォルト値。 - -### フォームの操作を受け取る -ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### フォームコントロールの種類 -#### スイッチ -type: `switch` スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。 - -##### プロパティ -`label` ... スイッチに表記するテキスト。 - -#### ラジオボタン -type: `radio` ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。 - -##### プロパティ -`items` ... ラジオボタンの選択肢。例: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '強', - value: 3 -}] -``` - -#### スライダー -type: `slider` スライダーを表示します。 - -##### プロパティ -`min` ... スライダーの下限。 `max` ... スライダーの上限。 `step` ... 入力欄で刻むステップ値。 - -#### テキストボックス -type: `textbox` テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。 - -## ユーザーにメッセージを表示する -設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 メッセージを表示するには、次のメッセージをストリームに送信します: -```javascript -{ - type: 'message', - body: { - text: 'メッセージ内容', - type: 'メッセージの種類' - } -} -``` -メッセージの種類: `success`, `info`, `warning`, `error`。 - -## 投了する -投了をするには、このエンドポイントにリクエストします。 diff --git a/src/docs/cs-CZ/stream.md b/src/docs/cs-CZ/stream.md deleted file mode 100644 index 9011c37c5..000000000 --- a/src/docs/cs-CZ/stream.md +++ /dev/null @@ -1,354 +0,0 @@ -# ストリーミングAPI - -ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。 - -## ストリームに接続する - -ストリーミングAPIを利用するには、まずMisskeyサーバーに**websocket**接続する必要があります。 - -以下のURLに、`i`というパラメータ名で認証情報を含めて、websocket接続してください。例: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。 - -
-

認証情報の取得については、こちらのドキュメントをご確認ください。

-
- ---- - -認証情報は省略することもできますが、その場合非ログインでの利用ということになり、受信できる情報や可能な操作は限られます。例: - -``` -%WS_URL%/streaming -``` - ---- - -ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。 - -**ストリームでのやり取りはすべてJSONです。** - -## チャンネル -MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。 - -### チャンネルに接続する -チャンネルに接続するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -ここで、 -* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。 -* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。 -* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。 - -
-

IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。

-
- -### チャンネルからのメッセージを受け取る -例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。 - -チャンネルがメッセージを発すると、次のようなデータがJSONでストリームに流れてきます: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。 -* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。 -* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。 - -### チャンネルに向けてメッセージを送信する -チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。 - -チャンネルにメッセージを送信するには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。 -* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。 -* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。 - -### チャンネルから切断する -チャンネルから切断するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。 - -## ストリームを経由してAPIリクエストする - -ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。 - -ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -ここで、 -* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 -* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 -* `data`には、エンドポイントのパラメータを含めます。 - -
-

APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。

-
- -### レスポンスの受信 - -APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。 - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -ここで、 -* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 -* `body`には、レスポンスが含まれています。 - -## 投稿のキャプチャ - -Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。 - -例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。 - -しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。 - -この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。 - -### 投稿をキャプチャする - -投稿をキャプチャするには、ストリームに次のようなメッセージを送信します: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャしたい投稿の`id`を設定します。 - -このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 - -例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -ここで、 -* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。 -* `body`内の`type`に、イベントの種類が設定されます。 -* `body`内の`body`に、イベントの詳細が設定されます。 - -#### イベントの種類 - -##### `reacted` -その投稿にリアクションがされた時に発生します。 - -* `reaction`に、リアクションの種類が設定されます。 -* `userId`に、リアクションを行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -その投稿が削除された時に発生します。 - -* `deletedAt`に、削除日時が設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -その投稿に添付されたアンケートに投票された時に発生します。 - -* `choice`に、選択肢IDが設定されます。 -* `userId`に、投票を行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### 投稿のキャプチャを解除する - -その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。 - -次のメッセージを送信します: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャを解除したい投稿の`id`を設定します。 - -このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 - -# チャンネル一覧 -## `main` -アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `renote` -自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。 - -#### `mention` -誰かからメンションされたときに発生するイベントです。 - -#### `readAllNotifications` -自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。 - -#### `meUpdated` -自分の情報が更新されたことを表すイベントです。 - -#### `follow` -自分が誰かをフォローしたときに発生するイベントです。 - -#### `unfollow` -自分が誰かのフォローを解除したときに発生するイベントです。 - -#### `followed` -自分が誰かにフォローされたときに発生するイベントです。 - -## `homeTimeline` -ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -タイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `localTimeline` -ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `hybridTimeline` -ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ソーシャルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `globalTimeline` -グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 diff --git a/src/docs/cs-CZ/theme.md b/src/docs/cs-CZ/theme.md deleted file mode 100644 index 33eb61448..000000000 --- a/src/docs/cs-CZ/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# Vzhled - -Můžete si vybrat vzhled a změnit tím jak vypadá Misskey klient. - -## Nastavení vzhledu -Nastavení > vzhled - -## Vytvořit vzhled -テーマコードはJSON5で記述されたテーマオブジェクトです。 テーマは以下のようなオブジェクトです。 -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... Unikátní ID vzhledu. UUID je povinné. -* `name` ... Jméno vzhledu -* `author` ... Autor vzhledu -* `desc` ... テーマの説明(オプション) -* `base` ... 明るいテーマか、暗いテーマか - * `light`にすると明るいテーマになり、`dark`にすると暗いテーマになります。 - * テーマはここで設定されたベーステーマを継承します。 -* `props` ... テーマのスタイル定義。これから説明します。 - -### テーマのスタイル定義 -`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 - -#### バリューで使える構文 -* 16進数で表された色 - * 例: `#00ff00` -* `rgb(r, g, b)`形式で表された色 - * 例: `rgb(0, 255, 0)` -* `rgb(r, g, b, a)`形式で表された透明度を含む色 - * 例: `rgba(0, 255, 0, 0.5)` -* 他のキーの値の参照 - * `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。 - * 例: `@panel` -* 定数(後述)の参照 - * `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。 - * 例: `$main` -* 関数(後述) - * `:{関数名}<{引数}<{色}` - -#### 定数 -「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 キー名を`$`で始めると、そのキーはCSS変数として出力されません。 - -#### 関数 -wip diff --git a/src/docs/cs-CZ/timelines.md b/src/docs/cs-CZ/timelines.md deleted file mode 100644 index 3bd9f1cff..000000000 --- a/src/docs/cs-CZ/timelines.md +++ /dev/null @@ -1,15 +0,0 @@ -# タイムラインの比較 - -https://docs.google.com/spreadsheets/d/1lxQ2ugKrhz58Bg96HTDK_2F98BUritkMyIiBkOByjHA/edit?usp=sharing - -## Domů -自分のフォローしているユーザーの投稿 - -## Lokální -全てのローカルユーザーの「ホーム」指定されていない投稿 - -## ソーシャル -自分のフォローしているユーザーの投稿と、全てのローカルユーザーの「ホーム」指定されていない投稿 - -## Globální -全てのローカルユーザーの「ホーム」指定されていない投稿と、サーバーに届いた全てのリモートユーザーの「ホーム」指定されていない投稿 diff --git a/src/docs/da-DK/admin/disable-timelines.md b/src/docs/da-DK/admin/disable-timelines.md deleted file mode 100644 index b081e35ab..000000000 --- a/src/docs/da-DK/admin/disable-timelines.md +++ /dev/null @@ -1,8 +0,0 @@ -# LTL/STL/GTLの無効化 -Misskeyでは、LTL/STL/GTLをそれぞれ無効化することができます。有効/無効を切り替えるには、インスタンスコントロールパネルで設定します。 - -LTLやSTLは、そのインスタンス全員の投稿が見れるため、新規のユーザーにとってはユーザーを探す必要がなくなり、興味のあるユーザーを見つけやすいという利点があります。 しかし同時に、フォロー機能が活用されなくなったり、不適切な投稿が目につきやすくなったり、チャットのようになることで内輪感が生じて逆に新規ユーザーが参加しにくくなるといったデメリットも持ち合わせています。 サーバーによってメリット/デメリットどちらが優勢かは異なるので、オプションとして無効にできるようになっています。 もしデメリットの方が上回っていると感じたら、それらのタイムラインを無効化することも検討してください。 - -
⚠️ 無効化を行うと、ユーザーが困惑し、短期的に見て利用者が減る可能性があります。そのため、無効化の際は影響を慎重に検討し、事前に説明してフォローを整える期間を一定程度設けることを推奨します。
- -なお、管理者/モデレーターは、これらのタイムラインの無効化状態は適用されず、引き続き利用することが可能です。 diff --git a/src/docs/da-DK/admin/faq.md b/src/docs/da-DK/admin/faq.md deleted file mode 100644 index 317b4e065..000000000 --- a/src/docs/da-DK/admin/faq.md +++ /dev/null @@ -1,5 +0,0 @@ -# よくある質問 -ここでは、サーバー管理者向けのよくある質問を掲載しています。 - -## デフォルトテーマを設定したい -現在、デフォルトテーマ設定機能は実装されていません。 diff --git a/src/docs/da-DK/advanced/aiscript.md b/src/docs/da-DK/advanced/aiscript.md deleted file mode 100644 index 604d17daa..000000000 --- a/src/docs/da-DK/advanced/aiscript.md +++ /dev/null @@ -1,7 +0,0 @@ -# AiScript -AiScriptは、Misskeyで使用できるスクリプト言語です。 - -
ℹ️ AiScript実装はMisskeyとは別リポジトリで、オープンソースで公開されています。
- -## 使い方 -AiScriptの構文や組み込み関数などのドキュメントは、[こちら](https://github.com/syuilo/aiscript/tree/master/docs)で公開されています。 diff --git a/src/docs/da-DK/advanced/api.md b/src/docs/da-DK/advanced/api.md deleted file mode 100644 index 76019b614..000000000 --- a/src/docs/da-DK/advanced/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス、Bot等(以下「アプリケーション」と呼びます)を開発できます。 ストリーミングAPIもあるので、リアルタイム性のあるアプリケーションを作ることも可能です。 - -APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。 - -## アクセストークンの取得 -基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。 - -* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む -* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む - -### 自分自身のアクセストークンを手動発行する -「設定 > API」で、自分のアクセストークンを発行できます。 - -[「APIの使い方」へ進む](#APIの使い方) - -### アプリケーション利用者にアクセストークンの発行をリクエストする -アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。 - -#### Step 1 - -UUIDを生成する。以後これをセッションIDと呼びます。 - -> このセッションIDは毎回生成し、使いまわさないようにしてください。 - -#### Step 2 - -`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。 -> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます: -* `name` ... アプリケーション名 - * > 例: `MissDeck` -* `icon` ... アプリケーションのアイコン画像URL - * > 例: `https://missdeck.example.com/icon.png` -* `callback` ... 認証が終わった後にリダイレクトするURL - * > 例: `https://missdeck.example.com/callback` - * リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます -* `permission` ... アプリケーションが要求する権限 - * > 例: `write:notes,write:following,read:drive` - * 要求する権限を`,`で区切って列挙します - * どのような権限があるかは[APIリファレンス](/api-doc)で確認できます - -#### Step 3 -ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。 - -レスポンスに含まれるプロパティ: -* `token` ... ユーザーのアクセストークン -* `user` ... ユーザーの情報 - -[「APIの使い方」へ進む](#APIの使い方) - -## APIの使い方 -**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。 - -* [APIリファレンス](/api-doc) -* [ストリーミングAPI](./stream) diff --git a/src/docs/da-DK/advanced/create-plugin.md b/src/docs/da-DK/advanced/create-plugin.md deleted file mode 100644 index 0d2fa1917..000000000 --- a/src/docs/da-DK/advanced/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# プラグインの作成 -Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。 - -## メタデータ -プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。 - -### name -プラグイン名 - -### author -プラグイン作者 - -### version -プラグインバージョン。数値を指定してください。 - -### description -プラグインの説明 - -### permissions -プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。 - -### config -プラグインの設定情報を表すオブジェクト。 キーに設定名、値に以下のプロパティを含めます。 - -#### type -設定値の種類を表す文字列。以下から選択します。 string number boolean - -#### label -ユーザーに表示する設定名 - -#### description -設定の説明 - -#### default -設定のデフォルト値 - -## APIリファレンス -AiScript標準で組み込まれているAPIは掲載しません。 - -### Mk:dialog(title text type) -ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。 - -### Mk:confirm(title text type) -確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。 - -### Mk:api(endpoint params) -Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。 - -### Mk:save(key value) -任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。 - -### Mk:load(key) -Mk:saveで永続化した指定の名前の値を読み取ります。 - -### Plugin:register_post_form_action(title fn) -投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。 - -### Plugin:register_note_action(title fn) -ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 - -### Plugin:register_user_action(title fn) -ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。 - -### Plugin:register_note_view_interruptor(fn) -UIに表示されるノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:register_note_post_interruptor(fn) -ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:open_url(url) -第一引数に渡されたURLをブラウザの新しいタブで開きます。 - -### Plugin:config -プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。 diff --git a/src/docs/da-DK/advanced/develop-bot.md b/src/docs/da-DK/advanced/develop-bot.md deleted file mode 100644 index 7f825e9bc..000000000 --- a/src/docs/da-DK/advanced/develop-bot.md +++ /dev/null @@ -1,6 +0,0 @@ -# Botの作成 -[Misskey API](./api)を利用してBotの開発が可能です。 また、いくつかのBot実装が公開されているため、ぜひ参考にしてください。 - -- [syuilo/ai](https://github.com/syuilo/ai) ... Node.js上で動く、TypeScript製Bot実装 - -Botを作成したときは、プロフィール設定からBotフラグをオンにしておくことを強くおすすめします。 diff --git a/src/docs/da-DK/advanced/reversi-bot.md b/src/docs/da-DK/advanced/reversi-bot.md deleted file mode 100644 index 7ab2a7212..000000000 --- a/src/docs/da-DK/advanced/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# MisskeyリバーシBotの開発 -Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。 - -1. `games/reversi`ストリームに以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - -2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる - * イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている - -3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する - -4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - * `game`: `game`の`id` - -5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う - -6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する - -7. ゲームが開始すると、`started`イベントが流れてくる - * イベントの中身にはゲーム情報が含まれている - -8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述) - -9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる - * `color`として石の色が含まれている - * `pos`として位置情報が含まれている - -## 位置の計算法 -8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### X,Y座標 から インデックス に変換する -``` -pos = x + (y * mapWidth) -``` -`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます: -``` -mapWidth = map[0].length -``` - -### インデックス から X,Y座標 に変換する -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## マップ情報 -マップ情報は、ゲーム情報の`map`に入っています。 文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 それをもとにマップのデザインを知る事が出来ます: -* `(スペース)` ... マス無し -* `-` ... マス -* `b` ... 初期配置される黒石 -* `w` ... 初期配置される白石 - -例えば、4*4の次のような単純なマップがあるとします: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -この場合、マップデータはこのようになります: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## ユーザーにフォームを提示して対話可能Botを作成する -ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。 - -フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します: -```javascript -{ - type: 'init-form', - body: [フォームコントロールの配列] -} -``` - -フォームコントロールの配列については今から説明します。 フォームコントロールは、次のようなオブジェクトです: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... コントロールのID。 `type` ... コントロールの種類。後述します。 `label` ... コントロールと一緒に表記するテキスト。 `value` ... コントロールのデフォルト値。 - -### フォームの操作を受け取る -ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### フォームコントロールの種類 -#### スイッチ -type: `switch` スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。 - -##### プロパティ -`label` ... スイッチに表記するテキスト。 - -#### ラジオボタン -type: `radio` ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。 - -##### プロパティ -`items` ... ラジオボタンの選択肢。例: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '強', - value: 3 -}] -``` - -#### スライダー -type: `slider` スライダーを表示します。 - -##### プロパティ -`min` ... スライダーの下限。 `max` ... スライダーの上限。 `step` ... 入力欄で刻むステップ値。 - -#### テキストボックス -type: `textbox` テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。 - -## ユーザーにメッセージを表示する -設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 メッセージを表示するには、次のメッセージをストリームに送信します: -```javascript -{ - type: 'message', - body: { - text: 'メッセージ内容', - type: 'メッセージの種類' - } -} -``` -メッセージの種類: `success`, `info`, `warning`, `error`。 - -## 投了する -投了をするには、このエンドポイントにリクエストします。 diff --git a/src/docs/da-DK/advanced/share-page.md b/src/docs/da-DK/advanced/share-page.md deleted file mode 100644 index 4fb7ded0b..000000000 --- a/src/docs/da-DK/advanced/share-page.md +++ /dev/null @@ -1,54 +0,0 @@ -# シェアページ -`/share`を開くと、共有用の投稿フォームを開くことができます。 ここではシェアページで利用できるクエリ文字列の一覧を示します。 - -## クエリ文字列一覧 -### 文字 - -
-
title
-
タイトルです。本文の先頭に[ … ]と挿入されます。
-
text
-
本文です。
-
url
-
URLです。末尾に挿入されます。
-
- -### リプライ情報 -以下のいずれか - -
-
replyId
-
リプライ先のノートid
-
replyUri
-
リプライ先のUrl(リモートのノートオブジェクトを指定)
-
- -### Renote情報 -以下のいずれか - -
-
renoteId
-
Renote先のノートid
-
renoteUri
-
Renote先のUrl(リモートのノートオブジェクトを指定)
-
- -### 公開範囲 -※specifiedに相当する値はvisibility=specifiedとvisibleAccts/visibleUserIdsで指定する - -
-
visibility
-
公開範囲 ['public' | 'home' | 'followers' | 'specified']
-
localOnly
-
0(false) or 1(true)
-
visibleUserIds
-
specified時のダイレクト先のユーザーid カンマ区切りで
-
visibleAccts
-
specified時のダイレクト先のacct(@?username[@host]) カンマ区切りで
-
- -### ファイル -
-
fileIds
-
添付したいファイルのid(カンマ区切りで)
-
diff --git a/src/docs/da-DK/advanced/stream.md b/src/docs/da-DK/advanced/stream.md deleted file mode 100644 index 0e5edd2b0..000000000 --- a/src/docs/da-DK/advanced/stream.md +++ /dev/null @@ -1,350 +0,0 @@ -# ストリーミングAPI - -ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。 - -## ストリームに接続する - -ストリーミングAPIを利用するには、まずMisskeyサーバーに**websocket**接続する必要があります。 - -以下のURLに、`i`というパラメータ名で認証情報を含めて、websocket接続してください。例: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。 - -
ℹ️ 認証情報の取得については、こちらのドキュメントをご確認ください。
- ---- - -認証情報は省略することもできますが、その場合非ログインでの利用ということになり、受信できる情報や可能な操作は限られます。例: - -``` -%WS_URL%/streaming -``` - ---- - -ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。 - -**ストリームでのやり取りはすべてJSONです。** - -## チャンネル -MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。 - -ひとつのストリーム上で、同時に複数のチャンネルに接続することができます。 - -### チャンネルに接続する -チャンネルに接続するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -ここで、 -* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。 -* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。 -* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。 - -
ℹ️ IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。
- -### チャンネルからのメッセージを受け取る -例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。 - -チャンネルがメッセージを発すると、次のようなデータがJSONでストリームに流れてきます: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。 -* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。 -* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。 - -### チャンネルに向けてメッセージを送信する -チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。 - -チャンネルにメッセージを送信するには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。 -* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。 -* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。 - -### チャンネルから切断する -チャンネルから切断するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。 - -## ストリームを経由してAPIリクエストする - -ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。 - -ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -ここで、 -* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 -* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 -* `data`には、エンドポイントのパラメータを含めます。 - -
ℹ️ APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。
- -### レスポンスの受信 - -APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。 - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -ここで、 -* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 -* `body`には、レスポンスが含まれています。 - -## 投稿のキャプチャ - -Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。 - -例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。 - -しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。 - -この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。 - -### 投稿をキャプチャする - -投稿をキャプチャするには、ストリームに次のようなメッセージを送信します: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャしたい投稿の`id`を設定します。 - -このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 - -例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -ここで、 -* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。 -* `body`内の`type`に、イベントの種類が設定されます。 -* `body`内の`body`に、イベントの詳細が設定されます。 - -#### イベントの種類 - -##### `reacted` -その投稿にリアクションがされた時に発生します。 - -* `reaction`に、リアクションの種類が設定されます。 -* `userId`に、リアクションを行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -その投稿が削除された時に発生します。 - -* `deletedAt`に、削除日時が設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -その投稿に添付されたアンケートに投票された時に発生します。 - -* `choice`に、選択肢IDが設定されます。 -* `userId`に、投票を行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### 投稿のキャプチャを解除する - -その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。 - -次のメッセージを送信します: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャを解除したい投稿の`id`を設定します。 - -このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 - -# チャンネル一覧 -## `main` -アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `renote` -自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。 - -#### `mention` -誰かからメンションされたときに発生するイベントです。 - -#### `readAllNotifications` -自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。 - -#### `meUpdated` -自分の情報が更新されたことを表すイベントです。 - -#### `follow` -自分が誰かをフォローしたときに発生するイベントです。 - -#### `unfollow` -自分が誰かのフォローを解除したときに発生するイベントです。 - -#### `followed` -自分が誰かにフォローされたときに発生するイベントです。 - -## `homeTimeline` -ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -タイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `localTimeline` -ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `hybridTimeline` -ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ソーシャルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `globalTimeline` -グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 diff --git a/src/docs/da-DK/aiscript.md b/src/docs/da-DK/aiscript.md deleted file mode 100644 index 6c28b446e..000000000 --- a/src/docs/da-DK/aiscript.md +++ /dev/null @@ -1,4 +0,0 @@ -# AiScript - -## 関数 -デフォルトで値渡しです。 diff --git a/src/docs/da-DK/api.md b/src/docs/da-DK/api.md deleted file mode 100644 index 76019b614..000000000 --- a/src/docs/da-DK/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス、Bot等(以下「アプリケーション」と呼びます)を開発できます。 ストリーミングAPIもあるので、リアルタイム性のあるアプリケーションを作ることも可能です。 - -APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。 - -## アクセストークンの取得 -基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。 - -* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む -* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む - -### 自分自身のアクセストークンを手動発行する -「設定 > API」で、自分のアクセストークンを発行できます。 - -[「APIの使い方」へ進む](#APIの使い方) - -### アプリケーション利用者にアクセストークンの発行をリクエストする -アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。 - -#### Step 1 - -UUIDを生成する。以後これをセッションIDと呼びます。 - -> このセッションIDは毎回生成し、使いまわさないようにしてください。 - -#### Step 2 - -`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。 -> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます: -* `name` ... アプリケーション名 - * > 例: `MissDeck` -* `icon` ... アプリケーションのアイコン画像URL - * > 例: `https://missdeck.example.com/icon.png` -* `callback` ... 認証が終わった後にリダイレクトするURL - * > 例: `https://missdeck.example.com/callback` - * リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます -* `permission` ... アプリケーションが要求する権限 - * > 例: `write:notes,write:following,read:drive` - * 要求する権限を`,`で区切って列挙します - * どのような権限があるかは[APIリファレンス](/api-doc)で確認できます - -#### Step 3 -ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。 - -レスポンスに含まれるプロパティ: -* `token` ... ユーザーのアクセストークン -* `user` ... ユーザーの情報 - -[「APIの使い方」へ進む](#APIの使い方) - -## APIの使い方 -**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。 - -* [APIリファレンス](/api-doc) -* [ストリーミングAPI](./stream) diff --git a/src/docs/da-DK/create-plugin.md b/src/docs/da-DK/create-plugin.md deleted file mode 100644 index 0d2fa1917..000000000 --- a/src/docs/da-DK/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# プラグインの作成 -Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。 - -## メタデータ -プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。 - -### name -プラグイン名 - -### author -プラグイン作者 - -### version -プラグインバージョン。数値を指定してください。 - -### description -プラグインの説明 - -### permissions -プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。 - -### config -プラグインの設定情報を表すオブジェクト。 キーに設定名、値に以下のプロパティを含めます。 - -#### type -設定値の種類を表す文字列。以下から選択します。 string number boolean - -#### label -ユーザーに表示する設定名 - -#### description -設定の説明 - -#### default -設定のデフォルト値 - -## APIリファレンス -AiScript標準で組み込まれているAPIは掲載しません。 - -### Mk:dialog(title text type) -ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。 - -### Mk:confirm(title text type) -確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。 - -### Mk:api(endpoint params) -Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。 - -### Mk:save(key value) -任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。 - -### Mk:load(key) -Mk:saveで永続化した指定の名前の値を読み取ります。 - -### Plugin:register_post_form_action(title fn) -投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。 - -### Plugin:register_note_action(title fn) -ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 - -### Plugin:register_user_action(title fn) -ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。 - -### Plugin:register_note_view_interruptor(fn) -UIに表示されるノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:register_note_post_interruptor(fn) -ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:open_url(url) -第一引数に渡されたURLをブラウザの新しいタブで開きます。 - -### Plugin:config -プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。 diff --git a/src/docs/da-DK/custom-emoji.md b/src/docs/da-DK/custom-emoji.md deleted file mode 100644 index ed2e92be1..000000000 --- a/src/docs/da-DK/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# カスタム絵文字 -カスタム絵文字は、インスタンスで用意された画像を絵文字のように使える機能です。 ノート、リアクション、チャット、自己紹介、名前などの場所で使うことができます。 カスタム絵文字をそれらの場所で使うには、絵文字ピッカーボタン(ある場合)を押すか、`:`を入力して絵文字サジェストを表示します。 テキスト内に`:foo:`のような形式の文字列が見つかると、`foo`の部分がカスタム絵文字名と解釈され、表示時には対応したカスタム絵文字に置き換わります。 diff --git a/src/docs/da-DK/deck.md b/src/docs/da-DK/deck.md deleted file mode 100644 index 8057e262f..000000000 --- a/src/docs/da-DK/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# デッキ - -デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。 - -## カラムの追加 -デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。 - -## カラムの移動 -カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。 - -## カラムの水平分割 -カラムは左右だけでなく、上下に並べることもできます。 カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 上下分割を解除するには、カラムメニューの「右に出す」を選択します。 - -## カラムの設定 -カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。 - -## デッキの設定 -デッキに関する設定は、[settings/deck](/settings/deck)で行えます。 diff --git a/src/docs/da-DK/features/antenna.md b/src/docs/da-DK/features/antenna.md deleted file mode 100644 index 94ad9e4ae..000000000 --- a/src/docs/da-DK/features/antenna.md +++ /dev/null @@ -1,4 +0,0 @@ -# アンテナ -アンテナは、自由に条件を設定して、合致するノートを自動で収集することができる機能です。 - -条件を設定したアンテナが作成された状態で、条件に合致するノートが投稿されると、リアルタイムでそのアンテナのタイムラインにノートが追加されます。 diff --git a/src/docs/da-DK/features/custom-emoji.md b/src/docs/da-DK/features/custom-emoji.md deleted file mode 100644 index ed2e92be1..000000000 --- a/src/docs/da-DK/features/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# カスタム絵文字 -カスタム絵文字は、インスタンスで用意された画像を絵文字のように使える機能です。 ノート、リアクション、チャット、自己紹介、名前などの場所で使うことができます。 カスタム絵文字をそれらの場所で使うには、絵文字ピッカーボタン(ある場合)を押すか、`:`を入力して絵文字サジェストを表示します。 テキスト内に`:foo:`のような形式の文字列が見つかると、`foo`の部分がカスタム絵文字名と解釈され、表示時には対応したカスタム絵文字に置き換わります。 diff --git a/src/docs/da-DK/features/deck.md b/src/docs/da-DK/features/deck.md deleted file mode 100644 index 8057e262f..000000000 --- a/src/docs/da-DK/features/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# デッキ - -デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。 - -## カラムの追加 -デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。 - -## カラムの移動 -カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。 - -## カラムの水平分割 -カラムは左右だけでなく、上下に並べることもできます。 カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 上下分割を解除するには、カラムメニューの「右に出す」を選択します。 - -## カラムの設定 -カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。 - -## デッキの設定 -デッキに関する設定は、[settings/deck](/settings/deck)で行えます。 diff --git a/src/docs/da-DK/features/drive.md b/src/docs/da-DK/features/drive.md deleted file mode 100644 index b82a41082..000000000 --- a/src/docs/da-DK/features/drive.md +++ /dev/null @@ -1,17 +0,0 @@ -# ドライブ -ドライブは、Misskey上でファイルを管理できる機能です。 - -[ドライブのページ](/my/drive)から任意のファイルをアップロードできるほか、アバターに設定した画像や、ノートに添付したファイルなどもすべてドライブにアップロードされます。 - -
⚠️ ドライブからファイルを削除すると、そのファイルが添付されたノートも消えます。
- -ドライブにアップロードされたファイルは、いつでもダウンロードすることができるほか、ノート作成時に「ドライブからファイルを添付」することでファイルを再利用することもできます。 - -ドライブ内にフォルダを作り、複数のファイルをまとめて整理することもできます。 - -## 閲覧注意 (NSFW) -
ℹ️ この項目が閲覧注意なわけではありません
- -閲覧注意またはNSFW (Not safe for work) は、ドライブのファイルに設定することができるフラグです。 閲覧注意フラグを設定されたファイルは、表示される際に閲覧者の操作なしには表示されなくなります。 このフラグは、例えば職場や公共の場で閲覧するのに適切でないと思われる画像などに設定し、そのような画像が突然表示されてしまうことを防ぐ目的で使われます。 - -このフラグは手動でオンオフを切り替えられるほか、モデレーターの判断で設定される場合もあります。 diff --git a/src/docs/da-DK/features/favorite.md b/src/docs/da-DK/features/favorite.md deleted file mode 100644 index a0e5f8bf7..000000000 --- a/src/docs/da-DK/features/favorite.md +++ /dev/null @@ -1,4 +0,0 @@ -# お気に入り -[ノート](./node)をお気に入りとして登録できる機能です。 お気に入り登録したノートは、[お気に入りページ](./my/favorites)で一覧することができます。 お気に入りに登録したことは相手に通知されず、お気に入りは自分しか見ることができません。 - -ノートをお気に入り登録するには、ノートメニューの「お気に入り」を押します。お気に入り解除するには、ノートメニューの「お気に入り解除」を押します。 diff --git a/src/docs/da-DK/features/follow.md b/src/docs/da-DK/features/follow.md deleted file mode 100644 index 3c1ea7bbe..000000000 --- a/src/docs/da-DK/features/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# フォロー -ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。 diff --git a/src/docs/da-DK/features/keyboard-shortcut.md b/src/docs/da-DK/features/keyboard-shortcut.md deleted file mode 100644 index 8659ace98..000000000 --- a/src/docs/da-DK/features/keyboard-shortcut.md +++ /dev/null @@ -1,66 +0,0 @@ -# キーボードショートカット - -## グローバル -これらのショートカットは基本的にどこでも使えます。 - - - - - - - - - - - -
ショートカット効果由来
P, N新規投稿Post, New, Note
Tタイムラインの最も新しい投稿にフォーカスTimeline, Top
Shift + N通知を表示/隠すNotifications
S検索Search
H, ?ヘルプを表示Help
- -## 投稿にフォーカスされた状態 - - - - - - - - - - - - - - - - - - -
ショートカット効果由来
, K, Shift + Tab上の投稿にフォーカスを移動-
, J, Tab下の投稿にフォーカスを移動-
R返信フォームを開くReply
QRenoteフォームを開くQuote
Ctrl + Q即刻Renoteする(フォームを開かずに)-
E, A, +リアクションフォームを開くEmote, reAction
0~9数字に対応したリアクションをする(対応については後述)-
F, Bお気に入りに登録Favorite, Bookmark
Del, Ctrl + D投稿を削除Delete
M, O投稿に対するメニューを開くMore, Other
SCWで隠された部分を表示 or 隠すShow, See
Escフォーカスを外す-
- -## Renoteフォーム - - - - - - - - - -
ショートカット効果由来
EnterRenoteする-
Qフォームを展開するQuote
Escフォームを閉じる-
- -## リアクションフォーム -デフォルトで「👍」にフォーカスが当たっている状態です。 - - - - - - - - - - - - - -
ショートカット効果由来
, K上のリアクションにフォーカスを移動-
, J下のリアクションにフォーカスを移動-
, H, Shift + Tab左のリアクションにフォーカスを移動-
, L, Tab右のリアクションにフォーカスを移動-
Enter, Space, +リアクション確定-
0~9数字に対応したリアクションで確定-
Escリアクションするのをやめる-
diff --git a/src/docs/da-DK/features/mfm.md b/src/docs/da-DK/features/mfm.md deleted file mode 100644 index 5be2df4f3..000000000 --- a/src/docs/da-DK/features/mfm.md +++ /dev/null @@ -1,12 +0,0 @@ -# MFM -MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます。 - -## MFMが使用可能な場所の例 -- ノート本文 -- CW注釈 -- ユーザーの名前 -- ユーザーの自己紹介 - -## 開発者向け情報 -MFMのパーサー実装はライブラリとして公開されており、簡単にクライアントにMFMを組み込むことが可能です。 -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptパーサー実装 diff --git a/src/docs/da-DK/features/mute-and-block.md b/src/docs/da-DK/features/mute-and-block.md deleted file mode 100644 index d78a7cea4..000000000 --- a/src/docs/da-DK/features/mute-and-block.md +++ /dev/null @@ -1,41 +0,0 @@ -# ミュートとブロック -好みではないユーザーがいる場合は、ミュートを行うことでそのユーザーが自分から見えないようにすることができます。 また、より強力な措置として、ブロックを行うことでそのユーザーから自分のコンテンツが見えないようになるほか、自分に対して関わることができないようにすることができます。 ミュートされていることは相手は分かりませんが、ブロックされていることは相手に分かります。どちらを選ぶかはご自身の判断で行ってください。 - -
ℹ️ ミュートとブロックは併用できます。
- -
⚠️ 利用規約に違反するような、迷惑なユーザーがいる場合は運営者に報告することも検討してください。
- -設定>ミュートとブロック から、自分がミュートまたはブロックしているユーザー一覧を確認することができます。 - -## ミュート -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -- タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -- そのユーザーからの通知 -- メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 -- など - -ユーザーをミュートするには、対象のユーザーのユーザーページのメニューを開き、「ミュート」ボタンを押します。 - -
ℹ️ ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。
- -## ブロック -ユーザーをブロックすると、そのユーザーからあなたのコンテンツが見えないようになり、またあなたに対して以下のようなアクションをすることができなくなります。 - -- フォローする -- ユーザーリストに追加する -- 返信する、Renoteする -- リアクションする、アンケートに投票する -- メッセージを送信する -- など - -また、 - -- ブロックする際に既にそのユーザーからフォローされていた場合はフォローが解除されます。 -- ブロックする際に既にそのユーザーがあなたをユーザーリストに入れていた場合はそのリストからあなたが削除されます。 - -ユーザーをブロックするには、対象のユーザーのユーザーページのメニューを開き、「ブロック」ボタンを押します。 - -
⚠️ ブロックを行ったこと自体は相手に通知されませんが、フォローを行ったりなどの上記のアクションが行えなくなるので間接的にブロックされていることは分かります。
- -
⚠️ 相手から自分のコンテンツが見えなくなりますが、相手がアカウントを切り替えたりログアウト状態になれば見ることができます。あくまで簡易的、補助的なものとしてお考えください。
diff --git a/src/docs/da-DK/features/mute.md b/src/docs/da-DK/features/mute.md deleted file mode 100644 index 6a9608662..000000000 --- a/src/docs/da-DK/features/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# ミュート - -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -* タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -* そのユーザーからの通知 -* メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 - -ユーザーをミュートするには、対象のユーザーのユーザーページに表示されている「ミュート」ボタンを押します。 - -ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。 - -設定>ミュート から、自分がミュートしているユーザー一覧を確認することができます。 diff --git a/src/docs/da-DK/features/note.md b/src/docs/da-DK/features/note.md deleted file mode 100644 index 305ff626f..000000000 --- a/src/docs/da-DK/features/note.md +++ /dev/null @@ -1,54 +0,0 @@ -# ノート -ノートは、Misskeyに投稿される、文章、ファイル、アンケートなどを含むコンテンツで、Misskeyの中心的概念です。また、そのノートを作成する行為自体もノートと呼ばれます。 - -ノートが作成されると、[タイムライン](./timeline)に追加され、自分の[フォロワー](./follow)やサーバーのユーザーが見れるようになります。 - -ノートには、[リアクション](./reaction)を行うことができます。また、返信や引用もできます。 - -ノートを[お気に入り](./favorite)登録することで、後で簡単に見返すことができます。 - -## ノートを作成する -ノートを作成するには、画面上にある鉛筆マークのボタンを押して、作成フォームを開きます。作成フォームに内容を入力し、「ノート」ボタンを押すことでノートが作成されます。 ノートには、画像、動画など任意のファイルや、[アンケート](./poll)を添付することができます。また、本文中には[MFM](./mfm)が使用でき、[メンション](./mention)や[ハッシュタグ](./hashtag)を含めることもできます。 他にも、CWや公開範囲といった設定も行えます(詳細は後述)。 -
ℹ️ コンピューターのクリップボードに画像データがある状態で、フォーム内のテキストボックスにペーストするとその画像を添付することができます。
-
ℹ️ テキストボックス内でCtrl + Enterを押すことでも投稿できます。
- -## Renote -既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノートをRenoteと呼びます。 自分がフォローしているユーザーの、気に入ったノートを自分のフォロワーに共有したい場合や、過去の自分のノートを再度共有したい場合に使います。 同じノートに対して無制限にRenoteを行うことができますが、あまり連続して使用すると迷惑になる場合もあるので、注意しましょう。 -
⚠️ 公開範囲がフォロワーやダイレクトのノートはRenoteできません
- -Renoteを削除するには、Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 - -## CW -Contents Warningの略で、ノートの内容を、閲覧者の操作なしには表示しないようにできる機能です。主に長大な内容を隠すためや、ネタバレ防止などに使うことができます。 設定するには、フォームの「内容を隠す」ボタン(目のアイコン)を押します。すると新しい入力エリアが表れるので、そこに内容の要約を記入します。 - -## 公開範囲 -ノートごとに、そのノートが公開される範囲を設定することができます。フォームの「ノート」ボタンの左にあるアイコンを押すと公開範囲を以下から選択できます。 - -### パブリック -全ての人に対してノートが公開されるほか、サーバーの全てのタイムライン(ホームタイムライン、ローカルタイムライン、ソーシャルタイムライン、グローバルタイムライン)にノートが流れます。 -
⚠️ アカウントがサイレンス状態の時は、この公開範囲は使用できません。
- -### ホーム -全ての人に対してノートが公開されますが、フォロワー以外のローカルタイムライン、ソーシャルタイムライン、グローバルタイムラインにはノートは流れません。 - -### フォロワー -自分のフォロワーに対してのみノートを公開します。フォロワーの全てのタイムラインに流れます。 - -### ダイレクト -指定したユーザーに対してのみノートを公開します。指定したユーザーの全てのタイムラインに流れます。 - -### 「ローカルのみ」オプション -このオプションを有効にすると、リモートにノートを連合しなくなります。 - -### 公開範囲の比較 - - - - -
パブリックホームフォロワーダイレクト
フォロワーのLTL/STL/GTL
非フォロワーのLTL/STL/GTL
- -## ピン留め -ノートをピン留めすると、ユーザーページに常にそのノートを表示しておくことができます。 ノートのメニューを開き、「ピン留め」を選択してピン留めできます。 複数のノートをピン留めできます。 - -## ウォッチ -ノートをウォッチすると、自分以外のノートへのリアクションや返信などの通知を受け取ることができます。 ノートのメニューを開き、「ウォッチ」を選択してウォッチできます。 diff --git a/src/docs/da-DK/features/pages.md b/src/docs/da-DK/features/pages.md deleted file mode 100644 index a7311b95e..000000000 --- a/src/docs/da-DK/features/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# Pages - -## 変数 -変数を使うことで動的なページを作成できます。テキスト内で { 変数名 } と書くとそこに変数の値を埋め込めます。例えば Hello { thing } world! というテキストで、変数(thing)の値が ai だった場合、テキストは Hello ai world! になります。 - -変数の評価(値を算出すること)は上から下に行われるので、ある変数の中で自分より下の変数を参照することはできません。例えば上から A、B、C と3つの変数を定義したとき、Cの中でABを参照することはできますが、Aの中でBCを参照することはできません。 - -ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。 - -関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。 diff --git a/src/docs/da-DK/features/reaction.md b/src/docs/da-DK/features/reaction.md deleted file mode 100644 index 4d479fd41..000000000 --- a/src/docs/da-DK/features/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# リアクション -他の人のノートに、絵文字を付けて簡単にあなたの反応を伝えられる機能です。 リアクションするには、ノートの + アイコンをクリックしてピッカーを表示し、絵文字を選択します。 リアクションには[カスタム絵文字](./custom-emoji)も使用できます。 - -## リアクションピッカーのカスタマイズ -ピッカーに表示される絵文字を自分好みにカスタマイズすることができます。 設定の「リアクション」で設定します。 - -## リモート投稿へのリアクションについて -リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。 - -## リモートからのリアクションについて -リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。 diff --git a/src/docs/da-DK/features/silence.md b/src/docs/da-DK/features/silence.md deleted file mode 100644 index 7e26feab0..000000000 --- a/src/docs/da-DK/features/silence.md +++ /dev/null @@ -1,6 +0,0 @@ -# サイレンス -サイレンスは、アカウントに設定される状態のひとつです。 - -アカウントがサイレンス状態になると、ノートの公開範囲をパブリックにできなくなります。 ホーム、フォロワー、ダイレクトは選択可能なため、サイレンスを受けた場合でもフォロワーやあなたのユーザーページを直接訪れた場合は投稿を閲覧できますが、GTL(連合タイムライン)やLTL(ローカルタイムライン)には投稿が流れません。 - -アカウントのサイレンス状態は、サーバーのモデレーターによって有効化/無効化されます。 diff --git a/src/docs/da-DK/features/theme.md b/src/docs/da-DK/features/theme.md deleted file mode 100644 index a406f3433..000000000 --- a/src/docs/da-DK/features/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# テーマ - -テーマを設定して、Misskeyクライアントの見た目を変更できます。 - -## テーマの設定 -設定 > テーマ - -## テーマを作成する -テーマコードはJSON5で記述されたテーマオブジェクトです。 テーマは以下のようなオブジェクトです。 -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... テーマの一意なID。UUIDをおすすめします。 -* `name` ... テーマ名 -* `author` ... テーマの作者 -* `desc` ... テーマの説明(オプション) -* `base` ... 明るいテーマか、暗いテーマか - * `light`にすると明るいテーマになり、`dark`にすると暗いテーマになります。 - * テーマはここで設定されたベーステーマを継承します。 -* `props` ... テーマのスタイル定義。これから説明します。 - -### テーマのスタイル定義 -`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 - -#### バリューで使える構文 -* 16進数で表された色 - * 例: `#00ff00` -* `rgb(r, g, b)`形式で表された色 - * 例: `rgb(0, 255, 0)` -* `rgb(r, g, b, a)`形式で表された透明度を含む色 - * 例: `rgba(0, 255, 0, 0.5)` -* 他のキーの値の参照 - * `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。 - * 例: `@panel` -* 定数(後述)の参照 - * `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。 - * 例: `$main` -* 関数(後述) - * `:{関数名}<{引数}<{色}` - -#### 定数 -「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 キー名を`$`で始めると、そのキーはCSS変数として出力されません。 - -#### 関数 -wip diff --git a/src/docs/da-DK/features/timeline.md b/src/docs/da-DK/features/timeline.md deleted file mode 100644 index f431014f8..000000000 --- a/src/docs/da-DK/features/timeline.md +++ /dev/null @@ -1,31 +0,0 @@ -# タイムライン -タイムラインは、[ノート](./note)が時系列で表示される機能です。 タイムラインには以下で示す種類があり、種類によって表示されるノートも異なります。 なお、タイムラインの種類によってはサーバーにより無効になっている場合があります。 - -## ホーム -自分のフォローしているユーザーの投稿が流れます。HTLと略されます。 - -## ローカル -全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。LTLと略されます。 - -## ソーシャル -自分のフォローしているユーザーの投稿と、全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。STLと略されます。 - -## グローバル -全てのローカルユーザーの「ホーム」指定されていない投稿と、サーバーに届いた全てのリモートユーザーの「ホーム」指定されていない投稿が流れます。GTLと略されます。 - -## 比較 -| ソース | | | タイムライン | | | -| ------------ | ----- | --- | ------ | ----- | ----- | -| ユーザー | 公開範囲 | ホーム | ローカル | ソーシャル | グローバル | -| ローカル (フォロー) | 公開 | ✔ | ✔ | ✔ | ✔ | -| | ホーム | ✔ | | ✔ | | -| | フォロワー | ✔ | ✔ | ✔ | ✔ | -| リモート (フォロー) | 公開 | ✔ | | ✔ | ✔ | -| | ホーム | ✔ | | ✔ | | -| | フォロワー | ✔ | | ✔ | ✔ | -| ローカル (未フォロー) | 公開 | | ✔ | ✔ | ✔ | -| | ホーム | | | | | -| | フォロワー | | | | | -| リモート (未フォロー) | 公開 | | | | ✔ | -| | ホーム | | | | | -| | フォロワー | | | | | diff --git a/src/docs/da-DK/features/widgets.md b/src/docs/da-DK/features/widgets.md deleted file mode 100644 index a7c2c1d1d..000000000 --- a/src/docs/da-DK/features/widgets.md +++ /dev/null @@ -1,7 +0,0 @@ -# ウィジェット -ウィジェットは、MisskeyのUI上に設置できる小型の情報表示、操作が行えるパーツです。 - -ウィジェットを編集するには、ウィジェット編集モードに切り替えます。切り替え方法はUIによって異なります。 ウィジェット編集モードでは、ウィジェットの追加、削除、並び替え、およびそれぞれのウィジェットの設定を行えます。 - -## 利用可能なウィジェット一覧 -todo diff --git a/src/docs/da-DK/features/word-mute.md b/src/docs/da-DK/features/word-mute.md deleted file mode 100644 index fa4d14346..000000000 --- a/src/docs/da-DK/features/word-mute.md +++ /dev/null @@ -1,20 +0,0 @@ -# ワードミュート -ワードミュートの設定をすると、条件に合致したノートが表示されなくなります。 - -ワードミュートには、ソフトワードミュートとハードワードミュートの2種類があります。それぞれについて設定の方法と挙動を説明します。 - -## ソフトワードミュート -ソフトワードミュートは、クライアント(アプリ)側でミュートを判断するワードミュートです。 - -ノートが設定した条件に合致すると、「(ユーザー名)が何かを言いました」という表示で隠れます。 -クリックすると元の通りに表示されます。 - -## ハードワードミュート -ハードワードミュートは、アンテナのようにサーバーが新しいノートの本文に対して条件に合致するかどうか判断し、タイムラインから対象となったノートを除外します。 - -つまり、ハードワードミュートには、以下のような特徴があります。 - -* 条件設定後、新しい投稿のみがミュートの対象になります。 -* 条件を変更しても、過去にハードミュートされたノートはミュートされたままになります。 -* 「○○が何かを言いました」でタイムラインが埋まることがありません。 -* ソフトミュートに非対応のアプリでも、ハードミュートは適用されます。 diff --git a/src/docs/da-DK/follow.md b/src/docs/da-DK/follow.md deleted file mode 100644 index 3c1ea7bbe..000000000 --- a/src/docs/da-DK/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# フォロー -ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。 diff --git a/src/docs/da-DK/general/apps.md b/src/docs/da-DK/general/apps.md deleted file mode 100644 index 1f4c85fe8..000000000 --- a/src/docs/da-DK/general/apps.md +++ /dev/null @@ -1,6 +0,0 @@ -# サードパーティアプリのリスト -## クライアント -todo - -## 連携サービス -todo diff --git a/src/docs/da-DK/general/changelog.md b/src/docs/da-DK/general/changelog.md deleted file mode 100644 index 6766a63b2..000000000 --- a/src/docs/da-DK/general/changelog.md +++ /dev/null @@ -1,5 +0,0 @@ -# 更新履歴 -
ℹ️ このサーバーの更新履歴です。Misskeyの最新のリリースについては、GitHubをご確認ください。
- - - diff --git a/src/docs/da-DK/general/faq.md b/src/docs/da-DK/general/faq.md deleted file mode 100644 index c272b2ad4..000000000 --- a/src/docs/da-DK/general/faq.md +++ /dev/null @@ -1,28 +0,0 @@ -# よくある質問 -ここでは利用上のよくある質問について掲載しています。 Misskeyのプロジェクト自体についてのよくある質問は[こちら](./misskey)に掲載されています。 - -## iOS/Androidのアプリはありますか? -公式にはそういったOSのネイティブアプリを開発していませんが、サードパーティ製のアプリがいくつかあります。 詳しくは[こちら](./apps)をご覧ください。 - -ただ、サードパーティ製アプリはどうしても機能への対応が遅れてしまうため、とくに拘りがなければ公式のWebクライアントの利用をおすすめします。 なお、MisskeyのWebクライアントはPWAに対応しているので、ネイティブアプリのように動作させることも可能です。 詳しくは[こちら](todo)をご覧ください。 - -## Mastodonクライアントでログインできないのですが? -MisskeyはMastodonのAPIと互換性がないため、一部を除きMastodonクライアントでMisskeyを利用することはできません。 - -## 他のサーバーのユーザーをフォローするときは? -メニューから検索を選び、ユーザー名をホスト込みで入力します。例: `@syuilo@misskey.io` - -## Renoteを削除するには? -Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 Renoteについては[こちら](../features/note)をご確認ください。 - -## URLのプレビューを表示させたくない -MFMには、そのURLのプレビューを無効にする構文があります。詳細は[MFMチートシート](/mfm-cheat-sheet)をご確認ください。 - -## カスタム絵文字を追加したい -運営者のみがカスタム絵文字を追加、編集、削除できます。それらを希望する場合は運営者に依頼してください。 - -## Botを開発したい -Misskey APIを利用してBotの開発が可能です。[こちら](../advanced/develop-bot)をご確認ください。 - -## ノートの翻訳機能はどのサービスを使用していますか? -[DeepL](https://www.deepl.com/)を使用しています。 diff --git a/src/docs/da-DK/general/glossary.md b/src/docs/da-DK/general/glossary.md deleted file mode 100644 index bb8a24336..000000000 --- a/src/docs/da-DK/general/glossary.md +++ /dev/null @@ -1,89 +0,0 @@ -# 用語集 -Misskeyに関する用語集です。 - -## ActivityPub -(読み: あくてぃびてぃぱぶ) 分散型を実現するために用いられるプロトコル(仕様)。このプロトコルに則ってサーバー同士通信を行うことで、連合が行われ、Fediverseを形成しています。 - -## AiScript -(読み: あいすくりぷと) Misskey上で使用できるプログラミング言語です。詳細は[こちら。](../advanced/aiscript) - -## API -(読み: えーぴーあい) Misskeyのサーバーが公開している、プログラムからMisskeyを扱うためのインターフェース。詳細は[こちら。](../advanced/api) - -## Bot -(読み: ぼっと) プログラムによって動作しているアカウント。 - -## CW -(読み: こんてんつわーにんぐ) Contents Warningの略。ノートの内容を、操作なしには表示しないようにできる機能。主に長大な内容を隠すためや、ネタバレ防止などに使われます。 - -## Fediverse -(読み: ふぇでぃばーす) Misskeyを含む様々な分散型ソフトウェアのサーバーで構成されたネットワーク。 - -## GTL -グローバルタイムライン(Global TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## HTL -ホームタイムライン(Home TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## LTL -ローカルタイムライン(Local TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## MFM -(読み: えむえふえむ) Misskey Flavored Markdownの略で、Misskey上で使用できるマークアップ言語です。詳細は[こちら。](../features/mfm) - -## NSFW -(読み: のっとせーふふぉーわーく) Not Safe For Workの略。画像を「閲覧注意」扱いにし、操作なしには表示しないようにすることができる機能。 - -## Renote -(読み: りのーと) 既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノート。詳細は[こちら。](../features/note) - -## STL -ソーシャルタイムライン(Social TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## 藍 -(読み: あい) Misskeyの看板娘(公式キャラクター)です。 - -## アクティブユーザー -インスタンスにアカウントを作っているユーザーのうち、現在も実際にサービスを利用しているユーザーのこと。 - -## インスタンス -todo - -## カスタム絵文字 -サーバーで用意された絵文字。カスタム絵文字ではない通常の絵文字は「Unicode絵文字」と区別して呼ばれる。 - -## コントロールパネル -インスタンスの設定画面のこと。 - -## サーバー -todo - -## サイレンス -ノートをパブリックな公開範囲で投稿できなくされている状態。モデレーターの判断でユーザーごとに設定されます。詳細は[こちら。](../features/silence) - -## ジョブキュー -アクティビティ配送などを順番に行うためのシステム。 - -## 凍結 -アカウントが使用不可に設定されている状態。 - -## ドライブ -Misskeyにアップロードしたファイルを管理する機能。詳細は[こちら。](../features/drive) - -## ノート -Misskeyに投稿される、文章、ファイル、アンケートなどを含めることができるコンテンツ。詳細は[こちら。](../features/note) - -## ミスキスト -Misskeyを使う人のこと。 - -## モデレーター -スパムの凍結およびサイレンスや不適切な投稿の削除など、コミュニティ運営に関する権限を持つユーザー。 - -## リモート -他サーバーのことを指します。リモートユーザーといったように接頭辞としても使われます。ローカルの逆です。 - -## 連合 -サーバー上で作成された情報が他のサーバーに伝わること。 - -## ローカル -自サーバーのことを指します。ローカルユーザー、ローカルタイムラインといったように接頭辞としても使われます。リモートの逆です。 diff --git a/src/docs/da-DK/general/links.md b/src/docs/da-DK/general/links.md deleted file mode 100644 index 5ce5e1ddb..000000000 --- a/src/docs/da-DK/general/links.md +++ /dev/null @@ -1,12 +0,0 @@ -# リンク集 - -## Webサイト -- [Official Discord](https://discord.gg/Wp8gVStHW3) - Misskey公式Discordサーバー -- [Misskey Forum](https://forum.misskey.io/) - Misskeyに関する話題を扱うフォーラム - -## アカウント -- [@repo@misskey.io](https://misskey.io/@repo) - Misskeyのリポジトリの更新を投稿するbot - -## ライブラリ -- [misskey-dev/misskey.js](https://github.com/misskey-dev/misskey.js) - JavaScriptのMisskey SDK -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptのMFMパーサー実装 diff --git a/src/docs/da-DK/general/misskey.md b/src/docs/da-DK/general/misskey.md deleted file mode 100644 index d97664ddc..000000000 --- a/src/docs/da-DK/general/misskey.md +++ /dev/null @@ -1,87 +0,0 @@ -# Misskeyについて - -Misskeyはオープンソースの分散型マイクロブログプラットフォームプロジェクトです。 開発は日本でsyuiloによって2014年から開始されました。 ドライブ、リアクションなどの豊富な機能や、高いカスタマイズ性を備えたUIを持つことが特徴です。 - -## 歴史 -開発当初は掲示板がメインのサービスでしたが、ユーザーが短文を投稿し、それを時系列で流れるタイムライン機能を追加したところ人気が高まり、徐々にそれがメインとして開発が進むようになりました。 当初は分散型ではありませんでしたが、2018年にActivityPubを実装し分散型になったことで、より多くの方に認知され利用されるサービスになり、現在に至ります。 -
ℹ️ Misskeyという名前は、syuiloが当時聴いていたMay'nというアーティストの楽曲、Brain Diverの歌詞に由来します。
- -誰でも開発に参加することができ、現在でも活発に開発が続いています。 - -## 分散型とは何か? - -分散(distributed)型とは、非中央集権(decentralized)とも呼ばれ、コミュニティが多数のサーバーに分散して存在し、それらが相互に通信(連合、federation)することでコンテンツ共有ネットワーク(Fediverse)を形成していることが特徴のサービスです。 単一のサーバーしか存在しない、もしくは複数存在しても互いに独立している場合は中央集権なサービスと言われ、例えばTwitterやFacebookなどほとんどのサービスがそれに該当します。 分散型のメリットは、自分に合った運営者やテーマのサーバーを選択できることです。自分でサーバーを作成することもできます。連合するおかげで、どのサーバーを選んでも、同じコミュニティにアクセスできます。 - -## 常にオープンソース -Misskeyはこれまでもこれからも、オープンソースであり続けます。オープンソースとは、簡単に言うとソフトウェアのソースコード(プログラム)が公開されていることです。ソースコードの修正や再配布が可能であることを定義に含めることもあります。 Misskeyのすべてのソースコードは[AGPL](https://github.com/misskey-dev/misskey/blob/develop/LICENSE)というオープンソースライセンスの下に[公開](https://github.com/misskey-dev)されていて、誰でも自由に閲覧、使用、修正、改変、再配布をすることができます。 オープンソースは、自分で好きなように変えたり、有害な処理が含まれていないことを確認することができたり、誰でも開発に参加できるなどの、様々なメリットがあります。 上述の分散型を実現するためにも、オープンソースであるということは必要不可欠な要素です。 再び引き合いに出しますが、TwitterやFacebookなどの利益を得ているほとんどのサービスはオープンソースではありません。 - -
ℹ️ 技術的に言うと、MisskeyのソースコードはGitで管理されていて、リポジトリはGitHub上でホスティングされています。
- -## 開発に参加する、プロジェクトを支援する -Misskeyを気に入っていただけたら、ぜひプロジェクトを支援してください。プロジェクトに貢献するには、以下で紹介するようにいろいろな方法があります。方法によっては開発のスキルは不要なので、誰でも気軽に参加し貢献することができます。いつでもお待ちしています。 - -### 機能を追加したり、バグを修正する -ソフトウェアエンジニアのスキルをお持ちの方であれば、ソースコードを編集する形でプロジェクトに貢献することができます。 貢献についてのガイドは[こちら](https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md)です。 - -### 議論に参加する -新しい機能、または既存の機能について意見を述べたり、不具合を報告したりすることでも貢献できます。 そのようなディスカッションは[GitHub](https://github.com/misskey-dev)上か、[フォーラム](https://forum.misskey.io/)等で行われます。 - -### テキストを翻訳する -Misskeyは様々な言語に対応しています(i18n -internationalizationの略- と呼ばれます)。元の言語は基本的に日本語ですが、有志によって他の言語へと翻訳されています。 その翻訳作業に加わっていただくことでもMisskeyに貢献できます。 Misskeyは[Crowdinというサービスを使用して翻訳の管理を行っています。](https://crowdin.com/project/misskey) - -### 感想を投稿する -不具合報告等だけではなく、Misskeyの良い点、楽しい点といったポジティブな意見もぜひ共有してください。開発の励みになり、それは間接的ですがプロジェクトへの貢献です。 - -### ミスキストを増やす -ミスキストとは、Misskeyを使用する人のことです。 知り合いに紹介するなどしてMisskeyを広めていただければ、ミスキストが増え開発のモチベーションが上がります。 - -### 寄付をする -Misskeyはビジネスではなく、利用は無料であるため、収益は皆様からの寄付のみです。(インスタンスによっては広告収入を得ているような場合もありますが、それは運営者の収入であり直接開発者への収入にはなりません) 寄付をしていただければ、今後も開発を続けることが可能になり、プロジェクトへの貢献になります。 寄付は基本的には[Patreon](https://www.patreon.com/syuilo)で受け付けています。 一定額寄付していただけると、Misskeyの[情報ページ](/about-misskey)に名前を記載することができます。 - -また、サーバーの運営者も、基本的には収益を得ていません。サーバーの運営にはコストがかかるので、運営者の支援をすることもご検討ください。 開発には直接関係しませんが、サーバーがあってこそのプロジェクトなので、運営が維持されるというのは開発と同じくらい重要なことです。 - -## クレジット -Misskeyの開発者や、Misskeyに寄付をしてくださった方の一覧は[こちら](/about-misskey)で見ることができます。 - -## よくある質問 -### プロジェクトは何を目指していますか? -強いて言うと、漠然的になりますが広く使われる汎用的なプラットフォームになることを目指しています。 Misskeyは他のプロジェクトとは違い、何らかの思想(例えば、反中央集権)やビジョンに基づいて開発が行われているわけではなく、その点ではフラットです。 それが逆に、特定の方向性に縛られないフレキシブルさを生み出すことに繋がっていると感じています。 - - -### 企業によって開発されていますか? -いいえ。Misskeyの開発は個人で行われており、商業的でもないため、特定の企業の関りはありません。 開発メンバーも基本的にはボランティアです。 また、開発に対し企業のスポンサーがつくこともありますが、その場合でもやはり開発は個人のコミュニティが主体です。 - -### 誰が運営していますか? -Misskeyは分散型なため、各サーバーにそれぞれ異なった運営者がいます。従って、特定の個人や企業によって、Misskeyの全てが運営されているわけではありません。 また、開発チームが運営を行うわけでもないため、運営に関する連絡は、お使いのサーバーの運営者に行ってください。 サーバーの運営者は、[このページ](/about)で確認することができます。 あなたがサーバーを作成すれば、あなたが運営者になります。 - -### どのサーバーを選べばいいですか? -[サーバー一覧が公開されています。](https://join.misskey.page/ja-JP/instances) サーバーによってコミュニティのテーマ(特定のこと、ものが好き 等)が決められている場合があるので、自分に合ったテーマのサーバーがあれば、そこを選ぶと良いかもしれません。 他にも、サーバーの規模、ユーザー層、国および言語、運営者が信頼できるかどうか、などの観点があります。 なお、Misskey公式のサーバーというものはありません。自身で新しくサーバーを作成するという選択肢もあります。 - -基本的にどのサーバーを選んだとしても、他の全てのサーバーのユーザーと繋がることができます。 - -### サーバーを建てるにはどうしたらいいですか? -Misskeyサーバーの作成に興味を持っていただきありがとうございます。 2021年現在、Misskeyのホスティングサービスは存在しないため、サーバーの作成にはある程度の知識が必要です。 サーバーの作成方法については[こちら](todo)をご覧ください。 - -### どのような技術を使用していますか? -Misskeyは開発が進むにつれ使用する技術も大きく変わってきました。開発当初はMySQL + PHP + jQueryといった構成でしたが、現在は以下のようになっています。 -- サーバーサイド: Node.js -- データベース: PostgreSQL、Redis -- UIフレームワーク: Vue.js -- プログラミング言語: TypeScript - -また、MFMやAiScriptなどの、Misskeyから派生して独自の技術も開発しています。 - -### Mastodonのフォークですか? -いいえ。MisskeyはMastodonやその他のプロジェクトとは全く別のプロジェクトです。 開発に関しても、Misskeyの方が昔から開発されています。ただし、分散型になったのはMastodonの登場より後です。 同じActivityPubという分散のためのプロトコルを実装しているという点以外、両者に特に関りがあるわけでもありません。 - -### iOS/Androidのアプリはありますか? -公式にはそういったOSのネイティブアプリを開発していませんが、サードパーティ製のアプリがいくつかあります。 詳しくは[こちら](./apps)をご覧ください。 - -ただ、サードパーティ製アプリはどうしても機能への対応が遅れてしまうため、とくに拘りがなければ公式のWebクライアントの利用をおすすめします。 なお、MisskeyのWebクライアントはPWAに対応しているので、ネイティブアプリのように動作させることも可能です。 詳しくは[こちら](todo)をご覧ください。 - -### Misskeyのロゴ、アイコンはどこで入手できますか? -(準備中) - -### 時折目にする猫耳の可愛い女の子は? -Misskeyの守り神、藍ちゃんです。アイチャンカワイイヤッター! -
ℹ️ 藍ちゃんについてはこちらです。
diff --git a/src/docs/da-DK/general/report-issue.md b/src/docs/da-DK/general/report-issue.md deleted file mode 100644 index 63527e32a..000000000 --- a/src/docs/da-DK/general/report-issue.md +++ /dev/null @@ -1,8 +0,0 @@ -# 不具合の報告 -不具合と思われる状況に遭遇したときは、まず[トラブルシューティング](./troubleshooting)をご一読ください。 それでも問題が解決しないときは、以下の情報を含めて[フォーラム](https://forum.misskey.io/)に投稿してください。 投稿することで、解決策が見つかったり、不具合と判断されれば開発チームによって修正が行われます。 - -## 含める情報 -- Misskeyのバージョン([情報ページ](/about)で確認できます) -- お使いのブラウザの種類とバージョン -- お使いのOSの種類とバージョン -- 問題の再現手順 diff --git a/src/docs/da-DK/general/troubleshooting.md b/src/docs/da-DK/general/troubleshooting.md deleted file mode 100644 index f895b4984..000000000 --- a/src/docs/da-DK/general/troubleshooting.md +++ /dev/null @@ -1,40 +0,0 @@ -# トラブルシューティング -
ℹ️ よくある質問も合わせてお役立てください。
- -問題が発生したときは、まずこちらをご確認ください。 該当する項目が無い、もしくは手順を試しても効果がない場合は、サーバーの管理者に連絡するか[不具合を報告](./report-issue)してください。 - -## クライアントが起動しない -ほとんどの場合、お使いのブラウザまたはOSのバージョンが古いことが原因です。 ブラウザおよびOSのバージョンを最新のものに更新してから、再度試してみてください。 - -これは稀ですが、それでも起動しない場合は、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。 - -## ページが読み込めない -クライアントが起動するもののページが読み込めないというエラーが出る場合は、ネットワークに問題がないか確認してください。また、サーバーがダウンしていないか確認してください。 - -これは稀ですが、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。 - -まだ問題がある場合は、サーバーの問題と思われるのでサーバーの管理者に連絡してください。 - -## クライアントの動作が遅い -以下を試してみてください: - -- クライアント設定で「UIのアニメーションを減らす」を有効にする -- クライアント設定で「モーダルにぼかし効果を使用」を無効にする -- お使いのブラウザの設定でハードウェアアクセラレーションを有効にする -- お使いのデバイスのスペックを上げる - -## UIの一部の表示がおかしい(背景が透明になっている等) -アップデートによりUIの改修が行われたときに、テーマのキャッシュシステムの影響でそのような表示になることがあります。 クライアントの設定の「キャッシュをクリア」すると直ります。 -
⚠️ 「クライアントの」キャッシュクリアです。「ブラウザの」キャッシュクリアは行わないでください。
- -## 通知やアンテナ等の点滅が消えない -点滅は、未読のコンテンツがあることを示しています。通常点滅が消えない場合は、コンテンツを遡ると未読なコンテンツが残っています。 すべて既読にしたと思われるのに、それでもなお点滅が続く場合(おそらく不具合と思われます)は設定から強制的にすべて既読扱いにすることができます。 - -## Renoteができない -フォロワー限定のノートはRenoteすることはできません。 - -## UI上で特定の要素が表示されない -広告ブロッカーを使用しているとそのような不具合が発生することがあります。Misskeyではオフにしてご利用ください。 - -## UI上で未翻訳の部分がある -ほとんどの場合、単に翻訳が間に合っていないだけで、不具合ではありません。翻訳が終わるまでお待ちください。 [翻訳に参加](./misskey)していただくことも可能です。 diff --git a/src/docs/da-DK/keyboard-shortcut.md b/src/docs/da-DK/keyboard-shortcut.md deleted file mode 100644 index 957ca838c..000000000 --- a/src/docs/da-DK/keyboard-shortcut.md +++ /dev/null @@ -1,68 +0,0 @@ -# キーボードショートカット - -## グローバル -これらのショートカットは基本的にどこでも使えます。 - - - - - - - - - - - -
ショートカット効果由来
P, N新規投稿Post, New, Note
Tタイムラインの最も新しい投稿にフォーカスTimeline, Top
Shift + N通知を表示/隠すNotifications
S検索Search
H, ?ヘルプを表示Help
- -## 投稿にフォーカスされた状態 - - - - - - - - - - - - - - - - - - - -
ショートカット効果由来
, K, Shift + Tab上の投稿にフォーカスを移動-
, J, Tab下の投稿にフォーカスを移動-
R返信フォームを開くReply
QRenoteフォームを開くQuote
Ctrl + Q即刻Renoteする(フォームを開かずに)-
E, A, +リアクションフォームを開くEmote, reAction
0~9数字に対応したリアクションをする(対応については後述)-
F, Bお気に入りに登録Favorite, Bookmark
Del, Ctrl + D投稿を削除Delete
M, O投稿に対するメニューを開くMore, Other
SCWで隠された部分を表示 or 隠すShow, See
Escフォーカスを外す-
- -## Renoteフォーム - - - - - - - - - - -
ショートカット効果由来
EnterRenoteする-
Qフォームを展開するQuote
Escフォームを閉じる-
- -## リアクションフォーム -デフォルトで「👍」にフォーカスが当たっている状態です。 - - - - - - - - - - - - - -
ショートカット効果由来
, K上のリアクションにフォーカスを移動-
, J下のリアクションにフォーカスを移動-
, H, Shift + Tab左のリアクションにフォーカスを移動-
, L, Tab右のリアクションにフォーカスを移動-
Enter, Space, +リアクション確定-
0~9数字に対応したリアクションで確定-
Escリアクションするのをやめる-
diff --git a/src/docs/da-DK/mfm.md b/src/docs/da-DK/mfm.md deleted file mode 100644 index e237287ac..000000000 --- a/src/docs/da-DK/mfm.md +++ /dev/null @@ -1,2 +0,0 @@ -# MFM -MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます。 diff --git a/src/docs/da-DK/mute.md b/src/docs/da-DK/mute.md deleted file mode 100644 index 6a9608662..000000000 --- a/src/docs/da-DK/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# ミュート - -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -* タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -* そのユーザーからの通知 -* メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 - -ユーザーをミュートするには、対象のユーザーのユーザーページに表示されている「ミュート」ボタンを押します。 - -ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。 - -設定>ミュート から、自分がミュートしているユーザー一覧を確認することができます。 diff --git a/src/docs/da-DK/pages.md b/src/docs/da-DK/pages.md deleted file mode 100644 index a7311b95e..000000000 --- a/src/docs/da-DK/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# Pages - -## 変数 -変数を使うことで動的なページを作成できます。テキスト内で { 変数名 } と書くとそこに変数の値を埋め込めます。例えば Hello { thing } world! というテキストで、変数(thing)の値が ai だった場合、テキストは Hello ai world! になります。 - -変数の評価(値を算出すること)は上から下に行われるので、ある変数の中で自分より下の変数を参照することはできません。例えば上から A、B、C と3つの変数を定義したとき、Cの中でABを参照することはできますが、Aの中でBCを参照することはできません。 - -ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。 - -関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。 diff --git a/src/docs/da-DK/reaction.md b/src/docs/da-DK/reaction.md deleted file mode 100644 index c26ead75b..000000000 --- a/src/docs/da-DK/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# リアクション -他の人のノートに、絵文字を付けて簡単にあなたの反応を伝えられる機能です。 リアクションするには、ノートの + アイコンをクリックしてピッカーを表示し、絵文字を選択します。 リアクションには[カスタム絵文字](./custom-emoji)も使用できます。 - -## リアクションピッカーのカスタマイズ -ピッカーに表示される絵文字を自分好みにカスタマイズすることができます。 設定の「リアクション」で設定します。 - -## リモート投稿へのリアクションについて -リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。 また、相手がMisskeyであったとしても、カスタム絵文字リアクションは伝わらず、自動的に「👍」等にフォールバックされます。 - -## リモートからのリアクションについて -リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。 diff --git a/src/docs/da-DK/reversi-bot.md b/src/docs/da-DK/reversi-bot.md deleted file mode 100644 index 7ab2a7212..000000000 --- a/src/docs/da-DK/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# MisskeyリバーシBotの開発 -Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。 - -1. `games/reversi`ストリームに以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - -2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる - * イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている - -3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する - -4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - * `game`: `game`の`id` - -5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う - -6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する - -7. ゲームが開始すると、`started`イベントが流れてくる - * イベントの中身にはゲーム情報が含まれている - -8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述) - -9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる - * `color`として石の色が含まれている - * `pos`として位置情報が含まれている - -## 位置の計算法 -8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### X,Y座標 から インデックス に変換する -``` -pos = x + (y * mapWidth) -``` -`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます: -``` -mapWidth = map[0].length -``` - -### インデックス から X,Y座標 に変換する -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## マップ情報 -マップ情報は、ゲーム情報の`map`に入っています。 文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 それをもとにマップのデザインを知る事が出来ます: -* `(スペース)` ... マス無し -* `-` ... マス -* `b` ... 初期配置される黒石 -* `w` ... 初期配置される白石 - -例えば、4*4の次のような単純なマップがあるとします: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -この場合、マップデータはこのようになります: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## ユーザーにフォームを提示して対話可能Botを作成する -ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。 - -フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します: -```javascript -{ - type: 'init-form', - body: [フォームコントロールの配列] -} -``` - -フォームコントロールの配列については今から説明します。 フォームコントロールは、次のようなオブジェクトです: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... コントロールのID。 `type` ... コントロールの種類。後述します。 `label` ... コントロールと一緒に表記するテキスト。 `value` ... コントロールのデフォルト値。 - -### フォームの操作を受け取る -ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### フォームコントロールの種類 -#### スイッチ -type: `switch` スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。 - -##### プロパティ -`label` ... スイッチに表記するテキスト。 - -#### ラジオボタン -type: `radio` ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。 - -##### プロパティ -`items` ... ラジオボタンの選択肢。例: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '強', - value: 3 -}] -``` - -#### スライダー -type: `slider` スライダーを表示します。 - -##### プロパティ -`min` ... スライダーの下限。 `max` ... スライダーの上限。 `step` ... 入力欄で刻むステップ値。 - -#### テキストボックス -type: `textbox` テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。 - -## ユーザーにメッセージを表示する -設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 メッセージを表示するには、次のメッセージをストリームに送信します: -```javascript -{ - type: 'message', - body: { - text: 'メッセージ内容', - type: 'メッセージの種類' - } -} -``` -メッセージの種類: `success`, `info`, `warning`, `error`。 - -## 投了する -投了をするには、このエンドポイントにリクエストします。 diff --git a/src/docs/da-DK/stream.md b/src/docs/da-DK/stream.md deleted file mode 100644 index 9011c37c5..000000000 --- a/src/docs/da-DK/stream.md +++ /dev/null @@ -1,354 +0,0 @@ -# ストリーミングAPI - -ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。 - -## ストリームに接続する - -ストリーミングAPIを利用するには、まずMisskeyサーバーに**websocket**接続する必要があります。 - -以下のURLに、`i`というパラメータ名で認証情報を含めて、websocket接続してください。例: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。 - -
-

認証情報の取得については、こちらのドキュメントをご確認ください。

-
- ---- - -認証情報は省略することもできますが、その場合非ログインでの利用ということになり、受信できる情報や可能な操作は限られます。例: - -``` -%WS_URL%/streaming -``` - ---- - -ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。 - -**ストリームでのやり取りはすべてJSONです。** - -## チャンネル -MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。 - -### チャンネルに接続する -チャンネルに接続するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -ここで、 -* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。 -* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。 -* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。 - -
-

IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。

-
- -### チャンネルからのメッセージを受け取る -例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。 - -チャンネルがメッセージを発すると、次のようなデータがJSONでストリームに流れてきます: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。 -* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。 -* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。 - -### チャンネルに向けてメッセージを送信する -チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。 - -チャンネルにメッセージを送信するには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。 -* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。 -* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。 - -### チャンネルから切断する -チャンネルから切断するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。 - -## ストリームを経由してAPIリクエストする - -ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。 - -ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -ここで、 -* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 -* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 -* `data`には、エンドポイントのパラメータを含めます。 - -
-

APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。

-
- -### レスポンスの受信 - -APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。 - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -ここで、 -* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 -* `body`には、レスポンスが含まれています。 - -## 投稿のキャプチャ - -Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。 - -例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。 - -しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。 - -この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。 - -### 投稿をキャプチャする - -投稿をキャプチャするには、ストリームに次のようなメッセージを送信します: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャしたい投稿の`id`を設定します。 - -このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 - -例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -ここで、 -* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。 -* `body`内の`type`に、イベントの種類が設定されます。 -* `body`内の`body`に、イベントの詳細が設定されます。 - -#### イベントの種類 - -##### `reacted` -その投稿にリアクションがされた時に発生します。 - -* `reaction`に、リアクションの種類が設定されます。 -* `userId`に、リアクションを行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -その投稿が削除された時に発生します。 - -* `deletedAt`に、削除日時が設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -その投稿に添付されたアンケートに投票された時に発生します。 - -* `choice`に、選択肢IDが設定されます。 -* `userId`に、投票を行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### 投稿のキャプチャを解除する - -その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。 - -次のメッセージを送信します: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャを解除したい投稿の`id`を設定します。 - -このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 - -# チャンネル一覧 -## `main` -アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `renote` -自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。 - -#### `mention` -誰かからメンションされたときに発生するイベントです。 - -#### `readAllNotifications` -自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。 - -#### `meUpdated` -自分の情報が更新されたことを表すイベントです。 - -#### `follow` -自分が誰かをフォローしたときに発生するイベントです。 - -#### `unfollow` -自分が誰かのフォローを解除したときに発生するイベントです。 - -#### `followed` -自分が誰かにフォローされたときに発生するイベントです。 - -## `homeTimeline` -ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -タイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `localTimeline` -ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `hybridTimeline` -ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ソーシャルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `globalTimeline` -グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 diff --git a/src/docs/da-DK/theme.md b/src/docs/da-DK/theme.md deleted file mode 100644 index a406f3433..000000000 --- a/src/docs/da-DK/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# テーマ - -テーマを設定して、Misskeyクライアントの見た目を変更できます。 - -## テーマの設定 -設定 > テーマ - -## テーマを作成する -テーマコードはJSON5で記述されたテーマオブジェクトです。 テーマは以下のようなオブジェクトです。 -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... テーマの一意なID。UUIDをおすすめします。 -* `name` ... テーマ名 -* `author` ... テーマの作者 -* `desc` ... テーマの説明(オプション) -* `base` ... 明るいテーマか、暗いテーマか - * `light`にすると明るいテーマになり、`dark`にすると暗いテーマになります。 - * テーマはここで設定されたベーステーマを継承します。 -* `props` ... テーマのスタイル定義。これから説明します。 - -### テーマのスタイル定義 -`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 - -#### バリューで使える構文 -* 16進数で表された色 - * 例: `#00ff00` -* `rgb(r, g, b)`形式で表された色 - * 例: `rgb(0, 255, 0)` -* `rgb(r, g, b, a)`形式で表された透明度を含む色 - * 例: `rgba(0, 255, 0, 0.5)` -* 他のキーの値の参照 - * `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。 - * 例: `@panel` -* 定数(後述)の参照 - * `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。 - * 例: `$main` -* 関数(後述) - * `:{関数名}<{引数}<{色}` - -#### 定数 -「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 キー名を`$`で始めると、そのキーはCSS変数として出力されません。 - -#### 関数 -wip diff --git a/src/docs/da-DK/timelines.md b/src/docs/da-DK/timelines.md deleted file mode 100644 index 36ba61bd2..000000000 --- a/src/docs/da-DK/timelines.md +++ /dev/null @@ -1,15 +0,0 @@ -# タイムラインの比較 - -https://docs.google.com/spreadsheets/d/1lxQ2ugKrhz58Bg96HTDK_2F98BUritkMyIiBkOByjHA/edit?usp=sharing - -## ホーム -自分のフォローしているユーザーの投稿 - -## ローカル -全てのローカルユーザーの「ホーム」指定されていない投稿 - -## ソーシャル -自分のフォローしているユーザーの投稿と、全てのローカルユーザーの「ホーム」指定されていない投稿 - -## グローバル -全てのローカルユーザーの「ホーム」指定されていない投稿と、サーバーに届いた全てのリモートユーザーの「ホーム」指定されていない投稿 diff --git a/src/docs/de-DE/admin/disable-timelines.md b/src/docs/de-DE/admin/disable-timelines.md deleted file mode 100644 index e11457314..000000000 --- a/src/docs/de-DE/admin/disable-timelines.md +++ /dev/null @@ -1,8 +0,0 @@ -# Lokale/soziale/globale Chronik deaktivieren -Misskey erlaubt es, die lokale, soziale und globale Chronik jeweils zu deaktivieren. Die Chroniken können in den Instanzeinstellungen aktiviert bzw. deaktiviert werden. - -Dass alle Notizen auf deiner Instanz auf der lokalen und sozialen Chronik erscheinen, erleichtert es neuen Nutzern, andere zu finden, ohne dafür die Suche benutzen zu müssen. Es bedeutet jedoch auch, dass es nicht unbedingt nötig ist, Nutzern zu folgen, um ihre Posts zu sehen, und dass häufiger unangebrachte Inhalte zu sehen sein könnten. Die Nutzung gleicht zudem eher der eines Chatrooms, was es neuen Nutzern wiederum erschweren könnte, in Gespräche unter Langzeitnutzern einzusteigen. Diese Vor- und Nachteile wiegen je nach Instanz unterschiedlich schwer, weshalb die Wahl letztendlich den Betreibern überlassen ist. Falls die Nachteile also in deinem Fall überwiegen, kannst du die jeweiligen Chroniken auch deaktivieren. - -
⚠️ Das Deaktiveren von Chroniken kann Nutzer verwirren und kurzzeitig abschrecken. Daher solltest du diese Entscheidung gut begründen können und die Nutzer deiner Instanz im Vorfeld darüber aufklären, damit diese sich entsprechend vorbereiten können, beispielsweise indem sie Nutzern folgen, mit denen sie sich häufiger unterhalten.
- -Beachte, dass Aministratoren und Moderatoren diese Chroniken weiterhin sehen können, auch nachdem sie deaktiviert wurden. diff --git a/src/docs/de-DE/admin/faq.md b/src/docs/de-DE/admin/faq.md deleted file mode 100644 index 44083fcd6..000000000 --- a/src/docs/de-DE/admin/faq.md +++ /dev/null @@ -1,5 +0,0 @@ -# Häufig gestellte Fragen -Dieses Dokument richtet sich an Administratoren und beantwortet besonders häufig gestellte Fragen. - -## Wie kann ich ein standardmäßiges Farbschema für meine Instanz festlegen? -Derzeit ist es noch nicht möglich, ein standardmäßiges Farbschema für eine Instanz festzulegen. diff --git a/src/docs/de-DE/advanced/aiscript.md b/src/docs/de-DE/advanced/aiscript.md deleted file mode 100644 index 604d17daa..000000000 --- a/src/docs/de-DE/advanced/aiscript.md +++ /dev/null @@ -1,7 +0,0 @@ -# AiScript -AiScriptは、Misskeyで使用できるスクリプト言語です。 - -
ℹ️ AiScript実装はMisskeyとは別リポジトリで、オープンソースで公開されています。
- -## 使い方 -AiScriptの構文や組み込み関数などのドキュメントは、[こちら](https://github.com/syuilo/aiscript/tree/master/docs)で公開されています。 diff --git a/src/docs/de-DE/advanced/api.md b/src/docs/de-DE/advanced/api.md deleted file mode 100644 index 76019b614..000000000 --- a/src/docs/de-DE/advanced/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス、Bot等(以下「アプリケーション」と呼びます)を開発できます。 ストリーミングAPIもあるので、リアルタイム性のあるアプリケーションを作ることも可能です。 - -APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。 - -## アクセストークンの取得 -基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。 - -* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む -* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む - -### 自分自身のアクセストークンを手動発行する -「設定 > API」で、自分のアクセストークンを発行できます。 - -[「APIの使い方」へ進む](#APIの使い方) - -### アプリケーション利用者にアクセストークンの発行をリクエストする -アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。 - -#### Step 1 - -UUIDを生成する。以後これをセッションIDと呼びます。 - -> このセッションIDは毎回生成し、使いまわさないようにしてください。 - -#### Step 2 - -`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。 -> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます: -* `name` ... アプリケーション名 - * > 例: `MissDeck` -* `icon` ... アプリケーションのアイコン画像URL - * > 例: `https://missdeck.example.com/icon.png` -* `callback` ... 認証が終わった後にリダイレクトするURL - * > 例: `https://missdeck.example.com/callback` - * リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます -* `permission` ... アプリケーションが要求する権限 - * > 例: `write:notes,write:following,read:drive` - * 要求する権限を`,`で区切って列挙します - * どのような権限があるかは[APIリファレンス](/api-doc)で確認できます - -#### Step 3 -ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。 - -レスポンスに含まれるプロパティ: -* `token` ... ユーザーのアクセストークン -* `user` ... ユーザーの情報 - -[「APIの使い方」へ進む](#APIの使い方) - -## APIの使い方 -**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。 - -* [APIリファレンス](/api-doc) -* [ストリーミングAPI](./stream) diff --git a/src/docs/de-DE/advanced/create-plugin.md b/src/docs/de-DE/advanced/create-plugin.md deleted file mode 100644 index ee9678685..000000000 --- a/src/docs/de-DE/advanced/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# プラグインの作成 -Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。 - -## Metadaten -プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。 - -### name -プラグイン名 - -### author -プラグイン作者 - -### version -プラグインバージョン。数値を指定してください。 - -### description -プラグインの説明 - -### permissions -プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。 - -### config -プラグインの設定情報を表すオブジェクト。 キーに設定名、値に以下のプロパティを含めます。 - -#### type -設定値の種類を表す文字列。以下から選択します。 string number boolean - -#### label -ユーザーに表示する設定名 - -#### description -設定の説明 - -#### default -設定のデフォルト値 - -## APIリファレンス -AiScript標準で組み込まれているAPIは掲載しません。 - -### Mk:dialog(title text type) -ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。 - -### Mk:confirm(title text type) -確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。 - -### Mk:api(endpoint params) -Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。 - -### Mk:save(key value) -任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。 - -### Mk:load(key) -Mk:saveで永続化した指定の名前の値を読み取ります。 - -### Plugin:register_post_form_action(title fn) -投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。 - -### Plugin:register_note_action(title fn) -ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 - -### Plugin:register_user_action(title fn) -ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。 - -### Plugin:register_note_view_interruptor(fn) -UIに表示されるノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:register_note_post_interruptor(fn) -ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:open_url(url) -第一引数に渡されたURLをブラウザの新しいタブで開きます。 - -### Plugin:config -プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。 diff --git a/src/docs/de-DE/advanced/develop-bot.md b/src/docs/de-DE/advanced/develop-bot.md deleted file mode 100644 index 7f825e9bc..000000000 --- a/src/docs/de-DE/advanced/develop-bot.md +++ /dev/null @@ -1,6 +0,0 @@ -# Botの作成 -[Misskey API](./api)を利用してBotの開発が可能です。 また、いくつかのBot実装が公開されているため、ぜひ参考にしてください。 - -- [syuilo/ai](https://github.com/syuilo/ai) ... Node.js上で動く、TypeScript製Bot実装 - -Botを作成したときは、プロフィール設定からBotフラグをオンにしておくことを強くおすすめします。 diff --git a/src/docs/de-DE/advanced/reversi-bot.md b/src/docs/de-DE/advanced/reversi-bot.md deleted file mode 100644 index 3ffb1ee24..000000000 --- a/src/docs/de-DE/advanced/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# MisskeyリバーシBotの開発 -Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。 - -1. `games/reversi`ストリームに以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - -2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる - * イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている - -3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する - -4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - * `game`: `game`の`id` - -5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う - -6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する - -7. ゲームが開始すると、`started`イベントが流れてくる - * イベントの中身にはゲーム情報が含まれている - -8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述) - -9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる - * `color`として石の色が含まれている - * `pos`として位置情報が含まれている - -## 位置の計算法 -8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### X,Y座標 から インデックス に変換する -``` -pos = x + (y * mapWidth) -``` -`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます: -``` -mapWidth = map[0].length -``` - -### インデックス から X,Y座標 に変換する -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## マップ情報 -マップ情報は、ゲーム情報の`map`に入っています。 文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 それをもとにマップのデザインを知る事が出来ます: -* `(スペース)` ... マス無し -* `-` ... マス -* `b` ... 初期配置される黒石 -* `w` ... 初期配置される白石 - -例えば、4*4の次のような単純なマップがあるとします: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -この場合、マップデータはこのようになります: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## ユーザーにフォームを提示して対話可能Botを作成する -ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。 - -フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します: -```javascript -{ - type: 'init-form', - body: [フォームコントロールの配列] -} -``` - -フォームコントロールの配列については今から説明します。 フォームコントロールは、次のようなオブジェクトです: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... コントロールのID。 `type` ... コントロールの種類。後述します。 `label` ... コントロールと一緒に表記するテキスト。 `value` ... コントロールのデフォルト値。 - -### フォームの操作を受け取る -ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### フォームコントロールの種類 -#### Fallunterscheidung -type: `switch` スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。 - -##### プロパティ -`label` ... スイッチに表記するテキスト。 - -#### ラジオボタン -type: `radio` ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。 - -##### プロパティ -`items` ... ラジオボタンの選択肢。例: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '強', - value: 3 -}] -``` - -#### スライダー -type: `slider` スライダーを表示します。 - -##### プロパティ -`min` ... スライダーの下限。 `max` ... スライダーの上限。 `step` ... 入力欄で刻むステップ値。 - -#### テキストボックス -type: `textbox` テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。 - -## ユーザーにメッセージを表示する -設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 メッセージを表示するには、次のメッセージをストリームに送信します: -```javascript -{ - type: 'message', - body: { - text: 'メッセージ内容', - type: 'メッセージの種類' - } -} -``` -メッセージの種類: `success`, `info`, `warning`, `error`。 - -## 投了する -投了をするには、このエンドポイントにリクエストします。 diff --git a/src/docs/de-DE/advanced/share-page.md b/src/docs/de-DE/advanced/share-page.md deleted file mode 100644 index e818e4646..000000000 --- a/src/docs/de-DE/advanced/share-page.md +++ /dev/null @@ -1,54 +0,0 @@ -# シェアページ -`/share`を開くと、共有用の投稿フォームを開くことができます。 ここではシェアページで利用できるクエリ文字列の一覧を示します。 - -## クエリ文字列一覧 -### Text - -
-
title
-
タイトルです。本文の先頭に[ … ]と挿入されます。
-
text
-
本文です。
-
url
-
URLです。末尾に挿入されます。
-
- -### リプライ情報 -以下のいずれか - -
-
replyId
-
リプライ先のノートid
-
replyUri
-
リプライ先のUrl(リモートのノートオブジェクトを指定)
-
- -### Renote情報 -以下のいずれか - -
-
renoteId
-
Renote先のノートid
-
renoteUri
-
Renote先のUrl(リモートのノートオブジェクトを指定)
-
- -### Sichtbarkeit -※specifiedに相当する値はvisibility=specifiedとvisibleAccts/visibleUserIdsで指定する - -
-
visibility
-
公開範囲 ['public' | 'home' | 'followers' | 'specified']
-
localOnly
-
0(false) or 1(true)
-
visibleUserIds
-
specified時のダイレクト先のユーザーid カンマ区切りで
-
visibleAccts
-
specified時のダイレクト先のacct(@?username[@host]) カンマ区切りで
-
- -### Dateien -
-
fileIds
-
添付したいファイルのid(カンマ区切りで)
-
diff --git a/src/docs/de-DE/advanced/stream.md b/src/docs/de-DE/advanced/stream.md deleted file mode 100644 index 42ec8df08..000000000 --- a/src/docs/de-DE/advanced/stream.md +++ /dev/null @@ -1,350 +0,0 @@ -# ストリーミングAPI - -ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。 - -## ストリームに接続する - -ストリーミングAPIを利用するには、まずMisskeyサーバーに**websocket**接続する必要があります。 - -以下のURLに、`i`というパラメータ名で認証情報を含めて、websocket接続してください。例: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。 - -
ℹ️ 認証情報の取得については、こちらのドキュメントをご確認ください。
- ---- - -認証情報は省略することもできますが、その場合非ログインでの利用ということになり、受信できる情報や可能な操作は限られます。例: - -``` -%WS_URL%/streaming -``` - ---- - -ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。 - -**ストリームでのやり取りはすべてJSONです。** - -## Kanäle -MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。 - -ひとつのストリーム上で、同時に複数のチャンネルに接続することができます。 - -### チャンネルに接続する -チャンネルに接続するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -ここで、 -* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。 -* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。 -* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。 - -
ℹ️ IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。
- -### チャンネルからのメッセージを受け取る -例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。 - -チャンネルがメッセージを発すると、次のようなデータがJSONでストリームに流れてきます: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。 -* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。 -* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。 - -### チャンネルに向けてメッセージを送信する -チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。 - -チャンネルにメッセージを送信するには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。 -* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。 -* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。 - -### チャンネルから切断する -チャンネルから切断するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。 - -## ストリームを経由してAPIリクエストする - -ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。 - -ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -ここで、 -* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 -* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 -* `data`には、エンドポイントのパラメータを含めます。 - -
ℹ️ APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。
- -### レスポンスの受信 - -APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。 - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -ここで、 -* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 -* `body`には、レスポンスが含まれています。 - -## 投稿のキャプチャ - -Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。 - -例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。 - -しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。 - -この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。 - -### 投稿をキャプチャする - -投稿をキャプチャするには、ストリームに次のようなメッセージを送信します: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャしたい投稿の`id`を設定します。 - -このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 - -例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -ここで、 -* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。 -* `body`内の`type`に、イベントの種類が設定されます。 -* `body`内の`body`に、イベントの詳細が設定されます。 - -#### イベントの種類 - -##### `reacted` -その投稿にリアクションがされた時に発生します。 - -* `reaction`に、リアクションの種類が設定されます。 -* `userId`に、リアクションを行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -その投稿が削除された時に発生します。 - -* `deletedAt`に、削除日時が設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -その投稿に添付されたアンケートに投票された時に発生します。 - -* `choice`に、選択肢IDが設定されます。 -* `userId`に、投票を行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### 投稿のキャプチャを解除する - -その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。 - -次のメッセージを送信します: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャを解除したい投稿の`id`を設定します。 - -このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 - -# チャンネル一覧 -## `main` -アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `renote` -自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。 - -#### `mention` -誰かからメンションされたときに発生するイベントです。 - -#### `readAllNotifications` -自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。 - -#### `meUpdated` -自分の情報が更新されたことを表すイベントです。 - -#### `follow` -自分が誰かをフォローしたときに発生するイベントです。 - -#### `unfollow` -自分が誰かのフォローを解除したときに発生するイベントです。 - -#### `followed` -自分が誰かにフォローされたときに発生するイベントです。 - -## `homeTimeline` -ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -タイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `localTimeline` -ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `hybridTimeline` -ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ソーシャルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `globalTimeline` -グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 diff --git a/src/docs/de-DE/aiscript.md b/src/docs/de-DE/aiscript.md deleted file mode 100644 index 493418ebe..000000000 --- a/src/docs/de-DE/aiscript.md +++ /dev/null @@ -1,4 +0,0 @@ -# AiScript - -## Funktionen -Verwenden für Parameter standardmäßig Pass-by-Value (Wertparameter). diff --git a/src/docs/de-DE/api.md b/src/docs/de-DE/api.md deleted file mode 100644 index c13bbd5b1..000000000 --- a/src/docs/de-DE/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -Durch die Verwendung des Misskey APIs können Misskey Clients, mit Misskey kompatible Web-Services, Bots (ab sofort "Anwendungen" genannt) und mehr entwickelt werden. Ebenso existiert ein Streaming-API, um Echtzeit-Anwendungen zu erstellen. - -Um mit der Verwendung des APIs zu beginnen, wird zuerst ein Zugriffstoken benötigt. Wie ein solcher Token erhalten werden kann, und wie die API dann hiermit verwendet werden kann, wird auf dieser Seite erklärt. - -## Einen Zugriffstoken erhalten -Generell benötigen alle API-Anfragen einen Zugriffstoken. Die Methode, wie ein solcher Zugriffstoken erlangt werden kann, unterscheidet sich je nach dem, ob Anfragen vom eigenen Benutzerkonto aus gesendet werden oder ob die Anfragen von einem anderen Benutzer aus durch eine Anwendung gesendet werden. - -* Im ersten Fall: Fahre mit "Einen Zugriffstoken für das eigene Benutzerkonto generieren" fort. -* Im zweiten Fall: Fahre mit "Einen Benutzer zur Generierung eines Zugangstokens für eine Anwendung auffordern" fort. - -### Einen Zugriffstoken für das eigene Benutzerkonto generieren -In Einstellungen > API kann ein Zugriffstoken für das eigene Benutzerkonto generiert werden. - -[Fahre mit "Verwendung der API" fort.](#APIの使い方) - -### Einen Benutzer zur Generierung eines Zugangstokens für eine Anwendung auffordern -Um einen in einer Anwendung zu verwendenden Zugriffstoken für ein Benutzerkonto zu erhalten, fordere die Generierung eines solchen durch den unten beschrieben Prozess an. - -#### Schritt 1 - -Generiere eine UUID.Diese werden wir ab jetzt die Sitzungs-ID nennen. - -> Die selbe Sitzungs-ID sollte nie mehrfach wieder verwendet werden, generiere anstattdessen für jeden Zugriffstoken eine neue Sitzungs-ID. - -#### Schritt 2 - -Öffne `{_URL_}/miauth/{session}` im Browser des Benutzers.`{session}` soll hierbei durch die vorher generierte Sitzungs-ID ersetzt werden. -> z.B.: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -Bei Aufruf dieser URL können verschiedene Einstellungen via Query-Parameter gesetzt werden: -* `name` ... Anwendungsname - * > z.B.: `MissDeck` -* `icon` ... URL zum Anwendungs-Icon - * > z.B.: `https://missdeck.example.com/icon.png` -* `callback` ... URL, zu der nach Ende der Authentifizierung weitergeleitet wird - * > z.B.: `https://missdeck.example.com/callback` - * In dieser Weiterleitung wird die Sessions-ID als `session` Query-Parameter an die URL angefügt -* `permission` ... Von der Anwendung geforderte Berechtigungen - * > z.B.: `write:notes,write:following,read:drive` - * Angeforderte Berechtigungen sind durch `,` von einander getrennt - * Welche Berechtigungen existieren kann in der [API-Referenz](/api-doc) nachgelesen werden - -#### Schritt 3 -Sobald der Benutzer der Erstellung des Zugriffstokens zugestimmt hat, kann durch eine POST-Anfrage an `{_URL_}/api/miauth/{session}/check` der Zugriffstoken aus dem JSON-Objekt der Antwort ausgelesen werden. - -In der Antwort enthaltene Attribute: -* `token` ... Zugriffstoken des Nutzers -* `user` ... Benutzerdaten - -[Fahre mit "Verwendung der API" fort.](#APIの使い方) - -## Verwendung der API -**Alle API-Anfragen sind POST-Anfragen, und alle Anfragen bzw. Antworten sind JSON-Objekte.REST wird nicht unterstützt.** Der Zugriffstoken muss unter dem `i`-Parameter beinhaltet werden. - -* [API-Referenz](/api-doc) -* [Streaming-API](./stream) diff --git a/src/docs/de-DE/create-plugin.md b/src/docs/de-DE/create-plugin.md deleted file mode 100644 index 9a1e4bb14..000000000 --- a/src/docs/de-DE/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# Erstellen von Plugins -Durch die Verwendung der Plugin-Funktionalität des Misskey Web-Clients kann dieser mit verschiedenen Funktionen erweitert werden. Diese Seite beinhaltet Definitionen von Metadaten für die Erstellung von Plugins sowie eine AiScript API-Referenz für Plugins. - -## Metadaten -Plugins müssen benötigte Metadaten im AiScript Metadata-Format angeben. Bei diesen Metadaten handelt es sich um ein Objekt mit folgenden Attributen: - -### name -Name des Plugins - -### author -Name des Plugin-Erstellers - -### version -Version des Plugins.Muss eine Zahl sein. - -### description -Beschreibung des Plugins - -### permissions -Die vom Plugin geforderten Berechtigungen.Werden bei Anfragen der Misskey API verwendet. - -### config -Ein Objekt, dass die Einstellungen des Plugins enthält. Schlüssel representieren Namen von Einstellungen, und Werte sind einer der unten genannten Attribute. - -#### type -Der Typ eines Einstellungswertes.Muss aus einem dieser Typen gewählt sein: string number boolean - -#### label -Dem Benutzer angezeigter Einstellungsname - -#### description -Beschreibung der Einstellung - -#### default -Standardwert der Einstellung - -## API-Referenz -Direkt in den AiScript-Standard eingebaute API wird nicht aufgelistet. - -### Mk:dialog(title text type) -Zeigt ein Dialogfenster an.type muss aus einem der folgenden Werte gewählt werden. info success warn error question Falls kein Typ angegeben wird, wird dieser zu info gesetzt. - -### Mk:confirm(title text type) -Zeigt ein Bestätigungsfenster an.type muss aus einem der folgenden Werte gewählt werden. info success warn error question Falls kein Typ angegeben wird, wird dieser zu question gesetzt. Drückt der Benutzer "OK" wird true zurückgegeben, drückt er "Cancel" wird false zurückgegeben. - -### Mk:api(endpoint params) -Sendet eine Misskey API-Anfrage.Der erste Parameter gibt den API-Endpunkt an, der zweite die Anfrageparameter als Objekt. - -### Mk:save(key value) -Speichert einen beliebigen Wert dauerhaft unter einem beliebigen Namen.Der gespeicherte Wert bleibt auch nach Verlassen des AiScript-Kontexts erhalten und kann mit Mk:load ausgelesen werden. - -### Mk:load(key) -Läd den Wert des gegebenen Schlüssels, der zuvor mit Mk:save gespeichert wurde - -### Plugin:register_post_form_action(title fn) -Fügt dem Beitragsfenster eine Aktion hinzu.Der erste Parameter gibt den Aktionsnamen an, der zweite Parameter eine Callback-Funktion, die bei Auswahl dieser Aktion ausgeführt wird, an. Die Callback-Funktion erhält als ersten Parameter ein Beitragsfenster-Objekt. - -### Plugin:register_note_action(title fn) -Fügt dem Notiz-Menü ein Listenelement hinzu.Der erste Parameter gibt den Aktionsnamen an, der zweite Parameter eine Callback-Funktion, die bei Auswahl dieses Elements ausgeführt wird, an. Die Callback-Funktion erhält als ersten Parameter ein Notiz-Objekt. - -### Plugin:register_user_action(title fn) -Fügt dem Benutzer-Menü ein Listenelement hinzu.Der erste Parameter gibt den Aktionsnamen an, der zweite Parameter eine Callback-Funktion, die bei Auswahl dieses Elements ausgeführt wird, an. Die Callback-Funktion erhält als ersten Parameter ein Benutzer-Objekt. - -### Plugin:register_note_view_interruptor(fn) -Verändert die Daten einer im UI angezeigten Notiz. Die Callback-Funktion erhält als ersten Parameter ein Notiz-Objekt. Die angezeigte Notiz wird mit dem Rückgabewert der Callback-Funktion überschrieben. - -### Plugin:register_note_post_interruptor(fn) -Verändert die Daten einer zu erstellenden Notiz. Die Callback-Funktion erhält als ersten Parameter ein Notiz-Objekt. Die zu erstellende Notiz wird mit dem Rückgabewert der Callback-Funktion überschrieben. - -### Plugin:open_url(url) -Öffnet die als ersten Parameter gegebene URL in einem neuen Browser-Tab. - -### Plugin:config -Ein Objekt, dass die Plugin-Einstellungen enthält.Die in den Plugin-Einstellung eingetragenen Werte sind hier unter den Einstellungsnamen gespeichert. diff --git a/src/docs/de-DE/custom-emoji.md b/src/docs/de-DE/custom-emoji.md deleted file mode 100644 index d60610e9c..000000000 --- a/src/docs/de-DE/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# Benutzerdefinierte Emojis -Benutzerdefinierte Emojis sind instanzenspezifische Bilder, die dort wie Emojis verwendet werden können. Sie können in Notizen, Reaktionen, Chats, Profilbeschreibungen, Benutzernamen und an anderen Orten verwendet werden. Um ein benutzerdefiniertes Emoji an einem solchen Ort zu verwenden, drücke den Knopf, um die Emoji-Auswahl zu öffnen (falls vorhanden), oder gib ein `:` ein, um Emoji-Vorschläge anzeigen zu lassen. Wird eine Zeichenkette des Formats `:foo:` innerhalb eines Textes gefunden, so wird `foo` als Name eines benutzerdefinierten Emojis interpretiert und mit dem dazugehörigen Bild ersetzt. diff --git a/src/docs/de-DE/deck.md b/src/docs/de-DE/deck.md deleted file mode 100644 index 4a2a3abe9..000000000 --- a/src/docs/de-DE/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# Deck - -Deck ist eines der in Misskey verwendbaren Benutzeroberflächen.Durch die Aneinanderreihung sogenannter "Spalten" wird ein hoher Anpassungsgrad sowie das Anzeigen vieler Informationen auf einmal ermöglicht. - -## Spalten hinzufügen -Um eine Spalte hinzuzufügen, klicke auf den Hintergrund des Decks und drücke "Spalte hinzufügen". - -## Spalten verschieben -Spalten können entweder durch Drag-and-Drop oder durch Anpassung der Spaltenoptionen (aufgerufen durch Rechtsklick auf den Spaltenkopf) individueller Spalten verschoben werden. - -## Horizontale Ausrichtung von Spalten -Spalten können nicht nur horizontal, sondern auch vertikal angeordnet werden. Durch Auswahl von "Auf linke Seite stapeln" im Spaltenmenü einer Spalte wird diese unter die Spalte links von sich selbst verschoben. Um dies aufzuheben, drücke "Nach rechts vom Stapel nehmen" im Spaltenmenü einer vertikal angeordneten Spalte. - -## Spalteneinstellungen -Um eine Spalte zu bearbeiten, drücke "Bearbeiten" in dessen Spaltenmenü.Der Name einer Spalte sowie dessen Breite können verändert werden. - -## Deck-Einstellungen -Deck-spezifische Einstellungen können in [settings/deck](/settings/deck) gefunden werden. diff --git a/src/docs/de-DE/features/antenna.md b/src/docs/de-DE/features/antenna.md deleted file mode 100644 index d9e667d01..000000000 --- a/src/docs/de-DE/features/antenna.md +++ /dev/null @@ -1,4 +0,0 @@ -# Antennen -アンテナは、自由に条件を設定して、合致するノートを自動で収集することができる機能です。 - -条件を設定したアンテナが作成された状態で、条件に合致するノートが投稿されると、リアルタイムでそのアンテナのタイムラインにノートが追加されます。 diff --git a/src/docs/de-DE/features/custom-emoji.md b/src/docs/de-DE/features/custom-emoji.md deleted file mode 100644 index beb3370e1..000000000 --- a/src/docs/de-DE/features/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# Benutzerdefinierte Emojis -カスタム絵文字は、インスタンスで用意された画像を絵文字のように使える機能です。 ノート、リアクション、チャット、自己紹介、名前などの場所で使うことができます。 カスタム絵文字をそれらの場所で使うには、絵文字ピッカーボタン(ある場合)を押すか、`:`を入力して絵文字サジェストを表示します。 テキスト内に`:foo:`のような形式の文字列が見つかると、`foo`の部分がカスタム絵文字名と解釈され、表示時には対応したカスタム絵文字に置き換わります。 diff --git a/src/docs/de-DE/features/deck.md b/src/docs/de-DE/features/deck.md deleted file mode 100644 index 73e9efdaa..000000000 --- a/src/docs/de-DE/features/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# Deck - -デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。 - -## カラムの追加 -デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。 - -## カラムの移動 -カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。 - -## カラムの水平分割 -カラムは左右だけでなく、上下に並べることもできます。 カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 上下分割を解除するには、カラムメニューの「右に出す」を選択します。 - -## カラムの設定 -カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。 - -## デッキの設定 -デッキに関する設定は、[settings/deck](/settings/deck)で行えます。 diff --git a/src/docs/de-DE/features/drive.md b/src/docs/de-DE/features/drive.md deleted file mode 100644 index c445b99a8..000000000 --- a/src/docs/de-DE/features/drive.md +++ /dev/null @@ -1,17 +0,0 @@ -# Drive -ドライブは、Misskey上でファイルを管理できる機能です。 - -[ドライブのページ](/my/drive)から任意のファイルをアップロードできるほか、アバターに設定した画像や、ノートに添付したファイルなどもすべてドライブにアップロードされます。 - -
⚠️ ドライブからファイルを削除すると、そのファイルが添付されたノートも消えます。
- -ドライブにアップロードされたファイルは、いつでもダウンロードすることができるほか、ノート作成時に「ドライブからファイルを添付」することでファイルを再利用することもできます。 - -ドライブ内にフォルダを作り、複数のファイルをまとめて整理することもできます。 - -## 閲覧注意 (NSFW) -
ℹ️ この項目が閲覧注意なわけではありません
- -閲覧注意またはNSFW (Not safe for work) は、ドライブのファイルに設定することができるフラグです。 閲覧注意フラグを設定されたファイルは、表示される際に閲覧者の操作なしには表示されなくなります。 このフラグは、例えば職場や公共の場で閲覧するのに適切でないと思われる画像などに設定し、そのような画像が突然表示されてしまうことを防ぐ目的で使われます。 - -このフラグは手動でオンオフを切り替えられるほか、モデレーターの判断で設定される場合もあります。 diff --git a/src/docs/de-DE/features/favorite.md b/src/docs/de-DE/features/favorite.md deleted file mode 100644 index f373490d1..000000000 --- a/src/docs/de-DE/features/favorite.md +++ /dev/null @@ -1,4 +0,0 @@ -# Zu Favoriten hinzufügen -[ノート](./node)をお気に入りとして登録できる機能です。 お気に入り登録したノートは、[お気に入りページ](./my/favorites)で一覧することができます。 お気に入りに登録したことは相手に通知されず、お気に入りは自分しか見ることができません。 - -ノートをお気に入り登録するには、ノートメニューの「お気に入り」を押します。お気に入り解除するには、ノートメニューの「お気に入り解除」を押します。 diff --git a/src/docs/de-DE/features/follow.md b/src/docs/de-DE/features/follow.md deleted file mode 100644 index ab1b86197..000000000 --- a/src/docs/de-DE/features/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# Folgt -ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。 diff --git a/src/docs/de-DE/features/keyboard-shortcut.md b/src/docs/de-DE/features/keyboard-shortcut.md deleted file mode 100644 index c0313d53a..000000000 --- a/src/docs/de-DE/features/keyboard-shortcut.md +++ /dev/null @@ -1,66 +0,0 @@ -# キーボードショートカット - -## Global -これらのショートカットは基本的にどこでも使えます。 - - - - - - - - - - - -
ショートカット効果由来
P, N新規投稿Post, New, Note
Tタイムラインの最も新しい投稿にフォーカスTimeline, Top
Shift + N通知を表示/隠すNotifications
SSuchenSearch
H, ?ヘルプを表示Help
- -## 投稿にフォーカスされた状態 - - - - - - - - - - - - - - - - - - -
ショートカット効果由来
, K, Shift + Tab上の投稿にフォーカスを移動-
, J, Tab下の投稿にフォーカスを移動-
R返信フォームを開くReply
QRenoteフォームを開くQuote
Ctrl + Q即刻Renoteする(フォームを開かずに)-
E, A, +リアクションフォームを開くEmote, reAction
0~9数字に対応したリアクションをする(対応については後述)-
F, Bお気に入りに登録Favorite, Bookmark
Del, Ctrl + D投稿を削除Delete
M, O投稿に対するメニューを開くMore, Other
SCWで隠された部分を表示 or 隠すShow, See
Escフォーカスを外す-
- -## Renoteフォーム - - - - - - - - - -
ショートカット効果由来
EnterRenoteする-
Qフォームを展開するQuote
Escフォームを閉じる-
- -## リアクションフォーム -デフォルトで「👍」にフォーカスが当たっている状態です。 - - - - - - - - - - - - - -
ショートカット効果由来
, K上のリアクションにフォーカスを移動-
, J下のリアクションにフォーカスを移動-
, H, Shift + Tab左のリアクションにフォーカスを移動-
, L, Tab右のリアクションにフォーカスを移動-
Enter, Space, +リアクション確定-
0~9数字に対応したリアクションで確定-
Escリアクションするのをやめる-
diff --git a/src/docs/de-DE/features/mfm.md b/src/docs/de-DE/features/mfm.md deleted file mode 100644 index 5be2df4f3..000000000 --- a/src/docs/de-DE/features/mfm.md +++ /dev/null @@ -1,12 +0,0 @@ -# MFM -MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます。 - -## MFMが使用可能な場所の例 -- ノート本文 -- CW注釈 -- ユーザーの名前 -- ユーザーの自己紹介 - -## 開発者向け情報 -MFMのパーサー実装はライブラリとして公開されており、簡単にクライアントにMFMを組み込むことが可能です。 -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptパーサー実装 diff --git a/src/docs/de-DE/features/mute-and-block.md b/src/docs/de-DE/features/mute-and-block.md deleted file mode 100644 index 429b3b352..000000000 --- a/src/docs/de-DE/features/mute-and-block.md +++ /dev/null @@ -1,41 +0,0 @@ -# Stummschaltungen und Blockierungen -好みではないユーザーがいる場合は、ミュートを行うことでそのユーザーが自分から見えないようにすることができます。 また、より強力な措置として、ブロックを行うことでそのユーザーから自分のコンテンツが見えないようになるほか、自分に対して関わることができないようにすることができます。 ミュートされていることは相手は分かりませんが、ブロックされていることは相手に分かります。どちらを選ぶかはご自身の判断で行ってください。 - -
ℹ️ ミュートとブロックは併用できます。
- -
⚠️ 利用規約に違反するような、迷惑なユーザーがいる場合は運営者に報告することも検討してください。
- -設定>ミュートとブロック から、自分がミュートまたはブロックしているユーザー一覧を確認することができます。 - -## Stummschalten -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -- タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -- そのユーザーからの通知 -- メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 -- など - -ユーザーをミュートするには、対象のユーザーのユーザーページのメニューを開き、「ミュート」ボタンを押します。 - -
ℹ️ ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。
- -## Blockieren -ユーザーをブロックすると、そのユーザーからあなたのコンテンツが見えないようになり、またあなたに対して以下のようなアクションをすることができなくなります。 - -- フォローする -- ユーザーリストに追加する -- 返信する、Renoteする -- リアクションする、アンケートに投票する -- メッセージを送信する -- など - -また、 - -- ブロックする際に既にそのユーザーからフォローされていた場合はフォローが解除されます。 -- ブロックする際に既にそのユーザーがあなたをユーザーリストに入れていた場合はそのリストからあなたが削除されます。 - -ユーザーをブロックするには、対象のユーザーのユーザーページのメニューを開き、「ブロック」ボタンを押します。 - -
⚠️ ブロックを行ったこと自体は相手に通知されませんが、フォローを行ったりなどの上記のアクションが行えなくなるので間接的にブロックされていることは分かります。
- -
⚠️ 相手から自分のコンテンツが見えなくなりますが、相手がアカウントを切り替えたりログアウト状態になれば見ることができます。あくまで簡易的、補助的なものとしてお考えください。
diff --git a/src/docs/de-DE/features/mute.md b/src/docs/de-DE/features/mute.md deleted file mode 100644 index 5b1c99cd9..000000000 --- a/src/docs/de-DE/features/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# Stummschalten - -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -* タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -* そのユーザーからの通知 -* メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 - -ユーザーをミュートするには、対象のユーザーのユーザーページに表示されている「ミュート」ボタンを押します。 - -ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。 - -設定>ミュート から、自分がミュートしているユーザー一覧を確認することができます。 diff --git a/src/docs/de-DE/features/note.md b/src/docs/de-DE/features/note.md deleted file mode 100644 index 1442b1096..000000000 --- a/src/docs/de-DE/features/note.md +++ /dev/null @@ -1,54 +0,0 @@ -# Notizen -ノートは、Misskeyに投稿される、文章、ファイル、アンケートなどを含むコンテンツで、Misskeyの中心的概念です。また、そのノートを作成する行為自体もノートと呼ばれます。 - -ノートが作成されると、[タイムライン](./timeline)に追加され、自分の[フォロワー](./follow)やサーバーのユーザーが見れるようになります。 - -ノートには、[リアクション](./reaction)を行うことができます。また、返信や引用もできます。 - -ノートを[お気に入り](./favorite)登録することで、後で簡単に見返すことができます。 - -## ノートを作成する -ノートを作成するには、画面上にある鉛筆マークのボタンを押して、作成フォームを開きます。作成フォームに内容を入力し、「ノート」ボタンを押すことでノートが作成されます。 ノートには、画像、動画など任意のファイルや、[アンケート](./poll)を添付することができます。また、本文中には[MFM](./mfm)が使用でき、[メンション](./mention)や[ハッシュタグ](./hashtag)を含めることもできます。 他にも、CWや公開範囲といった設定も行えます(詳細は後述)。 -
ℹ️ コンピューターのクリップボードに画像データがある状態で、フォーム内のテキストボックスにペーストするとその画像を添付することができます。
-
ℹ️ テキストボックス内でCtrl + Enterを押すことでも投稿できます。
- -## Renote -既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノートをRenoteと呼びます。 自分がフォローしているユーザーの、気に入ったノートを自分のフォロワーに共有したい場合や、過去の自分のノートを再度共有したい場合に使います。 同じノートに対して無制限にRenoteを行うことができますが、あまり連続して使用すると迷惑になる場合もあるので、注意しましょう。 -
⚠️ 公開範囲がフォロワーやダイレクトのノートはRenoteできません
- -Renoteを削除するには、Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 - -## CW -Contents Warningの略で、ノートの内容を、閲覧者の操作なしには表示しないようにできる機能です。主に長大な内容を隠すためや、ネタバレ防止などに使うことができます。 設定するには、フォームの「内容を隠す」ボタン(目のアイコン)を押します。すると新しい入力エリアが表れるので、そこに内容の要約を記入します。 - -## Sichtbarkeit -ノートごとに、そのノートが公開される範囲を設定することができます。フォームの「ノート」ボタンの左にあるアイコンを押すと公開範囲を以下から選択できます。 - -### Öffentlich -全ての人に対してノートが公開されるほか、サーバーの全てのタイムライン(ホームタイムライン、ローカルタイムライン、ソーシャルタイムライン、グローバルタイムライン)にノートが流れます。 -
⚠️ アカウントがサイレンス状態の時は、この公開範囲は使用できません。
- -### Startseite -全ての人に対してノートが公開されますが、フォロワー以外のローカルタイムライン、ソーシャルタイムライン、グローバルタイムラインにはノートは流れません。 - -### Gefolgt von -自分のフォロワーに対してのみノートを公開します。フォロワーの全てのタイムラインに流れます。 - -### Direkt -指定したユーザーに対してのみノートを公開します。指定したユーザーの全てのタイムラインに流れます。 - -### 「ローカルのみ」オプション -このオプションを有効にすると、リモートにノートを連合しなくなります。 - -### 公開範囲の比較 - - - - -
ÖffentlichStartseiteGefolgt vonDirekt
フォロワーのLTL/STL/GTL
非フォロワーのLTL/STL/GTL
- -## Anheften -ノートをピン留めすると、ユーザーページに常にそのノートを表示しておくことができます。 ノートのメニューを開き、「ピン留め」を選択してピン留めできます。 複数のノートをピン留めできます。 - -## Beobachten -ノートをウォッチすると、自分以外のノートへのリアクションや返信などの通知を受け取ることができます。 ノートのメニューを開き、「ウォッチ」を選択してウォッチできます。 diff --git a/src/docs/de-DE/features/pages.md b/src/docs/de-DE/features/pages.md deleted file mode 100644 index 60f04b9de..000000000 --- a/src/docs/de-DE/features/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# Pages - -## Variablen -変数を使うことで動的なページを作成できます。テキスト内で { 変数名 } と書くとそこに変数の値を埋め込めます。例えば Hello { thing } world! というテキストで、変数(thing)の値が ai だった場合、テキストは Hello ai world! になります。 - -変数の評価(値を算出すること)は上から下に行われるので、ある変数の中で自分より下の変数を参照することはできません。例えば上から A、B、C と3つの変数を定義したとき、Cの中でABを参照することはできますが、Aの中でBCを参照することはできません。 - -ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。 - -関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。 diff --git a/src/docs/de-DE/features/reaction.md b/src/docs/de-DE/features/reaction.md deleted file mode 100644 index b6cdf9d97..000000000 --- a/src/docs/de-DE/features/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# Reaktionen -他の人のノートに、絵文字を付けて簡単にあなたの反応を伝えられる機能です。 リアクションするには、ノートの + アイコンをクリックしてピッカーを表示し、絵文字を選択します。 リアクションには[カスタム絵文字](./custom-emoji)も使用できます。 - -## リアクションピッカーのカスタマイズ -ピッカーに表示される絵文字を自分好みにカスタマイズすることができます。 設定の「リアクション」で設定します。 - -## リモート投稿へのリアクションについて -リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。 - -## リモートからのリアクションについて -リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。 diff --git a/src/docs/de-DE/features/silence.md b/src/docs/de-DE/features/silence.md deleted file mode 100644 index 97d8ea27a..000000000 --- a/src/docs/de-DE/features/silence.md +++ /dev/null @@ -1,6 +0,0 @@ -# Instanzweit stummschalten -サイレンスは、アカウントに設定される状態のひとつです。 - -アカウントがサイレンス状態になると、ノートの公開範囲をパブリックにできなくなります。 ホーム、フォロワー、ダイレクトは選択可能なため、サイレンスを受けた場合でもフォロワーやあなたのユーザーページを直接訪れた場合は投稿を閲覧できますが、GTL(連合タイムライン)やLTL(ローカルタイムライン)には投稿が流れません。 - -アカウントのサイレンス状態は、サーバーのモデレーターによって有効化/無効化されます。 diff --git a/src/docs/de-DE/features/theme.md b/src/docs/de-DE/features/theme.md deleted file mode 100644 index 78e65ff51..000000000 --- a/src/docs/de-DE/features/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# Farbthemen - -テーマを設定して、Misskeyクライアントの見た目を変更できます。 - -## テーマの設定 -設定 > テーマ - -## テーマを作成する -テーマコードはJSON5で記述されたテーマオブジェクトです。 テーマは以下のようなオブジェクトです。 -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... テーマの一意なID。UUIDをおすすめします。 -* `name` ... テーマ名 -* `author` ... テーマの作者 -* `desc` ... テーマの説明(オプション) -* `base` ... 明るいテーマか、暗いテーマか - * `light`にすると明るいテーマになり、`dark`にすると暗いテーマになります。 - * テーマはここで設定されたベーステーマを継承します。 -* `props` ... テーマのスタイル定義。これから説明します。 - -### テーマのスタイル定義 -`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 - -#### バリューで使える構文 -* 16進数で表された色 - * 例: `#00ff00` -* `rgb(r, g, b)`形式で表された色 - * 例: `rgb(0, 255, 0)` -* `rgb(r, g, b, a)`形式で表された透明度を含む色 - * 例: `rgba(0, 255, 0, 0.5)` -* 他のキーの値の参照 - * `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。 - * 例: `@panel` -* 定数(後述)の参照 - * `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。 - * 例: `$main` -* 関数(後述) - * `:{関数名}<{引数}<{色}` - -#### Konstante -「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 キー名を`$`で始めると、そのキーはCSS変数として出力されません。 - -#### Funktionen -wip diff --git a/src/docs/de-DE/features/timeline.md b/src/docs/de-DE/features/timeline.md deleted file mode 100644 index 08cac4ac8..000000000 --- a/src/docs/de-DE/features/timeline.md +++ /dev/null @@ -1,31 +0,0 @@ -# Chronik -タイムラインは、[ノート](./note)が時系列で表示される機能です。 タイムラインには以下で示す種類があり、種類によって表示されるノートも異なります。 なお、タイムラインの種類によってはサーバーにより無効になっている場合があります。 - -## Startseite -自分のフォローしているユーザーの投稿が流れます。HTLと略されます。 - -## Lokal -全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。LTLと略されます。 - -## Sozial -自分のフォローしているユーザーの投稿と、全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。STLと略されます。 - -## Global -全てのローカルユーザーの「ホーム」指定されていない投稿と、サーバーに届いた全てのリモートユーザーの「ホーム」指定されていない投稿が流れます。GTLと略されます。 - -## Vergleiche -| ソース | | | Chronik | | | -| ------------ | --------------- | ---------- | ------- | ------ | ------ | -| Benutzer | Sichtbarkeit | Startseite | Lokal | Sozial | Global | -| ローカル (フォロー) | Veröffentlichen | ✔ | ✔ | ✔ | ✔ | -| | Startseite | ✔ | | ✔ | | -| | Gefolgt von | ✔ | ✔ | ✔ | ✔ | -| リモート (フォロー) | Veröffentlichen | ✔ | | ✔ | ✔ | -| | Startseite | ✔ | | ✔ | | -| | Gefolgt von | ✔ | | ✔ | ✔ | -| ローカル (未フォロー) | Veröffentlichen | | ✔ | ✔ | ✔ | -| | Startseite | | | | | -| | Gefolgt von | | | | | -| リモート (未フォロー) | Veröffentlichen | | | | ✔ | -| | Startseite | | | | | -| | Gefolgt von | | | | | diff --git a/src/docs/de-DE/features/widgets.md b/src/docs/de-DE/features/widgets.md deleted file mode 100644 index 7c5cacb39..000000000 --- a/src/docs/de-DE/features/widgets.md +++ /dev/null @@ -1,7 +0,0 @@ -# Widgets -ウィジェットは、MisskeyのUI上に設置できる小型の情報表示、操作が行えるパーツです。 - -ウィジェットを編集するには、ウィジェット編集モードに切り替えます。切り替え方法はUIによって異なります。 ウィジェット編集モードでは、ウィジェットの追加、削除、並び替え、およびそれぞれのウィジェットの設定を行えます。 - -## 利用可能なウィジェット一覧 -todo diff --git a/src/docs/de-DE/features/word-mute.md b/src/docs/de-DE/features/word-mute.md deleted file mode 100644 index 133e918ff..000000000 --- a/src/docs/de-DE/features/word-mute.md +++ /dev/null @@ -1,20 +0,0 @@ -# Wort-Stummschaltung -ワードミュートの設定をすると、条件に合致したノートが表示されなくなります。 - -ワードミュートには、ソフトワードミュートとハードワードミュートの2種類があります。それぞれについて設定の方法と挙動を説明します。 - -## ソフトワードミュート -ソフトワードミュートは、クライアント(アプリ)側でミュートを判断するワードミュートです。 - -ノートが設定した条件に合致すると、「(ユーザー名)が何かを言いました」という表示で隠れます。 -クリックすると元の通りに表示されます。 - -## ハードワードミュート -ハードワードミュートは、アンテナのようにサーバーが新しいノートの本文に対して条件に合致するかどうか判断し、タイムラインから対象となったノートを除外します。 - -つまり、ハードワードミュートには、以下のような特徴があります。 - -* 条件設定後、新しい投稿のみがミュートの対象になります。 -* 条件を変更しても、過去にハードミュートされたノートはミュートされたままになります。 -* 「○○が何かを言いました」でタイムラインが埋まることがありません。 -* ソフトミュートに非対応のアプリでも、ハードミュートは適用されます。 diff --git a/src/docs/de-DE/follow.md b/src/docs/de-DE/follow.md deleted file mode 100644 index fc50d2e37..000000000 --- a/src/docs/de-DE/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# Folgen -Folgst du einem Benutzer, so werden dessen Beiträge auf deiner Chronik angezeigt.Antworten dieses Benutzers auf Beiträge Anderer werden jedoch nicht angezeigt. Um einem Benutzer zu folgen, drücke den "Folgen"-Knopf auf dessen Profil.Um einem Benutzer nicht mehr zu folgen, drücke den selben Knopf erneut. diff --git a/src/docs/de-DE/general/apps.md b/src/docs/de-DE/general/apps.md deleted file mode 100644 index f0080bd30..000000000 --- a/src/docs/de-DE/general/apps.md +++ /dev/null @@ -1,6 +0,0 @@ -# Liste von Drittanbieter-Apps -## クライアント -todo - -## 連携サービス -todo diff --git a/src/docs/de-DE/general/changelog.md b/src/docs/de-DE/general/changelog.md deleted file mode 100644 index e8ee88f11..000000000 --- a/src/docs/de-DE/general/changelog.md +++ /dev/null @@ -1,5 +0,0 @@ -# Änderungshistorie -
ℹ️ このサーバーの更新履歴です。Misskeyの最新のリリースについては、GitHubをご確認ください。
- - - diff --git a/src/docs/de-DE/general/faq.md b/src/docs/de-DE/general/faq.md deleted file mode 100644 index a5534797c..000000000 --- a/src/docs/de-DE/general/faq.md +++ /dev/null @@ -1,28 +0,0 @@ -# Häufig gestellte Fragen -ここでは利用上のよくある質問について掲載しています。 Misskeyのプロジェクト自体についてのよくある質問は[こちら](./misskey)に掲載されています。 - -## iOS/Androidのアプリはありますか? -公式にはそういったOSのネイティブアプリを開発していませんが、サードパーティ製のアプリがいくつかあります。 詳しくは[こちら](./apps)をご覧ください。 - -ただ、サードパーティ製アプリはどうしても機能への対応が遅れてしまうため、とくに拘りがなければ公式のWebクライアントの利用をおすすめします。 なお、MisskeyのWebクライアントはPWAに対応しているので、ネイティブアプリのように動作させることも可能です。 詳しくは[こちら](todo)をご覧ください。 - -## Mastodonクライアントでログインできないのですが? -MisskeyはMastodonのAPIと互換性がないため、一部を除きMastodonクライアントでMisskeyを利用することはできません。 - -## 他のサーバーのユーザーをフォローするときは? -メニューから検索を選び、ユーザー名をホスト込みで入力します。例: `@syuilo@misskey.io` - -## Renoteを削除するには? -Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 Renoteについては[こちら](../features/note)をご確認ください。 - -## URLのプレビューを表示させたくない -MFMには、そのURLのプレビューを無効にする構文があります。詳細は[MFMチートシート](/mfm-cheat-sheet)をご確認ください。 - -## カスタム絵文字を追加したい -運営者のみがカスタム絵文字を追加、編集、削除できます。それらを希望する場合は運営者に依頼してください。 - -## Botを開発したい -Misskey APIを利用してBotの開発が可能です。[こちら](../advanced/develop-bot)をご確認ください。 - -## ノートの翻訳機能はどのサービスを使用していますか? -[DeepL](https://www.deepl.com/)を使用しています。 diff --git a/src/docs/de-DE/general/glossary.md b/src/docs/de-DE/general/glossary.md deleted file mode 100644 index 9b3196efb..000000000 --- a/src/docs/de-DE/general/glossary.md +++ /dev/null @@ -1,89 +0,0 @@ -# Glossar -Misskeyに関する用語集です。 - -## ActivityPub -(読み: あくてぃびてぃぱぶ) 分散型を実現するために用いられるプロトコル(仕様)。このプロトコルに則ってサーバー同士通信を行うことで、連合が行われ、Fediverseを形成しています。 - -## AiScript -(読み: あいすくりぷと) Misskey上で使用できるプログラミング言語です。詳細は[こちら。](../advanced/aiscript) - -## API -(読み: えーぴーあい) Misskeyのサーバーが公開している、プログラムからMisskeyを扱うためのインターフェース。詳細は[こちら。](../advanced/api) - -## Bot -(読み: ぼっと) プログラムによって動作しているアカウント。 - -## CW -(読み: こんてんつわーにんぐ) Contents Warningの略。ノートの内容を、操作なしには表示しないようにできる機能。主に長大な内容を隠すためや、ネタバレ防止などに使われます。 - -## Fediverse -(読み: ふぇでぃばーす) Misskeyを含む様々な分散型ソフトウェアのサーバーで構成されたネットワーク。 - -## GTL -グローバルタイムライン(Global TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## HTL -ホームタイムライン(Home TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## LTL -ローカルタイムライン(Local TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## MFM -(読み: えむえふえむ) Misskey Flavored Markdownの略で、Misskey上で使用できるマークアップ言語です。詳細は[こちら。](../features/mfm) - -## NSFW -(読み: のっとせーふふぉーわーく) Not Safe For Workの略。画像を「閲覧注意」扱いにし、操作なしには表示しないようにすることができる機能。 - -## Renote -(読み: りのーと) 既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノート。詳細は[こちら。](../features/note) - -## STL -ソーシャルタイムライン(Social TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## 藍 -(読み: あい) Misskeyの看板娘(公式キャラクター)です。 - -## アクティブユーザー -インスタンスにアカウントを作っているユーザーのうち、現在も実際にサービスを利用しているユーザーのこと。 - -## Instanz -todo - -## Benutzerdefinierte Emojis -サーバーで用意された絵文字。カスタム絵文字ではない通常の絵文字は「Unicode絵文字」と区別して呼ばれる。 - -## コントロールパネル -インスタンスの設定画面のこと。 - -## Server -todo - -## Instanzweit stummschalten -ノートをパブリックな公開範囲で投稿できなくされている状態。モデレーターの判断でユーザーごとに設定されます。詳細は[こちら。](../features/silence) - -## Job-Warteschlange -アクティビティ配送などを順番に行うためのシステム。 - -## Sperren -アカウントが使用不可に設定されている状態。 - -## Drive -Misskeyにアップロードしたファイルを管理する機能。詳細は[こちら。](../features/drive) - -## Notizen -Misskeyに投稿される、文章、ファイル、アンケートなどを含めることができるコンテンツ。詳細は[こちら。](../features/note) - -## ミスキスト -Misskeyを使う人のこと。 - -## Moderator -スパムの凍結およびサイレンスや不適切な投稿の削除など、コミュニティ運営に関する権限を持つユーザー。 - -## Fremd -他サーバーのことを指します。リモートユーザーといったように接頭辞としても使われます。ローカルの逆です。 - -## Föderation -サーバー上で作成された情報が他のサーバーに伝わること。 - -## Lokal -自サーバーのことを指します。ローカルユーザー、ローカルタイムラインといったように接頭辞としても使われます。リモートの逆です。 diff --git a/src/docs/de-DE/general/links.md b/src/docs/de-DE/general/links.md deleted file mode 100644 index 048378fa2..000000000 --- a/src/docs/de-DE/general/links.md +++ /dev/null @@ -1,12 +0,0 @@ -# Links - -## Webサイト -- [Official Discord](https://discord.gg/Wp8gVStHW3) - Misskey公式Discordサーバー -- [Misskey Forum](https://forum.misskey.io/) - Misskeyに関する話題を扱うフォーラム - -## Benutzerkonten -- [@repo@misskey.io](https://misskey.io/@repo) - Misskeyのリポジトリの更新を投稿するbot - -## ライブラリ -- [misskey-dev/misskey.js](https://github.com/misskey-dev/misskey.js) - JavaScriptのMisskey SDK -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptのMFMパーサー実装 diff --git a/src/docs/de-DE/general/misskey.md b/src/docs/de-DE/general/misskey.md deleted file mode 100644 index e3179488c..000000000 --- a/src/docs/de-DE/general/misskey.md +++ /dev/null @@ -1,87 +0,0 @@ -# Über Misskey - -Misskeyはオープンソースの分散型マイクロブログプラットフォームプロジェクトです。 開発は日本でsyuiloによって2014年から開始されました。 ドライブ、リアクションなどの豊富な機能や、高いカスタマイズ性を備えたUIを持つことが特徴です。 - -## 歴史 -開発当初は掲示板がメインのサービスでしたが、ユーザーが短文を投稿し、それを時系列で流れるタイムライン機能を追加したところ人気が高まり、徐々にそれがメインとして開発が進むようになりました。 当初は分散型ではありませんでしたが、2018年にActivityPubを実装し分散型になったことで、より多くの方に認知され利用されるサービスになり、現在に至ります。 -
ℹ️ Misskeyという名前は、syuiloが当時聴いていたMay'nというアーティストの楽曲、Brain Diverの歌詞に由来します。
- -誰でも開発に参加することができ、現在でも活発に開発が続いています。 - -## 分散型とは何か? - -分散(distributed)型とは、非中央集権(decentralized)とも呼ばれ、コミュニティが多数のサーバーに分散して存在し、それらが相互に通信(連合、federation)することでコンテンツ共有ネットワーク(Fediverse)を形成していることが特徴のサービスです。 単一のサーバーしか存在しない、もしくは複数存在しても互いに独立している場合は中央集権なサービスと言われ、例えばTwitterやFacebookなどほとんどのサービスがそれに該当します。 分散型のメリットは、自分に合った運営者やテーマのサーバーを選択できることです。自分でサーバーを作成することもできます。連合するおかげで、どのサーバーを選んでも、同じコミュニティにアクセスできます。 - -## 常にオープンソース -Misskeyはこれまでもこれからも、オープンソースであり続けます。オープンソースとは、簡単に言うとソフトウェアのソースコード(プログラム)が公開されていることです。ソースコードの修正や再配布が可能であることを定義に含めることもあります。 Misskeyのすべてのソースコードは[AGPL](https://github.com/misskey-dev/misskey/blob/develop/LICENSE)というオープンソースライセンスの下に[公開](https://github.com/misskey-dev)されていて、誰でも自由に閲覧、使用、修正、改変、再配布をすることができます。 オープンソースは、自分で好きなように変えたり、有害な処理が含まれていないことを確認することができたり、誰でも開発に参加できるなどの、様々なメリットがあります。 上述の分散型を実現するためにも、オープンソースであるということは必要不可欠な要素です。 再び引き合いに出しますが、TwitterやFacebookなどの利益を得ているほとんどのサービスはオープンソースではありません。 - -
ℹ️ 技術的に言うと、MisskeyのソースコードはGitで管理されていて、リポジトリはGitHub上でホスティングされています。
- -## 開発に参加する、プロジェクトを支援する -Misskeyを気に入っていただけたら、ぜひプロジェクトを支援してください。プロジェクトに貢献するには、以下で紹介するようにいろいろな方法があります。方法によっては開発のスキルは不要なので、誰でも気軽に参加し貢献することができます。いつでもお待ちしています。 - -### 機能を追加したり、バグを修正する -ソフトウェアエンジニアのスキルをお持ちの方であれば、ソースコードを編集する形でプロジェクトに貢献することができます。 貢献についてのガイドは[こちら](https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md)です。 - -### 議論に参加する -新しい機能、または既存の機能について意見を述べたり、不具合を報告したりすることでも貢献できます。 そのようなディスカッションは[GitHub](https://github.com/misskey-dev)上か、[フォーラム](https://forum.misskey.io/)等で行われます。 - -### テキストを翻訳する -Misskeyは様々な言語に対応しています(i18n -internationalizationの略- と呼ばれます)。元の言語は基本的に日本語ですが、有志によって他の言語へと翻訳されています。 その翻訳作業に加わっていただくことでもMisskeyに貢献できます。 Misskeyは[Crowdinというサービスを使用して翻訳の管理を行っています。](https://crowdin.com/project/misskey) - -### 感想を投稿する -不具合報告等だけではなく、Misskeyの良い点、楽しい点といったポジティブな意見もぜひ共有してください。開発の励みになり、それは間接的ですがプロジェクトへの貢献です。 - -### ミスキストを増やす -ミスキストとは、Misskeyを使用する人のことです。 知り合いに紹介するなどしてMisskeyを広めていただければ、ミスキストが増え開発のモチベーションが上がります。 - -### 寄付をする -Misskeyはビジネスではなく、利用は無料であるため、収益は皆様からの寄付のみです。(インスタンスによっては広告収入を得ているような場合もありますが、それは運営者の収入であり直接開発者への収入にはなりません) 寄付をしていただければ、今後も開発を続けることが可能になり、プロジェクトへの貢献になります。 寄付は基本的には[Patreon](https://www.patreon.com/syuilo)で受け付けています。 一定額寄付していただけると、Misskeyの[情報ページ](/about-misskey)に名前を記載することができます。 - -また、サーバーの運営者も、基本的には収益を得ていません。サーバーの運営にはコストがかかるので、運営者の支援をすることもご検討ください。 開発には直接関係しませんが、サーバーがあってこそのプロジェクトなので、運営が維持されるというのは開発と同じくらい重要なことです。 - -## クレジット -Misskeyの開発者や、Misskeyに寄付をしてくださった方の一覧は[こちら](/about-misskey)で見ることができます。 - -## Häufig gestellte Fragen -### プロジェクトは何を目指していますか? -強いて言うと、漠然的になりますが広く使われる汎用的なプラットフォームになることを目指しています。 Misskeyは他のプロジェクトとは違い、何らかの思想(例えば、反中央集権)やビジョンに基づいて開発が行われているわけではなく、その点ではフラットです。 それが逆に、特定の方向性に縛られないフレキシブルさを生み出すことに繋がっていると感じています。 - - -### 企業によって開発されていますか? -いいえ。Misskeyの開発は個人で行われており、商業的でもないため、特定の企業の関りはありません。 開発メンバーも基本的にはボランティアです。 また、開発に対し企業のスポンサーがつくこともありますが、その場合でもやはり開発は個人のコミュニティが主体です。 - -### 誰が運営していますか? -Misskeyは分散型なため、各サーバーにそれぞれ異なった運営者がいます。従って、特定の個人や企業によって、Misskeyの全てが運営されているわけではありません。 また、開発チームが運営を行うわけでもないため、運営に関する連絡は、お使いのサーバーの運営者に行ってください。 サーバーの運営者は、[このページ](/about)で確認することができます。 あなたがサーバーを作成すれば、あなたが運営者になります。 - -### どのサーバーを選べばいいですか? -[サーバー一覧が公開されています。](https://join.misskey.page/ja-JP/instances) サーバーによってコミュニティのテーマ(特定のこと、ものが好き 等)が決められている場合があるので、自分に合ったテーマのサーバーがあれば、そこを選ぶと良いかもしれません。 他にも、サーバーの規模、ユーザー層、国および言語、運営者が信頼できるかどうか、などの観点があります。 なお、Misskey公式のサーバーというものはありません。自身で新しくサーバーを作成するという選択肢もあります。 - -基本的にどのサーバーを選んだとしても、他の全てのサーバーのユーザーと繋がることができます。 - -### サーバーを建てるにはどうしたらいいですか? -Misskeyサーバーの作成に興味を持っていただきありがとうございます。 2021年現在、Misskeyのホスティングサービスは存在しないため、サーバーの作成にはある程度の知識が必要です。 サーバーの作成方法については[こちら](todo)をご覧ください。 - -### どのような技術を使用していますか? -Misskeyは開発が進むにつれ使用する技術も大きく変わってきました。開発当初はMySQL + PHP + jQueryといった構成でしたが、現在は以下のようになっています。 -- サーバーサイド: Node.js -- データベース: PostgreSQL、Redis -- UIフレームワーク: Vue.js -- プログラミング言語: TypeScript - -また、MFMやAiScriptなどの、Misskeyから派生して独自の技術も開発しています。 - -### Mastodonのフォークですか? -いいえ。MisskeyはMastodonやその他のプロジェクトとは全く別のプロジェクトです。 開発に関しても、Misskeyの方が昔から開発されています。ただし、分散型になったのはMastodonの登場より後です。 同じActivityPubという分散のためのプロトコルを実装しているという点以外、両者に特に関りがあるわけでもありません。 - -### iOS/Androidのアプリはありますか? -公式にはそういったOSのネイティブアプリを開発していませんが、サードパーティ製のアプリがいくつかあります。 詳しくは[こちら](./apps)をご覧ください。 - -ただ、サードパーティ製アプリはどうしても機能への対応が遅れてしまうため、とくに拘りがなければ公式のWebクライアントの利用をおすすめします。 なお、MisskeyのWebクライアントはPWAに対応しているので、ネイティブアプリのように動作させることも可能です。 詳しくは[こちら](todo)をご覧ください。 - -### Misskeyのロゴ、アイコンはどこで入手できますか? -(準備中) - -### 時折目にする猫耳の可愛い女の子は? -Misskeyの守り神、藍ちゃんです。アイチャンカワイイヤッター! -
ℹ️ 藍ちゃんについてはこちらです。
diff --git a/src/docs/de-DE/general/report-issue.md b/src/docs/de-DE/general/report-issue.md deleted file mode 100644 index 63c23aa5c..000000000 --- a/src/docs/de-DE/general/report-issue.md +++ /dev/null @@ -1,8 +0,0 @@ -# Fehler melden -不具合と思われる状況に遭遇したときは、まず[トラブルシューティング](./troubleshooting)をご一読ください。 それでも問題が解決しないときは、以下の情報を含めて[フォーラム](https://forum.misskey.io/)に投稿してください。 投稿することで、解決策が見つかったり、不具合と判断されれば開発チームによって修正が行われます。 - -## 含める情報 -- Misskeyのバージョン([情報ページ](/about)で確認できます) -- お使いのブラウザの種類とバージョン -- お使いのOSの種類とバージョン -- 問題の再現手順 diff --git a/src/docs/de-DE/general/troubleshooting.md b/src/docs/de-DE/general/troubleshooting.md deleted file mode 100644 index c0b8b010c..000000000 --- a/src/docs/de-DE/general/troubleshooting.md +++ /dev/null @@ -1,40 +0,0 @@ -# Problembehandlung -
ℹ️ よくある質問も合わせてお役立てください。
- -問題が発生したときは、まずこちらをご確認ください。 該当する項目が無い、もしくは手順を試しても効果がない場合は、サーバーの管理者に連絡するか[不具合を報告](./report-issue)してください。 - -## クライアントが起動しない -ほとんどの場合、お使いのブラウザまたはOSのバージョンが古いことが原因です。 ブラウザおよびOSのバージョンを最新のものに更新してから、再度試してみてください。 - -これは稀ですが、それでも起動しない場合は、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。 - -## ページが読み込めない -クライアントが起動するもののページが読み込めないというエラーが出る場合は、ネットワークに問題がないか確認してください。また、サーバーがダウンしていないか確認してください。 - -これは稀ですが、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。 - -まだ問題がある場合は、サーバーの問題と思われるのでサーバーの管理者に連絡してください。 - -## クライアントの動作が遅い -以下を試してみてください: - -- クライアント設定で「UIのアニメーションを減らす」を有効にする -- クライアント設定で「モーダルにぼかし効果を使用」を無効にする -- お使いのブラウザの設定でハードウェアアクセラレーションを有効にする -- お使いのデバイスのスペックを上げる - -## UIの一部の表示がおかしい(背景が透明になっている等) -アップデートによりUIの改修が行われたときに、テーマのキャッシュシステムの影響でそのような表示になることがあります。 クライアントの設定の「キャッシュをクリア」すると直ります。 -
⚠️ 「クライアントの」キャッシュクリアです。「ブラウザの」キャッシュクリアは行わないでください。
- -## 通知やアンテナ等の点滅が消えない -点滅は、未読のコンテンツがあることを示しています。通常点滅が消えない場合は、コンテンツを遡ると未読なコンテンツが残っています。 すべて既読にしたと思われるのに、それでもなお点滅が続く場合(おそらく不具合と思われます)は設定から強制的にすべて既読扱いにすることができます。 - -## Renoteができない -フォロワー限定のノートはRenoteすることはできません。 - -## UI上で特定の要素が表示されない -広告ブロッカーを使用しているとそのような不具合が発生することがあります。Misskeyではオフにしてご利用ください。 - -## UI上で未翻訳の部分がある -ほとんどの場合、単に翻訳が間に合っていないだけで、不具合ではありません。翻訳が終わるまでお待ちください。 [翻訳に参加](./misskey)していただくことも可能です。 diff --git a/src/docs/de-DE/keyboard-shortcut.md b/src/docs/de-DE/keyboard-shortcut.md deleted file mode 100644 index be3fb3232..000000000 --- a/src/docs/de-DE/keyboard-shortcut.md +++ /dev/null @@ -1,68 +0,0 @@ -# Tastenkürzel - -## Global -Hier gelistete Tastenkürzel können generell überall verwendet werden. - - - - - - - - - - - -
KürzelEffektUrsprung
P, NNeuer BeitragPost, New, Note
TNeusten Beitrag der Chronik fokussierenTimeline, Top
Shift + NBenachrichtigungen anzeigen / ausblendenNotifications
SSuchenSearch
H, ?Hilfe anzeigenHelp
- -## Auf Beiträge bezogene Kürzel - - - - - - - - - - - - - - - - - - - -
KürzelEffektUrsprung
, K, Shift + TabFokus zum oberen Beitrag wechseln-
, J, TabFokus zum unteren Beitrag wechseln-
RAntwort-Fenster öffnenReply
QRenote-Fenster öffnenQuote
Ctrl + QSofort Renote tätigen (ohne Fenster)-
E, A, +Reaktionsfenster öffnenEmote, reAction
0~9Mit dem Emoji, dessen Position in der Emoji-Auswahl der gedrückten Zahl entspricht, reagieren (Details folgen)-
F, BFavoriten hinzufügenFavorite, Bookmark
Del, Ctrl + DBeitrag löschenDelete
M, OBeitrags-Menü öffnenMore, Other
SVerdeckten Inhalt anzeigen / ausblendenShow, See
EscFokus lösen-
- -## Auf das Renote-Fenster bezogene Kürzel - - - - - - - - - - -
KürzelEffektUrsprung
EnterSendet Renote-
QFenster expandierenQuote
EscFenster schließen-
- -## Auf die Reaktionsauswahl bezogene Kürzel -Standardmäßig liegt der Fokus auf der "👍"-Reaktion. - - - - - - - - - - - - - -
KürzelEffektUrsprung
, KFokus zu oberer Reaktion wechseln-
, JFokus zur unteren Reaktion wechseln-
, H, Shift + TabFokus zur linken Reaktion wechseln-
, L, TabFokus zur rechten Reaktion wechseln-
Enter, Space, +Reaktion senden-
0~9Mit dem Emoji, dessen Position der gedrückten Zahl entspricht, reagieren-
EscReagieren abbrechen-
diff --git a/src/docs/de-DE/mfm.md b/src/docs/de-DE/mfm.md deleted file mode 100644 index 9319d8497..000000000 --- a/src/docs/de-DE/mfm.md +++ /dev/null @@ -1,2 +0,0 @@ -# MFM -MFM, abgekürzt für Misskey Flavored Markdown, beschreibt eine Misskey-exklusive Markup-Sprache. Eine Liste verwendbarer MFM-Syntax kann auf dem [MFM Spickzettel](/mfm-cheat-sheet) eingesehen werden. diff --git a/src/docs/de-DE/mute.md b/src/docs/de-DE/mute.md deleted file mode 100644 index f6003f9b6..000000000 --- a/src/docs/de-DE/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# Stummschaltung - -Sobald du einen Benutzer stummschaltest, werden die folgenden Arten von mit diesem Benutzer verbundenen Beiträge von Misskey nicht mehr angezeigt: - -* Beiträge dieses Nutzers in Chroniken sowie Suchergebnissen (inklusive Renotes und Antworten auf diese) -* Benachrichtigungen von diesem Benutzer -* Chatverläufe mit diesem Benutzer in der Liste aller Chatverläufe - -Um einen Benutzer stummzuschalten, navigiere zu dessen Profil und drücke den dort angezeigten "Stummschalten"-Knopf. - -Der stummgeschaltete Benutzer erhält hierüber keine Benachrichtung, und erhält darüber, ob er von einem anderen Benutzer Stummgeschaltet ist, auch keine Informationen. - -Unter Einstellungen > Stummschaltungen / Blockierungen kann eine Liste aller stummgeschalteter Benutzer eingesehen werden. diff --git a/src/docs/de-DE/pages.md b/src/docs/de-DE/pages.md deleted file mode 100644 index be1496867..000000000 --- a/src/docs/de-DE/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# Seiten - -## Variablen -Durch die Verwendung von Variablen ist es möglich, dynamische Seiten zu erstellen.Wird in einem Text { Variablenname } beinhaltet, wird dies mit dem Wert dieser Variable eingesetzt.Ist Beispielsweise der Wert der Variable thing in diesem Fall ai, dann wird der Text Hallo { thing } Welt! zu Hallo ai Welt! ausgewertet. - -Variablen werden von oben nach unten ausgewertet, d.h. Referenzen zu Variablen, die noch nicht definiert sind, sind nicht möglich.Werden Beispielsweise die Variablen A, B, C in der gegebenen Reihenfolge definiert, so kann sich innerhalb von C auf A oder B bezogen werden, aber innerhalb von A nicht auf B oder C. - -Um (Text-)Eingabe durch Benutzer empfangen zu können, kann der Seite ein "Benutzereingabe"-Feld hinzugefügt werden, welches dann den Wert, den der Benutzer eingibt, in einer Variable mit gewünschtem Namen speichert.Durch die Verwendung dieser Benutzereingabe können dann die weiteren Aktionen der Seite gesteuert werden. - -Die Verwendung von Funktionen erlaubt die Definition von wiederverwendbaren Werteberechnungen.Um eine Funktion zu erstellen, wähle "Funktion" als Variablentyp.Funktionen können ebenso Slots (Parameter) verwenden, auf dessen Werte dann innerhalb der Funktion zugegriffen werden kann.Zudem ist es möglich, eine Funktion zu erstellen, dessen Parameter eine weitere Funktion ist ("Funktion höherer Ordnung").Neben der vorherigen Definition von Funktionen können in Funktionen höherer Ordnung Funktionen ebenso direkt in der Parametereingabe definiert werden. diff --git a/src/docs/de-DE/reaction.md b/src/docs/de-DE/reaction.md deleted file mode 100644 index 44321eb43..000000000 --- a/src/docs/de-DE/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# Reaktionen -Verleih deinen Gedanken über die Beiträge anderer durch Reaktionen einfach Ausdruck. Um auf einen Beitrag zu reagieren, drücke das "+"-Symbol, das mit dem Beitrag angezeigt wird, und wähle ein Emoji. Es ist ebenso möglich, mit [Benutzerdefinierten Emojis](./custom-emoji) zu reagieren. - -## Anpassung der Reaktionsauswahl -Die in der Reaktionsauswahl angezeigten Emojis können angepasst werden. Dies ist in den Einstellungen im Unterpunkt "Reaktionen" möglich. - -## Reaktionen auf Beiträge von anderen Servern -Da Reaktionen eine Misskey-spezifische Funktionalität sind, werden diese von nicht-Misskey Instanzen meist als "Like"-Aktivität interpretiert.In den meisten Fällen ist die "Like"-Funktionalität als "Favoriten"-Funktion implementiert. Zudem werden Reaktionen mit benutzerdefinierten Emojis nicht übertragen und anstattdessen automatisch auf eine "👍"-Reaktion zurückfallen, auch wenn der Interaktionspartner ein anderer Misskey-Server ist. - -## Reaktionen von Benutzern anderer Server -Werden von entfernten Servern "Like"-Aktivitäten gesendet, so werden diese von Misskey als "👍"-Reaktion interpretiert. diff --git a/src/docs/de-DE/reversi-bot.md b/src/docs/de-DE/reversi-bot.md deleted file mode 100644 index 922b8c965..000000000 --- a/src/docs/de-DE/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# Entwicklung eines Misskey Reversi-Bots -Auf dieser Seite wird die Entwicklung eines Bots für Misskey Reversi erläutert. - -1. Verbinde dich unter Verwendung folgender Parameter mit dem `games/reversi`-Stream: - * `i`: API-Schlüssel des Bot-Kontos - -2. Sobald den Bot eine Spieleinladung erreicht, wird das `invited`-Event vom Stream gesendet - * Der Inhalt dieses Events ist ein `parent`-Attribut, was Daten über den Benutzer, der die Einladung verschickt hat, beinhaltet - -3. Sende eine Anfrage an `games/reversi/match`, wobei der Wert des `user_id`-Parameters das `id`-Attribut des vorher erhaltenen `parent`-Objekts ist - -4. Gelingt die Anfrage, werden die Spieldaten als Rückgabewert geliefert. Nutze diese dann, um die unten gelisteten Parameter an den `games/reversi-game`-Stream zu senden: - * `i`: API-Schlüssel des Bot-Kontos - * `game`: `id`-Attribut des `game`-Objekts - -5. Währenddessen kann der Spielgegner die Spieleinstellungen verändern. Jedes mal, wenn eine Einstellung verändert wird, sendet der Stream ein `update-settings`-Event, weswegen möglicherweise Logik, um solche Events verarbeiten zu können, notwendig ist. - -6. Sobald du mit den Spieleinstellungen zufrieden bist, sende die Nachricht `{ type: 'accept' }` an den Stream - -7. Sobald das Spiel startet, wird das `started`-Event gesendet - * Der Inhalt dieses Events sind die Spieldaten - -8. Um einen Stein zu setzen, sende die folgende Nachricht an den Stream: `{ type: 'set', pos: }` (Positionsberechnungen werden später erläutert) - -9. Setzt der Gegner oder du einen Stein, wird das `set`-Event vom Stream gesendet - * Die Farbe der Spielfigur ist als `color` enthalten - * Die Position der Spielfigur ist als `pos` enthalten - -## Positionsberechnungen -Im Falle eines 8x8 Spielbrettes sind die Felder wie folgt aufgestellt (jeweils mit ihrem Index versehen): -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### Berechnung von Indizes durch X und Y Koordinaten -``` -pos = x + (y * mapWidth) -``` -Bei `mapWidth` handelt es sich um wie folgt aus `map` entnommene Spielbrettdaten: -``` -mapWidth = map[0].length -``` - -### Berechnung der X und Y Koordinaten durch Indizes -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## Spielbrettdaten -Die Spielbrettdaten sind innerhalb vom in den Spieldaten enthaltenen `map`-Attribut gespeichert. Da das Spielbrett als Array von Zeichenketten representiert wird, steht jedes Symbol für ein Spielfeld. Basierend auf diesen Informationen lässt sich der Spielbrettzustand rekonstruieren. -* `(Leer)` ... Kein Spielfeld -* `-` ... Spielfeld -* `b` ... Spielfeld auf dem zuerst platzierter Stein schwarz war -* `w` ... Spielfeld auf dem zuerst platzierter Stein weiß war - -Sei folgendes simple 4*4 Spielbrett als Beispiel gegeben: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -In diesem Fall sehen die Spielbrettdaten wie folgt aus: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## Erstellen eines Bots, der mit dem Benutzer durch das Zeigen von Fenstern kommunizieren kann -Das Kommunizieren mit dem Spieler kann durch das Anzeigen von Fenstern während der Vorbereitungsphase des Spiels umgesetz werden. Beispielsweise kann so die Schwierigkeit des Bots durch den Benutzer konfiguriert werden. - -Um ein Fenster anzuzeigen, sende folgende Nachricht an den `reversi-game`-Stream: -```javascript -{ - type: 'init-form', - body: [Array an Fenster-Elementen] -} -``` - -Details bezüglich des Arrays an Fenster-Elementen werden nun erklärt. Ein Element eines Fensters ist wie das folgende Objekt aufgebaut: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... Die ID des Elements. `type` ... Der Typ des Elements.Diese werden später erläutert. `label` ... Text der zusammen mit dem Element angezeigt wird. `value` ... Standardwert des Elements. - -### Verarbeitung von Interaktionen mit Elementen -Interagiert der Benutzer mit einem der Elemente eines Fensters, so wird ein `update-form`-Element vom Stream gesendet. Die Inhalte dieses Events sind die ID des Elements sowie der Wert des Elements, der vom Benutzer eingestellt wurde. Wird beispielsweise der obige Beispielschalter eingeschaltet, wird das folgende Event gesendet: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### Arten von Form-Elementen -#### Schalter -type: `switch` Zeigt einen Schalter an.Eignet sich für Fälle, in denen etwas entweder ein- oder ausgeschaltet werden kann. - -##### Attribute -`label` ... Auf dem Schalter anzuzeigender Text. - -#### Optionsfeld -type: `radio` Zeigt ein Optionsfeld an.Eignet sich für Fälle, in denen verschiedene Optionen angezeigt werden.z.B. zur Einstellung der Stärke des Bots. - -##### Attribute -`items` ... Die verfügbaren Optionen.z.B.: -```javascript -items: [{ - label: 'Schwach', - value: 1 -}, { - label: 'Mittelmäßíg', - value: 2 -}, { - label: 'Stark', - value: 3 -}] -``` - -#### Schieberegler -type: `slider` Zeigt einen Schieberegler an. - -##### Attribute -`min` ... Der minimale Reglerwert. `max` ... Der maximale Reglerwert. `step` ... Der Abstand zwischen zwei Stufen des Reglers. - -#### Textbox -type: `textbox` Zeigt eine Textbox an.Für verschiedene Fälle, in denen Texteingabe des Benutzers gefragt sind, verwendbar. - -## Dem Benutzer Nachrichten zeigen -Dies ist eine alternative Methode, um mit dem Benutzer zu kommunieren, abgesehen vom Anzeigen eines Fensters während der Vorbereitungsphase des Spiels.Hierdurch kann dem Benutzer eine Nachricht angezeigt werden. Beispielsweise kann eine Warnung angezeigt werden, falls ein Spielmodus oder eine Spielkarte ausgewählt wird, mit der der Bot nicht kompatibel ist. Um eine Nachricht anzuzeigen, muss folgende Nachricht an den Stream gesendet werden: -```javascript -{ - type: 'message', - body: { - text: 'Nachrichteninhalt', - type: 'Nachrichtenart' - } -} -``` -Nachrichtenarten: `success`, `info`, `warning`, `error`. - -## Aufgeben -Um aufzugeben, sende eine Anfrage an diesen Endpunkt. diff --git a/src/docs/de-DE/stream.md b/src/docs/de-DE/stream.md deleted file mode 100644 index e0ec1fc35..000000000 --- a/src/docs/de-DE/stream.md +++ /dev/null @@ -1,354 +0,0 @@ -# Streaming API - -Durch die Verwendung des Streaming-APIs können verschiedene Daten (z.B. darüber, dass neue Beiträge geschrieben wurden, neue Direktnachrichten eingetroffen sind, Benachrichtigungen über einen neuen Follower, usw) in Echtzeit empfangen werden und dann basierend auf diesen verschiedene Aktionen getätigt werden. - -## Eine Verbindung zum Stream aufbauen - -Um das Streaming-API zu benutzen, muss zuerst eine Verbindung zu Misskey's **websocket** Server aufgebaut werden. - -Baue bitte mit Hilfe der unten stehenden URL eine websocket-Verbindung auf, wobei die Anmeldedaten als `i`-Parameter enthalten sind.z.B.: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -Anmeldedaten steht hierfür entweder für den eigenen API-Schlüssel oder bei Verbindungen zum Stream für den durch eine Anwendung generierten Zugangstoken eines Benutzers. - -
-

Siehe dieses Dokument für Informationen, wie solche Anmeldedaten erhalten werden können.

-
- ---- - -Ein Verbindungsaufbau ohne Anmeldedaten ist ebenso möglich, jedoch wird in diesem Fall der Zugriff auf manche Daten sowie die Verwendung mancher Funktionen eingeschränkt.z.B.: - -``` -%WS_URL%/streaming -``` - ---- - -Eine Verbindung zum Stream kann durch die später erläuterte API oder durch das Abbonieren individueller Beiträge getätigt werden. Jedoch können zu diesem Zeitpunkt noch keine Informationen über Chroniken wie das Eintreffen neuer Beiträge empfangen werden. Um dies zu ermöglichen, müssen Verbindungen zu später erläuterten **Kanälen** aufgebaut werden. - -**Alle Nachrichten an den sowie vom Stream sind in JSON-Format.** - -## Kanäle -Innerhalb des Misskey Streaming-APIs existiert das Konzept von Kanälen.Diese werden zur Abspaltung der Informationen, die erhalten werden sollen, verwendet. Wird eine Verbindung zum Misskey Stream aufgebaut, so ist es noch nicht möglich, sofort Echtzeit-Aktualisierungen zu empfangen. Durch den Verbindungsaufbau zu Kanälen des Streams wird beidseitige Kommunikation bezüglich Informationen dieses Kanals ermöglicht. - -### Verbindungen zu Kanälen aufbauen -Um eine Verbindung zu einem Kanal aufzubauen, sende die folgende Nachricht: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -Hier, -* steht `channel` für den Namen des Kanals, zu dem eine Verbindung aufgebaut werden soll.Eine Liste der verfügbaren Kanäle wird später angegeben. -* steht `id` für eine einzigartige ID zur Kommunikation mit diesem Kanal.Da durch den Stream viele verschiedene Nachrichten erhalten werden können, ist eine Zuordnung, zu welchen Kanal eine Nachricht gehört, notwendig.Diese ID kann eine UUID oder etwas wie der Wert eines Zufallszahlengenerators sein. -* steht `params` für die Parameter zum Verbindunsgaufbau.Je nach Kanal können die verfügbaren Parameter abweichen.Bei Kanälen, die keine Parameter akzeptieren, kann dieses Attribut ausgelassen werden. - -
-

Diese IDs sollen für jede Verbindung zu einem Kanal einzigartig sein, nicht nur für jeden Kanal.Der Grund dafür ist, dass mehrere Verbindungen zum selben Kanal mit unterschiedlichen Parametern zur selben Zeit bestehen können.

-
- -### Verarbeitung von eintreffenden Nachrichten der Kanäle -Beispielsweise wird bei Erstellung eines neuen Beitrags auf einer Chronik von einem Kanal eine Nachricht ausgelöst.Durch die Verarbeitung solcher Nachrichten ist es möglich, in Echtzeit über die Erstellung eines neuen Beitrags zu erfahren. - -Sendet ein Kanal eine Nachricht, so wird vom Stream folgendes JSON-Objekt empfangen: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -Hier, -* steht `id` für die zum Verbindungsaufbau gewählte ID, die zuvor erläutert wurde.Hierdurch wird eine Zuordnung, welche Nachricht zu welchen Kanal gehört, ermöglicht. -* steht `type` für die Art der Nachricht.Je nach Kanal können die Arten der Nachrichten, die von einem Kanal empfangen werden, abweichen. -* steht `body` für den Inhalt der Nachricht.Je nach Kanal kann der Inhalt der Nachrichten, die von einem Kanal empfangen werden, abweichen. - -### Nachrichten an Kanäle senden -Je nach Kanal kann es möglich sein, nicht nur Nachrichten vom Kanal zu empfangen, sondern auch Nachrichten an diesen zu senden, die dann unterschiedliche Aktionen auslösen können. - -Um eine Nachricht an einen Kanal zu senden, sende folgendes JSON-Objekt an den Stream: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -Hier, -* steht `id` für die zum Verbindungsaufbau gewählte ID, die zuvor erläutert wurde.Hierdurch wird festgelegt, an welchen Kanal diese Nachricht gesendet werden soll. -* steht `type` für die Art der Nachricht.Je nach Kanal können die Arten der Nachrichten, die an einen Kanal gesendet werden können, abweichen. -* steht `body` für den Inhalt der Nachricht.Je nach Kanal kann der Inhalt der Nachrichten, der an einen Kanal gesendet werden kann, abweichen. - -### Verbindungen zu Kanälen trennen -Um die Verbindung zu einem Kanal zu trennen, sende die folgende Nachricht: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -Hier, -* steht `id` für die zum Verbindungsaufbau gewählte ID. - -## API-Anfragen durch den Stream senden - -Durch den Stream ist es auch möglich, API-Anfragen ohne die Verwendung einer HTTP-Anfrage zu senden.So kann möglicherweise Code übersichtlicher und effizienter gehalten werden. - -Um via den Stream eine API-Anfrage zu senden, sende folgendes JSON-Objekt an den Stream: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -Hier, -* existiert `id` zur Zuordnung von Anfrage und Antwort und muss auf eine einzigartige ID gesetzt werden.Die Verwendung von UUIDs oder auch dem Wert eines simplen Zufallszahlengenerators ist empfohlen. -* gibt `endpoint` den Endpoint an, an den die Anfrage gesendet werden soll. -* enthält `data` die Parameter der Anfrage des Endpoints. - -
-

Siehe die API-Referenz bezüglich einer Auflistung verfügbarer API-Endpoints sowie dessen Parameter.

-
- -### Verarbeitung von Antworten auf Anfragen - -Sobald eine Anfrage an die API gesendet wurde, wird eine Antwort wie die folgende empfangen: - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -Hier, -* steht an Stelle der `xxxxxxxxxxxxxxxx` die vorher angegebene `id`.Dadurch ist eine Zuordnung von Anfrage zu Antwort möglich. -* ist der Antwortwert der Anfrage in `body` enthalten. - -## Beitragserfassung - -Misskey stellt eine sogenannte Beitragserfassung zur Verfügung.Hierdurch können dem angegebenen Beitrag zugehörige Events über den Stream empfangen werden. - -Sei beispielsweise eine Situation, in der einem Benutzer eine Chronik angezeigt wird.Nun wird von jemanden auf einen der Beiträge dieser Chronik reagiert. - -Da der Client jedoch nicht wissen kann, dass ein spezieller Beitrag eine Reaktion erhalten hat, ist es nicht möglich, diese Reaktion in Echtzeit darzustellen. - -Um dieses Problem zu lösen, wurde die Funktionalität der Beitragserfassung implementiert.Wird ein Beitrag erfasst, so werden verschiedene diesem Beitrag zugeordnete Events in Echtzeit übermittelt, um bei einer Veränderung diese sofort auf der Chronik anzeigen zu können. - -### Einen Beitrag erfassen - -Um einen Beitrag zu erfassen, sende folgende Nachricht an den Stream: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -Hier, -* `id` enthält die `id` des Beitrags der erfasst werden soll. - -Sobald diese Nachricht gesendet wurde wird dieser Beitrag von Misskey erfasst und es können von nun an diesen Beitrag betreffende Events empfangen werden. - -Beispielsweise wird das folgende Event empfangen, sobald einem erfassten Beitrag eine Reaktion hinzugefügt wurde: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -Hier, -* das `id`-Attribut in `body` enthält die ID des Beitrags, der das Event ausgelöst hat. -* das `type`-Attribut in `body` die Art des Events. -* das `body`-Attribut von `body` enthält weitere Informationen über das Event. - -#### Arten von Events - -##### `reacted` -Wird bei Reaktion auf den Beitrag ausgelöst. - -* `reaction` enthält die Art der Reaktion. -* `userId` enthält die ID des Benutzers, der die Reaktion hinzufügte - -z.B.: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -Wird bei Löschung des Beitrags ausgelöst. - -* `deletedAt` enthält Löschdatum und Zeitpunkt. - -z.B.: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -Wird bei Abstimmung in einer dem Beitrag angehörigen Umfrage ausgelöst. - -* `choice` enthält die ID der gewählten Auswahlmöglichkeit. -* `userId` enthält die ID des Benutzers, der auf die Umfrage antwortete - -z.B.: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### Beitragserfassung aufheben - -Sobald ein Beitrag nicht mehr auf der Chronik angezeigt wird und somit diesen Beitrag betreffende Events nicht mehr benötigt werden, bitten wir um die Aufhebung der Erfassung dieses Beitrags. - -Sende die folgende Nachricht: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -Hier, -* `id` enthält die `id` des Beitrags, für den Erfassung aufgehoben werden soll. - -Sobald diese Nachricht versendet wurde, werden mit diesem Beitrag verbundene Events nicht mehr empfangen. - -# List aller Kanäle -## `main` -Allgemeine den Benutzer betreffende Informationen werden über diesen Kanal empfangen.Dieser Kanal hat keine Parameter. - -### Liste der Events, die augelöst werden können - -#### `renote` -Wird ausgelöst, sobald ein eigener Beitrag ein Renote erhält.Renotes von eigenen Beiträgen lösen dieses Event nicht aus. - -#### `mention` -Wird ausgelöst, sobald der Benutzer von einem anderen Benutzer erwähnt wird. - -#### `readAllNotifications` -Dieses Event gibt an, dass alle Benachrichtungen auf gelesen gesetzt wurden.Es wird erwartet, dass dieses Event für bsp. Fälle eingesetzt wird, in denen der Indikator für ungelesene Benachrichtigungen deaktiviert werden soll. - -#### `meUpdated` -Wird bei Aktualisierung der eigenen Benutzerdaten augelöst. - -#### `follow` -Wird augelöst, sobald einem neuen Benutzer gefolgt wird. - -#### `unfollow` -Wird augelöst, sobald einem Benutzer nicht mehr gefolgt wird. - -#### `followed` -Wird augelöst, sobald der Benutzer einen neuen Follower erhält. - -## `homeTimeline` -Informationen über Beiträge der Startseiten-Chronik werden über diesen Kanal empfangen.Dieser Kanal hat keine Parameter. - -### Liste der Events, die augelöst werden können - -#### `note` -Wird augelöst, sobald auf der Chronik ein neuer Beitrag erscheint. - -## `localTimeline` -Informationen über Beiträge der lokalen Chronik werden über diesen Kanal empfangen.Dieser Kanal hat keine Parameter. - -### Liste der Events, die augelöst werden können - -#### `note` -Wird augelöst, sobald auf der lokalen Chronik ein neuer Beitrag erscheint. - -## `hybridTimeline` -Informationen über Beiträge der Sozial-Chronik werden über diesen Kanal empfangen.Dieser Kanal hat keine Parameter. - -### Liste der Events, die augelöst werden können - -#### `note` -Wird augelöst, sobald auf der Sozial-Chronik ein neuer Beitrag erscheint. - -## `globalTimeline` -Informationen über Beiträge der globalen Chronik werden über diesen Kanal empfangen.Dieser Kanal hat keine Parameter. - -### Liste der Events, die augelöst werden können - -#### `note` -Wird augelöst, sobald auf der globalen Chronik ein neuer Beitrag erscheint. diff --git a/src/docs/de-DE/theme.md b/src/docs/de-DE/theme.md deleted file mode 100644 index fe1c4fc7b..000000000 --- a/src/docs/de-DE/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# Farbthemen - -Durch die Verwendung von Farbthemen kann das Aussehen des Misskey-Clients verändert werden. - -## Themeneinstellungen -Einstellungen > Farbthemen - -## Erstellung eines Themas -Themencodes werden im Format eines JSON5-Objekts gespeichert. Themen werden wie das folgende Objekt dargestellt: -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... Die einzigartige Identifikation des Themas.Verwendung von UUIDs ist empfohlen. -* `name` ... Name des Themas -* `author` ... Ersteller des Themas -* `desc` ... Beschreibung des Themas (optional) -* `base` ... Ob dies ein Thema für den Hell- oder Dunkelmodus ist - * Wird `light` angegeben, so wird es als Thema des Hellmodus angezeigt, wird `dark` angegeben, so wird es als Thema des Dunkelmodus angezeigt. - * Das Thema erbt die Eigenschaften der hier eingestellten Vorlage. -* `props` ... Definitionen der Themenoptionen.Diese werden im folgenden erläutert. - -### Definition von Themenoptionen -Die Optionen des Themas werden in `props` definiert. Die Schlüssel werden zu CSS-Variablen, die Werte geben den Inhalt an. Zusätzlich werden die `props` des gewählten Basisthemas von diesem Thema geerbt. Ist die `base` dieses Themas auf `light` gesetzt, so werden sie aus [_light.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_light.json5) kopiert, ist sie auf `dark` gesetzt, so werden sie aus [_dark.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_dark.json5) kopiert. Beispielsweise wird, falls sich in den `props` dieses Themas keine Definition für den Schlüssel `panel` befindet, so wird der Wert von `panel` aus dem Basisthema verwendet. - -#### Syntax für Wertangaben -* Hexadezimalfarben - * z.B.: `#00ff00` -* RGB-Farben mit `rgb(r, g, b)`-Syntax - * z.B.: `rgb(0, 255, 0)` -* RGBA-Farben mit `rgb(r, g, b, a)`-Syntax - * z.B.: `rgba(0, 255, 0, 0.5)` -* Werte anderer Schlüssel referenzieren - * Durch das angeben von `@{Schlüsselname}` wird dies durch eine Referenz auf den Wert des gegebenen Schlüssels ersetzt.Ersetze `{Schlüsselname}` mit dem Namen des Schlüssels, der referenziert werden soll. - * z.B.: `@panel` -* Konstantenreferenz (später erläutert) - * Durch das angeben von `${Konstantenname}` wird dies durch eine Referenz auf den Wert der angegebenen Konstante ersetzt.Ersetze `{Konstantenname}` durch den Namen der Konstanten, die referenziert werden soll. - * z.B.: `$main` -* Funktionen (später erläutert) - * `:{Funktionsname}<{Parameter}<{Farbe}` - -#### Konstante -In Fällen, in denen ein Wert nicht als CSS-Variable angesehen werden soll, sondern als Wert für eine andere CSS-Variable verwendet werden soll, eignet sich die Verwendung einer Konstante. Wird ein Wert mit einem `$`-Präfix versehen, so wird er nicht als CSS-Variable, sondern als Referenz angesehen. - -#### Funktionen -wip diff --git a/src/docs/de-DE/timelines.md b/src/docs/de-DE/timelines.md deleted file mode 100644 index 212a1c30d..000000000 --- a/src/docs/de-DE/timelines.md +++ /dev/null @@ -1,15 +0,0 @@ -# Liste der Chroniken - -https://docs.google.com/spreadsheets/d/1lxQ2ugKrhz58Bg96HTDK_2F98BUritkMyIiBkOByjHA/edit?usp=sharing - -## Startseite -Alle Beiträge von Benutzern, denen gefolgt wird - -## Lokal -Alle Beiträge von lokalen Benutzern, die nicht auf "Startseite" gesetzt sind - -## Sozial -Alle Beiträge von Benutzern, denen gefolgt wird sowie alle Beiträge von lokalen Benutzern, die nicht auf "Startseite" gesetzt sind - -## Global -Alle Beiträge von lokalen Benutzern, die nicht auf "Startseite" gesetzt sind sowie alle nicht auf "Startseite" gesetzen Beiträge von Benutzern entfernter Server, die den verwendeten Server erreichen. diff --git a/src/docs/en-US/admin/disable-timelines.md b/src/docs/en-US/admin/disable-timelines.md deleted file mode 100644 index 94ba3dd17..000000000 --- a/src/docs/en-US/admin/disable-timelines.md +++ /dev/null @@ -1,8 +0,0 @@ -# Disabling the LTL/STL/GTL -In Misskey, it's possible to individually deactivate the LTL/STL/GTL.You can enable or disable these individual timelines via the instance control panel. - -As all posts across your instance can be seen in both the LTL and STL, they have the advantage of making it easy for new users to find others that they are interested in without having to use the manual user search. At the same time however, this means that following other users to see their posts is less important and inappropriate posts may be shown to users more frequently. Additionally, the experience becomes more alike that of a Chatroom, which in turn may make it more difficult for new users to join in one conversations with those who have been taking part for a long time. As the weight of these advantages and disadvantages may vary from server to server, the choice of using or not using them has been left to each individual instance. If you feel like the demerits outweigh the merits, please consider deactivating these respective timelines. - -
⚠️ Disabling timelines can lead to confusion and possibly to a short-time drop in users.Therefore, please carefully consider the effects of disabling a timeline, and explain the reasoning for doing so in advance, so that your users can prepare by e.g. following users they often talk with on the LTL/STL.
- -Additionally, Administrators / Moderators will be able to continue viewing these timelines even after they have been disabled. diff --git a/src/docs/en-US/admin/faq.md b/src/docs/en-US/admin/faq.md deleted file mode 100644 index a7fbc66a7..000000000 --- a/src/docs/en-US/admin/faq.md +++ /dev/null @@ -1,5 +0,0 @@ -# Frequently Asked Questions -This document is aimed at server administrators and will list answers for frequently asked questions. - -## "I want to set a default theme for my instance" -There is currently no feature allowing you to set a default theme for your instance. diff --git a/src/docs/en-US/advanced/aiscript.md b/src/docs/en-US/advanced/aiscript.md deleted file mode 100644 index cfcdfebf9..000000000 --- a/src/docs/en-US/advanced/aiscript.md +++ /dev/null @@ -1,7 +0,0 @@ -# AiScript -AiScript is a scripting language for Misskey. - -
ℹ️ AiScript is open source and hosted in a separate repository from Misskey.
- -## Usage -AiScript documentation such as syntax and built-in functions can be found [here](https://github.com/syuilo/aiscript/tree/master/docs). diff --git a/src/docs/en-US/advanced/api.md b/src/docs/en-US/advanced/api.md deleted file mode 100644 index ef1995b18..000000000 --- a/src/docs/en-US/advanced/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス、Bot等(以下「アプリケーション」と呼びます)を開発できます。 ストリーミングAPIもあるので、リアルタイム性のあるアプリケーションを作ることも可能です。 - -APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。 - -## Obtain an access token -基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。 - -* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む -* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む - -### 自分自身のアクセストークンを手動発行する -「設定 > API」で、自分のアクセストークンを発行できます。 - -[「APIの使い方」へ進む](#APIの使い方) - -### アプリケーション利用者にアクセストークンの発行をリクエストする -アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。 - -#### Step 1 - -Generate UUID.以後これをセッションIDと呼びます。 - -> このセッションIDは毎回生成し、使いまわさないようにしてください。 - -#### Step 2 - -`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。 -> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます: -* `name` ... App name - * > 例: `MissDeck` -* `icon` ... App icon URL - * > 例: `https://missdeck.example.com/icon.png` -* `callback` ... 認証が終わった後にリダイレクトするURL - * > 例: `https://missdeck.example.com/callback` - * リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます -* `permission` ... App permissions - * > 例: `write:notes,write:following,read:drive` - * 要求する権限を`,`で区切って列挙します - * どのような権限があるかは[APIリファレンス](/api-doc)で確認できます - -#### Step 3 -ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。 - -レスポンスに含まれるプロパティ: -* `token` ... User access token -* `user` ... User info - -[「APIの使い方」へ進む](#APIの使い方) - -## API usage -**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。There is no REST support.** アクセストークンは、`i`というパラメータ名でリクエストに含めます。 - -* [API Reference](/api-doc) -* [Streaming API](./stream) diff --git a/src/docs/en-US/advanced/create-plugin.md b/src/docs/en-US/advanced/create-plugin.md deleted file mode 100644 index 3b8763dfd..000000000 --- a/src/docs/en-US/advanced/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# New Plugin -Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。 - -## Metadata -プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。 - -### name -Plugin name - -### author -Plugin author - -### version -プラグインバージョン。A number must be specified. - -### description -Plugin description - -### permissions -プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。 - -### config -プラグインの設定情報を表すオブジェクト。 キーに設定名、値に以下のプロパティを含めます。 - -#### type -設定値の種類を表す文字列。以下から選択します。 string number boolean - -#### label -ユーザーに表示する設定名 - -#### description -設定の説明 - -#### default -設定のデフォルト値 - -## API Reference -AiScript標準で組み込まれているAPIは掲載しません。 - -### Mk:dialog(title text type) -ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。 - -### Mk:confirm(title text type) -確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。 - -### Mk:api(endpoint params) -Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。 - -### Mk:save(key value) -任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。 - -### Mk:load(key) -Mk:saveで永続化した指定の名前の値を読み取ります。 - -### Plugin:register_post_form_action(title fn) -投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。 - -### Plugin:register_note_action(title fn) -ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 - -### Plugin:register_user_action(title fn) -ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。 - -### Plugin:register_note_view_interruptor(fn) -UIに表示されるノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:register_note_post_interruptor(fn) -ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:open_url(url) -第一引数に渡されたURLをブラウザの新しいタブで開きます。 - -### Plugin:config -プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。 diff --git a/src/docs/en-US/advanced/develop-bot.md b/src/docs/en-US/advanced/develop-bot.md deleted file mode 100644 index c6a312e79..000000000 --- a/src/docs/en-US/advanced/develop-bot.md +++ /dev/null @@ -1,6 +0,0 @@ -# Create a bot -[Misskey API](./api)を利用してBotの開発が可能です。 また、いくつかのBot実装が公開されているため、ぜひ参考にしてください。 - -- [syuilo/ai](https://github.com/syuilo/ai) ... Node.js上で動く、TypeScript製Bot実装 - -Botを作成したときは、プロフィール設定からBotフラグをオンにしておくことを強くおすすめします。 diff --git a/src/docs/en-US/advanced/reversi-bot.md b/src/docs/en-US/advanced/reversi-bot.md deleted file mode 100644 index f1be888cb..000000000 --- a/src/docs/en-US/advanced/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# MisskeyリバーシBotの開発 -Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。 - -1. `games/reversi`ストリームに以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - -2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる - * イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている - -3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する - -4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - * `game`: `game`の`id` - -5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う - -6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する - -7. ゲームが開始すると、`started`イベントが流れてくる - * イベントの中身にはゲーム情報が含まれている - -8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述) - -9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる - * `color`として石の色が含まれている - * `pos`として位置情報が含まれている - -## 位置の計算法 -8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### X,Y座標 から インデックス に変換する -``` -pos = x + (y * mapWidth) -``` -`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます: -``` -mapWidth = map[0].length -``` - -### インデックス から X,Y座標 に変換する -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## マップ情報 -マップ情報は、ゲーム情報の`map`に入っています。 文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 それをもとにマップのデザインを知る事が出来ます: -* `(スペース)` ... マス無し -* `-` ... マス -* `b` ... 初期配置される黒石 -* `w` ... 初期配置される白石 - -例えば、4*4の次のような単純なマップがあるとします: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -この場合、マップデータはこのようになります: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## ユーザーにフォームを提示して対話可能Botを作成する -ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。 - -フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します: -```javascript -{ - type: 'init-form', - body: [フォームコントロールの配列] -} -``` - -フォームコントロールの配列については今から説明します。 フォームコントロールは、次のようなオブジェクトです: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... コントロールのID。 `type` ... コントロールの種類。後述します。 `label` ... コントロールと一緒に表記するテキスト。 `value` ... コントロールのデフォルト値。 - -### フォームの操作を受け取る -ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### フォームコントロールの種類 -#### Switch -type: `switch` スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。 - -##### プロパティ -`label` ... スイッチに表記するテキスト。 - -#### ラジオボタン -type: `radio` ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。 - -##### プロパティ -`items` ... ラジオボタンの選択肢。例: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '強', - value: 3 -}] -``` - -#### スライダー -type: `slider` スライダーを表示します。 - -##### プロパティ -`min` ... スライダーの下限。 `max` ... スライダーの上限。 `step` ... 入力欄で刻むステップ値。 - -#### テキストボックス -type: `textbox` テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。 - -## ユーザーにメッセージを表示する -設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 メッセージを表示するには、次のメッセージをストリームに送信します: -```javascript -{ - type: 'message', - body: { - text: 'メッセージ内容', - type: 'メッセージの種類' - } -} -``` -メッセージの種類: `success`, `info`, `warning`, `error`。 - -## 投了する -投了をするには、このエンドポイントにリクエストします。 diff --git a/src/docs/en-US/advanced/share-page.md b/src/docs/en-US/advanced/share-page.md deleted file mode 100644 index 9bec559cd..000000000 --- a/src/docs/en-US/advanced/share-page.md +++ /dev/null @@ -1,54 +0,0 @@ -# シェアページ -`/share`を開くと、共有用の投稿フォームを開くことができます。 ここではシェアページで利用できるクエリ文字列の一覧を示します。 - -## クエリ文字列一覧 -### Text - -
-
title
-
タイトルです。本文の先頭に[ … ]と挿入されます。
-
text
-
本文です。
-
url
-
URLです。末尾に挿入されます。
-
- -### リプライ情報 -以下のいずれか - -
-
replyId
-
リプライ先のノートid
-
replyUri
-
リプライ先のUrl(リモートのノートオブジェクトを指定)
-
- -### Renote情報 -以下のいずれか - -
-
renoteId
-
Renote先のノートid
-
renoteUri
-
Renote先のUrl(リモートのノートオブジェクトを指定)
-
- -### Visiblility -※specifiedに相当する値はvisibility=specifiedとvisibleAccts/visibleUserIdsで指定する - -
-
visibility
-
公開範囲 ['public' | 'home' | 'followers' | 'specified']
-
localOnly
-
0(false) or 1(true)
-
visibleUserIds
-
specified時のダイレクト先のユーザーid カンマ区切りで
-
visibleAccts
-
specified時のダイレクト先のacct(@?username[@host]) カンマ区切りで
-
- -### Files -
-
fileIds
-
添付したいファイルのid(カンマ区切りで)
-
diff --git a/src/docs/en-US/advanced/stream.md b/src/docs/en-US/advanced/stream.md deleted file mode 100644 index 16b15c761..000000000 --- a/src/docs/en-US/advanced/stream.md +++ /dev/null @@ -1,350 +0,0 @@ -# Streaming API - -ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。 - -## ストリームに接続する - -ストリーミングAPIを利用するには、まずMisskeyサーバーに**websocket**接続する必要があります。 - -以下のURLに、`i`というパラメータ名で認証情報を含めて、websocket接続してください。例: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。 - -
ℹ️ 認証情報の取得については、こちらのドキュメントをご確認ください。
- ---- - -認証情報は省略することもできますが、その場合非ログインでの利用ということになり、受信できる情報や可能な操作は限られます。例: - -``` -%WS_URL%/streaming -``` - ---- - -ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。 - -**ストリームでのやり取りはすべてJSONです。** - -## Channels -MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。 - -ひとつのストリーム上で、同時に複数のチャンネルに接続することができます。 - -### チャンネルに接続する -チャンネルに接続するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -ここで、 -* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。 -* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。 -* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。 - -
ℹ️ IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。
- -### チャンネルからのメッセージを受け取る -例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。 - -チャンネルがメッセージを発すると、次のようなデータがJSONでストリームに流れてきます: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。 -* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。 -* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。 - -### チャンネルに向けてメッセージを送信する -チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。 - -チャンネルにメッセージを送信するには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。 -* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。 -* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。 - -### チャンネルから切断する -チャンネルから切断するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。 - -## ストリームを経由してAPIリクエストする - -ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。 - -ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -ここで、 -* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 -* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 -* `data`には、エンドポイントのパラメータを含めます。 - -
ℹ️ APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。
- -### レスポンスの受信 - -APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。 - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -ここで、 -* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 -* `body`には、レスポンスが含まれています。 - -## 投稿のキャプチャ - -Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。 - -例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。 - -しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。 - -この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。 - -### 投稿をキャプチャする - -投稿をキャプチャするには、ストリームに次のようなメッセージを送信します: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャしたい投稿の`id`を設定します。 - -このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 - -例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -ここで、 -* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。 -* `body`内の`type`に、イベントの種類が設定されます。 -* `body`内の`body`に、イベントの詳細が設定されます。 - -#### イベントの種類 - -##### `reacted` -その投稿にリアクションがされた時に発生します。 - -* `reaction`に、リアクションの種類が設定されます。 -* `userId`に、リアクションを行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -その投稿が削除された時に発生します。 - -* `deletedAt`に、削除日時が設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -その投稿に添付されたアンケートに投票された時に発生します。 - -* `choice`に、選択肢IDが設定されます。 -* `userId`に、投票を行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### 投稿のキャプチャを解除する - -その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。 - -次のメッセージを送信します: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャを解除したい投稿の`id`を設定します。 - -このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 - -# チャンネル一覧 -## `main` -アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `renote` -自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。 - -#### `mention` -誰かからメンションされたときに発生するイベントです。 - -#### `readAllNotifications` -自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。 - -#### `meUpdated` -自分の情報が更新されたことを表すイベントです。 - -#### `follow` -自分が誰かをフォローしたときに発生するイベントです。 - -#### `unfollow` -自分が誰かのフォローを解除したときに発生するイベントです。 - -#### `followed` -自分が誰かにフォローされたときに発生するイベントです。 - -## `homeTimeline` -ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -タイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `localTimeline` -ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `hybridTimeline` -ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ソーシャルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `globalTimeline` -グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 diff --git a/src/docs/en-US/aiscript.md b/src/docs/en-US/aiscript.md deleted file mode 100644 index 20bd18f6e..000000000 --- a/src/docs/en-US/aiscript.md +++ /dev/null @@ -1,4 +0,0 @@ -# AiScript - -## Functions -Behave as pass by value by default. diff --git a/src/docs/en-US/api.md b/src/docs/en-US/api.md deleted file mode 100644 index adec20ec6..000000000 --- a/src/docs/en-US/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -Using the Misskey API you can develop Misskey clients, Webservices integrating with Misskey, Bots (later called "Applications" here) etc. The streaming API also exists, so it is also possible to create real-time applications. - -To starting using the API, you first need to get an access token. This page will explain how to acquire an access token and then give basic API usage instructions. - -## Obtaining an access token -Fundamentally, all API requests require an access token. The method of acquiring such an access token will vary depending on whether you yourself are sending API requests or requests are being sent through an application used by an end-user. - -* In case of the former: Move on to [ "Manually issuing an access token for your own account" ](#自分自身のアクセストークンを手動発行する) -* In case of the latter: Move on to [ "Requesting the application user to generate an access token" ](#アプリケーション利用者にアクセストークンの発行をリクエストする) - -### Manually issuing your own access token -You can create an access token for your own account in Settings > API. - -[Proceed to using the API.](#APIの使い方) - -### Requesting the application user to generate an access token -To obtain an access token of the end user's account for your app, request permissions for it via the below process. - -#### Step 1 - -Generate a UUID.We will call it the session ID from here on. - -> The same session ID should not be used for multiple plugins, so please generate a new UUID for each access token. - -#### Step 2 - -Open the URL `{_URL_}/miauth/{session}` in the user's browser.Replace the `{session}` part with your previously generated session ID. -> E.g.: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -When opening this URL, you can set various settings via query prameters: -* `name` ... Application name - * > E.g.: `MissDeck` -* `icon` ... Icon URL of the application - * > E.g.: `https://missdeck.example.com/icon.png` -* `callback` ... URL to redirect to after authorization - * > E.g.: `https://missdeck.example.com/callback` - * In the redirect a `session` query parameter containing the session ID will be attached. -* `permission` ... Permissions requested by the application - * > E.g.: `write:notes,write:following,read:drive` - * List the requested permissions separated with a `,` character. - * You can check all available permissions at the [API Reference](/api-doc) - -#### Step 3 -If you send a POST request to `{_URL_}/api/miauth/{session}/check` after the user has authorized the access token, the response will be a JSON object containing said token. - -Properties included in the response: -* `token` ... Access token of the user -* `user` ... User data - -[Proceed to using the API.](#APIの使い方) - -## Using the API -**All API requests are POST, and all request and response data is formatted in JSON.There is no REST support.** The access token must be included in the request parameter called `i`. - -* [API Reference](/api-doc) -* [Streaming API](./stream) diff --git a/src/docs/en-US/create-plugin.md b/src/docs/en-US/create-plugin.md deleted file mode 100644 index 1544c0d85..000000000 --- a/src/docs/en-US/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# New Plugin -If you use the plugin function of the Misskey web client, you can expand the web client with a variety of different functionality. This page will list metadata definitions for plugin creation as well as an AiScript API reference for plugins. - -## Metadata -Plugins must define default plugin metadata via the AiScript metadata format. Metadata is an object containing the following properties: - -### name -Plugin name - -### author -Plugin author - -### version -Plugin version.Please enter a number. - -### description -Plugin description - -### permissions -Permissions required by the plugin.Used when making requests to the Misskey API. - -### config -An object representing the plugin's settings. Keys represent setting names and values are any of the below properties. - -#### type -A string representing the setting's value type.Selected from one of the below types. string number boolean - -#### label -Setting name to do display to the user - -#### description -Description of the setting - -#### default -Default value of the setting - -## API Reference -API built directly into the AiScript standard itself will not be listed. - -### Mk:dialog(title text type) -Display a dialog.You can select one of the below types. info success warn error question If no type is selected, "info" is chosen by default. - -### Mk:confirm(title text type) -Display a confirmation dialog.You can select one of the below types. info success warn error question If no type is selected, "question" is chosen by default. If the user presses "OK" true will be returned, if they press "Cancel" false will be returned. - -### Mk:api(endpoint params) -Sends a request to the Misskey API.Specify the endpoint name as the first parameter and the request parameters as the second argument. - -### Mk:save(key value) -Persistently saves any given value under a given key.The saved value will remain even after the AiScript context ends and can be loaded with Mk:load. - -### Mk:load(key) -Reads the value of the given key that was previously saved with Mk:save. - -### Plugin:register_post_form_action(title fn) -Add an action to the post form.Enter an action name as the first parameter, and a callback function for when the action is executed as second parameter. A post form object is passed to the callback function as first argument. - -### Plugin:register_note_action(title fn) -Add an item to the note menu.Enter an item name as the first parameter, and a callback function for when the menu item is pressed as second parameter. A note object of the targeted note is passed to the callback function as first parameter. - -### Plugin:register_user_action(title fn) -Add an item to the user menu.Enter an item name as the first parameter, and a callback function for when the menu item is pressed as second parameter. A user object of the selected user is passed to the callback function as first parameter. - -### Plugin:register_note_view_interruptor(fn) -Modify the data of notes displayed in the UI. A note object is passed to the callback function as first parameter. The note will be modified based on the note object returned by the callback function. - -### Plugin:register_note_post_interruptor(fn) -Modify the data of notes about to be posted. A note object is passed to the callback function as first parameter. The note to be posted will be modified based on the note object returned by the callback function. - -### Plugin:open_url(url) -Opens the URL given as first argument in a new browser tab. - -### Plugin:config -An object containing the plugin settings.The values entered in the plugin definition are saved under the setting keys. diff --git a/src/docs/en-US/custom-emoji.md b/src/docs/en-US/custom-emoji.md deleted file mode 100644 index 0bc94296d..000000000 --- a/src/docs/en-US/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# Custom Emoji -Custom emojis are a function that allows images uploaded to the server to be used like emojis. They can be used in notes, reactions, chat, your profile, your username as well as other places. To use custom emojis in the above mentioned places, press the Emoji picker button (if present) or type a `:` and emoji suggestions will appear. If a string that looks like `:foo:` is found in any text, then the `foo` portion is interpreted as a custom emoji name and will be replaced with said custom emoji picture when displayed. diff --git a/src/docs/en-US/deck.md b/src/docs/en-US/deck.md deleted file mode 100644 index a35f3cad9..000000000 --- a/src/docs/en-US/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# Deck - -Deck is one of the available UI types.By displaying several views called "Columns" next to another, it provides high customizability and can display high amounts of information at once. - -## Adding columns -You can add additional columns by right-clicking the Deck background and pressing "Add column". - -## Moving columns -You can switch the positions of two columns via drag-and-dropping them or change a column's position from its column menu (accesible by right-clicking the column header). - -## Horizontally dividing columns -Columns can not only be arranged vertically, but also horizontally. If you click "Stack on left column" when opening the column menu, the column will be moved below the column to the left of the current one. To cancel the stacking, press the "Pop to the right" button in the column menu. - -## Column settings -You can edit individual column settings by clicking "Edit" in the column menu.You can edit a column's name and width. - -## Deck settings -Deck-related settings can be found in [settings/deck](/settings/deck). diff --git a/src/docs/en-US/features/antenna.md b/src/docs/en-US/features/antenna.md deleted file mode 100644 index 6c4fd8ad6..000000000 --- a/src/docs/en-US/features/antenna.md +++ /dev/null @@ -1,4 +0,0 @@ -# Antennas -Antennas are a feature through which you can automatically collect notes meeting freely specified conditions. - -If a note meeting the conditions of an existing antenna is posted, this note will be added to the timeline of that antenna in real-time. diff --git a/src/docs/en-US/features/custom-emoji.md b/src/docs/en-US/features/custom-emoji.md deleted file mode 100644 index 2bef4a563..000000000 --- a/src/docs/en-US/features/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# Custom Emoji -カスタム絵文字は、インスタンスで用意された画像を絵文字のように使える機能です。 ノート、リアクション、チャット、自己紹介、名前などの場所で使うことができます。 カスタム絵文字をそれらの場所で使うには、絵文字ピッカーボタン(ある場合)を押すか、`:`を入力して絵文字サジェストを表示します。 テキスト内に`:foo:`のような形式の文字列が見つかると、`foo`の部分がカスタム絵文字名と解釈され、表示時には対応したカスタム絵文字に置き換わります。 diff --git a/src/docs/en-US/features/deck.md b/src/docs/en-US/features/deck.md deleted file mode 100644 index 73e9efdaa..000000000 --- a/src/docs/en-US/features/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# Deck - -デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。 - -## カラムの追加 -デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。 - -## カラムの移動 -カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。 - -## カラムの水平分割 -カラムは左右だけでなく、上下に並べることもできます。 カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 上下分割を解除するには、カラムメニューの「右に出す」を選択します。 - -## カラムの設定 -カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。 - -## デッキの設定 -デッキに関する設定は、[settings/deck](/settings/deck)で行えます。 diff --git a/src/docs/en-US/features/drive.md b/src/docs/en-US/features/drive.md deleted file mode 100644 index c4a51f6e8..000000000 --- a/src/docs/en-US/features/drive.md +++ /dev/null @@ -1,17 +0,0 @@ -# Drive -Drive is a feature to manage the files you have uploaded to Misskey. - -In addition to being able to upload files to your Drive from the [Drive page](/my/drive), any images set as your avatar or those included in your notes will be added to your Drive. - -
⚠️ By deleting a file from your Drive, any note it is attached to will also be deleted.
- -You can always download any file uploaded to your Drive, and also reuse it during the composition of new notes by selecting "Attach from Drive" before posting. - -In addition, you can create folders within your Drive to easen the organization multiple files. - -## NSFW -
ℹ️ This text section itself is not NSFW
- -NSFW ("Not Safe For Work") is a setting that can be applied to files in your Drive. Images with this setting will not be displayed unless explicitly requested by the viewing user. This setting is for example used to prevent an image that would not be suitable at places like one's workplace or in public from being abrubtly displayed to other users. - -This flag can be switched off and on, and may be manually set for images by the discretion of a Moderator. diff --git a/src/docs/en-US/features/favorite.md b/src/docs/en-US/features/favorite.md deleted file mode 100644 index 39e3ceadf..000000000 --- a/src/docs/en-US/features/favorite.md +++ /dev/null @@ -1,4 +0,0 @@ -# Favorites -A feature to register a [note](./node) as part of favorites. These notes can then be viewed in a list in your [Favorites page](./my/favorites). Setting a note as favorite does not notify the author of the note, and your favorites are only visible to you. - -To register a note as part of your favorites, click the "Favorit" button in the menu of the respective note.To remove a note from your favorites, click the "Unfavorite" button in the same menu. diff --git a/src/docs/en-US/features/follow.md b/src/docs/en-US/features/follow.md deleted file mode 100644 index 3e71012b5..000000000 --- a/src/docs/en-US/features/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# Following -ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。 diff --git a/src/docs/en-US/features/keyboard-shortcut.md b/src/docs/en-US/features/keyboard-shortcut.md deleted file mode 100644 index 75018e81f..000000000 --- a/src/docs/en-US/features/keyboard-shortcut.md +++ /dev/null @@ -1,66 +0,0 @@ -# Keyboard shortcuts - -## Global -These shortcuts are usually available anywhere. - - - - - - - - - - - -
ShortcutEffectWhy this key?
P, NCreate a notePost, New, Note
TFocus the latest noteTimeline, Top
Shift + NShow/hide notificationsNotifications
SSearchSearch
H, ?Show helpHelp
- -## 投稿にフォーカスされた状態 - - - - - - - - - - - - - - - - - - -
ShortcutEffectWhy this key?
, K, Shift + Tab上の投稿にフォーカスを移動-
, J, Tab下の投稿にフォーカスを移動-
R返信フォームを開くReply
QRenoteフォームを開くQuote
Ctrl + Q即刻Renoteする(フォームを開かずに)-
E, A, +リアクションフォームを開くEmote, reAction
0~9数字に対応したリアクションをする(対応については後述)-
F, Bお気に入りに登録Favorite, Bookmark
Del, Ctrl + D投稿を削除Delete
M, O投稿に対するメニューを開くMore, Other
SCWで隠された部分を表示 or 隠すShow, See
Escフォーカスを外す-
- -## Renoteフォーム - - - - - - - - - -
ShortcutEffectWhy this key?
EnterRenote-
QExpand formQuote
EscClose form-
- -## リアクションフォーム -デフォルトで「👍」にフォーカスが当たっている状態です。 - - - - - - - - - - - - - -
ShortcutEffectWhy this key?
, K上のリアクションにフォーカスを移動-
, J下のリアクションにフォーカスを移動-
, H, Shift + Tab左のリアクションにフォーカスを移動-
, L, Tab右のリアクションにフォーカスを移動-
Enter, Space, +リアクション確定-
0~9数字に対応したリアクションで確定-
Escリアクションするのをやめる-
diff --git a/src/docs/en-US/features/mfm.md b/src/docs/en-US/features/mfm.md deleted file mode 100644 index 5be2df4f3..000000000 --- a/src/docs/en-US/features/mfm.md +++ /dev/null @@ -1,12 +0,0 @@ -# MFM -MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます。 - -## MFMが使用可能な場所の例 -- ノート本文 -- CW注釈 -- ユーザーの名前 -- ユーザーの自己紹介 - -## 開発者向け情報 -MFMのパーサー実装はライブラリとして公開されており、簡単にクライアントにMFMを組み込むことが可能です。 -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptパーサー実装 diff --git a/src/docs/en-US/features/mute-and-block.md b/src/docs/en-US/features/mute-and-block.md deleted file mode 100644 index a9e8fcc1c..000000000 --- a/src/docs/en-US/features/mute-and-block.md +++ /dev/null @@ -1,41 +0,0 @@ -# Mutes and Blocks -好みではないユーザーがいる場合は、ミュートを行うことでそのユーザーが自分から見えないようにすることができます。 また、より強力な措置として、ブロックを行うことでそのユーザーから自分のコンテンツが見えないようになるほか、自分に対して関わることができないようにすることができます。 ミュートされていることは相手は分かりませんが、ブロックされていることは相手に分かります。どちらを選ぶかはご自身の判断で行ってください。 - -
ℹ️ ミュートとブロックは併用できます。
- -
⚠️ 利用規約に違反するような、迷惑なユーザーがいる場合は運営者に報告することも検討してください。
- -設定>ミュートとブロック から、自分がミュートまたはブロックしているユーザー一覧を確認することができます。 - -## Mute -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -- タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -- そのユーザーからの通知 -- メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 -- など - -ユーザーをミュートするには、対象のユーザーのユーザーページのメニューを開き、「ミュート」ボタンを押します。 - -
ℹ️ ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。
- -## Block -ユーザーをブロックすると、そのユーザーからあなたのコンテンツが見えないようになり、またあなたに対して以下のようなアクションをすることができなくなります。 - -- フォローする -- ユーザーリストに追加する -- 返信する、Renoteする -- リアクションする、アンケートに投票する -- メッセージを送信する -- など - -また、 - -- ブロックする際に既にそのユーザーからフォローされていた場合はフォローが解除されます。 -- ブロックする際に既にそのユーザーがあなたをユーザーリストに入れていた場合はそのリストからあなたが削除されます。 - -ユーザーをブロックするには、対象のユーザーのユーザーページのメニューを開き、「ブロック」ボタンを押します。 - -
⚠️ ブロックを行ったこと自体は相手に通知されませんが、フォローを行ったりなどの上記のアクションが行えなくなるので間接的にブロックされていることは分かります。
- -
⚠️ 相手から自分のコンテンツが見えなくなりますが、相手がアカウントを切り替えたりログアウト状態になれば見ることができます。あくまで簡易的、補助的なものとしてお考えください。
diff --git a/src/docs/en-US/features/mute.md b/src/docs/en-US/features/mute.md deleted file mode 100644 index 306beee57..000000000 --- a/src/docs/en-US/features/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# Mute - -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -* タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -* そのユーザーからの通知 -* メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 - -ユーザーをミュートするには、対象のユーザーのユーザーページに表示されている「ミュート」ボタンを押します。 - -ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。 - -設定>ミュート から、自分がミュートしているユーザー一覧を確認することができます。 diff --git a/src/docs/en-US/features/note.md b/src/docs/en-US/features/note.md deleted file mode 100644 index a835cf09a..000000000 --- a/src/docs/en-US/features/note.md +++ /dev/null @@ -1,54 +0,0 @@ -# Notes -Notes are a central concept within Misskey, and refer to content that may include text, images, surveys and more that has been posted to Misskey. In this context, "to note" is also used as a verb refering to the creation of a note. - -By composing a note, it will be added to the [timeline](./timeline) and become visible by your followers and other users from your server. - -On Misskey, it is also possible to add [Reactions](./reaction) to notes.In addition to that, you can reply to or quote notes. - -By adding a note to your [Favorites](./favorite), you can easily look back at it at a later point in time. - -## Composing notes -To compose a note, press the button with a pencil icon on the upper part of your screen to open the posting form.Enter the content you want to post in the form, and press the "Note" button to publish it. Notes can contain text as well as files such as images or videos and also [Surveys](./poll).In addition, by using [MFM](./mfm) within your text, you can additionally include [Mentions](./mention) and [Hashtags](./hashtag). There are also other settings such as CW or note visibility (explained later). -
ℹ️ If you are on a computer and have an image saved in your clipboard, you can attach it to your note by using the usual paste shortcut within the text box.
-
ℹ️You can also press Ctrl + Enter within the text box to publish your note.
- -## Renote -The act of quoting an existing note, sharing an existing note, or the note created as a result of these acts are all called Renote (or "renoting" as verb). Most of the time, this is used when you want to share a note you like to your own followers, or when you want a share a note that you posted in the past once more. While it is possible to renote the same note multiple times, please be aware that doing so may be seen as annoying by others. -
⚠️If you've set your note's visibility to Followers-only or Direct, then renoting it will not be possible
- -To take back a renote, press the "..." next to the renote timestamp and select "Take back Renote". - -## CW -An abbreviation of "Content Warning", resulting in the content of a note being hidden unless explicitly requested to be shown by a viewing user.It is mainly used to hide the content of long notes or to prevent posting spoilers publicly. To enable CW for a note, press the "Hide content" button (eye icon) in the post form.By doing so a new text input area will appear, where you can write a summary of the content hidden by the CW. - -## Visiblility -It's possible to individually set where your note will be visible (Visibility) for each of your notes.By pressing the icon to the left of the "Note" button in the post form, you can choose from the visibility settings listed below. - -### Public -Your note will be visible to all users and will show up on all timelines (home, local, social, global). -
⚠️ This visibility will be unavailable if your account is silenced.
- -### Home -Your note will be visible to all users, but will not show up on the local, social or global timeline for non-followers. - -### Followers -Your note will only be visible to those that are following you.The note will show up on all timelines of your followers. - -### Direct -Your note will only be visible to individually specified users.The note will show up on all timelines of the specified users. - -### The "Local only" option -If you enable this option, your note won't be federated to remote instances. - -### Visibility comparison - - - - -
PublicHomeFollowersDirect
LTL/STL/GTL of Followers
LTL/STL/GTL of Others
- -## Pin to profile -By pinning a note to your profile it will be constantly displayed on your profile page. To pin a note, open the note menu and press "Pin to profile". It's also possible to pin multiple notes to your profile. - -## Watch -You can get notifications for replies, reactions etc. for a note that is not yours by watching it. To watch a note, select "Watch" from the respective note's menu. diff --git a/src/docs/en-US/features/pages.md b/src/docs/en-US/features/pages.md deleted file mode 100644 index dc5134b94..000000000 --- a/src/docs/en-US/features/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# Pages - -## Variables -Use variables to create dynamic pages. Put { variable-name } in your content to embed the value. For example, if a variable named "thing" has the value ai, the string Hello { thing } world! turns into Hello ai world!. - -Variables are evaluated from top to bottom, so referencing variables before declaring is not possible. For example, when declaring the three variables A, B, C in this order, you can use A or B in C, but you cannot use B or C in A. - -ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。 - -関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。 diff --git a/src/docs/en-US/features/reaction.md b/src/docs/en-US/features/reaction.md deleted file mode 100644 index 41e933923..000000000 --- a/src/docs/en-US/features/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# Reactions -他の人のノートに、絵文字を付けて簡単にあなたの反応を伝えられる機能です。 リアクションするには、ノートの + アイコンをクリックしてピッカーを表示し、絵文字を選択します。 リアクションには[カスタム絵文字](./custom-emoji)も使用できます。 - -## リアクションピッカーのカスタマイズ -ピッカーに表示される絵文字を自分好みにカスタマイズすることができます。 設定の「リアクション」で設定します。 - -## リモート投稿へのリアクションについて -リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。 - -## リモートからのリアクションについて -リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。 diff --git a/src/docs/en-US/features/silence.md b/src/docs/en-US/features/silence.md deleted file mode 100644 index fb588247a..000000000 --- a/src/docs/en-US/features/silence.md +++ /dev/null @@ -1,6 +0,0 @@ -# Silence -"Silence" refers to one of the statuses an account may be in. - -If an account is silenced, the visibility of their notes cannot be set to "Public" anymore. A silenced user will still be able to use the "Home", "Followers" and "Direct" visibility, so their posts will still be visible to their followers in addition to being able to directly visit their profile page, but their posts will not show up on the GTL (Federated timeline) or LTL (Local timeline) anymore. - -Whether an account is silenced or not can be controlled by the moderators of a server. diff --git a/src/docs/en-US/features/theme.md b/src/docs/en-US/features/theme.md deleted file mode 100644 index e9b3406c4..000000000 --- a/src/docs/en-US/features/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# Themes - -テーマを設定して、Misskeyクライアントの見た目を変更できます。 - -## Configuring the theme -設定 > テーマ - -## Creating a theme -テーマコードはJSON5で記述されたテーマオブジェクトです。 テーマは以下のようなオブジェクトです。 -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... A unique theme ID. UUID Recommended. -* `name` ... Theme name -* `author` ... The author of the theme (you!) -* `desc` ... The description of the theme (optional) -* `base` ... 明るいテーマか、暗いテーマか - * `light`にすると明るいテーマになり、`dark`にすると暗いテーマになります。 - * The theme will be inheriting the default values of the theme specified here. -* `props` ... テーマのスタイル定義。これから説明します。 - -### テーマのスタイル定義 -`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 - -#### バリューで使える構文 -* 16進数で表された色 - * 例: `#00ff00` -* `rgb(r, g, b)`形式で表された色 - * 例: `rgb(0, 255, 0)` -* `rgb(r, g, b, a)`形式で表された透明度を含む色 - * 例: `rgba(0, 255, 0, 0.5)` -* 他のキーの値の参照 - * `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。 - * 例: `@panel` -* 定数(後述)の参照 - * `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。 - * 例: `$main` -* 関数(後述) - * `:{関数名}<{引数}<{色}` - -#### Constant -「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 キー名を`$`で始めると、そのキーはCSS変数として出力されません。 - -#### Functions -wip diff --git a/src/docs/en-US/features/timeline.md b/src/docs/en-US/features/timeline.md deleted file mode 100644 index a98d2b8a2..000000000 --- a/src/docs/en-US/features/timeline.md +++ /dev/null @@ -1,31 +0,0 @@ -# Timeline -[Notes](./note) are shown in the timelines. There are several kinds of timelines as mentioned below and each of them displays the different set of notes. Servers might disable some of them. - -## Home -This is where you see posts from users you follow. Often abbreviated as HTL. - -## Local -This is where you see all the posts from the local users, except those with "Home" visibility. Often abbreviated as LTL. - -## Social -This is where you see the posts from users you follow AND all the posts from the local users, except those with "Home" visibility. Often abbreviated as STL. - -## Global -This is where you see the posts from the local users and the remote users in federated servers, except those with "Home" visibility. Often abbreviated as GTL. - -## Comparison -| Source | | | Timeline | | | -| ----------------------------- | ----------- | ---- | -------- | ------ | ------ | -| Users | Visiblility | Home | Local | Social | Global | -| Local users you follow | Publish | ✔ | ✔ | ✔ | ✔ | -| | Home | ✔ | | ✔ | | -| | Followers | ✔ | ✔ | ✔ | ✔ | -| Remote users you follow | Publish | ✔ | | ✔ | ✔ | -| | Home | ✔ | | ✔ | | -| | Followers | ✔ | | ✔ | ✔ | -| Local users you don't follow | Publish | | ✔ | ✔ | ✔ | -| | Home | | | | | -| | Followers | | | | | -| Remote users you don't follow | Publish | | | | ✔ | -| | Home | | | | | -| | Followers | | | | | diff --git a/src/docs/en-US/features/widgets.md b/src/docs/en-US/features/widgets.md deleted file mode 100644 index ba301273c..000000000 --- a/src/docs/en-US/features/widgets.md +++ /dev/null @@ -1,7 +0,0 @@ -# Widgets -Widgets are small information displays or operational parts that can be added to the Misskey UI. - -To edit which widgets are displayed, enter the Widget editing mode.Entering this mode can differ based on the used UI. In it you can add, delete, reorganize or change the configuration of individual widgets. - -## List of available widgets -todo diff --git a/src/docs/en-US/features/word-mute.md b/src/docs/en-US/features/word-mute.md deleted file mode 100644 index 77283c862..000000000 --- a/src/docs/en-US/features/word-mute.md +++ /dev/null @@ -1,20 +0,0 @@ -# Word mute -Through setting up word mutes, you can make notes satisfying set conditions not appear on your timeline anymore. - -There are two types of word mutes: soft and hard.Below is an explanation of the setup process and effect of both. - -## Soft word mute -With soft mutes, the word mute is processed within the client (app) you are using. - -When a note meets the set conditions, it will be hidden behind text stating "(username) said something". -You can display the note as it was by clicking on this text. - -## Hard word mute -With hard mutes, the server judges whether the content of a new incoming note meets the set conditions similar to antennas, and will completely exclude it from your timeline if so. - -To summarize, a hard word mute has the following features: - -* Only new notes created after configuration will be affected by the mute. -* If the conditions are changed, previously hard muted notes will still remain muted. -* Timelines will not be filled with "(...) said something". -* Hard mutes will function even for apps without functionality for soft mutes. diff --git a/src/docs/en-US/follow.md b/src/docs/en-US/follow.md deleted file mode 100644 index 781729ebf..000000000 --- a/src/docs/en-US/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# Following -If you follow a user, the posts of that user will appear on your timeline.However, replies from them to other users will not be displayed. To follow a user, click the "Follow" button on their user page.To stop following a user, click the button once more. diff --git a/src/docs/en-US/general/apps.md b/src/docs/en-US/general/apps.md deleted file mode 100644 index 5be276ff3..000000000 --- a/src/docs/en-US/general/apps.md +++ /dev/null @@ -1,6 +0,0 @@ -# List of third-party applications -## Clients -todo - -## Linked services -todo diff --git a/src/docs/en-US/general/changelog.md b/src/docs/en-US/general/changelog.md deleted file mode 100644 index 5a14f9d18..000000000 --- a/src/docs/en-US/general/changelog.md +++ /dev/null @@ -1,5 +0,0 @@ -# Changelog -
ℹ️ This changelog reflects this server's latest version only.To read the changelog for the newest release of Misskey, please check out GitHub.
- - - diff --git a/src/docs/en-US/general/faq.md b/src/docs/en-US/general/faq.md deleted file mode 100644 index 32d363298..000000000 --- a/src/docs/en-US/general/faq.md +++ /dev/null @@ -1,28 +0,0 @@ -# Frequently Asked Questions -This document will list answers to frequently asked questions regarding the usage of Misskey. Answers to frequently asked questions related to Misskey as a project can be found [here](./misskey). - -## "Are there any apps for iOS / Android available?" -While no official Misskey app for either OS exists, there are several third-party applications. For details, please check [here](./apps). - -However, functionality of third-party applications will inevitably lag behind the official Web client, so unless you really want to use a native application, we recommend the official Web client instead. As the Misskey Web client supports PWA, it is also possible to make it act as if it was a native application instead. For details regarding this, please check [here](todo). - -## "Can't I log in through a Mastodon client?" -As Misskey is not compatible with the Mastodon API, barring some exceptions, using Mastodon clients to log into Misskey is not possible. - -## "What do I do when I want to follow users from other servers?" -Select the search bar from the menu and enter their username including their host server. E.g.: `@syuilo@misskey.io` - -## "How do I take back a Renote?" -Press the three dots ("...") displayed next to the renote timestamp and select "Take back Renote". To read more about Renotes, please check [here](../features/note). - -## "I don't want the preview of an URL to be displayed." -You can prevent an URL from being previewed using MFM. Please check the [MFM Cheatsheet](/mfm-cheat-sheet) for more details. - -## "I want to add custom emoji." -Only administrators can add, edit or delete custom emoji. If you'd like to do either of these things, please ask your instance administrator. - -## "I want to develop a Bot." -It is possible to develop a Bot using the Misskey API. Please, [see here](../advanced/develop-bot). - -## Which service does the note translation function use? -[DeepL](https://www.deepl.com/) is being used for this. diff --git a/src/docs/en-US/general/glossary.md b/src/docs/en-US/general/glossary.md deleted file mode 100644 index 12156134a..000000000 --- a/src/docs/en-US/general/glossary.md +++ /dev/null @@ -1,89 +0,0 @@ -# Glossary -A glossary about terms related to Misskey. - -## ActivityPub -The protocol (method) used for enabling the distributed nature of Misskey.By adhering to this protocol, communication with other servers that also follow it becomes possible, forming what is known as the Fediverse. - -## AiScript -A programming language available for use on Misskey.For details, see [here.](../advanced/aiscript) - -## API -An interface that can be used for interacting with Misskey through a program, available for each individiual instance.For details, see [here.](../advanced/api) - -## Bot -An account that is being controlled by a program. - -## CW -An abbreviation of "Content Warning".A feature to hide the content of a note unless explicitly requested to be shown by a user.Mainly used to hide the content of long notes or to prevent posting spoilers publicly. - -## Fediverse -A network of servers composed of various different platforms that communicate with each other, including Misskey. - -## GTL -An abbreviation for "Global TimeLine".For details about timelines, please see [here](../features/timeline). - -## HTL -An abbreviation for "Home TimeLine".For details about timelines, please see [here](../features/timeline) - -## LTL -An abbreviation for "Local TimeLine".For details about timelines, please see [here](../features/timeline) - -## MFM -An abbreviation for "Misskey Flavored Markdown", a markdown language available for use on Misskey.For details, see [here.](../features/mfm) - -## NSFW -An abbreviation for "Not Safe For Work".A feature to tag an image as "NSFW" and hide it unless explicitly requested to be shown by a user. - -## Renote -The act of quoting an existing note, sharing an existing note, or the note created as a result of these acts.For details, see [here.](../features/note) - -## STL -An abbreviation for "Social TimeLine".For details about timelines, please see [here](../features/timeline) - -## Ai -Ai is Misskey's official mascot. - -## Active users -Those users amongst all existing ones who are continually using their account. - -## Instance -todo - -## Custom Emoji -Emoji provided by your server.Emoji that are not specifically provided by your server but are available by default are called "Unicode Emoji". - -## Control Panel -todo - -## Server -todo - -## Silence -A state in which the visibility of the notes by said user cannot be set to "Public" anymore.Can be set for individual users by the discretion of Moderators.For details, see [here.](../features/silence) - -## Job Queue -A system used for sequentially broadcasting activities to other servers etc. - -## Suspend -A state which makes the account of a user unusable. - -## Drive -A feature allowing users to organize the files they have uploaded to Misskey.For details, see [here.](../features/drive) - -## Notes -Content which may include text, images, surveys and others that has been posted to Misskey.For details, see [here.](../features/note) - -## Misskeyist -Users of Misskey. - -## Moderator -Users with the authority to manage the community of a server by deactivating spam accounts, silencing users, deleting inappropriate posts, etc. - -## Remote -Used in context of servers separate from your own.Also used as prefix in other words like "Remote user".The opposite of "Local". - -## Federation -The act of sharing information created on one's server with other servers. - -## Local -Used in context of your own server.Also used as prefix in other words like "Local users", "local timeline".The opposite of "Remote". diff --git a/src/docs/en-US/general/links.md b/src/docs/en-US/general/links.md deleted file mode 100644 index 11a44e894..000000000 --- a/src/docs/en-US/general/links.md +++ /dev/null @@ -1,12 +0,0 @@ -# Links - -## Websites -- [Official Discord](https://discord.gg/Wp8gVStHW3) - The official Discord server for Misskey -- [Misskey Forum](https://forum.misskey.io/) - A forum used for questions surrounding Misskey - -## Accounts -- [@repo@misskey.io](https://misskey.io/@repo) - A bot that publishes posts about updates to the Misskey repository - -## Libraries -- [misskey-dev/misskey.js](https://github.com/misskey-dev/misskey.js) - A Misskey SDK for JavaScript -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - A JavaScript implementation of an MFM Parser diff --git a/src/docs/en-US/general/misskey.md b/src/docs/en-US/general/misskey.md deleted file mode 100644 index 8ae898244..000000000 --- a/src/docs/en-US/general/misskey.md +++ /dev/null @@ -1,86 +0,0 @@ -# About Misskey - -Misskey is an open-source and distributed platform for microblogging. Development was started in 2014 by syuilo in Japan. It features an abundance of features such as Drive or Reactions as well as a very high UI customizability. - -## History -While Misskey started centered around Bulletin Boards as its main feature, the growth in popularity due to the addition of a timeline that let users post short messages and view them in chronological order lead to a gradual shift in the main focus of development towards this kind of functionality. Misskey was not always a decentralized service, but became decentralized through the adoption of ActivityPub in 2018. Since then, it has become a service that is acknowledged and used by many. -
ℹ️ The name "Misskey" comes from a song called "Brain Diver" by a band that syuilo used to listen to at the time called May'n.
- -With anyone being able to join its development, Misskey is still continually being actively developed. - -## What does "Distributed" mean? -A Distributed service, also called a Decentralized service, refers to a service which features the division of a community into many servers that all mutually communicate (federate) with each other to share their contents, building a network (Fediverse). Services for which only one server exists, or for which many independent server exist, are called centralized. Most services fall under the category of centralized, some examples for this are Twitter or Facebook. The advantage of distributed services is being able to select the administration or server theme that suits you freely.It's also possible for you to make your own server.Thanks to the federated nature, you will be able to access the same community, no matter which server you choose. - -## Always Open-Source -Misskey has always been, and will always be, open source.Open source means, simply speaking, making the source code of software (a program) publicly available.This also includes being able to adjust or redistribute the source code in its definition. The entirety of Misskey's source code is [being licensed](https://github.com/misskey-dev) under an open-source license called [AGPL](https://github.com/misskey-dev/misskey/blob/develop/LICENSE), which means anyone can freely inspect, use, adjust, change or redistribute as they see fit. Open source has many merits, including allowing anyone being able to make changes as they like, to make sure the code does not include any harmful components and being able to easily participate in its development. For realizing the distributed nature of Misskey, this concept of open source is indispensable. Using the same example as before, most profit-oriented services like Twitter, Facebook etc. are not open source. - -
ℹ️ Technically speaking, Misskey's source code is being managed via Git, and its repository is being hosted at GitHub.
- -## Joining development and supporting the project -If you like Misskey, please support the project.Supporting the project can be done in many ways, with some of them introduced below.Some of these do not require programming skills, so anyone can feel free to support Misskey their own way.We're always waiting for you. - -### Adding features or fixing bugs -If you possess software engineering skills, you can contribute to the project through editing its source code. For guidelines regarding this, please see [here](https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md). - -### Participating in discussions -You can contribute by sharing your opinion on new or existing features, as well as by reporting bugs. Such discussions can be held at [GitHub](https://github.com/misskey-dev) or the [Forums](https://forum.misskey.io/) etc. - -### Translating text -Misskey is available in many languages (also called i18n, which is an abbreviation for Internationalization).While the original language is generally japanese, volunteers are translating Misskey into other languages. Helping out with this translation work is also a form of contributing. Misskey uses a service called [Crowdin to manage its translations.](https://crowdin.com/project/misskey) - -### Sharing your impressions -Besides reporting bugs, please also feel free to share positive impressions such as which parts of Misskey you personally like, or things about Misskey that you find fun.As things like these serve as motivation for the developers, it also counts as indirect support for the project. - -### Increasing the number of Misskists -"Misskist" refers to the people using Misskey. By spreading the word about Misskey through introducing it to your acquaintances, the number of Misskists may increase, which serves as motivation for the developers. - -### Making donations -Misskey is not a business, and stays free to use by receiving its earnings through donations from everyone.(Depending on the instance, some revenue may be earned through showing advertisments, but these earnings go straight to the instance administrator and not to the developers of Misskey) As donations make it possible for the project to continue to be developed, they are another way of supporting Misskey. Donations are generally accepted via [Patreon](https://www.patreon.com/syuilo). By donating a certain amount of money, you can also have your username displayed on Misskey's [About page](/about-misskey). - -In addition to this, server administrators are also generally speaking not earning revenue.As operating a server costs money, please also consider supporting your server's administrator. This does not have a direct relation to the development of Misskey, but the existence of servers is what makes up the project, meaning the continued existence of servers is just about as important as that of the project itself. - -## Credits -A list of Misskey's developers and donators can be seen [here](/about-misskey). - -## Frequently Asked Questions -### What is this project aiming to achieve? -To put it bluntly, while this is a bit vague, Misskey is aiming to be a widely-used all-purpose platform. Unlike other platforms, Misskey is not grounded in a specific idea (for example, anti-centralization) or vision and being developed with that in mind, so it's a bit "aimless" in this respect. On the other hand though, this creates a flexibility due to not being bound by a specific direction to go towards. - - -### Is Misskey being developed by a company? -No.Misskey is being developed by an individual person and not commercialized through connection with any particular company. Development members are generally volunteers. Additionally, while there are some corporate sponsors, development is still centered around the community. - -### Who is managing Misskey? -Due to the distributed nature of Misskey, each individual server has their own administration.Therefore, not all of Misskey is managed by one individual person or company. This means that, as the development team does not control individual servers, for management-related questions you should contact your server's administration instead. You can verify who is managing your individual server on [this page](/about). If you were to create a server, then you would also become its administrator. - -### Which server should I choose? -[You can find an (incomplete) list of servers here.](https://join.misskey.page/ja-JP/instances) Depending on the server, its community or central theme (for example, liking a show) may vary, so if there is a server that suits your interests, joining it would likely be a good choice. Besides that, server size, userbase, country or spoken language, reliance or trust in the administration team and many other things can also serve as criteria. There is however no single server that serves as the official server of Misskey.You also have the choice of creating a new server of your own. - -Generally speaking, no matter which server you join, you will still be able to connect with users from all other servers. - -### How can I create my own server? -Thank you for having an interest in creating a Misskey server. In the current year of 2021 there is no specialized Misskey hosting service, so creating a new server requires a certain amount of knowledge. Please see [here](todo) for more information regarding this. - -### What kind of technology does Misskey use? -As development on Misskey progressed, the technology it has used has changed greatly.In the beginning, it used a combination of MySQL + PHP + jQuery, but currently uses the following. -- Server-side: Node.js -- Database: PostgreSQL, Redis -- UI Framework: Vue.js -- Programming language: TypeScript - -In addition to this, from Misskey derived technology such as MFM or AiScript are also being used. - -### Is this a fork of Mastodon? -No.Misskey is a project completely different from Mastodon or other alike projects. It has been in development for a long time already.However, it only became a distributed network after the appearance of Mastodon. Besides both projects implementing the ActivityPub protocol, there is no relation between the two. - -### Are there any apps for iOS / Android available? -While no official Misskey app for either OS exists, there are several third-party applications. For details, please check [here](./apps). - -However, functionality of third-party applications will inevitably lag behind the official Web client, so unless you really want to use a native application, we recommend the official Web client instead. As the Misskey Web client supports PWA, it is also possible to make it act as if it was a native application instead. For details regarding this, please check [here](todo). - -### Where can I download Misskey's logo or icon? -(Coming soon) - -### Who's that cute cat-eared girl that you see sometimes? -It's Misskey's guardian deity, Ai.(They called Ai cute, yay!) -
ℹ️ To read more about Ai, check here (Japanese-only).
diff --git a/src/docs/en-US/general/report-issue.md b/src/docs/en-US/general/report-issue.md deleted file mode 100644 index 8df13aef7..000000000 --- a/src/docs/en-US/general/report-issue.md +++ /dev/null @@ -1,8 +0,0 @@ -# Reporting bugs -If you run into situations you believe to be a bug, please check th [Troubleshooting](./troubleshooting) first. In the case that this doesn't solve your issue, please post to the [Forums](https://forum.misskey.io/) including the below information. By doing so a solution may be found or your situation can be noted down as a bug, which means the development team can work on fixing it. - -## Information to include -- Misskey version (Can be seen on the [About page](/about)) -- Type and version of your used browser -- Type and version of your used operating system -- Steps to reproduce your problem diff --git a/src/docs/en-US/general/troubleshooting.md b/src/docs/en-US/general/troubleshooting.md deleted file mode 100644 index 75051debe..000000000 --- a/src/docs/en-US/general/troubleshooting.md +++ /dev/null @@ -1,40 +0,0 @@ -# Troubleshooting -
ℹ️ Please also use the Frequently asked questions page.
- -If you run into a problem, please check this page first. In the case that you can't find your problem here, or the steps described here don't solve your issue, please contact your server's administrator or [Report it as a bug](./report-issue). - -## The client does not start -In most of the cases, this is due your used browser's or operating system's version being outdated. Please try updating your browser or operating system to the latest version and then try again. - -Although this does not happen frequently, if your client will still not start after this, it is possible for the cache to be at fault.In this case, please try clearing your cache and then try again. - -## Pages cannot be loaded -If your client does boot, but you get an error when trying to load a page, please check your network connection for errors.In addition, check that the server you are trying to access is not down. - -Although this does not happen frequently, cases where the cache is at fault can happen.In this case, please try clearing your cache and then try again. - -Any remaining problems are likely related to the server you are trying to access, so please contact its administrator. - -## The client is slow -Please try the following: - -- Activate "Reduce UI animations" in the client settings -- Deactivate "Use blur effect for modals" in the client settings -- Activate hardware acceleration in your browser's settings -- Upgrade the specs of your used device - -## Parts of the UI are weird (For example, the background is transparent) -Broken UI display may be caused by the theme cache system when the UI is changed as part of an update. Pressing "Clear cache" in the settings will fix this. -
⚠️ Specifically clear the "Client's" cache.Don't clear the "Browser's" cache.
- -## The blinking light of a notification or Antenna won't go away -A blinking light indicates unread content.In cases where this light won't go away, there is usually unread content that has been pushed away by new incoming content. If you believe to have read all content, but the light still won't go away (likely a bug), you can forcibly mark all content as read via the user settings. - -## The renote button is blocked out -Followers-only notes cannot be renoted. - -## Specific parts of the UI are not being displayed -Problems like these can arise if you are using an Adblocker. For an optimized experience on Misskey, please turn it off. - -## Some parts of the UI are untranslated -In most cases, this is simply a matter of the translation not having been done yet instead of being a bug.Please wait until the translation of this area has been completed. You can alternatively also [participate in translation](./misskey) yourself. diff --git a/src/docs/en-US/keyboard-shortcut.md b/src/docs/en-US/keyboard-shortcut.md deleted file mode 100644 index fdd606f73..000000000 --- a/src/docs/en-US/keyboard-shortcut.md +++ /dev/null @@ -1,68 +0,0 @@ -# Keyboard shortcuts - -## Global -The shortcuts listed here can be used basically everywhere. - - - - - - - - - - - -
ShortcutEffectOrigin
P, NNew postPost, New, Note
TFocus newest post on timelineTimeline, Top
Shift + NShow/hide notificationsNotifications
SSearchSearch
H, ?Show helpHelp
- -## Shortcuts related to posts - - - - - - - - - - - - - - - - - - - -
ShortcutEffectOrigin
, K, Shift + TabMove focus to above post-
, J, TabMove focus to below post-
ROpen reply formReply
QOpen renote formQuote
Ctrl + QImmediately renote (without opening form)-
E, A, +Open reaction formEmote, reAction
0~9React with the emote in nth place of the reaction picker-
F, BAdd to favoritesFavorite, Bookmark
Del, Ctrl + DDelete postDelete
M, OOpen post context menuMore, Other
SToggle show or hide of content marked with CWShow, See
EscDeselect Note-
- -## Renote form - - - - - - - - - - -
ShortcutEffectOrigin
EnterRenote-
QExpand formQuote
EscClose form-
- -## Reaction form -By default, the "👍" reaction is focused. - - - - - - - - - - - - - -
ShortcutEffectOrigin
, KMove focus to above reaction-
, JMove focus to below reaction-
, H, Shift + TabMove focus to left reaction-
, L, TabMove focus to right reaction-
Enter, Space, +React with focused reaction-
0~9React with the reaction at nth place in the reaction picker-
EscCancel reacting-
diff --git a/src/docs/en-US/mfm.md b/src/docs/en-US/mfm.md deleted file mode 100644 index 2087d076f..000000000 --- a/src/docs/en-US/mfm.md +++ /dev/null @@ -1,2 +0,0 @@ -# MFM -MFM stands for Misskey Flavored Markdown and is a Misskey-exclusive text markup language that can be used in many places. For valid MFM syntax, see the [MFM Cheatsheet](/mfm-cheat-sheet). diff --git a/src/docs/en-US/mute.md b/src/docs/en-US/mute.md deleted file mode 100644 index aa1de29c1..000000000 --- a/src/docs/en-US/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# Mute - -If you mute a user, the following contents related to that user will not be displayed by Misskey anymore: - -* Posts of that user on the timeline or in the search results (including Renotes or replies to related to these posts) -* Notifications from that user -* Chat history with that user in the chat history list - -To mute a user, press the "Mute" button displayed on the user's profile page. - -Users muted by you will not be notified that they have been muted, and will also not know that they have been muted by you. - -You can confirm the list of users you have muted in the settings by going to Settings > Mute / Block diff --git a/src/docs/en-US/pages.md b/src/docs/en-US/pages.md deleted file mode 100644 index aacdb1987..000000000 --- a/src/docs/en-US/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# Pages - -## Variables -You can create dynamic pages using variables.By writing { variable-name } in your text, the value of that variable can be embedded.For example, if the value of the variable thing in the text Hello { thing } world! is ai, then the text will turn into Hello ai world!. - -Variables are evaluated from top to bottom, so referencing variables not yet declared is not possible.For example, when declaring the three variables A, B, C in the given order, referencing A or B from within C is possible, but referencing B or C from within A is not. - -To receive user input on your page, include a "User input" block and set it to store the user's input in a variable name (the variable will automatically be created).You can then activate different actions depending on the user input stored in that variable. - -Using functions allows you to create a reusable way of calculating values.To use functions, create a variable of the type "function".Functions can use slots (arguments), which are then available as variables within the function.In addition, functions whose arguments are functions ("higher-order functions") are also possible.Besides predefining functions, you can also define functions in the slots of higher-order functions on the fly. diff --git a/src/docs/en-US/reaction.md b/src/docs/en-US/reaction.md deleted file mode 100644 index 4826c6e1f..000000000 --- a/src/docs/en-US/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# Reaction -Easily express your feelings about the notes of others by attaching emojis to them. To react to a note, press the "+" icon to display the reaction picker and click on an emoji. You can also use [Custom Emoji](./custom-emoji) as reactions. - -## Customizing the reaction picker -It's possible to customize the emoji picker to display the emojis you want. You can configure it in the "Reactions" settings menu. - -## About reacting to remote posts -Because reactions are a Misskey-original feature, unless the remote instance is also a Misskey instance, reactions to posts will be sent as a "Like" activity.Generally speaking, "Like" functionality seems to be implemented as a "Favorite" feature. In addition, even if the interaction partner is a Misskey instance, custom emoji reactions will not be transmitted and instead fall back to a "👍" reaction or similar. - -## About reactions from remote servers -If a "Like" activity is sent from a remote server, it will be interpreted as a "👍" reaction in Misskey. diff --git a/src/docs/en-US/reversi-bot.md b/src/docs/en-US/reversi-bot.md deleted file mode 100644 index ac017979f..000000000 --- a/src/docs/en-US/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# Development of Misskey Reversi Bots -This page will explain how to develop a bot for Misskey's Reversi function. - -1. Connect to the `games/reversi` stream with the following parameters: - * `i`: API key of the bot account - -2. When an invitation to a game arrives, an `invited` event is emitted from the stream. - * Information about the user who sent the invitation is included in the event as `parent`. - -3. Send a request to `games/reversi/match` including the `id` of the `parent` as `user_id` - -4. If the request suceeds, information about the game will be returned. Then, send a request to the `games/reversi-game` stream with the following parameters: - * `i`: API key of the bot account - * `game`: The `id` of the `game` - -5. In the meanwhile, the opponent can modify the game's settings. Each time this happens, a `update-settings` event is emitted, so implementing logic to handle these events may be necessary. - -6. Once satisfied with the settings, send a `{ type: 'accept' }` message to the stream. - -7. When the game starts, a `started` event is emitted. - * Information about the game's state is included in this event - -8. To place a stone, send `{ type: 'set', pos: }` to the stream (how to calculate positions will be explained later). - -9. When the opponent or you place a stone, the `set` event is emitted. - * Contains the color of the placed stone as `color` - * Contains the position the stone was placed at as `pos` - -## Calculating positions -In the case of an 8x8 map, the fields of the board are arranged like this (fields are marked with their respective index): -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### Find indices from X, Y coordinates -``` -pos = x + (y * mapWidth) -``` -`mapWidth` can be acquired from the `map` information as follows: -``` -mapWidth = map[0].length -``` - -### Find X, Y coordinates from indices -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## Map information -Map data is included within `map` of the game data. As the data is represented as an array of strings, each character represents a field. Based on this data, you can reconstruct the map state: -* `(Empty)` ... No field -* `-` ... Field -* `b` ... Piece placed first was black -* `w` ... Piece placed first was white - -For example, suppose a situation with the following 4*4 board: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -In this case, the map data look like this: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## Creating a bot that can interact with the user through forms -To communicate with the user, you can show them a form in the settings screen. For example, to let the user select the strength of the Bot. - -To display a form, send the following message to the `reversi-game` stream: -```javascript -{ - type: 'init-form', - body: [Array of form control fields] -} -``` - -From here on, the structure of form control elements will be explained. Form controls are objects arranged as follows: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... The ID of the control element. `type` ... The type of the control element.Explained later. `label` ... Text displayed alongside the control element. `value` ... Default value of the control element. - -### Handling form interactions -When the user interacts with the form, an `update-form` event is emitted. Included in this event is the control element's ID as well as the value of the setting the user changed. For example, if the user flipped the switch from above to on, the following event would be emitted: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### Types of form control elements -#### Switch -type: `switch` Shows a slider.These can be helpful for functions that can be turned either on or off. - -##### Properties -`label` ... The text written on the switch. - -#### Radio button -type: `radio` Shows a radio button.These can be useful for choices.For example to choose the strength of the Bot. - -##### Properties -`items` ... The options of the radio button.E.g.: -```javascript -items: [{ - label: 'Weak', - value: 1 -}, { - label: 'Moderate', - value: 2 -}, { - label: 'Strong', - value: 3 -}] -``` - -#### Slider -type: `slider` Shows a slider. - -##### Properties -`min` ... The minimum value of the slider. `max` ... The maximum value of the slider. `step` ... The step between each value on the slider. - -#### Textbox -type: `textbox` Shows a textbox.These can be used for all general purposes which require user input. - -## Showing a message to a user -This is another way to interact with the user from the settings screen, separate from showing them a form.It's possible to display a message to the user. For example, when the user selects a map that the bot does not support, a warning can be displayed. To display a message, send the following message to the stream: -```javascript -{ - type: 'message', - body: { - text: 'Message contents', - type: 'Message type' - } -} -``` -Message types: `success`, `info`, `warning`, `error`。 - -## Give up -To give up, send a request to this endpoint. diff --git a/src/docs/en-US/stream.md b/src/docs/en-US/stream.md deleted file mode 100644 index 765aba087..000000000 --- a/src/docs/en-US/stream.md +++ /dev/null @@ -1,354 +0,0 @@ -# Streaming API - -By using the streaming API, you can receive various data (such as new posts arriving on the timeline, receiving direct messages, notifications about being followed, etc) in real-time and perform various different actions based on it. - -## Connecting to streams - -To use the streaming API, you must first connect to the **websocket** of the Misskey server. - -Connect to the websocket located at the below URL, including your credentials within the `i` parameter.E.g.: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -Credentials refer to your own API key or in the case of connecting to the Stream the access token granted to an application by a user. - -
-

To read about acquiring such credentials, please refer to this document.

-
- ---- - -It's possible to omit the credentials and use the Streaming API without logging in, but doing so will limit the data that can be received and the functions that can be used.E.g.: - -``` -%WS_URL%/streaming -``` - ---- - -To connect to the stream, using the later-mentioned API or subscribing to individual posts is possible. At this stage however it is not possible to receive timeline information about things such as new posts arriving yet. To do this, connecting to later-mentioned **Channels** is required. - -**All interactions of sending to and receiving from the Stream are done in JSON format.** - -## Channels -Within the Misskey Streaming API, a concept called Channels exists.These are used for the purpose of separating which data to receive. When first connecting to the Misskey Stream, you can not receive real-time updates yet. By connecting to channels in the stream, both sending and receiving various information related to said channels becomes possible. - -### Connecting to a channel -To connect to a channel, send a message in JSON format like the following to the stream: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -Here, -* `channel` specifies the name of the channel to connect to.A list of valid channels will be given later. -* `id` contains an arbitrary ID for both sending to and receiving from this channel.The stream sends out various different messages, so to differentiate which channel a message came from, such an ID is required.This ID can be something such as an UUID or a simple random number generator output. -* `params` include the parameters for connecting to the channel.Which parameters are required for connecting varies by channel.For channels which do not require any parameters, this property can be omitted. - -
-

These IDs should be unique for each individual connection to a channel, not for each channel only.This is for cases in which multiple different connections with different parameters are made to the same channel.

-
- -### Receiving messages from channels -For example, when an event is emitted in one of the timeline channels due to a new post being made.By receiving such messages, it's possible to become aware of new posts being made in a timeline in real-time. - -When a channel sends a message, a JSON message like the following will be transmitted: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -Here, -* `id` refers to the ID that was previously set when connecting to the channel.Using this, it is possible to figure out which channel a message came from. -* `type` contains the type of this message.Which types of messages are sent varies depending on the channel the message came from. -* `body` contains the actual contents of this message.What kind of data is included varies depending on the channel the message came from. - -### Sending messages to channels -Depending on the channel, it is not only possible to receive messages, but also to send messages to the channel which can then trigger various different actions. - -To send a message to a channel, send a message in JSON format like the following one to the stream: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -Here, -* `id` refers to the ID that was previously set when connecting to the channel.Using this, it is possible to tell for which channel a message is intended. -* `type` sets the type of this message.The types of messages a channel accepts varies depending on the channel the message is being sent to. -* `body` sets the actual contents of the message.The types of content a channel accepts varies depending on which channel it is being sent to. - -### Disconnecting from a channel -To connect to a channel, send a JSON message like the following to the stream: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -Here, -* `id` refers to the ID that was previously set when connecting to the channel. - -## Making API requests via streams - -It is possible to send requests to the API without a HTTP request by using the Stream.Doing so might help with keeping code cleaner and more efficient. - -To send an API request through the stream, send a JSON message like the following to the stream: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -Here, -* `id` must be set to an unique ID with which to identify separate request responses.This can be something such as an UUID or a simple random number generator output. -* `endpoint` contains the API endpoint to which the request is sent. -* `data` contains the endpoint parameters to send. - -
-

Please check the API reference for possible API endpoints and parameters.

-
- -### Receiving responses - -Once you send a request to the API, the stream will send a response message similar to the following: - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -Here, -* the `xxxxxxxxxxxxxxxx` part will normally be replaced with that request's previously set `id`.Due to this, it is easy to tell which response corresponds to which request. -* the actual response data is included as `body`. - -## Post capturing - -Misskey provides a structure called Post capturing".This structure makes it possible to receive events about a targeted post from the stream. - -For example, assume a situation in which a timeline is displayed to a user.Imagine that someone reacts to a post on this timeline. - -Since the client does not have any way of knowing that a certain post has received a reaction, it is not possible to reflect the reaction on this post in real-time. - -To solve this problem, Misskey introduced the feature of Post capturing.If you capture a post, events related to said post will be transmitted in real-time, allowing you to reflect the reaction to it on the timeline immediately. - -### Capturing a post - -To capture a post, send a message like the following to the stream: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -Here, -* the value of `id` must be the `id` of the post to capture. - -Sending this message requests Misskey to capture it and thus events related to this post will start to be emitted. - -For example, when a reaction is added to the post, the following message will be emitted: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -Here, -* the ID of the note that caused the event is included in the `id` of the `body`. -* the type of the event is included in the `type` of the `body`. -* the details of the event are included in the `body` of the `body`. - -#### Types of events - -##### `reacted` -This event is emitted when a reaction is added to the captured post. - -* the type of reaction is included as `reaction`. -* the ID of the user who sent the reaction is included as `userId`. - -E.g.: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -This event is emitted when the captured post is deleted. - -* The date and time of deletion is included within `deletedAt`. - -E.g.: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -This event is emitted when a vote is submitted to a poll attached to the captured post. - -* the ID of the selected option is included as `choice`. -* the ID of the user who sent the vote is included as `userId`. - -E.g.: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### Canceling post capturing - -Once a post is no longer displayed on the screen and events related to it do not need to be received any longer, please cancel post capturing on it. - -Send the following message: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -Here, -* the value of `id` must be the `id` of the post for which to cancel capturing. - -Once you send this message, events related to this post will no longer be transmitted. - -# List of channels -## `main` -Basic information related to the account will be transmitted here.This channel does not have any parameters. - -### List of sent events - -#### `renote` -This event will be emitted when one of your posts is renoted.If you renote your own post, it will not be emitted. - -#### `mention` -This event will be emitted when someone mentions you. - -#### `readAllNotifications` -This event indicates that all your notifications have been set to read.It is expected to be used in cases such as turning off the indicator that there are unread notifications. - -#### `meUpdated` -This event indicates that your profile information has been updated. - -#### `follow` -This event will be emitted when you follow someone. - -#### `unfollow` -This event will be emitted when you unfollow someone. - -#### `followed` -This event will be emitted when someone follows you. - -## `homeTimeline` -Information about posts on the home timeline will be transmitted here.This channel does not have any parameters. - -### List of sent events - -#### `note` -This event will be emitted when a new post arrives in the timeline. - -## `localTimeline` -Information about posts on the local timeline will be transmitted here.This channel does not have any parameters. - -### List of sent events - -#### `note` -This event will be emitted when a new post arrives in the local timeline. - -## `hybridTimeline` -Information about posts on the social timeline will be transmitted here.This channel does not have any parameters. - -### List of sent events - -#### `note` -This event will be emitted when a new post arrives in the social timeline. - -## `globalTimeline` -Information about posts on the global timeline will be transmitted here.This channel does not have any parameters. - -### List of sent events - -#### `note` -This event will be emitted when a new post arrives in the global timeline. diff --git a/src/docs/en-US/theme.md b/src/docs/en-US/theme.md deleted file mode 100644 index 674566b4e..000000000 --- a/src/docs/en-US/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# Themes - -You can change the appearance of the Misskey client by setting a theme. - -## Theme settings -Settings > Themes - -## Creating a theme -Theme codes are saved as a JSON5 object of theme options. Themes are composed of the following options. -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... A unique theme ID.Using an UUID is recommended. -* `name` ... The name of the theme -* `author` ... The creator of the theme -* `desc` ... A description of the theme (optional) -* `base` ... Whether the theme is based on a light or dark theme - * If you set it to `light` the theme will be listed as a light mode theme, if you set it to `dark` it will be listed as a dark mode theme. - * The theme will be inheriting the default values of the theme specified here. -* `props` ... The style definitions of the theme.These will be explained in the following. - -### Theme style definitions -Define the style of the theme within `props`. The keys will become CSS variables names, and the value specifies the content. In addition, the default `props` options are inherited from the base theme. If this theme's `base` is `light`, they will be copied from [_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5), and if it is `dark`, they will be copied from [_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5). In other words, if there is for example no `panel` key contained in `props`, then the value of `panel` from the base theme will be used. - -#### Syntax for values -* Hex colors - * E.g.: `#00ff00` -* RGB colors with `rgb(r, g, b)` syntax - * E.g.: `rgb(0, 255, 0)` -* RGBA colors with `rgb(r, g, b)` syntax - * E.g.: `rgba(0, 255, 0, 0.5)` -* References to values of other keys - * If you write `@{key-name}` the value of the given key will be used.Replace `{key-name}` with the name of the key to reference. - * E.g.: `@panel` -* Constants (see below) - * If you write `${constant-name}` the value of the given constant will be used.Replace `{constant-name}` with the name of the constant to reference. - * E.g.: `$main` -* Functions (see below) - * `:{function-name}<{argument}<{color}` - -#### Constants -In cases where you have a value that you don't want to output as a CSS variable, but want to use it as the value of another CSS variable, you can use a constant. If you prefix the name of a key with a `$`, it will be not be used as a CSS variable, but a referenced value. - -#### Functions -wip diff --git a/src/docs/en-US/timelines.md b/src/docs/en-US/timelines.md deleted file mode 100644 index 09f5031a3..000000000 --- a/src/docs/en-US/timelines.md +++ /dev/null @@ -1,15 +0,0 @@ -# Timeline comparison - -https://docs.google.com/spreadsheets/d/1lxQ2ugKrhz58Bg96HTDK_2F98BUritkMyIiBkOByjHA/edit?usp=sharing - -## Home -Posts of users you are following - -## Local -All posts of local users that are not marked as "Home-only" - -## Social -Posts of users you are following as well as all posts of local users that are not marked as "Home-only" - -## Global -All posts of local users that are not marked as "Home-only" as well as all messages received by the server that are not marked as "Home-only" diff --git a/src/docs/eo-UY/admin/disable-timelines.md b/src/docs/eo-UY/admin/disable-timelines.md deleted file mode 100644 index 6037653e3..000000000 --- a/src/docs/eo-UY/admin/disable-timelines.md +++ /dev/null @@ -1,8 +0,0 @@ -# Malebligo de loka/sociala/malloka templinio -Misskeyでは、LTL/STL/GTLをそれぞれ無効化することができます。有効/無効を切り替えるには、インスタンスコントロールパネルで設定します。 - -LTLやSTLは、そのインスタンス全員の投稿が見れるため、新規のユーザーにとってはユーザーを探す必要がなくなり、興味のあるユーザーを見つけやすいという利点があります。 しかし同時に、フォロー機能が活用されなくなったり、不適切な投稿が目につきやすくなったり、チャットのようになることで内輪感が生じて逆に新規ユーザーが参加しにくくなるといったデメリットも持ち合わせています。 サーバーによってメリット/デメリットどちらが優勢かは異なるので、オプションとして無効にできるようになっています。 もしデメリットの方が上回っていると感じたら、それらのタイムラインを無効化することも検討してください。 - -
⚠️ 無効化を行うと、ユーザーが困惑し、短期的に見て利用者が減る可能性があります。そのため、無効化の際は影響を慎重に検討し、事前に説明してフォローを整える期間を一定程度設けることを推奨します。
- -なお、管理者/モデレーターは、これらのタイムラインの無効化状態は適用されず、引き続き利用することが可能です。 diff --git a/src/docs/eo-UY/admin/faq.md b/src/docs/eo-UY/admin/faq.md deleted file mode 100644 index 5341c0f16..000000000 --- a/src/docs/eo-UY/admin/faq.md +++ /dev/null @@ -1,5 +0,0 @@ -# Oftaj demandoj -ここでは、サーバー管理者向けのよくある質問を掲載しています。 - -## デフォルトテーマを設定したい -現在、デフォルトテーマ設定機能は実装されていません。 diff --git a/src/docs/eo-UY/advanced/aiscript.md b/src/docs/eo-UY/advanced/aiscript.md deleted file mode 100644 index 604d17daa..000000000 --- a/src/docs/eo-UY/advanced/aiscript.md +++ /dev/null @@ -1,7 +0,0 @@ -# AiScript -AiScriptは、Misskeyで使用できるスクリプト言語です。 - -
ℹ️ AiScript実装はMisskeyとは別リポジトリで、オープンソースで公開されています。
- -## 使い方 -AiScriptの構文や組み込み関数などのドキュメントは、[こちら](https://github.com/syuilo/aiscript/tree/master/docs)で公開されています。 diff --git a/src/docs/eo-UY/advanced/api.md b/src/docs/eo-UY/advanced/api.md deleted file mode 100644 index ec21cc619..000000000 --- a/src/docs/eo-UY/advanced/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス、Bot等(以下「アプリケーション」と呼びます)を開発できます。 ストリーミングAPIもあるので、リアルタイム性のあるアプリケーションを作ることも可能です。 - -APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。 - -## アクセストークンの取得 -基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。 - -* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む -* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む - -### 自分自身のアクセストークンを手動発行する -「設定 > API」で、自分のアクセストークンを発行できます。 - -[「APIの使い方」へ進む](#APIの使い方) - -### アプリケーション利用者にアクセストークンの発行をリクエストする -アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。 - -#### Step 1 - -UUIDを生成する。以後これをセッションIDと呼びます。 - -> このセッションIDは毎回生成し、使いまわさないようにしてください。 - -#### Step 2 - -`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。 -> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます: -* `name` ... アプリケーション名 - * > 例: `MissDeck` -* `icon` ... URL de ikono de la programo - * > 例: `https://missdeck.example.com/icon.png` -* `callback` ... 認証が終わった後にリダイレクトするURL - * > 例: `https://missdeck.example.com/callback` - * リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます -* `permission` ... アプリケーションが要求する権限 - * > 例: `write:notes,write:following,read:drive` - * 要求する権限を`,`で区切って列挙します - * どのような権限があるかは[APIリファレンス](/api-doc)で確認できます - -#### Step 3 -ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。 - -レスポンスに含まれるプロパティ: -* `token` ... ユーザーのアクセストークン -* `user` ... Informoj de uzanto - -[「APIの使い方」へ進む](#APIの使い方) - -## Uzado de API -**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。 - -* [APIリファレンス](/api-doc) -* [ストリーミングAPI](./stream) diff --git a/src/docs/eo-UY/advanced/create-plugin.md b/src/docs/eo-UY/advanced/create-plugin.md deleted file mode 100644 index 7ed29bb82..000000000 --- a/src/docs/eo-UY/advanced/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# Krei kromaĵo -Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。 - -## Metadatumoj -プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。 - -### name -Nomo de kromaĵo - -### author -プラグイン作者 - -### version -Versio de kromaĵo.数値を指定してください。 - -### description -プラグインの説明 - -### permissions -プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。 - -### config -プラグインの設定情報を表すオブジェクト。 キーに設定名、値に以下のプロパティを含めます。 - -#### type -設定値の種類を表す文字列。以下から選択します。 string number boolean - -#### label -ユーザーに表示する設定名 - -#### description -設定の説明 - -#### default -設定のデフォルト値 - -## APIリファレンス -AiScript標準で組み込まれているAPIは掲載しません。 - -### Mk:dialog(title text type) -ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。 - -### Mk:confirm(title text type) -確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。 - -### Mk:api(endpoint params) -Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。 - -### Mk:save(key value) -任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。 - -### Mk:load(key) -Mk:saveで永続化した指定の名前の値を読み取ります。 - -### Plugin:register_post_form_action(title fn) -投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。 - -### Plugin:register_note_action(title fn) -ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 - -### Plugin:register_user_action(title fn) -ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。 - -### Plugin:register_note_view_interruptor(fn) -UIに表示されるノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:register_note_post_interruptor(fn) -ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:open_url(url) -第一引数に渡されたURLをブラウザの新しいタブで開きます。 - -### Plugin:config -プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。 diff --git a/src/docs/eo-UY/advanced/develop-bot.md b/src/docs/eo-UY/advanced/develop-bot.md deleted file mode 100644 index 0ea99c1bb..000000000 --- a/src/docs/eo-UY/advanced/develop-bot.md +++ /dev/null @@ -1,6 +0,0 @@ -# Evoluigi robotan uzanton -[Misskey API](./api)を利用してBotの開発が可能です。 また、いくつかのBot実装が公開されているため、ぜひ参考にしてください。 - -- [syuilo/ai](https://github.com/syuilo/ai) ... Node.js上で動く、TypeScript製Bot実装 - -Botを作成したときは、プロフィール設定からBotフラグをオンにしておくことを強くおすすめします。 diff --git a/src/docs/eo-UY/advanced/reversi-bot.md b/src/docs/eo-UY/advanced/reversi-bot.md deleted file mode 100644 index 7ab2a7212..000000000 --- a/src/docs/eo-UY/advanced/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# MisskeyリバーシBotの開発 -Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。 - -1. `games/reversi`ストリームに以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - -2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる - * イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている - -3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する - -4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - * `game`: `game`の`id` - -5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う - -6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する - -7. ゲームが開始すると、`started`イベントが流れてくる - * イベントの中身にはゲーム情報が含まれている - -8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述) - -9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる - * `color`として石の色が含まれている - * `pos`として位置情報が含まれている - -## 位置の計算法 -8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### X,Y座標 から インデックス に変換する -``` -pos = x + (y * mapWidth) -``` -`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます: -``` -mapWidth = map[0].length -``` - -### インデックス から X,Y座標 に変換する -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## マップ情報 -マップ情報は、ゲーム情報の`map`に入っています。 文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 それをもとにマップのデザインを知る事が出来ます: -* `(スペース)` ... マス無し -* `-` ... マス -* `b` ... 初期配置される黒石 -* `w` ... 初期配置される白石 - -例えば、4*4の次のような単純なマップがあるとします: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -この場合、マップデータはこのようになります: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## ユーザーにフォームを提示して対話可能Botを作成する -ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。 - -フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します: -```javascript -{ - type: 'init-form', - body: [フォームコントロールの配列] -} -``` - -フォームコントロールの配列については今から説明します。 フォームコントロールは、次のようなオブジェクトです: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... コントロールのID。 `type` ... コントロールの種類。後述します。 `label` ... コントロールと一緒に表記するテキスト。 `value` ... コントロールのデフォルト値。 - -### フォームの操作を受け取る -ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### フォームコントロールの種類 -#### スイッチ -type: `switch` スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。 - -##### プロパティ -`label` ... スイッチに表記するテキスト。 - -#### ラジオボタン -type: `radio` ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。 - -##### プロパティ -`items` ... ラジオボタンの選択肢。例: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '強', - value: 3 -}] -``` - -#### スライダー -type: `slider` スライダーを表示します。 - -##### プロパティ -`min` ... スライダーの下限。 `max` ... スライダーの上限。 `step` ... 入力欄で刻むステップ値。 - -#### テキストボックス -type: `textbox` テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。 - -## ユーザーにメッセージを表示する -設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 メッセージを表示するには、次のメッセージをストリームに送信します: -```javascript -{ - type: 'message', - body: { - text: 'メッセージ内容', - type: 'メッセージの種類' - } -} -``` -メッセージの種類: `success`, `info`, `warning`, `error`。 - -## 投了する -投了をするには、このエンドポイントにリクエストします。 diff --git a/src/docs/eo-UY/advanced/share-page.md b/src/docs/eo-UY/advanced/share-page.md deleted file mode 100644 index b1959b4d6..000000000 --- a/src/docs/eo-UY/advanced/share-page.md +++ /dev/null @@ -1,54 +0,0 @@ -# La paĝo nur por skribi novan noton -`/share`を開くと、共有用の投稿フォームを開くことができます。 ここではシェアページで利用できるクエリ文字列の一覧を示します。 - -## La listo de la tekstoj por informpeti -### Teksto - -
-
title
-
Tio estas titolo.本文の先頭に[ … ]と挿入されます。
-
text
-
Tio estas teksto
-
url
-
Tio estas URL.末尾に挿入されます。
-
- -### La informo por respondi -以下のいずれか - -
-
replyId
-
リプライ先のノートid
-
replyUri
-
リプライ先のUrl(リモートのノートオブジェクトを指定)
-
- -### La informo por plusendi noton -以下のいずれか - -
-
renoteId
-
la ID de la noto plusendota
-
renoteUri
-
la URL de la noto plusendota el fora nodo
-
- -### Videbleco -※specifiedに相当する値はvisibility=specifiedとvisibleAccts/visibleUserIdsで指定する - -
-
visibility
-
公開範囲 ['public' | 'home' | 'followers' | 'specified']
-
localOnly
-
0(false) or 1(true)
-
visibleUserIds
-
specified時のダイレクト先のユーザーid カンマ区切りで
-
visibleAccts
-
specified時のダイレクト先のacct(@?username[@host]) カンマ区切りで
-
- -### Dosieroj -
-
fileIds
-
La ID-oj de viaj aldonotaj dosieroj (devas esti apartigita de komoj)
-
diff --git a/src/docs/eo-UY/advanced/stream.md b/src/docs/eo-UY/advanced/stream.md deleted file mode 100644 index 9f5cdbbcb..000000000 --- a/src/docs/eo-UY/advanced/stream.md +++ /dev/null @@ -1,350 +0,0 @@ -# API de Flui - -ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。 - -## ストリームに接続する - -ストリーミングAPIを利用するには、まずMisskeyサーバーに**websocket**接続する必要があります。 - -以下のURLに、`i`というパラメータ名で認証情報を含めて、websocket接続してください。例: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。 - -
ℹ️ 認証情報の取得については、こちらのドキュメントをご確認ください。
- ---- - -認証情報は省略することもできますが、その場合非ログインでの利用ということになり、受信できる情報や可能な操作は限られます。例: - -``` -%WS_URL%/streaming -``` - ---- - -ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。 - -**ストリームでのやり取りはすべてJSONです。** - -## Kanalo -MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。 - -ひとつのストリーム上で、同時に複数のチャンネルに接続することができます。 - -### チャンネルに接続する -チャンネルに接続するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -ここで、 -* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。 -* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。 -* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。 - -
ℹ️ IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。
- -### チャンネルからのメッセージを受け取る -例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。 - -チャンネルがメッセージを発すると、次のようなデータがJSONでストリームに流れてきます: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。 -* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。 -* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。 - -### チャンネルに向けてメッセージを送信する -チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。 - -チャンネルにメッセージを送信するには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。 -* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。 -* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。 - -### チャンネルから切断する -チャンネルから切断するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。 - -## ストリームを経由してAPIリクエストする - -ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。 - -ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -ここで、 -* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 -* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 -* `data`には、エンドポイントのパラメータを含めます。 - -
ℹ️ APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。
- -### レスポンスの受信 - -APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。 - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -ここで、 -* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 -* `body`には、レスポンスが含まれています。 - -## 投稿のキャプチャ - -Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。 - -例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。 - -しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。 - -この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。 - -### 投稿をキャプチャする - -投稿をキャプチャするには、ストリームに次のようなメッセージを送信します: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャしたい投稿の`id`を設定します。 - -このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 - -例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -ここで、 -* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。 -* `body`内の`type`に、イベントの種類が設定されます。 -* `body`内の`body`に、イベントの詳細が設定されます。 - -#### イベントの種類 - -##### `reacted` -その投稿にリアクションがされた時に発生します。 - -* `reaction`に、リアクションの種類が設定されます。 -* `userId`に、リアクションを行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -その投稿が削除された時に発生します。 - -* `deletedAt`に、削除日時が設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -その投稿に添付されたアンケートに投票された時に発生します。 - -* `choice`に、選択肢IDが設定されます。 -* `userId`に、投票を行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### 投稿のキャプチャを解除する - -その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。 - -次のメッセージを送信します: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャを解除したい投稿の`id`を設定します。 - -このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 - -# チャンネル一覧 -## `main` -アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `renote` -自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。 - -#### `mention` -誰かからメンションされたときに発生するイベントです。 - -#### `readAllNotifications` -自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。 - -#### `meUpdated` -自分の情報が更新されたことを表すイベントです。 - -#### `follow` -自分が誰かをフォローしたときに発生するイベントです。 - -#### `unfollow` -自分が誰かのフォローを解除したときに発生するイベントです。 - -#### `followed` -自分が誰かにフォローされたときに発生するイベントです。 - -## `homeTimeline` -ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -タイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `localTimeline` -ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `hybridTimeline` -ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ソーシャルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `globalTimeline` -グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 diff --git a/src/docs/eo-UY/aiscript.md b/src/docs/eo-UY/aiscript.md deleted file mode 100644 index 6c28b446e..000000000 --- a/src/docs/eo-UY/aiscript.md +++ /dev/null @@ -1,4 +0,0 @@ -# AiScript - -## 関数 -デフォルトで値渡しです。 diff --git a/src/docs/eo-UY/api.md b/src/docs/eo-UY/api.md deleted file mode 100644 index 76019b614..000000000 --- a/src/docs/eo-UY/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス、Bot等(以下「アプリケーション」と呼びます)を開発できます。 ストリーミングAPIもあるので、リアルタイム性のあるアプリケーションを作ることも可能です。 - -APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。 - -## アクセストークンの取得 -基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。 - -* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む -* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む - -### 自分自身のアクセストークンを手動発行する -「設定 > API」で、自分のアクセストークンを発行できます。 - -[「APIの使い方」へ進む](#APIの使い方) - -### アプリケーション利用者にアクセストークンの発行をリクエストする -アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。 - -#### Step 1 - -UUIDを生成する。以後これをセッションIDと呼びます。 - -> このセッションIDは毎回生成し、使いまわさないようにしてください。 - -#### Step 2 - -`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。 -> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます: -* `name` ... アプリケーション名 - * > 例: `MissDeck` -* `icon` ... アプリケーションのアイコン画像URL - * > 例: `https://missdeck.example.com/icon.png` -* `callback` ... 認証が終わった後にリダイレクトするURL - * > 例: `https://missdeck.example.com/callback` - * リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます -* `permission` ... アプリケーションが要求する権限 - * > 例: `write:notes,write:following,read:drive` - * 要求する権限を`,`で区切って列挙します - * どのような権限があるかは[APIリファレンス](/api-doc)で確認できます - -#### Step 3 -ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。 - -レスポンスに含まれるプロパティ: -* `token` ... ユーザーのアクセストークン -* `user` ... ユーザーの情報 - -[「APIの使い方」へ進む](#APIの使い方) - -## APIの使い方 -**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。 - -* [APIリファレンス](/api-doc) -* [ストリーミングAPI](./stream) diff --git a/src/docs/eo-UY/create-plugin.md b/src/docs/eo-UY/create-plugin.md deleted file mode 100644 index 0d2fa1917..000000000 --- a/src/docs/eo-UY/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# プラグインの作成 -Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。 - -## メタデータ -プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。 - -### name -プラグイン名 - -### author -プラグイン作者 - -### version -プラグインバージョン。数値を指定してください。 - -### description -プラグインの説明 - -### permissions -プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。 - -### config -プラグインの設定情報を表すオブジェクト。 キーに設定名、値に以下のプロパティを含めます。 - -#### type -設定値の種類を表す文字列。以下から選択します。 string number boolean - -#### label -ユーザーに表示する設定名 - -#### description -設定の説明 - -#### default -設定のデフォルト値 - -## APIリファレンス -AiScript標準で組み込まれているAPIは掲載しません。 - -### Mk:dialog(title text type) -ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。 - -### Mk:confirm(title text type) -確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。 - -### Mk:api(endpoint params) -Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。 - -### Mk:save(key value) -任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。 - -### Mk:load(key) -Mk:saveで永続化した指定の名前の値を読み取ります。 - -### Plugin:register_post_form_action(title fn) -投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。 - -### Plugin:register_note_action(title fn) -ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 - -### Plugin:register_user_action(title fn) -ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。 - -### Plugin:register_note_view_interruptor(fn) -UIに表示されるノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:register_note_post_interruptor(fn) -ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:open_url(url) -第一引数に渡されたURLをブラウザの新しいタブで開きます。 - -### Plugin:config -プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。 diff --git a/src/docs/eo-UY/custom-emoji.md b/src/docs/eo-UY/custom-emoji.md deleted file mode 100644 index ab8c6c7f1..000000000 --- a/src/docs/eo-UY/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# Personecigitaj emoĵioj -カスタム絵文字は、インスタンスで用意された画像を絵文字のように使える機能です。 ノート、リアクション、チャット、自己紹介、名前などの場所で使うことができます。 カスタム絵文字をそれらの場所で使うには、絵文字ピッカーボタン(ある場合)を押すか、`:`を入力して絵文字サジェストを表示します。 テキスト内に`:foo:`のような形式の文字列が見つかると、`foo`の部分がカスタム絵文字名と解釈され、表示時には対応したカスタム絵文字に置き換わります。 diff --git a/src/docs/eo-UY/deck.md b/src/docs/eo-UY/deck.md deleted file mode 100644 index 8057e262f..000000000 --- a/src/docs/eo-UY/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# デッキ - -デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。 - -## カラムの追加 -デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。 - -## カラムの移動 -カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。 - -## カラムの水平分割 -カラムは左右だけでなく、上下に並べることもできます。 カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 上下分割を解除するには、カラムメニューの「右に出す」を選択します。 - -## カラムの設定 -カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。 - -## デッキの設定 -デッキに関する設定は、[settings/deck](/settings/deck)で行えます。 diff --git a/src/docs/eo-UY/features/antenna.md b/src/docs/eo-UY/features/antenna.md deleted file mode 100644 index b315a462f..000000000 --- a/src/docs/eo-UY/features/antenna.md +++ /dev/null @@ -1,4 +0,0 @@ -# Antenoj -アンテナは、自由に条件を設定して、合致するノートを自動で収集することができる機能です。 - -条件を設定したアンテナが作成された状態で、条件に合致するノートが投稿されると、リアルタイムでそのアンテナのタイムラインにノートが追加されます。 diff --git a/src/docs/eo-UY/features/custom-emoji.md b/src/docs/eo-UY/features/custom-emoji.md deleted file mode 100644 index ab8c6c7f1..000000000 --- a/src/docs/eo-UY/features/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# Personecigitaj emoĵioj -カスタム絵文字は、インスタンスで用意された画像を絵文字のように使える機能です。 ノート、リアクション、チャット、自己紹介、名前などの場所で使うことができます。 カスタム絵文字をそれらの場所で使うには、絵文字ピッカーボタン(ある場合)を押すか、`:`を入力して絵文字サジェストを表示します。 テキスト内に`:foo:`のような形式の文字列が見つかると、`foo`の部分がカスタム絵文字名と解釈され、表示時には対応したカスタム絵文字に置き換わります。 diff --git a/src/docs/eo-UY/features/deck.md b/src/docs/eo-UY/features/deck.md deleted file mode 100644 index a92e6162b..000000000 --- a/src/docs/eo-UY/features/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# Kartaro - -デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。 - -## カラムの追加 -デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。 - -## カラムの移動 -カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。 - -## カラムの水平分割 -カラムは左右だけでなく、上下に並べることもできます。 カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 上下分割を解除するには、カラムメニューの「右に出す」を選択します。 - -## カラムの設定 -カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。 - -## デッキの設定 -デッキに関する設定は、[settings/deck](/settings/deck)で行えます。 diff --git a/src/docs/eo-UY/features/drive.md b/src/docs/eo-UY/features/drive.md deleted file mode 100644 index ef654688e..000000000 --- a/src/docs/eo-UY/features/drive.md +++ /dev/null @@ -1,17 +0,0 @@ -# Disko -ドライブは、Misskey上でファイルを管理できる機能です。 - -[ドライブのページ](/my/drive)から任意のファイルをアップロードできるほか、アバターに設定した画像や、ノートに添付したファイルなどもすべてドライブにアップロードされます。 - -
⚠️ ドライブからファイルを削除すると、そのファイルが添付されたノートも消えます。
- -ドライブにアップロードされたファイルは、いつでもダウンロードすることができるほか、ノート作成時に「ドライブからファイルを添付」することでファイルを再利用することもできます。 - -ドライブ内にフォルダを作り、複数のファイルをまとめて整理することもできます。 - -## 閲覧注意 (NSFW) -
ℹ️ この項目が閲覧注意なわけではありません
- -閲覧注意またはNSFW (Not safe for work) は、ドライブのファイルに設定することができるフラグです。 閲覧注意フラグを設定されたファイルは、表示される際に閲覧者の操作なしには表示されなくなります。 このフラグは、例えば職場や公共の場で閲覧するのに適切でないと思われる画像などに設定し、そのような画像が突然表示されてしまうことを防ぐ目的で使われます。 - -このフラグは手動でオンオフを切り替えられるほか、モデレーターの判断で設定される場合もあります。 diff --git a/src/docs/eo-UY/features/favorite.md b/src/docs/eo-UY/features/favorite.md deleted file mode 100644 index 747c871a5..000000000 --- a/src/docs/eo-UY/features/favorite.md +++ /dev/null @@ -1,4 +0,0 @@ -# Preferaĵoj -[ノート](./node)をお気に入りとして登録できる機能です。 お気に入り登録したノートは、[お気に入りページ](./my/favorites)で一覧することができます。 お気に入りに登録したことは相手に通知されず、お気に入りは自分しか見ることができません。 - -ノートをお気に入り登録するには、ノートメニューの「お気に入り」を押します。お気に入り解除するには、ノートメニューの「お気に入り解除」を押します。 diff --git a/src/docs/eo-UY/features/follow.md b/src/docs/eo-UY/features/follow.md deleted file mode 100644 index 69f6b9631..000000000 --- a/src/docs/eo-UY/features/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# Sekvatoj -ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。 diff --git a/src/docs/eo-UY/features/keyboard-shortcut.md b/src/docs/eo-UY/features/keyboard-shortcut.md deleted file mode 100644 index 413bef16c..000000000 --- a/src/docs/eo-UY/features/keyboard-shortcut.md +++ /dev/null @@ -1,66 +0,0 @@ -# Fulmoklavoj - -## Malloka -これらのショートカットは基本的にどこでも使えます。 - - - - - - - - - - - -
FulmoklavojRezultatoDeveno (angla)
P, NSkribi novan notonPost, New, Note
Tタイムラインの最も新しい投稿にフォーカスTimeline, Top
Shift + NMalfermi sekcio de sciigojNotifications
SSerĉiSearch
H, ?Montru helponHelp
- -## 投稿にフォーカスされた状態 - - - - - - - - - - - - - - - - - - -
FulmoklavojRezultatoDeveno (angla)
, K, Shift + Tab上の投稿にフォーカスを移動-
, J, Tab下の投稿にフォーカスを移動-
R返信フォームを開くReply
QRenoteフォームを開くQuote
Ctrl + QTuj plusendos (sen la fasado)-
E, A, +リアクションフォームを開くEmote, reAction
0-9数字に対応したリアクションをする(対応については後述)-
F, BAldoni al vian liston de preferaĵojFavorite, Bookmark
Del, Ctrl + DForviŝi la notonDelete
M, OMalfelmi poŝtaĵan menuonMore, Other
SCWで隠された部分を表示 or 隠すShow, See
Escフォーカスを外す-
- -## Renoteフォーム - - - - - - - - - -
FulmoklavojEfektojDeveno (angla)
EnterPlusendi-
QMalfermi sekcioQuote
Escフォームを閉じる-
- -## Elektilo de reago -デフォルトで「👍」にフォーカスが当たっている状態です。 - - - - - - - - - - - - - -
FulmoklavojRezultatoDeveno (angla)
, K上のリアクションにフォーカスを移動-
, J下のリアクションにフォーカスを移動-
, H, Shift + Tab左のリアクションにフォーカスを移動-
, L, Tab右のリアクションにフォーカスを移動-
Enter, Space, +リアクション確定-
0-9数字に対応したリアクションで確定-
Escリアクションするのをやめる-
diff --git a/src/docs/eo-UY/features/mfm.md b/src/docs/eo-UY/features/mfm.md deleted file mode 100644 index 3389cb499..000000000 --- a/src/docs/eo-UY/features/mfm.md +++ /dev/null @@ -1,12 +0,0 @@ -# MFM -MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます。 - -## MFMが使用可能な場所の例 -- Teksto de notoj -- CW注釈 -- La nomo de uzantoj -- Sinprezento en la profilo de la uzanto - -## Informoj por programistoj -MFMのパーサー実装はライブラリとして公開されており、簡単にクライアントにMFMを組み込むことが可能です。 -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptパーサー実装 diff --git a/src/docs/eo-UY/features/mute-and-block.md b/src/docs/eo-UY/features/mute-and-block.md deleted file mode 100644 index d45a793e8..000000000 --- a/src/docs/eo-UY/features/mute-and-block.md +++ /dev/null @@ -1,41 +0,0 @@ -# Silentigitoj kaj blokitoj -好みではないユーザーがいる場合は、ミュートを行うことでそのユーザーが自分から見えないようにすることができます。 また、より強力な措置として、ブロックを行うことでそのユーザーから自分のコンテンツが見えないようになるほか、自分に対して関わることができないようにすることができます。 ミュートされていることは相手は分かりませんが、ブロックされていることは相手に分かります。どちらを選ぶかはご自身の判断で行ってください。 - -
ℹ️ ミュートとブロックは併用できます。
- -
⚠️ 利用規約に違反するような、迷惑なユーザーがいる場合は運営者に報告することも検討してください。
- -設定>ミュートとブロック から、自分がミュートまたはブロックしているユーザー一覧を確認することができます。 - -## Silentigi -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -- タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -- そのユーザーからの通知 -- メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 -- など - -ユーザーをミュートするには、対象のユーザーのユーザーページのメニューを開き、「ミュート」ボタンを押します。 - -
ℹ️ ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。
- -## Bloki -ユーザーをブロックすると、そのユーザーからあなたのコンテンツが見えないようになり、またあなたに対して以下のようなアクションをすることができなくなります。 - -- Eksekvi -- Aldoni al listo de uzantoj -- Respondi aŭ plusendi -- Reagi aŭ voĉi -- Senti mesaĝon -- k.t.p - -また、 - -- Se la uzanto jam sekvas vin kiam vi blokas, la uzanto ĉesos sekvi. -- Se la uzanto jam aldonis vin al listo de uzantoj kiam vi blokas, oni forigos vin de la listo - -Por bloki uzanton klaku la butonon "Bloki" el la menuo de uzula paĝo de specifa uzanto. - -
⚠️ ブロックを行ったこと自体は相手に通知されませんが、フォローを行ったりなどの上記のアクションが行えなくなるので間接的にブロックされていることは分かります。
- -
⚠️ 相手から自分のコンテンツが見えなくなりますが、相手がアカウントを切り替えたりログアウト状態になれば見ることができます。あくまで簡易的、補助的なものとしてお考えください。
diff --git a/src/docs/eo-UY/features/mute.md b/src/docs/eo-UY/features/mute.md deleted file mode 100644 index 3a36c00f7..000000000 --- a/src/docs/eo-UY/features/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# Silentigi - -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -* タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -* そのユーザーからの通知 -* メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 - -ユーザーをミュートするには、対象のユーザーのユーザーページに表示されている「ミュート」ボタンを押します。 - -ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。 - -設定>ミュート から、自分がミュートしているユーザー一覧を確認することができます。 diff --git a/src/docs/eo-UY/features/note.md b/src/docs/eo-UY/features/note.md deleted file mode 100644 index 3f87c44e1..000000000 --- a/src/docs/eo-UY/features/note.md +++ /dev/null @@ -1,54 +0,0 @@ -# Notoj -Notoj estas centraj konceptoj en Misskey kaj enhavoj kiuj konsistas el teksto, bildoj, dosieroj, balotujo k.t.p.Ankaŭ krei notojn estas nomata "noto" same kiel ili - -ノートが作成されると、[タイムライン](./timeline)に追加され、自分の[フォロワー](./follow)やサーバーのユーザーが見れるようになります。 - -ノートには、[リアクション](./reaction)を行うことができます。また、返信や引用もできます。 - -ノートを[お気に入り](./favorite)登録することで、後で簡単に見返すことができます。 - -## Skribi notojn -ノートを作成するには、画面上にある鉛筆マークのボタンを押して、作成フォームを開きます。作成フォームに内容を入力し、「ノート」ボタンを押すことでノートが作成されます。 ノートには、画像、動画など任意のファイルや、[アンケート](./poll)を添付することができます。また、本文中には[MFM](./mfm)が使用でき、[メンション](./mention)や[ハッシュタグ](./hashtag)を含めることもできます。 他にも、CWや公開範囲といった設定も行えます(詳細は後述)。 -
ℹ️ コンピューターのクリップボードに画像データがある状態で、フォーム内のテキストボックスにペーストするとその画像を添付することができます。
-
ℹ️ テキストボックス内でCtrl + Enterを押すことでも投稿できます。
- -## Plusendi noton -既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノートをRenoteと呼びます。 自分がフォローしているユーザーの、気に入ったノートを自分のフォロワーに共有したい場合や、過去の自分のノートを再度共有したい場合に使います。 同じノートに対して無制限にRenoteを行うことができますが、あまり連続して使用すると迷惑になる場合もあるので、注意しましょう。 -
⚠️ Se vi havigas al via noto videblecon ke nur al sekvantoj aŭ ke rekte, iliaj ne estos plusendeblaj.
- -Renoteを削除するには、Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 - -## CW -Contents Warningの略で、ノートの内容を、閲覧者の操作なしには表示しないようにできる機能です。主に長大な内容を隠すためや、ネタバレ防止などに使うことができます。 設定するには、フォームの「内容を隠す」ボタン(目のアイコン)を押します。すると新しい入力エリアが表れるので、そこに内容の要約を記入します。 - -## Videbleco -ノートごとに、そのノートが公開される範囲を設定することができます。フォームの「ノート」ボタンの左にあるアイコンを押すと公開範囲を以下から選択できます。 - -### Publika -全ての人に対してノートが公開されるほか、サーバーの全てのタイムライン(ホームタイムライン、ローカルタイムライン、ソーシャルタイムライン、グローバルタイムライン)にノートが流れます。 -
⚠️ アカウントがサイレンス状態の時は、この公開範囲は使用できません。
- -### Hejma -全ての人に対してノートが公開されますが、フォロワー以外のローカルタイムライン、ソーシャルタイムライン、グローバルタイムラインにはノートは流れません。 - -### Nur al sekvantoj -Viaj notoj estos senditaj nur al viaj sekvantoj.La noto aperos sur ĉiuj templinioj de viaj sekvantoj. - -### Rekte -指定したユーザーに対してのみノートを公開します。指定したユーザーの全てのタイムラインに流れます。 - -### 「ローカルのみ」オプション -このオプションを有効にすると、リモートにノートを連合しなくなります。 - -### 公開範囲の比較 - - - - -
PublikaHejmaNur al sekvantojRekte
フォロワーのLTL/STL/GTL
非フォロワーのLTL/STL/GTL
- -## Alpingli sur profilo -ノートをピン留めすると、ユーザーページに常にそのノートを表示しておくことができます。 ノートのメニューを開き、「ピン留め」を選択してピン留めできます。 複数のノートをピン留めできます。 - -## Observi -Per la funkcio Observi vi povas ricevi novajn sciigojn pri reagoj, respondoj, k.t.p al tiu noto kiu ne apartenas al vi. Por observi noton elektu la "Observi" el la menuo kunteksta de la noto respektiva. diff --git a/src/docs/eo-UY/features/pages.md b/src/docs/eo-UY/features/pages.md deleted file mode 100644 index a7311b95e..000000000 --- a/src/docs/eo-UY/features/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# Pages - -## 変数 -変数を使うことで動的なページを作成できます。テキスト内で { 変数名 } と書くとそこに変数の値を埋め込めます。例えば Hello { thing } world! というテキストで、変数(thing)の値が ai だった場合、テキストは Hello ai world! になります。 - -変数の評価(値を算出すること)は上から下に行われるので、ある変数の中で自分より下の変数を参照することはできません。例えば上から A、B、C と3つの変数を定義したとき、Cの中でABを参照することはできますが、Aの中でBCを参照することはできません。 - -ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。 - -関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。 diff --git a/src/docs/eo-UY/features/reaction.md b/src/docs/eo-UY/features/reaction.md deleted file mode 100644 index d53bfd313..000000000 --- a/src/docs/eo-UY/features/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# Reagoj -他の人のノートに、絵文字を付けて簡単にあなたの反応を伝えられる機能です。 リアクションするには、ノートの + アイコンをクリックしてピッカーを表示し、絵文字を選択します。 リアクションには[カスタム絵文字](./custom-emoji)も使用できます。 - -## リアクションピッカーのカスタマイズ -ピッカーに表示される絵文字を自分好みにカスタマイズすることができます。 設定の「リアクション」で設定します。 - -## リモート投稿へのリアクションについて -リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。 - -## リモートからのリアクションについて -リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。 diff --git a/src/docs/eo-UY/features/silence.md b/src/docs/eo-UY/features/silence.md deleted file mode 100644 index 24bc722a1..000000000 --- a/src/docs/eo-UY/features/silence.md +++ /dev/null @@ -1,6 +0,0 @@ -# Mutigi -サイレンスは、アカウントに設定される状態のひとつです。 - -アカウントがサイレンス状態になると、ノートの公開範囲をパブリックにできなくなります。 ホーム、フォロワー、ダイレクトは選択可能なため、サイレンスを受けた場合でもフォロワーやあなたのユーザーページを直接訪れた場合は投稿を閲覧できますが、GTL(連合タイムライン)やLTL(ローカルタイムライン)には投稿が流れません。 - -アカウントのサイレンス状態は、サーバーのモデレーターによって有効化/無効化されます。 diff --git a/src/docs/eo-UY/features/theme.md b/src/docs/eo-UY/features/theme.md deleted file mode 100644 index 0d1036ab5..000000000 --- a/src/docs/eo-UY/features/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# Koloraro - -テーマを設定して、Misskeyクライアントの見た目を変更できます。 - -## Agordoj de koloraro -Agordoj > Koloraro - -## Krei koloraron -テーマコードはJSON5で記述されたテーマオブジェクトです。 テーマは以下のようなオブジェクトです。 -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... テーマの一意なID。UUIDをおすすめします。 -* `name` ... テーマ名 -* `author` ... テーマの作者 -* `desc` ... テーマの説明(オプション) -* `base` ... 明るいテーマか、暗いテーマか - * `light`にすると明るいテーマになり、`dark`にすると暗いテーマになります。 - * テーマはここで設定されたベーステーマを継承します。 -* `props` ... テーマのスタイル定義。これから説明します。 - -### テーマのスタイル定義 -`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 - -#### バリューで使える構文 -* 16進数で表された色 - * 例: `#00ff00` -* `rgb(r, g, b)`形式で表された色 - * 例: `rgb(0, 255, 0)` -* `rgb(r, g, b, a)`形式で表された透明度を含む色 - * 例: `rgba(0, 255, 0, 0.5)` -* 他のキーの値の参照 - * `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。 - * 例: `@panel` -* 定数(後述)の参照 - * `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。 - * 例: `$main` -* 関数(後述) - * `:{関数名}<{引数}<{色}` - -#### 定数 -「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 キー名を`$`で始めると、そのキーはCSS変数として出力されません。 - -#### 関数 -wip diff --git a/src/docs/eo-UY/features/timeline.md b/src/docs/eo-UY/features/timeline.md deleted file mode 100644 index 72ee7a5d7..000000000 --- a/src/docs/eo-UY/features/timeline.md +++ /dev/null @@ -1,31 +0,0 @@ -# Templinio -タイムラインは、[ノート](./note)が時系列で表示される機能です。 タイムラインには以下で示す種類があり、種類によって表示されるノートも異なります。 なお、タイムラインの種類によってはサーバーにより無効になっている場合があります。 - -## Hejma -自分のフォローしているユーザーの投稿が流れます。HTLと略されます。 - -## Loka -全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。LTLと略されます。 - -## Sociala -自分のフォローしているユーザーの投稿と、全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。STLと略されます。 - -## Malloka -全てのローカルユーザーの「ホーム」指定されていない投稿と、サーバーに届いた全てのリモートユーザーの「ホーム」指定されていない投稿が流れます。GTLと略されます。 - -## 比較 -| ソース | | | Templinio | | | -| --------------------- | --------- | ----- | --------- | ------- | ------- | -| Uzantoj | Videbleco | Hejma | Loka | Sociala | Malloka | -| Lokaj (sekvataj) | Publika | ✔ | ✔ | ✔ | ✔ | -| | Nur hejma | ✔ | | ✔ | | -| | Sekvantoj | ✔ | ✔ | ✔ | ✔ | -| Transaj (sekvataj) | Publika | ✔ | | ✔ | ✔ | -| | Nur hejma | ✔ | | ✔ | | -| | Sekvantoj | ✔ | | ✔ | ✔ | -| Lokaj (ne sekvataj) | Publika | | ✔ | ✔ | ✔ | -| | Nur hejma | | | | | -| | Sekvantoj | | | | | -| Transaj (ne sekvataj) | Publika | | | | ✔ | -| | Nur hejma | | | | | -| | Sekvantoj | | | | | diff --git a/src/docs/eo-UY/features/widgets.md b/src/docs/eo-UY/features/widgets.md deleted file mode 100644 index a7c2c1d1d..000000000 --- a/src/docs/eo-UY/features/widgets.md +++ /dev/null @@ -1,7 +0,0 @@ -# ウィジェット -ウィジェットは、MisskeyのUI上に設置できる小型の情報表示、操作が行えるパーツです。 - -ウィジェットを編集するには、ウィジェット編集モードに切り替えます。切り替え方法はUIによって異なります。 ウィジェット編集モードでは、ウィジェットの追加、削除、並び替え、およびそれぞれのウィジェットの設定を行えます。 - -## 利用可能なウィジェット一覧 -todo diff --git a/src/docs/eo-UY/features/word-mute.md b/src/docs/eo-UY/features/word-mute.md deleted file mode 100644 index ed1da9167..000000000 --- a/src/docs/eo-UY/features/word-mute.md +++ /dev/null @@ -1,20 +0,0 @@ -# Silentigi specifajn vortojn -ワードミュートの設定をすると、条件に合致したノートが表示されなくなります。 - -ワードミュートには、ソフトワードミュートとハードワードミュートの2種類があります。それぞれについて設定の方法と挙動を説明します。 - -## ソフトワードミュート -ソフトワードミュートは、クライアント(アプリ)側でミュートを判断するワードミュートです。 - -ノートが設定した条件に合致すると、「(ユーザー名)が何かを言いました」という表示で隠れます。 -クリックすると元の通りに表示されます。 - -## ハードワードミュート -ハードワードミュートは、アンテナのようにサーバーが新しいノートの本文に対して条件に合致するかどうか判断し、タイムラインから対象となったノートを除外します。 - -つまり、ハードワードミュートには、以下のような特徴があります。 - -* 条件設定後、新しい投稿のみがミュートの対象になります。 -* 条件を変更しても、過去にハードミュートされたノートはミュートされたままになります。 -* 「○○が何かを言いました」でタイムラインが埋まることがありません。 -* ソフトミュートに非対応のアプリでも、ハードミュートは適用されます。 diff --git a/src/docs/eo-UY/follow.md b/src/docs/eo-UY/follow.md deleted file mode 100644 index 6199895eb..000000000 --- a/src/docs/eo-UY/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# Sekvataj -ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。 diff --git a/src/docs/eo-UY/general/apps.md b/src/docs/eo-UY/general/apps.md deleted file mode 100644 index 793a2bdd6..000000000 --- a/src/docs/eo-UY/general/apps.md +++ /dev/null @@ -1,6 +0,0 @@ -# サードパーティアプリのリスト -## Klientoj -todo - -## 連携サービス -todo diff --git a/src/docs/eo-UY/general/changelog.md b/src/docs/eo-UY/general/changelog.md deleted file mode 100644 index 6766a63b2..000000000 --- a/src/docs/eo-UY/general/changelog.md +++ /dev/null @@ -1,5 +0,0 @@ -# 更新履歴 -
ℹ️ このサーバーの更新履歴です。Misskeyの最新のリリースについては、GitHubをご確認ください。
- - - diff --git a/src/docs/eo-UY/general/faq.md b/src/docs/eo-UY/general/faq.md deleted file mode 100644 index 14e02e39e..000000000 --- a/src/docs/eo-UY/general/faq.md +++ /dev/null @@ -1,28 +0,0 @@ -# Oftaj demandoj -ここでは利用上のよくある質問について掲載しています。 Misskeyのプロジェクト自体についてのよくある質問は[こちら](./misskey)に掲載されています。 - -## iOS/Androidのアプリはありますか? -公式にはそういったOSのネイティブアプリを開発していませんが、サードパーティ製のアプリがいくつかあります。 詳しくは[こちら](./apps)をご覧ください。 - -ただ、サードパーティ製アプリはどうしても機能への対応が遅れてしまうため、とくに拘りがなければ公式のWebクライアントの利用をおすすめします。 なお、MisskeyのWebクライアントはPWAに対応しているので、ネイティブアプリのように動作させることも可能です。 詳しくは[こちら](todo)をご覧ください。 - -## Mastodonクライアントでログインできないのですが? -MisskeyはMastodonのAPIと互換性がないため、一部を除きMastodonクライアントでMisskeyを利用することはできません。 - -## 他のサーバーのユーザーをフォローするときは? -メニューから検索を選び、ユーザー名をホスト込みで入力します。例: `@syuilo@misskey.io` - -## "Kiel mi malfari plusendon de noto?" -Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 Renoteについては[こちら](../features/note)をご確認ください。 - -## URLのプレビューを表示させたくない -MFMには、そのURLのプレビューを無効にする構文があります。詳細は[MFMチートシート](/mfm-cheat-sheet)をご確認ください。 - -## カスタム絵文字を追加したい -運営者のみがカスタム絵文字を追加、編集、削除できます。それらを希望する場合は運営者に依頼してください。 - -## Botを開発したい -Misskey APIを利用してBotの開発が可能です。[こちら](../advanced/develop-bot)をご確認ください。 - -## ノートの翻訳機能はどのサービスを使用していますか? -[DeepL](https://www.deepl.com/)を使用しています。 diff --git a/src/docs/eo-UY/general/glossary.md b/src/docs/eo-UY/general/glossary.md deleted file mode 100644 index 25dd5f82c..000000000 --- a/src/docs/eo-UY/general/glossary.md +++ /dev/null @@ -1,89 +0,0 @@ -# Glosaro -Misskeyに関する用語集です。 - -## ActivityPub -(読み: あくてぃびてぃぱぶ) 分散型を実現するために用いられるプロトコル(仕様)。このプロトコルに則ってサーバー同士通信を行うことで、連合が行われ、Fediverseを形成しています。 - -## AiScript -(読み: あいすくりぷと) Misskey上で使用できるプログラミング言語です。詳細は[こちら。](../advanced/aiscript) - -## API -(読み: えーぴーあい) Misskeyのサーバーが公開している、プログラムからMisskeyを扱うためのインターフェース。詳細は[こちら。](../advanced/api) - -## Roboto -(読み: ぼっと) プログラムによって動作しているアカウント。 - -## CW -(読み: こんてんつわーにんぐ) Contents Warningの略。ノートの内容を、操作なしには表示しないようにできる機能。主に長大な内容を隠すためや、ネタバレ防止などに使われます。 - -## Fediverso -(読み: ふぇでぃばーす) Misskeyを含む様々な分散型ソフトウェアのサーバーで構成されたネットワーク。 - -## MTL (GTL) -Kaplitero de "Malloka TempLinio".タイムラインの詳細は[こちら。](../features/timeline) - -## HTL -Kaplitero de "Hejma TempLinio".タイムラインの詳細は[こちら。](../features/timeline) - -## LTL -Kaplitero de "Loka TempLinio".タイムラインの詳細は[こちら。](../features/timeline) - -## MFM -(読み: えむえふえむ) Misskey Flavored Markdownの略で、Misskey上で使用できるマークアップ言語です。詳細は[こちら。](../features/mfm) - -## NSFW -(読み: のっとせーふふぉーわーく) Not Safe For Workの略。画像を「閲覧注意」扱いにし、操作なしには表示しないようにすることができる機能。 - -## Notoj plusenditaj -(読み: りのーと) 既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノート。Rigardu por sciu pli tie[.](../features/note) - -## STL -Kaplitero de "Sociala TempLinio".Por sciu pri la templinio, rigardu tie[.](../features/timeline) - -## Ai -Ai estas oficiala maskoto de Misskey. - -## Aktiva uzanto -インスタンスにアカウントを作っているユーザーのうち、現在も実際にサービスを利用しているユーザーのこと。 - -## Nodo -todo - -## Emoĵioj personecigitaj -サーバーで用意された絵文字。カスタム絵文字ではない通常の絵文字は「Unicode絵文字」と区別して呼ばれる。 - -## Ŝaltpodio -インスタンスの設定画面のこと。 - -## Servilo -todo - -## Mutigi -ノートをパブリックな公開範囲で投稿できなくされている状態。モデレーターの判断でユーザーごとに設定されます。詳細は[こちら。](../features/silence) - -## ジョブキュー -アクティビティ配送などを順番に行うためのシステム。 - -## Flostigita -アカウントが使用不可に設定されている状態。 - -## Disko -Funkcio ebligas al uzantoj administri dosierojn kiujn ili alŝutis al Misskey.Rigardu por sciu pli tie[.](../features/drive) - -## Notoj -Enpoŝtigaĵoj en Misskey kiuj konsistas el teksto, dosiero, balotujo, ktp.Rigardu por sciu pli tie[.](../features/note) - -## Miskiisto -Uzuloj de Misskey. - -## Kontrolisto -スパムの凍結およびサイレンスや不適切な投稿の削除など、コミュニティ運営に関する権限を持つユーザー。 - -## Transa, Surloka -他サーバーのことを指します。リモートユーザーといったように接頭辞としても使われます。ローカルの逆です。 - -## Federado -サーバー上で作成された情報が他のサーバーに伝わること。 - -## Loka -自サーバーのことを指します。ローカルユーザー、ローカルタイムラインといったように接頭辞としても使われます。リモートの逆です。 diff --git a/src/docs/eo-UY/general/links.md b/src/docs/eo-UY/general/links.md deleted file mode 100644 index 5d5c8dc7d..000000000 --- a/src/docs/eo-UY/general/links.md +++ /dev/null @@ -1,12 +0,0 @@ -# リンク集 - -## Webサイト -- [Oficiala Discord](https://discord.gg/Wp8gVStHW3) - la Servilo Discord'a oficiala de Misskey -- [Misskey Forum](https://forum.misskey.io/) - Misskeyに関する話題を扱うフォーラム - -## Kontoj -- [@repo@misskey.io](https://misskey.io/@repo) - Misskeyのリポジトリの更新を投稿するbot - -## ライブラリ -- [misskey-dev/misskey.js](https://github.com/misskey-dev/misskey.js) - JavaScriptのMisskey SDK -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptのMFMパーサー実装 diff --git a/src/docs/eo-UY/general/misskey.md b/src/docs/eo-UY/general/misskey.md deleted file mode 100644 index ef287e596..000000000 --- a/src/docs/eo-UY/general/misskey.md +++ /dev/null @@ -1,87 +0,0 @@ -# Pri Misskey - -Misskey estas malfermitkoda distribuita mikroblogo. Ĝi enhavas diversaj funkcioj ekzemple disko, reagoj, ktp kaj alte agordebla fasado. Evoluigo ekfaris de syuilo de 2014. - -## Historio -開発当初は掲示板がメインのサービスでしたが、ユーザーが短文を投稿し、それを時系列で流れるタイムライン機能を追加したところ人気が高まり、徐々にそれがメインとして開発が進むようになりました。 当初は分散型ではありませんでしたが、2018年にActivityPubを実装し分散型になったことで、より多くの方に認知され利用されるサービスになり、現在に至ります。 -
ℹ️ Misskeyという名前は、syuiloが当時聴いていたMay'nというアーティストの楽曲、Brain Diverの歌詞に由来します。
- -誰でも開発に参加することができ、現在でも活発に開発が続いています。 - -## 分散型とは何か? - -分散(distributed)型とは、非中央集権(decentralized)とも呼ばれ、コミュニティが多数のサーバーに分散して存在し、それらが相互に通信(連合、federation)することでコンテンツ共有ネットワーク(Fediverse)を形成していることが特徴のサービスです。 単一のサーバーしか存在しない、もしくは複数存在しても互いに独立している場合は中央集権なサービスと言われ、例えばTwitterやFacebookなどほとんどのサービスがそれに該当します。 分散型のメリットは、自分に合った運営者やテーマのサーバーを選択できることです。自分でサーバーを作成することもできます。連合するおかげで、どのサーバーを選んでも、同じコミュニティにアクセスできます。 - -## Ĉiam malfermitkoda -Misskeyはこれまでもこれからも、オープンソースであり続けます。オープンソースとは、簡単に言うとソフトウェアのソースコード(プログラム)が公開されていることです。ソースコードの修正や再配布が可能であることを定義に含めることもあります。 Misskeyのすべてのソースコードは[AGPL](https://github.com/misskey-dev/misskey/blob/develop/LICENSE)というオープンソースライセンスの下に[公開](https://github.com/misskey-dev)されていて、誰でも自由に閲覧、使用、修正、改変、再配布をすることができます。 オープンソースは、自分で好きなように変えたり、有害な処理が含まれていないことを確認することができたり、誰でも開発に参加できるなどの、様々なメリットがあります。 上述の分散型を実現するためにも、オープンソースであるということは必要不可欠な要素です。 再び引き合いに出しますが、TwitterやFacebookなどの利益を得ているほとんどのサービスはオープンソースではありません。 - -
ℹ️ 技術的に言うと、MisskeyのソースコードはGitで管理されていて、リポジトリはGitHub上でホスティングされています。
- -## 開発に参加する、プロジェクトを支援する -Misskeyを気に入っていただけたら、ぜひプロジェクトを支援してください。プロジェクトに貢献するには、以下で紹介するようにいろいろな方法があります。方法によっては開発のスキルは不要なので、誰でも気軽に参加し貢献することができます。いつでもお待ちしています。 - -### 機能を追加したり、バグを修正する -ソフトウェアエンジニアのスキルをお持ちの方であれば、ソースコードを編集する形でプロジェクトに貢献することができます。 貢献についてのガイドは[こちら](https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md)です。 - -### 議論に参加する -新しい機能、または既存の機能について意見を述べたり、不具合を報告したりすることでも貢献できます。 そのようなディスカッションは[GitHub](https://github.com/misskey-dev)上か、[フォーラム](https://forum.misskey.io/)等で行われます。 - -### Traduki tekston -Misskeyは様々な言語に対応しています(i18n -internationalizationの略- と呼ばれます)。元の言語は基本的に日本語ですが、有志によって他の言語へと翻訳されています。 その翻訳作業に加わっていただくことでもMisskeyに貢献できます。 Misskeyは[Crowdinというサービスを使用して翻訳の管理を行っています。](https://crowdin.com/project/misskey) - -### 感想を投稿する -不具合報告等だけではなく、Misskeyの良い点、楽しい点といったポジティブな意見もぜひ共有してください。開発の励みになり、それは間接的ですがプロジェクトへの貢献です。 - -### ミスキストを増やす -ミスキストとは、Misskeyを使用する人のことです。 知り合いに紹介するなどしてMisskeyを広めていただければ、ミスキストが増え開発のモチベーションが上がります。 - -### 寄付をする -Misskeyはビジネスではなく、利用は無料であるため、収益は皆様からの寄付のみです。(インスタンスによっては広告収入を得ているような場合もありますが、それは運営者の収入であり直接開発者への収入にはなりません) 寄付をしていただければ、今後も開発を続けることが可能になり、プロジェクトへの貢献になります。 寄付は基本的には[Patreon](https://www.patreon.com/syuilo)で受け付けています。 一定額寄付していただけると、Misskeyの[情報ページ](/about-misskey)に名前を記載することができます。 - -また、サーバーの運営者も、基本的には収益を得ていません。サーバーの運営にはコストがかかるので、運営者の支援をすることもご検討ください。 開発には直接関係しませんが、サーバーがあってこそのプロジェクトなので、運営が維持されるというのは開発と同じくらい重要なことです。 - -## クレジット -Misskeyの開発者や、Misskeyに寄付をしてくださった方の一覧は[こちら](/about-misskey)で見ることができます。 - -## Oftaj demandoj -### プロジェクトは何を目指していますか? -強いて言うと、漠然的になりますが広く使われる汎用的なプラットフォームになることを目指しています。 Misskeyは他のプロジェクトとは違い、何らかの思想(例えば、反中央集権)やビジョンに基づいて開発が行われているわけではなく、その点ではフラットです。 それが逆に、特定の方向性に縛られないフレキシブルさを生み出すことに繋がっていると感じています。 - - -### 企業によって開発されていますか? -いいえ。Misskeyの開発は個人で行われており、商業的でもないため、特定の企業の関りはありません。 開発メンバーも基本的にはボランティアです。 また、開発に対し企業のスポンサーがつくこともありますが、その場合でもやはり開発は個人のコミュニティが主体です。 - -### Kiu administras Misskey'on? -Misskeyは分散型なため、各サーバーにそれぞれ異なった運営者がいます。従って、特定の個人や企業によって、Misskeyの全てが運営されているわけではありません。 また、開発チームが運営を行うわけでもないため、運営に関する連絡は、お使いのサーバーの運営者に行ってください。 サーバーの運営者は、[このページ](/about)で確認することができます。 あなたがサーバーを作成すれば、あなたが運営者になります。 - -### どのサーバーを選べばいいですか? -[サーバー一覧が公開されています。](https://join.misskey.page/ja-JP/instances) サーバーによってコミュニティのテーマ(特定のこと、ものが好き 等)が決められている場合があるので、自分に合ったテーマのサーバーがあれば、そこを選ぶと良いかもしれません。 他にも、サーバーの規模、ユーザー層、国および言語、運営者が信頼できるかどうか、などの観点があります。 なお、Misskey公式のサーバーというものはありません。自身で新しくサーバーを作成するという選択肢もあります。 - -基本的にどのサーバーを選んだとしても、他の全てのサーバーのユーザーと繋がることができます。 - -### サーバーを建てるにはどうしたらいいですか? -Misskeyサーバーの作成に興味を持っていただきありがとうございます。 2021年現在、Misskeyのホスティングサービスは存在しないため、サーバーの作成にはある程度の知識が必要です。 サーバーの作成方法については[こちら](todo)をご覧ください。 - -### どのような技術を使用していますか? -Misskeyは開発が進むにつれ使用する技術も大きく変わってきました。開発当初はMySQL + PHP + jQueryといった構成でしたが、現在は以下のようになっています。 -- サーバーサイド: Node.js -- データベース: PostgreSQL、Redis -- UIフレームワーク: Vue.js -- プログラミング言語: TypeScript - -また、MFMやAiScriptなどの、Misskeyから派生して独自の技術も開発しています。 - -### Mastodonのフォークですか? -いいえ。MisskeyはMastodonやその他のプロジェクトとは全く別のプロジェクトです。 開発に関しても、Misskeyの方が昔から開発されています。ただし、分散型になったのはMastodonの登場より後です。 同じActivityPubという分散のためのプロトコルを実装しているという点以外、両者に特に関りがあるわけでもありません。 - -### iOS/Androidのアプリはありますか? -公式にはそういったOSのネイティブアプリを開発していませんが、サードパーティ製のアプリがいくつかあります。 詳しくは[こちら](./apps)をご覧ください。 - -ただ、サードパーティ製アプリはどうしても機能への対応が遅れてしまうため、とくに拘りがなければ公式のWebクライアントの利用をおすすめします。 なお、MisskeyのWebクライアントはPWAに対応しているので、ネイティブアプリのように動作させることも可能です。 詳しくは[こちら](todo)をご覧ください。 - -### Misskeyのロゴ、アイコンはどこで入手できますか? -(準備中) - -### 時折目にする猫耳の可愛い女の子は? -Misskeyの守り神、藍ちゃんです。アイチャンカワイイヤッター! -
ℹ️ 藍ちゃんについてはこちらです。
diff --git a/src/docs/eo-UY/general/report-issue.md b/src/docs/eo-UY/general/report-issue.md deleted file mode 100644 index 63527e32a..000000000 --- a/src/docs/eo-UY/general/report-issue.md +++ /dev/null @@ -1,8 +0,0 @@ -# 不具合の報告 -不具合と思われる状況に遭遇したときは、まず[トラブルシューティング](./troubleshooting)をご一読ください。 それでも問題が解決しないときは、以下の情報を含めて[フォーラム](https://forum.misskey.io/)に投稿してください。 投稿することで、解決策が見つかったり、不具合と判断されれば開発チームによって修正が行われます。 - -## 含める情報 -- Misskeyのバージョン([情報ページ](/about)で確認できます) -- お使いのブラウザの種類とバージョン -- お使いのOSの種類とバージョン -- 問題の再現手順 diff --git a/src/docs/eo-UY/general/troubleshooting.md b/src/docs/eo-UY/general/troubleshooting.md deleted file mode 100644 index d7f132e63..000000000 --- a/src/docs/eo-UY/general/troubleshooting.md +++ /dev/null @@ -1,40 +0,0 @@ -# Problemsolvi -
ℹ️ よくある質問も合わせてお役立てください。
- -問題が発生したときは、まずこちらをご確認ください。 該当する項目が無い、もしくは手順を試しても効果がない場合は、サーバーの管理者に連絡するか[不具合を報告](./report-issue)してください。 - -## クライアントが起動しない -ほとんどの場合、お使いのブラウザまたはOSのバージョンが古いことが原因です。 ブラウザおよびOSのバージョンを最新のものに更新してから、再度試してみてください。 - -これは稀ですが、それでも起動しない場合は、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。 - -## ページが読み込めない -クライアントが起動するもののページが読み込めないというエラーが出る場合は、ネットワークに問題がないか確認してください。また、サーバーがダウンしていないか確認してください。 - -これは稀ですが、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。 - -まだ問題がある場合は、サーバーの問題と思われるのでサーバーの管理者に連絡してください。 - -## クライアントの動作が遅い -以下を試してみてください: - -- クライアント設定で「UIのアニメーションを減らす」を有効にする -- クライアント設定で「モーダルにぼかし効果を使用」を無効にする -- お使いのブラウザの設定でハードウェアアクセラレーションを有効にする -- お使いのデバイスのスペックを上げる - -## UIの一部の表示がおかしい(背景が透明になっている等) -アップデートによりUIの改修が行われたときに、テーマのキャッシュシステムの影響でそのような表示になることがあります。 クライアントの設定の「キャッシュをクリア」すると直ります。 -
⚠️ 「クライアントの」キャッシュクリアです。「ブラウザの」キャッシュクリアは行わないでください。
- -## 通知やアンテナ等の点滅が消えない -点滅は、未読のコンテンツがあることを示しています。通常点滅が消えない場合は、コンテンツを遡ると未読なコンテンツが残っています。 すべて既読にしたと思われるのに、それでもなお点滅が続く場合(おそらく不具合と思われます)は設定から強制的にすべて既読扱いにすることができます。 - -## Oni ne povas plusendi noton -Notoj nur al sekvantoj ne estas plusendeblaj. - -## UI上で特定の要素が表示されない -広告ブロッカーを使用しているとそのような不具合が発生することがあります。Misskeyではオフにしてご利用ください。 - -## UI上で未翻訳の部分がある -ほとんどの場合、単に翻訳が間に合っていないだけで、不具合ではありません。翻訳が終わるまでお待ちください。 [翻訳に参加](./misskey)していただくことも可能です。 diff --git a/src/docs/eo-UY/keyboard-shortcut.md b/src/docs/eo-UY/keyboard-shortcut.md deleted file mode 100644 index 1efd76f66..000000000 --- a/src/docs/eo-UY/keyboard-shortcut.md +++ /dev/null @@ -1,68 +0,0 @@ -# キーボードショートカット - -## Konfederacia -これらのショートカットは基本的にどこでも使えます。 - - - - - - - - - - - -
ショートカット効果由来
P, N新規投稿Post, New, Note
Tタイムラインの最も新しい投稿にフォーカスTimeline, Top
Shift + N通知を表示/隠すNotifications
SSerĉiSearch
H, ?ヘルプを表示Help
- -## 投稿にフォーカスされた状態 - - - - - - - - - - - - - - - - - - - -
ショートカット効果由来
, K, Shift + Tab上の投稿にフォーカスを移動-
, J, Tab下の投稿にフォーカスを移動-
R返信フォームを開くReply
QRenoteフォームを開くQuote
Ctrl + Q即刻Renoteする(フォームを開かずに)-
E, A, +リアクションフォームを開くEmote, reAction
0~9数字に対応したリアクションをする(対応については後述)-
F, Bお気に入りに登録Favorite, Bookmark
Del, Ctrl + D投稿を削除Delete
M, O投稿に対するメニューを開くMore, Other
SCWで隠された部分を表示 or 隠すShow, See
Escフォーカスを外す-
- -## Renoteフォーム - - - - - - - - - - -
ショートカット効果由来
EnterRenoteする-
Qフォームを展開するQuote
Escフォームを閉じる-
- -## リアクションフォーム -デフォルトで「👍」にフォーカスが当たっている状態です。 - - - - - - - - - - - - - -
ショートカット効果由来
, K上のリアクションにフォーカスを移動-
, J下のリアクションにフォーカスを移動-
, H, Shift + Tab左のリアクションにフォーカスを移動-
, L, Tab右のリアクションにフォーカスを移動-
Enter, Space, +リアクション確定-
0~9数字に対応したリアクションで確定-
Escリアクションするのをやめる-
diff --git a/src/docs/eo-UY/mfm.md b/src/docs/eo-UY/mfm.md deleted file mode 100644 index e237287ac..000000000 --- a/src/docs/eo-UY/mfm.md +++ /dev/null @@ -1,2 +0,0 @@ -# MFM -MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます。 diff --git a/src/docs/eo-UY/mute.md b/src/docs/eo-UY/mute.md deleted file mode 100644 index 3a36c00f7..000000000 --- a/src/docs/eo-UY/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# Silentigi - -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -* タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -* そのユーザーからの通知 -* メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 - -ユーザーをミュートするには、対象のユーザーのユーザーページに表示されている「ミュート」ボタンを押します。 - -ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。 - -設定>ミュート から、自分がミュートしているユーザー一覧を確認することができます。 diff --git a/src/docs/eo-UY/pages.md b/src/docs/eo-UY/pages.md deleted file mode 100644 index a7311b95e..000000000 --- a/src/docs/eo-UY/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# Pages - -## 変数 -変数を使うことで動的なページを作成できます。テキスト内で { 変数名 } と書くとそこに変数の値を埋め込めます。例えば Hello { thing } world! というテキストで、変数(thing)の値が ai だった場合、テキストは Hello ai world! になります。 - -変数の評価(値を算出すること)は上から下に行われるので、ある変数の中で自分より下の変数を参照することはできません。例えば上から A、B、C と3つの変数を定義したとき、Cの中でABを参照することはできますが、Aの中でBCを参照することはできません。 - -ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。 - -関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。 diff --git a/src/docs/eo-UY/reaction.md b/src/docs/eo-UY/reaction.md deleted file mode 100644 index dfb9de382..000000000 --- a/src/docs/eo-UY/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# Reagoj -他の人のノートに、絵文字を付けて簡単にあなたの反応を伝えられる機能です。 リアクションするには、ノートの + アイコンをクリックしてピッカーを表示し、絵文字を選択します。 リアクションには[カスタム絵文字](./custom-emoji)も使用できます。 - -## リアクションピッカーのカスタマイズ -ピッカーに表示される絵文字を自分好みにカスタマイズすることができます。 設定の「リアクション」で設定します。 - -## リモート投稿へのリアクションについて -リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。 また、相手がMisskeyであったとしても、カスタム絵文字リアクションは伝わらず、自動的に「👍」等にフォールバックされます。 - -## リモートからのリアクションについて -リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。 diff --git a/src/docs/eo-UY/reversi-bot.md b/src/docs/eo-UY/reversi-bot.md deleted file mode 100644 index 7ab2a7212..000000000 --- a/src/docs/eo-UY/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# MisskeyリバーシBotの開発 -Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。 - -1. `games/reversi`ストリームに以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - -2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる - * イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている - -3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する - -4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - * `game`: `game`の`id` - -5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う - -6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する - -7. ゲームが開始すると、`started`イベントが流れてくる - * イベントの中身にはゲーム情報が含まれている - -8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述) - -9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる - * `color`として石の色が含まれている - * `pos`として位置情報が含まれている - -## 位置の計算法 -8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### X,Y座標 から インデックス に変換する -``` -pos = x + (y * mapWidth) -``` -`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます: -``` -mapWidth = map[0].length -``` - -### インデックス から X,Y座標 に変換する -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## マップ情報 -マップ情報は、ゲーム情報の`map`に入っています。 文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 それをもとにマップのデザインを知る事が出来ます: -* `(スペース)` ... マス無し -* `-` ... マス -* `b` ... 初期配置される黒石 -* `w` ... 初期配置される白石 - -例えば、4*4の次のような単純なマップがあるとします: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -この場合、マップデータはこのようになります: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## ユーザーにフォームを提示して対話可能Botを作成する -ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。 - -フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します: -```javascript -{ - type: 'init-form', - body: [フォームコントロールの配列] -} -``` - -フォームコントロールの配列については今から説明します。 フォームコントロールは、次のようなオブジェクトです: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... コントロールのID。 `type` ... コントロールの種類。後述します。 `label` ... コントロールと一緒に表記するテキスト。 `value` ... コントロールのデフォルト値。 - -### フォームの操作を受け取る -ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### フォームコントロールの種類 -#### スイッチ -type: `switch` スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。 - -##### プロパティ -`label` ... スイッチに表記するテキスト。 - -#### ラジオボタン -type: `radio` ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。 - -##### プロパティ -`items` ... ラジオボタンの選択肢。例: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '強', - value: 3 -}] -``` - -#### スライダー -type: `slider` スライダーを表示します。 - -##### プロパティ -`min` ... スライダーの下限。 `max` ... スライダーの上限。 `step` ... 入力欄で刻むステップ値。 - -#### テキストボックス -type: `textbox` テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。 - -## ユーザーにメッセージを表示する -設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 メッセージを表示するには、次のメッセージをストリームに送信します: -```javascript -{ - type: 'message', - body: { - text: 'メッセージ内容', - type: 'メッセージの種類' - } -} -``` -メッセージの種類: `success`, `info`, `warning`, `error`。 - -## 投了する -投了をするには、このエンドポイントにリクエストします。 diff --git a/src/docs/eo-UY/stream.md b/src/docs/eo-UY/stream.md deleted file mode 100644 index f06eb96be..000000000 --- a/src/docs/eo-UY/stream.md +++ /dev/null @@ -1,354 +0,0 @@ -# ストリーミングAPI - -ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。 - -## ストリームに接続する - -ストリーミングAPIを利用するには、まずMisskeyサーバーに**websocket**接続する必要があります。 - -以下のURLに、`i`というパラメータ名で認証情報を含めて、websocket接続してください。例: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。 - -
-

認証情報の取得については、こちらのドキュメントをご確認ください。

-
- ---- - -認証情報は省略することもできますが、その場合非ログインでの利用ということになり、受信できる情報や可能な操作は限られます。例: - -``` -%WS_URL%/streaming -``` - ---- - -ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。 - -**ストリームでのやり取りはすべてJSONです。** - -## Kanalo -MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。 - -### チャンネルに接続する -チャンネルに接続するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -ここで、 -* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。 -* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。 -* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。 - -
-

IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。

-
- -### チャンネルからのメッセージを受け取る -例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。 - -チャンネルがメッセージを発すると、次のようなデータがJSONでストリームに流れてきます: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。 -* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。 -* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。 - -### チャンネルに向けてメッセージを送信する -チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。 - -チャンネルにメッセージを送信するには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。 -* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。 -* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。 - -### チャンネルから切断する -チャンネルから切断するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。 - -## ストリームを経由してAPIリクエストする - -ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。 - -ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -ここで、 -* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 -* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 -* `data`には、エンドポイントのパラメータを含めます。 - -
-

APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。

-
- -### レスポンスの受信 - -APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。 - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -ここで、 -* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 -* `body`には、レスポンスが含まれています。 - -## 投稿のキャプチャ - -Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。 - -例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。 - -しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。 - -この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。 - -### 投稿をキャプチャする - -投稿をキャプチャするには、ストリームに次のようなメッセージを送信します: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャしたい投稿の`id`を設定します。 - -このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 - -例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -ここで、 -* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。 -* `body`内の`type`に、イベントの種類が設定されます。 -* `body`内の`body`に、イベントの詳細が設定されます。 - -#### イベントの種類 - -##### `reacted` -その投稿にリアクションがされた時に発生します。 - -* `reaction`に、リアクションの種類が設定されます。 -* `userId`に、リアクションを行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -その投稿が削除された時に発生します。 - -* `deletedAt`に、削除日時が設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -その投稿に添付されたアンケートに投票された時に発生します。 - -* `choice`に、選択肢IDが設定されます。 -* `userId`に、投票を行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### 投稿のキャプチャを解除する - -その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。 - -次のメッセージを送信します: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャを解除したい投稿の`id`を設定します。 - -このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 - -# チャンネル一覧 -## `main` -アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `renote` -自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。 - -#### `mention` -誰かからメンションされたときに発生するイベントです。 - -#### `readAllNotifications` -自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。 - -#### `meUpdated` -自分の情報が更新されたことを表すイベントです。 - -#### `follow` -自分が誰かをフォローしたときに発生するイベントです。 - -#### `unfollow` -自分が誰かのフォローを解除したときに発生するイベントです。 - -#### `followed` -自分が誰かにフォローされたときに発生するイベントです。 - -## `homeTimeline` -ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -タイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `localTimeline` -ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `hybridTimeline` -ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ソーシャルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `globalTimeline` -グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 diff --git a/src/docs/eo-UY/theme.md b/src/docs/eo-UY/theme.md deleted file mode 100644 index a406f3433..000000000 --- a/src/docs/eo-UY/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# テーマ - -テーマを設定して、Misskeyクライアントの見た目を変更できます。 - -## テーマの設定 -設定 > テーマ - -## テーマを作成する -テーマコードはJSON5で記述されたテーマオブジェクトです。 テーマは以下のようなオブジェクトです。 -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... テーマの一意なID。UUIDをおすすめします。 -* `name` ... テーマ名 -* `author` ... テーマの作者 -* `desc` ... テーマの説明(オプション) -* `base` ... 明るいテーマか、暗いテーマか - * `light`にすると明るいテーマになり、`dark`にすると暗いテーマになります。 - * テーマはここで設定されたベーステーマを継承します。 -* `props` ... テーマのスタイル定義。これから説明します。 - -### テーマのスタイル定義 -`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 - -#### バリューで使える構文 -* 16進数で表された色 - * 例: `#00ff00` -* `rgb(r, g, b)`形式で表された色 - * 例: `rgb(0, 255, 0)` -* `rgb(r, g, b, a)`形式で表された透明度を含む色 - * 例: `rgba(0, 255, 0, 0.5)` -* 他のキーの値の参照 - * `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。 - * 例: `@panel` -* 定数(後述)の参照 - * `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。 - * 例: `$main` -* 関数(後述) - * `:{関数名}<{引数}<{色}` - -#### 定数 -「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 キー名を`$`で始めると、そのキーはCSS変数として出力されません。 - -#### 関数 -wip diff --git a/src/docs/eo-UY/timelines.md b/src/docs/eo-UY/timelines.md deleted file mode 100644 index 8f0e8a93a..000000000 --- a/src/docs/eo-UY/timelines.md +++ /dev/null @@ -1,15 +0,0 @@ -# タイムラインの比較 - -https://docs.google.com/spreadsheets/d/1lxQ2ugKrhz58Bg96HTDK_2F98BUritkMyIiBkOByjHA/edit?usp=sharing - -## Hejmo -自分のフォローしているユーザーの投稿 - -## Loka -全てのローカルユーザーの「ホーム」指定されていない投稿 - -## Hejmo kaj loka -自分のフォローしているユーザーの投稿と、全てのローカルユーザーの「ホーム」指定されていない投稿 - -## Konfederacia -全てのローカルユーザーの「ホーム」指定されていない投稿と、サーバーに届いた全てのリモートユーザーの「ホーム」指定されていない投稿 diff --git a/src/docs/es-ES/admin/disable-timelines.md b/src/docs/es-ES/admin/disable-timelines.md deleted file mode 100644 index b081e35ab..000000000 --- a/src/docs/es-ES/admin/disable-timelines.md +++ /dev/null @@ -1,8 +0,0 @@ -# LTL/STL/GTLの無効化 -Misskeyでは、LTL/STL/GTLをそれぞれ無効化することができます。有効/無効を切り替えるには、インスタンスコントロールパネルで設定します。 - -LTLやSTLは、そのインスタンス全員の投稿が見れるため、新規のユーザーにとってはユーザーを探す必要がなくなり、興味のあるユーザーを見つけやすいという利点があります。 しかし同時に、フォロー機能が活用されなくなったり、不適切な投稿が目につきやすくなったり、チャットのようになることで内輪感が生じて逆に新規ユーザーが参加しにくくなるといったデメリットも持ち合わせています。 サーバーによってメリット/デメリットどちらが優勢かは異なるので、オプションとして無効にできるようになっています。 もしデメリットの方が上回っていると感じたら、それらのタイムラインを無効化することも検討してください。 - -
⚠️ 無効化を行うと、ユーザーが困惑し、短期的に見て利用者が減る可能性があります。そのため、無効化の際は影響を慎重に検討し、事前に説明してフォローを整える期間を一定程度設けることを推奨します。
- -なお、管理者/モデレーターは、これらのタイムラインの無効化状態は適用されず、引き続き利用することが可能です。 diff --git a/src/docs/es-ES/admin/faq.md b/src/docs/es-ES/admin/faq.md deleted file mode 100644 index 317b4e065..000000000 --- a/src/docs/es-ES/admin/faq.md +++ /dev/null @@ -1,5 +0,0 @@ -# よくある質問 -ここでは、サーバー管理者向けのよくある質問を掲載しています。 - -## デフォルトテーマを設定したい -現在、デフォルトテーマ設定機能は実装されていません。 diff --git a/src/docs/es-ES/advanced/aiscript.md b/src/docs/es-ES/advanced/aiscript.md deleted file mode 100644 index 604d17daa..000000000 --- a/src/docs/es-ES/advanced/aiscript.md +++ /dev/null @@ -1,7 +0,0 @@ -# AiScript -AiScriptは、Misskeyで使用できるスクリプト言語です。 - -
ℹ️ AiScript実装はMisskeyとは別リポジトリで、オープンソースで公開されています。
- -## 使い方 -AiScriptの構文や組み込み関数などのドキュメントは、[こちら](https://github.com/syuilo/aiscript/tree/master/docs)で公開されています。 diff --git a/src/docs/es-ES/advanced/api.md b/src/docs/es-ES/advanced/api.md deleted file mode 100644 index 76019b614..000000000 --- a/src/docs/es-ES/advanced/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス、Bot等(以下「アプリケーション」と呼びます)を開発できます。 ストリーミングAPIもあるので、リアルタイム性のあるアプリケーションを作ることも可能です。 - -APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。 - -## アクセストークンの取得 -基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。 - -* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む -* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む - -### 自分自身のアクセストークンを手動発行する -「設定 > API」で、自分のアクセストークンを発行できます。 - -[「APIの使い方」へ進む](#APIの使い方) - -### アプリケーション利用者にアクセストークンの発行をリクエストする -アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。 - -#### Step 1 - -UUIDを生成する。以後これをセッションIDと呼びます。 - -> このセッションIDは毎回生成し、使いまわさないようにしてください。 - -#### Step 2 - -`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。 -> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます: -* `name` ... アプリケーション名 - * > 例: `MissDeck` -* `icon` ... アプリケーションのアイコン画像URL - * > 例: `https://missdeck.example.com/icon.png` -* `callback` ... 認証が終わった後にリダイレクトするURL - * > 例: `https://missdeck.example.com/callback` - * リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます -* `permission` ... アプリケーションが要求する権限 - * > 例: `write:notes,write:following,read:drive` - * 要求する権限を`,`で区切って列挙します - * どのような権限があるかは[APIリファレンス](/api-doc)で確認できます - -#### Step 3 -ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。 - -レスポンスに含まれるプロパティ: -* `token` ... ユーザーのアクセストークン -* `user` ... ユーザーの情報 - -[「APIの使い方」へ進む](#APIの使い方) - -## APIの使い方 -**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。 - -* [APIリファレンス](/api-doc) -* [ストリーミングAPI](./stream) diff --git a/src/docs/es-ES/advanced/create-plugin.md b/src/docs/es-ES/advanced/create-plugin.md deleted file mode 100644 index 46db70220..000000000 --- a/src/docs/es-ES/advanced/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# プラグインの作成 -Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。 - -## Metadatos -プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。 - -### name -プラグイン名 - -### author -プラグイン作者 - -### version -プラグインバージョン。数値を指定してください。 - -### description -プラグインの説明 - -### permissions -プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。 - -### config -プラグインの設定情報を表すオブジェクト。 キーに設定名、値に以下のプロパティを含めます。 - -#### type -設定値の種類を表す文字列。以下から選択します。 string number boolean - -#### label -ユーザーに表示する設定名 - -#### description -設定の説明 - -#### default -設定のデフォルト値 - -## APIリファレンス -AiScript標準で組み込まれているAPIは掲載しません。 - -### Mk:dialog(title text type) -ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。 - -### Mk:confirm(title text type) -確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。 - -### Mk:api(endpoint params) -Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。 - -### Mk:save(key value) -任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。 - -### Mk:load(key) -Mk:saveで永続化した指定の名前の値を読み取ります。 - -### Plugin:register_post_form_action(title fn) -投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。 - -### Plugin:register_note_action(title fn) -ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 - -### Plugin:register_user_action(title fn) -ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。 - -### Plugin:register_note_view_interruptor(fn) -UIに表示されるノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:register_note_post_interruptor(fn) -ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:open_url(url) -第一引数に渡されたURLをブラウザの新しいタブで開きます。 - -### Plugin:config -プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。 diff --git a/src/docs/es-ES/advanced/develop-bot.md b/src/docs/es-ES/advanced/develop-bot.md deleted file mode 100644 index 7f825e9bc..000000000 --- a/src/docs/es-ES/advanced/develop-bot.md +++ /dev/null @@ -1,6 +0,0 @@ -# Botの作成 -[Misskey API](./api)を利用してBotの開発が可能です。 また、いくつかのBot実装が公開されているため、ぜひ参考にしてください。 - -- [syuilo/ai](https://github.com/syuilo/ai) ... Node.js上で動く、TypeScript製Bot実装 - -Botを作成したときは、プロフィール設定からBotフラグをオンにしておくことを強くおすすめします。 diff --git a/src/docs/es-ES/advanced/reversi-bot.md b/src/docs/es-ES/advanced/reversi-bot.md deleted file mode 100644 index 1019fa447..000000000 --- a/src/docs/es-ES/advanced/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# MisskeyリバーシBotの開発 -Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。 - -1. `games/reversi`ストリームに以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - -2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる - * イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている - -3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する - -4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - * `game`: `game`の`id` - -5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う - -6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する - -7. ゲームが開始すると、`started`イベントが流れてくる - * イベントの中身にはゲーム情報が含まれている - -8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述) - -9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる - * `color`として石の色が含まれている - * `pos`として位置情報が含まれている - -## 位置の計算法 -8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### X,Y座標 から インデックス に変換する -``` -pos = x + (y * mapWidth) -``` -`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます: -``` -mapWidth = map[0].length -``` - -### インデックス から X,Y座標 に変換する -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## マップ情報 -マップ情報は、ゲーム情報の`map`に入っています。 文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 それをもとにマップのデザインを知る事が出来ます: -* `(スペース)` ... マス無し -* `-` ... マス -* `b` ... 初期配置される黒石 -* `w` ... 初期配置される白石 - -例えば、4*4の次のような単純なマップがあるとします: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -この場合、マップデータはこのようになります: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## ユーザーにフォームを提示して対話可能Botを作成する -ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。 - -フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します: -```javascript -{ - type: 'init-form', - body: [フォームコントロールの配列] -} -``` - -フォームコントロールの配列については今から説明します。 フォームコントロールは、次のようなオブジェクトです: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... コントロールのID。 `type` ... コントロールの種類。後述します。 `label` ... コントロールと一緒に表記するテキスト。 `value` ... コントロールのデフォルト値。 - -### フォームの操作を受け取る -ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### フォームコントロールの種類 -#### Interruptor -type: `switch` スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。 - -##### プロパティ -`label` ... スイッチに表記するテキスト。 - -#### ラジオボタン -type: `radio` ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。 - -##### プロパティ -`items` ... ラジオボタンの選択肢。例: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '強', - value: 3 -}] -``` - -#### スライダー -type: `slider` スライダーを表示します。 - -##### プロパティ -`min` ... スライダーの下限。 `max` ... スライダーの上限。 `step` ... 入力欄で刻むステップ値。 - -#### テキストボックス -type: `textbox` テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。 - -## ユーザーにメッセージを表示する -設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 メッセージを表示するには、次のメッセージをストリームに送信します: -```javascript -{ - type: 'message', - body: { - text: 'メッセージ内容', - type: 'メッセージの種類' - } -} -``` -メッセージの種類: `success`, `info`, `warning`, `error`。 - -## 投了する -投了をするには、このエンドポイントにリクエストします。 diff --git a/src/docs/es-ES/advanced/share-page.md b/src/docs/es-ES/advanced/share-page.md deleted file mode 100644 index 20df38767..000000000 --- a/src/docs/es-ES/advanced/share-page.md +++ /dev/null @@ -1,54 +0,0 @@ -# シェアページ -`/share`を開くと、共有用の投稿フォームを開くことができます。 ここではシェアページで利用できるクエリ文字列の一覧を示します。 - -## クエリ文字列一覧 -### Texto - -
-
title
-
タイトルです。本文の先頭に[ … ]と挿入されます。
-
text
-
本文です。
-
url
-
URLです。末尾に挿入されます。
-
- -### リプライ情報 -以下のいずれか - -
-
replyId
-
リプライ先のノートid
-
replyUri
-
リプライ先のUrl(リモートのノートオブジェクトを指定)
-
- -### Renote情報 -以下のいずれか - -
-
renoteId
-
Renote先のノートid
-
renoteUri
-
Renote先のUrl(リモートのノートオブジェクトを指定)
-
- -### Visibilidad -※specifiedに相当する値はvisibility=specifiedとvisibleAccts/visibleUserIdsで指定する - -
-
visibility
-
公開範囲 ['public' | 'home' | 'followers' | 'specified']
-
localOnly
-
0(false) or 1(true)
-
visibleUserIds
-
specified時のダイレクト先のユーザーid カンマ区切りで
-
visibleAccts
-
specified時のダイレクト先のacct(@?username[@host]) カンマ区切りで
-
- -### Archivos -
-
fileIds
-
添付したいファイルのid(カンマ区切りで)
-
diff --git a/src/docs/es-ES/advanced/stream.md b/src/docs/es-ES/advanced/stream.md deleted file mode 100644 index 97e30e98d..000000000 --- a/src/docs/es-ES/advanced/stream.md +++ /dev/null @@ -1,350 +0,0 @@ -# ストリーミングAPI - -ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。 - -## ストリームに接続する - -ストリーミングAPIを利用するには、まずMisskeyサーバーに**websocket**接続する必要があります。 - -以下のURLに、`i`というパラメータ名で認証情報を含めて、websocket接続してください。例: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。 - -
ℹ️ 認証情報の取得については、こちらのドキュメントをご確認ください。
- ---- - -認証情報は省略することもできますが、その場合非ログインでの利用ということになり、受信できる情報や可能な操作は限られます。例: - -``` -%WS_URL%/streaming -``` - ---- - -ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。 - -**ストリームでのやり取りはすべてJSONです。** - -## Canal -MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。 - -ひとつのストリーム上で、同時に複数のチャンネルに接続することができます。 - -### チャンネルに接続する -チャンネルに接続するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -ここで、 -* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。 -* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。 -* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。 - -
ℹ️ IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。
- -### チャンネルからのメッセージを受け取る -例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。 - -チャンネルがメッセージを発すると、次のようなデータがJSONでストリームに流れてきます: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。 -* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。 -* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。 - -### チャンネルに向けてメッセージを送信する -チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。 - -チャンネルにメッセージを送信するには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。 -* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。 -* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。 - -### チャンネルから切断する -チャンネルから切断するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。 - -## ストリームを経由してAPIリクエストする - -ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。 - -ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -ここで、 -* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 -* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 -* `data`には、エンドポイントのパラメータを含めます。 - -
ℹ️ APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。
- -### レスポンスの受信 - -APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。 - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -ここで、 -* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 -* `body`には、レスポンスが含まれています。 - -## 投稿のキャプチャ - -Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。 - -例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。 - -しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。 - -この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。 - -### 投稿をキャプチャする - -投稿をキャプチャするには、ストリームに次のようなメッセージを送信します: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャしたい投稿の`id`を設定します。 - -このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 - -例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -ここで、 -* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。 -* `body`内の`type`に、イベントの種類が設定されます。 -* `body`内の`body`に、イベントの詳細が設定されます。 - -#### イベントの種類 - -##### `reacted` -その投稿にリアクションがされた時に発生します。 - -* `reaction`に、リアクションの種類が設定されます。 -* `userId`に、リアクションを行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -その投稿が削除された時に発生します。 - -* `deletedAt`に、削除日時が設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -その投稿に添付されたアンケートに投票された時に発生します。 - -* `choice`に、選択肢IDが設定されます。 -* `userId`に、投票を行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### 投稿のキャプチャを解除する - -その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。 - -次のメッセージを送信します: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャを解除したい投稿の`id`を設定します。 - -このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 - -# チャンネル一覧 -## `main` -アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `renote` -自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。 - -#### `mention` -誰かからメンションされたときに発生するイベントです。 - -#### `readAllNotifications` -自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。 - -#### `meUpdated` -自分の情報が更新されたことを表すイベントです。 - -#### `follow` -自分が誰かをフォローしたときに発生するイベントです。 - -#### `unfollow` -自分が誰かのフォローを解除したときに発生するイベントです。 - -#### `followed` -自分が誰かにフォローされたときに発生するイベントです。 - -## `homeTimeline` -ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -タイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `localTimeline` -ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `hybridTimeline` -ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ソーシャルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `globalTimeline` -グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 diff --git a/src/docs/es-ES/aiscript.md b/src/docs/es-ES/aiscript.md deleted file mode 100644 index 3d936e906..000000000 --- a/src/docs/es-ES/aiscript.md +++ /dev/null @@ -1,4 +0,0 @@ -# AiScript - -## funciones -Pasando valores por defecto diff --git a/src/docs/es-ES/api.md b/src/docs/es-ES/api.md deleted file mode 100644 index 76019b614..000000000 --- a/src/docs/es-ES/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス、Bot等(以下「アプリケーション」と呼びます)を開発できます。 ストリーミングAPIもあるので、リアルタイム性のあるアプリケーションを作ることも可能です。 - -APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。 - -## アクセストークンの取得 -基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。 - -* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む -* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む - -### 自分自身のアクセストークンを手動発行する -「設定 > API」で、自分のアクセストークンを発行できます。 - -[「APIの使い方」へ進む](#APIの使い方) - -### アプリケーション利用者にアクセストークンの発行をリクエストする -アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。 - -#### Step 1 - -UUIDを生成する。以後これをセッションIDと呼びます。 - -> このセッションIDは毎回生成し、使いまわさないようにしてください。 - -#### Step 2 - -`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。 -> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます: -* `name` ... アプリケーション名 - * > 例: `MissDeck` -* `icon` ... アプリケーションのアイコン画像URL - * > 例: `https://missdeck.example.com/icon.png` -* `callback` ... 認証が終わった後にリダイレクトするURL - * > 例: `https://missdeck.example.com/callback` - * リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます -* `permission` ... アプリケーションが要求する権限 - * > 例: `write:notes,write:following,read:drive` - * 要求する権限を`,`で区切って列挙します - * どのような権限があるかは[APIリファレンス](/api-doc)で確認できます - -#### Step 3 -ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。 - -レスポンスに含まれるプロパティ: -* `token` ... ユーザーのアクセストークン -* `user` ... ユーザーの情報 - -[「APIの使い方」へ進む](#APIの使い方) - -## APIの使い方 -**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。 - -* [APIリファレンス](/api-doc) -* [ストリーミングAPI](./stream) diff --git a/src/docs/es-ES/create-plugin.md b/src/docs/es-ES/create-plugin.md deleted file mode 100644 index 46db70220..000000000 --- a/src/docs/es-ES/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# プラグインの作成 -Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。 - -## Metadatos -プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。 - -### name -プラグイン名 - -### author -プラグイン作者 - -### version -プラグインバージョン。数値を指定してください。 - -### description -プラグインの説明 - -### permissions -プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。 - -### config -プラグインの設定情報を表すオブジェクト。 キーに設定名、値に以下のプロパティを含めます。 - -#### type -設定値の種類を表す文字列。以下から選択します。 string number boolean - -#### label -ユーザーに表示する設定名 - -#### description -設定の説明 - -#### default -設定のデフォルト値 - -## APIリファレンス -AiScript標準で組み込まれているAPIは掲載しません。 - -### Mk:dialog(title text type) -ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。 - -### Mk:confirm(title text type) -確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。 - -### Mk:api(endpoint params) -Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。 - -### Mk:save(key value) -任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。 - -### Mk:load(key) -Mk:saveで永続化した指定の名前の値を読み取ります。 - -### Plugin:register_post_form_action(title fn) -投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。 - -### Plugin:register_note_action(title fn) -ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 - -### Plugin:register_user_action(title fn) -ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。 - -### Plugin:register_note_view_interruptor(fn) -UIに表示されるノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:register_note_post_interruptor(fn) -ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:open_url(url) -第一引数に渡されたURLをブラウザの新しいタブで開きます。 - -### Plugin:config -プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。 diff --git a/src/docs/es-ES/custom-emoji.md b/src/docs/es-ES/custom-emoji.md deleted file mode 100644 index 842db20f0..000000000 --- a/src/docs/es-ES/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# Emojis personalizados -カスタム絵文字は、インスタンスで用意された画像を絵文字のように使える機能です。 ノート、リアクション、チャット、自己紹介、名前などの場所で使うことができます。 カスタム絵文字をそれらの場所で使うには、絵文字ピッカーボタン(ある場合)を押すか、`:`を入力して絵文字サジェストを表示します。 テキスト内に`:foo:`のような形式の文字列が見つかると、`foo`の部分がカスタム絵文字名と解釈され、表示時には対応したカスタム絵文字に置き換わります。 diff --git a/src/docs/es-ES/deck.md b/src/docs/es-ES/deck.md deleted file mode 100644 index 73e9efdaa..000000000 --- a/src/docs/es-ES/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# Deck - -デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。 - -## カラムの追加 -デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。 - -## カラムの移動 -カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。 - -## カラムの水平分割 -カラムは左右だけでなく、上下に並べることもできます。 カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 上下分割を解除するには、カラムメニューの「右に出す」を選択します。 - -## カラムの設定 -カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。 - -## デッキの設定 -デッキに関する設定は、[settings/deck](/settings/deck)で行えます。 diff --git a/src/docs/es-ES/features/antenna.md b/src/docs/es-ES/features/antenna.md deleted file mode 100644 index f321d79e2..000000000 --- a/src/docs/es-ES/features/antenna.md +++ /dev/null @@ -1,4 +0,0 @@ -# Antenas -アンテナは、自由に条件を設定して、合致するノートを自動で収集することができる機能です。 - -条件を設定したアンテナが作成された状態で、条件に合致するノートが投稿されると、リアルタイムでそのアンテナのタイムラインにノートが追加されます。 diff --git a/src/docs/es-ES/features/custom-emoji.md b/src/docs/es-ES/features/custom-emoji.md deleted file mode 100644 index 842db20f0..000000000 --- a/src/docs/es-ES/features/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# Emojis personalizados -カスタム絵文字は、インスタンスで用意された画像を絵文字のように使える機能です。 ノート、リアクション、チャット、自己紹介、名前などの場所で使うことができます。 カスタム絵文字をそれらの場所で使うには、絵文字ピッカーボタン(ある場合)を押すか、`:`を入力して絵文字サジェストを表示します。 テキスト内に`:foo:`のような形式の文字列が見つかると、`foo`の部分がカスタム絵文字名と解釈され、表示時には対応したカスタム絵文字に置き換わります。 diff --git a/src/docs/es-ES/features/deck.md b/src/docs/es-ES/features/deck.md deleted file mode 100644 index 73e9efdaa..000000000 --- a/src/docs/es-ES/features/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# Deck - -デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。 - -## カラムの追加 -デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。 - -## カラムの移動 -カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。 - -## カラムの水平分割 -カラムは左右だけでなく、上下に並べることもできます。 カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 上下分割を解除するには、カラムメニューの「右に出す」を選択します。 - -## カラムの設定 -カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。 - -## デッキの設定 -デッキに関する設定は、[settings/deck](/settings/deck)で行えます。 diff --git a/src/docs/es-ES/features/drive.md b/src/docs/es-ES/features/drive.md deleted file mode 100644 index c445b99a8..000000000 --- a/src/docs/es-ES/features/drive.md +++ /dev/null @@ -1,17 +0,0 @@ -# Drive -ドライブは、Misskey上でファイルを管理できる機能です。 - -[ドライブのページ](/my/drive)から任意のファイルをアップロードできるほか、アバターに設定した画像や、ノートに添付したファイルなどもすべてドライブにアップロードされます。 - -
⚠️ ドライブからファイルを削除すると、そのファイルが添付されたノートも消えます。
- -ドライブにアップロードされたファイルは、いつでもダウンロードすることができるほか、ノート作成時に「ドライブからファイルを添付」することでファイルを再利用することもできます。 - -ドライブ内にフォルダを作り、複数のファイルをまとめて整理することもできます。 - -## 閲覧注意 (NSFW) -
ℹ️ この項目が閲覧注意なわけではありません
- -閲覧注意またはNSFW (Not safe for work) は、ドライブのファイルに設定することができるフラグです。 閲覧注意フラグを設定されたファイルは、表示される際に閲覧者の操作なしには表示されなくなります。 このフラグは、例えば職場や公共の場で閲覧するのに適切でないと思われる画像などに設定し、そのような画像が突然表示されてしまうことを防ぐ目的で使われます。 - -このフラグは手動でオンオフを切り替えられるほか、モデレーターの判断で設定される場合もあります。 diff --git a/src/docs/es-ES/features/favorite.md b/src/docs/es-ES/features/favorite.md deleted file mode 100644 index f108d2231..000000000 --- a/src/docs/es-ES/features/favorite.md +++ /dev/null @@ -1,4 +0,0 @@ -# Favorito -[ノート](./node)をお気に入りとして登録できる機能です。 お気に入り登録したノートは、[お気に入りページ](./my/favorites)で一覧することができます。 お気に入りに登録したことは相手に通知されず、お気に入りは自分しか見ることができません。 - -ノートをお気に入り登録するには、ノートメニューの「お気に入り」を押します。お気に入り解除するには、ノートメニューの「お気に入り解除」を押します。 diff --git a/src/docs/es-ES/features/follow.md b/src/docs/es-ES/features/follow.md deleted file mode 100644 index 474cc594f..000000000 --- a/src/docs/es-ES/features/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# Siguiendo -ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。 diff --git a/src/docs/es-ES/features/keyboard-shortcut.md b/src/docs/es-ES/features/keyboard-shortcut.md deleted file mode 100644 index 026b0ea0c..000000000 --- a/src/docs/es-ES/features/keyboard-shortcut.md +++ /dev/null @@ -1,66 +0,0 @@ -# キーボードショートカット - -## Global -これらのショートカットは基本的にどこでも使えます。 - - - - - - - - - - - -
ショートカット効果由来
P, N新規投稿Post, New, Note
Tタイムラインの最も新しい投稿にフォーカスTimeline, Top
Shift + N通知を表示/隠すNotifications
SBuscarSearch
H, ?ヘルプを表示Help
- -## 投稿にフォーカスされた状態 - - - - - - - - - - - - - - - - - - -
ショートカット効果由来
, K, Shift + Tab上の投稿にフォーカスを移動-
, J, Tab下の投稿にフォーカスを移動-
R返信フォームを開くReply
QRenoteフォームを開くQuote
Ctrl + Q即刻Renoteする(フォームを開かずに)-
E, A, +リアクションフォームを開くEmote, reAction
0~9数字に対応したリアクションをする(対応については後述)-
F, Bお気に入りに登録Favorite, Bookmark
Del, Ctrl + D投稿を削除Delete
M, O投稿に対するメニューを開くMore, Other
SCWで隠された部分を表示 or 隠すShow, See
Escフォーカスを外す-
- -## Renoteフォーム - - - - - - - - - -
ショートカット効果由来
EnterRenoteする-
Qフォームを展開するQuote
Escフォームを閉じる-
- -## リアクションフォーム -デフォルトで「👍」にフォーカスが当たっている状態です。 - - - - - - - - - - - - - -
ショートカット効果由来
, K上のリアクションにフォーカスを移動-
, J下のリアクションにフォーカスを移動-
, H, Shift + Tab左のリアクションにフォーカスを移動-
, L, Tab右のリアクションにフォーカスを移動-
Enter, Space, +リアクション確定-
0~9数字に対応したリアクションで確定-
Escリアクションするのをやめる-
diff --git a/src/docs/es-ES/features/mfm.md b/src/docs/es-ES/features/mfm.md deleted file mode 100644 index 5be2df4f3..000000000 --- a/src/docs/es-ES/features/mfm.md +++ /dev/null @@ -1,12 +0,0 @@ -# MFM -MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます。 - -## MFMが使用可能な場所の例 -- ノート本文 -- CW注釈 -- ユーザーの名前 -- ユーザーの自己紹介 - -## 開発者向け情報 -MFMのパーサー実装はライブラリとして公開されており、簡単にクライアントにMFMを組み込むことが可能です。 -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptパーサー実装 diff --git a/src/docs/es-ES/features/mute-and-block.md b/src/docs/es-ES/features/mute-and-block.md deleted file mode 100644 index b876f898b..000000000 --- a/src/docs/es-ES/features/mute-and-block.md +++ /dev/null @@ -1,41 +0,0 @@ -# Silenciar y bloquear -好みではないユーザーがいる場合は、ミュートを行うことでそのユーザーが自分から見えないようにすることができます。 また、より強力な措置として、ブロックを行うことでそのユーザーから自分のコンテンツが見えないようになるほか、自分に対して関わることができないようにすることができます。 ミュートされていることは相手は分かりませんが、ブロックされていることは相手に分かります。どちらを選ぶかはご自身の判断で行ってください。 - -
ℹ️ ミュートとブロックは併用できます。
- -
⚠️ 利用規約に違反するような、迷惑なユーザーがいる場合は運営者に報告することも検討してください。
- -設定>ミュートとブロック から、自分がミュートまたはブロックしているユーザー一覧を確認することができます。 - -## Silenciar -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -- タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -- そのユーザーからの通知 -- メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 -- など - -ユーザーをミュートするには、対象のユーザーのユーザーページのメニューを開き、「ミュート」ボタンを押します。 - -
ℹ️ ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。
- -## Bloquear -ユーザーをブロックすると、そのユーザーからあなたのコンテンツが見えないようになり、またあなたに対して以下のようなアクションをすることができなくなります。 - -- フォローする -- ユーザーリストに追加する -- 返信する、Renoteする -- リアクションする、アンケートに投票する -- メッセージを送信する -- など - -また、 - -- ブロックする際に既にそのユーザーからフォローされていた場合はフォローが解除されます。 -- ブロックする際に既にそのユーザーがあなたをユーザーリストに入れていた場合はそのリストからあなたが削除されます。 - -ユーザーをブロックするには、対象のユーザーのユーザーページのメニューを開き、「ブロック」ボタンを押します。 - -
⚠️ ブロックを行ったこと自体は相手に通知されませんが、フォローを行ったりなどの上記のアクションが行えなくなるので間接的にブロックされていることは分かります。
- -
⚠️ 相手から自分のコンテンツが見えなくなりますが、相手がアカウントを切り替えたりログアウト状態になれば見ることができます。あくまで簡易的、補助的なものとしてお考えください。
diff --git a/src/docs/es-ES/features/mute.md b/src/docs/es-ES/features/mute.md deleted file mode 100644 index 331e5cc10..000000000 --- a/src/docs/es-ES/features/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# Silenciar - -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -* タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -* そのユーザーからの通知 -* メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 - -ユーザーをミュートするには、対象のユーザーのユーザーページに表示されている「ミュート」ボタンを押します。 - -ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。 - -設定>ミュート から、自分がミュートしているユーザー一覧を確認することができます。 diff --git a/src/docs/es-ES/features/note.md b/src/docs/es-ES/features/note.md deleted file mode 100644 index 857c16042..000000000 --- a/src/docs/es-ES/features/note.md +++ /dev/null @@ -1,54 +0,0 @@ -# Notas -ノートは、Misskeyに投稿される、文章、ファイル、アンケートなどを含むコンテンツで、Misskeyの中心的概念です。また、そのノートを作成する行為自体もノートと呼ばれます。 - -ノートが作成されると、[タイムライン](./timeline)に追加され、自分の[フォロワー](./follow)やサーバーのユーザーが見れるようになります。 - -ノートには、[リアクション](./reaction)を行うことができます。また、返信や引用もできます。 - -ノートを[お気に入り](./favorite)登録することで、後で簡単に見返すことができます。 - -## ノートを作成する -ノートを作成するには、画面上にある鉛筆マークのボタンを押して、作成フォームを開きます。作成フォームに内容を入力し、「ノート」ボタンを押すことでノートが作成されます。 ノートには、画像、動画など任意のファイルや、[アンケート](./poll)を添付することができます。また、本文中には[MFM](./mfm)が使用でき、[メンション](./mention)や[ハッシュタグ](./hashtag)を含めることもできます。 他にも、CWや公開範囲といった設定も行えます(詳細は後述)。 -
ℹ️ コンピューターのクリップボードに画像データがある状態で、フォーム内のテキストボックスにペーストするとその画像を添付することができます。
-
ℹ️ テキストボックス内でCtrl + Enterを押すことでも投稿できます。
- -## Renotar -既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノートをRenoteと呼びます。 自分がフォローしているユーザーの、気に入ったノートを自分のフォロワーに共有したい場合や、過去の自分のノートを再度共有したい場合に使います。 同じノートに対して無制限にRenoteを行うことができますが、あまり連続して使用すると迷惑になる場合もあるので、注意しましょう。 -
⚠️ 公開範囲がフォロワーやダイレクトのノートはRenoteできません
- -Renoteを削除するには、Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 - -## CW -Contents Warningの略で、ノートの内容を、閲覧者の操作なしには表示しないようにできる機能です。主に長大な内容を隠すためや、ネタバレ防止などに使うことができます。 設定するには、フォームの「内容を隠す」ボタン(目のアイコン)を押します。すると新しい入力エリアが表れるので、そこに内容の要約を記入します。 - -## Visibilidad -ノートごとに、そのノートが公開される範囲を設定することができます。フォームの「ノート」ボタンの左にあるアイコンを押すと公開範囲を以下から選択できます。 - -### Público -全ての人に対してノートが公開されるほか、サーバーの全てのタイムライン(ホームタイムライン、ローカルタイムライン、ソーシャルタイムライン、グローバルタイムライン)にノートが流れます。 -
⚠️ アカウントがサイレンス状態の時は、この公開範囲は使用できません。
- -### Inicio -全ての人に対してノートが公開されますが、フォロワー以外のローカルタイムライン、ソーシャルタイムライン、グローバルタイムラインにはノートは流れません。 - -### Seguidores -自分のフォロワーに対してのみノートを公開します。フォロワーの全てのタイムラインに流れます。 - -### Mensaje directo -指定したユーザーに対してのみノートを公開します。指定したユーザーの全てのタイムラインに流れます。 - -### 「ローカルのみ」オプション -このオプションを有効にすると、リモートにノートを連合しなくなります。 - -### 公開範囲の比較 - - - - -
PúblicoInicioSeguidoresMensaje directo
フォロワーのLTL/STL/GTL
非フォロワーのLTL/STL/GTL
- -## Fijar -ノートをピン留めすると、ユーザーページに常にそのノートを表示しておくことができます。 ノートのメニューを開き、「ピン留め」を選択してピン留めできます。 複数のノートをピン留めできます。 - -## Ver -ノートをウォッチすると、自分以外のノートへのリアクションや返信などの通知を受け取ることができます。 ノートのメニューを開き、「ウォッチ」を選択してウォッチできます。 diff --git a/src/docs/es-ES/features/pages.md b/src/docs/es-ES/features/pages.md deleted file mode 100644 index 7fc6ee29c..000000000 --- a/src/docs/es-ES/features/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# Pages - -## Variables -変数を使うことで動的なページを作成できます。テキスト内で { 変数名 } と書くとそこに変数の値を埋め込めます。例えば Hello { thing } world! というテキストで、変数(thing)の値が ai だった場合、テキストは Hello ai world! になります。 - -変数の評価(値を算出すること)は上から下に行われるので、ある変数の中で自分より下の変数を参照することはできません。例えば上から A、B、C と3つの変数を定義したとき、Cの中でABを参照することはできますが、Aの中でBCを参照することはできません。 - -ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。 - -関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。 diff --git a/src/docs/es-ES/features/reaction.md b/src/docs/es-ES/features/reaction.md deleted file mode 100644 index 3d13c8fae..000000000 --- a/src/docs/es-ES/features/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# Reacción -他の人のノートに、絵文字を付けて簡単にあなたの反応を伝えられる機能です。 リアクションするには、ノートの + アイコンをクリックしてピッカーを表示し、絵文字を選択します。 リアクションには[カスタム絵文字](./custom-emoji)も使用できます。 - -## リアクションピッカーのカスタマイズ -ピッカーに表示される絵文字を自分好みにカスタマイズすることができます。 設定の「リアクション」で設定します。 - -## リモート投稿へのリアクションについて -リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。 - -## リモートからのリアクションについて -リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。 diff --git a/src/docs/es-ES/features/silence.md b/src/docs/es-ES/features/silence.md deleted file mode 100644 index 31292d905..000000000 --- a/src/docs/es-ES/features/silence.md +++ /dev/null @@ -1,6 +0,0 @@ -# Silenciar -サイレンスは、アカウントに設定される状態のひとつです。 - -アカウントがサイレンス状態になると、ノートの公開範囲をパブリックにできなくなります。 ホーム、フォロワー、ダイレクトは選択可能なため、サイレンスを受けた場合でもフォロワーやあなたのユーザーページを直接訪れた場合は投稿を閲覧できますが、GTL(連合タイムライン)やLTL(ローカルタイムライン)には投稿が流れません。 - -アカウントのサイレンス状態は、サーバーのモデレーターによって有効化/無効化されます。 diff --git a/src/docs/es-ES/features/theme.md b/src/docs/es-ES/features/theme.md deleted file mode 100644 index 3e379ee5f..000000000 --- a/src/docs/es-ES/features/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# Tema - -テーマを設定して、Misskeyクライアントの見た目を変更できます。 - -## テーマの設定 -設定 > テーマ - -## テーマを作成する -テーマコードはJSON5で記述されたテーマオブジェクトです。 テーマは以下のようなオブジェクトです。 -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... テーマの一意なID。UUIDをおすすめします。 -* `name` ... テーマ名 -* `author` ... テーマの作者 -* `desc` ... テーマの説明(オプション) -* `base` ... 明るいテーマか、暗いテーマか - * `light`にすると明るいテーマになり、`dark`にすると暗いテーマになります。 - * テーマはここで設定されたベーステーマを継承します。 -* `props` ... テーマのスタイル定義。これから説明します。 - -### テーマのスタイル定義 -`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 - -#### バリューで使える構文 -* 16進数で表された色 - * 例: `#00ff00` -* `rgb(r, g, b)`形式で表された色 - * 例: `rgb(0, 255, 0)` -* `rgb(r, g, b, a)`形式で表された透明度を含む色 - * 例: `rgba(0, 255, 0, 0.5)` -* 他のキーの値の参照 - * `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。 - * 例: `@panel` -* 定数(後述)の参照 - * `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。 - * 例: `$main` -* 関数(後述) - * `:{関数名}<{引数}<{色}` - -#### Constante -「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 キー名を`$`で始めると、そのキーはCSS変数として出力されません。 - -#### funciones -wip diff --git a/src/docs/es-ES/features/timeline.md b/src/docs/es-ES/features/timeline.md deleted file mode 100644 index 026f2139f..000000000 --- a/src/docs/es-ES/features/timeline.md +++ /dev/null @@ -1,31 +0,0 @@ -# Linea de tiempo -タイムラインは、[ノート](./note)が時系列で表示される機能です。 タイムラインには以下で示す種類があり、種類によって表示されるノートも異なります。 なお、タイムラインの種類によってはサーバーにより無効になっている場合があります。 - -## Inicio -自分のフォローしているユーザーの投稿が流れます。HTLと略されます。 - -## Local -全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。LTLと略されます。 - -## Social -自分のフォローしているユーザーの投稿と、全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。STLと略されます。 - -## Global -全てのローカルユーザーの「ホーム」指定されていない投稿と、サーバーに届いた全てのリモートユーザーの「ホーム」指定されていない投稿が流れます。GTLと略されます。 - -## Comparar -| ソース | | | Linea de tiempo | | | -| ------------ | ----------- | ------ | --------------- | ------ | ------ | -| Usuarios | Visibilidad | Inicio | Local | Social | Global | -| ローカル (フォロー) | 公開 | ✔ | ✔ | ✔ | ✔ | -| | Inicio | ✔ | | ✔ | | -| | Seguidores | ✔ | ✔ | ✔ | ✔ | -| リモート (フォロー) | 公開 | ✔ | | ✔ | ✔ | -| | Inicio | ✔ | | ✔ | | -| | Seguidores | ✔ | | ✔ | ✔ | -| ローカル (未フォロー) | 公開 | | ✔ | ✔ | ✔ | -| | Inicio | | | | | -| | Seguidores | | | | | -| リモート (未フォロー) | 公開 | | | | ✔ | -| | Inicio | | | | | -| | Seguidores | | | | | diff --git a/src/docs/es-ES/features/widgets.md b/src/docs/es-ES/features/widgets.md deleted file mode 100644 index 7c5cacb39..000000000 --- a/src/docs/es-ES/features/widgets.md +++ /dev/null @@ -1,7 +0,0 @@ -# Widgets -ウィジェットは、MisskeyのUI上に設置できる小型の情報表示、操作が行えるパーツです。 - -ウィジェットを編集するには、ウィジェット編集モードに切り替えます。切り替え方法はUIによって異なります。 ウィジェット編集モードでは、ウィジェットの追加、削除、並び替え、およびそれぞれのウィジェットの設定を行えます。 - -## 利用可能なウィジェット一覧 -todo diff --git a/src/docs/es-ES/features/word-mute.md b/src/docs/es-ES/features/word-mute.md deleted file mode 100644 index 3e3bec290..000000000 --- a/src/docs/es-ES/features/word-mute.md +++ /dev/null @@ -1,20 +0,0 @@ -# Silenciar palabras -ワードミュートの設定をすると、条件に合致したノートが表示されなくなります。 - -ワードミュートには、ソフトワードミュートとハードワードミュートの2種類があります。それぞれについて設定の方法と挙動を説明します。 - -## ソフトワードミュート -ソフトワードミュートは、クライアント(アプリ)側でミュートを判断するワードミュートです。 - -ノートが設定した条件に合致すると、「(ユーザー名)が何かを言いました」という表示で隠れます。 -クリックすると元の通りに表示されます。 - -## ハードワードミュート -ハードワードミュートは、アンテナのようにサーバーが新しいノートの本文に対して条件に合致するかどうか判断し、タイムラインから対象となったノートを除外します。 - -つまり、ハードワードミュートには、以下のような特徴があります。 - -* 条件設定後、新しい投稿のみがミュートの対象になります。 -* 条件を変更しても、過去にハードミュートされたノートはミュートされたままになります。 -* 「○○が何かを言いました」でタイムラインが埋まることがありません。 -* ソフトミュートに非対応のアプリでも、ハードミュートは適用されます。 diff --git a/src/docs/es-ES/follow.md b/src/docs/es-ES/follow.md deleted file mode 100644 index 474cc594f..000000000 --- a/src/docs/es-ES/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# Siguiendo -ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。 diff --git a/src/docs/es-ES/general/apps.md b/src/docs/es-ES/general/apps.md deleted file mode 100644 index 1f4c85fe8..000000000 --- a/src/docs/es-ES/general/apps.md +++ /dev/null @@ -1,6 +0,0 @@ -# サードパーティアプリのリスト -## クライアント -todo - -## 連携サービス -todo diff --git a/src/docs/es-ES/general/changelog.md b/src/docs/es-ES/general/changelog.md deleted file mode 100644 index 6766a63b2..000000000 --- a/src/docs/es-ES/general/changelog.md +++ /dev/null @@ -1,5 +0,0 @@ -# 更新履歴 -
ℹ️ このサーバーの更新履歴です。Misskeyの最新のリリースについては、GitHubをご確認ください。
- - - diff --git a/src/docs/es-ES/general/faq.md b/src/docs/es-ES/general/faq.md deleted file mode 100644 index c272b2ad4..000000000 --- a/src/docs/es-ES/general/faq.md +++ /dev/null @@ -1,28 +0,0 @@ -# よくある質問 -ここでは利用上のよくある質問について掲載しています。 Misskeyのプロジェクト自体についてのよくある質問は[こちら](./misskey)に掲載されています。 - -## iOS/Androidのアプリはありますか? -公式にはそういったOSのネイティブアプリを開発していませんが、サードパーティ製のアプリがいくつかあります。 詳しくは[こちら](./apps)をご覧ください。 - -ただ、サードパーティ製アプリはどうしても機能への対応が遅れてしまうため、とくに拘りがなければ公式のWebクライアントの利用をおすすめします。 なお、MisskeyのWebクライアントはPWAに対応しているので、ネイティブアプリのように動作させることも可能です。 詳しくは[こちら](todo)をご覧ください。 - -## Mastodonクライアントでログインできないのですが? -MisskeyはMastodonのAPIと互換性がないため、一部を除きMastodonクライアントでMisskeyを利用することはできません。 - -## 他のサーバーのユーザーをフォローするときは? -メニューから検索を選び、ユーザー名をホスト込みで入力します。例: `@syuilo@misskey.io` - -## Renoteを削除するには? -Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 Renoteについては[こちら](../features/note)をご確認ください。 - -## URLのプレビューを表示させたくない -MFMには、そのURLのプレビューを無効にする構文があります。詳細は[MFMチートシート](/mfm-cheat-sheet)をご確認ください。 - -## カスタム絵文字を追加したい -運営者のみがカスタム絵文字を追加、編集、削除できます。それらを希望する場合は運営者に依頼してください。 - -## Botを開発したい -Misskey APIを利用してBotの開発が可能です。[こちら](../advanced/develop-bot)をご確認ください。 - -## ノートの翻訳機能はどのサービスを使用していますか? -[DeepL](https://www.deepl.com/)を使用しています。 diff --git a/src/docs/es-ES/general/glossary.md b/src/docs/es-ES/general/glossary.md deleted file mode 100644 index 4bef9068f..000000000 --- a/src/docs/es-ES/general/glossary.md +++ /dev/null @@ -1,89 +0,0 @@ -# 用語集 -Misskeyに関する用語集です。 - -## ActivityPub -(読み: あくてぃびてぃぱぶ) 分散型を実現するために用いられるプロトコル(仕様)。このプロトコルに則ってサーバー同士通信を行うことで、連合が行われ、Fediverseを形成しています。 - -## AiScript -(読み: あいすくりぷと) Misskey上で使用できるプログラミング言語です。詳細は[こちら。](../advanced/aiscript) - -## API -(読み: えーぴーあい) Misskeyのサーバーが公開している、プログラムからMisskeyを扱うためのインターフェース。詳細は[こちら。](../advanced/api) - -## Bot -(読み: ぼっと) プログラムによって動作しているアカウント。 - -## CW -(読み: こんてんつわーにんぐ) Contents Warningの略。ノートの内容を、操作なしには表示しないようにできる機能。主に長大な内容を隠すためや、ネタバレ防止などに使われます。 - -## Fediverse -(読み: ふぇでぃばーす) Misskeyを含む様々な分散型ソフトウェアのサーバーで構成されたネットワーク。 - -## GTL -グローバルタイムライン(Global TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## HTL -ホームタイムライン(Home TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## LTL -ローカルタイムライン(Local TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## MFM -(読み: えむえふえむ) Misskey Flavored Markdownの略で、Misskey上で使用できるマークアップ言語です。詳細は[こちら。](../features/mfm) - -## NSFW -(読み: のっとせーふふぉーわーく) Not Safe For Workの略。画像を「閲覧注意」扱いにし、操作なしには表示しないようにすることができる機能。 - -## Renotar -(読み: りのーと) 既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノート。詳細は[こちら。](../features/note) - -## STL -ソーシャルタイムライン(Social TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## 藍 -(読み: あい) Misskeyの看板娘(公式キャラクター)です。 - -## アクティブユーザー -インスタンスにアカウントを作っているユーザーのうち、現在も実際にサービスを利用しているユーザーのこと。 - -## Instancia -todo - -## Emojis personalizados -サーバーで用意された絵文字。カスタム絵文字ではない通常の絵文字は「Unicode絵文字」と区別して呼ばれる。 - -## コントロールパネル -インスタンスの設定画面のこと。 - -## Servidor -todo - -## Silenciar -ノートをパブリックな公開範囲で投稿できなくされている状態。モデレーターの判断でユーザーごとに設定されます。詳細は[こちら。](../features/silence) - -## Cola de trabajos -アクティビティ配送などを順番に行うためのシステム。 - -## Suspender -アカウントが使用不可に設定されている状態。 - -## Drive -Misskeyにアップロードしたファイルを管理する機能。詳細は[こちら。](../features/drive) - -## Notas -Misskeyに投稿される、文章、ファイル、アンケートなどを含めることができるコンテンツ。詳細は[こちら。](../features/note) - -## ミスキスト -Misskeyを使う人のこと。 - -## Moderador -スパムの凍結およびサイレンスや不適切な投稿の削除など、コミュニティ運営に関する権限を持つユーザー。 - -## Remoto -他サーバーのことを指します。リモートユーザーといったように接頭辞としても使われます。ローカルの逆です。 - -## Federación -サーバー上で作成された情報が他のサーバーに伝わること。 - -## Local -自サーバーのことを指します。ローカルユーザー、ローカルタイムラインといったように接頭辞としても使われます。リモートの逆です。 diff --git a/src/docs/es-ES/general/links.md b/src/docs/es-ES/general/links.md deleted file mode 100644 index 5ce5e1ddb..000000000 --- a/src/docs/es-ES/general/links.md +++ /dev/null @@ -1,12 +0,0 @@ -# リンク集 - -## Webサイト -- [Official Discord](https://discord.gg/Wp8gVStHW3) - Misskey公式Discordサーバー -- [Misskey Forum](https://forum.misskey.io/) - Misskeyに関する話題を扱うフォーラム - -## アカウント -- [@repo@misskey.io](https://misskey.io/@repo) - Misskeyのリポジトリの更新を投稿するbot - -## ライブラリ -- [misskey-dev/misskey.js](https://github.com/misskey-dev/misskey.js) - JavaScriptのMisskey SDK -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptのMFMパーサー実装 diff --git a/src/docs/es-ES/general/misskey.md b/src/docs/es-ES/general/misskey.md deleted file mode 100644 index aa16437c2..000000000 --- a/src/docs/es-ES/general/misskey.md +++ /dev/null @@ -1,87 +0,0 @@ -# Sobre Misskey - -Misskeyはオープンソースの分散型マイクロブログプラットフォームプロジェクトです。 開発は日本でsyuiloによって2014年から開始されました。 ドライブ、リアクションなどの豊富な機能や、高いカスタマイズ性を備えたUIを持つことが特徴です。 - -## 歴史 -開発当初は掲示板がメインのサービスでしたが、ユーザーが短文を投稿し、それを時系列で流れるタイムライン機能を追加したところ人気が高まり、徐々にそれがメインとして開発が進むようになりました。 当初は分散型ではありませんでしたが、2018年にActivityPubを実装し分散型になったことで、より多くの方に認知され利用されるサービスになり、現在に至ります。 -
ℹ️ Misskeyという名前は、syuiloが当時聴いていたMay'nというアーティストの楽曲、Brain Diverの歌詞に由来します。
- -誰でも開発に参加することができ、現在でも活発に開発が続いています。 - -## 分散型とは何か? - -分散(distributed)型とは、非中央集権(decentralized)とも呼ばれ、コミュニティが多数のサーバーに分散して存在し、それらが相互に通信(連合、federation)することでコンテンツ共有ネットワーク(Fediverse)を形成していることが特徴のサービスです。 単一のサーバーしか存在しない、もしくは複数存在しても互いに独立している場合は中央集権なサービスと言われ、例えばTwitterやFacebookなどほとんどのサービスがそれに該当します。 分散型のメリットは、自分に合った運営者やテーマのサーバーを選択できることです。自分でサーバーを作成することもできます。連合するおかげで、どのサーバーを選んでも、同じコミュニティにアクセスできます。 - -## 常にオープンソース -Misskeyはこれまでもこれからも、オープンソースであり続けます。オープンソースとは、簡単に言うとソフトウェアのソースコード(プログラム)が公開されていることです。ソースコードの修正や再配布が可能であることを定義に含めることもあります。 Misskeyのすべてのソースコードは[AGPL](https://github.com/misskey-dev/misskey/blob/develop/LICENSE)というオープンソースライセンスの下に[公開](https://github.com/misskey-dev)されていて、誰でも自由に閲覧、使用、修正、改変、再配布をすることができます。 オープンソースは、自分で好きなように変えたり、有害な処理が含まれていないことを確認することができたり、誰でも開発に参加できるなどの、様々なメリットがあります。 上述の分散型を実現するためにも、オープンソースであるということは必要不可欠な要素です。 再び引き合いに出しますが、TwitterやFacebookなどの利益を得ているほとんどのサービスはオープンソースではありません。 - -
ℹ️ 技術的に言うと、MisskeyのソースコードはGitで管理されていて、リポジトリはGitHub上でホスティングされています。
- -## 開発に参加する、プロジェクトを支援する -Misskeyを気に入っていただけたら、ぜひプロジェクトを支援してください。プロジェクトに貢献するには、以下で紹介するようにいろいろな方法があります。方法によっては開発のスキルは不要なので、誰でも気軽に参加し貢献することができます。いつでもお待ちしています。 - -### 機能を追加したり、バグを修正する -ソフトウェアエンジニアのスキルをお持ちの方であれば、ソースコードを編集する形でプロジェクトに貢献することができます。 貢献についてのガイドは[こちら](https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md)です。 - -### 議論に参加する -新しい機能、または既存の機能について意見を述べたり、不具合を報告したりすることでも貢献できます。 そのようなディスカッションは[GitHub](https://github.com/misskey-dev)上か、[フォーラム](https://forum.misskey.io/)等で行われます。 - -### テキストを翻訳する -Misskeyは様々な言語に対応しています(i18n -internationalizationの略- と呼ばれます)。元の言語は基本的に日本語ですが、有志によって他の言語へと翻訳されています。 その翻訳作業に加わっていただくことでもMisskeyに貢献できます。 Misskeyは[Crowdinというサービスを使用して翻訳の管理を行っています。](https://crowdin.com/project/misskey) - -### 感想を投稿する -不具合報告等だけではなく、Misskeyの良い点、楽しい点といったポジティブな意見もぜひ共有してください。開発の励みになり、それは間接的ですがプロジェクトへの貢献です。 - -### ミスキストを増やす -ミスキストとは、Misskeyを使用する人のことです。 知り合いに紹介するなどしてMisskeyを広めていただければ、ミスキストが増え開発のモチベーションが上がります。 - -### 寄付をする -Misskeyはビジネスではなく、利用は無料であるため、収益は皆様からの寄付のみです。(インスタンスによっては広告収入を得ているような場合もありますが、それは運営者の収入であり直接開発者への収入にはなりません) 寄付をしていただければ、今後も開発を続けることが可能になり、プロジェクトへの貢献になります。 寄付は基本的には[Patreon](https://www.patreon.com/syuilo)で受け付けています。 一定額寄付していただけると、Misskeyの[情報ページ](/about-misskey)に名前を記載することができます。 - -また、サーバーの運営者も、基本的には収益を得ていません。サーバーの運営にはコストがかかるので、運営者の支援をすることもご検討ください。 開発には直接関係しませんが、サーバーがあってこそのプロジェクトなので、運営が維持されるというのは開発と同じくらい重要なことです。 - -## クレジット -Misskeyの開発者や、Misskeyに寄付をしてくださった方の一覧は[こちら](/about-misskey)で見ることができます。 - -## よくある質問 -### プロジェクトは何を目指していますか? -強いて言うと、漠然的になりますが広く使われる汎用的なプラットフォームになることを目指しています。 Misskeyは他のプロジェクトとは違い、何らかの思想(例えば、反中央集権)やビジョンに基づいて開発が行われているわけではなく、その点ではフラットです。 それが逆に、特定の方向性に縛られないフレキシブルさを生み出すことに繋がっていると感じています。 - - -### 企業によって開発されていますか? -いいえ。Misskeyの開発は個人で行われており、商業的でもないため、特定の企業の関りはありません。 開発メンバーも基本的にはボランティアです。 また、開発に対し企業のスポンサーがつくこともありますが、その場合でもやはり開発は個人のコミュニティが主体です。 - -### 誰が運営していますか? -Misskeyは分散型なため、各サーバーにそれぞれ異なった運営者がいます。従って、特定の個人や企業によって、Misskeyの全てが運営されているわけではありません。 また、開発チームが運営を行うわけでもないため、運営に関する連絡は、お使いのサーバーの運営者に行ってください。 サーバーの運営者は、[このページ](/about)で確認することができます。 あなたがサーバーを作成すれば、あなたが運営者になります。 - -### どのサーバーを選べばいいですか? -[サーバー一覧が公開されています。](https://join.misskey.page/ja-JP/instances) サーバーによってコミュニティのテーマ(特定のこと、ものが好き 等)が決められている場合があるので、自分に合ったテーマのサーバーがあれば、そこを選ぶと良いかもしれません。 他にも、サーバーの規模、ユーザー層、国および言語、運営者が信頼できるかどうか、などの観点があります。 なお、Misskey公式のサーバーというものはありません。自身で新しくサーバーを作成するという選択肢もあります。 - -基本的にどのサーバーを選んだとしても、他の全てのサーバーのユーザーと繋がることができます。 - -### サーバーを建てるにはどうしたらいいですか? -Misskeyサーバーの作成に興味を持っていただきありがとうございます。 2021年現在、Misskeyのホスティングサービスは存在しないため、サーバーの作成にはある程度の知識が必要です。 サーバーの作成方法については[こちら](todo)をご覧ください。 - -### どのような技術を使用していますか? -Misskeyは開発が進むにつれ使用する技術も大きく変わってきました。開発当初はMySQL + PHP + jQueryといった構成でしたが、現在は以下のようになっています。 -- サーバーサイド: Node.js -- データベース: PostgreSQL、Redis -- UIフレームワーク: Vue.js -- プログラミング言語: TypeScript - -また、MFMやAiScriptなどの、Misskeyから派生して独自の技術も開発しています。 - -### Mastodonのフォークですか? -いいえ。MisskeyはMastodonやその他のプロジェクトとは全く別のプロジェクトです。 開発に関しても、Misskeyの方が昔から開発されています。ただし、分散型になったのはMastodonの登場より後です。 同じActivityPubという分散のためのプロトコルを実装しているという点以外、両者に特に関りがあるわけでもありません。 - -### iOS/Androidのアプリはありますか? -公式にはそういったOSのネイティブアプリを開発していませんが、サードパーティ製のアプリがいくつかあります。 詳しくは[こちら](./apps)をご覧ください。 - -ただ、サードパーティ製アプリはどうしても機能への対応が遅れてしまうため、とくに拘りがなければ公式のWebクライアントの利用をおすすめします。 なお、MisskeyのWebクライアントはPWAに対応しているので、ネイティブアプリのように動作させることも可能です。 詳しくは[こちら](todo)をご覧ください。 - -### Misskeyのロゴ、アイコンはどこで入手できますか? -(準備中) - -### 時折目にする猫耳の可愛い女の子は? -Misskeyの守り神、藍ちゃんです。アイチャンカワイイヤッター! -
ℹ️ 藍ちゃんについてはこちらです。
diff --git a/src/docs/es-ES/general/report-issue.md b/src/docs/es-ES/general/report-issue.md deleted file mode 100644 index 63527e32a..000000000 --- a/src/docs/es-ES/general/report-issue.md +++ /dev/null @@ -1,8 +0,0 @@ -# 不具合の報告 -不具合と思われる状況に遭遇したときは、まず[トラブルシューティング](./troubleshooting)をご一読ください。 それでも問題が解決しないときは、以下の情報を含めて[フォーラム](https://forum.misskey.io/)に投稿してください。 投稿することで、解決策が見つかったり、不具合と判断されれば開発チームによって修正が行われます。 - -## 含める情報 -- Misskeyのバージョン([情報ページ](/about)で確認できます) -- お使いのブラウザの種類とバージョン -- お使いのOSの種類とバージョン -- 問題の再現手順 diff --git a/src/docs/es-ES/general/troubleshooting.md b/src/docs/es-ES/general/troubleshooting.md deleted file mode 100644 index 2bedfc312..000000000 --- a/src/docs/es-ES/general/troubleshooting.md +++ /dev/null @@ -1,40 +0,0 @@ -# Solución de problemas -
ℹ️ よくある質問も合わせてお役立てください。
- -問題が発生したときは、まずこちらをご確認ください。 該当する項目が無い、もしくは手順を試しても効果がない場合は、サーバーの管理者に連絡するか[不具合を報告](./report-issue)してください。 - -## クライアントが起動しない -ほとんどの場合、お使いのブラウザまたはOSのバージョンが古いことが原因です。 ブラウザおよびOSのバージョンを最新のものに更新してから、再度試してみてください。 - -これは稀ですが、それでも起動しない場合は、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。 - -## ページが読み込めない -クライアントが起動するもののページが読み込めないというエラーが出る場合は、ネットワークに問題がないか確認してください。また、サーバーがダウンしていないか確認してください。 - -これは稀ですが、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。 - -まだ問題がある場合は、サーバーの問題と思われるのでサーバーの管理者に連絡してください。 - -## クライアントの動作が遅い -以下を試してみてください: - -- クライアント設定で「UIのアニメーションを減らす」を有効にする -- クライアント設定で「モーダルにぼかし効果を使用」を無効にする -- お使いのブラウザの設定でハードウェアアクセラレーションを有効にする -- お使いのデバイスのスペックを上げる - -## UIの一部の表示がおかしい(背景が透明になっている等) -アップデートによりUIの改修が行われたときに、テーマのキャッシュシステムの影響でそのような表示になることがあります。 クライアントの設定の「キャッシュをクリア」すると直ります。 -
⚠️ 「クライアントの」キャッシュクリアです。「ブラウザの」キャッシュクリアは行わないでください。
- -## 通知やアンテナ等の点滅が消えない -点滅は、未読のコンテンツがあることを示しています。通常点滅が消えない場合は、コンテンツを遡ると未読なコンテンツが残っています。 すべて既読にしたと思われるのに、それでもなお点滅が続く場合(おそらく不具合と思われます)は設定から強制的にすべて既読扱いにすることができます。 - -## Renoteができない -フォロワー限定のノートはRenoteすることはできません。 - -## UI上で特定の要素が表示されない -広告ブロッカーを使用しているとそのような不具合が発生することがあります。Misskeyではオフにしてご利用ください。 - -## UI上で未翻訳の部分がある -ほとんどの場合、単に翻訳が間に合っていないだけで、不具合ではありません。翻訳が終わるまでお待ちください。 [翻訳に参加](./misskey)していただくことも可能です。 diff --git a/src/docs/es-ES/keyboard-shortcut.md b/src/docs/es-ES/keyboard-shortcut.md deleted file mode 100644 index 27162c6b2..000000000 --- a/src/docs/es-ES/keyboard-shortcut.md +++ /dev/null @@ -1,68 +0,0 @@ -# キーボードショートカット - -## Global -これらのショートカットは基本的にどこでも使えます。 - - - - - - - - - - - -
ショートカット効果由来
P, N新規投稿Post, New, Note
Tタイムラインの最も新しい投稿にフォーカスTimeline, Top
Shift + N通知を表示/隠すNotifications
SBuscarSearch
H, ?ヘルプを表示Help
- -## 投稿にフォーカスされた状態 - - - - - - - - - - - - - - - - - - - -
ショートカット効果由来
, K, Shift + Tab上の投稿にフォーカスを移動-
, J, Tab下の投稿にフォーカスを移動-
R返信フォームを開くReply
QRenoteフォームを開くQuote
Ctrl + Q即刻Renoteする(フォームを開かずに)-
E, A, +リアクションフォームを開くEmote, reAction
0~9数字に対応したリアクションをする(対応については後述)-
F, Bお気に入りに登録Favorite, Bookmark
Del, Ctrl + D投稿を削除Delete
M, O投稿に対するメニューを開くMore, Other
SCWで隠された部分を表示 or 隠すShow, See
Escフォーカスを外す-
- -## Renoteフォーム - - - - - - - - - - -
ショートカット効果由来
EnterRenoteする-
Qフォームを展開するQuote
Escフォームを閉じる-
- -## リアクションフォーム -デフォルトで「👍」にフォーカスが当たっている状態です。 - - - - - - - - - - - - - -
ショートカット効果由来
, K上のリアクションにフォーカスを移動-
, J下のリアクションにフォーカスを移動-
, H, Shift + Tab左のリアクションにフォーカスを移動-
, L, Tab右のリアクションにフォーカスを移動-
Enter, Space, +リアクション確定-
0~9数字に対応したリアクションで確定-
Escリアクションするのをやめる-
diff --git a/src/docs/es-ES/mfm.md b/src/docs/es-ES/mfm.md deleted file mode 100644 index fcb1379a1..000000000 --- a/src/docs/es-ES/mfm.md +++ /dev/null @@ -1,2 +0,0 @@ -# MFM -MFM es la abreviación de Misskey Flavored Markdown. Es un lenguaje Markdown exclusivo que puede usarse en varios lugares de Misskey. Para ver la sintaxis permitida de MFM, consulte su [lista de códigos](/mfm-cheat-sheet) diff --git a/src/docs/es-ES/mute.md b/src/docs/es-ES/mute.md deleted file mode 100644 index 331e5cc10..000000000 --- a/src/docs/es-ES/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# Silenciar - -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -* タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -* そのユーザーからの通知 -* メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 - -ユーザーをミュートするには、対象のユーザーのユーザーページに表示されている「ミュート」ボタンを押します。 - -ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。 - -設定>ミュート から、自分がミュートしているユーザー一覧を確認することができます。 diff --git a/src/docs/es-ES/pages.md b/src/docs/es-ES/pages.md deleted file mode 100644 index 7fc6ee29c..000000000 --- a/src/docs/es-ES/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# Pages - -## Variables -変数を使うことで動的なページを作成できます。テキスト内で { 変数名 } と書くとそこに変数の値を埋め込めます。例えば Hello { thing } world! というテキストで、変数(thing)の値が ai だった場合、テキストは Hello ai world! になります。 - -変数の評価(値を算出すること)は上から下に行われるので、ある変数の中で自分より下の変数を参照することはできません。例えば上から A、B、C と3つの変数を定義したとき、Cの中でABを参照することはできますが、Aの中でBCを参照することはできません。 - -ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。 - -関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。 diff --git a/src/docs/es-ES/reaction.md b/src/docs/es-ES/reaction.md deleted file mode 100644 index ac10a52f5..000000000 --- a/src/docs/es-ES/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# Reacción -他の人のノートに、絵文字を付けて簡単にあなたの反応を伝えられる機能です。 リアクションするには、ノートの + アイコンをクリックしてピッカーを表示し、絵文字を選択します。 リアクションには[カスタム絵文字](./custom-emoji)も使用できます。 - -## リアクションピッカーのカスタマイズ -ピッカーに表示される絵文字を自分好みにカスタマイズすることができます。 設定の「リアクション」で設定します。 - -## リモート投稿へのリアクションについて -リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。 また、相手がMisskeyであったとしても、カスタム絵文字リアクションは伝わらず、自動的に「👍」等にフォールバックされます。 - -## リモートからのリアクションについて -リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。 diff --git a/src/docs/es-ES/reversi-bot.md b/src/docs/es-ES/reversi-bot.md deleted file mode 100644 index 4336ae349..000000000 --- a/src/docs/es-ES/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# Desarrollo del bot de reversi de Misskey -Aquí se cuenta la forma de desarrollar un Bot compatible con la característica del Reversi en Misskey. - -1. Conéctese al stream `games/reversi` con los siguientes parámetros - * `i`: clave API de la cuenta del bot - -2. Cuando llegue una invitación al juego, aparecerá un evento `invited` desde el stream - * En el contenido del evento, en la sección `parent` viene la información del usuario que hizo la invitación - -3. Envíe un pedido a `games/reversi/match` incluyendo el `id` del `parent` como `user_id` - -4. Si todo anda bien, la respuesta será la información del juego. Luego conéctese al stream `games/reversi-game` con los siguientes parámetros: - * `i`: clave API de la cuenta del bot - * `game`:`id` del `game` - -5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う - -6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する - -7. ゲームが開始すると、`started`イベントが流れてくる - * イベントの中身にはゲーム情報が含まれている - -8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述) - -9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる - * `color`として石の色が含まれている - * `pos`として位置情報が含まれている - -## 位置の計算法 -8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### X,Y座標 から インデックス に変換する -``` -pos = x + (y * mapWidth) -``` -`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます: -``` -mapWidth = map[0].length -``` - -### インデックス から X,Y座標 に変換する -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## マップ情報 -マップ情報は、ゲーム情報の`map`に入っています。 文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 それをもとにマップのデザインを知る事が出来ます: -* `(スペース)` ... マス無し -* `-` ... マス -* `b` ... 初期配置される黒石 -* `w` ... 初期配置される白石 - -例えば、4*4の次のような単純なマップがあるとします: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -この場合、マップデータはこのようになります: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## ユーザーにフォームを提示して対話可能Botを作成する -ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。 - -フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します: -```javascript -{ - type: 'init-form', - body: [フォームコントロールの配列] -} -``` - -フォームコントロールの配列については今から説明します。 フォームコントロールは、次のようなオブジェクトです: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... コントロールのID。 `type` ... コントロールの種類。後述します。 `label` ... コントロールと一緒に表記するテキスト。 `value` ... コントロールのデフォルト値。 - -### フォームの操作を受け取る -ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### フォームコントロールの種類 -#### Interruptor -type: `switch` スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。 - -##### プロパティ -`label` ... スイッチに表記するテキスト。 - -#### ラジオボタン -type: `radio` ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。 - -##### プロパティ -`items` ... ラジオボタンの選択肢。例: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '強', - value: 3 -}] -``` - -#### スライダー -type: `slider` スライダーを表示します。 - -##### プロパティ -`min` ... スライダーの下限。 `max` ... スライダーの上限。 `step` ... 入力欄で刻むステップ値。 - -#### テキストボックス -type: `textbox` テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。 - -## ユーザーにメッセージを表示する -設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 メッセージを表示するには、次のメッセージをストリームに送信します: -```javascript -{ - type: 'message', - body: { - text: 'メッセージ内容', - type: 'メッセージの種類' - } -} -``` -メッセージの種類: `success`, `info`, `warning`, `error`。 - -## 投了する -投了をするには、このエンドポイントにリクエストします。 diff --git a/src/docs/es-ES/stream.md b/src/docs/es-ES/stream.md deleted file mode 100644 index 37c1ab5e4..000000000 --- a/src/docs/es-ES/stream.md +++ /dev/null @@ -1,354 +0,0 @@ -# API de Streaming - -Usando la API de streaming, se puede recibir en tiempo real toda clase de información (por ejemplo, los posts nuevos que pasaron por la linea de tiempo, los mensajes recibidos, las notificaciones de seguimiento, etc.) y manejar varias operaciones en estas. - -## Conectarse a streams - -Para usar la API de streaming, primero hay que conectar un **websocket** al servidor de Misskey - -Conecte el websocket a la URL mencionada abajo, incluyendo la información de autenticación en el parámetro `i`Ej: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -La información de autenticación hace referencia a tu propia clave de la API, o al token de acceso del usuario cuando se conecta al stream desde la aplicación - -
-

Para obtener la información de la autenticación, consulte Este documento

-
- ---- - -La información de autenticación puede omitirse, pero en ese caso de uso sin un login, se restringirá la información que puede ser recibida y las operaciones posibles,Ej: - -``` -%WS_URL%/streaming -``` - ---- - -Al conectarse al stream, se pueden ejecutar las operaciones de la API mencionadas abajo y la suscripción de posts. Sin embargo en esta fase, todavía no es posible recibir los posts nuevos llegando a la linea de tiempo. Para hacer eso, es necesario conectarse a los **canales** mencionados más abajo. - -**Todos los envíos y recibimientos de información con el stream son JSONs** - -## Canales -En la API de streaming de Misskey, hay un concepto llamado "canal". Es una estructura para separar la información enviada y recibida. Solo con conectarse al stream de Misskey, aún no es posible recibir los posts de la linea de tiempo en tiempo real. Al conectarse al canal en el stream, se puede enviar y recibir variada información relacionada a los canales. - -### Conectarse a canales -Para conectarse a los canales, hay que enviar al stream en formato JSON los siguientes datos. - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -Aquí -* En `channel` ingrese el nombre del canal al que quiere conectarse. Más abajo se menciona una lista de canales. -* En `id` ingrese un ID al azar para el intercambio de información con aquel canal. Como en el stream pasan varios mensajes, es necesario identificar de qué canales son esos mensajes. Este ID puede ser un UUID o un número al azar. -* `params` son los parámetros para conectarse al canal. Los parámetros requeridos al momento de conectarse varían según el canal. Si se conecta a un canal que no requiere parámetros, esta propiedad puede omitirse. - -
-

El ID no es por canal sino "por conexión al canal". Porque hay casos en que se pueden hacer múltiples conexiones con parámetros distintos al mismo canal.

-
- -### Recibir mensajes del canal -Por ejemplo, cuando hay nuevos posts en el canal, envía un mensaje. Al recibir ese mensaje, se puede conocer en tiempo real que hay nuevos posts en la linea de tiempo. - -Cuando el canal envía un mensaje, se envía al stream en formato JSON los siguientes datos. -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -Aquí -* En `id` se incluye el ID usado para conectarse al canal mencionado más arriba. Con esto se puede conocer a qué canales pertenecen los mensajes. -* En `type` se incluye el tipo del mensaje. Dependiendo del canal, varía qué tipo de mensajes pasan. -* En `body` se incluye el contenido del mensaje. Dependiendo del canal, varía qué contenido de mensajes pasan. - -### Enviar mensajes al canal -Dependiendo del canal, se puede no solo recibir mensajes, sino también mandar mensajes a dicho canal, y realizar algunas operaciones. - -Para mandar un mensaje al canal, se envía al stream en formato JSON los siguientes datos. -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -Aquí -* En `id` ingrese el ID usado para conectarse al canal mencionado más arriba. Con esto se puede identificar a qué canales fueron dirigidos los mensajes. -* En `type` ingrese el tipo del mensaje. Dependiendo del canal, varía qué tipo de mensajes serán aceptados. -* En `body` ingrese el contenido del mensaje. Dependiendo del canal, varía qué contenidos de mensajes serán aceptados. - -### Desconectarse del canal -Para desconectarse de un canal, se envía al stream en formato JSON los siguientes datos. - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -Aquí -* En `id` ingrese el ID usado para conectarse al canal mencionado más arriba. - -## Hacer pedidos a la API a través del stream - -Al hacer pedidos a la API a través del stream, se puede usar la API sin que se genere un pedido HTTP. Para eso, probablemente se pueda hacer el código más conciso y mejorar el rendimiento. - -Para hacer pedidos a la API a través del stream, se envía al stream en formato JSON los siguientes datos. -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -Aquí -* En `id` se requiere ingresar un ID único por cada pedido a la API, para distinguir las respuestas de la API. Puede ser un UUID o un número aleatorio. -* En `endpoint` ingrese el endpoint de la API a la que quiere hacer el pedido. -* En `data` incluya los parámetros del endpoint - -
-

En cuanto a los endpoint de la API y los parámetros, consulte las referencias de la API.

-
- -### Recibiendo respuestas - -Al hacer un pedido a la API, llegará desde el stream una respuesta en el siguiente formato. - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -Aquí -* En la porción que dice `xxxxxxxxxxxxxxxx` viene el `id` ingresado en el momento de hacer el pedido. Con esto, se puede distinguir a qué pedido corresponde la respuesta. -* En `body` vienen los datos de la respuesta. - -## Captura de posts - -Misskey ofrece una construcción llamada "captura de posts". Es una función para recibir en el stream los eventos de un post seleccionado. - -Por ejemplo, supongamos que se obtiene la linea de tiempo y se la muestra al usuario. Y ahí, supongamos que alguien reaccionó a un post incluido en esa linea de tiempo. - -Sin embargo, como desde el cliente no hay forma de conocer las reacciones añadidas a cierto post, las reacciones no pueden reflejarse en el post en la linea de tiempo en tiempo real. - -Para solucionar este problema, Misskey prepara un mecanismo de captura de posts. Cuando se captura un post, se pueden reflejar las reacciones en tiempo real para poder recibir los eventos relacionados al post. - -### Capturar posts - -Para capturar posts, se envía al stream el siguiente mensaje. - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -Aquí -* En `id` ingrese el `id` del post que se desea capturar. - -Al enviarse el mensaje, se convierte en un pedido de captura a Misskey. Luego, los eventos relacionados a ese post serán emitidos. - -Por ejemplo, suponiendo que se reacciona a un post, se emite el siguiente mensaje: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -Aquí -* En el `id` dentro del `body`, viene el ID del post que causó el evento. -* En el `type` dentro del `body`, viene el tipo del evento. -* En el `body` dentro del `body`, vienen los detalles del evento. - -#### Tipos de eventos - -##### `reacted` -Ocurre cuando se añade una reacción a un post. - -* En `reaction` viene el tipo de reacción. -* En `userId` viene el ID del usuario que hizo la reacción. - -Ej: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -Ocurre cuando ese post fue eliminado. - -* En `deletedAt` viene la fecha y hora en que fue eliminado. - -Ej: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -Ocurre cuando se hizo un voto a una encuesta incluida en el post. - -* En `choice` viene el ID de la opción elegida. -* En `userId` viene el ID del usuario que hizo el voto. - -Ej: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### Cancelar la captura del post - -Cuando el post ya no sea mostrado en pantalla y ya no sea necesario recibir los eventos relacionados a este, pida cancelar la captura. - -Envíe el siguiente mensaje: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -Aquí -* En `id` ingrese el `id` del post que se desea dejar de capturar. - -Al mandar este mensaje, ya no se emitirán los eventos relacionados a dicho post. - -# Lista de canales -## `main` -Se emite la información básica relacionada a la cuenta. Este canal no tiene parámetros. - -### Lista de eventos emitidos - -#### `renote` -Un evento que ocurre cuando un post propio es renotado. No ocurre cuando uno mismo renota el post. - -#### `mention` -Un evento que ocurre cuando alguien te menciona. - -#### `readAllNotifications` -Un evento que ocurre cuando todas tus notificaciones fueron marcadas como leídas. Se espera que se use el evento en casos como apagar el indicador que muestra si se tienen notificaciones sin leer. - -#### `meUpdated` -Un evento que ocurre cuando tu información de perfil es actualizada. - -#### `follow` -Un evento que ocurre cuando tú sigues a alguien. - -#### `unfollow` -Un evento que ocurre cuando dejas de seguir a alguien. - -#### `followed` -Un evento que ocurre cuando alguien te sigue. - -## `homeTimeline` -Se emite la información subida a la linea de tiempo del inicio. Este canal no tiene parámetros. - -### Lista de eventos emitidos - -#### `note` -Un evento que ocurre cuando se emite un nuevo post en la linea de tiempo. - -## `localTimeline` -Se emite la información subida a la linea de tiempo local. Este canal no tiene parámetros. - -### Lista de eventos emitidos - -#### `note` -Un evento que ocurre cuando se emite un nuevo post en la linea de tiempo local. - -## `hybridTimeline` -Se emite la información subida a la linea de tiempo social. Este canal no tiene parámetros. - -### Lista de eventos emitidos - -#### `note` -Un evento que ocurre cuando se emite un nuevo post en la linea de tiempo social. - -## `globalTimeline` -Se emite la información subida a la linea de tiempo global. Este canal no tiene parámetros. - -### Lista de eventos emitidos - -#### `note` -Un evento que ocurre cuando se emite un nuevo post en la linea de tiempo global. diff --git a/src/docs/es-ES/theme.md b/src/docs/es-ES/theme.md deleted file mode 100644 index 090b40e6a..000000000 --- a/src/docs/es-ES/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# Tema - -Eligiendo un tema, se puede cambiar la apariencia del cliente de Misskey - -## Configuración del tema -Configuración > Tema - -## Crear tema -El código del tema se guarda como un archivo JSON5. Un ejemplo de tema se puede ver aquí: -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... Clave única del tema.Se recomienda un código UUID -* `name` ... Nombre del tema -* `author` ... Autor del tema -* `desc` ... Descripción del tema (opcional) -* `base` ... Si es un tema claro u oscuro - * Si se elige `light`, será un tema claro. Si se elige `dark`, será un tema oscuro. - * Aquí el tema hereda los valores por defecto del tema base elegido -* `props` ... Definición del estilo del tema. Esto se explica en lo siguiente. - -### Definición del estilo del tema -Debajo de `props`, se define el estilo del tema. La clave es el nombre de las variables del CSS, y con los valores estos se configuran. Incluso más, este objeto `props` hereda los valores por defecto del tema base. El tema base es [_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5) si el `base` de este tema es `light`, y [_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5) si si el `base` de este tema es `dark` Resumiendo, aunque no haya una clave `panel` en el `props` del tema, se considera el <0>panel del tema base. - -#### Sintaxis de las variables -* Los colores en base hexadecimal - * Ej: `#00ff00` -* Los colores con la sintaxis `rgb(r, g, b)` - * Ej: `rgb(0, 255, 0)` -* Los colores con la sintaxis `rgb(r, g, b, a)` con un grado de transparencia - * Ej: `rgba(0, 255, 0, 0.5)` -* Referencias a valores de otras claves - * Escribiendo `@{nombre de clave}` se hace referencia al valor de la otra clave.Reemplace `{nombre de clave}` por el nombre de la clave al cual quiera hacer referencia. - * Ej: `@panel` -* Referencia a una constante (ver más abajo) - * Escribiendo `${nombre de la constante}` se hace referencia a la constante.Reemplace `{nombre de la constante}` por la constante al cual quiera hacer referencia. - * Ej: `$main` -* Funciones (ver más abajo) - * `:{nombre de la función}<{parámetros}<{color}` - -#### Constantes -Cuando hay un valor que no se quiere generar como variable CSS pero sí se quiere reutilizar como valor de otra variable CSS, es conveniente usar constantes. Cuando a un nombre de clave se le añade como prefijo `$`, esa clave no será generada como una variable CSS. - -#### funciones -wip diff --git a/src/docs/es-ES/timelines.md b/src/docs/es-ES/timelines.md deleted file mode 100644 index 60834cfda..000000000 --- a/src/docs/es-ES/timelines.md +++ /dev/null @@ -1,15 +0,0 @@ -# Comparación de las lineas de tiempo - -https://docs.google.com/spreadsheets/d/1lxQ2ugKrhz58Bg96HTDK_2F98BUritkMyIiBkOByjHA/edit?usp=sharing - -## Inicio -Los posts de los usuarios que uno sigue - -## Local -Todos los posts de los usuarios locales que no estén marcados como "Solo inicio" - -## Social -Los posts de los usuarios que uno sigue más todos los posts de los usuarios locales que no estén marcados como "Solo inicio" - -## Global -Todos los posts de los usuarios locales que no estén marcados como "Solo inicio" más todos los posts de los usuarios remotos recibidos por el servidor que no estén marcados como "Solo inicio" diff --git a/src/docs/fr-FR/admin/disable-timelines.md b/src/docs/fr-FR/admin/disable-timelines.md deleted file mode 100644 index b081e35ab..000000000 --- a/src/docs/fr-FR/admin/disable-timelines.md +++ /dev/null @@ -1,8 +0,0 @@ -# LTL/STL/GTLの無効化 -Misskeyでは、LTL/STL/GTLをそれぞれ無効化することができます。有効/無効を切り替えるには、インスタンスコントロールパネルで設定します。 - -LTLやSTLは、そのインスタンス全員の投稿が見れるため、新規のユーザーにとってはユーザーを探す必要がなくなり、興味のあるユーザーを見つけやすいという利点があります。 しかし同時に、フォロー機能が活用されなくなったり、不適切な投稿が目につきやすくなったり、チャットのようになることで内輪感が生じて逆に新規ユーザーが参加しにくくなるといったデメリットも持ち合わせています。 サーバーによってメリット/デメリットどちらが優勢かは異なるので、オプションとして無効にできるようになっています。 もしデメリットの方が上回っていると感じたら、それらのタイムラインを無効化することも検討してください。 - -
⚠️ 無効化を行うと、ユーザーが困惑し、短期的に見て利用者が減る可能性があります。そのため、無効化の際は影響を慎重に検討し、事前に説明してフォローを整える期間を一定程度設けることを推奨します。
- -なお、管理者/モデレーターは、これらのタイムラインの無効化状態は適用されず、引き続き利用することが可能です。 diff --git a/src/docs/fr-FR/admin/faq.md b/src/docs/fr-FR/admin/faq.md deleted file mode 100644 index 9be3edc44..000000000 --- a/src/docs/fr-FR/admin/faq.md +++ /dev/null @@ -1,5 +0,0 @@ -# Questions fréquentes -Ici sont publiées les questions que les administrateur·rice·s de serveurs posent le plus fréquemment. - -## « Je veux configurer un thème par défaut » -Pour l'instant, il n'existe aucune fonctionnalité permettant de configurer un thème par défaut pour votre instance. diff --git a/src/docs/fr-FR/advanced/aiscript.md b/src/docs/fr-FR/advanced/aiscript.md deleted file mode 100644 index 5af011f99..000000000 --- a/src/docs/fr-FR/advanced/aiscript.md +++ /dev/null @@ -1,7 +0,0 @@ -# AiScript -AiScriptは、Misskeyで使用できるスクリプト言語です。 - -
ℹ️ AiScript実装はMisskeyとは別リポジトリで、オープンソースで公開されています。
- -## Utilisation -AiScriptの構文や組み込み関数などのドキュメントは、[こちら](https://github.com/syuilo/aiscript/tree/master/docs)で公開されています。 diff --git a/src/docs/fr-FR/advanced/api.md b/src/docs/fr-FR/advanced/api.md deleted file mode 100644 index bffde881f..000000000 --- a/src/docs/fr-FR/advanced/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# API de Misskey - -MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス、Bot等(以下「アプリケーション」と呼びます)を開発できます。 ストリーミングAPIもあるので、リアルタイム性のあるアプリケーションを作ることも可能です。 - -APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。 - -## アクセストークンの取得 -基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。 - -* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む -* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む - -### 自分自身のアクセストークンを手動発行する -「設定 > API」で、自分のアクセストークンを発行できます。 - -[「APIの使い方」へ進む](#APIの使い方) - -### アプリケーション利用者にアクセストークンの発行をリクエストする -アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。 - -#### Étape 1 - -UUIDを生成する。以後これをセッションIDと呼びます。 - -> このセッションIDは毎回生成し、使いまわさないようにしてください。 - -#### Étape 2 - -`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。 -> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます: -* `name` ... アプリケーション名 - * > 例: `MissDeck` -* `icon` ... アプリケーションのアイコン画像URL - * > 例: `https://missdeck.example.com/icon.png` -* `callback` ... 認証が終わった後にリダイレクトするURL - * > 例: `https://missdeck.example.com/callback` - * リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます -* `permission` ... アプリケーションが要求する権限 - * > 例: `write:notes,write:following,read:drive` - * 要求する権限を`,`で区切って列挙します - * どのような権限があるかは[APIリファレンス](/api-doc)で確認できます - -#### Étape 3 -ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。 - -レスポンスに含まれるプロパティ: -* `token` ... ユーザーのアクセストークン -* `user` ... ユーザーの情報 - -[「APIの使い方」へ進む](#APIの使い方) - -## APIの使い方 -**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。 - -* [APIリファレンス](/api-doc) -* [ストリーミングAPI](./stream) diff --git a/src/docs/fr-FR/advanced/create-plugin.md b/src/docs/fr-FR/advanced/create-plugin.md deleted file mode 100644 index 540909de4..000000000 --- a/src/docs/fr-FR/advanced/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# プラグインの作成 -Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。 - -## Métadonnées -プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。 - -### name -プラグイン名 - -### author -プラグイン作者 - -### version -プラグインバージョン。数値を指定してください。 - -### description -プラグインの説明 - -### permissions -プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。 - -### config -プラグインの設定情報を表すオブジェクト。 キーに設定名、値に以下のプロパティを含めます。 - -#### type -設定値の種類を表す文字列。以下から選択します。 string number boolean - -#### label -ユーザーに表示する設定名 - -#### description -設定の説明 - -#### default -設定のデフォルト値 - -## APIリファレンス -AiScript標準で組み込まれているAPIは掲載しません。 - -### Mk:dialog(title text type) -ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。 - -### Mk:confirm(title text type) -確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。 - -### Mk:api(endpoint params) -Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。 - -### Mk:save(key value) -任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。 - -### Mk:load(key) -Mk:saveで永続化した指定の名前の値を読み取ります。 - -### Plugin:register_post_form_action(title fn) -投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。 - -### Plugin:register_note_action(title fn) -ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 - -### Plugin:register_user_action(title fn) -ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。 - -### Plugin:register_note_view_interruptor(fn) -UIに表示されるノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:register_note_post_interruptor(fn) -ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:open_url(url) -第一引数に渡されたURLをブラウザの新しいタブで開きます。 - -### Plugin:config -プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。 diff --git a/src/docs/fr-FR/advanced/develop-bot.md b/src/docs/fr-FR/advanced/develop-bot.md deleted file mode 100644 index 7f825e9bc..000000000 --- a/src/docs/fr-FR/advanced/develop-bot.md +++ /dev/null @@ -1,6 +0,0 @@ -# Botの作成 -[Misskey API](./api)を利用してBotの開発が可能です。 また、いくつかのBot実装が公開されているため、ぜひ参考にしてください。 - -- [syuilo/ai](https://github.com/syuilo/ai) ... Node.js上で動く、TypeScript製Bot実装 - -Botを作成したときは、プロフィール設定からBotフラグをオンにしておくことを強くおすすめします。 diff --git a/src/docs/fr-FR/advanced/reversi-bot.md b/src/docs/fr-FR/advanced/reversi-bot.md deleted file mode 100644 index 2da95be1d..000000000 --- a/src/docs/fr-FR/advanced/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# MisskeyリバーシBotの開発 -Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。 - -1. `games/reversi`ストリームに以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - -2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる - * イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている - -3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する - -4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - * `game`: `game`の`id` - -5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う - -6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する - -7. ゲームが開始すると、`started`イベントが流れてくる - * イベントの中身にはゲーム情報が含まれている - -8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述) - -9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる - * `color`として石の色が含まれている - * `pos`として位置情報が含まれている - -## 位置の計算法 -8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### X,Y座標 から インデックス に変換する -``` -pos = x + (y * mapWidth) -``` -`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます: -``` -mapWidth = map[0].length -``` - -### インデックス から X,Y座標 に変換する -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## マップ情報 -マップ情報は、ゲーム情報の`map`に入っています。 文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 それをもとにマップのデザインを知る事が出来ます: -* `(スペース)` ... マス無し -* `-` ... マス -* `b` ... 初期配置される黒石 -* `w` ... 初期配置される白石 - -例えば、4*4の次のような単純なマップがあるとします: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -この場合、マップデータはこのようになります: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## ユーザーにフォームを提示して対話可能Botを作成する -ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。 - -フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します: -```javascript -{ - type: 'init-form', - body: [フォームコントロールの配列] -} -``` - -フォームコントロールの配列については今から説明します。 フォームコントロールは、次のようなオブジェクトです: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... コントロールのID。 `type` ... コントロールの種類。後述します。 `label` ... コントロールと一緒に表記するテキスト。 `value` ... コントロールのデフォルト値。 - -### フォームの操作を受け取る -ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### フォームコントロールの種類 -#### Interrupteur -type: `switch` スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。 - -##### プロパティ -`label` ... スイッチに表記するテキスト。 - -#### ラジオボタン -type: `radio` ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。 - -##### プロパティ -`items` ... ラジオボタンの選択肢。例: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '強', - value: 3 -}] -``` - -#### スライダー -type: `slider` スライダーを表示します。 - -##### プロパティ -`min` ... スライダーの下限。 `max` ... スライダーの上限。 `step` ... 入力欄で刻むステップ値。 - -#### テキストボックス -type: `textbox` テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。 - -## ユーザーにメッセージを表示する -設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 メッセージを表示するには、次のメッセージをストリームに送信します: -```javascript -{ - type: 'message', - body: { - text: 'メッセージ内容', - type: 'メッセージの種類' - } -} -``` -メッセージの種類: `success`, `info`, `warning`, `error`。 - -## 投了する -投了をするには、このエンドポイントにリクエストします。 diff --git a/src/docs/fr-FR/advanced/share-page.md b/src/docs/fr-FR/advanced/share-page.md deleted file mode 100644 index 056f8e1ef..000000000 --- a/src/docs/fr-FR/advanced/share-page.md +++ /dev/null @@ -1,54 +0,0 @@ -# シェアページ -`/share`を開くと、共有用の投稿フォームを開くことができます。 ここではシェアページで利用できるクエリ文字列の一覧を示します。 - -## クエリ文字列一覧 -### Texte - -
-
title
-
タイトルです。本文の先頭に[ … ]と挿入されます。
-
text
-
本文です。
-
url
-
URLです。末尾に挿入されます。
-
- -### リプライ情報 -以下のいずれか - -
-
replyId
-
リプライ先のノートid
-
replyUri
-
リプライ先のUrl(リモートのノートオブジェクトを指定)
-
- -### Renote情報 -以下のいずれか - -
-
renoteId
-
Renote先のノートid
-
renoteUri
-
Renote先のUrl(リモートのノートオブジェクトを指定)
-
- -### Visibilité -※specifiedに相当する値はvisibility=specifiedとvisibleAccts/visibleUserIdsで指定する - -
-
visibility
-
公開範囲 ['public' | 'home' | 'followers' | 'specified']
-
localOnly
-
0(false) or 1(true)
-
visibleUserIds
-
specified時のダイレクト先のユーザーid カンマ区切りで
-
visibleAccts
-
specified時のダイレクト先のacct(@?username[@host]) カンマ区切りで
-
- -### Fichiers -
-
fileIds
-
添付したいファイルのid(カンマ区切りで)
-
diff --git a/src/docs/fr-FR/advanced/stream.md b/src/docs/fr-FR/advanced/stream.md deleted file mode 100644 index b1820bf61..000000000 --- a/src/docs/fr-FR/advanced/stream.md +++ /dev/null @@ -1,350 +0,0 @@ -# ストリーミングAPI - -ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。 - -## ストリームに接続する - -ストリーミングAPIを利用するには、まずMisskeyサーバーに**websocket**接続する必要があります。 - -以下のURLに、`i`というパラメータ名で認証情報を含めて、websocket接続してください。例: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。 - -
ℹ️ 認証情報の取得については、こちらのドキュメントをご確認ください。
- ---- - -認証情報は省略することもできますが、その場合非ログインでの利用ということになり、受信できる情報や可能な操作は限られます。例: - -``` -%WS_URL%/streaming -``` - ---- - -ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。 - -**ストリームでのやり取りはすべてJSONです。** - -## Canaux -MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。 - -ひとつのストリーム上で、同時に複数のチャンネルに接続することができます。 - -### チャンネルに接続する -チャンネルに接続するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -ここで、 -* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。 -* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。 -* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。 - -
ℹ️ IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。
- -### チャンネルからのメッセージを受け取る -例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。 - -チャンネルがメッセージを発すると、次のようなデータがJSONでストリームに流れてきます: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。 -* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。 -* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。 - -### チャンネルに向けてメッセージを送信する -チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。 - -チャンネルにメッセージを送信するには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。 -* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。 -* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。 - -### チャンネルから切断する -チャンネルから切断するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。 - -## ストリームを経由してAPIリクエストする - -ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。 - -ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -ここで、 -* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 -* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 -* `data`には、エンドポイントのパラメータを含めます。 - -
ℹ️ APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。
- -### レスポンスの受信 - -APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。 - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -ここで、 -* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 -* `body`には、レスポンスが含まれています。 - -## 投稿のキャプチャ - -Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。 - -例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。 - -しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。 - -この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。 - -### 投稿をキャプチャする - -投稿をキャプチャするには、ストリームに次のようなメッセージを送信します: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャしたい投稿の`id`を設定します。 - -このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 - -例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -ここで、 -* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。 -* `body`内の`type`に、イベントの種類が設定されます。 -* `body`内の`body`に、イベントの詳細が設定されます。 - -#### イベントの種類 - -##### `reacted` -その投稿にリアクションがされた時に発生します。 - -* `reaction`に、リアクションの種類が設定されます。 -* `userId`に、リアクションを行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -その投稿が削除された時に発生します。 - -* `deletedAt`に、削除日時が設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -その投稿に添付されたアンケートに投票された時に発生します。 - -* `choice`に、選択肢IDが設定されます。 -* `userId`に、投票を行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### 投稿のキャプチャを解除する - -その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。 - -次のメッセージを送信します: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャを解除したい投稿の`id`を設定します。 - -このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 - -# チャンネル一覧 -## `main` -アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `renote` -自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。 - -#### `mention` -誰かからメンションされたときに発生するイベントです。 - -#### `readAllNotifications` -自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。 - -#### `meUpdated` -自分の情報が更新されたことを表すイベントです。 - -#### `follow` -自分が誰かをフォローしたときに発生するイベントです。 - -#### `unfollow` -自分が誰かのフォローを解除したときに発生するイベントです。 - -#### `followed` -自分が誰かにフォローされたときに発生するイベントです。 - -## `homeTimeline` -ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -タイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `localTimeline` -ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `hybridTimeline` -ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ソーシャルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `globalTimeline` -グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 diff --git a/src/docs/fr-FR/aiscript.md b/src/docs/fr-FR/aiscript.md deleted file mode 100644 index 8ca752e25..000000000 --- a/src/docs/fr-FR/aiscript.md +++ /dev/null @@ -1,4 +0,0 @@ -# AiScript - -## Fonction -Réglé sur « passage par valeur » par défaut. diff --git a/src/docs/fr-FR/api.md b/src/docs/fr-FR/api.md deleted file mode 100644 index 0147f95ba..000000000 --- a/src/docs/fr-FR/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# API de Misskey - -Vous pouvez utiliser l'API de Misskey pour développer des clients Misskey, des services web s'intégrant à Misskey, des Bots (que nous appellerons plus loin "Applications"), etc. Comme l'API streaming est aussi implémenté, vous avez la possibilité de créer des applications de temps réel. - -Pour pouvoir vous servir de l'API, il vous faudra d'abord obtenir un jeton d'accès. Ce guide a été conçu pour vous accompagner dans le processus d'obtention du jeton d'accès, puis donner des instructions de base sur l'utilisation de l'API. - -## Obtenir le jeton d'accès -Une requête d'API, par essence, nécessite un jeton d'accès. La procédure d'acquisition du jeton diffère selon que vous effectuez la requête vous-même, ou qu'elle est envoyée via une application par un utilisateur final non défini. - -* Dans le premier cas : allez à [« Générer manuellement un jeton d'accès pour son propre compte »](#自分自身のアクセストークンを手動発行する). -* Dans le second cas : allez à [« Demander la génération du jeton d'accès via un utilisateur d'application »](#アプリケーション利用者にアクセストークンの発行をリクエストする). - -### Générer manuellement un jeton d'accès pour son propre compte -Vous pouvez générer votre propre jeton d'accès en allant dans { Paramètres > API }. - -[Continuer avec « Utiliser l'API ».](#APIの使い方) - -### Demander la génération du jeton d'accès via un utilisateur d'application -Pour obtenir un jeton d'accès pour le compte utilisateur final de votre application, suivez la procédure de génération ci-dessous. - -#### Étape 1 - -Générez un UUID. Nous l'appellerons « ID de session » dans la suite de ce guide. - -> Un même ID de session ne devrait pas être utilisé plusieurs fois ; veillez à en générer un nouveau pour chaque jeton d'accès. - -#### Étape 2 - -Ouvrez l'adresse `{_URL_}/miauth/{session}` dans le navigateur de l'utilisateur. Remplacez alors la partie `{session}` de l'URL par l'ID de session que vous venez de générer. -> Par ex. : `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -En ouvrant cette URL, vous pourrez configurer un certain nombre d'options pour les paramètres de requête : -* `name` : nom de l'application - * > Ex. : `MissDeck` -* `icon` : URL de l'icône de l'application - * > Ex. : `https://missdeck.example.com/icon.png` -* `callback` : URL de redirection après l'authentification - * > Ex. : `https://missdeck.example.com/callback` - * Lors de la redirection, un paramètre de requête `session` contenant l'ID de session sera joint. -* `permission` : permissions requises par l'application - * > Ex. : `write:notes,write:following,read:drive` - * Listez les permissions requises en utilisant une `,` pour les séparer. - * Vous pouvez vérifier quelles sont les permissions disponibles sur [les références API de Misskey](/api-doc). - -#### Étape 3 -Si vous envoyez une requête POST à `{_URL_}/api/miauth/{session}/check` une fois que l'utilisateur a validé le jeton d'accès, la réponse arrivera sous forme de fichier JSON contenant ce jeton. - -Propriétés incluses dans la réponse : -* `token` : jeton d'accès de l'utilisateur -* `user` : données de l'utilisateur - -[Continuer avec « Utiliser l'API ».](#APIの使い方) - -## Utiliser l'API -**L'API utilise seulement la méthode POST, et toutes les requêtes / réponses sont au format JSON. REST n'est pas pris en charge. ** Le jeton d'accès s'insère dans le paramètre de requête nommé `i`. - -* [Références API de Misskey](/api-doc) -* [API streaming](./stream) diff --git a/src/docs/fr-FR/create-plugin.md b/src/docs/fr-FR/create-plugin.md deleted file mode 100644 index 0d6e8a8ad..000000000 --- a/src/docs/fr-FR/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# Création d'un plugin -En utilisant la fonction plugin du client web Misskey, vous pouvez étendre et y ajouter de nouvelles fonctionnalités. Cette page liste la définition des métadonnées et les références de l'API AIScript pour la création des plugins. - -## Métadonnées -Les plugins doivent définir des métadonnées de plugin par défaut via le format de métadonnées AiScript. Les métadonnées sont un objet contenant les propriétés suivantes : - -### name -Nom du plugin. - -### author -Nom de l'auteur du plugin. - -### version -Version du plugin.Cette valeur doit être un nombre. - -### description -Description du plugin. - -### permissions -Permissions requises par le plugin.Utilisé pour les requêtes de l'API Misskey. - -### config -Un objet représentant les paramètres du plugin. Les clés représentent les noms des paramètres et les valeurs sont l'une des propriétés ci-dessous. - -#### type -Une chaîne de caractères représentant le type de valeur du paramètre.Sélectionnez l'une des options suivantes : string number boolean - -#### label -Nom du paramètre affiché à l'utilisateur. - -#### description -Description du paramètre - -#### default -Valeur par défaut du paramètre - -## Références API de Misskey -L'API intégrée directement dans la norme AiScript elle-même ne sera pas répertoriée. - -### Mk:dialog(title text type) -Affiche la boîte de dialogue.type peut être défini par les valeurs suivantes. info success warn error question Si elle est omise, c'est "info" qui est utilisée. - -### Mk:confirm(title text type) -Affiche une boîte de dialogue de confirmation.Le type peut être défini par les valeurs suivantes. info success warn error question Si elle est omise, c'est "question" qui est utilisé par défaut. Si l'utilisateur sélectionne "OK", true est renvoyé, si l'utilisateur sélectionne "Cancel", false est renvoyé. - -### Mk:api(endpoint params) -Envoie une requête à l'API Misskey.Le premier paramètre spécifie le point de terminaison de l'API, le second spécifie les paramètres de la requête sous forme d'objet. - -### Mk:save(key value) -Fait persister une valeur arbitraire avec un nom arbitraire.La valeur persistante reste après la fin du contexte AiScript et peut être lue par Mk:load. - -### Mk:load(key) -Lit la valeur du nom spécifié persisté par Mk:save. - -### Plugin:register_post_form_action(title fn) -Ajoute une action au formulaire de soumission.Le premier argument est le nom de l'action, le second est la fonction de rappel lorsque l'action est sélectionnée. La fonction de rappel reçoit l'objet du formulaire de soumission comme premier argument. - -### Plugin:register_note_action(title fn) -Ajoute un élément au menu note. Le premier paramètre spécifie le nom de l'action, le second paramètre spécifie une fonction de rappel qui est exécutée lorsque cet élément est sélectionné. La fonction de rappel reçoit un objet note comme premier paramètre. - -### Plugin:register_user_action(title fn) -Ajoute un élément au menu de l'utilisateur.Le premier paramètre spécifie le nom de l'action, le second paramètre spécifie une fonction de rappel qui est exécutée lorsque cet élément est sélectionné. La fonction de rappel reçoit un objet utilisateur comme premier paramètre. - -### Plugin:register_note_view_interruptor(fn) -Réécrit les informations de la note affichée dans l'interface utilisateur. L'objet note cible est passé comme premier argument à la fonction de rappel. La note est réécrite dans la valeur de retour de la fonction de rappel. - -### Plugin:register_note_post_interruptor(fn) -Réécrit les informations de la note lors de la publication d'une note. L'objet note cible est passé comme premier argument à la fonction de rappel. La note sera réécrite dans la valeur de retour de la fonction de rappel. - -### Plugin:open_url(url) -Ouvre l'URL passée comme premier argument dans un nouvel onglet du navigateur. - -### Plugin:config -Un objet dans lequel la configuration du plugin est stockée.La valeur est saisie par la clé définie dans la configuration de la définition du plugin. diff --git a/src/docs/fr-FR/custom-emoji.md b/src/docs/fr-FR/custom-emoji.md deleted file mode 100644 index 649da5d3a..000000000 --- a/src/docs/fr-FR/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# Émojis personnalisés -Les émojis personnalisés sont une fonctionnalité qui vous permet d'utiliser une sélection d'images disponibles sur votre instance comme des émojis. Vous pouvez les utiliser dans différents contextes : vos notes, vos réactions, vos discussions directes, votre présentation de profil, votre nom, etc. Lorsque vous voulez utiliser des émojis personnalisés, vous pouvez utiliser le sélecteur d'émojis (s'il est disponible), ou bien faire apparaître des suggestions d'émojis en tapant `:`. Ainsi, quand cette suite de caractères (au format `:foo:`) est détectée dans un texte, elle est interprétée comme un nom d'émoji personnalisé : les lettres contenues au centre de la suite `foo` provoquent alors l'affichage de la suggestion d'émoji personnalisé approprié. diff --git a/src/docs/fr-FR/deck.md b/src/docs/fr-FR/deck.md deleted file mode 100644 index 610cf967a..000000000 --- a/src/docs/fr-FR/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# Deck - -Le deck est l'une des interfaces utilisateur disponibles.Sa particularité est de former une interface riche en contenus et hautement personnalisable grâce à l'affichage de plusieurs colonnes. - -## Ajouter une colonne -Vous pouvez ajouter une colonne en cliquant avec le clic-droit dans l'arrière-plan du deck puis sur « Ajouter une colonne » . - -## Déplacer une colonne -Vous pouvez déplacer une colonne à la place d'une autre en la faisant glisser. Il est en outre possible de réorganiser les colonnes depuis le menu des colonnes — en faisant un clic-droit dans l'en-tête de colonne. - -## Division horizontale des colonnes -Il est possible d'agencer les colonnes horizontalement. Depuis le menu de la colonne que vous voulez déplacer, cliquez sur « Empiler à gauche » pour la déplacer sous la colonne de gauche. Cliquez sur « Déplacer à droite » pour annuler. - -## Configuration de la colonne -Vous pouvez éditer la configuration de la colonne en cliquant sur « édition » dans le menu de colonne. Vous pourrez y changer le nom ou la largeur de la colonne. - -## Configuration du deck -Vous trouverez les options de configuration du deck à [settings/deck](/settings/deck) diff --git a/src/docs/fr-FR/features/antenna.md b/src/docs/fr-FR/features/antenna.md deleted file mode 100644 index 49746e708..000000000 --- a/src/docs/fr-FR/features/antenna.md +++ /dev/null @@ -1,4 +0,0 @@ -# Antennes -Les antennes vous permettent de recueillir des notes automatiquement, en fonction de critères que vous définissez librement. - -Ainsi, lorsqu'une note répondant aux critères que vous avez spécifiés dans une antenne est publiée, elle est ajoutée au fil de l'antenne correspondante en temps réel. diff --git a/src/docs/fr-FR/features/custom-emoji.md b/src/docs/fr-FR/features/custom-emoji.md deleted file mode 100644 index 01840868e..000000000 --- a/src/docs/fr-FR/features/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# Émojis personnalisés -カスタム絵文字は、インスタンスで用意された画像を絵文字のように使える機能です。 ノート、リアクション、チャット、自己紹介、名前などの場所で使うことができます。 カスタム絵文字をそれらの場所で使うには、絵文字ピッカーボタン(ある場合)を押すか、`:`を入力して絵文字サジェストを表示します。 テキスト内に`:foo:`のような形式の文字列が見つかると、`foo`の部分がカスタム絵文字名と解釈され、表示時には対応したカスタム絵文字に置き換わります。 diff --git a/src/docs/fr-FR/features/deck.md b/src/docs/fr-FR/features/deck.md deleted file mode 100644 index 73e9efdaa..000000000 --- a/src/docs/fr-FR/features/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# Deck - -デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。 - -## カラムの追加 -デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。 - -## カラムの移動 -カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。 - -## カラムの水平分割 -カラムは左右だけでなく、上下に並べることもできます。 カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 上下分割を解除するには、カラムメニューの「右に出す」を選択します。 - -## カラムの設定 -カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。 - -## デッキの設定 -デッキに関する設定は、[settings/deck](/settings/deck)で行えます。 diff --git a/src/docs/fr-FR/features/drive.md b/src/docs/fr-FR/features/drive.md deleted file mode 100644 index c445b99a8..000000000 --- a/src/docs/fr-FR/features/drive.md +++ /dev/null @@ -1,17 +0,0 @@ -# Drive -ドライブは、Misskey上でファイルを管理できる機能です。 - -[ドライブのページ](/my/drive)から任意のファイルをアップロードできるほか、アバターに設定した画像や、ノートに添付したファイルなどもすべてドライブにアップロードされます。 - -
⚠️ ドライブからファイルを削除すると、そのファイルが添付されたノートも消えます。
- -ドライブにアップロードされたファイルは、いつでもダウンロードすることができるほか、ノート作成時に「ドライブからファイルを添付」することでファイルを再利用することもできます。 - -ドライブ内にフォルダを作り、複数のファイルをまとめて整理することもできます。 - -## 閲覧注意 (NSFW) -
ℹ️ この項目が閲覧注意なわけではありません
- -閲覧注意またはNSFW (Not safe for work) は、ドライブのファイルに設定することができるフラグです。 閲覧注意フラグを設定されたファイルは、表示される際に閲覧者の操作なしには表示されなくなります。 このフラグは、例えば職場や公共の場で閲覧するのに適切でないと思われる画像などに設定し、そのような画像が突然表示されてしまうことを防ぐ目的で使われます。 - -このフラグは手動でオンオフを切り替えられるほか、モデレーターの判断で設定される場合もあります。 diff --git a/src/docs/fr-FR/features/favorite.md b/src/docs/fr-FR/features/favorite.md deleted file mode 100644 index a7ef5b7fd..000000000 --- a/src/docs/fr-FR/features/favorite.md +++ /dev/null @@ -1,4 +0,0 @@ -# Ajouter aux favoris -[ノート](./node)をお気に入りとして登録できる機能です。 お気に入り登録したノートは、[お気に入りページ](./my/favorites)で一覧することができます。 お気に入りに登録したことは相手に通知されず、お気に入りは自分しか見ることができません。 - -ノートをお気に入り登録するには、ノートメニューの「お気に入り」を押します。お気に入り解除するには、ノートメニューの「お気に入り解除」を押します。 diff --git a/src/docs/fr-FR/features/follow.md b/src/docs/fr-FR/features/follow.md deleted file mode 100644 index 93c8428e2..000000000 --- a/src/docs/fr-FR/features/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# Abonnements -ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。 diff --git a/src/docs/fr-FR/features/keyboard-shortcut.md b/src/docs/fr-FR/features/keyboard-shortcut.md deleted file mode 100644 index 2bb01c331..000000000 --- a/src/docs/fr-FR/features/keyboard-shortcut.md +++ /dev/null @@ -1,66 +0,0 @@ -# キーボードショートカット - -## Global -これらのショートカットは基本的にどこでも使えます。 - - - - - - - - - - - -
ショートカット効果由来
P, N新規投稿Post, New, Note
Tタイムラインの最も新しい投稿にフォーカスTimeline, Top
Shift + N通知を表示/隠すNotifications
SRechercherSearch
H, ?ヘルプを表示Help
- -## 投稿にフォーカスされた状態 - - - - - - - - - - - - - - - - - - -
ショートカット効果由来
, K, Shift + Tab上の投稿にフォーカスを移動-
, J, Tab下の投稿にフォーカスを移動-
R返信フォームを開くReply
QRenoteフォームを開くQuote
Ctrl + Q即刻Renoteする(フォームを開かずに)-
E, A, +リアクションフォームを開くEmote, reAction
0~9数字に対応したリアクションをする(対応については後述)-
F, Bお気に入りに登録Favorite, Bookmark
Del, Ctrl + D投稿を削除Delete
M, O投稿に対するメニューを開くMore, Other
SCWで隠された部分を表示 or 隠すShow, See
Escフォーカスを外す-
- -## Renoteフォーム - - - - - - - - - -
ショートカット効果由来
EnterRenoteする-
Qフォームを展開するQuote
Escフォームを閉じる-
- -## リアクションフォーム -デフォルトで「👍」にフォーカスが当たっている状態です。 - - - - - - - - - - - - - -
ショートカット効果由来
, K上のリアクションにフォーカスを移動-
, J下のリアクションにフォーカスを移動-
, H, Shift + Tab左のリアクションにフォーカスを移動-
, L, Tab右のリアクションにフォーカスを移動-
Enter, Space, +リアクション確定-
0~9数字に対応したリアクションで確定-
Escリアクションするのをやめる-
diff --git a/src/docs/fr-FR/features/mfm.md b/src/docs/fr-FR/features/mfm.md deleted file mode 100644 index 5be2df4f3..000000000 --- a/src/docs/fr-FR/features/mfm.md +++ /dev/null @@ -1,12 +0,0 @@ -# MFM -MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます。 - -## MFMが使用可能な場所の例 -- ノート本文 -- CW注釈 -- ユーザーの名前 -- ユーザーの自己紹介 - -## 開発者向け情報 -MFMのパーサー実装はライブラリとして公開されており、簡単にクライアントにMFMを組み込むことが可能です。 -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptパーサー実装 diff --git a/src/docs/fr-FR/features/mute-and-block.md b/src/docs/fr-FR/features/mute-and-block.md deleted file mode 100644 index 9f4cfd39b..000000000 --- a/src/docs/fr-FR/features/mute-and-block.md +++ /dev/null @@ -1,41 +0,0 @@ -# Masqué·e·s / Bloqué·e·s -好みではないユーザーがいる場合は、ミュートを行うことでそのユーザーが自分から見えないようにすることができます。 また、より強力な措置として、ブロックを行うことでそのユーザーから自分のコンテンツが見えないようになるほか、自分に対して関わることができないようにすることができます。 ミュートされていることは相手は分かりませんが、ブロックされていることは相手に分かります。どちらを選ぶかはご自身の判断で行ってください。 - -
ℹ️ ミュートとブロックは併用できます。
- -
⚠️ 利用規約に違反するような、迷惑なユーザーがいる場合は運営者に報告することも検討してください。
- -設定>ミュートとブロック から、自分がミュートまたはブロックしているユーザー一覧を確認することができます。 - -## Masquer -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -- タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -- そのユーザーからの通知 -- メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 -- など - -ユーザーをミュートするには、対象のユーザーのユーザーページのメニューを開き、「ミュート」ボタンを押します。 - -
ℹ️ ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。
- -## Bloquer -ユーザーをブロックすると、そのユーザーからあなたのコンテンツが見えないようになり、またあなたに対して以下のようなアクションをすることができなくなります。 - -- フォローする -- ユーザーリストに追加する -- 返信する、Renoteする -- リアクションする、アンケートに投票する -- メッセージを送信する -- など - -また、 - -- ブロックする際に既にそのユーザーからフォローされていた場合はフォローが解除されます。 -- ブロックする際に既にそのユーザーがあなたをユーザーリストに入れていた場合はそのリストからあなたが削除されます。 - -ユーザーをブロックするには、対象のユーザーのユーザーページのメニューを開き、「ブロック」ボタンを押します。 - -
⚠️ ブロックを行ったこと自体は相手に通知されませんが、フォローを行ったりなどの上記のアクションが行えなくなるので間接的にブロックされていることは分かります。
- -
⚠️ 相手から自分のコンテンツが見えなくなりますが、相手がアカウントを切り替えたりログアウト状態になれば見ることができます。あくまで簡易的、補助的なものとしてお考えください。
diff --git a/src/docs/fr-FR/features/mute.md b/src/docs/fr-FR/features/mute.md deleted file mode 100644 index b64dbfeae..000000000 --- a/src/docs/fr-FR/features/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# Masquer - -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -* タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -* そのユーザーからの通知 -* メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 - -ユーザーをミュートするには、対象のユーザーのユーザーページに表示されている「ミュート」ボタンを押します。 - -ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。 - -設定>ミュート から、自分がミュートしているユーザー一覧を確認することができます。 diff --git a/src/docs/fr-FR/features/note.md b/src/docs/fr-FR/features/note.md deleted file mode 100644 index 9aa6de7de..000000000 --- a/src/docs/fr-FR/features/note.md +++ /dev/null @@ -1,54 +0,0 @@ -# Notes -ノートは、Misskeyに投稿される、文章、ファイル、アンケートなどを含むコンテンツで、Misskeyの中心的概念です。また、そのノートを作成する行為自体もノートと呼ばれます。 - -ノートが作成されると、[タイムライン](./timeline)に追加され、自分の[フォロワー](./follow)やサーバーのユーザーが見れるようになります。 - -ノートには、[リアクション](./reaction)を行うことができます。また、返信や引用もできます。 - -ノートを[お気に入り](./favorite)登録することで、後で簡単に見返すことができます。 - -## ノートを作成する -ノートを作成するには、画面上にある鉛筆マークのボタンを押して、作成フォームを開きます。作成フォームに内容を入力し、「ノート」ボタンを押すことでノートが作成されます。 ノートには、画像、動画など任意のファイルや、[アンケート](./poll)を添付することができます。また、本文中には[MFM](./mfm)が使用でき、[メンション](./mention)や[ハッシュタグ](./hashtag)を含めることもできます。 他にも、CWや公開範囲といった設定も行えます(詳細は後述)。 -
ℹ️ コンピューターのクリップボードに画像データがある状態で、フォーム内のテキストボックスにペーストするとその画像を添付することができます。
-
ℹ️ テキストボックス内でCtrl + Enterを押すことでも投稿できます。
- -## Renoter -既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノートをRenoteと呼びます。 自分がフォローしているユーザーの、気に入ったノートを自分のフォロワーに共有したい場合や、過去の自分のノートを再度共有したい場合に使います。 同じノートに対して無制限にRenoteを行うことができますが、あまり連続して使用すると迷惑になる場合もあるので、注意しましょう。 -
⚠️ 公開範囲がフォロワーやダイレクトのノートはRenoteできません
- -Renoteを削除するには、Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 - -## CW -Contents Warningの略で、ノートの内容を、閲覧者の操作なしには表示しないようにできる機能です。主に長大な内容を隠すためや、ネタバレ防止などに使うことができます。 設定するには、フォームの「内容を隠す」ボタン(目のアイコン)を押します。すると新しい入力エリアが表れるので、そこに内容の要約を記入します。 - -## Visibilité -ノートごとに、そのノートが公開される範囲を設定することができます。フォームの「ノート」ボタンの左にあるアイコンを押すと公開範囲を以下から選択できます。 - -### Public -全ての人に対してノートが公開されるほか、サーバーの全てのタイムライン(ホームタイムライン、ローカルタイムライン、ソーシャルタイムライン、グローバルタイムライン)にノートが流れます。 -
⚠️ アカウントがサイレンス状態の時は、この公開範囲は使用できません。
- -### Principal -全ての人に対してノートが公開されますが、フォロワー以外のローカルタイムライン、ソーシャルタイムライン、グローバルタイムラインにはノートは流れません。 - -### Abonné·e·s -自分のフォロワーに対してのみノートを公開します。フォロワーの全てのタイムラインに流れます。 - -### Direct -指定したユーザーに対してのみノートを公開します。指定したユーザーの全てのタイムラインに流れます。 - -### 「ローカルのみ」オプション -このオプションを有効にすると、リモートにノートを連合しなくなります。 - -### 公開範囲の比較 - - - - -
PublicPrincipalAbonné·e·sDirect
フォロワーのLTL/STL/GTL
非フォロワーのLTL/STL/GTL
- -## Épingler sur le profil -ノートをピン留めすると、ユーザーページに常にそのノートを表示しておくことができます。 ノートのメニューを開き、「ピン留め」を選択してピン留めできます。 複数のノートをピン留めできます。 - -## Surveiller -ノートをウォッチすると、自分以外のノートへのリアクションや返信などの通知を受け取ることができます。 ノートのメニューを開き、「ウォッチ」を選択してウォッチできます。 diff --git a/src/docs/fr-FR/features/pages.md b/src/docs/fr-FR/features/pages.md deleted file mode 100644 index 7fc6ee29c..000000000 --- a/src/docs/fr-FR/features/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# Pages - -## Variables -変数を使うことで動的なページを作成できます。テキスト内で { 変数名 } と書くとそこに変数の値を埋め込めます。例えば Hello { thing } world! というテキストで、変数(thing)の値が ai だった場合、テキストは Hello ai world! になります。 - -変数の評価(値を算出すること)は上から下に行われるので、ある変数の中で自分より下の変数を参照することはできません。例えば上から A、B、C と3つの変数を定義したとき、Cの中でABを参照することはできますが、Aの中でBCを参照することはできません。 - -ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。 - -関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。 diff --git a/src/docs/fr-FR/features/reaction.md b/src/docs/fr-FR/features/reaction.md deleted file mode 100644 index a61cee147..000000000 --- a/src/docs/fr-FR/features/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# Réactions -他の人のノートに、絵文字を付けて簡単にあなたの反応を伝えられる機能です。 リアクションするには、ノートの + アイコンをクリックしてピッカーを表示し、絵文字を選択します。 リアクションには[カスタム絵文字](./custom-emoji)も使用できます。 - -## リアクションピッカーのカスタマイズ -ピッカーに表示される絵文字を自分好みにカスタマイズすることができます。 設定の「リアクション」で設定します。 - -## リモート投稿へのリアクションについて -リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。 - -## リモートからのリアクションについて -リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。 diff --git a/src/docs/fr-FR/features/silence.md b/src/docs/fr-FR/features/silence.md deleted file mode 100644 index a33a58525..000000000 --- a/src/docs/fr-FR/features/silence.md +++ /dev/null @@ -1,6 +0,0 @@ -# Mettre en sourdine -サイレンスは、アカウントに設定される状態のひとつです。 - -アカウントがサイレンス状態になると、ノートの公開範囲をパブリックにできなくなります。 ホーム、フォロワー、ダイレクトは選択可能なため、サイレンスを受けた場合でもフォロワーやあなたのユーザーページを直接訪れた場合は投稿を閲覧できますが、GTL(連合タイムライン)やLTL(ローカルタイムライン)には投稿が流れません。 - -アカウントのサイレンス状態は、サーバーのモデレーターによって有効化/無効化されます。 diff --git a/src/docs/fr-FR/features/theme.md b/src/docs/fr-FR/features/theme.md deleted file mode 100644 index 161cc44dd..000000000 --- a/src/docs/fr-FR/features/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# Thème - -テーマを設定して、Misskeyクライアントの見た目を変更できます。 - -## テーマの設定 -設定 > テーマ - -## テーマを作成する -テーマコードはJSON5で記述されたテーマオブジェクトです。 テーマは以下のようなオブジェクトです。 -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... テーマの一意なID。UUIDをおすすめします。 -* `name` ... テーマ名 -* `author` ... テーマの作者 -* `desc` ... テーマの説明(オプション) -* `base` ... 明るいテーマか、暗いテーマか - * `light`にすると明るいテーマになり、`dark`にすると暗いテーマになります。 - * テーマはここで設定されたベーステーマを継承します。 -* `props` ... テーマのスタイル定義。これから説明します。 - -### テーマのスタイル定義 -`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 - -#### バリューで使える構文 -* 16進数で表された色 - * 例: `#00ff00` -* `rgb(r, g, b)`形式で表された色 - * 例: `rgb(0, 255, 0)` -* `rgb(r, g, b, a)`形式で表された透明度を含む色 - * 例: `rgba(0, 255, 0, 0.5)` -* 他のキーの値の参照 - * `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。 - * 例: `@panel` -* 定数(後述)の参照 - * `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。 - * 例: `$main` -* 関数(後述) - * `:{関数名}<{引数}<{色}` - -#### Constante -「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 キー名を`$`で始めると、そのキーはCSS変数として出力されません。 - -#### Fonction -wip diff --git a/src/docs/fr-FR/features/timeline.md b/src/docs/fr-FR/features/timeline.md deleted file mode 100644 index 46f26ffd3..000000000 --- a/src/docs/fr-FR/features/timeline.md +++ /dev/null @@ -1,31 +0,0 @@ -# Fil -タイムラインは、[ノート](./note)が時系列で表示される機能です。 タイムラインには以下で示す種類があり、種類によって表示されるノートも異なります。 なお、タイムラインの種類によってはサーバーにより無効になっている場合があります。 - -## Principal -自分のフォローしているユーザーの投稿が流れます。HTLと略されます。 - -## Local -全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。LTLと略されます。 - -## Social -自分のフォローしているユーザーの投稿と、全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。STLと略されます。 - -## Global -全てのローカルユーザーの「ホーム」指定されていない投稿と、サーバーに届いた全てのリモートユーザーの「ホーム」指定されていない投稿が流れます。GTLと略されます。 - -## Comparer -| ソース | | | Fil | | | -| ------------------ | ---------- | --------- | ----- | ------ | ------ | -| Utilisateur·rice·s | Visibilité | Principal | Local | Social | Global | -| ローカル (フォロー) | Public | ✔ | ✔ | ✔ | ✔ | -| | Principal | ✔ | | ✔ | | -| | Abonné·e·s | ✔ | ✔ | ✔ | ✔ | -| リモート (フォロー) | Public | ✔ | | ✔ | ✔ | -| | Principal | ✔ | | ✔ | | -| | Abonné·e·s | ✔ | | ✔ | ✔ | -| ローカル (未フォロー) | Public | | ✔ | ✔ | ✔ | -| | Principal | | | | | -| | Abonné·e·s | | | | | -| リモート (未フォロー) | Public | | | | ✔ | -| | Principal | | | | | -| | Abonné·e·s | | | | | diff --git a/src/docs/fr-FR/features/widgets.md b/src/docs/fr-FR/features/widgets.md deleted file mode 100644 index 7c5cacb39..000000000 --- a/src/docs/fr-FR/features/widgets.md +++ /dev/null @@ -1,7 +0,0 @@ -# Widgets -ウィジェットは、MisskeyのUI上に設置できる小型の情報表示、操作が行えるパーツです。 - -ウィジェットを編集するには、ウィジェット編集モードに切り替えます。切り替え方法はUIによって異なります。 ウィジェット編集モードでは、ウィジェットの追加、削除、並び替え、およびそれぞれのウィジェットの設定を行えます。 - -## 利用可能なウィジェット一覧 -todo diff --git a/src/docs/fr-FR/features/word-mute.md b/src/docs/fr-FR/features/word-mute.md deleted file mode 100644 index 84935a428..000000000 --- a/src/docs/fr-FR/features/word-mute.md +++ /dev/null @@ -1,20 +0,0 @@ -# Filtre de mots -ワードミュートの設定をすると、条件に合致したノートが表示されなくなります。 - -ワードミュートには、ソフトワードミュートとハードワードミュートの2種類があります。それぞれについて設定の方法と挙動を説明します。 - -## ソフトワードミュート -ソフトワードミュートは、クライアント(アプリ)側でミュートを判断するワードミュートです。 - -ノートが設定した条件に合致すると、「(ユーザー名)が何かを言いました」という表示で隠れます。 -クリックすると元の通りに表示されます。 - -## ハードワードミュート -ハードワードミュートは、アンテナのようにサーバーが新しいノートの本文に対して条件に合致するかどうか判断し、タイムラインから対象となったノートを除外します。 - -つまり、ハードワードミュートには、以下のような特徴があります。 - -* 条件設定後、新しい投稿のみがミュートの対象になります。 -* 条件を変更しても、過去にハードミュートされたノートはミュートされたままになります。 -* 「○○が何かを言いました」でタイムラインが埋まることがありません。 -* ソフトミュートに非対応のアプリでも、ハードミュートは適用されます。 diff --git a/src/docs/fr-FR/follow.md b/src/docs/fr-FR/follow.md deleted file mode 100644 index fde5c5e47..000000000 --- a/src/docs/fr-FR/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# Abonnements -Lorsque vous suivez un·e utilisateur·rice, ses publications apparaissent dans votre fil.Cela n'inclut toutefois pas ses réponses aux autres utilisateur·ice·s. Pour suivre un compte, rendez-vous sur sa page et cliquez sur le bouton « s'abonner ». Vous pouvez vous désabonner du compte en cliquant une seconde fois. diff --git a/src/docs/fr-FR/general/apps.md b/src/docs/fr-FR/general/apps.md deleted file mode 100644 index 32a1274a5..000000000 --- a/src/docs/fr-FR/general/apps.md +++ /dev/null @@ -1,6 +0,0 @@ -# Liste des applications tierces -## Client -todo - -## Services connexes -todo diff --git a/src/docs/fr-FR/general/changelog.md b/src/docs/fr-FR/general/changelog.md deleted file mode 100644 index 0f2c782a9..000000000 --- a/src/docs/fr-FR/general/changelog.md +++ /dev/null @@ -1,5 +0,0 @@ -# Journal des changements -
ℹ️ Ce journal concerne uniquement les changements survenus sur ce serveur. Pour en savoir plus sur la dernière version de Misskey, merci de vous rendre sur GitHub.
- - - diff --git a/src/docs/fr-FR/general/faq.md b/src/docs/fr-FR/general/faq.md deleted file mode 100644 index 0ec7159eb..000000000 --- a/src/docs/fr-FR/general/faq.md +++ /dev/null @@ -1,28 +0,0 @@ -# Questions fréquentes -Vous trouverez ici les questions les plus fréquentes sur l'utilisation de Misskey. Les questions fréquentes concernant Misskey en tant que projet sont publiées [sur cette page](./misskey). - -## « Existe-t-il des appli pour Android / iOS ? » -Bien qu'il n'existe d'application Misskey officielle pour aucun OS, différentes applications développées par des tiers sont disponibles. [Voir ici](./apps) pour plus de détails. - -Cependant, à moins que vous ne soyez particulièrement déterminé·e à utiliser une application dédiée, l'utilisation du client Web officiel est vivement recommandée du fait que les applications développées par des tiers seront forcément en retard par rapport à celui-ci. Par ailleurs, étant donné que le client Web de Misskey est compatible avec une PWA, il peut adopter le comportement d'une application native. [Voir ici](todo) pour plus d'informations. - -## « Ne peut-on pas utiliser un client Mastodon pour se connecter à Misskey ? » -Étant donné que Misskey n'est pas compatible avec l'API Mastodon, sauf cas exceptionnels, il n'est pas possible d'utiliser un client Mastodon pour Misskey. - -## « Comment faire pour suivre des utilisateur·rice·s d'autres instances ? » -Sélectionnez la fonction « Recherche » depuis le menu et tapez le nom d'utilisateur·rice suivi du nom de l'instance. Ex. : `@syuilo@misskey.io` - -## « Comment puis-je annuler une Renote ? » -Cliquez sur sur les trois points (« ... ») situés à côté de l'horodatage de votre Renote et sélectionnez « Annuler la Renote ». Pour en savoir plus sur les Renotes, vous pouvez consulter [cette page](../features/note). - -## « Je ne veux pas afficher les aperçus d'URL. » -Vous pouvez désactiver l'affichage des aperçus d'URL grâce au langage MFM. Voir l'[Antisèche MFM](/mfm-cheat-sheet) pour plus de détails. - -## « Je veux ajouter des émojis personnalisés. » -Seul·e·s les administrateur·rice·s peuvent ajouter, éditer ou effacer des émojis personnalisés. Ainsi, si vous avez une requête à ce sujet, merci de contacter votre administrateur·rice d'instance. - -## « Je veux créer un Bot. » -Vous pouvez développer un Bot en utilisant l'API de Misskey. Plus d'informations sur [cette page](../advanced/develop-bot). - -## « Quel est le service utilisé pour la fonctionnalité de traduction des notes ? » -Il s'agit de [DeepL](https://www.deepl.com/). diff --git a/src/docs/fr-FR/general/glossary.md b/src/docs/fr-FR/general/glossary.md deleted file mode 100644 index 863ca57ba..000000000 --- a/src/docs/fr-FR/general/glossary.md +++ /dev/null @@ -1,89 +0,0 @@ -# Glossaire -Glossaire des termes utilisés dans Misskey. - -## ActivityPub -Nom du protocole (procédé technique) utilisé par Misskey pour pouvoir fonctionner comme service décentralisé. Ce protocole permet à tous les serveurs l'ayant adopté de communiquer entre eux et de former une sorte de fédération que l'on appelle « Fédiverse ». - -## AiScript -Langage de programmation qui peut être utilisé sur Misskey. [Voir ici pour plus d'informations.](../advanced/aiscript) - -## API -Interface pour permettre à un programme d'utiliser Misskey, disponible publiquement sur le serveur de Misskey. [Voir ici pour plus d'informations. ](../advanced/api) - -## Bot -Anglicisme désignant un compte géré par un programme informatique (vous le trouverez parfois aussi sous le terme de « robot »). - -## CW -Abréviation de « Content Warning » (qui signifie littéralement « alerte de contenu »). Fonctionnalité permettant d'assujettir l'affichage du contenu d'une note à une intervention de l'utilisateur·rice par le biais d'un bouton de masquage automatique. Principalement employée pour cacher le contenu des notes très longues, ou pour éviter de dévoiler publiquement des spoils potentiels, etc. - -## Fédiverse -Nom du réseau social fédéré qui rassemble une multitude d'instances appartenant à différents services et dont fait partie Misskey. - -## FG -Abréviation de « Fil global ». Pour en savoir plus sur les différents fils, [voir ici.](../features/timeline) - -## FP -Abréviation de « Fil principal ». Pour en savoir plus sur les différents fils, [voir ici.](../features/timeline) - -## FL -Abréviation de « Fil local ». Pour en savoir plus sur les différents fils, [voir ici.](../features/timeline) - -## MFM -Abréviation de « Misskey Flavored Markdown », un langage Markdown qui peut être utilisé sur Misskey. [Voir ici pour plus d'informations.](../features/mfm) - -## NSFW -Abréviation de « Not Safe For Work » (qui signifie littéralement « pas sûr pour le travail »). Fonctionnalité permettant d'avertir que le contenu d'une note n'est pas approprié sur le lieu de travail et d'en assujettir l'affichage à une intervention de l'utilisateur·rice par le biais d'un bouton de masquage automatique. - -## Renoter -Il s'agit du fait de citer une note existante ou de partager une note existante dans une nouvelle note. La note créée par l'un de ces deux biais est alors appelée une « Renote ». [Voir ici pour plus d'informations.](../features/note) - -## FS -Abréviation de « Fil social ». Pour en savoir plus sur les différents fils, [voir ici.](../features/timeline) - -## Ai -Nom de la mascotte officielle de Misskey. (Le mot japonais, à prononcer « a-i », signifie littéralement « indigo »). - -## Utilisateurices actif·ve·s -Désigne les utilisateur·rice·s, parmi tou·te·s celleux inscrit·e·s sur l'instance, qui utilisent effectivement leur compte au moment présent. - -## Instance -todo - -## Émojis personnalisés -Désigne les émojis mis à disposition par votre instance. Par opposition, les émojis disponibles par défaut (donc pas « personnalisés ») sont appelés « émojis unicode ». - -## Panneau de contrôle -Écran de contrôle des paramètres d'instance. - -## Serveurs -todo - -## Mettre en sourdine -Désigne le fait de paramétrer un compte pour empêcher ses publications d'être partagées en mode « Public ». Peut être appliqué à des utilisateur·rice·s individuel·le·s à la discrétion des modérateur·rice·s. [Voir ici pour plus d'informations. ](../features/silence) - -## File d’attente -Système permettant de distribuer les activités dans un ordre successif. - -## Suspendre -Désigne le fait de paramétrer un compte pour le rendre inutilisable à son/sa propriétaire. - -## Drive -Fonctionnalité vous permettant de gérer les fichiers que vous avez téléversés sur Misskey. [Voir ici pour plus d'informations. ](../features/drive) - -## Notes -Nom des publications sur Misskey. Leur contenu peut être du texte, mais aussi des fichiers, des enquêtes, etc. [Voir ici pour plus d'informations.](../features/note) - -## Misskeynaute -Désigne les utilisateur·rice·s de Misskey. - -## Modérateur·rice·s -Utilisateur·rice·s chargé·e·s de gérer la communauté d'une instance, ayant autorité pour désactiver les comptes de spam, mettre des utilisateur·rice·s en sourdine, supprimer des publications inappropriées, etc. - -## Distant -Désigne les autres instances que celle où vous êtes inscrit·e. Peut aussi être utilisé pour qualifier d'autres mots, comme « utilisateur·rice·s distant·e·s ». C'est le contraire de « local ». - -## Fédération -Désigne le fait de partager les informations publiées sur un serveur avec les autres serveurs du réseau. - -## Local -Désigne l'instance où vous êtes inscrit·e. Peut aussi être utilisé pour qualifier d'autres mots, comme « utilisateur·rice·s locaux·cales » ou « fil local ». C'est le contraire de « distant ». diff --git a/src/docs/fr-FR/general/links.md b/src/docs/fr-FR/general/links.md deleted file mode 100644 index a8c08df93..000000000 --- a/src/docs/fr-FR/general/links.md +++ /dev/null @@ -1,12 +0,0 @@ -# Liens utiles - -## Sites internet -- [Official Discord](https://discord.gg/Wp8gVStHW3) - Serveur Discord officiel de Misskey -- [Misskey Forum](https://forum.misskey.io/) - Forum pour discuter de tout sujet en lien avec Misskey - -## Comptes -- [@repo@misskey.io](https://misskey.io/@repo) - Bot publiant les mises à jour effectuées dans le dépôt Misskey - -## Programmathèques -- [misskey-dev/misskey.js](https://github.com/misskey-dev/misskey.js) - SDK de Misskey en JavaScript -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - Implémentation d'un analyseur MFM en JavaScript diff --git a/src/docs/fr-FR/general/misskey.md b/src/docs/fr-FR/general/misskey.md deleted file mode 100644 index 1fb7008ce..000000000 --- a/src/docs/fr-FR/general/misskey.md +++ /dev/null @@ -1,87 +0,0 @@ -# À propos de Misskey - -Misskeyはオープンソースの分散型マイクロブログプラットフォームプロジェクトです。 開発は日本でsyuiloによって2014年から開始されました。 ドライブ、リアクションなどの豊富な機能や、高いカスタマイズ性を備えたUIを持つことが特徴です。 - -## 歴史 -開発当初は掲示板がメインのサービスでしたが、ユーザーが短文を投稿し、それを時系列で流れるタイムライン機能を追加したところ人気が高まり、徐々にそれがメインとして開発が進むようになりました。 当初は分散型ではありませんでしたが、2018年にActivityPubを実装し分散型になったことで、より多くの方に認知され利用されるサービスになり、現在に至ります。 -
ℹ️ Misskeyという名前は、syuiloが当時聴いていたMay'nというアーティストの楽曲、Brain Diverの歌詞に由来します。
- -誰でも開発に参加することができ、現在でも活発に開発が続いています。 - -## 分散型とは何か? - -分散(distributed)型とは、非中央集権(decentralized)とも呼ばれ、コミュニティが多数のサーバーに分散して存在し、それらが相互に通信(連合、federation)することでコンテンツ共有ネットワーク(Fediverse)を形成していることが特徴のサービスです。 単一のサーバーしか存在しない、もしくは複数存在しても互いに独立している場合は中央集権なサービスと言われ、例えばTwitterやFacebookなどほとんどのサービスがそれに該当します。 分散型のメリットは、自分に合った運営者やテーマのサーバーを選択できることです。自分でサーバーを作成することもできます。連合するおかげで、どのサーバーを選んでも、同じコミュニティにアクセスできます。 - -## 常にオープンソース -Misskeyはこれまでもこれからも、オープンソースであり続けます。オープンソースとは、簡単に言うとソフトウェアのソースコード(プログラム)が公開されていることです。ソースコードの修正や再配布が可能であることを定義に含めることもあります。 Misskeyのすべてのソースコードは[AGPL](https://github.com/misskey-dev/misskey/blob/develop/LICENSE)というオープンソースライセンスの下に[公開](https://github.com/misskey-dev)されていて、誰でも自由に閲覧、使用、修正、改変、再配布をすることができます。 オープンソースは、自分で好きなように変えたり、有害な処理が含まれていないことを確認することができたり、誰でも開発に参加できるなどの、様々なメリットがあります。 上述の分散型を実現するためにも、オープンソースであるということは必要不可欠な要素です。 再び引き合いに出しますが、TwitterやFacebookなどの利益を得ているほとんどのサービスはオープンソースではありません。 - -
ℹ️ 技術的に言うと、MisskeyのソースコードはGitで管理されていて、リポジトリはGitHub上でホスティングされています。
- -## 開発に参加する、プロジェクトを支援する -Misskeyを気に入っていただけたら、ぜひプロジェクトを支援してください。プロジェクトに貢献するには、以下で紹介するようにいろいろな方法があります。方法によっては開発のスキルは不要なので、誰でも気軽に参加し貢献することができます。いつでもお待ちしています。 - -### 機能を追加したり、バグを修正する -ソフトウェアエンジニアのスキルをお持ちの方であれば、ソースコードを編集する形でプロジェクトに貢献することができます。 貢献についてのガイドは[こちら](https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md)です。 - -### 議論に参加する -新しい機能、または既存の機能について意見を述べたり、不具合を報告したりすることでも貢献できます。 そのようなディスカッションは[GitHub](https://github.com/misskey-dev)上か、[フォーラム](https://forum.misskey.io/)等で行われます。 - -### テキストを翻訳する -Misskeyは様々な言語に対応しています(i18n -internationalizationの略- と呼ばれます)。元の言語は基本的に日本語ですが、有志によって他の言語へと翻訳されています。 その翻訳作業に加わっていただくことでもMisskeyに貢献できます。 Misskeyは[Crowdinというサービスを使用して翻訳の管理を行っています。](https://crowdin.com/project/misskey) - -### 感想を投稿する -不具合報告等だけではなく、Misskeyの良い点、楽しい点といったポジティブな意見もぜひ共有してください。開発の励みになり、それは間接的ですがプロジェクトへの貢献です。 - -### ミスキストを増やす -ミスキストとは、Misskeyを使用する人のことです。 知り合いに紹介するなどしてMisskeyを広めていただければ、ミスキストが増え開発のモチベーションが上がります。 - -### 寄付をする -Misskeyはビジネスではなく、利用は無料であるため、収益は皆様からの寄付のみです。(インスタンスによっては広告収入を得ているような場合もありますが、それは運営者の収入であり直接開発者への収入にはなりません) 寄付をしていただければ、今後も開発を続けることが可能になり、プロジェクトへの貢献になります。 寄付は基本的には[Patreon](https://www.patreon.com/syuilo)で受け付けています。 一定額寄付していただけると、Misskeyの[情報ページ](/about-misskey)に名前を記載することができます。 - -また、サーバーの運営者も、基本的には収益を得ていません。サーバーの運営にはコストがかかるので、運営者の支援をすることもご検討ください。 開発には直接関係しませんが、サーバーがあってこそのプロジェクトなので、運営が維持されるというのは開発と同じくらい重要なことです。 - -## クレジット -Misskeyの開発者や、Misskeyに寄付をしてくださった方の一覧は[こちら](/about-misskey)で見ることができます。 - -## Questions fréquentes -### プロジェクトは何を目指していますか? -強いて言うと、漠然的になりますが広く使われる汎用的なプラットフォームになることを目指しています。 Misskeyは他のプロジェクトとは違い、何らかの思想(例えば、反中央集権)やビジョンに基づいて開発が行われているわけではなく、その点ではフラットです。 それが逆に、特定の方向性に縛られないフレキシブルさを生み出すことに繋がっていると感じています。 - - -### 企業によって開発されていますか? -いいえ。Misskeyの開発は個人で行われており、商業的でもないため、特定の企業の関りはありません。 開発メンバーも基本的にはボランティアです。 また、開発に対し企業のスポンサーがつくこともありますが、その場合でもやはり開発は個人のコミュニティが主体です。 - -### 誰が運営していますか? -Misskeyは分散型なため、各サーバーにそれぞれ異なった運営者がいます。従って、特定の個人や企業によって、Misskeyの全てが運営されているわけではありません。 また、開発チームが運営を行うわけでもないため、運営に関する連絡は、お使いのサーバーの運営者に行ってください。 サーバーの運営者は、[このページ](/about)で確認することができます。 あなたがサーバーを作成すれば、あなたが運営者になります。 - -### どのサーバーを選べばいいですか? -[サーバー一覧が公開されています。](https://join.misskey.page/ja-JP/instances) サーバーによってコミュニティのテーマ(特定のこと、ものが好き 等)が決められている場合があるので、自分に合ったテーマのサーバーがあれば、そこを選ぶと良いかもしれません。 他にも、サーバーの規模、ユーザー層、国および言語、運営者が信頼できるかどうか、などの観点があります。 なお、Misskey公式のサーバーというものはありません。自身で新しくサーバーを作成するという選択肢もあります。 - -基本的にどのサーバーを選んだとしても、他の全てのサーバーのユーザーと繋がることができます。 - -### サーバーを建てるにはどうしたらいいですか? -Misskeyサーバーの作成に興味を持っていただきありがとうございます。 2021年現在、Misskeyのホスティングサービスは存在しないため、サーバーの作成にはある程度の知識が必要です。 サーバーの作成方法については[こちら](todo)をご覧ください。 - -### どのような技術を使用していますか? -Misskeyは開発が進むにつれ使用する技術も大きく変わってきました。開発当初はMySQL + PHP + jQueryといった構成でしたが、現在は以下のようになっています。 -- サーバーサイド: Node.js -- データベース: PostgreSQL、Redis -- UIフレームワーク: Vue.js -- プログラミング言語: TypeScript - -また、MFMやAiScriptなどの、Misskeyから派生して独自の技術も開発しています。 - -### Mastodonのフォークですか? -いいえ。MisskeyはMastodonやその他のプロジェクトとは全く別のプロジェクトです。 開発に関しても、Misskeyの方が昔から開発されています。ただし、分散型になったのはMastodonの登場より後です。 同じActivityPubという分散のためのプロトコルを実装しているという点以外、両者に特に関りがあるわけでもありません。 - -### « Existe-t-il des appli pour Android / iOS ? » -Bien qu'il n'existe d'application Misskey officielle pour aucun OS, différentes applications développées par des tiers sont disponibles. [Voir ici](./apps) pour plus de détails. - -Cependant, à moins que vous ne soyez particulièrement déterminé·e à utiliser une application dédiée, l'utilisation du client Web officiel est vivement recommandée du fait que les applications développées par des tiers seront forcément en retard par rapport à celui-ci. Par ailleurs, étant donné que le client Web de Misskey est compatible avec une PWA, il peut adopter le comportement d'une application native. [Voir ici](todo) pour plus d'informations. - -### Misskeyのロゴ、アイコンはどこで入手できますか? -(準備中) - -### 時折目にする猫耳の可愛い女の子は? -Misskeyの守り神、藍ちゃんです。アイチャンカワイイヤッター! -
ℹ️ 藍ちゃんについてはこちらです。
diff --git a/src/docs/fr-FR/general/report-issue.md b/src/docs/fr-FR/general/report-issue.md deleted file mode 100644 index 903335218..000000000 --- a/src/docs/fr-FR/general/report-issue.md +++ /dev/null @@ -1,8 +0,0 @@ -# Signaler un problème -Lorsque vous pensez rencontrer un bug, commencez par consulter la page [Résolution des problèmes](./troubleshooting). Si, malgré cela, vous ne parvenez toujours pas à résoudre le problème, vous pouvez le soumettre sur le [Forum](https://forum.misskey.io/) en incluant dans votre message les renseignements listés ci-dessous. Contribuer sur le Forum vous permettra soit de trouver une solution soit de conclure à un bug, auquel cas l'équipe de développement sera en mesure d'effectuer les corrections nécessaires. - -## Renseignements à inclure -- La version de Misskey que vous utilisez (peut être consultée sur la page [À propos de Misskey](/about)) -- Le nom et la version du navigateur que vous utilisez -- Le nom et la version du système d'exploitation que vous utilisez -- Les étapes à suivre pour reproduire votre problème diff --git a/src/docs/fr-FR/general/troubleshooting.md b/src/docs/fr-FR/general/troubleshooting.md deleted file mode 100644 index 3abcf3400..000000000 --- a/src/docs/fr-FR/general/troubleshooting.md +++ /dev/null @@ -1,40 +0,0 @@ -# Résolution des problèmes -
ℹ️ N'hésitez pas à consulter les Questions fréquentes en complément de cette page.
- -Lorsque vous rencontrez un problème, nous vous prions de lire cette page tout d'abord. Si toutefois aucun des paragraphes ci-dessous ne correspond à votre problème, ou bien si vous n'arrivez pas à le résoudre en suivant les instructions détaillées ici, nous vous invitons à contacter l'administrateur·rice de votre instance ou à [Signaler un bug](./report-issue). - -## Le client ne démarre pas -Généralement, ce problème est dû au fait que vous utilisez une version trop ancienne de votre navigateur ou de votre système d'exploitation. Effectuez les mises à jour pour chacun d'eux vers leurs versions les plus récentes, puis essayez à nouveau. - -Cela arrive rarement, mais si votre client ne démarre toujours pas après cela, le problème vient du cache. Dans ce cas, videz le cache et essayez à nouveau. - -## La page ne charge pas -Si votre client démarre mais qu'un message d'erreur apparaît lors du chargement de la page, assurez-vous qu'il ne s'agit pas d'un problème de connexion au réseau. Assurez-vous également que votre serveur n'est pas temporairement inaccessible. - -Bien que cela arrive rarement, il se peut que le cache soit à l'origine du problème. Dans ce cas, videz le cache et essayez à nouveau. - -Si le problème persiste malgré tout, il est très probable qu'il s'agisse d'une panne côté serveur ; nous vous invitons donc à contacter l'administrateur·rice de votre instance. - -## Le client est lent -Essayez les solutions proposées ci-dessous : - -- activer l'option « Réduire les animations dans l'interface » dans les paramètres du client -- désactiver l'option « Utiliser un effet de flou pour les modals » dans les paramètres du client -- activer l'accélération matérielle dans les paramètres de votre navigateur -- effectuer les mises à jour de votre appareil. - -## Certaines parties de l'interface ne s'affichent pas correctement (arrière-plan transparent, etc.) -Cela peut être lié au système de mise en cache du thème lorsqu'une mise à jour visant à améliorer l'interface a eu lieu. Pour résoudre le problème, sélectionnez la touche « Vider le cache » dans les paramètres du client. -
⚠️ Attention de bien vider le cache du -client-... et pas celui du -navigateur- !
- -## Les pastilles de notification clignotantes ne disparaissent pas -Une pastille clignotante indique la présence de nouveau contenu que vous n'avez pas encore lu. Lorsque cette pastille ne disparaît pas, c'est généralement parce que du contenu laissé non lu a été repoussé par la réception de nouveau contenu. S'il s'avère que vous avez déjà lu le contenu dans sa totalité mais que la pastille continue tout de même de clignoter, il s'agit alors vraisemblablement d'un bug et vous pouvez forcer Misskey à tout marquer comme lu depuis vos paramètres généraux. - -## La fonction « Renoter » ne fonctionne pas -Les notes dont l'audience est limitée aux « Abonné·e·s uniquement » ne peuvent pas être renotées. - -## Des éléments spécifiques de l'interface ne s'affichent pas -Ce type de dysfonctionnement survient lorsque vous utilisez des bloqueurs de publicité. Désactivez-les pour profiter d'une expérience optimale sur Misskey. - -## Certaines parties de l'interface ne sont pas traduites -La plupart du temps, cela n'est pas un bug mais simplement un problème de traduction qui n'a pas encore été faite. Merci de patienter jusqu'à ce que la traduction de la portion en question soit achevée. Vous pouvez également [aider à traduire](./misskey) Misskey. diff --git a/src/docs/fr-FR/keyboard-shortcut.md b/src/docs/fr-FR/keyboard-shortcut.md deleted file mode 100644 index 1223224f4..000000000 --- a/src/docs/fr-FR/keyboard-shortcut.md +++ /dev/null @@ -1,68 +0,0 @@ -# Raccourcis clavier - -## Général -Ces raccourcis sont utilisables dans n'importe quel contexte. - - - - - - - - - - - -
RaccourciEffetAccès universel
P, NRédiger une nouvelle publicationPost, New, Note
TAfficher la dernière publicationTimeline, Top
Shift + NAfficher/cacher les notificationsNotifications
SRechercherSearch
H, ?Afficher l'aideHelp
- -## Actions concernant les publications - - - - - - - - - - - - - - - - - - - -
RaccourciEffetAccès universel
, K, Shift + TabDéplacer le focus sur la publication du dessus-
, J, TabDéplacer le focus sur la publication du dessous-
ROuvrir la fenêtre de réponseReply
QOuvrir la fenêtre de RenoteQuote
Ctrl + QRenote rapide (sans ouvrir de fenêtre)-
E, A, +Ouvrir la fenêtre de réactionsEmote, reAction
0~9Utiliser la réaction attribuée au chiffre-
F, BAjouter à mes favorisFavorite, Bookmark
Del, Ctrl + DSupprimer la publicationDelete
M, OOuvrir le menu des publicationsMore, Other
SAfficher ou cacher le contenu marqué CWShow, See
EscQuitter le focus-
- -## Formulaire de Renote - - - - - - - - - - -
RaccourciEffetAccès universel
EnterRenoter-
QOuvrir la fenêtreQuote
EscFermer la fenêtre-
- -## Fenêtre de réactions -La réaction sélectionnée par défaut est « 👍 ». - - - - - - - - - - - - - -
RaccourciEffetAccès universel
, KDéplacer le focus vers la réaction du dessus-
, JDéplacer le focus vers la réaction du dessous-
, H, Shift + TabDéplacer le focus vers la réaction de gauche-
, L, TabDéplacer le focus vers la réaction de droite-
Enter, Space, +Sélectionner la réaction-
0~9Utiliser la réaction correspondant au chiffre-
EscAnnuler la réaction-
diff --git a/src/docs/fr-FR/mfm.md b/src/docs/fr-FR/mfm.md deleted file mode 100644 index 107911c0a..000000000 --- a/src/docs/fr-FR/mfm.md +++ /dev/null @@ -1,2 +0,0 @@ -# MFM -MFM – abréviation de Misskey Flavored Markdown – est un langage Markdown spécifique utilisable ici et là dans Misskey. Vous pouvez vérifier les structures utilisables dans [l'antisèche MFM](/mfm-cheat-sheet). diff --git a/src/docs/fr-FR/mute.md b/src/docs/fr-FR/mute.md deleted file mode 100644 index 7760caa43..000000000 --- a/src/docs/fr-FR/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# Masquer - -Le contenu afférent à un utilisateur ne vous sera plus présenté dès lors que vous le masquez : - -* les publications de cet·te utilisateur·ice dans le fil ou les résultats de recherche, de même que ses réponses et Renotes ; -* les notifications touchant à cet·te utilisateur·ice ; -* l'historique des messages avec cet·te utilisateur·ice. - -Pour masquer un·e utilisateur·ice, utilisez le bouton « Masquer » de sa page de profil. - -L'utilisateur·rice que vous ignorez ne sera pas prévenu·e. De même, vous ne serez pas prévenu·e lorsque vous serez ignoré·e par un·e autre utilisateur·rice. - -Vous pouvez vérifier la liste des utilisateur·rice·s masqué·e·s depuis l'onglet « Masqués » de vos paramètres. diff --git a/src/docs/fr-FR/pages.md b/src/docs/fr-FR/pages.md deleted file mode 100644 index 0dbafb806..000000000 --- a/src/docs/fr-FR/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# Pages - -## Variables -Vous pouvez créer des pages dynamiques en utilisant des variables.Vous pouvez incorporer la valeur d'une variable en insérant le { variablename } dans votre texte.Par exemple, si la valeur de la variable "thing" dans le texte Hello { thing } world! est ai, votre trexte devient alors : Hello ai world!. - -Les variables sont prises en compte dans l'ordre chronologique, de haut en bas. Il n'est donc pas possible d'appeler une variable située plus bas dans le code. Par exemple, si vous définissez, dans l'ordre, 3 variables telles que A, B, C, vous pourrez appeler en C aussi bien A que B ; par contre, vous ne pourrez appeler en A ni B ni C. - -Pour recevoir une entrée utilisateur, ajoutez un bloc "Entrée" sur la page et définissez le nom des variables que vous souhaitez stocker dans le champ "Nom de la variable" (les variables seront créées automatiquement).Vous pourrez alors exécuter les actions en fonction de l'entrée utilisateur de ces variables. - -Appeler des fonctions vous permet de définir des valeurs que vous pourrez réutiliser. Pour créer des fonctions, il faut d'abord définir une variable du type "fonction". Vous pouvez y configurer des « slots » (arguments), dont la valeur devient alors disponible en tant que variable à l'intérieur de la fonction. Par ailleurs, il existe ce que l'on appelle des "fonctions d'ordre supérieur" dont les arguments sont aussi des fonctions. En plus de paramétrer des fonctions à l'avance, vous avez également la possibilité de définir des fonctions à l'improviste directement dans les « slots » de ces fonctions d'ordre supérieur. diff --git a/src/docs/fr-FR/reaction.md b/src/docs/fr-FR/reaction.md deleted file mode 100644 index 164a257d4..000000000 --- a/src/docs/fr-FR/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# Réactions -Les réactions vous permettent d'interagir facilement avec les notes des autres utilisateur·rice·s en y attribuant des émojis. Pour réagir, cliquez sur le « + » de la note afin d'afficher le panneau de sélection puis choisissez un émoji. Il est également possible d'utiliser des [émojis personnalisés](./custom-emoji). - -## Personnalisation du panneau de réactions -Il est possible de choisir les émojis affichés dans le panneau de réactions en allant dans l'onglet « réactions » des paramètres. - -## Envoi de réactions à des serveurs distants -Les réactions étant une fonctionnalité originale de Misskey, la plupart des autres instances du Fediverse recevront votre réaction comme un simple "J'aime" - à moins qu'il s'agisse d'une autre instance Misskey.Généralement dans le Fediverse, les " J'aime " sont appelés " Favoris ". En outre, si vous réagissez avec un émoji personnalisé, même si l'instance destinataire est une instance Misskey, il sera automatiquement transmis comme un " 👍 " ou assimilé. - -## Réception de réactions de la part de serveurs distants -Les " J'aime " que vous recevez de la part d'utilisateur·ice·s d'autres instances apparaissent sur Misskey sous la forme de " 👍 ". diff --git a/src/docs/fr-FR/reversi-bot.md b/src/docs/fr-FR/reversi-bot.md deleted file mode 100644 index c75cb1784..000000000 --- a/src/docs/fr-FR/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# Développement du bot Reversi de Misskey -Cette page explique comment développer un bot pour la fonction Reversi de Misskey. - -1. Connectez-vous au flux `games/reversi` avec les paramètres suivants : - * `i` : Clé API pour le compte du bot - -2. Lorsqu'une invitation à un jeu arrive, un événement `invited` sera lancé à partir du flux. - * Le contenu de cet événement est un attribut `parent`, qui contient des informations sur l'utilisateur qui a envoyé l'invitation. - -3. Envoie une requête à `games/reversi/match`, où la valeur du paramètre `user_id` est l'attribut `id` de l'objet `parent` obtenu précédemment. - -4. Si la requête fonctionne, les informations sur le jeu seront renvoyées et vous pourrez vous connecter au flux `games/reversi-game` avec les paramètres suivants : - * `i` : Clé API pour le compte du bot - * `game`: `game` de `id` - -5. Pendant ce temps, l'adversaire peut modifier les paramètres du jeu. Chaque fois qu'un paramètre est modifié, le flux envoie un événement `update-settings`, donc une logique pour gérer ces événements peut être nécessaire. - -6. Une fois que vous êtes satisfait·e des paramètres du jeu, envoyez le message `{ type : 'accept' }` au flux. - -7. Lorsque le jeu commence, l'événement `started` sera envoyé. - * Les informations sur l'état du jeu seront inclus dans cet événement. - -8. Pour placer une pierre, envoyez `{ type : 'set', pos : cette terminaison. diff --git a/src/docs/fr-FR/stream.md b/src/docs/fr-FR/stream.md deleted file mode 100644 index 6e8d7b782..000000000 --- a/src/docs/fr-FR/stream.md +++ /dev/null @@ -1,354 +0,0 @@ -# API streaming - -L'API Streaming permet d'implémenter l'exécution d'opérations variées et la réception de diverses informations en temps réel. Cela concerne, par exemple, l'affichage des nouvelles publications dans les fils, la réception de nouveaux messages, les nouveaux abonnements, etc. - -## Se connecter aux flux - -Pour utiliser l'API de streaming, vous devez d'abord effectuer une connexion **websocket** au serveur Misskey. - -Veuillez vous connecter à l'URL suivante avec le nom de paramètre `i` et inclure les informations d'authentification dans la connexion websocket.Par exemple : -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -Les informations d'identification sont votre clé API ou, en cas de connexion au flux depuis votre application, le jeton d'accès de l'utilisateur. - -
-

Pour obtenir des informations sur l'obtention d'accréditations, veuillez consulter ce document.

-
- ---- - -Vous pouvez omettre les informations d'authentification, mais dans ce cas, vous utiliserez le système sans vous connecter, et les informations que vous pourrez recevoir et les opérations que vous pourrez effectuer seront limitées.Par exemple : - -``` -%WS_URL%/streaming -``` - ---- - -Une fois que vous êtes connecté au flux, vous pouvez utiliser l'API comme décrit ci-dessous, ou vous abonner aux messages. Cependant, à ce stade, vous ne pouvez pas recevoir de nouveaux messages sur votre fil, par exemple. Pour ce faire, vous devez vous connecter à un **canal** sur le flux, comme décrit ci-dessous. - -**Toutes les interactions dans le flux sont JSON.** - -## Canaux -L'API de streaming de Misskey possède le concept de canaux.Il s'agit d'un mécanisme permettant de séparer les informations que vous envoyez et recevez. Si vous vous connectez simplement à un flux Misskey, vous ne pourrez pas encore recevoir les messages de votre timeline en temps réel. En vous connectant aux canaux du flux, vous pourrez recevoir diverses informations et en envoyer. - -### Se connecter à un canal -Pour se connecter à un canal, envoyez les données suivantes au flux en JSON : - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -Ici, -* Définissez `channel` au nom du canal auquel vous voulez vous connecter.Les types de canaux sont décrits ci-dessous. -* `id` est un identifiant arbitraire pour interagir avec ce canal.En effet, le flux contient une variété de messages, et nous devons identifier de quel canal provient le message.Cet ID peut être un UUID ou une sorte de numéro aléatoire. -* `params` sont les paramètres utilisés pour se connecter au canal.Les différents canaux nécessitent des paramètres différents pour la connexion.Lors de la connexion à un canal qui ne nécessite pas de paramètres, cette propriété peut être omise. - -
-

L'ID est "par connexion de canal", et non par canal. En effet, dans certains cas, plusieurs connexions sont établies sur le même canal avec des paramètres différents.

-
- -### Recevoir des messages du canal -Par exemple, lorsqu'un événement est émis dans l'un des canaux du fil en raison de la publication d'un nouveau message.En recevant ce message, vous saurez en temps réel qu'une nouvelle publication a été faite sur votre fil. - -Lorsqu'un canal émet un message, les données suivantes sont diffusées en JSON : -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -Ici, -* `id` est réglé sur l'ID que vous avez défini lors de la connexion à ce canal comme décrit ci-dessus.Cela vous permettra de savoir de quel canal provient ce message. -* `type` est défini comme le type du message.Le type de message qui sera diffusé dépend du canal. -* `body` est défini comme le contenu du message.En fonction du canal, le type de message qui sera diffusé dépendra du canal. - -### Envoi d'un message à un canal -Selon le canal, il se peut que vous ne receviez pas seulement des messages, mais que vous puissiez également envoyer certains messages et effectuer certaines opérations. - -Pour envoyer un message à un canal, envoyez les données suivantes au flux en JSON : -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -Ici, -* `id` doit être réglé sur l'ID que vous avez défini lors de la connexion à ce canal comme décrit ci-dessus.Cela vous permettra d'identifier le canal auquel ce message est destiné. -* `type` définit le type du message.Les différents canaux acceptent différents types de messages. -* `body` est défini comme le contenu du message.Les différents canaux acceptent différents types de messages. - -### Déconnexion d'un canal -Pour se déconnecter d'un canal, envoyez les données suivantes au flux en JSON : - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -Ici, -* `id` doit être réglé sur l'ID que vous avez défini lors de la connexion à ce canal comme décrit ci-dessus. - -## Faire une requête API via le flux - -Si vous effectuez une requête d'API via un flux, vous pouvez utiliser l'API sans générer de requête HTTP.Cela peut rendre votre code plus concis et améliorer les performances. - -Pour effectuer une demande d'API via un flux, envoyez les données suivantes au flux en JSON : -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -Ici, -* `id` doit être défini comme un identifiant unique pour chaque demande d'API afin d'identifier la réponse de l'API.Il peut s'agir de quelque chose comme un UUID ou un simple nombre aléatoire. -* `endpoint` est le point de terminaison de l'API que vous voulez demander. -* `data` contient les paramètres de la terminaison. - -
-

Veuillez vous reporter à la référence de l'API pour les points de terminaison et les paramètres de l'API.

-
- -### Réception des réponses - -Lorsque vous faites une demande à l'API, la réponse viendra du flux dans le format suivant. - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -Ici, -* La partie `xxxxxxxxxxxxxxxx` contient le `id` qui a été défini au moment de la demande.Cela vous permet de déterminer à quelle demande il répond. -* `body` contient la réponse. - -## Capture de message - -Misskey propose un mécanisme appelé post-capture.Il s'agit de la possibilité de recevoir un flux d'événements pour un message donné. - -Par exemple, supposons une situation dans laquelle le fil est affichée pour un utilisateur.Supposons maintenant que quelqu'un réagisse à l'un des messages de ce fil. - -Cependant, comme le client n'a aucun moyen de savoir qu'un message a reçu une réaction, il n'est pas possible de refléter la réaction en temps réel sur le message dans le fil. - -Pour résoudre ce problème, Misskey fournit un mécanisme de post-capture.Lorsque vous capturez un message, vous recevez des événements liés à ce message, ce qui vous permet de refléter les réactions en temps réel. - -### Capturer un message - -Pour capturer un message, envoyez un message comme le suivant au flux : - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -Ici, -* Définissez `id` comme l'`id` du message que vous voulez capturer. - -Lorsque vous envoyez ce message, vous demandez à Misskey de le saisir, et les événements liés à ce message se succéderont à partir de ce moment-là. - -Par exemple, lorsqu'un message suscite une réaction, vous verrez apparaître un message du type suivant : - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -Ici, -* Le `id` dans le `body` est défini comme l'ID du post qui a déclenché l'événement. -* Le type de l'événement est défini par `type` dans `body`. -* L'attribut `body` dans `body` contient les informations sur l'événement. - -#### Type d'événements - -##### `reacted` -Cela se produit lorsqu'une réaction est faite à ce message. - -* `reaction` est défini comme le type de réaction. -* `userId` sera défini comme l'ID de l'utilisateur qui a fait la réaction. - -Par exemple : -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -Cela se produit lorsque ce message est supprimé. - -* `deletedAt` est défini comme la date et l'heure de la suppression. - -Par exemple : -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -Déclenché lors du vote sur un sondage dans ce message. - -* `choice` contient l'ID du choix sélectionné. -* `userId` sera défini comme l'ID de l'utilisateur qui a voté. - -Par exemple : -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### Annuler la capture de publication - -Quand une publication n'est plus affichée et que vous n'avez plus besoin de recevoir les événements la concernant, vous pouvez demander l'annulation de la capture. - -Envoyez le message suivant : - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -Ici, -* Définissez `id` comme le `id` du message que vous voulez annuler. - -Une fois que vous aurez envoyé ce message, aucun autre événement lié au message ne sera diffusé. - -# Liste des canaux -## `main` -Les informations de base relatives au compte seront transmises ici.Il n'y a pas de paramètres pour ce canal. - -### Liste des événements envoyés - -#### `renote` -Cet événement est déclenché lorsque votre message est renoté.Cela ne se produit pas lorsque vous renotez votre propre message. - -#### `mention` -Il s'agit d'un événement qui se produit lorsque quelqu'un fait vous mentionne. - -#### `readAllNotifications` -Cet événement indique que toutes les notifications qui vous ont été adressées ont été lues.Cet événement peut être utilisé pour désactiver des choses comme "l'icône indiquant qu'il y a une notification" et d'autres cas. - -#### `meUpdated` -Cet événement indique que vos informations ont été mises à jour. - -#### `follow` -Cet événement se produit lorsque vous suivez quelqu'un. - -#### `unfollow` -Cet événement se produit lorsque vous retirez quelqu'un de vos suivis. - -#### `followed` -Cet événement se produit lorsque vous êtes suivi par quelqu'un. - -## `homeTimeline` -Vous verrez ce flux d'informations s'afficher sur votre fil personnel.Il n'y a pas de paramètres pour ce canal. - -### Liste des événements envoyés - -#### `note` -Cet événement est déclenché lorsqu'un nouveau message arrive sur sur fil. - -## `localTimeline` -Vous verrez l'information affichée sur votre fil local.Il n'y a pas de paramètres pour ce canal. - -### Liste des événements envoyés - -#### `note` -Cet événement est déclenché lorsqu'un nouveau message apparaît dans le fil local. - -## `hybridTimeline` -Vous verrez l'information affichée sur le fil social.Il n'y a pas de paramètres pour ce canal. - -### Liste des événements envoyés - -#### `note` -Cet événement est déclenché lorsqu'un nouveau message apparaît sur votre fil social. - -## `globalTimeline` -Vous verrez l'information s'afficher sur le fil global.Il n'y a pas de paramètres pour ce canal. - -### Liste des événements envoyés - -#### `note` -Cet événement est déclenché lorsqu'un nouveau message arrive sur le fil global. diff --git a/src/docs/fr-FR/theme.md b/src/docs/fr-FR/theme.md deleted file mode 100644 index 1ea74ae8a..000000000 --- a/src/docs/fr-FR/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# Thème - -Vous pouvez modifier l'apparence de votre client Misskey à l'aide de thèmes. - -## Paramètres de thème -Paramètres > Thèmes - -## Créer un thème -Le code des thèmes est écrit sous forme d'objets JSON5. Les thèmes comprennent les objets suivants : -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... L'identifiant unique du thème. L'utilisation d'un UUID est recommandée ; -* `name` ... Nom du thème ; -* `author` ... Auteur du thème ; -* `desc` ... Description du thème (facultatif) ; -* `base` ... Thème clair ou sombre : - * Sélectionnez `light` pour définir le thème comme thème clair et `dark` pour le définir comme sombre, - * Le thème héritera des valeurs par défaut du thème spécifié ici ; -* `props` ... Définir un style de thème.Voir les explications ci-après. - -### Définir un style de thème -C'est dans `props` que vous définirez le style du thème. Les clés deviendront des noms de variables CSS dont le contenu sera spécifié par les valeurs associées. Par ailleurs, les objets présents par défaut dans `props` sont hérités du thème de base. Ainsi, si le thème de `base` est `clair`, ce sera le fichier [_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5) ; et s'il est `sombre`, le fichier [_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5). En bref, s'il n'y a, par exemple, pas de clé `panel` définie dans les `props` du thème, alors ce sera la valeur `panel` du thème de base qui sera prise en compte. - -#### Syntaxe des valeurs -* Codes de couleur Hex - * Ex. : `#00ff00` -* Couleurs avec les valeurs RVB : `rgb(r, g, b)` - * Ex. : `rgb(0, 255, 0)` -* Couleurs avec les valeurs RVBA : `rgba(r, g, b, a)` - * Ex. : `rgba(0, 255, 0, 0.5)` -* Appeler les valeurs d'autres clés - * Entrer `@{keyname}` pour appeler la valeur d'une autre clé. Remplacer alors `{keyname}` par le nom de la clé que vous souhaitez appeler. - * Ex. : `@panel` -* Constantes (voir ci-dessous) - * Entrer `${constantname}` vous permet d'appeler une constante. Remplacer alors `{constantname}` par le nom de la constante que vous souhaitez appeler. - * Ex. : `$main` -* Fonctions (voir ci-dessous) - * `:{functionname}<{argument}<{color}` - -#### Constantes -Dans le cas où vous ne souhaiteriez pas qu'une valeur génère une variable CSS mais que vous voudriez l'utiliser comme valeur pour une autre variable CSS, vous avez la possibilité d'utiliser une constante. Il suffit de faire précéder le nom de la propriété de : `$` pour que celle-ci ne génère pas de variable CSS. - -#### Fonctions -wip diff --git a/src/docs/fr-FR/timelines.md b/src/docs/fr-FR/timelines.md deleted file mode 100644 index 308dccaaa..000000000 --- a/src/docs/fr-FR/timelines.md +++ /dev/null @@ -1,15 +0,0 @@ -# Comparaison des fils - -https://docs.google.com/spreadsheets/d/1lxQ2ugKrhz58Bg96HTDK_2F98BUritkMyIiBkOByjHA/edit?usp=sharing - -## Principal -Les publications des utilisateurs que vous suivez - -## Local -Les publications des utilisateurs de votre instance. Les notes publiées avec le statut « principal » n'y sont pas affichées. - -## Social -Regroupe le fil principal et le fil local - -## Global -Toutes les publications reçues par l'instance, qu'elles soient locales ou non. Les notes publiées avec le statut « principal » n'y sont pas affichées. diff --git a/src/docs/ht-HT/admin/disable-timelines.md b/src/docs/ht-HT/admin/disable-timelines.md deleted file mode 100644 index b081e35ab..000000000 --- a/src/docs/ht-HT/admin/disable-timelines.md +++ /dev/null @@ -1,8 +0,0 @@ -# LTL/STL/GTLの無効化 -Misskeyでは、LTL/STL/GTLをそれぞれ無効化することができます。有効/無効を切り替えるには、インスタンスコントロールパネルで設定します。 - -LTLやSTLは、そのインスタンス全員の投稿が見れるため、新規のユーザーにとってはユーザーを探す必要がなくなり、興味のあるユーザーを見つけやすいという利点があります。 しかし同時に、フォロー機能が活用されなくなったり、不適切な投稿が目につきやすくなったり、チャットのようになることで内輪感が生じて逆に新規ユーザーが参加しにくくなるといったデメリットも持ち合わせています。 サーバーによってメリット/デメリットどちらが優勢かは異なるので、オプションとして無効にできるようになっています。 もしデメリットの方が上回っていると感じたら、それらのタイムラインを無効化することも検討してください。 - -
⚠️ 無効化を行うと、ユーザーが困惑し、短期的に見て利用者が減る可能性があります。そのため、無効化の際は影響を慎重に検討し、事前に説明してフォローを整える期間を一定程度設けることを推奨します。
- -なお、管理者/モデレーターは、これらのタイムラインの無効化状態は適用されず、引き続き利用することが可能です。 diff --git a/src/docs/ht-HT/admin/faq.md b/src/docs/ht-HT/admin/faq.md deleted file mode 100644 index 317b4e065..000000000 --- a/src/docs/ht-HT/admin/faq.md +++ /dev/null @@ -1,5 +0,0 @@ -# よくある質問 -ここでは、サーバー管理者向けのよくある質問を掲載しています。 - -## デフォルトテーマを設定したい -現在、デフォルトテーマ設定機能は実装されていません。 diff --git a/src/docs/ht-HT/advanced/aiscript.md b/src/docs/ht-HT/advanced/aiscript.md deleted file mode 100644 index 604d17daa..000000000 --- a/src/docs/ht-HT/advanced/aiscript.md +++ /dev/null @@ -1,7 +0,0 @@ -# AiScript -AiScriptは、Misskeyで使用できるスクリプト言語です。 - -
ℹ️ AiScript実装はMisskeyとは別リポジトリで、オープンソースで公開されています。
- -## 使い方 -AiScriptの構文や組み込み関数などのドキュメントは、[こちら](https://github.com/syuilo/aiscript/tree/master/docs)で公開されています。 diff --git a/src/docs/ht-HT/advanced/api.md b/src/docs/ht-HT/advanced/api.md deleted file mode 100644 index 76019b614..000000000 --- a/src/docs/ht-HT/advanced/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス、Bot等(以下「アプリケーション」と呼びます)を開発できます。 ストリーミングAPIもあるので、リアルタイム性のあるアプリケーションを作ることも可能です。 - -APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。 - -## アクセストークンの取得 -基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。 - -* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む -* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む - -### 自分自身のアクセストークンを手動発行する -「設定 > API」で、自分のアクセストークンを発行できます。 - -[「APIの使い方」へ進む](#APIの使い方) - -### アプリケーション利用者にアクセストークンの発行をリクエストする -アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。 - -#### Step 1 - -UUIDを生成する。以後これをセッションIDと呼びます。 - -> このセッションIDは毎回生成し、使いまわさないようにしてください。 - -#### Step 2 - -`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。 -> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます: -* `name` ... アプリケーション名 - * > 例: `MissDeck` -* `icon` ... アプリケーションのアイコン画像URL - * > 例: `https://missdeck.example.com/icon.png` -* `callback` ... 認証が終わった後にリダイレクトするURL - * > 例: `https://missdeck.example.com/callback` - * リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます -* `permission` ... アプリケーションが要求する権限 - * > 例: `write:notes,write:following,read:drive` - * 要求する権限を`,`で区切って列挙します - * どのような権限があるかは[APIリファレンス](/api-doc)で確認できます - -#### Step 3 -ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。 - -レスポンスに含まれるプロパティ: -* `token` ... ユーザーのアクセストークン -* `user` ... ユーザーの情報 - -[「APIの使い方」へ進む](#APIの使い方) - -## APIの使い方 -**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。 - -* [APIリファレンス](/api-doc) -* [ストリーミングAPI](./stream) diff --git a/src/docs/ht-HT/advanced/create-plugin.md b/src/docs/ht-HT/advanced/create-plugin.md deleted file mode 100644 index 0d2fa1917..000000000 --- a/src/docs/ht-HT/advanced/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# プラグインの作成 -Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。 - -## メタデータ -プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。 - -### name -プラグイン名 - -### author -プラグイン作者 - -### version -プラグインバージョン。数値を指定してください。 - -### description -プラグインの説明 - -### permissions -プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。 - -### config -プラグインの設定情報を表すオブジェクト。 キーに設定名、値に以下のプロパティを含めます。 - -#### type -設定値の種類を表す文字列。以下から選択します。 string number boolean - -#### label -ユーザーに表示する設定名 - -#### description -設定の説明 - -#### default -設定のデフォルト値 - -## APIリファレンス -AiScript標準で組み込まれているAPIは掲載しません。 - -### Mk:dialog(title text type) -ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。 - -### Mk:confirm(title text type) -確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。 - -### Mk:api(endpoint params) -Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。 - -### Mk:save(key value) -任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。 - -### Mk:load(key) -Mk:saveで永続化した指定の名前の値を読み取ります。 - -### Plugin:register_post_form_action(title fn) -投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。 - -### Plugin:register_note_action(title fn) -ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 - -### Plugin:register_user_action(title fn) -ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。 - -### Plugin:register_note_view_interruptor(fn) -UIに表示されるノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:register_note_post_interruptor(fn) -ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:open_url(url) -第一引数に渡されたURLをブラウザの新しいタブで開きます。 - -### Plugin:config -プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。 diff --git a/src/docs/ht-HT/advanced/develop-bot.md b/src/docs/ht-HT/advanced/develop-bot.md deleted file mode 100644 index 7f825e9bc..000000000 --- a/src/docs/ht-HT/advanced/develop-bot.md +++ /dev/null @@ -1,6 +0,0 @@ -# Botの作成 -[Misskey API](./api)を利用してBotの開発が可能です。 また、いくつかのBot実装が公開されているため、ぜひ参考にしてください。 - -- [syuilo/ai](https://github.com/syuilo/ai) ... Node.js上で動く、TypeScript製Bot実装 - -Botを作成したときは、プロフィール設定からBotフラグをオンにしておくことを強くおすすめします。 diff --git a/src/docs/ht-HT/advanced/reversi-bot.md b/src/docs/ht-HT/advanced/reversi-bot.md deleted file mode 100644 index 7ab2a7212..000000000 --- a/src/docs/ht-HT/advanced/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# MisskeyリバーシBotの開発 -Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。 - -1. `games/reversi`ストリームに以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - -2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる - * イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている - -3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する - -4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - * `game`: `game`の`id` - -5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う - -6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する - -7. ゲームが開始すると、`started`イベントが流れてくる - * イベントの中身にはゲーム情報が含まれている - -8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述) - -9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる - * `color`として石の色が含まれている - * `pos`として位置情報が含まれている - -## 位置の計算法 -8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### X,Y座標 から インデックス に変換する -``` -pos = x + (y * mapWidth) -``` -`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます: -``` -mapWidth = map[0].length -``` - -### インデックス から X,Y座標 に変換する -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## マップ情報 -マップ情報は、ゲーム情報の`map`に入っています。 文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 それをもとにマップのデザインを知る事が出来ます: -* `(スペース)` ... マス無し -* `-` ... マス -* `b` ... 初期配置される黒石 -* `w` ... 初期配置される白石 - -例えば、4*4の次のような単純なマップがあるとします: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -この場合、マップデータはこのようになります: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## ユーザーにフォームを提示して対話可能Botを作成する -ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。 - -フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します: -```javascript -{ - type: 'init-form', - body: [フォームコントロールの配列] -} -``` - -フォームコントロールの配列については今から説明します。 フォームコントロールは、次のようなオブジェクトです: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... コントロールのID。 `type` ... コントロールの種類。後述します。 `label` ... コントロールと一緒に表記するテキスト。 `value` ... コントロールのデフォルト値。 - -### フォームの操作を受け取る -ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### フォームコントロールの種類 -#### スイッチ -type: `switch` スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。 - -##### プロパティ -`label` ... スイッチに表記するテキスト。 - -#### ラジオボタン -type: `radio` ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。 - -##### プロパティ -`items` ... ラジオボタンの選択肢。例: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '強', - value: 3 -}] -``` - -#### スライダー -type: `slider` スライダーを表示します。 - -##### プロパティ -`min` ... スライダーの下限。 `max` ... スライダーの上限。 `step` ... 入力欄で刻むステップ値。 - -#### テキストボックス -type: `textbox` テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。 - -## ユーザーにメッセージを表示する -設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 メッセージを表示するには、次のメッセージをストリームに送信します: -```javascript -{ - type: 'message', - body: { - text: 'メッセージ内容', - type: 'メッセージの種類' - } -} -``` -メッセージの種類: `success`, `info`, `warning`, `error`。 - -## 投了する -投了をするには、このエンドポイントにリクエストします。 diff --git a/src/docs/ht-HT/advanced/share-page.md b/src/docs/ht-HT/advanced/share-page.md deleted file mode 100644 index 4fb7ded0b..000000000 --- a/src/docs/ht-HT/advanced/share-page.md +++ /dev/null @@ -1,54 +0,0 @@ -# シェアページ -`/share`を開くと、共有用の投稿フォームを開くことができます。 ここではシェアページで利用できるクエリ文字列の一覧を示します。 - -## クエリ文字列一覧 -### 文字 - -
-
title
-
タイトルです。本文の先頭に[ … ]と挿入されます。
-
text
-
本文です。
-
url
-
URLです。末尾に挿入されます。
-
- -### リプライ情報 -以下のいずれか - -
-
replyId
-
リプライ先のノートid
-
replyUri
-
リプライ先のUrl(リモートのノートオブジェクトを指定)
-
- -### Renote情報 -以下のいずれか - -
-
renoteId
-
Renote先のノートid
-
renoteUri
-
Renote先のUrl(リモートのノートオブジェクトを指定)
-
- -### 公開範囲 -※specifiedに相当する値はvisibility=specifiedとvisibleAccts/visibleUserIdsで指定する - -
-
visibility
-
公開範囲 ['public' | 'home' | 'followers' | 'specified']
-
localOnly
-
0(false) or 1(true)
-
visibleUserIds
-
specified時のダイレクト先のユーザーid カンマ区切りで
-
visibleAccts
-
specified時のダイレクト先のacct(@?username[@host]) カンマ区切りで
-
- -### ファイル -
-
fileIds
-
添付したいファイルのid(カンマ区切りで)
-
diff --git a/src/docs/ht-HT/advanced/stream.md b/src/docs/ht-HT/advanced/stream.md deleted file mode 100644 index 0e5edd2b0..000000000 --- a/src/docs/ht-HT/advanced/stream.md +++ /dev/null @@ -1,350 +0,0 @@ -# ストリーミングAPI - -ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。 - -## ストリームに接続する - -ストリーミングAPIを利用するには、まずMisskeyサーバーに**websocket**接続する必要があります。 - -以下のURLに、`i`というパラメータ名で認証情報を含めて、websocket接続してください。例: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。 - -
ℹ️ 認証情報の取得については、こちらのドキュメントをご確認ください。
- ---- - -認証情報は省略することもできますが、その場合非ログインでの利用ということになり、受信できる情報や可能な操作は限られます。例: - -``` -%WS_URL%/streaming -``` - ---- - -ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。 - -**ストリームでのやり取りはすべてJSONです。** - -## チャンネル -MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。 - -ひとつのストリーム上で、同時に複数のチャンネルに接続することができます。 - -### チャンネルに接続する -チャンネルに接続するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -ここで、 -* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。 -* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。 -* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。 - -
ℹ️ IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。
- -### チャンネルからのメッセージを受け取る -例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。 - -チャンネルがメッセージを発すると、次のようなデータがJSONでストリームに流れてきます: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。 -* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。 -* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。 - -### チャンネルに向けてメッセージを送信する -チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。 - -チャンネルにメッセージを送信するには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。 -* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。 -* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。 - -### チャンネルから切断する -チャンネルから切断するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。 - -## ストリームを経由してAPIリクエストする - -ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。 - -ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -ここで、 -* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 -* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 -* `data`には、エンドポイントのパラメータを含めます。 - -
ℹ️ APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。
- -### レスポンスの受信 - -APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。 - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -ここで、 -* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 -* `body`には、レスポンスが含まれています。 - -## 投稿のキャプチャ - -Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。 - -例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。 - -しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。 - -この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。 - -### 投稿をキャプチャする - -投稿をキャプチャするには、ストリームに次のようなメッセージを送信します: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャしたい投稿の`id`を設定します。 - -このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 - -例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -ここで、 -* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。 -* `body`内の`type`に、イベントの種類が設定されます。 -* `body`内の`body`に、イベントの詳細が設定されます。 - -#### イベントの種類 - -##### `reacted` -その投稿にリアクションがされた時に発生します。 - -* `reaction`に、リアクションの種類が設定されます。 -* `userId`に、リアクションを行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -その投稿が削除された時に発生します。 - -* `deletedAt`に、削除日時が設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -その投稿に添付されたアンケートに投票された時に発生します。 - -* `choice`に、選択肢IDが設定されます。 -* `userId`に、投票を行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### 投稿のキャプチャを解除する - -その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。 - -次のメッセージを送信します: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャを解除したい投稿の`id`を設定します。 - -このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 - -# チャンネル一覧 -## `main` -アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `renote` -自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。 - -#### `mention` -誰かからメンションされたときに発生するイベントです。 - -#### `readAllNotifications` -自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。 - -#### `meUpdated` -自分の情報が更新されたことを表すイベントです。 - -#### `follow` -自分が誰かをフォローしたときに発生するイベントです。 - -#### `unfollow` -自分が誰かのフォローを解除したときに発生するイベントです。 - -#### `followed` -自分が誰かにフォローされたときに発生するイベントです。 - -## `homeTimeline` -ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -タイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `localTimeline` -ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `hybridTimeline` -ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ソーシャルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `globalTimeline` -グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 diff --git a/src/docs/ht-HT/aiscript.md b/src/docs/ht-HT/aiscript.md deleted file mode 100644 index 6c28b446e..000000000 --- a/src/docs/ht-HT/aiscript.md +++ /dev/null @@ -1,4 +0,0 @@ -# AiScript - -## 関数 -デフォルトで値渡しです。 diff --git a/src/docs/ht-HT/api.md b/src/docs/ht-HT/api.md deleted file mode 100644 index 76019b614..000000000 --- a/src/docs/ht-HT/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス、Bot等(以下「アプリケーション」と呼びます)を開発できます。 ストリーミングAPIもあるので、リアルタイム性のあるアプリケーションを作ることも可能です。 - -APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。 - -## アクセストークンの取得 -基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。 - -* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む -* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む - -### 自分自身のアクセストークンを手動発行する -「設定 > API」で、自分のアクセストークンを発行できます。 - -[「APIの使い方」へ進む](#APIの使い方) - -### アプリケーション利用者にアクセストークンの発行をリクエストする -アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。 - -#### Step 1 - -UUIDを生成する。以後これをセッションIDと呼びます。 - -> このセッションIDは毎回生成し、使いまわさないようにしてください。 - -#### Step 2 - -`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。 -> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます: -* `name` ... アプリケーション名 - * > 例: `MissDeck` -* `icon` ... アプリケーションのアイコン画像URL - * > 例: `https://missdeck.example.com/icon.png` -* `callback` ... 認証が終わった後にリダイレクトするURL - * > 例: `https://missdeck.example.com/callback` - * リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます -* `permission` ... アプリケーションが要求する権限 - * > 例: `write:notes,write:following,read:drive` - * 要求する権限を`,`で区切って列挙します - * どのような権限があるかは[APIリファレンス](/api-doc)で確認できます - -#### Step 3 -ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。 - -レスポンスに含まれるプロパティ: -* `token` ... ユーザーのアクセストークン -* `user` ... ユーザーの情報 - -[「APIの使い方」へ進む](#APIの使い方) - -## APIの使い方 -**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。 - -* [APIリファレンス](/api-doc) -* [ストリーミングAPI](./stream) diff --git a/src/docs/ht-HT/create-plugin.md b/src/docs/ht-HT/create-plugin.md deleted file mode 100644 index 0d2fa1917..000000000 --- a/src/docs/ht-HT/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# プラグインの作成 -Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。 - -## メタデータ -プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。 - -### name -プラグイン名 - -### author -プラグイン作者 - -### version -プラグインバージョン。数値を指定してください。 - -### description -プラグインの説明 - -### permissions -プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。 - -### config -プラグインの設定情報を表すオブジェクト。 キーに設定名、値に以下のプロパティを含めます。 - -#### type -設定値の種類を表す文字列。以下から選択します。 string number boolean - -#### label -ユーザーに表示する設定名 - -#### description -設定の説明 - -#### default -設定のデフォルト値 - -## APIリファレンス -AiScript標準で組み込まれているAPIは掲載しません。 - -### Mk:dialog(title text type) -ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。 - -### Mk:confirm(title text type) -確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。 - -### Mk:api(endpoint params) -Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。 - -### Mk:save(key value) -任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。 - -### Mk:load(key) -Mk:saveで永続化した指定の名前の値を読み取ります。 - -### Plugin:register_post_form_action(title fn) -投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。 - -### Plugin:register_note_action(title fn) -ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 - -### Plugin:register_user_action(title fn) -ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。 - -### Plugin:register_note_view_interruptor(fn) -UIに表示されるノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:register_note_post_interruptor(fn) -ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:open_url(url) -第一引数に渡されたURLをブラウザの新しいタブで開きます。 - -### Plugin:config -プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。 diff --git a/src/docs/ht-HT/custom-emoji.md b/src/docs/ht-HT/custom-emoji.md deleted file mode 100644 index ed2e92be1..000000000 --- a/src/docs/ht-HT/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# カスタム絵文字 -カスタム絵文字は、インスタンスで用意された画像を絵文字のように使える機能です。 ノート、リアクション、チャット、自己紹介、名前などの場所で使うことができます。 カスタム絵文字をそれらの場所で使うには、絵文字ピッカーボタン(ある場合)を押すか、`:`を入力して絵文字サジェストを表示します。 テキスト内に`:foo:`のような形式の文字列が見つかると、`foo`の部分がカスタム絵文字名と解釈され、表示時には対応したカスタム絵文字に置き換わります。 diff --git a/src/docs/ht-HT/deck.md b/src/docs/ht-HT/deck.md deleted file mode 100644 index 8057e262f..000000000 --- a/src/docs/ht-HT/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# デッキ - -デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。 - -## カラムの追加 -デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。 - -## カラムの移動 -カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。 - -## カラムの水平分割 -カラムは左右だけでなく、上下に並べることもできます。 カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 上下分割を解除するには、カラムメニューの「右に出す」を選択します。 - -## カラムの設定 -カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。 - -## デッキの設定 -デッキに関する設定は、[settings/deck](/settings/deck)で行えます。 diff --git a/src/docs/ht-HT/features/antenna.md b/src/docs/ht-HT/features/antenna.md deleted file mode 100644 index 94ad9e4ae..000000000 --- a/src/docs/ht-HT/features/antenna.md +++ /dev/null @@ -1,4 +0,0 @@ -# アンテナ -アンテナは、自由に条件を設定して、合致するノートを自動で収集することができる機能です。 - -条件を設定したアンテナが作成された状態で、条件に合致するノートが投稿されると、リアルタイムでそのアンテナのタイムラインにノートが追加されます。 diff --git a/src/docs/ht-HT/features/custom-emoji.md b/src/docs/ht-HT/features/custom-emoji.md deleted file mode 100644 index ed2e92be1..000000000 --- a/src/docs/ht-HT/features/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# カスタム絵文字 -カスタム絵文字は、インスタンスで用意された画像を絵文字のように使える機能です。 ノート、リアクション、チャット、自己紹介、名前などの場所で使うことができます。 カスタム絵文字をそれらの場所で使うには、絵文字ピッカーボタン(ある場合)を押すか、`:`を入力して絵文字サジェストを表示します。 テキスト内に`:foo:`のような形式の文字列が見つかると、`foo`の部分がカスタム絵文字名と解釈され、表示時には対応したカスタム絵文字に置き換わります。 diff --git a/src/docs/ht-HT/features/deck.md b/src/docs/ht-HT/features/deck.md deleted file mode 100644 index 8057e262f..000000000 --- a/src/docs/ht-HT/features/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# デッキ - -デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。 - -## カラムの追加 -デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。 - -## カラムの移動 -カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。 - -## カラムの水平分割 -カラムは左右だけでなく、上下に並べることもできます。 カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 上下分割を解除するには、カラムメニューの「右に出す」を選択します。 - -## カラムの設定 -カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。 - -## デッキの設定 -デッキに関する設定は、[settings/deck](/settings/deck)で行えます。 diff --git a/src/docs/ht-HT/features/drive.md b/src/docs/ht-HT/features/drive.md deleted file mode 100644 index b82a41082..000000000 --- a/src/docs/ht-HT/features/drive.md +++ /dev/null @@ -1,17 +0,0 @@ -# ドライブ -ドライブは、Misskey上でファイルを管理できる機能です。 - -[ドライブのページ](/my/drive)から任意のファイルをアップロードできるほか、アバターに設定した画像や、ノートに添付したファイルなどもすべてドライブにアップロードされます。 - -
⚠️ ドライブからファイルを削除すると、そのファイルが添付されたノートも消えます。
- -ドライブにアップロードされたファイルは、いつでもダウンロードすることができるほか、ノート作成時に「ドライブからファイルを添付」することでファイルを再利用することもできます。 - -ドライブ内にフォルダを作り、複数のファイルをまとめて整理することもできます。 - -## 閲覧注意 (NSFW) -
ℹ️ この項目が閲覧注意なわけではありません
- -閲覧注意またはNSFW (Not safe for work) は、ドライブのファイルに設定することができるフラグです。 閲覧注意フラグを設定されたファイルは、表示される際に閲覧者の操作なしには表示されなくなります。 このフラグは、例えば職場や公共の場で閲覧するのに適切でないと思われる画像などに設定し、そのような画像が突然表示されてしまうことを防ぐ目的で使われます。 - -このフラグは手動でオンオフを切り替えられるほか、モデレーターの判断で設定される場合もあります。 diff --git a/src/docs/ht-HT/features/favorite.md b/src/docs/ht-HT/features/favorite.md deleted file mode 100644 index a0e5f8bf7..000000000 --- a/src/docs/ht-HT/features/favorite.md +++ /dev/null @@ -1,4 +0,0 @@ -# お気に入り -[ノート](./node)をお気に入りとして登録できる機能です。 お気に入り登録したノートは、[お気に入りページ](./my/favorites)で一覧することができます。 お気に入りに登録したことは相手に通知されず、お気に入りは自分しか見ることができません。 - -ノートをお気に入り登録するには、ノートメニューの「お気に入り」を押します。お気に入り解除するには、ノートメニューの「お気に入り解除」を押します。 diff --git a/src/docs/ht-HT/features/follow.md b/src/docs/ht-HT/features/follow.md deleted file mode 100644 index 3c1ea7bbe..000000000 --- a/src/docs/ht-HT/features/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# フォロー -ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。 diff --git a/src/docs/ht-HT/features/keyboard-shortcut.md b/src/docs/ht-HT/features/keyboard-shortcut.md deleted file mode 100644 index 8659ace98..000000000 --- a/src/docs/ht-HT/features/keyboard-shortcut.md +++ /dev/null @@ -1,66 +0,0 @@ -# キーボードショートカット - -## グローバル -これらのショートカットは基本的にどこでも使えます。 - - - - - - - - - - - -
ショートカット効果由来
P, N新規投稿Post, New, Note
Tタイムラインの最も新しい投稿にフォーカスTimeline, Top
Shift + N通知を表示/隠すNotifications
S検索Search
H, ?ヘルプを表示Help
- -## 投稿にフォーカスされた状態 - - - - - - - - - - - - - - - - - - -
ショートカット効果由来
, K, Shift + Tab上の投稿にフォーカスを移動-
, J, Tab下の投稿にフォーカスを移動-
R返信フォームを開くReply
QRenoteフォームを開くQuote
Ctrl + Q即刻Renoteする(フォームを開かずに)-
E, A, +リアクションフォームを開くEmote, reAction
0~9数字に対応したリアクションをする(対応については後述)-
F, Bお気に入りに登録Favorite, Bookmark
Del, Ctrl + D投稿を削除Delete
M, O投稿に対するメニューを開くMore, Other
SCWで隠された部分を表示 or 隠すShow, See
Escフォーカスを外す-
- -## Renoteフォーム - - - - - - - - - -
ショートカット効果由来
EnterRenoteする-
Qフォームを展開するQuote
Escフォームを閉じる-
- -## リアクションフォーム -デフォルトで「👍」にフォーカスが当たっている状態です。 - - - - - - - - - - - - - -
ショートカット効果由来
, K上のリアクションにフォーカスを移動-
, J下のリアクションにフォーカスを移動-
, H, Shift + Tab左のリアクションにフォーカスを移動-
, L, Tab右のリアクションにフォーカスを移動-
Enter, Space, +リアクション確定-
0~9数字に対応したリアクションで確定-
Escリアクションするのをやめる-
diff --git a/src/docs/ht-HT/features/mfm.md b/src/docs/ht-HT/features/mfm.md deleted file mode 100644 index 5be2df4f3..000000000 --- a/src/docs/ht-HT/features/mfm.md +++ /dev/null @@ -1,12 +0,0 @@ -# MFM -MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます。 - -## MFMが使用可能な場所の例 -- ノート本文 -- CW注釈 -- ユーザーの名前 -- ユーザーの自己紹介 - -## 開発者向け情報 -MFMのパーサー実装はライブラリとして公開されており、簡単にクライアントにMFMを組み込むことが可能です。 -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptパーサー実装 diff --git a/src/docs/ht-HT/features/mute-and-block.md b/src/docs/ht-HT/features/mute-and-block.md deleted file mode 100644 index d78a7cea4..000000000 --- a/src/docs/ht-HT/features/mute-and-block.md +++ /dev/null @@ -1,41 +0,0 @@ -# ミュートとブロック -好みではないユーザーがいる場合は、ミュートを行うことでそのユーザーが自分から見えないようにすることができます。 また、より強力な措置として、ブロックを行うことでそのユーザーから自分のコンテンツが見えないようになるほか、自分に対して関わることができないようにすることができます。 ミュートされていることは相手は分かりませんが、ブロックされていることは相手に分かります。どちらを選ぶかはご自身の判断で行ってください。 - -
ℹ️ ミュートとブロックは併用できます。
- -
⚠️ 利用規約に違反するような、迷惑なユーザーがいる場合は運営者に報告することも検討してください。
- -設定>ミュートとブロック から、自分がミュートまたはブロックしているユーザー一覧を確認することができます。 - -## ミュート -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -- タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -- そのユーザーからの通知 -- メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 -- など - -ユーザーをミュートするには、対象のユーザーのユーザーページのメニューを開き、「ミュート」ボタンを押します。 - -
ℹ️ ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。
- -## ブロック -ユーザーをブロックすると、そのユーザーからあなたのコンテンツが見えないようになり、またあなたに対して以下のようなアクションをすることができなくなります。 - -- フォローする -- ユーザーリストに追加する -- 返信する、Renoteする -- リアクションする、アンケートに投票する -- メッセージを送信する -- など - -また、 - -- ブロックする際に既にそのユーザーからフォローされていた場合はフォローが解除されます。 -- ブロックする際に既にそのユーザーがあなたをユーザーリストに入れていた場合はそのリストからあなたが削除されます。 - -ユーザーをブロックするには、対象のユーザーのユーザーページのメニューを開き、「ブロック」ボタンを押します。 - -
⚠️ ブロックを行ったこと自体は相手に通知されませんが、フォローを行ったりなどの上記のアクションが行えなくなるので間接的にブロックされていることは分かります。
- -
⚠️ 相手から自分のコンテンツが見えなくなりますが、相手がアカウントを切り替えたりログアウト状態になれば見ることができます。あくまで簡易的、補助的なものとしてお考えください。
diff --git a/src/docs/ht-HT/features/mute.md b/src/docs/ht-HT/features/mute.md deleted file mode 100644 index 6a9608662..000000000 --- a/src/docs/ht-HT/features/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# ミュート - -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -* タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -* そのユーザーからの通知 -* メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 - -ユーザーをミュートするには、対象のユーザーのユーザーページに表示されている「ミュート」ボタンを押します。 - -ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。 - -設定>ミュート から、自分がミュートしているユーザー一覧を確認することができます。 diff --git a/src/docs/ht-HT/features/note.md b/src/docs/ht-HT/features/note.md deleted file mode 100644 index 305ff626f..000000000 --- a/src/docs/ht-HT/features/note.md +++ /dev/null @@ -1,54 +0,0 @@ -# ノート -ノートは、Misskeyに投稿される、文章、ファイル、アンケートなどを含むコンテンツで、Misskeyの中心的概念です。また、そのノートを作成する行為自体もノートと呼ばれます。 - -ノートが作成されると、[タイムライン](./timeline)に追加され、自分の[フォロワー](./follow)やサーバーのユーザーが見れるようになります。 - -ノートには、[リアクション](./reaction)を行うことができます。また、返信や引用もできます。 - -ノートを[お気に入り](./favorite)登録することで、後で簡単に見返すことができます。 - -## ノートを作成する -ノートを作成するには、画面上にある鉛筆マークのボタンを押して、作成フォームを開きます。作成フォームに内容を入力し、「ノート」ボタンを押すことでノートが作成されます。 ノートには、画像、動画など任意のファイルや、[アンケート](./poll)を添付することができます。また、本文中には[MFM](./mfm)が使用でき、[メンション](./mention)や[ハッシュタグ](./hashtag)を含めることもできます。 他にも、CWや公開範囲といった設定も行えます(詳細は後述)。 -
ℹ️ コンピューターのクリップボードに画像データがある状態で、フォーム内のテキストボックスにペーストするとその画像を添付することができます。
-
ℹ️ テキストボックス内でCtrl + Enterを押すことでも投稿できます。
- -## Renote -既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノートをRenoteと呼びます。 自分がフォローしているユーザーの、気に入ったノートを自分のフォロワーに共有したい場合や、過去の自分のノートを再度共有したい場合に使います。 同じノートに対して無制限にRenoteを行うことができますが、あまり連続して使用すると迷惑になる場合もあるので、注意しましょう。 -
⚠️ 公開範囲がフォロワーやダイレクトのノートはRenoteできません
- -Renoteを削除するには、Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 - -## CW -Contents Warningの略で、ノートの内容を、閲覧者の操作なしには表示しないようにできる機能です。主に長大な内容を隠すためや、ネタバレ防止などに使うことができます。 設定するには、フォームの「内容を隠す」ボタン(目のアイコン)を押します。すると新しい入力エリアが表れるので、そこに内容の要約を記入します。 - -## 公開範囲 -ノートごとに、そのノートが公開される範囲を設定することができます。フォームの「ノート」ボタンの左にあるアイコンを押すと公開範囲を以下から選択できます。 - -### パブリック -全ての人に対してノートが公開されるほか、サーバーの全てのタイムライン(ホームタイムライン、ローカルタイムライン、ソーシャルタイムライン、グローバルタイムライン)にノートが流れます。 -
⚠️ アカウントがサイレンス状態の時は、この公開範囲は使用できません。
- -### ホーム -全ての人に対してノートが公開されますが、フォロワー以外のローカルタイムライン、ソーシャルタイムライン、グローバルタイムラインにはノートは流れません。 - -### フォロワー -自分のフォロワーに対してのみノートを公開します。フォロワーの全てのタイムラインに流れます。 - -### ダイレクト -指定したユーザーに対してのみノートを公開します。指定したユーザーの全てのタイムラインに流れます。 - -### 「ローカルのみ」オプション -このオプションを有効にすると、リモートにノートを連合しなくなります。 - -### 公開範囲の比較 - - - - -
パブリックホームフォロワーダイレクト
フォロワーのLTL/STL/GTL
非フォロワーのLTL/STL/GTL
- -## ピン留め -ノートをピン留めすると、ユーザーページに常にそのノートを表示しておくことができます。 ノートのメニューを開き、「ピン留め」を選択してピン留めできます。 複数のノートをピン留めできます。 - -## ウォッチ -ノートをウォッチすると、自分以外のノートへのリアクションや返信などの通知を受け取ることができます。 ノートのメニューを開き、「ウォッチ」を選択してウォッチできます。 diff --git a/src/docs/ht-HT/features/pages.md b/src/docs/ht-HT/features/pages.md deleted file mode 100644 index a7311b95e..000000000 --- a/src/docs/ht-HT/features/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# Pages - -## 変数 -変数を使うことで動的なページを作成できます。テキスト内で { 変数名 } と書くとそこに変数の値を埋め込めます。例えば Hello { thing } world! というテキストで、変数(thing)の値が ai だった場合、テキストは Hello ai world! になります。 - -変数の評価(値を算出すること)は上から下に行われるので、ある変数の中で自分より下の変数を参照することはできません。例えば上から A、B、C と3つの変数を定義したとき、Cの中でABを参照することはできますが、Aの中でBCを参照することはできません。 - -ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。 - -関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。 diff --git a/src/docs/ht-HT/features/reaction.md b/src/docs/ht-HT/features/reaction.md deleted file mode 100644 index 4d479fd41..000000000 --- a/src/docs/ht-HT/features/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# リアクション -他の人のノートに、絵文字を付けて簡単にあなたの反応を伝えられる機能です。 リアクションするには、ノートの + アイコンをクリックしてピッカーを表示し、絵文字を選択します。 リアクションには[カスタム絵文字](./custom-emoji)も使用できます。 - -## リアクションピッカーのカスタマイズ -ピッカーに表示される絵文字を自分好みにカスタマイズすることができます。 設定の「リアクション」で設定します。 - -## リモート投稿へのリアクションについて -リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。 - -## リモートからのリアクションについて -リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。 diff --git a/src/docs/ht-HT/features/silence.md b/src/docs/ht-HT/features/silence.md deleted file mode 100644 index 7e26feab0..000000000 --- a/src/docs/ht-HT/features/silence.md +++ /dev/null @@ -1,6 +0,0 @@ -# サイレンス -サイレンスは、アカウントに設定される状態のひとつです。 - -アカウントがサイレンス状態になると、ノートの公開範囲をパブリックにできなくなります。 ホーム、フォロワー、ダイレクトは選択可能なため、サイレンスを受けた場合でもフォロワーやあなたのユーザーページを直接訪れた場合は投稿を閲覧できますが、GTL(連合タイムライン)やLTL(ローカルタイムライン)には投稿が流れません。 - -アカウントのサイレンス状態は、サーバーのモデレーターによって有効化/無効化されます。 diff --git a/src/docs/ht-HT/features/theme.md b/src/docs/ht-HT/features/theme.md deleted file mode 100644 index a406f3433..000000000 --- a/src/docs/ht-HT/features/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# テーマ - -テーマを設定して、Misskeyクライアントの見た目を変更できます。 - -## テーマの設定 -設定 > テーマ - -## テーマを作成する -テーマコードはJSON5で記述されたテーマオブジェクトです。 テーマは以下のようなオブジェクトです。 -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... テーマの一意なID。UUIDをおすすめします。 -* `name` ... テーマ名 -* `author` ... テーマの作者 -* `desc` ... テーマの説明(オプション) -* `base` ... 明るいテーマか、暗いテーマか - * `light`にすると明るいテーマになり、`dark`にすると暗いテーマになります。 - * テーマはここで設定されたベーステーマを継承します。 -* `props` ... テーマのスタイル定義。これから説明します。 - -### テーマのスタイル定義 -`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 - -#### バリューで使える構文 -* 16進数で表された色 - * 例: `#00ff00` -* `rgb(r, g, b)`形式で表された色 - * 例: `rgb(0, 255, 0)` -* `rgb(r, g, b, a)`形式で表された透明度を含む色 - * 例: `rgba(0, 255, 0, 0.5)` -* 他のキーの値の参照 - * `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。 - * 例: `@panel` -* 定数(後述)の参照 - * `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。 - * 例: `$main` -* 関数(後述) - * `:{関数名}<{引数}<{色}` - -#### 定数 -「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 キー名を`$`で始めると、そのキーはCSS変数として出力されません。 - -#### 関数 -wip diff --git a/src/docs/ht-HT/features/timeline.md b/src/docs/ht-HT/features/timeline.md deleted file mode 100644 index f431014f8..000000000 --- a/src/docs/ht-HT/features/timeline.md +++ /dev/null @@ -1,31 +0,0 @@ -# タイムライン -タイムラインは、[ノート](./note)が時系列で表示される機能です。 タイムラインには以下で示す種類があり、種類によって表示されるノートも異なります。 なお、タイムラインの種類によってはサーバーにより無効になっている場合があります。 - -## ホーム -自分のフォローしているユーザーの投稿が流れます。HTLと略されます。 - -## ローカル -全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。LTLと略されます。 - -## ソーシャル -自分のフォローしているユーザーの投稿と、全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。STLと略されます。 - -## グローバル -全てのローカルユーザーの「ホーム」指定されていない投稿と、サーバーに届いた全てのリモートユーザーの「ホーム」指定されていない投稿が流れます。GTLと略されます。 - -## 比較 -| ソース | | | タイムライン | | | -| ------------ | ----- | --- | ------ | ----- | ----- | -| ユーザー | 公開範囲 | ホーム | ローカル | ソーシャル | グローバル | -| ローカル (フォロー) | 公開 | ✔ | ✔ | ✔ | ✔ | -| | ホーム | ✔ | | ✔ | | -| | フォロワー | ✔ | ✔ | ✔ | ✔ | -| リモート (フォロー) | 公開 | ✔ | | ✔ | ✔ | -| | ホーム | ✔ | | ✔ | | -| | フォロワー | ✔ | | ✔ | ✔ | -| ローカル (未フォロー) | 公開 | | ✔ | ✔ | ✔ | -| | ホーム | | | | | -| | フォロワー | | | | | -| リモート (未フォロー) | 公開 | | | | ✔ | -| | ホーム | | | | | -| | フォロワー | | | | | diff --git a/src/docs/ht-HT/features/widgets.md b/src/docs/ht-HT/features/widgets.md deleted file mode 100644 index a7c2c1d1d..000000000 --- a/src/docs/ht-HT/features/widgets.md +++ /dev/null @@ -1,7 +0,0 @@ -# ウィジェット -ウィジェットは、MisskeyのUI上に設置できる小型の情報表示、操作が行えるパーツです。 - -ウィジェットを編集するには、ウィジェット編集モードに切り替えます。切り替え方法はUIによって異なります。 ウィジェット編集モードでは、ウィジェットの追加、削除、並び替え、およびそれぞれのウィジェットの設定を行えます。 - -## 利用可能なウィジェット一覧 -todo diff --git a/src/docs/ht-HT/features/word-mute.md b/src/docs/ht-HT/features/word-mute.md deleted file mode 100644 index fa4d14346..000000000 --- a/src/docs/ht-HT/features/word-mute.md +++ /dev/null @@ -1,20 +0,0 @@ -# ワードミュート -ワードミュートの設定をすると、条件に合致したノートが表示されなくなります。 - -ワードミュートには、ソフトワードミュートとハードワードミュートの2種類があります。それぞれについて設定の方法と挙動を説明します。 - -## ソフトワードミュート -ソフトワードミュートは、クライアント(アプリ)側でミュートを判断するワードミュートです。 - -ノートが設定した条件に合致すると、「(ユーザー名)が何かを言いました」という表示で隠れます。 -クリックすると元の通りに表示されます。 - -## ハードワードミュート -ハードワードミュートは、アンテナのようにサーバーが新しいノートの本文に対して条件に合致するかどうか判断し、タイムラインから対象となったノートを除外します。 - -つまり、ハードワードミュートには、以下のような特徴があります。 - -* 条件設定後、新しい投稿のみがミュートの対象になります。 -* 条件を変更しても、過去にハードミュートされたノートはミュートされたままになります。 -* 「○○が何かを言いました」でタイムラインが埋まることがありません。 -* ソフトミュートに非対応のアプリでも、ハードミュートは適用されます。 diff --git a/src/docs/ht-HT/follow.md b/src/docs/ht-HT/follow.md deleted file mode 100644 index 3c1ea7bbe..000000000 --- a/src/docs/ht-HT/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# フォロー -ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。 diff --git a/src/docs/ht-HT/general/apps.md b/src/docs/ht-HT/general/apps.md deleted file mode 100644 index 1f4c85fe8..000000000 --- a/src/docs/ht-HT/general/apps.md +++ /dev/null @@ -1,6 +0,0 @@ -# サードパーティアプリのリスト -## クライアント -todo - -## 連携サービス -todo diff --git a/src/docs/ht-HT/general/changelog.md b/src/docs/ht-HT/general/changelog.md deleted file mode 100644 index 6766a63b2..000000000 --- a/src/docs/ht-HT/general/changelog.md +++ /dev/null @@ -1,5 +0,0 @@ -# 更新履歴 -
ℹ️ このサーバーの更新履歴です。Misskeyの最新のリリースについては、GitHubをご確認ください。
- - - diff --git a/src/docs/ht-HT/general/faq.md b/src/docs/ht-HT/general/faq.md deleted file mode 100644 index c272b2ad4..000000000 --- a/src/docs/ht-HT/general/faq.md +++ /dev/null @@ -1,28 +0,0 @@ -# よくある質問 -ここでは利用上のよくある質問について掲載しています。 Misskeyのプロジェクト自体についてのよくある質問は[こちら](./misskey)に掲載されています。 - -## iOS/Androidのアプリはありますか? -公式にはそういったOSのネイティブアプリを開発していませんが、サードパーティ製のアプリがいくつかあります。 詳しくは[こちら](./apps)をご覧ください。 - -ただ、サードパーティ製アプリはどうしても機能への対応が遅れてしまうため、とくに拘りがなければ公式のWebクライアントの利用をおすすめします。 なお、MisskeyのWebクライアントはPWAに対応しているので、ネイティブアプリのように動作させることも可能です。 詳しくは[こちら](todo)をご覧ください。 - -## Mastodonクライアントでログインできないのですが? -MisskeyはMastodonのAPIと互換性がないため、一部を除きMastodonクライアントでMisskeyを利用することはできません。 - -## 他のサーバーのユーザーをフォローするときは? -メニューから検索を選び、ユーザー名をホスト込みで入力します。例: `@syuilo@misskey.io` - -## Renoteを削除するには? -Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 Renoteについては[こちら](../features/note)をご確認ください。 - -## URLのプレビューを表示させたくない -MFMには、そのURLのプレビューを無効にする構文があります。詳細は[MFMチートシート](/mfm-cheat-sheet)をご確認ください。 - -## カスタム絵文字を追加したい -運営者のみがカスタム絵文字を追加、編集、削除できます。それらを希望する場合は運営者に依頼してください。 - -## Botを開発したい -Misskey APIを利用してBotの開発が可能です。[こちら](../advanced/develop-bot)をご確認ください。 - -## ノートの翻訳機能はどのサービスを使用していますか? -[DeepL](https://www.deepl.com/)を使用しています。 diff --git a/src/docs/ht-HT/general/glossary.md b/src/docs/ht-HT/general/glossary.md deleted file mode 100644 index bb8a24336..000000000 --- a/src/docs/ht-HT/general/glossary.md +++ /dev/null @@ -1,89 +0,0 @@ -# 用語集 -Misskeyに関する用語集です。 - -## ActivityPub -(読み: あくてぃびてぃぱぶ) 分散型を実現するために用いられるプロトコル(仕様)。このプロトコルに則ってサーバー同士通信を行うことで、連合が行われ、Fediverseを形成しています。 - -## AiScript -(読み: あいすくりぷと) Misskey上で使用できるプログラミング言語です。詳細は[こちら。](../advanced/aiscript) - -## API -(読み: えーぴーあい) Misskeyのサーバーが公開している、プログラムからMisskeyを扱うためのインターフェース。詳細は[こちら。](../advanced/api) - -## Bot -(読み: ぼっと) プログラムによって動作しているアカウント。 - -## CW -(読み: こんてんつわーにんぐ) Contents Warningの略。ノートの内容を、操作なしには表示しないようにできる機能。主に長大な内容を隠すためや、ネタバレ防止などに使われます。 - -## Fediverse -(読み: ふぇでぃばーす) Misskeyを含む様々な分散型ソフトウェアのサーバーで構成されたネットワーク。 - -## GTL -グローバルタイムライン(Global TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## HTL -ホームタイムライン(Home TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## LTL -ローカルタイムライン(Local TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## MFM -(読み: えむえふえむ) Misskey Flavored Markdownの略で、Misskey上で使用できるマークアップ言語です。詳細は[こちら。](../features/mfm) - -## NSFW -(読み: のっとせーふふぉーわーく) Not Safe For Workの略。画像を「閲覧注意」扱いにし、操作なしには表示しないようにすることができる機能。 - -## Renote -(読み: りのーと) 既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノート。詳細は[こちら。](../features/note) - -## STL -ソーシャルタイムライン(Social TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## 藍 -(読み: あい) Misskeyの看板娘(公式キャラクター)です。 - -## アクティブユーザー -インスタンスにアカウントを作っているユーザーのうち、現在も実際にサービスを利用しているユーザーのこと。 - -## インスタンス -todo - -## カスタム絵文字 -サーバーで用意された絵文字。カスタム絵文字ではない通常の絵文字は「Unicode絵文字」と区別して呼ばれる。 - -## コントロールパネル -インスタンスの設定画面のこと。 - -## サーバー -todo - -## サイレンス -ノートをパブリックな公開範囲で投稿できなくされている状態。モデレーターの判断でユーザーごとに設定されます。詳細は[こちら。](../features/silence) - -## ジョブキュー -アクティビティ配送などを順番に行うためのシステム。 - -## 凍結 -アカウントが使用不可に設定されている状態。 - -## ドライブ -Misskeyにアップロードしたファイルを管理する機能。詳細は[こちら。](../features/drive) - -## ノート -Misskeyに投稿される、文章、ファイル、アンケートなどを含めることができるコンテンツ。詳細は[こちら。](../features/note) - -## ミスキスト -Misskeyを使う人のこと。 - -## モデレーター -スパムの凍結およびサイレンスや不適切な投稿の削除など、コミュニティ運営に関する権限を持つユーザー。 - -## リモート -他サーバーのことを指します。リモートユーザーといったように接頭辞としても使われます。ローカルの逆です。 - -## 連合 -サーバー上で作成された情報が他のサーバーに伝わること。 - -## ローカル -自サーバーのことを指します。ローカルユーザー、ローカルタイムラインといったように接頭辞としても使われます。リモートの逆です。 diff --git a/src/docs/ht-HT/general/links.md b/src/docs/ht-HT/general/links.md deleted file mode 100644 index 5ce5e1ddb..000000000 --- a/src/docs/ht-HT/general/links.md +++ /dev/null @@ -1,12 +0,0 @@ -# リンク集 - -## Webサイト -- [Official Discord](https://discord.gg/Wp8gVStHW3) - Misskey公式Discordサーバー -- [Misskey Forum](https://forum.misskey.io/) - Misskeyに関する話題を扱うフォーラム - -## アカウント -- [@repo@misskey.io](https://misskey.io/@repo) - Misskeyのリポジトリの更新を投稿するbot - -## ライブラリ -- [misskey-dev/misskey.js](https://github.com/misskey-dev/misskey.js) - JavaScriptのMisskey SDK -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptのMFMパーサー実装 diff --git a/src/docs/ht-HT/general/misskey.md b/src/docs/ht-HT/general/misskey.md deleted file mode 100644 index d97664ddc..000000000 --- a/src/docs/ht-HT/general/misskey.md +++ /dev/null @@ -1,87 +0,0 @@ -# Misskeyについて - -Misskeyはオープンソースの分散型マイクロブログプラットフォームプロジェクトです。 開発は日本でsyuiloによって2014年から開始されました。 ドライブ、リアクションなどの豊富な機能や、高いカスタマイズ性を備えたUIを持つことが特徴です。 - -## 歴史 -開発当初は掲示板がメインのサービスでしたが、ユーザーが短文を投稿し、それを時系列で流れるタイムライン機能を追加したところ人気が高まり、徐々にそれがメインとして開発が進むようになりました。 当初は分散型ではありませんでしたが、2018年にActivityPubを実装し分散型になったことで、より多くの方に認知され利用されるサービスになり、現在に至ります。 -
ℹ️ Misskeyという名前は、syuiloが当時聴いていたMay'nというアーティストの楽曲、Brain Diverの歌詞に由来します。
- -誰でも開発に参加することができ、現在でも活発に開発が続いています。 - -## 分散型とは何か? - -分散(distributed)型とは、非中央集権(decentralized)とも呼ばれ、コミュニティが多数のサーバーに分散して存在し、それらが相互に通信(連合、federation)することでコンテンツ共有ネットワーク(Fediverse)を形成していることが特徴のサービスです。 単一のサーバーしか存在しない、もしくは複数存在しても互いに独立している場合は中央集権なサービスと言われ、例えばTwitterやFacebookなどほとんどのサービスがそれに該当します。 分散型のメリットは、自分に合った運営者やテーマのサーバーを選択できることです。自分でサーバーを作成することもできます。連合するおかげで、どのサーバーを選んでも、同じコミュニティにアクセスできます。 - -## 常にオープンソース -Misskeyはこれまでもこれからも、オープンソースであり続けます。オープンソースとは、簡単に言うとソフトウェアのソースコード(プログラム)が公開されていることです。ソースコードの修正や再配布が可能であることを定義に含めることもあります。 Misskeyのすべてのソースコードは[AGPL](https://github.com/misskey-dev/misskey/blob/develop/LICENSE)というオープンソースライセンスの下に[公開](https://github.com/misskey-dev)されていて、誰でも自由に閲覧、使用、修正、改変、再配布をすることができます。 オープンソースは、自分で好きなように変えたり、有害な処理が含まれていないことを確認することができたり、誰でも開発に参加できるなどの、様々なメリットがあります。 上述の分散型を実現するためにも、オープンソースであるということは必要不可欠な要素です。 再び引き合いに出しますが、TwitterやFacebookなどの利益を得ているほとんどのサービスはオープンソースではありません。 - -
ℹ️ 技術的に言うと、MisskeyのソースコードはGitで管理されていて、リポジトリはGitHub上でホスティングされています。
- -## 開発に参加する、プロジェクトを支援する -Misskeyを気に入っていただけたら、ぜひプロジェクトを支援してください。プロジェクトに貢献するには、以下で紹介するようにいろいろな方法があります。方法によっては開発のスキルは不要なので、誰でも気軽に参加し貢献することができます。いつでもお待ちしています。 - -### 機能を追加したり、バグを修正する -ソフトウェアエンジニアのスキルをお持ちの方であれば、ソースコードを編集する形でプロジェクトに貢献することができます。 貢献についてのガイドは[こちら](https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md)です。 - -### 議論に参加する -新しい機能、または既存の機能について意見を述べたり、不具合を報告したりすることでも貢献できます。 そのようなディスカッションは[GitHub](https://github.com/misskey-dev)上か、[フォーラム](https://forum.misskey.io/)等で行われます。 - -### テキストを翻訳する -Misskeyは様々な言語に対応しています(i18n -internationalizationの略- と呼ばれます)。元の言語は基本的に日本語ですが、有志によって他の言語へと翻訳されています。 その翻訳作業に加わっていただくことでもMisskeyに貢献できます。 Misskeyは[Crowdinというサービスを使用して翻訳の管理を行っています。](https://crowdin.com/project/misskey) - -### 感想を投稿する -不具合報告等だけではなく、Misskeyの良い点、楽しい点といったポジティブな意見もぜひ共有してください。開発の励みになり、それは間接的ですがプロジェクトへの貢献です。 - -### ミスキストを増やす -ミスキストとは、Misskeyを使用する人のことです。 知り合いに紹介するなどしてMisskeyを広めていただければ、ミスキストが増え開発のモチベーションが上がります。 - -### 寄付をする -Misskeyはビジネスではなく、利用は無料であるため、収益は皆様からの寄付のみです。(インスタンスによっては広告収入を得ているような場合もありますが、それは運営者の収入であり直接開発者への収入にはなりません) 寄付をしていただければ、今後も開発を続けることが可能になり、プロジェクトへの貢献になります。 寄付は基本的には[Patreon](https://www.patreon.com/syuilo)で受け付けています。 一定額寄付していただけると、Misskeyの[情報ページ](/about-misskey)に名前を記載することができます。 - -また、サーバーの運営者も、基本的には収益を得ていません。サーバーの運営にはコストがかかるので、運営者の支援をすることもご検討ください。 開発には直接関係しませんが、サーバーがあってこそのプロジェクトなので、運営が維持されるというのは開発と同じくらい重要なことです。 - -## クレジット -Misskeyの開発者や、Misskeyに寄付をしてくださった方の一覧は[こちら](/about-misskey)で見ることができます。 - -## よくある質問 -### プロジェクトは何を目指していますか? -強いて言うと、漠然的になりますが広く使われる汎用的なプラットフォームになることを目指しています。 Misskeyは他のプロジェクトとは違い、何らかの思想(例えば、反中央集権)やビジョンに基づいて開発が行われているわけではなく、その点ではフラットです。 それが逆に、特定の方向性に縛られないフレキシブルさを生み出すことに繋がっていると感じています。 - - -### 企業によって開発されていますか? -いいえ。Misskeyの開発は個人で行われており、商業的でもないため、特定の企業の関りはありません。 開発メンバーも基本的にはボランティアです。 また、開発に対し企業のスポンサーがつくこともありますが、その場合でもやはり開発は個人のコミュニティが主体です。 - -### 誰が運営していますか? -Misskeyは分散型なため、各サーバーにそれぞれ異なった運営者がいます。従って、特定の個人や企業によって、Misskeyの全てが運営されているわけではありません。 また、開発チームが運営を行うわけでもないため、運営に関する連絡は、お使いのサーバーの運営者に行ってください。 サーバーの運営者は、[このページ](/about)で確認することができます。 あなたがサーバーを作成すれば、あなたが運営者になります。 - -### どのサーバーを選べばいいですか? -[サーバー一覧が公開されています。](https://join.misskey.page/ja-JP/instances) サーバーによってコミュニティのテーマ(特定のこと、ものが好き 等)が決められている場合があるので、自分に合ったテーマのサーバーがあれば、そこを選ぶと良いかもしれません。 他にも、サーバーの規模、ユーザー層、国および言語、運営者が信頼できるかどうか、などの観点があります。 なお、Misskey公式のサーバーというものはありません。自身で新しくサーバーを作成するという選択肢もあります。 - -基本的にどのサーバーを選んだとしても、他の全てのサーバーのユーザーと繋がることができます。 - -### サーバーを建てるにはどうしたらいいですか? -Misskeyサーバーの作成に興味を持っていただきありがとうございます。 2021年現在、Misskeyのホスティングサービスは存在しないため、サーバーの作成にはある程度の知識が必要です。 サーバーの作成方法については[こちら](todo)をご覧ください。 - -### どのような技術を使用していますか? -Misskeyは開発が進むにつれ使用する技術も大きく変わってきました。開発当初はMySQL + PHP + jQueryといった構成でしたが、現在は以下のようになっています。 -- サーバーサイド: Node.js -- データベース: PostgreSQL、Redis -- UIフレームワーク: Vue.js -- プログラミング言語: TypeScript - -また、MFMやAiScriptなどの、Misskeyから派生して独自の技術も開発しています。 - -### Mastodonのフォークですか? -いいえ。MisskeyはMastodonやその他のプロジェクトとは全く別のプロジェクトです。 開発に関しても、Misskeyの方が昔から開発されています。ただし、分散型になったのはMastodonの登場より後です。 同じActivityPubという分散のためのプロトコルを実装しているという点以外、両者に特に関りがあるわけでもありません。 - -### iOS/Androidのアプリはありますか? -公式にはそういったOSのネイティブアプリを開発していませんが、サードパーティ製のアプリがいくつかあります。 詳しくは[こちら](./apps)をご覧ください。 - -ただ、サードパーティ製アプリはどうしても機能への対応が遅れてしまうため、とくに拘りがなければ公式のWebクライアントの利用をおすすめします。 なお、MisskeyのWebクライアントはPWAに対応しているので、ネイティブアプリのように動作させることも可能です。 詳しくは[こちら](todo)をご覧ください。 - -### Misskeyのロゴ、アイコンはどこで入手できますか? -(準備中) - -### 時折目にする猫耳の可愛い女の子は? -Misskeyの守り神、藍ちゃんです。アイチャンカワイイヤッター! -
ℹ️ 藍ちゃんについてはこちらです。
diff --git a/src/docs/ht-HT/general/report-issue.md b/src/docs/ht-HT/general/report-issue.md deleted file mode 100644 index 63527e32a..000000000 --- a/src/docs/ht-HT/general/report-issue.md +++ /dev/null @@ -1,8 +0,0 @@ -# 不具合の報告 -不具合と思われる状況に遭遇したときは、まず[トラブルシューティング](./troubleshooting)をご一読ください。 それでも問題が解決しないときは、以下の情報を含めて[フォーラム](https://forum.misskey.io/)に投稿してください。 投稿することで、解決策が見つかったり、不具合と判断されれば開発チームによって修正が行われます。 - -## 含める情報 -- Misskeyのバージョン([情報ページ](/about)で確認できます) -- お使いのブラウザの種類とバージョン -- お使いのOSの種類とバージョン -- 問題の再現手順 diff --git a/src/docs/ht-HT/general/troubleshooting.md b/src/docs/ht-HT/general/troubleshooting.md deleted file mode 100644 index f895b4984..000000000 --- a/src/docs/ht-HT/general/troubleshooting.md +++ /dev/null @@ -1,40 +0,0 @@ -# トラブルシューティング -
ℹ️ よくある質問も合わせてお役立てください。
- -問題が発生したときは、まずこちらをご確認ください。 該当する項目が無い、もしくは手順を試しても効果がない場合は、サーバーの管理者に連絡するか[不具合を報告](./report-issue)してください。 - -## クライアントが起動しない -ほとんどの場合、お使いのブラウザまたはOSのバージョンが古いことが原因です。 ブラウザおよびOSのバージョンを最新のものに更新してから、再度試してみてください。 - -これは稀ですが、それでも起動しない場合は、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。 - -## ページが読み込めない -クライアントが起動するもののページが読み込めないというエラーが出る場合は、ネットワークに問題がないか確認してください。また、サーバーがダウンしていないか確認してください。 - -これは稀ですが、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。 - -まだ問題がある場合は、サーバーの問題と思われるのでサーバーの管理者に連絡してください。 - -## クライアントの動作が遅い -以下を試してみてください: - -- クライアント設定で「UIのアニメーションを減らす」を有効にする -- クライアント設定で「モーダルにぼかし効果を使用」を無効にする -- お使いのブラウザの設定でハードウェアアクセラレーションを有効にする -- お使いのデバイスのスペックを上げる - -## UIの一部の表示がおかしい(背景が透明になっている等) -アップデートによりUIの改修が行われたときに、テーマのキャッシュシステムの影響でそのような表示になることがあります。 クライアントの設定の「キャッシュをクリア」すると直ります。 -
⚠️ 「クライアントの」キャッシュクリアです。「ブラウザの」キャッシュクリアは行わないでください。
- -## 通知やアンテナ等の点滅が消えない -点滅は、未読のコンテンツがあることを示しています。通常点滅が消えない場合は、コンテンツを遡ると未読なコンテンツが残っています。 すべて既読にしたと思われるのに、それでもなお点滅が続く場合(おそらく不具合と思われます)は設定から強制的にすべて既読扱いにすることができます。 - -## Renoteができない -フォロワー限定のノートはRenoteすることはできません。 - -## UI上で特定の要素が表示されない -広告ブロッカーを使用しているとそのような不具合が発生することがあります。Misskeyではオフにしてご利用ください。 - -## UI上で未翻訳の部分がある -ほとんどの場合、単に翻訳が間に合っていないだけで、不具合ではありません。翻訳が終わるまでお待ちください。 [翻訳に参加](./misskey)していただくことも可能です。 diff --git a/src/docs/ht-HT/keyboard-shortcut.md b/src/docs/ht-HT/keyboard-shortcut.md deleted file mode 100644 index 957ca838c..000000000 --- a/src/docs/ht-HT/keyboard-shortcut.md +++ /dev/null @@ -1,68 +0,0 @@ -# キーボードショートカット - -## グローバル -これらのショートカットは基本的にどこでも使えます。 - - - - - - - - - - - -
ショートカット効果由来
P, N新規投稿Post, New, Note
Tタイムラインの最も新しい投稿にフォーカスTimeline, Top
Shift + N通知を表示/隠すNotifications
S検索Search
H, ?ヘルプを表示Help
- -## 投稿にフォーカスされた状態 - - - - - - - - - - - - - - - - - - - -
ショートカット効果由来
, K, Shift + Tab上の投稿にフォーカスを移動-
, J, Tab下の投稿にフォーカスを移動-
R返信フォームを開くReply
QRenoteフォームを開くQuote
Ctrl + Q即刻Renoteする(フォームを開かずに)-
E, A, +リアクションフォームを開くEmote, reAction
0~9数字に対応したリアクションをする(対応については後述)-
F, Bお気に入りに登録Favorite, Bookmark
Del, Ctrl + D投稿を削除Delete
M, O投稿に対するメニューを開くMore, Other
SCWで隠された部分を表示 or 隠すShow, See
Escフォーカスを外す-
- -## Renoteフォーム - - - - - - - - - - -
ショートカット効果由来
EnterRenoteする-
Qフォームを展開するQuote
Escフォームを閉じる-
- -## リアクションフォーム -デフォルトで「👍」にフォーカスが当たっている状態です。 - - - - - - - - - - - - - -
ショートカット効果由来
, K上のリアクションにフォーカスを移動-
, J下のリアクションにフォーカスを移動-
, H, Shift + Tab左のリアクションにフォーカスを移動-
, L, Tab右のリアクションにフォーカスを移動-
Enter, Space, +リアクション確定-
0~9数字に対応したリアクションで確定-
Escリアクションするのをやめる-
diff --git a/src/docs/ht-HT/mfm.md b/src/docs/ht-HT/mfm.md deleted file mode 100644 index e237287ac..000000000 --- a/src/docs/ht-HT/mfm.md +++ /dev/null @@ -1,2 +0,0 @@ -# MFM -MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます。 diff --git a/src/docs/ht-HT/mute.md b/src/docs/ht-HT/mute.md deleted file mode 100644 index 6a9608662..000000000 --- a/src/docs/ht-HT/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# ミュート - -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -* タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -* そのユーザーからの通知 -* メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 - -ユーザーをミュートするには、対象のユーザーのユーザーページに表示されている「ミュート」ボタンを押します。 - -ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。 - -設定>ミュート から、自分がミュートしているユーザー一覧を確認することができます。 diff --git a/src/docs/ht-HT/pages.md b/src/docs/ht-HT/pages.md deleted file mode 100644 index a7311b95e..000000000 --- a/src/docs/ht-HT/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# Pages - -## 変数 -変数を使うことで動的なページを作成できます。テキスト内で { 変数名 } と書くとそこに変数の値を埋め込めます。例えば Hello { thing } world! というテキストで、変数(thing)の値が ai だった場合、テキストは Hello ai world! になります。 - -変数の評価(値を算出すること)は上から下に行われるので、ある変数の中で自分より下の変数を参照することはできません。例えば上から A、B、C と3つの変数を定義したとき、Cの中でABを参照することはできますが、Aの中でBCを参照することはできません。 - -ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。 - -関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。 diff --git a/src/docs/ht-HT/reaction.md b/src/docs/ht-HT/reaction.md deleted file mode 100644 index c26ead75b..000000000 --- a/src/docs/ht-HT/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# リアクション -他の人のノートに、絵文字を付けて簡単にあなたの反応を伝えられる機能です。 リアクションするには、ノートの + アイコンをクリックしてピッカーを表示し、絵文字を選択します。 リアクションには[カスタム絵文字](./custom-emoji)も使用できます。 - -## リアクションピッカーのカスタマイズ -ピッカーに表示される絵文字を自分好みにカスタマイズすることができます。 設定の「リアクション」で設定します。 - -## リモート投稿へのリアクションについて -リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。 また、相手がMisskeyであったとしても、カスタム絵文字リアクションは伝わらず、自動的に「👍」等にフォールバックされます。 - -## リモートからのリアクションについて -リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。 diff --git a/src/docs/ht-HT/reversi-bot.md b/src/docs/ht-HT/reversi-bot.md deleted file mode 100644 index 7ab2a7212..000000000 --- a/src/docs/ht-HT/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# MisskeyリバーシBotの開発 -Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。 - -1. `games/reversi`ストリームに以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - -2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる - * イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている - -3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する - -4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - * `game`: `game`の`id` - -5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う - -6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する - -7. ゲームが開始すると、`started`イベントが流れてくる - * イベントの中身にはゲーム情報が含まれている - -8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述) - -9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる - * `color`として石の色が含まれている - * `pos`として位置情報が含まれている - -## 位置の計算法 -8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### X,Y座標 から インデックス に変換する -``` -pos = x + (y * mapWidth) -``` -`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます: -``` -mapWidth = map[0].length -``` - -### インデックス から X,Y座標 に変換する -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## マップ情報 -マップ情報は、ゲーム情報の`map`に入っています。 文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 それをもとにマップのデザインを知る事が出来ます: -* `(スペース)` ... マス無し -* `-` ... マス -* `b` ... 初期配置される黒石 -* `w` ... 初期配置される白石 - -例えば、4*4の次のような単純なマップがあるとします: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -この場合、マップデータはこのようになります: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## ユーザーにフォームを提示して対話可能Botを作成する -ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。 - -フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します: -```javascript -{ - type: 'init-form', - body: [フォームコントロールの配列] -} -``` - -フォームコントロールの配列については今から説明します。 フォームコントロールは、次のようなオブジェクトです: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... コントロールのID。 `type` ... コントロールの種類。後述します。 `label` ... コントロールと一緒に表記するテキスト。 `value` ... コントロールのデフォルト値。 - -### フォームの操作を受け取る -ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### フォームコントロールの種類 -#### スイッチ -type: `switch` スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。 - -##### プロパティ -`label` ... スイッチに表記するテキスト。 - -#### ラジオボタン -type: `radio` ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。 - -##### プロパティ -`items` ... ラジオボタンの選択肢。例: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '強', - value: 3 -}] -``` - -#### スライダー -type: `slider` スライダーを表示します。 - -##### プロパティ -`min` ... スライダーの下限。 `max` ... スライダーの上限。 `step` ... 入力欄で刻むステップ値。 - -#### テキストボックス -type: `textbox` テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。 - -## ユーザーにメッセージを表示する -設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 メッセージを表示するには、次のメッセージをストリームに送信します: -```javascript -{ - type: 'message', - body: { - text: 'メッセージ内容', - type: 'メッセージの種類' - } -} -``` -メッセージの種類: `success`, `info`, `warning`, `error`。 - -## 投了する -投了をするには、このエンドポイントにリクエストします。 diff --git a/src/docs/ht-HT/stream.md b/src/docs/ht-HT/stream.md deleted file mode 100644 index 9011c37c5..000000000 --- a/src/docs/ht-HT/stream.md +++ /dev/null @@ -1,354 +0,0 @@ -# ストリーミングAPI - -ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。 - -## ストリームに接続する - -ストリーミングAPIを利用するには、まずMisskeyサーバーに**websocket**接続する必要があります。 - -以下のURLに、`i`というパラメータ名で認証情報を含めて、websocket接続してください。例: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。 - -
-

認証情報の取得については、こちらのドキュメントをご確認ください。

-
- ---- - -認証情報は省略することもできますが、その場合非ログインでの利用ということになり、受信できる情報や可能な操作は限られます。例: - -``` -%WS_URL%/streaming -``` - ---- - -ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。 - -**ストリームでのやり取りはすべてJSONです。** - -## チャンネル -MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。 - -### チャンネルに接続する -チャンネルに接続するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -ここで、 -* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。 -* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。 -* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。 - -
-

IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。

-
- -### チャンネルからのメッセージを受け取る -例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。 - -チャンネルがメッセージを発すると、次のようなデータがJSONでストリームに流れてきます: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。 -* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。 -* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。 - -### チャンネルに向けてメッセージを送信する -チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。 - -チャンネルにメッセージを送信するには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。 -* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。 -* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。 - -### チャンネルから切断する -チャンネルから切断するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。 - -## ストリームを経由してAPIリクエストする - -ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。 - -ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -ここで、 -* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 -* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 -* `data`には、エンドポイントのパラメータを含めます。 - -
-

APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。

-
- -### レスポンスの受信 - -APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。 - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -ここで、 -* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 -* `body`には、レスポンスが含まれています。 - -## 投稿のキャプチャ - -Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。 - -例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。 - -しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。 - -この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。 - -### 投稿をキャプチャする - -投稿をキャプチャするには、ストリームに次のようなメッセージを送信します: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャしたい投稿の`id`を設定します。 - -このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 - -例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -ここで、 -* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。 -* `body`内の`type`に、イベントの種類が設定されます。 -* `body`内の`body`に、イベントの詳細が設定されます。 - -#### イベントの種類 - -##### `reacted` -その投稿にリアクションがされた時に発生します。 - -* `reaction`に、リアクションの種類が設定されます。 -* `userId`に、リアクションを行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -その投稿が削除された時に発生します。 - -* `deletedAt`に、削除日時が設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -その投稿に添付されたアンケートに投票された時に発生します。 - -* `choice`に、選択肢IDが設定されます。 -* `userId`に、投票を行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### 投稿のキャプチャを解除する - -その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。 - -次のメッセージを送信します: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャを解除したい投稿の`id`を設定します。 - -このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 - -# チャンネル一覧 -## `main` -アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `renote` -自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。 - -#### `mention` -誰かからメンションされたときに発生するイベントです。 - -#### `readAllNotifications` -自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。 - -#### `meUpdated` -自分の情報が更新されたことを表すイベントです。 - -#### `follow` -自分が誰かをフォローしたときに発生するイベントです。 - -#### `unfollow` -自分が誰かのフォローを解除したときに発生するイベントです。 - -#### `followed` -自分が誰かにフォローされたときに発生するイベントです。 - -## `homeTimeline` -ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -タイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `localTimeline` -ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `hybridTimeline` -ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ソーシャルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `globalTimeline` -グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 diff --git a/src/docs/ht-HT/theme.md b/src/docs/ht-HT/theme.md deleted file mode 100644 index a406f3433..000000000 --- a/src/docs/ht-HT/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# テーマ - -テーマを設定して、Misskeyクライアントの見た目を変更できます。 - -## テーマの設定 -設定 > テーマ - -## テーマを作成する -テーマコードはJSON5で記述されたテーマオブジェクトです。 テーマは以下のようなオブジェクトです。 -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... テーマの一意なID。UUIDをおすすめします。 -* `name` ... テーマ名 -* `author` ... テーマの作者 -* `desc` ... テーマの説明(オプション) -* `base` ... 明るいテーマか、暗いテーマか - * `light`にすると明るいテーマになり、`dark`にすると暗いテーマになります。 - * テーマはここで設定されたベーステーマを継承します。 -* `props` ... テーマのスタイル定義。これから説明します。 - -### テーマのスタイル定義 -`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 - -#### バリューで使える構文 -* 16進数で表された色 - * 例: `#00ff00` -* `rgb(r, g, b)`形式で表された色 - * 例: `rgb(0, 255, 0)` -* `rgb(r, g, b, a)`形式で表された透明度を含む色 - * 例: `rgba(0, 255, 0, 0.5)` -* 他のキーの値の参照 - * `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。 - * 例: `@panel` -* 定数(後述)の参照 - * `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。 - * 例: `$main` -* 関数(後述) - * `:{関数名}<{引数}<{色}` - -#### 定数 -「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 キー名を`$`で始めると、そのキーはCSS変数として出力されません。 - -#### 関数 -wip diff --git a/src/docs/ht-HT/timelines.md b/src/docs/ht-HT/timelines.md deleted file mode 100644 index 36ba61bd2..000000000 --- a/src/docs/ht-HT/timelines.md +++ /dev/null @@ -1,15 +0,0 @@ -# タイムラインの比較 - -https://docs.google.com/spreadsheets/d/1lxQ2ugKrhz58Bg96HTDK_2F98BUritkMyIiBkOByjHA/edit?usp=sharing - -## ホーム -自分のフォローしているユーザーの投稿 - -## ローカル -全てのローカルユーザーの「ホーム」指定されていない投稿 - -## ソーシャル -自分のフォローしているユーザーの投稿と、全てのローカルユーザーの「ホーム」指定されていない投稿 - -## グローバル -全てのローカルユーザーの「ホーム」指定されていない投稿と、サーバーに届いた全てのリモートユーザーの「ホーム」指定されていない投稿 diff --git a/src/docs/id-ID/admin/disable-timelines.md b/src/docs/id-ID/admin/disable-timelines.md deleted file mode 100644 index 54d350ec4..000000000 --- a/src/docs/id-ID/admin/disable-timelines.md +++ /dev/null @@ -1,8 +0,0 @@ -# Menonaktifkan LTL/STL/GTL -Misskey memungkinkan untuk menonaktifkan LTL/STL/GTL secara satu persatu.Kamu dapat mengaktifkan atau menonaktifkan linimasa individual tersebut melalui panel kontrol instansi. - -LTLやSTLは、そのインスタンス全員の投稿が見れるため、新規のユーザーにとってはユーザーを探す必要がなくなり、興味のあるユーザーを見つけやすいという利点があります。 しかし同時に、フォロー機能が活用されなくなったり、不適切な投稿が目につきやすくなったり、チャットのようになることで内輪感が生じて逆に新規ユーザーが参加しにくくなるといったデメリットも持ち合わせています。 サーバーによってメリット/デメリットどちらが優勢かは異なるので、オプションとして無効にできるようになっています。 もしデメリットの方が上回っていると感じたら、それらのタイムラインを無効化することも検討してください。 - -
Menonaktifkan linimasa dapat menyebabkan kebingungan dan memungkinkan untuk pengguna mengalami drop-in jangka pendek.Oleh karena itu, dimohon berhati-hati dengan efek dari menonaktifkan linimasa, dan jelaskan alasannya mengapa menonaktifkan tersebut dari awal, agar pengguna kamu dapat bersiap dengan mengikuti pengguna yang seringnya mereka berkomunikasi di LTL/STL.
- -Sebagai tambahan, Administrator / Moderator akan tetap dapat melihat linimasa ini meskipun telah dinonaktifkan. diff --git a/src/docs/id-ID/admin/faq.md b/src/docs/id-ID/admin/faq.md deleted file mode 100644 index 747a4a24f..000000000 --- a/src/docs/id-ID/admin/faq.md +++ /dev/null @@ -1,5 +0,0 @@ -# Pertanyaan Yang Sering Ditanyakan (FAQ) -Dokumen ini ditujukan kepada administrator server dan memberikan daftar jawaban untuk pertanyaan yang sering ditanyakan. - -## "Aku ingin menyetel tema bawaan untuk instansi milikku" -Untuk saat ini belum ada fitur yang membolehkan kamu untuk menyetel tema default instansi milikmu. diff --git a/src/docs/id-ID/advanced/aiscript.md b/src/docs/id-ID/advanced/aiscript.md deleted file mode 100644 index 604d17daa..000000000 --- a/src/docs/id-ID/advanced/aiscript.md +++ /dev/null @@ -1,7 +0,0 @@ -# AiScript -AiScriptは、Misskeyで使用できるスクリプト言語です。 - -
ℹ️ AiScript実装はMisskeyとは別リポジトリで、オープンソースで公開されています。
- -## 使い方 -AiScriptの構文や組み込み関数などのドキュメントは、[こちら](https://github.com/syuilo/aiscript/tree/master/docs)で公開されています。 diff --git a/src/docs/id-ID/advanced/api.md b/src/docs/id-ID/advanced/api.md deleted file mode 100644 index 76019b614..000000000 --- a/src/docs/id-ID/advanced/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス、Bot等(以下「アプリケーション」と呼びます)を開発できます。 ストリーミングAPIもあるので、リアルタイム性のあるアプリケーションを作ることも可能です。 - -APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。 - -## アクセストークンの取得 -基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。 - -* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む -* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む - -### 自分自身のアクセストークンを手動発行する -「設定 > API」で、自分のアクセストークンを発行できます。 - -[「APIの使い方」へ進む](#APIの使い方) - -### アプリケーション利用者にアクセストークンの発行をリクエストする -アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。 - -#### Step 1 - -UUIDを生成する。以後これをセッションIDと呼びます。 - -> このセッションIDは毎回生成し、使いまわさないようにしてください。 - -#### Step 2 - -`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。 -> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます: -* `name` ... アプリケーション名 - * > 例: `MissDeck` -* `icon` ... アプリケーションのアイコン画像URL - * > 例: `https://missdeck.example.com/icon.png` -* `callback` ... 認証が終わった後にリダイレクトするURL - * > 例: `https://missdeck.example.com/callback` - * リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます -* `permission` ... アプリケーションが要求する権限 - * > 例: `write:notes,write:following,read:drive` - * 要求する権限を`,`で区切って列挙します - * どのような権限があるかは[APIリファレンス](/api-doc)で確認できます - -#### Step 3 -ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。 - -レスポンスに含まれるプロパティ: -* `token` ... ユーザーのアクセストークン -* `user` ... ユーザーの情報 - -[「APIの使い方」へ進む](#APIの使い方) - -## APIの使い方 -**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。 - -* [APIリファレンス](/api-doc) -* [ストリーミングAPI](./stream) diff --git a/src/docs/id-ID/advanced/create-plugin.md b/src/docs/id-ID/advanced/create-plugin.md deleted file mode 100644 index ec17b9518..000000000 --- a/src/docs/id-ID/advanced/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# プラグインの作成 -Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。 - -## Metadata -プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。 - -### name -プラグイン名 - -### author -プラグイン作者 - -### version -プラグインバージョン。数値を指定してください。 - -### description -プラグインの説明 - -### permissions -プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。 - -### config -プラグインの設定情報を表すオブジェクト。 キーに設定名、値に以下のプロパティを含めます。 - -#### type -設定値の種類を表す文字列。以下から選択します。 string number boolean - -#### label -ユーザーに表示する設定名 - -#### description -設定の説明 - -#### default -設定のデフォルト値 - -## APIリファレンス -AiScript標準で組み込まれているAPIは掲載しません。 - -### Mk:dialog(title text type) -ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。 - -### Mk:confirm(title text type) -確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。 - -### Mk:api(endpoint params) -Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。 - -### Mk:save(key value) -任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。 - -### Mk:load(key) -Mk:saveで永続化した指定の名前の値を読み取ります。 - -### Plugin:register_post_form_action(title fn) -投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。 - -### Plugin:register_note_action(title fn) -ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 - -### Plugin:register_user_action(title fn) -ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。 - -### Plugin:register_note_view_interruptor(fn) -UIに表示されるノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:register_note_post_interruptor(fn) -ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:open_url(url) -第一引数に渡されたURLをブラウザの新しいタブで開きます。 - -### Plugin:config -プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。 diff --git a/src/docs/id-ID/advanced/develop-bot.md b/src/docs/id-ID/advanced/develop-bot.md deleted file mode 100644 index 7f825e9bc..000000000 --- a/src/docs/id-ID/advanced/develop-bot.md +++ /dev/null @@ -1,6 +0,0 @@ -# Botの作成 -[Misskey API](./api)を利用してBotの開発が可能です。 また、いくつかのBot実装が公開されているため、ぜひ参考にしてください。 - -- [syuilo/ai](https://github.com/syuilo/ai) ... Node.js上で動く、TypeScript製Bot実装 - -Botを作成したときは、プロフィール設定からBotフラグをオンにしておくことを強くおすすめします。 diff --git a/src/docs/id-ID/advanced/reversi-bot.md b/src/docs/id-ID/advanced/reversi-bot.md deleted file mode 100644 index 5d764242e..000000000 --- a/src/docs/id-ID/advanced/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# MisskeyリバーシBotの開発 -Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。 - -1. `games/reversi`ストリームに以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - -2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる - * イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている - -3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する - -4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - * `game`: `game`の`id` - -5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う - -6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する - -7. ゲームが開始すると、`started`イベントが流れてくる - * イベントの中身にはゲーム情報が含まれている - -8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述) - -9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる - * `color`として石の色が含まれている - * `pos`として位置情報が含まれている - -## 位置の計算法 -8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### X,Y座標 から インデックス に変換する -``` -pos = x + (y * mapWidth) -``` -`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます: -``` -mapWidth = map[0].length -``` - -### インデックス から X,Y座標 に変換する -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## マップ情報 -マップ情報は、ゲーム情報の`map`に入っています。 文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 それをもとにマップのデザインを知る事が出来ます: -* `(スペース)` ... マス無し -* `-` ... マス -* `b` ... 初期配置される黒石 -* `w` ... 初期配置される白石 - -例えば、4*4の次のような単純なマップがあるとします: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -この場合、マップデータはこのようになります: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## ユーザーにフォームを提示して対話可能Botを作成する -ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。 - -フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します: -```javascript -{ - type: 'init-form', - body: [フォームコントロールの配列] -} -``` - -フォームコントロールの配列については今から説明します。 フォームコントロールは、次のようなオブジェクトです: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... コントロールのID。 `type` ... コントロールの種類。後述します。 `label` ... コントロールと一緒に表記するテキスト。 `value` ... コントロールのデフォルト値。 - -### フォームの操作を受け取る -ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### フォームコントロールの種類 -#### Beralih -type: `switch` スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。 - -##### プロパティ -`label` ... スイッチに表記するテキスト。 - -#### ラジオボタン -type: `radio` ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。 - -##### プロパティ -`items` ... ラジオボタンの選択肢。例: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '強', - value: 3 -}] -``` - -#### スライダー -type: `slider` スライダーを表示します。 - -##### プロパティ -`min` ... スライダーの下限。 `max` ... スライダーの上限。 `step` ... 入力欄で刻むステップ値。 - -#### テキストボックス -type: `textbox` テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。 - -## ユーザーにメッセージを表示する -設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 メッセージを表示するには、次のメッセージをストリームに送信します: -```javascript -{ - type: 'message', - body: { - text: 'メッセージ内容', - type: 'メッセージの種類' - } -} -``` -メッセージの種類: `success`, `info`, `warning`, `error`。 - -## 投了する -投了をするには、このエンドポイントにリクエストします。 diff --git a/src/docs/id-ID/advanced/share-page.md b/src/docs/id-ID/advanced/share-page.md deleted file mode 100644 index b7072a2cc..000000000 --- a/src/docs/id-ID/advanced/share-page.md +++ /dev/null @@ -1,54 +0,0 @@ -# シェアページ -`/share`を開くと、共有用の投稿フォームを開くことができます。 ここではシェアページで利用できるクエリ文字列の一覧を示します。 - -## クエリ文字列一覧 -### Teks - -
-
title
-
タイトルです。本文の先頭に[ … ]と挿入されます。
-
text
-
本文です。
-
url
-
URLです。末尾に挿入されます。
-
- -### リプライ情報 -以下のいずれか - -
-
replyId
-
リプライ先のノートid
-
replyUri
-
リプライ先のUrl(リモートのノートオブジェクトを指定)
-
- -### Renote情報 -以下のいずれか - -
-
renoteId
-
Renote先のノートid
-
renoteUri
-
Renote先のUrl(リモートのノートオブジェクトを指定)
-
- -### Visibilitas -※specifiedに相当する値はvisibility=specifiedとvisibleAccts/visibleUserIdsで指定する - -
-
visibility
-
公開範囲 ['public' | 'home' | 'followers' | 'specified']
-
localOnly
-
0(false) or 1(true)
-
visibleUserIds
-
specified時のダイレクト先のユーザーid カンマ区切りで
-
visibleAccts
-
specified時のダイレクト先のacct(@?username[@host]) カンマ区切りで
-
- -### Berkas -
-
fileIds
-
添付したいファイルのid(カンマ区切りで)
-
diff --git a/src/docs/id-ID/advanced/stream.md b/src/docs/id-ID/advanced/stream.md deleted file mode 100644 index 0f01df467..000000000 --- a/src/docs/id-ID/advanced/stream.md +++ /dev/null @@ -1,350 +0,0 @@ -# ストリーミングAPI - -ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。 - -## ストリームに接続する - -ストリーミングAPIを利用するには、まずMisskeyサーバーに**websocket**接続する必要があります。 - -以下のURLに、`i`というパラメータ名で認証情報を含めて、websocket接続してください。例: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。 - -
ℹ️ 認証情報の取得については、こちらのドキュメントをご確認ください。
- ---- - -認証情報は省略することもできますが、その場合非ログインでの利用ということになり、受信できる情報や可能な操作は限られます。例: - -``` -%WS_URL%/streaming -``` - ---- - -ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。 - -**ストリームでのやり取りはすべてJSONです。** - -## Kanal -MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。 - -ひとつのストリーム上で、同時に複数のチャンネルに接続することができます。 - -### チャンネルに接続する -チャンネルに接続するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -ここで、 -* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。 -* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。 -* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。 - -
ℹ️ IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。
- -### チャンネルからのメッセージを受け取る -例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。 - -チャンネルがメッセージを発すると、次のようなデータがJSONでストリームに流れてきます: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。 -* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。 -* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。 - -### チャンネルに向けてメッセージを送信する -チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。 - -チャンネルにメッセージを送信するには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。 -* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。 -* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。 - -### チャンネルから切断する -チャンネルから切断するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。 - -## ストリームを経由してAPIリクエストする - -ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。 - -ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -ここで、 -* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 -* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 -* `data`には、エンドポイントのパラメータを含めます。 - -
ℹ️ APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。
- -### レスポンスの受信 - -APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。 - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -ここで、 -* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 -* `body`には、レスポンスが含まれています。 - -## 投稿のキャプチャ - -Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。 - -例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。 - -しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。 - -この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。 - -### 投稿をキャプチャする - -投稿をキャプチャするには、ストリームに次のようなメッセージを送信します: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャしたい投稿の`id`を設定します。 - -このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 - -例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -ここで、 -* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。 -* `body`内の`type`に、イベントの種類が設定されます。 -* `body`内の`body`に、イベントの詳細が設定されます。 - -#### イベントの種類 - -##### `reacted` -その投稿にリアクションがされた時に発生します。 - -* `reaction`に、リアクションの種類が設定されます。 -* `userId`に、リアクションを行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -その投稿が削除された時に発生します。 - -* `deletedAt`に、削除日時が設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -その投稿に添付されたアンケートに投票された時に発生します。 - -* `choice`に、選択肢IDが設定されます。 -* `userId`に、投票を行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### 投稿のキャプチャを解除する - -その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。 - -次のメッセージを送信します: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャを解除したい投稿の`id`を設定します。 - -このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 - -# チャンネル一覧 -## `main` -アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `renote` -自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。 - -#### `mention` -誰かからメンションされたときに発生するイベントです。 - -#### `readAllNotifications` -自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。 - -#### `meUpdated` -自分の情報が更新されたことを表すイベントです。 - -#### `follow` -自分が誰かをフォローしたときに発生するイベントです。 - -#### `unfollow` -自分が誰かのフォローを解除したときに発生するイベントです。 - -#### `followed` -自分が誰かにフォローされたときに発生するイベントです。 - -## `homeTimeline` -ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -タイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `localTimeline` -ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `hybridTimeline` -ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ソーシャルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `globalTimeline` -グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 diff --git a/src/docs/id-ID/aiscript.md b/src/docs/id-ID/aiscript.md deleted file mode 100644 index 682ba6b51..000000000 --- a/src/docs/id-ID/aiscript.md +++ /dev/null @@ -1,4 +0,0 @@ -# AiScript - -## Fungsi -Secara bawaan, berjalan sebagai pass dari value. diff --git a/src/docs/id-ID/api.md b/src/docs/id-ID/api.md deleted file mode 100644 index 57e271b5f..000000000 --- a/src/docs/id-ID/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -Dengan menggunakan Misskey API kamu dapat mengembangkan klien Misskey, Webservice yang terintegrasi dengan Misskey, Bots (nantinya akan disebut "Aplikasi" disini), dll. Terdapat juga streaming API, yang memungkinan untuk membuat aplikasi real-time. - -Untuk memulai menggunakin API, kamu harus memiliki access token terlebih dahulu. Halaman ini akan menjelaskan bagaimana untuk mendapatkan access token dan menjelaskan instruksi penggunaan dasar dari Misskey API. - -## Mendapatkan access token -Pada dasarnya, semua request API membutuhkan access token. Metode untuk mendapatkan sebuah access token bermacam-macam bergantung pada kamu sendiri yang mengirim request API atau request tersebut dikirim melalui aplikasi yang dipakai oleh pengguna akhir. - -* Apabila kamu pengguna lama: Langsung saja menuju [ "Menerbitkan access token untuk akun kamu sendiri secara manual" ](#自分自身のアクセストークンを手動発行する) -* Apabila kamu pengguna baru: Langsung saja menuju [ "Meminta aplikasi pengguna untuk menghasilkan access token" ](#アプリケーション利用者にアクセストークンの発行をリクエストする) - -### Menerbitkan access token untuk akun kamu sendiri secara manual -Kamu dapat membuat access token untuk akun milikmu di Pengaturan > API. - -[Lanjutkan untuk menggunakan API.](#APIの使い方) - -### アプリケーション利用者にアクセストークンの発行をリクエストする -アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。 - -#### Step 1 - -UUIDを生成する。以後これをセッションIDと呼びます。 - -> このセッションIDは毎回生成し、使いまわさないようにしてください。 - -#### Step 2 - -`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。 -> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます: -* `name` ... アプリケーション名 - * > 例: `MissDeck` -* `icon` ... アプリケーションのアイコン画像URL - * > 例: `https://missdeck.example.com/icon.png` -* `callback` ... 認証が終わった後にリダイレクトするURL - * > 例: `https://missdeck.example.com/callback` - * リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます -* `permission` ... アプリケーションが要求する権限 - * > 例: `write:notes,write:following,read:drive` - * 要求する権限を`,`で区切って列挙します - * どのような権限があるかは[APIリファレンス](/api-doc)で確認できます - -#### Step 3 -ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。 - -レスポンスに含まれるプロパティ: -* `token` ... ユーザーのアクセストークン -* `user` ... ユーザーの情報 - -[Lanjutkan untuk menggunakan API.](#APIの使い方) - -## Menggunakan API -**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。 - -* [APIリファレンス](/api-doc) -* [ストリーミングAPI](./stream) diff --git a/src/docs/id-ID/create-plugin.md b/src/docs/id-ID/create-plugin.md deleted file mode 100644 index 5f6b3daa9..000000000 --- a/src/docs/id-ID/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# Membuat Plugin -Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。 - -## Metadata -プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。 - -### name -プラグイン名 - -### author -プラグイン作者 - -### version -プラグインバージョン。数値を指定してください。 - -### description -プラグインの説明 - -### permissions -プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。 - -### config -プラグインの設定情報を表すオブジェクト。 キーに設定名、値に以下のプロパティを含めます。 - -#### type -設定値の種類を表す文字列。以下から選択します。 string number boolean - -#### label -ユーザーに表示する設定名 - -#### description -設定の説明 - -#### default -設定のデフォルト値 - -## APIリファレンス -AiScript標準で組み込まれているAPIは掲載しません。 - -### Mk:dialog(title text type) -ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。 - -### Mk:confirm(title text type) -確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。 - -### Mk:api(endpoint params) -Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。 - -### Mk:save(key value) -任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。 - -### Mk:load(key) -Mk:saveで永続化した指定の名前の値を読み取ります。 - -### Plugin:register_post_form_action(title fn) -投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。 - -### Plugin:register_note_action(title fn) -ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 - -### Plugin:register_user_action(title fn) -ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。 - -### Plugin:register_note_view_interruptor(fn) -UIに表示されるノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:register_note_post_interruptor(fn) -ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:open_url(url) -第一引数に渡されたURLをブラウザの新しいタブで開きます。 - -### Plugin:config -プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。 diff --git a/src/docs/id-ID/custom-emoji.md b/src/docs/id-ID/custom-emoji.md deleted file mode 100644 index 91a3cef1d..000000000 --- a/src/docs/id-ID/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# Emoji kustom -Emoji kustom merupakan fungsi yang menyediakan gambar terunggah ke server untuk digunakan seperti emoji. Emoji kustom ini dapt digunakan pada note, reaksi, obrolan, profil, dan bahkan username serta tempat-tempat lainnya. Untuk menggunakan emoji kustom pada tempat yang disebutkan di atas, tekan tombol pemilih Emoji (bila ada) atau ketik sebuah `:` dan jendela saran emoji akan muncul. Jika sebuah string yang terlihat seperti `:foo:` ditemukan dalam text apapun, maka sebagian dari `foo` diinterpretaskan sebagai nama emoji kustom dan akan digantikan dengan gambar emoji kustom ketika ditampilkan. diff --git a/src/docs/id-ID/deck.md b/src/docs/id-ID/deck.md deleted file mode 100644 index 7e0836f35..000000000 --- a/src/docs/id-ID/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# Dek - -デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。 - -## カラムの追加 -デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。 - -## カラムの移動 -カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。 - -## カラムの水平分割 -カラムは左右だけでなく、上下に並べることもできます。 カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 上下分割を解除するには、カラムメニューの「右に出す」を選択します。 - -## カラムの設定 -カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。 - -## デッキの設定 -デッキに関する設定は、[settings/deck](/settings/deck)で行えます。 diff --git a/src/docs/id-ID/features/antenna.md b/src/docs/id-ID/features/antenna.md deleted file mode 100644 index a0cc8506a..000000000 --- a/src/docs/id-ID/features/antenna.md +++ /dev/null @@ -1,4 +0,0 @@ -# Antena -アンテナは、自由に条件を設定して、合致するノートを自動で収集することができる機能です。 - -条件を設定したアンテナが作成された状態で、条件に合致するノートが投稿されると、リアルタイムでそのアンテナのタイムラインにノートが追加されます。 diff --git a/src/docs/id-ID/features/custom-emoji.md b/src/docs/id-ID/features/custom-emoji.md deleted file mode 100644 index 7a509195e..000000000 --- a/src/docs/id-ID/features/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# Emoji kustom -カスタム絵文字は、インスタンスで用意された画像を絵文字のように使える機能です。 ノート、リアクション、チャット、自己紹介、名前などの場所で使うことができます。 カスタム絵文字をそれらの場所で使うには、絵文字ピッカーボタン(ある場合)を押すか、`:`を入力して絵文字サジェストを表示します。 テキスト内に`:foo:`のような形式の文字列が見つかると、`foo`の部分がカスタム絵文字名と解釈され、表示時には対応したカスタム絵文字に置き換わります。 diff --git a/src/docs/id-ID/features/deck.md b/src/docs/id-ID/features/deck.md deleted file mode 100644 index 7e0836f35..000000000 --- a/src/docs/id-ID/features/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# Dek - -デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。 - -## カラムの追加 -デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。 - -## カラムの移動 -カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。 - -## カラムの水平分割 -カラムは左右だけでなく、上下に並べることもできます。 カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 上下分割を解除するには、カラムメニューの「右に出す」を選択します。 - -## カラムの設定 -カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。 - -## デッキの設定 -デッキに関する設定は、[settings/deck](/settings/deck)で行えます。 diff --git a/src/docs/id-ID/features/drive.md b/src/docs/id-ID/features/drive.md deleted file mode 100644 index c445b99a8..000000000 --- a/src/docs/id-ID/features/drive.md +++ /dev/null @@ -1,17 +0,0 @@ -# Drive -ドライブは、Misskey上でファイルを管理できる機能です。 - -[ドライブのページ](/my/drive)から任意のファイルをアップロードできるほか、アバターに設定した画像や、ノートに添付したファイルなどもすべてドライブにアップロードされます。 - -
⚠️ ドライブからファイルを削除すると、そのファイルが添付されたノートも消えます。
- -ドライブにアップロードされたファイルは、いつでもダウンロードすることができるほか、ノート作成時に「ドライブからファイルを添付」することでファイルを再利用することもできます。 - -ドライブ内にフォルダを作り、複数のファイルをまとめて整理することもできます。 - -## 閲覧注意 (NSFW) -
ℹ️ この項目が閲覧注意なわけではありません
- -閲覧注意またはNSFW (Not safe for work) は、ドライブのファイルに設定することができるフラグです。 閲覧注意フラグを設定されたファイルは、表示される際に閲覧者の操作なしには表示されなくなります。 このフラグは、例えば職場や公共の場で閲覧するのに適切でないと思われる画像などに設定し、そのような画像が突然表示されてしまうことを防ぐ目的で使われます。 - -このフラグは手動でオンオフを切り替えられるほか、モデレーターの判断で設定される場合もあります。 diff --git a/src/docs/id-ID/features/favorite.md b/src/docs/id-ID/features/favorite.md deleted file mode 100644 index 27d36e64e..000000000 --- a/src/docs/id-ID/features/favorite.md +++ /dev/null @@ -1,4 +0,0 @@ -# Favorit -[ノート](./node)をお気に入りとして登録できる機能です。 お気に入り登録したノートは、[お気に入りページ](./my/favorites)で一覧することができます。 お気に入りに登録したことは相手に通知されず、お気に入りは自分しか見ることができません。 - -ノートをお気に入り登録するには、ノートメニューの「お気に入り」を押します。お気に入り解除するには、ノートメニューの「お気に入り解除」を押します。 diff --git a/src/docs/id-ID/features/follow.md b/src/docs/id-ID/features/follow.md deleted file mode 100644 index 4799dc9d8..000000000 --- a/src/docs/id-ID/features/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# Ikuti -ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。 diff --git a/src/docs/id-ID/features/keyboard-shortcut.md b/src/docs/id-ID/features/keyboard-shortcut.md deleted file mode 100644 index 779f77dce..000000000 --- a/src/docs/id-ID/features/keyboard-shortcut.md +++ /dev/null @@ -1,66 +0,0 @@ -# キーボードショートカット - -## Global -これらのショートカットは基本的にどこでも使えます。 - - - - - - - - - - - -
ショートカット効果由来
P, N新規投稿Post, New, Note
Tタイムラインの最も新しい投稿にフォーカスTimeline, Top
Shift + N通知を表示/隠すNotifications
SPenelusuranSearch
H, ?ヘルプを表示Help
- -## 投稿にフォーカスされた状態 - - - - - - - - - - - - - - - - - - -
ショートカット効果由来
, K, Shift + Tab上の投稿にフォーカスを移動-
, J, Tab下の投稿にフォーカスを移動-
R返信フォームを開くReply
QRenoteフォームを開くQuote
Ctrl + Q即刻Renoteする(フォームを開かずに)-
E, A, +リアクションフォームを開くEmote, reAction
0~9数字に対応したリアクションをする(対応については後述)-
F, Bお気に入りに登録Favorite, Bookmark
Del, Ctrl + D投稿を削除Delete
M, O投稿に対するメニューを開くMore, Other
SCWで隠された部分を表示 or 隠すShow, See
Escフォーカスを外す-
- -## Renoteフォーム - - - - - - - - - -
ショートカット効果由来
EnterRenoteする-
Qフォームを展開するQuote
Escフォームを閉じる-
- -## リアクションフォーム -デフォルトで「👍」にフォーカスが当たっている状態です。 - - - - - - - - - - - - - -
ショートカット効果由来
, K上のリアクションにフォーカスを移動-
, J下のリアクションにフォーカスを移動-
, H, Shift + Tab左のリアクションにフォーカスを移動-
, L, Tab右のリアクションにフォーカスを移動-
Enter, Space, +リアクション確定-
0~9数字に対応したリアクションで確定-
Escリアクションするのをやめる-
diff --git a/src/docs/id-ID/features/mfm.md b/src/docs/id-ID/features/mfm.md deleted file mode 100644 index 5be2df4f3..000000000 --- a/src/docs/id-ID/features/mfm.md +++ /dev/null @@ -1,12 +0,0 @@ -# MFM -MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます。 - -## MFMが使用可能な場所の例 -- ノート本文 -- CW注釈 -- ユーザーの名前 -- ユーザーの自己紹介 - -## 開発者向け情報 -MFMのパーサー実装はライブラリとして公開されており、簡単にクライアントにMFMを組み込むことが可能です。 -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptパーサー実装 diff --git a/src/docs/id-ID/features/mute-and-block.md b/src/docs/id-ID/features/mute-and-block.md deleted file mode 100644 index 2444a8d43..000000000 --- a/src/docs/id-ID/features/mute-and-block.md +++ /dev/null @@ -1,41 +0,0 @@ -# Bisukan / Blokir -好みではないユーザーがいる場合は、ミュートを行うことでそのユーザーが自分から見えないようにすることができます。 また、より強力な措置として、ブロックを行うことでそのユーザーから自分のコンテンツが見えないようになるほか、自分に対して関わることができないようにすることができます。 ミュートされていることは相手は分かりませんが、ブロックされていることは相手に分かります。どちらを選ぶかはご自身の判断で行ってください。 - -
ℹ️ ミュートとブロックは併用できます。
- -
⚠️ 利用規約に違反するような、迷惑なユーザーがいる場合は運営者に報告することも検討してください。
- -設定>ミュートとブロック から、自分がミュートまたはブロックしているユーザー一覧を確認することができます。 - -## Bisukan -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -- タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -- そのユーザーからの通知 -- メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 -- など - -ユーザーをミュートするには、対象のユーザーのユーザーページのメニューを開き、「ミュート」ボタンを押します。 - -
ℹ️ ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。
- -## Blokir -ユーザーをブロックすると、そのユーザーからあなたのコンテンツが見えないようになり、またあなたに対して以下のようなアクションをすることができなくなります。 - -- フォローする -- ユーザーリストに追加する -- 返信する、Renoteする -- リアクションする、アンケートに投票する -- メッセージを送信する -- など - -また、 - -- ブロックする際に既にそのユーザーからフォローされていた場合はフォローが解除されます。 -- ブロックする際に既にそのユーザーがあなたをユーザーリストに入れていた場合はそのリストからあなたが削除されます。 - -ユーザーをブロックするには、対象のユーザーのユーザーページのメニューを開き、「ブロック」ボタンを押します。 - -
⚠️ ブロックを行ったこと自体は相手に通知されませんが、フォローを行ったりなどの上記のアクションが行えなくなるので間接的にブロックされていることは分かります。
- -
⚠️ 相手から自分のコンテンツが見えなくなりますが、相手がアカウントを切り替えたりログアウト状態になれば見ることができます。あくまで簡易的、補助的なものとしてお考えください。
diff --git a/src/docs/id-ID/features/mute.md b/src/docs/id-ID/features/mute.md deleted file mode 100644 index 66f717a4f..000000000 --- a/src/docs/id-ID/features/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# Bisukan - -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -* タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -* そのユーザーからの通知 -* メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 - -ユーザーをミュートするには、対象のユーザーのユーザーページに表示されている「ミュート」ボタンを押します。 - -ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。 - -設定>ミュート から、自分がミュートしているユーザー一覧を確認することができます。 diff --git a/src/docs/id-ID/features/note.md b/src/docs/id-ID/features/note.md deleted file mode 100644 index f921ffc20..000000000 --- a/src/docs/id-ID/features/note.md +++ /dev/null @@ -1,54 +0,0 @@ -# Catatan -ノートは、Misskeyに投稿される、文章、ファイル、アンケートなどを含むコンテンツで、Misskeyの中心的概念です。また、そのノートを作成する行為自体もノートと呼ばれます。 - -ノートが作成されると、[タイムライン](./timeline)に追加され、自分の[フォロワー](./follow)やサーバーのユーザーが見れるようになります。 - -ノートには、[リアクション](./reaction)を行うことができます。また、返信や引用もできます。 - -ノートを[お気に入り](./favorite)登録することで、後で簡単に見返すことができます。 - -## ノートを作成する -ノートを作成するには、画面上にある鉛筆マークのボタンを押して、作成フォームを開きます。作成フォームに内容を入力し、「ノート」ボタンを押すことでノートが作成されます。 ノートには、画像、動画など任意のファイルや、[アンケート](./poll)を添付することができます。また、本文中には[MFM](./mfm)が使用でき、[メンション](./mention)や[ハッシュタグ](./hashtag)を含めることもできます。 他にも、CWや公開範囲といった設定も行えます(詳細は後述)。 -
ℹ️ コンピューターのクリップボードに画像データがある状態で、フォーム内のテキストボックスにペーストするとその画像を添付することができます。
-
ℹ️ テキストボックス内でCtrl + Enterを押すことでも投稿できます。
- -## Renote -既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノートをRenoteと呼びます。 自分がフォローしているユーザーの、気に入ったノートを自分のフォロワーに共有したい場合や、過去の自分のノートを再度共有したい場合に使います。 同じノートに対して無制限にRenoteを行うことができますが、あまり連続して使用すると迷惑になる場合もあるので、注意しましょう。 -
⚠️ 公開範囲がフォロワーやダイレクトのノートはRenoteできません
- -Renoteを削除するには、Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 - -## CW -Contents Warningの略で、ノートの内容を、閲覧者の操作なしには表示しないようにできる機能です。主に長大な内容を隠すためや、ネタバレ防止などに使うことができます。 設定するには、フォームの「内容を隠す」ボタン(目のアイコン)を押します。すると新しい入力エリアが表れるので、そこに内容の要約を記入します。 - -## Visibilitas -ノートごとに、そのノートが公開される範囲を設定することができます。フォームの「ノート」ボタンの左にあるアイコンを押すと公開範囲を以下から選択できます。 - -### Publik -全ての人に対してノートが公開されるほか、サーバーの全てのタイムライン(ホームタイムライン、ローカルタイムライン、ソーシャルタイムライン、グローバルタイムライン)にノートが流れます。 -
⚠️ アカウントがサイレンス状態の時は、この公開範囲は使用できません。
- -### Beranda -全ての人に対してノートが公開されますが、フォロワー以外のローカルタイムライン、ソーシャルタイムライン、グローバルタイムラインにはノートは流れません。 - -### Pengikut -自分のフォロワーに対してのみノートを公開します。フォロワーの全てのタイムラインに流れます。 - -### Langsung -指定したユーザーに対してのみノートを公開します。指定したユーザーの全てのタイムラインに流れます。 - -### 「ローカルのみ」オプション -このオプションを有効にすると、リモートにノートを連合しなくなります。 - -### 公開範囲の比較 - - - - -
PublikBerandaPengikutLangsung
フォロワーのLTL/STL/GTL
非フォロワーのLTL/STL/GTL
- -## Sematkan ke profil -ノートをピン留めすると、ユーザーページに常にそのノートを表示しておくことができます。 ノートのメニューを開き、「ピン留め」を選択してピン留めできます。 複数のノートをピン留めできます。 - -## Tonton -ノートをウォッチすると、自分以外のノートへのリアクションや返信などの通知を受け取ることができます。 ノートのメニューを開き、「ウォッチ」を選択してウォッチできます。 diff --git a/src/docs/id-ID/features/pages.md b/src/docs/id-ID/features/pages.md deleted file mode 100644 index a9684c702..000000000 --- a/src/docs/id-ID/features/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# Pages - -## Variabel -変数を使うことで動的なページを作成できます。テキスト内で { 変数名 } と書くとそこに変数の値を埋め込めます。例えば Hello { thing } world! というテキストで、変数(thing)の値が ai だった場合、テキストは Hello ai world! になります。 - -変数の評価(値を算出すること)は上から下に行われるので、ある変数の中で自分より下の変数を参照することはできません。例えば上から A、B、C と3つの変数を定義したとき、Cの中でABを参照することはできますが、Aの中でBCを参照することはできません。 - -ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。 - -関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。 diff --git a/src/docs/id-ID/features/reaction.md b/src/docs/id-ID/features/reaction.md deleted file mode 100644 index 5361378ac..000000000 --- a/src/docs/id-ID/features/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# Reaksi -他の人のノートに、絵文字を付けて簡単にあなたの反応を伝えられる機能です。 リアクションするには、ノートの + アイコンをクリックしてピッカーを表示し、絵文字を選択します。 リアクションには[カスタム絵文字](./custom-emoji)も使用できます。 - -## リアクションピッカーのカスタマイズ -ピッカーに表示される絵文字を自分好みにカスタマイズすることができます。 設定の「リアクション」で設定します。 - -## リモート投稿へのリアクションについて -リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。 - -## リモートからのリアクションについて -リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。 diff --git a/src/docs/id-ID/features/silence.md b/src/docs/id-ID/features/silence.md deleted file mode 100644 index 1aba8535c..000000000 --- a/src/docs/id-ID/features/silence.md +++ /dev/null @@ -1,6 +0,0 @@ -# Bungkam -サイレンスは、アカウントに設定される状態のひとつです。 - -アカウントがサイレンス状態になると、ノートの公開範囲をパブリックにできなくなります。 ホーム、フォロワー、ダイレクトは選択可能なため、サイレンスを受けた場合でもフォロワーやあなたのユーザーページを直接訪れた場合は投稿を閲覧できますが、GTL(連合タイムライン)やLTL(ローカルタイムライン)には投稿が流れません。 - -アカウントのサイレンス状態は、サーバーのモデレーターによって有効化/無効化されます。 diff --git a/src/docs/id-ID/features/theme.md b/src/docs/id-ID/features/theme.md deleted file mode 100644 index b4b3f6d08..000000000 --- a/src/docs/id-ID/features/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# Tema - -テーマを設定して、Misskeyクライアントの見た目を変更できます。 - -## テーマの設定 -設定 > テーマ - -## テーマを作成する -テーマコードはJSON5で記述されたテーマオブジェクトです。 テーマは以下のようなオブジェクトです。 -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... テーマの一意なID。UUIDをおすすめします。 -* `name` ... テーマ名 -* `author` ... テーマの作者 -* `desc` ... テーマの説明(オプション) -* `base` ... 明るいテーマか、暗いテーマか - * `light`にすると明るいテーマになり、`dark`にすると暗いテーマになります。 - * テーマはここで設定されたベーステーマを継承します。 -* `props` ... テーマのスタイル定義。これから説明します。 - -### テーマのスタイル定義 -`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 - -#### バリューで使える構文 -* 16進数で表された色 - * 例: `#00ff00` -* `rgb(r, g, b)`形式で表された色 - * 例: `rgb(0, 255, 0)` -* `rgb(r, g, b, a)`形式で表された透明度を含む色 - * 例: `rgba(0, 255, 0, 0.5)` -* 他のキーの値の参照 - * `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。 - * 例: `@panel` -* 定数(後述)の参照 - * `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。 - * 例: `$main` -* 関数(後述) - * `:{関数名}<{引数}<{色}` - -#### Konstanta -「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 キー名を`$`で始めると、そのキーはCSS変数として出力されません。 - -#### Fungsi -wip diff --git a/src/docs/id-ID/features/timeline.md b/src/docs/id-ID/features/timeline.md deleted file mode 100644 index 55977ab16..000000000 --- a/src/docs/id-ID/features/timeline.md +++ /dev/null @@ -1,31 +0,0 @@ -# Linimasa -タイムラインは、[ノート](./note)が時系列で表示される機能です。 タイムラインには以下で示す種類があり、種類によって表示されるノートも異なります。 なお、タイムラインの種類によってはサーバーにより無効になっている場合があります。 - -## Beranda -自分のフォローしているユーザーの投稿が流れます。HTLと略されます。 - -## Lokal -全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。LTLと略されます。 - -## Sosial -自分のフォローしているユーザーの投稿と、全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。STLと略されます。 - -## Global -全てのローカルユーザーの「ホーム」指定されていない投稿と、サーバーに届いた全てのリモートユーザーの「ホーム」指定されていない投稿が流れます。GTLと略されます。 - -## Membandingkan -| ソース | | | Linimasa | | | -| ------------ | ----------- | ------- | -------- | ------ | ------ | -| Pengguna | Visibilitas | Beranda | Lokal | Sosial | Global | -| ローカル (フォロー) | Terbitkan | ✔ | ✔ | ✔ | ✔ | -| | Beranda | ✔ | | ✔ | | -| | Pengikut | ✔ | ✔ | ✔ | ✔ | -| リモート (フォロー) | Terbitkan | ✔ | | ✔ | ✔ | -| | Beranda | ✔ | | ✔ | | -| | Pengikut | ✔ | | ✔ | ✔ | -| ローカル (未フォロー) | Terbitkan | | ✔ | ✔ | ✔ | -| | Beranda | | | | | -| | Pengikut | | | | | -| リモート (未フォロー) | Terbitkan | | | | ✔ | -| | Beranda | | | | | -| | Pengikut | | | | | diff --git a/src/docs/id-ID/features/widgets.md b/src/docs/id-ID/features/widgets.md deleted file mode 100644 index 363254503..000000000 --- a/src/docs/id-ID/features/widgets.md +++ /dev/null @@ -1,7 +0,0 @@ -# Widget -ウィジェットは、MisskeyのUI上に設置できる小型の情報表示、操作が行えるパーツです。 - -ウィジェットを編集するには、ウィジェット編集モードに切り替えます。切り替え方法はUIによって異なります。 ウィジェット編集モードでは、ウィジェットの追加、削除、並び替え、およびそれぞれのウィジェットの設定を行えます。 - -## 利用可能なウィジェット一覧 -todo diff --git a/src/docs/id-ID/features/word-mute.md b/src/docs/id-ID/features/word-mute.md deleted file mode 100644 index 811de5279..000000000 --- a/src/docs/id-ID/features/word-mute.md +++ /dev/null @@ -1,20 +0,0 @@ -# Bisukan kata -ワードミュートの設定をすると、条件に合致したノートが表示されなくなります。 - -ワードミュートには、ソフトワードミュートとハードワードミュートの2種類があります。それぞれについて設定の方法と挙動を説明します。 - -## ソフトワードミュート -ソフトワードミュートは、クライアント(アプリ)側でミュートを判断するワードミュートです。 - -ノートが設定した条件に合致すると、「(ユーザー名)が何かを言いました」という表示で隠れます。 -クリックすると元の通りに表示されます。 - -## ハードワードミュート -ハードワードミュートは、アンテナのようにサーバーが新しいノートの本文に対して条件に合致するかどうか判断し、タイムラインから対象となったノートを除外します。 - -つまり、ハードワードミュートには、以下のような特徴があります。 - -* 条件設定後、新しい投稿のみがミュートの対象になります。 -* 条件を変更しても、過去にハードミュートされたノートはミュートされたままになります。 -* 「○○が何かを言いました」でタイムラインが埋まることがありません。 -* ソフトミュートに非対応のアプリでも、ハードミュートは適用されます。 diff --git a/src/docs/id-ID/follow.md b/src/docs/id-ID/follow.md deleted file mode 100644 index 9fa281a69..000000000 --- a/src/docs/id-ID/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# Ikuti -Jika kamu mengikuti seorang pengguna, postingan dari pengguna tersebut akan muncul pada linimasa kamu.Akan tetapi, balasan dari mereka kepada pengguna lain tidak akan ditampilkan. Untuk mengikuti seorang pengguna, klik tombol "Ikuti" pada halaman pengguna mereka.Untuk berhenti mengikuti seorang pengguna, klik tombol tersebut sekali lagi. diff --git a/src/docs/id-ID/general/apps.md b/src/docs/id-ID/general/apps.md deleted file mode 100644 index 1f4c85fe8..000000000 --- a/src/docs/id-ID/general/apps.md +++ /dev/null @@ -1,6 +0,0 @@ -# サードパーティアプリのリスト -## クライアント -todo - -## 連携サービス -todo diff --git a/src/docs/id-ID/general/changelog.md b/src/docs/id-ID/general/changelog.md deleted file mode 100644 index 3b00e6acb..000000000 --- a/src/docs/id-ID/general/changelog.md +++ /dev/null @@ -1,5 +0,0 @@ -# Catatan Rilis -
ℹ️ Catatan rilis ini hanya berlaku pada versi terakhir dari server ini.Untuk membaca catatan rilis Misskey paling terbaru, mohon periksa ke GitHub.
- - - diff --git a/src/docs/id-ID/general/faq.md b/src/docs/id-ID/general/faq.md deleted file mode 100644 index b82f0986f..000000000 --- a/src/docs/id-ID/general/faq.md +++ /dev/null @@ -1,28 +0,0 @@ -# Pertanyaan Yang Sering Ditanyakan (FAQ) -ここでは利用上のよくある質問について掲載しています。 Misskeyのプロジェクト自体についてのよくある質問は[こちら](./misskey)に掲載されています。 - -## iOS/Androidのアプリはありますか? -公式にはそういったOSのネイティブアプリを開発していませんが、サードパーティ製のアプリがいくつかあります。 詳しくは[こちら](./apps)をご覧ください。 - -ただ、サードパーティ製アプリはどうしても機能への対応が遅れてしまうため、とくに拘りがなければ公式のWebクライアントの利用をおすすめします。 なお、MisskeyのWebクライアントはPWAに対応しているので、ネイティブアプリのように動作させることも可能です。 詳しくは[こちら](todo)をご覧ください。 - -## Mastodonクライアントでログインできないのですが? -MisskeyはMastodonのAPIと互換性がないため、一部を除きMastodonクライアントでMisskeyを利用することはできません。 - -## 他のサーバーのユーザーをフォローするときは? -メニューから検索を選び、ユーザー名をホスト込みで入力します。例: `@syuilo@misskey.io` - -## Renoteを削除するには? -Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 Renoteについては[こちら](../features/note)をご確認ください。 - -## URLのプレビューを表示させたくない -MFMには、そのURLのプレビューを無効にする構文があります。詳細は[MFMチートシート](/mfm-cheat-sheet)をご確認ください。 - -## カスタム絵文字を追加したい -運営者のみがカスタム絵文字を追加、編集、削除できます。それらを希望する場合は運営者に依頼してください。 - -## Botを開発したい -Misskey APIを利用してBotの開発が可能です。[こちら](../advanced/develop-bot)をご確認ください。 - -## ノートの翻訳機能はどのサービスを使用していますか? -[DeepL](https://www.deepl.com/)を使用しています。 diff --git a/src/docs/id-ID/general/glossary.md b/src/docs/id-ID/general/glossary.md deleted file mode 100644 index b98b3b111..000000000 --- a/src/docs/id-ID/general/glossary.md +++ /dev/null @@ -1,89 +0,0 @@ -# Kosakata -Kosakata yang terkait dengan Misskey. - -## ActivityPub -Protokol yang digunakan untuk memungkinkan distribusi dari Misskey.Dengan mengikuti protokol ini, komunikasi dengan server lainnya yang juga mengikuti protokol ini menjadi mungkin, yang mana membentuk suatu semesta yang disebut sebagai Fediverse. - -## AiScript -Bahasa pemrograman yang tersedia untuk digunakan dalam Misskey.Untuk detilnya, [lihat disini.](../advanced/aiscript) - -## API -Antarmuka yang dapat digunakan untuk berinteraksi dengan Misskey melalui program, tersedia untuk setiap instansi individual.Untuk detilnya, [lihat disini.](../advanced/api) - -## Bot -Sebuah akun yang dikendalikan oleh program. - -## CW -Singkatan dari "Content Warning".Sebuah fitur untuk menyembunyikan konten dari catatan kecuali diminta untuk diperlihatkan oleh pengguna.Utamanya digunakan untuk menyembunyikan konten catatan panjang atau untuk mencegah postingan spoiler secara publik. - -## Fediverse -Sebuah jaringan server yang terdiri dari berbagai platform berbeda yang saling berkomunikasi, termasuk Misskey. - -## GTL -Singkatan dari "Global TimeLine" (Linimasa Global).Untuk informasi lebih lanjut tentang linimasa, mohon [lihat disini](../features/timeline). - -## HTL -Singkatan dari "Home TimeLine" (Linimasa Beranda).Untuk informasi lebih lanjut tentang linimasa, mohon [lihat disini](../features/timeline) - -## LTL -Singkatan dari "Local TimeLine" (Linimasa Lokal).Untuk informasi lebih lanjut tentang linimasa, mohon [lihat disini](../features/timeline) - -## MFM -Singkatan dari "Misskey Flavored Markdown", sebuah bahasa markdown yang tersedia untuk digunakan pada Misskey.Untuk detilnya, [lihat disini.](../features/mfm) - -## NSFW -(読み: のっとせーふふぉーわーく) Not Safe For Workの略。画像を「閲覧注意」扱いにし、操作なしには表示しないようにすることができる機能。 - -## Renote -(読み: りのーと) 既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノート。詳細は[こちら。](../features/note) - -## STL -Singkatan dari "Social TimeLine" (Linimasa Sosial).Untuk informasi lebih lanjut tentang linimasa, mohon [lihat disini](../features/timeline) - -## Ai -Ai adalah maskot resmi milik Misskey. - -## Pengguna Aktif -Para pengguna di antara semua pengguna yang ada yang terus menggunakan akun mereka. - -## Instansi -todo - -## Emoji kustom -Emoji yang disediakan oleh server kamu.Emoji yang spesifik tidak disediakan oleh server kamu tetapi tersedia secara bawaan adalah "Unicode Emoji". - -## Panel kontrol -インスタンスの設定画面のこと。 - -## Server -todo - -## Bungkam -ノートをパブリックな公開範囲で投稿できなくされている状態。モデレーターの判断でユーザーごとに設定されます。詳細は[こちら。](../features/silence) - -## Antrian kerja -アクティビティ配送などを順番に行うためのシステム。 - -## Bekukan -アカウントが使用不可に設定されている状態。 - -## Drive -Misskeyにアップロードしたファイルを管理する機能。詳細は[こちら。](../features/drive) - -## Catatan -Misskeyに投稿される、文章、ファイル、アンケートなどを含めることができるコンテンツ。詳細は[こちら。](../features/note) - -## Misskist -Pengguna dari Misskey. - -## Moderator -スパムの凍結およびサイレンスや不適切な投稿の削除など、コミュニティ運営に関する権限を持つユーザー。 - -## Remote -他サーバーのことを指します。リモートユーザーといったように接頭辞としても使われます。ローカルの逆です。 - -## Federasi -サーバー上で作成された情報が他のサーバーに伝わること。 - -## Lokal -自サーバーのことを指します。ローカルユーザー、ローカルタイムラインといったように接頭辞としても使われます。リモートの逆です。 diff --git a/src/docs/id-ID/general/links.md b/src/docs/id-ID/general/links.md deleted file mode 100644 index 39cab001d..000000000 --- a/src/docs/id-ID/general/links.md +++ /dev/null @@ -1,12 +0,0 @@ -# リンク集 - -## Webサイト -- [Official Discord](https://discord.gg/Wp8gVStHW3) - Misskey公式Discordサーバー -- [Misskey Forum](https://forum.misskey.io/) - Misskeyに関する話題を扱うフォーラム - -## Akun -- [@repo@misskey.io](https://misskey.io/@repo) - Misskeyのリポジトリの更新を投稿するbot - -## ライブラリ -- [misskey-dev/misskey.js](https://github.com/misskey-dev/misskey.js) - JavaScriptのMisskey SDK -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptのMFMパーサー実装 diff --git a/src/docs/id-ID/general/misskey.md b/src/docs/id-ID/general/misskey.md deleted file mode 100644 index a843f2888..000000000 --- a/src/docs/id-ID/general/misskey.md +++ /dev/null @@ -1,87 +0,0 @@ -# Tentang Misskey - -Misskey adalah platform sumber terbuka dan terdistribusi untuk mikroblogging. Pengembangan dimulai dari 2014 oleh syuilo di Jepang. Memiliki banyak fitur seperti Drive atau Reaksi dan juga kustomisasi UI yang tinggi. - -## Sejarah -開発当初は掲示板がメインのサービスでしたが、ユーザーが短文を投稿し、それを時系列で流れるタイムライン機能を追加したところ人気が高まり、徐々にそれがメインとして開発が進むようになりました。 当初は分散型ではありませんでしたが、2018年にActivityPubを実装し分散型になったことで、より多くの方に認知され利用されるサービスになり、現在に至ります。 -
ℹ️ Misskeyという名前は、syuiloが当時聴いていたMay'nというアーティストの楽曲、Brain Diverの歌詞に由来します。
- -誰でも開発に参加することができ、現在でも活発に開発が続いています。 - -## Apa yang dimaksud dengan "Terdistribusi"? - -分散(distributed)型とは、非中央集権(decentralized)とも呼ばれ、コミュニティが多数のサーバーに分散して存在し、それらが相互に通信(連合、federation)することでコンテンツ共有ネットワーク(Fediverse)を形成していることが特徴のサービスです。 単一のサーバーしか存在しない、もしくは複数存在しても互いに独立している場合は中央集権なサービスと言われ、例えばTwitterやFacebookなどほとんどのサービスがそれに該当します。 分散型のメリットは、自分に合った運営者やテーマのサーバーを選択できることです。自分でサーバーを作成することもできます。連合するおかげで、どのサーバーを選んでも、同じコミュニティにアクセスできます。 - -## Selalu sumber-terbuka -Misskey sudah selalu, dan akan selalu menjadi perangkat lunak sumber terbuka.オープンソースとは、簡単に言うとソフトウェアのソースコード(プログラム)が公開されていることです。ソースコードの修正や再配布が可能であることを定義に含めることもあります。 Misskeyのすべてのソースコードは[AGPL](https://github.com/misskey-dev/misskey/blob/develop/LICENSE)というオープンソースライセンスの下に[公開](https://github.com/misskey-dev)されていて、誰でも自由に閲覧、使用、修正、改変、再配布をすることができます。 オープンソースは、自分で好きなように変えたり、有害な処理が含まれていないことを確認することができたり、誰でも開発に参加できるなどの、様々なメリットがあります。 上述の分散型を実現するためにも、オープンソースであるということは必要不可欠な要素です。 再び引き合いに出しますが、TwitterやFacebookなどの利益を得ているほとんどのサービスはオープンソースではありません。 - -
ℹ️ 技術的に言うと、MisskeyのソースコードはGitで管理されていて、リポジトリはGitHub上でホスティングされています。
- -## Ikut mengembangkan dan mendukung proyek -Misskeyを気に入っていただけたら、ぜひプロジェクトを支援してください。プロジェクトに貢献するには、以下で紹介するようにいろいろな方法があります。方法によっては開発のスキルは不要なので、誰でも気軽に参加し貢献することができます。いつでもお待ちしています。 - -### Menambahkan fitur atau memperbaiki bug -ソフトウェアエンジニアのスキルをお持ちの方であれば、ソースコードを編集する形でプロジェクトに貢献することができます。 貢献についてのガイドは[こちら](https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md)です。 - -### Berpartisipasi dalam diskusi -新しい機能、または既存の機能について意見を述べたり、不具合を報告したりすることでも貢献できます。 そのようなディスカッションは[GitHub](https://github.com/misskey-dev)上か、[フォーラム](https://forum.misskey.io/)等で行われます。 - -### Menerjemahkan teks -Misskeyは様々な言語に対応しています(i18n -internationalizationの略- と呼ばれます)。元の言語は基本的に日本語ですが、有志によって他の言語へと翻訳されています。 その翻訳作業に加わっていただくことでもMisskeyに貢献できます。 Misskeyは[Crowdinというサービスを使用して翻訳の管理を行っています。](https://crowdin.com/project/misskey) - -### Berbagi impresimu -不具合報告等だけではなく、Misskeyの良い点、楽しい点といったポジティブな意見もぜひ共有してください。開発の励みになり、それは間接的ですがプロジェクトへの貢献です。 - -### Menambahkan jumlah Misskist -ミスキストとは、Misskeyを使用する人のことです。 知り合いに紹介するなどしてMisskeyを広めていただければ、ミスキストが増え開発のモチベーションが上がります。 - -### Membuat donasi -Misskeyはビジネスではなく、利用は無料であるため、収益は皆様からの寄付のみです。(インスタンスによっては広告収入を得ているような場合もありますが、それは運営者の収入であり直接開発者への収入にはなりません) 寄付をしていただければ、今後も開発を続けることが可能になり、プロジェクトへの貢献になります。 寄付は基本的には[Patreon](https://www.patreon.com/syuilo)で受け付けています。 一定額寄付していただけると、Misskeyの[情報ページ](/about-misskey)に名前を記載することができます。 - -また、サーバーの運営者も、基本的には収益を得ていません。サーバーの運営にはコストがかかるので、運営者の支援をすることもご検討ください。 開発には直接関係しませんが、サーバーがあってこそのプロジェクトなので、運営が維持されるというのは開発と同じくらい重要なことです。 - -## Kredit -Misskeyの開発者や、Misskeyに寄付をしてくださった方の一覧は[こちら](/about-misskey)で見ることができます。 - -## Pertanyaan Yang Sering Ditanyakan (FAQ) -### Apa yang ingin dicapai dari project ini? -強いて言うと、漠然的になりますが広く使われる汎用的なプラットフォームになることを目指しています。 Misskeyは他のプロジェクトとは違い、何らかの思想(例えば、反中央集権)やビジョンに基づいて開発が行われているわけではなく、その点ではフラットです。 それが逆に、特定の方向性に縛られないフレキシブルさを生み出すことに繋がっていると感じています。 - - -### Apakah Misskey dikembangkan oleh perusahaan? -いいえ。Misskeyの開発は個人で行われており、商業的でもないため、特定の企業の関りはありません。 開発メンバーも基本的にはボランティアです。 また、開発に対し企業のスポンサーがつくこともありますが、その場合でもやはり開発は個人のコミュニティが主体です。 - -### Siapa yang mengelola Misskey? -Misskeyは分散型なため、各サーバーにそれぞれ異なった運営者がいます。従って、特定の個人や企業によって、Misskeyの全てが運営されているわけではありません。 また、開発チームが運営を行うわけでもないため、運営に関する連絡は、お使いのサーバーの運営者に行ってください。 サーバーの運営者は、[このページ](/about)で確認することができます。 あなたがサーバーを作成すれば、あなたが運営者になります。 - -### Server mana yang seharusnya aku pilih? -[サーバー一覧が公開されています。](https://join.misskey.page/ja-JP/instances) サーバーによってコミュニティのテーマ(特定のこと、ものが好き 等)が決められている場合があるので、自分に合ったテーマのサーバーがあれば、そこを選ぶと良いかもしれません。 他にも、サーバーの規模、ユーザー層、国および言語、運営者が信頼できるかどうか、などの観点があります。 なお、Misskey公式のサーバーというものはありません。自身で新しくサーバーを作成するという選択肢もあります。 - -基本的にどのサーバーを選んだとしても、他の全てのサーバーのユーザーと繋がることができます。 - -### Bagaimana cara untuk membuat server milikku sendiri? -Misskeyサーバーの作成に興味を持っていただきありがとうございます。 2021年現在、Misskeyのホスティングサービスは存在しないため、サーバーの作成にはある程度の知識が必要です。 サーバーの作成方法については[こちら](todo)をご覧ください。 - -### Teknologi apa yang Misskey gunakan? -Misskeyは開発が進むにつれ使用する技術も大きく変わってきました。開発当初はMySQL + PHP + jQueryといった構成でしたが、現在は以下のようになっています。 -- Server: Node.js -- Database: PostgreSQL, Redis -- UI Framework: Vue.js -- Bahasa Pemrograman: TypeScript - -また、MFMやAiScriptなどの、Misskeyから派生して独自の技術も開発しています。 - -### Apakah ini fork dari Mastodon? -いいえ。MisskeyはMastodonやその他のプロジェクトとは全く別のプロジェクトです。 開発に関しても、Misskeyの方が昔から開発されています。ただし、分散型になったのはMastodonの登場より後です。 同じActivityPubという分散のためのプロトコルを実装しているという点以外、両者に特に関りがあるわけでもありません。 - -### Apakah ada aplikasi untuk iOS / Android tersedia? -公式にはそういったOSのネイティブアプリを開発していませんが、サードパーティ製のアプリがいくつかあります。 詳しくは[こちら](./apps)をご覧ください。 - -ただ、サードパーティ製アプリはどうしても機能への対応が遅れてしまうため、とくに拘りがなければ公式のWebクライアントの利用をおすすめします。 なお、MisskeyのWebクライアントはPWAに対応しているので、ネイティブアプリのように動作させることも可能です。 詳しくは[こちら](todo)をご覧ください。 - -### Dimana aku bisa mengunduh logo atau ikon Misskey? -(Sedang dipersiapkan) - -### Siapa gadis imut bertelinga kucing yang sering muncul di Misskey? -Misskeyの守り神、藍ちゃんです。アイチャンカワイイヤッター! -
ℹ️ 藍ちゃんについてはこちらです。
diff --git a/src/docs/id-ID/general/report-issue.md b/src/docs/id-ID/general/report-issue.md deleted file mode 100644 index 63527e32a..000000000 --- a/src/docs/id-ID/general/report-issue.md +++ /dev/null @@ -1,8 +0,0 @@ -# 不具合の報告 -不具合と思われる状況に遭遇したときは、まず[トラブルシューティング](./troubleshooting)をご一読ください。 それでも問題が解決しないときは、以下の情報を含めて[フォーラム](https://forum.misskey.io/)に投稿してください。 投稿することで、解決策が見つかったり、不具合と判断されれば開発チームによって修正が行われます。 - -## 含める情報 -- Misskeyのバージョン([情報ページ](/about)で確認できます) -- お使いのブラウザの種類とバージョン -- お使いのOSの種類とバージョン -- 問題の再現手順 diff --git a/src/docs/id-ID/general/troubleshooting.md b/src/docs/id-ID/general/troubleshooting.md deleted file mode 100644 index 5cdd0ae8d..000000000 --- a/src/docs/id-ID/general/troubleshooting.md +++ /dev/null @@ -1,40 +0,0 @@ -# Penyelesaian Masalah -
ℹ️ よくある質問も合わせてお役立てください。
- -問題が発生したときは、まずこちらをご確認ください。 該当する項目が無い、もしくは手順を試しても効果がない場合は、サーバーの管理者に連絡するか[不具合を報告](./report-issue)してください。 - -## クライアントが起動しない -ほとんどの場合、お使いのブラウザまたはOSのバージョンが古いことが原因です。 ブラウザおよびOSのバージョンを最新のものに更新してから、再度試してみてください。 - -これは稀ですが、それでも起動しない場合は、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。 - -## ページが読み込めない -クライアントが起動するもののページが読み込めないというエラーが出る場合は、ネットワークに問題がないか確認してください。また、サーバーがダウンしていないか確認してください。 - -これは稀ですが、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。 - -まだ問題がある場合は、サーバーの問題と思われるのでサーバーの管理者に連絡してください。 - -## クライアントの動作が遅い -以下を試してみてください: - -- クライアント設定で「UIのアニメーションを減らす」を有効にする -- クライアント設定で「モーダルにぼかし効果を使用」を無効にする -- お使いのブラウザの設定でハードウェアアクセラレーションを有効にする -- お使いのデバイスのスペックを上げる - -## UIの一部の表示がおかしい(背景が透明になっている等) -アップデートによりUIの改修が行われたときに、テーマのキャッシュシステムの影響でそのような表示になることがあります。 クライアントの設定の「キャッシュをクリア」すると直ります。 -
⚠️ 「クライアントの」キャッシュクリアです。「ブラウザの」キャッシュクリアは行わないでください。
- -## 通知やアンテナ等の点滅が消えない -点滅は、未読のコンテンツがあることを示しています。通常点滅が消えない場合は、コンテンツを遡ると未読なコンテンツが残っています。 すべて既読にしたと思われるのに、それでもなお点滅が続く場合(おそらく不具合と思われます)は設定から強制的にすべて既読扱いにすることができます。 - -## Renoteができない -フォロワー限定のノートはRenoteすることはできません。 - -## UI上で特定の要素が表示されない -広告ブロッカーを使用しているとそのような不具合が発生することがあります。Misskeyではオフにしてご利用ください。 - -## UI上で未翻訳の部分がある -ほとんどの場合、単に翻訳が間に合っていないだけで、不具合ではありません。翻訳が終わるまでお待ちください。 [翻訳に参加](./misskey)していただくことも可能です。 diff --git a/src/docs/id-ID/keyboard-shortcut.md b/src/docs/id-ID/keyboard-shortcut.md deleted file mode 100644 index 5320785a6..000000000 --- a/src/docs/id-ID/keyboard-shortcut.md +++ /dev/null @@ -1,68 +0,0 @@ -# キーボードショートカット - -## Global -Pintasan yang terdaftar di sini pada dasarnya bisa digunakan di mana pun. - - - - - - - - - - - -
Pintasan効果由来
P, NKiriman baruPost, New, Note
Tタイムラインの最も新しい投稿にフォーカスTimeline, Top
Shift + NTampilkan/sembunyikan pemberitahuanNotifications
SPenelusuranSearch
H, ?Tampilkan bantuanHelp
- -## 投稿にフォーカスされた状態 - - - - - - - - - - - - - - - - - - - -
Pintasan効果由来
, K, Shift + Tab上の投稿にフォーカスを移動-
, J, Tab下の投稿にフォーカスを移動-
R返信フォームを開くReply
QRenoteフォームを開くQuote
Ctrl + Q即刻Renoteする(フォームを開かずに)-
E, A, +リアクションフォームを開くEmote, reAction
0~9数字に対応したリアクションをする(対応については後述)-
F, Bお気に入りに登録Favorite, Bookmark
Del, Ctrl + DHapus kirimanDelete
M, O投稿に対するメニューを開くMore, Other
SCWで隠された部分を表示 or 隠すShow, See
Escフォーカスを外す-
- -## Renoteフォーム - - - - - - - - - - -
Pintasan効果由来
EnterRenoteする-
Qフォームを展開するQuote
Escフォームを閉じる-
- -## リアクションフォーム -デフォルトで「👍」にフォーカスが当たっている状態です。 - - - - - - - - - - - - - -
Pintasan効果由来
, K上のリアクションにフォーカスを移動-
, J下のリアクションにフォーカスを移動-
, H, Shift + Tab左のリアクションにフォーカスを移動-
, L, Tab右のリアクションにフォーカスを移動-
Enter, Space, +リアクション確定-
0~9数字に対応したリアクションで確定-
Escリアクションするのをやめる-
diff --git a/src/docs/id-ID/mfm.md b/src/docs/id-ID/mfm.md deleted file mode 100644 index e237287ac..000000000 --- a/src/docs/id-ID/mfm.md +++ /dev/null @@ -1,2 +0,0 @@ -# MFM -MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます。 diff --git a/src/docs/id-ID/mute.md b/src/docs/id-ID/mute.md deleted file mode 100644 index 179b92164..000000000 --- a/src/docs/id-ID/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# Bisukan - -Apabila membisukan seorang pengguna, konten berikut yang berkaitan dengan pengguna tersebut tidak akan ditampilkan lagi di Misskey. - -* Kiriman pengguna pada linimasa atau hasil penelusuran (termasuk Renote atau balasan yang terkait dengan kiriman tersebut) -* Pemberitahuan dari pengguna tersebut -* Riwayat obrolan dengan pengguna tersebut di daftar riwayat obrolan - -Untuk membisukan seorang pengguna, tekan tombol "Bisukan" yang ada di laman profil pengguna tersebut. - -Pengguna yang dibisukan tidak akan diberitahu bahwa ia telah dibisukan, dan juga tidak akan tahu siapa yang membisukannya. - -Untuk megkonfirmasi daftar pengguna yang telah dibisukan, bisa lihat di pengaturan dengan menuju Pengaturan > Bisu / Blok. diff --git a/src/docs/id-ID/pages.md b/src/docs/id-ID/pages.md deleted file mode 100644 index e6e718f1e..000000000 --- a/src/docs/id-ID/pages.md +++ /dev/null @@ -1,14 +0,0 @@ -# Laman - -## Variabel -Kamu bisa buat laman dinamis menggunakan variabel. Dengan menulis { nama-variabel } di teksmu, nilai variabel tersebut bisa disematkan.Contohnya, jika nilai suatu variabel thing di dalam teks Hello {thing} world! adalah ai, maka teksnya akan berubah menjadi Hello ai world! - -Variabel dievaluasi dari atas ke bawah, makanya tidak mungkin merujuk variabel sebelum dideklarasikan.Contohnya, saat mendeklarasikan tiga variable A, B, C dalam urutan seperti itu, merujuk A atau B dari dalam C itu mungkin, tapi merujuk B atau C dari dalam A<0> tidak.

- -

- ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。 -

- -

- 関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。 -

diff --git a/src/docs/id-ID/reaction.md b/src/docs/id-ID/reaction.md deleted file mode 100644 index 79952a7b0..000000000 --- a/src/docs/id-ID/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# Reaksi -他の人のノートに、絵文字を付けて簡単にあなたの反応を伝えられる機能です。 リアクションするには、ノートの + アイコンをクリックしてピッカーを表示し、絵文字を選択します。 リアクションには[カスタム絵文字](./custom-emoji)も使用できます。 - -## リアクションピッカーのカスタマイズ -ピッカーに表示される絵文字を自分好みにカスタマイズすることができます。 設定の「リアクション」で設定します。 - -## リモート投稿へのリアクションについて -リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。 また、相手がMisskeyであったとしても、カスタム絵文字リアクションは伝わらず、自動的に「👍」等にフォールバックされます。 - -## リモートからのリアクションについて -リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。 diff --git a/src/docs/id-ID/reversi-bot.md b/src/docs/id-ID/reversi-bot.md deleted file mode 100644 index 3325ab849..000000000 --- a/src/docs/id-ID/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# Pengembangan Bot Reversi Misskey -Laman ini akan menjelaskan bagaimana caranya mengembangkan bot untuk fungsi Reversi Misskey. - -1. `games/reversi`ストリームに以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - -2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる - * イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている - -3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する - -4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - * `game`: `game`の`id` - -5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う - -6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する - -7. ゲームが開始すると、`started`イベントが流れてくる - * イベントの中身にはゲーム情報が含まれている - -8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述) - -9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる - * `color`として石の色が含まれている - * `pos`として位置情報が含まれている - -## 位置の計算法 -8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### X,Y座標 から インデックス に変換する -``` -pos = x + (y * mapWidth) -``` -`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます: -``` -mapWidth = map[0].length -``` - -### インデックス から X,Y座標 に変換する -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## マップ情報 -マップ情報は、ゲーム情報の`map`に入っています。 文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 それをもとにマップのデザインを知る事が出来ます: -* `(スペース)` ... マス無し -* `-` ... マス -* `b` ... 初期配置される黒石 -* `w` ... 初期配置される白石 - -例えば、4*4の次のような単純なマップがあるとします: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -この場合、マップデータはこのようになります: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## ユーザーにフォームを提示して対話可能Botを作成する -ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。 - -フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します: -```javascript -{ - type: 'init-form', - body: [フォームコントロールの配列] -} -``` - -フォームコントロールの配列については今から説明します。 フォームコントロールは、次のようなオブジェクトです: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... コントロールのID。 `type` ... コントロールの種類。後述します。 `label` ... コントロールと一緒に表記するテキスト。 `value` ... コントロールのデフォルト値。 - -### フォームの操作を受け取る -ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### フォームコントロールの種類 -#### Beralih -type: `switch` スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。 - -##### プロパティ -`label` ... スイッチに表記するテキスト。 - -#### ラジオボタン -type: `radio` ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。 - -##### プロパティ -`items` ... ラジオボタンの選択肢。例: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '強', - value: 3 -}] -``` - -#### スライダー -type: `slider` スライダーを表示します。 - -##### プロパティ -`min` ... スライダーの下限。 `max` ... スライダーの上限。 `step` ... 入力欄で刻むステップ値。 - -#### テキストボックス -type: `textbox` テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。 - -## ユーザーにメッセージを表示する -設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 メッセージを表示するには、次のメッセージをストリームに送信します: -```javascript -{ - type: 'message', - body: { - text: 'メッセージ内容', - type: 'メッセージの種類' - } -} -``` -メッセージの種類: `success`, `info`, `warning`, `error`。 - -## 投了する -投了をするには、このエンドポイントにリクエストします。 diff --git a/src/docs/id-ID/stream.md b/src/docs/id-ID/stream.md deleted file mode 100644 index f69299f6e..000000000 --- a/src/docs/id-ID/stream.md +++ /dev/null @@ -1,354 +0,0 @@ -# ストリーミングAPI - -ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。 - -## ストリームに接続する - -ストリーミングAPIを利用するには、まずMisskeyサーバーに**websocket**接続する必要があります。 - -以下のURLに、`i`というパラメータ名で認証情報を含めて、websocket接続してください。例: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。 - -
-

認証情報の取得については、こちらのドキュメントをご確認ください。

-
- ---- - -認証情報は省略することもできますが、その場合非ログインでの利用ということになり、受信できる情報や可能な操作は限られます。例: - -``` -%WS_URL%/streaming -``` - ---- - -ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。 - -**ストリームでのやり取りはすべてJSONです。** - -## Kanal -MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。 - -### チャンネルに接続する -チャンネルに接続するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -ここで、 -* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。 -* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。 -* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。 - -
-

IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。

-
- -### チャンネルからのメッセージを受け取る -例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。 - -チャンネルがメッセージを発すると、次のようなデータがJSONでストリームに流れてきます: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。 -* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。 -* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。 - -### チャンネルに向けてメッセージを送信する -チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。 - -チャンネルにメッセージを送信するには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。 -* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。 -* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。 - -### チャンネルから切断する -チャンネルから切断するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。 - -## ストリームを経由してAPIリクエストする - -ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。 - -ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -ここで、 -* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 -* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 -* `data`には、エンドポイントのパラメータを含めます。 - -
-

APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。

-
- -### レスポンスの受信 - -APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。 - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -ここで、 -* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 -* `body`には、レスポンスが含まれています。 - -## 投稿のキャプチャ - -Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。 - -例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。 - -しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。 - -この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。 - -### 投稿をキャプチャする - -投稿をキャプチャするには、ストリームに次のようなメッセージを送信します: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャしたい投稿の`id`を設定します。 - -このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 - -例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -ここで、 -* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。 -* `body`内の`type`に、イベントの種類が設定されます。 -* `body`内の`body`に、イベントの詳細が設定されます。 - -#### イベントの種類 - -##### `reacted` -その投稿にリアクションがされた時に発生します。 - -* `reaction`に、リアクションの種類が設定されます。 -* `userId`に、リアクションを行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -その投稿が削除された時に発生します。 - -* `deletedAt`に、削除日時が設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -その投稿に添付されたアンケートに投票された時に発生します。 - -* `choice`に、選択肢IDが設定されます。 -* `userId`に、投票を行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### 投稿のキャプチャを解除する - -その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。 - -次のメッセージを送信します: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャを解除したい投稿の`id`を設定します。 - -このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 - -# チャンネル一覧 -## `main` -アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `renote` -自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。 - -#### `mention` -誰かからメンションされたときに発生するイベントです。 - -#### `readAllNotifications` -自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。 - -#### `meUpdated` -自分の情報が更新されたことを表すイベントです。 - -#### `follow` -自分が誰かをフォローしたときに発生するイベントです。 - -#### `unfollow` -自分が誰かのフォローを解除したときに発生するイベントです。 - -#### `followed` -自分が誰かにフォローされたときに発生するイベントです。 - -## `homeTimeline` -ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -タイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `localTimeline` -ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `hybridTimeline` -ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ソーシャルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `globalTimeline` -グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 diff --git a/src/docs/id-ID/theme.md b/src/docs/id-ID/theme.md deleted file mode 100644 index 6e3e300ce..000000000 --- a/src/docs/id-ID/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# Tema - -Kamu bisa mengubah tampilan klien Misskey dengan mengatur temanya. - -## Pengaturan tema -Pengaturan > Tema - -## Membuat tema -テーマコードはJSON5で記述されたテーマオブジェクトです。 テーマは以下のようなオブジェクトです。 -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... ID tema unik.Dianjurkan menggunakan UUID. -* `name` ... Nama tema -* `author` ... Pembuat tema -* `desc` ... Deskripsi tema (opsional) -* `base` ... Apakah tema cerah, ataukah tema gelap - * Jika `light` maka akan terdaftar sebagai tema mode cerah, jika `dark` maka akan terdaftar sebagai tema mode gelap. - * テーマはここで設定されたベーステーマを継承します。 -* `props` ... Definisi gaya tema.Akan dijelaskan sebagai berikut. - -### Definisi gaya tema -`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 - -#### バリューで使える構文 -* 16進数で表された色 - * 例: `#00ff00` -* `rgb(r, g, b)`形式で表された色 - * 例: `rgb(0, 255, 0)` -* `rgb(r, g, b, a)`形式で表された透明度を含む色 - * 例: `rgba(0, 255, 0, 0.5)` -* 他のキーの値の参照 - * `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。 - * 例: `@panel` -* 定数(後述)の参照 - * `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。 - * 例: `$main` -* 関数(後述) - * `:{関数名}<{引数}<{色}` - -#### Konstanta -「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 キー名を`$`で始めると、そのキーはCSS変数として出力されません。 - -#### Fungsi -wip diff --git a/src/docs/id-ID/timelines.md b/src/docs/id-ID/timelines.md deleted file mode 100644 index af08d248c..000000000 --- a/src/docs/id-ID/timelines.md +++ /dev/null @@ -1,15 +0,0 @@ -# Perbandingan Linimasa - -https://docs.google.com/spreadsheets/d/1lxQ2ugKrhz58Bg96HTDK_2F98BUritkMyIiBkOByjHA/edit?usp=sharing - -## Beranda -Postingan dari pengguna yang kamu ikuti - -## Lokal -Seluruh postingan dari pengguna lokal yang tidak ditandai sebagai "Hanya Beranda" - -## Sosial -Postingan dari pengguna yang kamu ikuti beserta dengan semua postingan dari pengguna lokal yang tidak ditandai sebagai "Hanya Beranda" - -## Global -Seluruh postingan dari pengguna lokal yang tidak ditandai sebagai "Hanya Beranda" dan juga pesan yang diterima oleh server yang tidak ditandai sebagai "Hanya Beranda" diff --git a/src/docs/it-IT/admin/disable-timelines.md b/src/docs/it-IT/admin/disable-timelines.md deleted file mode 100644 index b081e35ab..000000000 --- a/src/docs/it-IT/admin/disable-timelines.md +++ /dev/null @@ -1,8 +0,0 @@ -# LTL/STL/GTLの無効化 -Misskeyでは、LTL/STL/GTLをそれぞれ無効化することができます。有効/無効を切り替えるには、インスタンスコントロールパネルで設定します。 - -LTLやSTLは、そのインスタンス全員の投稿が見れるため、新規のユーザーにとってはユーザーを探す必要がなくなり、興味のあるユーザーを見つけやすいという利点があります。 しかし同時に、フォロー機能が活用されなくなったり、不適切な投稿が目につきやすくなったり、チャットのようになることで内輪感が生じて逆に新規ユーザーが参加しにくくなるといったデメリットも持ち合わせています。 サーバーによってメリット/デメリットどちらが優勢かは異なるので、オプションとして無効にできるようになっています。 もしデメリットの方が上回っていると感じたら、それらのタイムラインを無効化することも検討してください。 - -
⚠️ 無効化を行うと、ユーザーが困惑し、短期的に見て利用者が減る可能性があります。そのため、無効化の際は影響を慎重に検討し、事前に説明してフォローを整える期間を一定程度設けることを推奨します。
- -なお、管理者/モデレーターは、これらのタイムラインの無効化状態は適用されず、引き続き利用することが可能です。 diff --git a/src/docs/it-IT/admin/faq.md b/src/docs/it-IT/admin/faq.md deleted file mode 100644 index 317b4e065..000000000 --- a/src/docs/it-IT/admin/faq.md +++ /dev/null @@ -1,5 +0,0 @@ -# よくある質問 -ここでは、サーバー管理者向けのよくある質問を掲載しています。 - -## デフォルトテーマを設定したい -現在、デフォルトテーマ設定機能は実装されていません。 diff --git a/src/docs/it-IT/advanced/aiscript.md b/src/docs/it-IT/advanced/aiscript.md deleted file mode 100644 index 604d17daa..000000000 --- a/src/docs/it-IT/advanced/aiscript.md +++ /dev/null @@ -1,7 +0,0 @@ -# AiScript -AiScriptは、Misskeyで使用できるスクリプト言語です。 - -
ℹ️ AiScript実装はMisskeyとは別リポジトリで、オープンソースで公開されています。
- -## 使い方 -AiScriptの構文や組み込み関数などのドキュメントは、[こちら](https://github.com/syuilo/aiscript/tree/master/docs)で公開されています。 diff --git a/src/docs/it-IT/advanced/api.md b/src/docs/it-IT/advanced/api.md deleted file mode 100644 index 76019b614..000000000 --- a/src/docs/it-IT/advanced/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス、Bot等(以下「アプリケーション」と呼びます)を開発できます。 ストリーミングAPIもあるので、リアルタイム性のあるアプリケーションを作ることも可能です。 - -APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。 - -## アクセストークンの取得 -基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。 - -* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む -* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む - -### 自分自身のアクセストークンを手動発行する -「設定 > API」で、自分のアクセストークンを発行できます。 - -[「APIの使い方」へ進む](#APIの使い方) - -### アプリケーション利用者にアクセストークンの発行をリクエストする -アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。 - -#### Step 1 - -UUIDを生成する。以後これをセッションIDと呼びます。 - -> このセッションIDは毎回生成し、使いまわさないようにしてください。 - -#### Step 2 - -`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。 -> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます: -* `name` ... アプリケーション名 - * > 例: `MissDeck` -* `icon` ... アプリケーションのアイコン画像URL - * > 例: `https://missdeck.example.com/icon.png` -* `callback` ... 認証が終わった後にリダイレクトするURL - * > 例: `https://missdeck.example.com/callback` - * リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます -* `permission` ... アプリケーションが要求する権限 - * > 例: `write:notes,write:following,read:drive` - * 要求する権限を`,`で区切って列挙します - * どのような権限があるかは[APIリファレンス](/api-doc)で確認できます - -#### Step 3 -ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。 - -レスポンスに含まれるプロパティ: -* `token` ... ユーザーのアクセストークン -* `user` ... ユーザーの情報 - -[「APIの使い方」へ進む](#APIの使い方) - -## APIの使い方 -**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。 - -* [APIリファレンス](/api-doc) -* [ストリーミングAPI](./stream) diff --git a/src/docs/it-IT/advanced/create-plugin.md b/src/docs/it-IT/advanced/create-plugin.md deleted file mode 100644 index a263408fc..000000000 --- a/src/docs/it-IT/advanced/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# プラグインの作成 -Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。 - -## Metadato -プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。 - -### name -プラグイン名 - -### author -プラグイン作者 - -### version -プラグインバージョン。数値を指定してください。 - -### description -プラグインの説明 - -### permissions -プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。 - -### config -プラグインの設定情報を表すオブジェクト。 キーに設定名、値に以下のプロパティを含めます。 - -#### type -設定値の種類を表す文字列。以下から選択します。 string number boolean - -#### label -ユーザーに表示する設定名 - -#### description -設定の説明 - -#### default -設定のデフォルト値 - -## APIリファレンス -AiScript標準で組み込まれているAPIは掲載しません。 - -### Mk:dialog(title text type) -ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。 - -### Mk:confirm(title text type) -確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。 - -### Mk:api(endpoint params) -Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。 - -### Mk:save(key value) -任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。 - -### Mk:load(key) -Mk:saveで永続化した指定の名前の値を読み取ります。 - -### Plugin:register_post_form_action(title fn) -投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。 - -### Plugin:register_note_action(title fn) -ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 - -### Plugin:register_user_action(title fn) -ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。 - -### Plugin:register_note_view_interruptor(fn) -UIに表示されるノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:register_note_post_interruptor(fn) -ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:open_url(url) -第一引数に渡されたURLをブラウザの新しいタブで開きます。 - -### Plugin:config -プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。 diff --git a/src/docs/it-IT/advanced/develop-bot.md b/src/docs/it-IT/advanced/develop-bot.md deleted file mode 100644 index 7f825e9bc..000000000 --- a/src/docs/it-IT/advanced/develop-bot.md +++ /dev/null @@ -1,6 +0,0 @@ -# Botの作成 -[Misskey API](./api)を利用してBotの開発が可能です。 また、いくつかのBot実装が公開されているため、ぜひ参考にしてください。 - -- [syuilo/ai](https://github.com/syuilo/ai) ... Node.js上で動く、TypeScript製Bot実装 - -Botを作成したときは、プロフィール設定からBotフラグをオンにしておくことを強くおすすめします。 diff --git a/src/docs/it-IT/advanced/reversi-bot.md b/src/docs/it-IT/advanced/reversi-bot.md deleted file mode 100644 index 00d4a18a8..000000000 --- a/src/docs/it-IT/advanced/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# MisskeyリバーシBotの開発 -Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。 - -1. `games/reversi`ストリームに以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - -2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる - * イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている - -3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する - -4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - * `game`: `game`の`id` - -5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う - -6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する - -7. ゲームが開始すると、`started`イベントが流れてくる - * イベントの中身にはゲーム情報が含まれている - -8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述) - -9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる - * `color`として石の色が含まれている - * `pos`として位置情報が含まれている - -## 位置の計算法 -8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### X,Y座標 から インデックス に変換する -``` -pos = x + (y * mapWidth) -``` -`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます: -``` -mapWidth = map[0].length -``` - -### インデックス から X,Y座標 に変換する -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## マップ情報 -マップ情報は、ゲーム情報の`map`に入っています。 文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 それをもとにマップのデザインを知る事が出来ます: -* `(スペース)` ... マス無し -* `-` ... マス -* `b` ... 初期配置される黒石 -* `w` ... 初期配置される白石 - -例えば、4*4の次のような単純なマップがあるとします: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -この場合、マップデータはこのようになります: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## ユーザーにフォームを提示して対話可能Botを作成する -ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。 - -フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します: -```javascript -{ - type: 'init-form', - body: [フォームコントロールの配列] -} -``` - -フォームコントロールの配列については今から説明します。 フォームコントロールは、次のようなオブジェクトです: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... コントロールのID。 `type` ... コントロールの種類。後述します。 `label` ... コントロールと一緒に表記するテキスト。 `value` ... コントロールのデフォルト値。 - -### フォームの操作を受け取る -ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### フォームコントロールの種類 -#### Interruttore -type: `switch` スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。 - -##### プロパティ -`label` ... スイッチに表記するテキスト。 - -#### ラジオボタン -type: `radio` ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。 - -##### プロパティ -`items` ... ラジオボタンの選択肢。例: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '強', - value: 3 -}] -``` - -#### スライダー -type: `slider` スライダーを表示します。 - -##### プロパティ -`min` ... スライダーの下限。 `max` ... スライダーの上限。 `step` ... 入力欄で刻むステップ値。 - -#### テキストボックス -type: `textbox` テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。 - -## ユーザーにメッセージを表示する -設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 メッセージを表示するには、次のメッセージをストリームに送信します: -```javascript -{ - type: 'message', - body: { - text: 'メッセージ内容', - type: 'メッセージの種類' - } -} -``` -メッセージの種類: `success`, `info`, `warning`, `error`。 - -## 投了する -投了をするには、このエンドポイントにリクエストします。 diff --git a/src/docs/it-IT/advanced/share-page.md b/src/docs/it-IT/advanced/share-page.md deleted file mode 100644 index bf6b2c8b4..000000000 --- a/src/docs/it-IT/advanced/share-page.md +++ /dev/null @@ -1,54 +0,0 @@ -# シェアページ -`/share`を開くと、共有用の投稿フォームを開くことができます。 ここではシェアページで利用できるクエリ文字列の一覧を示します。 - -## クエリ文字列一覧 -### Testo - -
-
title
-
タイトルです。本文の先頭に[ … ]と挿入されます。
-
text
-
本文です。
-
url
-
URLです。末尾に挿入されます。
-
- -### リプライ情報 -以下のいずれか - -
-
replyId
-
リプライ先のノートid
-
replyUri
-
リプライ先のUrl(リモートのノートオブジェクトを指定)
-
- -### Renote情報 -以下のいずれか - -
-
renoteId
-
Renote先のノートid
-
renoteUri
-
Renote先のUrl(リモートのノートオブジェクトを指定)
-
- -### Visibilità -※specifiedに相当する値はvisibility=specifiedとvisibleAccts/visibleUserIdsで指定する - -
-
visibility
-
公開範囲 ['public' | 'home' | 'followers' | 'specified']
-
localOnly
-
0(false) or 1(true)
-
visibleUserIds
-
specified時のダイレクト先のユーザーid カンマ区切りで
-
visibleAccts
-
specified時のダイレクト先のacct(@?username[@host]) カンマ区切りで
-
- -### Allegati -
-
fileIds
-
添付したいファイルのid(カンマ区切りで)
-
diff --git a/src/docs/it-IT/advanced/stream.md b/src/docs/it-IT/advanced/stream.md deleted file mode 100644 index 025eb41de..000000000 --- a/src/docs/it-IT/advanced/stream.md +++ /dev/null @@ -1,350 +0,0 @@ -# ストリーミングAPI - -ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。 - -## ストリームに接続する - -ストリーミングAPIを利用するには、まずMisskeyサーバーに**websocket**接続する必要があります。 - -以下のURLに、`i`というパラメータ名で認証情報を含めて、websocket接続してください。例: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。 - -
ℹ️ 認証情報の取得については、こちらのドキュメントをご確認ください。
- ---- - -認証情報は省略することもできますが、その場合非ログインでの利用ということになり、受信できる情報や可能な操作は限られます。例: - -``` -%WS_URL%/streaming -``` - ---- - -ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。 - -**ストリームでのやり取りはすべてJSONです。** - -## Canale -MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。 - -ひとつのストリーム上で、同時に複数のチャンネルに接続することができます。 - -### チャンネルに接続する -チャンネルに接続するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -ここで、 -* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。 -* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。 -* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。 - -
ℹ️ IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。
- -### チャンネルからのメッセージを受け取る -例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。 - -チャンネルがメッセージを発すると、次のようなデータがJSONでストリームに流れてきます: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。 -* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。 -* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。 - -### チャンネルに向けてメッセージを送信する -チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。 - -チャンネルにメッセージを送信するには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。 -* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。 -* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。 - -### チャンネルから切断する -チャンネルから切断するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。 - -## ストリームを経由してAPIリクエストする - -ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。 - -ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -ここで、 -* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 -* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 -* `data`には、エンドポイントのパラメータを含めます。 - -
ℹ️ APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。
- -### レスポンスの受信 - -APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。 - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -ここで、 -* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 -* `body`には、レスポンスが含まれています。 - -## 投稿のキャプチャ - -Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。 - -例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。 - -しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。 - -この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。 - -### 投稿をキャプチャする - -投稿をキャプチャするには、ストリームに次のようなメッセージを送信します: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャしたい投稿の`id`を設定します。 - -このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 - -例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -ここで、 -* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。 -* `body`内の`type`に、イベントの種類が設定されます。 -* `body`内の`body`に、イベントの詳細が設定されます。 - -#### イベントの種類 - -##### `reacted` -その投稿にリアクションがされた時に発生します。 - -* `reaction`に、リアクションの種類が設定されます。 -* `userId`に、リアクションを行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -その投稿が削除された時に発生します。 - -* `deletedAt`に、削除日時が設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -その投稿に添付されたアンケートに投票された時に発生します。 - -* `choice`に、選択肢IDが設定されます。 -* `userId`に、投票を行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### 投稿のキャプチャを解除する - -その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。 - -次のメッセージを送信します: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャを解除したい投稿の`id`を設定します。 - -このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 - -# チャンネル一覧 -## `main` -アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `renote` -自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。 - -#### `mention` -誰かからメンションされたときに発生するイベントです。 - -#### `readAllNotifications` -自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。 - -#### `meUpdated` -自分の情報が更新されたことを表すイベントです。 - -#### `follow` -自分が誰かをフォローしたときに発生するイベントです。 - -#### `unfollow` -自分が誰かのフォローを解除したときに発生するイベントです。 - -#### `followed` -自分が誰かにフォローされたときに発生するイベントです。 - -## `homeTimeline` -ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -タイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `localTimeline` -ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `hybridTimeline` -ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ソーシャルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `globalTimeline` -グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 diff --git a/src/docs/it-IT/aiscript.md b/src/docs/it-IT/aiscript.md deleted file mode 100644 index c016cb324..000000000 --- a/src/docs/it-IT/aiscript.md +++ /dev/null @@ -1,4 +0,0 @@ -# AiScript - -## Funzione -デフォルトで値渡しです。 diff --git a/src/docs/it-IT/api.md b/src/docs/it-IT/api.md deleted file mode 100644 index 76019b614..000000000 --- a/src/docs/it-IT/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス、Bot等(以下「アプリケーション」と呼びます)を開発できます。 ストリーミングAPIもあるので、リアルタイム性のあるアプリケーションを作ることも可能です。 - -APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。 - -## アクセストークンの取得 -基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。 - -* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む -* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む - -### 自分自身のアクセストークンを手動発行する -「設定 > API」で、自分のアクセストークンを発行できます。 - -[「APIの使い方」へ進む](#APIの使い方) - -### アプリケーション利用者にアクセストークンの発行をリクエストする -アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。 - -#### Step 1 - -UUIDを生成する。以後これをセッションIDと呼びます。 - -> このセッションIDは毎回生成し、使いまわさないようにしてください。 - -#### Step 2 - -`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。 -> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます: -* `name` ... アプリケーション名 - * > 例: `MissDeck` -* `icon` ... アプリケーションのアイコン画像URL - * > 例: `https://missdeck.example.com/icon.png` -* `callback` ... 認証が終わった後にリダイレクトするURL - * > 例: `https://missdeck.example.com/callback` - * リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます -* `permission` ... アプリケーションが要求する権限 - * > 例: `write:notes,write:following,read:drive` - * 要求する権限を`,`で区切って列挙します - * どのような権限があるかは[APIリファレンス](/api-doc)で確認できます - -#### Step 3 -ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。 - -レスポンスに含まれるプロパティ: -* `token` ... ユーザーのアクセストークン -* `user` ... ユーザーの情報 - -[「APIの使い方」へ進む](#APIの使い方) - -## APIの使い方 -**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。 - -* [APIリファレンス](/api-doc) -* [ストリーミングAPI](./stream) diff --git a/src/docs/it-IT/create-plugin.md b/src/docs/it-IT/create-plugin.md deleted file mode 100644 index a263408fc..000000000 --- a/src/docs/it-IT/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# プラグインの作成 -Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。 - -## Metadato -プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。 - -### name -プラグイン名 - -### author -プラグイン作者 - -### version -プラグインバージョン。数値を指定してください。 - -### description -プラグインの説明 - -### permissions -プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。 - -### config -プラグインの設定情報を表すオブジェクト。 キーに設定名、値に以下のプロパティを含めます。 - -#### type -設定値の種類を表す文字列。以下から選択します。 string number boolean - -#### label -ユーザーに表示する設定名 - -#### description -設定の説明 - -#### default -設定のデフォルト値 - -## APIリファレンス -AiScript標準で組み込まれているAPIは掲載しません。 - -### Mk:dialog(title text type) -ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。 - -### Mk:confirm(title text type) -確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。 - -### Mk:api(endpoint params) -Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。 - -### Mk:save(key value) -任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。 - -### Mk:load(key) -Mk:saveで永続化した指定の名前の値を読み取ります。 - -### Plugin:register_post_form_action(title fn) -投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。 - -### Plugin:register_note_action(title fn) -ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 - -### Plugin:register_user_action(title fn) -ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。 - -### Plugin:register_note_view_interruptor(fn) -UIに表示されるノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:register_note_post_interruptor(fn) -ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:open_url(url) -第一引数に渡されたURLをブラウザの新しいタブで開きます。 - -### Plugin:config -プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。 diff --git a/src/docs/it-IT/custom-emoji.md b/src/docs/it-IT/custom-emoji.md deleted file mode 100644 index 900f115d3..000000000 --- a/src/docs/it-IT/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# Emoji personalizzati -Gli emoji personalizzati sono una funzionalità che ti permette di usare delle immagini preparate dalla tua istanza come emoji. Si possono usare in note, reazioni, chat, nella biografia di profilo, nel tuo nome, e altrove su Misskey. Per usare gli emoji personalizzati, puoi aprire la tastiera emoji (quando c'è), oppure visualizzare suggerimenti emoji scrivendo `:`. Quando una sequenza di caratteri del tipo `:foo:` è trovata in un testo, la parte centrale `foo` viene interpretata come un nome di emoji personalizzato e quindi viene sostituita dall'emoji corrispondente. diff --git a/src/docs/it-IT/deck.md b/src/docs/it-IT/deck.md deleted file mode 100644 index cea1c59dc..000000000 --- a/src/docs/it-IT/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# Deck - -Il deck è una delle interfacce utente disponibili.Ti consente di configurare varie colonne fianco a fianco, con molte possibilità di personalizzazione, per ottenere uno schermo più ricco in contenuti. - -## Aggiungere colonne -Puoi aggiungere una colonna facendo un clic destro nello sfondo del deck, poi selezionando "Aggiungi colonna". - -## Spostare colonne -カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。 - -## Dividere colonne in orizzontale -カラムは左右だけでなく、上下に並べることもできます。 カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 上下分割を解除するには、カラムメニューの「右に出す」を選択します。 - -## Impostazioni colonna -Puoi modificare le impostazioni della singola colonna premendo "Modifica" nel menù di colonna. È possibile cambiare il nome e la larghezza della colonna. - -## Impostazioni deck -Puoi trovare le opzioni d'impostazione in [settings/deck](/settings/deck). diff --git a/src/docs/it-IT/features/antenna.md b/src/docs/it-IT/features/antenna.md deleted file mode 100644 index 87424cc12..000000000 --- a/src/docs/it-IT/features/antenna.md +++ /dev/null @@ -1,4 +0,0 @@ -# Antenne -アンテナは、自由に条件を設定して、合致するノートを自動で収集することができる機能です。 - -条件を設定したアンテナが作成された状態で、条件に合致するノートが投稿されると、リアルタイムでそのアンテナのタイムラインにノートが追加されます。 diff --git a/src/docs/it-IT/features/custom-emoji.md b/src/docs/it-IT/features/custom-emoji.md deleted file mode 100644 index 603ac85ad..000000000 --- a/src/docs/it-IT/features/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# Emoji personalizzati -カスタム絵文字は、インスタンスで用意された画像を絵文字のように使える機能です。 ノート、リアクション、チャット、自己紹介、名前などの場所で使うことができます。 カスタム絵文字をそれらの場所で使うには、絵文字ピッカーボタン(ある場合)を押すか、`:`を入力して絵文字サジェストを表示します。 テキスト内に`:foo:`のような形式の文字列が見つかると、`foo`の部分がカスタム絵文字名と解釈され、表示時には対応したカスタム絵文字に置き換わります。 diff --git a/src/docs/it-IT/features/deck.md b/src/docs/it-IT/features/deck.md deleted file mode 100644 index 73e9efdaa..000000000 --- a/src/docs/it-IT/features/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# Deck - -デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。 - -## カラムの追加 -デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。 - -## カラムの移動 -カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。 - -## カラムの水平分割 -カラムは左右だけでなく、上下に並べることもできます。 カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 上下分割を解除するには、カラムメニューの「右に出す」を選択します。 - -## カラムの設定 -カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。 - -## デッキの設定 -デッキに関する設定は、[settings/deck](/settings/deck)で行えます。 diff --git a/src/docs/it-IT/features/drive.md b/src/docs/it-IT/features/drive.md deleted file mode 100644 index c445b99a8..000000000 --- a/src/docs/it-IT/features/drive.md +++ /dev/null @@ -1,17 +0,0 @@ -# Drive -ドライブは、Misskey上でファイルを管理できる機能です。 - -[ドライブのページ](/my/drive)から任意のファイルをアップロードできるほか、アバターに設定した画像や、ノートに添付したファイルなどもすべてドライブにアップロードされます。 - -
⚠️ ドライブからファイルを削除すると、そのファイルが添付されたノートも消えます。
- -ドライブにアップロードされたファイルは、いつでもダウンロードすることができるほか、ノート作成時に「ドライブからファイルを添付」することでファイルを再利用することもできます。 - -ドライブ内にフォルダを作り、複数のファイルをまとめて整理することもできます。 - -## 閲覧注意 (NSFW) -
ℹ️ この項目が閲覧注意なわけではありません
- -閲覧注意またはNSFW (Not safe for work) は、ドライブのファイルに設定することができるフラグです。 閲覧注意フラグを設定されたファイルは、表示される際に閲覧者の操作なしには表示されなくなります。 このフラグは、例えば職場や公共の場で閲覧するのに適切でないと思われる画像などに設定し、そのような画像が突然表示されてしまうことを防ぐ目的で使われます。 - -このフラグは手動でオンオフを切り替えられるほか、モデレーターの判断で設定される場合もあります。 diff --git a/src/docs/it-IT/features/favorite.md b/src/docs/it-IT/features/favorite.md deleted file mode 100644 index 2272dbcc9..000000000 --- a/src/docs/it-IT/features/favorite.md +++ /dev/null @@ -1,4 +0,0 @@ -# Preferiti -[ノート](./node)をお気に入りとして登録できる機能です。 お気に入り登録したノートは、[お気に入りページ](./my/favorites)で一覧することができます。 お気に入りに登録したことは相手に通知されず、お気に入りは自分しか見ることができません。 - -ノートをお気に入り登録するには、ノートメニューの「お気に入り」を押します。お気に入り解除するには、ノートメニューの「お気に入り解除」を押します。 diff --git a/src/docs/it-IT/features/follow.md b/src/docs/it-IT/features/follow.md deleted file mode 100644 index eab673b0c..000000000 --- a/src/docs/it-IT/features/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# Follows -ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。 diff --git a/src/docs/it-IT/features/keyboard-shortcut.md b/src/docs/it-IT/features/keyboard-shortcut.md deleted file mode 100644 index 60533afce..000000000 --- a/src/docs/it-IT/features/keyboard-shortcut.md +++ /dev/null @@ -1,66 +0,0 @@ -# キーボードショートカット - -## Federata -これらのショートカットは基本的にどこでも使えます。 - - - - - - - - - - - -
ショートカット効果由来
P, N新規投稿Post, New, Note
Tタイムラインの最も新しい投稿にフォーカスTimeline, Top
Shift + N通知を表示/隠すNotifications
SCercaSearch
H, ?ヘルプを表示Help
- -## 投稿にフォーカスされた状態 - - - - - - - - - - - - - - - - - - -
ショートカット効果由来
, K, Shift + Tab上の投稿にフォーカスを移動-
, J, Tab下の投稿にフォーカスを移動-
R返信フォームを開くReply
QRenoteフォームを開くQuote
Ctrl + Q即刻Renoteする(フォームを開かずに)-
E, A, +リアクションフォームを開くEmote, reAction
0~9数字に対応したリアクションをする(対応については後述)-
F, Bお気に入りに登録Favorite, Bookmark
Del, Ctrl + D投稿を削除Delete
M, O投稿に対するメニューを開くMore, Other
SCWで隠された部分を表示 or 隠すShow, See
Escフォーカスを外す-
- -## Renoteフォーム - - - - - - - - - -
ショートカット効果由来
EnterRenoteする-
Qフォームを展開するQuote
Escフォームを閉じる-
- -## リアクションフォーム -デフォルトで「👍」にフォーカスが当たっている状態です。 - - - - - - - - - - - - - -
ショートカット効果由来
, K上のリアクションにフォーカスを移動-
, J下のリアクションにフォーカスを移動-
, H, Shift + Tab左のリアクションにフォーカスを移動-
, L, Tab右のリアクションにフォーカスを移動-
Enter, Space, +リアクション確定-
0~9数字に対応したリアクションで確定-
Escリアクションするのをやめる-
diff --git a/src/docs/it-IT/features/mfm.md b/src/docs/it-IT/features/mfm.md deleted file mode 100644 index 5be2df4f3..000000000 --- a/src/docs/it-IT/features/mfm.md +++ /dev/null @@ -1,12 +0,0 @@ -# MFM -MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます。 - -## MFMが使用可能な場所の例 -- ノート本文 -- CW注釈 -- ユーザーの名前 -- ユーザーの自己紹介 - -## 開発者向け情報 -MFMのパーサー実装はライブラリとして公開されており、簡単にクライアントにMFMを組み込むことが可能です。 -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptパーサー実装 diff --git a/src/docs/it-IT/features/mute-and-block.md b/src/docs/it-IT/features/mute-and-block.md deleted file mode 100644 index bf3296602..000000000 --- a/src/docs/it-IT/features/mute-and-block.md +++ /dev/null @@ -1,41 +0,0 @@ -# Silenziati / Bloccati -好みではないユーザーがいる場合は、ミュートを行うことでそのユーザーが自分から見えないようにすることができます。 また、より強力な措置として、ブロックを行うことでそのユーザーから自分のコンテンツが見えないようになるほか、自分に対して関わることができないようにすることができます。 ミュートされていることは相手は分かりませんが、ブロックされていることは相手に分かります。どちらを選ぶかはご自身の判断で行ってください。 - -
ℹ️ ミュートとブロックは併用できます。
- -
⚠️ 利用規約に違反するような、迷惑なユーザーがいる場合は運営者に報告することも検討してください。
- -設定>ミュートとブロック から、自分がミュートまたはブロックしているユーザー一覧を確認することができます。 - -## Silenzia -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -- タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -- そのユーザーからの通知 -- メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 -- など - -ユーザーをミュートするには、対象のユーザーのユーザーページのメニューを開き、「ミュート」ボタンを押します。 - -
ℹ️ ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。
- -## Blocca -ユーザーをブロックすると、そのユーザーからあなたのコンテンツが見えないようになり、またあなたに対して以下のようなアクションをすることができなくなります。 - -- フォローする -- ユーザーリストに追加する -- 返信する、Renoteする -- リアクションする、アンケートに投票する -- メッセージを送信する -- など - -また、 - -- ブロックする際に既にそのユーザーからフォローされていた場合はフォローが解除されます。 -- ブロックする際に既にそのユーザーがあなたをユーザーリストに入れていた場合はそのリストからあなたが削除されます。 - -ユーザーをブロックするには、対象のユーザーのユーザーページのメニューを開き、「ブロック」ボタンを押します。 - -
⚠️ ブロックを行ったこと自体は相手に通知されませんが、フォローを行ったりなどの上記のアクションが行えなくなるので間接的にブロックされていることは分かります。
- -
⚠️ 相手から自分のコンテンツが見えなくなりますが、相手がアカウントを切り替えたりログアウト状態になれば見ることができます。あくまで簡易的、補助的なものとしてお考えください。
diff --git a/src/docs/it-IT/features/mute.md b/src/docs/it-IT/features/mute.md deleted file mode 100644 index a6cb07375..000000000 --- a/src/docs/it-IT/features/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# Silenzia - -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -* タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -* そのユーザーからの通知 -* メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 - -ユーザーをミュートするには、対象のユーザーのユーザーページに表示されている「ミュート」ボタンを押します。 - -ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。 - -設定>ミュート から、自分がミュートしているユーザー一覧を確認することができます。 diff --git a/src/docs/it-IT/features/note.md b/src/docs/it-IT/features/note.md deleted file mode 100644 index f65e33c76..000000000 --- a/src/docs/it-IT/features/note.md +++ /dev/null @@ -1,54 +0,0 @@ -# Note -ノートは、Misskeyに投稿される、文章、ファイル、アンケートなどを含むコンテンツで、Misskeyの中心的概念です。また、そのノートを作成する行為自体もノートと呼ばれます。 - -ノートが作成されると、[タイムライン](./timeline)に追加され、自分の[フォロワー](./follow)やサーバーのユーザーが見れるようになります。 - -ノートには、[リアクション](./reaction)を行うことができます。また、返信や引用もできます。 - -ノートを[お気に入り](./favorite)登録することで、後で簡単に見返すことができます。 - -## ノートを作成する -ノートを作成するには、画面上にある鉛筆マークのボタンを押して、作成フォームを開きます。作成フォームに内容を入力し、「ノート」ボタンを押すことでノートが作成されます。 ノートには、画像、動画など任意のファイルや、[アンケート](./poll)を添付することができます。また、本文中には[MFM](./mfm)が使用でき、[メンション](./mention)や[ハッシュタグ](./hashtag)を含めることもできます。 他にも、CWや公開範囲といった設定も行えます(詳細は後述)。 -
ℹ️ コンピューターのクリップボードに画像データがある状態で、フォーム内のテキストボックスにペーストするとその画像を添付することができます。
-
ℹ️ テキストボックス内でCtrl + Enterを押すことでも投稿できます。
- -## Rinota -既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノートをRenoteと呼びます。 自分がフォローしているユーザーの、気に入ったノートを自分のフォロワーに共有したい場合や、過去の自分のノートを再度共有したい場合に使います。 同じノートに対して無制限にRenoteを行うことができますが、あまり連続して使用すると迷惑になる場合もあるので、注意しましょう。 -
⚠️ 公開範囲がフォロワーやダイレクトのノートはRenoteできません
- -Renoteを削除するには、Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 - -## CW -Contents Warningの略で、ノートの内容を、閲覧者の操作なしには表示しないようにできる機能です。主に長大な内容を隠すためや、ネタバレ防止などに使うことができます。 設定するには、フォームの「内容を隠す」ボタン(目のアイコン)を押します。すると新しい入力エリアが表れるので、そこに内容の要約を記入します。 - -## Visibilità -ノートごとに、そのノートが公開される範囲を設定することができます。フォームの「ノート」ボタンの左にあるアイコンを押すと公開範囲を以下から選択できます。 - -### Pubblica -全ての人に対してノートが公開されるほか、サーバーの全てのタイムライン(ホームタイムライン、ローカルタイムライン、ソーシャルタイムライン、グローバルタイムライン)にノートが流れます。 -
⚠️ アカウントがサイレンス状態の時は、この公開範囲は使用できません。
- -### Home -全ての人に対してノートが公開されますが、フォロワー以外のローカルタイムライン、ソーシャルタイムライン、グローバルタイムラインにはノートは流れません。 - -### Followers -自分のフォロワーに対してのみノートを公開します。フォロワーの全てのタイムラインに流れます。 - -### Diretta -指定したユーザーに対してのみノートを公開します。指定したユーザーの全てのタイムラインに流れます。 - -### 「ローカルのみ」オプション -このオプションを有効にすると、リモートにノートを連合しなくなります。 - -### 公開範囲の比較 - - - - -
PubblicaHomeFollowersDiretta
フォロワーのLTL/STL/GTL
非フォロワーのLTL/STL/GTL
- -## Fissa sul profilo -ノートをピン留めすると、ユーザーページに常にそのノートを表示しておくことができます。 ノートのメニューを開き、「ピン留め」を選択してピン留めできます。 複数のノートをピン留めできます。 - -## Osserva -ノートをウォッチすると、自分以外のノートへのリアクションや返信などの通知を受け取ることができます。 ノートのメニューを開き、「ウォッチ」を選択してウォッチできます。 diff --git a/src/docs/it-IT/features/pages.md b/src/docs/it-IT/features/pages.md deleted file mode 100644 index 81c19dd20..000000000 --- a/src/docs/it-IT/features/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# Pages - -## Variabili -変数を使うことで動的なページを作成できます。テキスト内で { 変数名 } と書くとそこに変数の値を埋め込めます。例えば Hello { thing } world! というテキストで、変数(thing)の値が ai だった場合、テキストは Hello ai world! になります。 - -変数の評価(値を算出すること)は上から下に行われるので、ある変数の中で自分より下の変数を参照することはできません。例えば上から A、B、C と3つの変数を定義したとき、Cの中でABを参照することはできますが、Aの中でBCを参照することはできません。 - -ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。 - -関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。 diff --git a/src/docs/it-IT/features/reaction.md b/src/docs/it-IT/features/reaction.md deleted file mode 100644 index bca8c97d6..000000000 --- a/src/docs/it-IT/features/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# Reazione -他の人のノートに、絵文字を付けて簡単にあなたの反応を伝えられる機能です。 リアクションするには、ノートの + アイコンをクリックしてピッカーを表示し、絵文字を選択します。 リアクションには[カスタム絵文字](./custom-emoji)も使用できます。 - -## リアクションピッカーのカスタマイズ -ピッカーに表示される絵文字を自分好みにカスタマイズすることができます。 設定の「リアクション」で設定します。 - -## リモート投稿へのリアクションについて -リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。 - -## リモートからのリアクションについて -リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。 diff --git a/src/docs/it-IT/features/silence.md b/src/docs/it-IT/features/silence.md deleted file mode 100644 index bcecce5f4..000000000 --- a/src/docs/it-IT/features/silence.md +++ /dev/null @@ -1,6 +0,0 @@ -# Silenzia -サイレンスは、アカウントに設定される状態のひとつです。 - -アカウントがサイレンス状態になると、ノートの公開範囲をパブリックにできなくなります。 ホーム、フォロワー、ダイレクトは選択可能なため、サイレンスを受けた場合でもフォロワーやあなたのユーザーページを直接訪れた場合は投稿を閲覧できますが、GTL(連合タイムライン)やLTL(ローカルタイムライン)には投稿が流れません。 - -アカウントのサイレンス状態は、サーバーのモデレーターによって有効化/無効化されます。 diff --git a/src/docs/it-IT/features/theme.md b/src/docs/it-IT/features/theme.md deleted file mode 100644 index 793babb97..000000000 --- a/src/docs/it-IT/features/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# Tema - -テーマを設定して、Misskeyクライアントの見た目を変更できます。 - -## テーマの設定 -設定 > テーマ - -## テーマを作成する -テーマコードはJSON5で記述されたテーマオブジェクトです。 テーマは以下のようなオブジェクトです。 -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... テーマの一意なID。UUIDをおすすめします。 -* `name` ... テーマ名 -* `author` ... テーマの作者 -* `desc` ... テーマの説明(オプション) -* `base` ... 明るいテーマか、暗いテーマか - * `light`にすると明るいテーマになり、`dark`にすると暗いテーマになります。 - * テーマはここで設定されたベーステーマを継承します。 -* `props` ... テーマのスタイル定義。これから説明します。 - -### テーマのスタイル定義 -`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 - -#### バリューで使える構文 -* 16進数で表された色 - * 例: `#00ff00` -* `rgb(r, g, b)`形式で表された色 - * 例: `rgb(0, 255, 0)` -* `rgb(r, g, b, a)`形式で表された透明度を含む色 - * 例: `rgba(0, 255, 0, 0.5)` -* 他のキーの値の参照 - * `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。 - * 例: `@panel` -* 定数(後述)の参照 - * `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。 - * 例: `$main` -* 関数(後述) - * `:{関数名}<{引数}<{色}` - -#### Costante -「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 キー名を`$`で始めると、そのキーはCSS変数として出力されません。 - -#### Funzione -wip diff --git a/src/docs/it-IT/features/timeline.md b/src/docs/it-IT/features/timeline.md deleted file mode 100644 index 958c414b7..000000000 --- a/src/docs/it-IT/features/timeline.md +++ /dev/null @@ -1,31 +0,0 @@ -# Timeline -タイムラインは、[ノート](./note)が時系列で表示される機能です。 タイムラインには以下で示す種類があり、種類によって表示されるノートも異なります。 なお、タイムラインの種類によってはサーバーにより無効になっている場合があります。 - -## Home -自分のフォローしているユーザーの投稿が流れます。HTLと略されます。 - -## Locale -全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。LTLと略されます。 - -## Sociale -自分のフォローしているユーザーの投稿と、全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。STLと略されます。 - -## Federata -全てのローカルユーザーの「ホーム」指定されていない投稿と、サーバーに届いた全てのリモートユーザーの「ホーム」指定されていない投稿が流れます。GTLと略されます。 - -## Metodo comparativo -| ソース | | | Timeline | | | -| ------------ | ---------- | ---- | -------- | ------- | -------- | -| Utente | Visibilità | Home | Locale | Sociale | Federata | -| ローカル (フォロー) | Pubblico | ✔ | ✔ | ✔ | ✔ | -| | Home | ✔ | | ✔ | | -| | Followers | ✔ | ✔ | ✔ | ✔ | -| リモート (フォロー) | Pubblico | ✔ | | ✔ | ✔ | -| | Home | ✔ | | ✔ | | -| | Followers | ✔ | | ✔ | ✔ | -| ローカル (未フォロー) | Pubblico | | ✔ | ✔ | ✔ | -| | Home | | | | | -| | Followers | | | | | -| リモート (未フォロー) | Pubblico | | | | ✔ | -| | Home | | | | | -| | Followers | | | | | diff --git a/src/docs/it-IT/features/widgets.md b/src/docs/it-IT/features/widgets.md deleted file mode 100644 index 363254503..000000000 --- a/src/docs/it-IT/features/widgets.md +++ /dev/null @@ -1,7 +0,0 @@ -# Widget -ウィジェットは、MisskeyのUI上に設置できる小型の情報表示、操作が行えるパーツです。 - -ウィジェットを編集するには、ウィジェット編集モードに切り替えます。切り替え方法はUIによって異なります。 ウィジェット編集モードでは、ウィジェットの追加、削除、並び替え、およびそれぞれのウィジェットの設定を行えます。 - -## 利用可能なウィジェット一覧 -todo diff --git a/src/docs/it-IT/features/word-mute.md b/src/docs/it-IT/features/word-mute.md deleted file mode 100644 index 3104147f2..000000000 --- a/src/docs/it-IT/features/word-mute.md +++ /dev/null @@ -1,20 +0,0 @@ -# Filtri parole -ワードミュートの設定をすると、条件に合致したノートが表示されなくなります。 - -ワードミュートには、ソフトワードミュートとハードワードミュートの2種類があります。それぞれについて設定の方法と挙動を説明します。 - -## ソフトワードミュート -ソフトワードミュートは、クライアント(アプリ)側でミュートを判断するワードミュートです。 - -ノートが設定した条件に合致すると、「(ユーザー名)が何かを言いました」という表示で隠れます。 -クリックすると元の通りに表示されます。 - -## ハードワードミュート -ハードワードミュートは、アンテナのようにサーバーが新しいノートの本文に対して条件に合致するかどうか判断し、タイムラインから対象となったノートを除外します。 - -つまり、ハードワードミュートには、以下のような特徴があります。 - -* 条件設定後、新しい投稿のみがミュートの対象になります。 -* 条件を変更しても、過去にハードミュートされたノートはミュートされたままになります。 -* 「○○が何かを言いました」でタイムラインが埋まることがありません。 -* ソフトミュートに非対応のアプリでも、ハードミュートは適用されます。 diff --git a/src/docs/it-IT/follow.md b/src/docs/it-IT/follow.md deleted file mode 100644 index c54099a36..000000000 --- a/src/docs/it-IT/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# Follow -Se segui un utente, le sue pubblicazioni verranno mostrate sulla tua timeline. A esclusione delle sue risposte ad altrə utenti. Per seguire un utente, bisogna premere il pulsante "seguire" della sua pagina. Premi una seconda volta sul pulsante per smettere di seguire l'account. diff --git a/src/docs/it-IT/general/apps.md b/src/docs/it-IT/general/apps.md deleted file mode 100644 index 1f4c85fe8..000000000 --- a/src/docs/it-IT/general/apps.md +++ /dev/null @@ -1,6 +0,0 @@ -# サードパーティアプリのリスト -## クライアント -todo - -## 連携サービス -todo diff --git a/src/docs/it-IT/general/changelog.md b/src/docs/it-IT/general/changelog.md deleted file mode 100644 index 6766a63b2..000000000 --- a/src/docs/it-IT/general/changelog.md +++ /dev/null @@ -1,5 +0,0 @@ -# 更新履歴 -
ℹ️ このサーバーの更新履歴です。Misskeyの最新のリリースについては、GitHubをご確認ください。
- - - diff --git a/src/docs/it-IT/general/faq.md b/src/docs/it-IT/general/faq.md deleted file mode 100644 index c272b2ad4..000000000 --- a/src/docs/it-IT/general/faq.md +++ /dev/null @@ -1,28 +0,0 @@ -# よくある質問 -ここでは利用上のよくある質問について掲載しています。 Misskeyのプロジェクト自体についてのよくある質問は[こちら](./misskey)に掲載されています。 - -## iOS/Androidのアプリはありますか? -公式にはそういったOSのネイティブアプリを開発していませんが、サードパーティ製のアプリがいくつかあります。 詳しくは[こちら](./apps)をご覧ください。 - -ただ、サードパーティ製アプリはどうしても機能への対応が遅れてしまうため、とくに拘りがなければ公式のWebクライアントの利用をおすすめします。 なお、MisskeyのWebクライアントはPWAに対応しているので、ネイティブアプリのように動作させることも可能です。 詳しくは[こちら](todo)をご覧ください。 - -## Mastodonクライアントでログインできないのですが? -MisskeyはMastodonのAPIと互換性がないため、一部を除きMastodonクライアントでMisskeyを利用することはできません。 - -## 他のサーバーのユーザーをフォローするときは? -メニューから検索を選び、ユーザー名をホスト込みで入力します。例: `@syuilo@misskey.io` - -## Renoteを削除するには? -Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 Renoteについては[こちら](../features/note)をご確認ください。 - -## URLのプレビューを表示させたくない -MFMには、そのURLのプレビューを無効にする構文があります。詳細は[MFMチートシート](/mfm-cheat-sheet)をご確認ください。 - -## カスタム絵文字を追加したい -運営者のみがカスタム絵文字を追加、編集、削除できます。それらを希望する場合は運営者に依頼してください。 - -## Botを開発したい -Misskey APIを利用してBotの開発が可能です。[こちら](../advanced/develop-bot)をご確認ください。 - -## ノートの翻訳機能はどのサービスを使用していますか? -[DeepL](https://www.deepl.com/)を使用しています。 diff --git a/src/docs/it-IT/general/glossary.md b/src/docs/it-IT/general/glossary.md deleted file mode 100644 index b7ec7bddf..000000000 --- a/src/docs/it-IT/general/glossary.md +++ /dev/null @@ -1,89 +0,0 @@ -# 用語集 -Misskeyに関する用語集です。 - -## ActivityPub -(読み: あくてぃびてぃぱぶ) 分散型を実現するために用いられるプロトコル(仕様)。このプロトコルに則ってサーバー同士通信を行うことで、連合が行われ、Fediverseを形成しています。 - -## AiScript -(読み: あいすくりぷと) Misskey上で使用できるプログラミング言語です。詳細は[こちら。](../advanced/aiscript) - -## API -(読み: えーぴーあい) Misskeyのサーバーが公開している、プログラムからMisskeyを扱うためのインターフェース。詳細は[こちら。](../advanced/api) - -## Bot -(読み: ぼっと) プログラムによって動作しているアカウント。 - -## CW -(読み: こんてんつわーにんぐ) Contents Warningの略。ノートの内容を、操作なしには表示しないようにできる機能。主に長大な内容を隠すためや、ネタバレ防止などに使われます。 - -## Fediverse -(読み: ふぇでぃばーす) Misskeyを含む様々な分散型ソフトウェアのサーバーで構成されたネットワーク。 - -## GTL -グローバルタイムライン(Global TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## HTL -ホームタイムライン(Home TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## LTL -ローカルタイムライン(Local TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## MFM -(読み: えむえふえむ) Misskey Flavored Markdownの略で、Misskey上で使用できるマークアップ言語です。詳細は[こちら。](../features/mfm) - -## NSFW -(読み: のっとせーふふぉーわーく) Not Safe For Workの略。画像を「閲覧注意」扱いにし、操作なしには表示しないようにすることができる機能。 - -## Rinota -(読み: りのーと) 既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノート。詳細は[こちら。](../features/note) - -## STL -ソーシャルタイムライン(Social TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## 藍 -(読み: あい) Misskeyの看板娘(公式キャラクター)です。 - -## アクティブユーザー -インスタンスにアカウントを作っているユーザーのうち、現在も実際にサービスを利用しているユーザーのこと。 - -## Istanza -todo - -## Emoji personalizzati -サーバーで用意された絵文字。カスタム絵文字ではない通常の絵文字は「Unicode絵文字」と区別して呼ばれる。 - -## コントロールパネル -インスタンスの設定画面のこと。 - -## Server -todo - -## Silenzia -ノートをパブリックな公開範囲で投稿できなくされている状態。モデレーターの判断でユーザーごとに設定されます。詳細は[こちら。](../features/silence) - -## Coda di lavoro -アクティビティ配送などを順番に行うためのシステム。 - -## Sospendi -アカウントが使用不可に設定されている状態。 - -## Drive -Misskeyにアップロードしたファイルを管理する機能。詳細は[こちら。](../features/drive) - -## Note -Misskeyに投稿される、文章、ファイル、アンケートなどを含めることができるコンテンツ。詳細は[こちら。](../features/note) - -## ミスキスト -Misskeyを使う人のこと。 - -## Moderatore -スパムの凍結およびサイレンスや不適切な投稿の削除など、コミュニティ運営に関する権限を持つユーザー。 - -## Remoto -他サーバーのことを指します。リモートユーザーといったように接頭辞としても使われます。ローカルの逆です。 - -## Federazione -サーバー上で作成された情報が他のサーバーに伝わること。 - -## Locale -自サーバーのことを指します。ローカルユーザー、ローカルタイムラインといったように接頭辞としても使われます。リモートの逆です。 diff --git a/src/docs/it-IT/general/links.md b/src/docs/it-IT/general/links.md deleted file mode 100644 index 4493bc2d5..000000000 --- a/src/docs/it-IT/general/links.md +++ /dev/null @@ -1,12 +0,0 @@ -# リンク集 - -## Webサイト -- [Official Discord](https://discord.gg/Wp8gVStHW3) - Misskey公式Discordサーバー -- [Misskey Forum](https://forum.misskey.io/) - Misskeyに関する話題を扱うフォーラム - -## Account -- [@repo@misskey.io](https://misskey.io/@repo) - Misskeyのリポジトリの更新を投稿するbot - -## ライブラリ -- [misskey-dev/misskey.js](https://github.com/misskey-dev/misskey.js) - JavaScriptのMisskey SDK -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptのMFMパーサー実装 diff --git a/src/docs/it-IT/general/misskey.md b/src/docs/it-IT/general/misskey.md deleted file mode 100644 index c89ed2837..000000000 --- a/src/docs/it-IT/general/misskey.md +++ /dev/null @@ -1,87 +0,0 @@ -# Informazioni di Misskey - -Misskeyはオープンソースの分散型マイクロブログプラットフォームプロジェクトです。 開発は日本でsyuiloによって2014年から開始されました。 ドライブ、リアクションなどの豊富な機能や、高いカスタマイズ性を備えたUIを持つことが特徴です。 - -## 歴史 -開発当初は掲示板がメインのサービスでしたが、ユーザーが短文を投稿し、それを時系列で流れるタイムライン機能を追加したところ人気が高まり、徐々にそれがメインとして開発が進むようになりました。 当初は分散型ではありませんでしたが、2018年にActivityPubを実装し分散型になったことで、より多くの方に認知され利用されるサービスになり、現在に至ります。 -
ℹ️ Misskeyという名前は、syuiloが当時聴いていたMay'nというアーティストの楽曲、Brain Diverの歌詞に由来します。
- -誰でも開発に参加することができ、現在でも活発に開発が続いています。 - -## 分散型とは何か? - -分散(distributed)型とは、非中央集権(decentralized)とも呼ばれ、コミュニティが多数のサーバーに分散して存在し、それらが相互に通信(連合、federation)することでコンテンツ共有ネットワーク(Fediverse)を形成していることが特徴のサービスです。 単一のサーバーしか存在しない、もしくは複数存在しても互いに独立している場合は中央集権なサービスと言われ、例えばTwitterやFacebookなどほとんどのサービスがそれに該当します。 分散型のメリットは、自分に合った運営者やテーマのサーバーを選択できることです。自分でサーバーを作成することもできます。連合するおかげで、どのサーバーを選んでも、同じコミュニティにアクセスできます。 - -## 常にオープンソース -Misskeyはこれまでもこれからも、オープンソースであり続けます。オープンソースとは、簡単に言うとソフトウェアのソースコード(プログラム)が公開されていることです。ソースコードの修正や再配布が可能であることを定義に含めることもあります。 Misskeyのすべてのソースコードは[AGPL](https://github.com/misskey-dev/misskey/blob/develop/LICENSE)というオープンソースライセンスの下に[公開](https://github.com/misskey-dev)されていて、誰でも自由に閲覧、使用、修正、改変、再配布をすることができます。 オープンソースは、自分で好きなように変えたり、有害な処理が含まれていないことを確認することができたり、誰でも開発に参加できるなどの、様々なメリットがあります。 上述の分散型を実現するためにも、オープンソースであるということは必要不可欠な要素です。 再び引き合いに出しますが、TwitterやFacebookなどの利益を得ているほとんどのサービスはオープンソースではありません。 - -
ℹ️ 技術的に言うと、MisskeyのソースコードはGitで管理されていて、リポジトリはGitHub上でホスティングされています。
- -## 開発に参加する、プロジェクトを支援する -Misskeyを気に入っていただけたら、ぜひプロジェクトを支援してください。プロジェクトに貢献するには、以下で紹介するようにいろいろな方法があります。方法によっては開発のスキルは不要なので、誰でも気軽に参加し貢献することができます。いつでもお待ちしています。 - -### 機能を追加したり、バグを修正する -ソフトウェアエンジニアのスキルをお持ちの方であれば、ソースコードを編集する形でプロジェクトに貢献することができます。 貢献についてのガイドは[こちら](https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md)です。 - -### 議論に参加する -新しい機能、または既存の機能について意見を述べたり、不具合を報告したりすることでも貢献できます。 そのようなディスカッションは[GitHub](https://github.com/misskey-dev)上か、[フォーラム](https://forum.misskey.io/)等で行われます。 - -### テキストを翻訳する -Misskeyは様々な言語に対応しています(i18n -internationalizationの略- と呼ばれます)。元の言語は基本的に日本語ですが、有志によって他の言語へと翻訳されています。 その翻訳作業に加わっていただくことでもMisskeyに貢献できます。 Misskeyは[Crowdinというサービスを使用して翻訳の管理を行っています。](https://crowdin.com/project/misskey) - -### 感想を投稿する -不具合報告等だけではなく、Misskeyの良い点、楽しい点といったポジティブな意見もぜひ共有してください。開発の励みになり、それは間接的ですがプロジェクトへの貢献です。 - -### ミスキストを増やす -ミスキストとは、Misskeyを使用する人のことです。 知り合いに紹介するなどしてMisskeyを広めていただければ、ミスキストが増え開発のモチベーションが上がります。 - -### 寄付をする -Misskeyはビジネスではなく、利用は無料であるため、収益は皆様からの寄付のみです。(インスタンスによっては広告収入を得ているような場合もありますが、それは運営者の収入であり直接開発者への収入にはなりません) 寄付をしていただければ、今後も開発を続けることが可能になり、プロジェクトへの貢献になります。 寄付は基本的には[Patreon](https://www.patreon.com/syuilo)で受け付けています。 一定額寄付していただけると、Misskeyの[情報ページ](/about-misskey)に名前を記載することができます。 - -また、サーバーの運営者も、基本的には収益を得ていません。サーバーの運営にはコストがかかるので、運営者の支援をすることもご検討ください。 開発には直接関係しませんが、サーバーがあってこそのプロジェクトなので、運営が維持されるというのは開発と同じくらい重要なことです。 - -## クレジット -Misskeyの開発者や、Misskeyに寄付をしてくださった方の一覧は[こちら](/about-misskey)で見ることができます。 - -## よくある質問 -### プロジェクトは何を目指していますか? -強いて言うと、漠然的になりますが広く使われる汎用的なプラットフォームになることを目指しています。 Misskeyは他のプロジェクトとは違い、何らかの思想(例えば、反中央集権)やビジョンに基づいて開発が行われているわけではなく、その点ではフラットです。 それが逆に、特定の方向性に縛られないフレキシブルさを生み出すことに繋がっていると感じています。 - - -### 企業によって開発されていますか? -いいえ。Misskeyの開発は個人で行われており、商業的でもないため、特定の企業の関りはありません。 開発メンバーも基本的にはボランティアです。 また、開発に対し企業のスポンサーがつくこともありますが、その場合でもやはり開発は個人のコミュニティが主体です。 - -### 誰が運営していますか? -Misskeyは分散型なため、各サーバーにそれぞれ異なった運営者がいます。従って、特定の個人や企業によって、Misskeyの全てが運営されているわけではありません。 また、開発チームが運営を行うわけでもないため、運営に関する連絡は、お使いのサーバーの運営者に行ってください。 サーバーの運営者は、[このページ](/about)で確認することができます。 あなたがサーバーを作成すれば、あなたが運営者になります。 - -### どのサーバーを選べばいいですか? -[サーバー一覧が公開されています。](https://join.misskey.page/ja-JP/instances) サーバーによってコミュニティのテーマ(特定のこと、ものが好き 等)が決められている場合があるので、自分に合ったテーマのサーバーがあれば、そこを選ぶと良いかもしれません。 他にも、サーバーの規模、ユーザー層、国および言語、運営者が信頼できるかどうか、などの観点があります。 なお、Misskey公式のサーバーというものはありません。自身で新しくサーバーを作成するという選択肢もあります。 - -基本的にどのサーバーを選んだとしても、他の全てのサーバーのユーザーと繋がることができます。 - -### サーバーを建てるにはどうしたらいいですか? -Misskeyサーバーの作成に興味を持っていただきありがとうございます。 2021年現在、Misskeyのホスティングサービスは存在しないため、サーバーの作成にはある程度の知識が必要です。 サーバーの作成方法については[こちら](todo)をご覧ください。 - -### どのような技術を使用していますか? -Misskeyは開発が進むにつれ使用する技術も大きく変わってきました。開発当初はMySQL + PHP + jQueryといった構成でしたが、現在は以下のようになっています。 -- サーバーサイド: Node.js -- データベース: PostgreSQL、Redis -- UIフレームワーク: Vue.js -- プログラミング言語: TypeScript - -また、MFMやAiScriptなどの、Misskeyから派生して独自の技術も開発しています。 - -### Mastodonのフォークですか? -いいえ。MisskeyはMastodonやその他のプロジェクトとは全く別のプロジェクトです。 開発に関しても、Misskeyの方が昔から開発されています。ただし、分散型になったのはMastodonの登場より後です。 同じActivityPubという分散のためのプロトコルを実装しているという点以外、両者に特に関りがあるわけでもありません。 - -### iOS/Androidのアプリはありますか? -公式にはそういったOSのネイティブアプリを開発していませんが、サードパーティ製のアプリがいくつかあります。 詳しくは[こちら](./apps)をご覧ください。 - -ただ、サードパーティ製アプリはどうしても機能への対応が遅れてしまうため、とくに拘りがなければ公式のWebクライアントの利用をおすすめします。 なお、MisskeyのWebクライアントはPWAに対応しているので、ネイティブアプリのように動作させることも可能です。 詳しくは[こちら](todo)をご覧ください。 - -### Misskeyのロゴ、アイコンはどこで入手できますか? -(準備中) - -### 時折目にする猫耳の可愛い女の子は? -Misskeyの守り神、藍ちゃんです。アイチャンカワイイヤッター! -
ℹ️ 藍ちゃんについてはこちらです。
diff --git a/src/docs/it-IT/general/report-issue.md b/src/docs/it-IT/general/report-issue.md deleted file mode 100644 index 63527e32a..000000000 --- a/src/docs/it-IT/general/report-issue.md +++ /dev/null @@ -1,8 +0,0 @@ -# 不具合の報告 -不具合と思われる状況に遭遇したときは、まず[トラブルシューティング](./troubleshooting)をご一読ください。 それでも問題が解決しないときは、以下の情報を含めて[フォーラム](https://forum.misskey.io/)に投稿してください。 投稿することで、解決策が見つかったり、不具合と判断されれば開発チームによって修正が行われます。 - -## 含める情報 -- Misskeyのバージョン([情報ページ](/about)で確認できます) -- お使いのブラウザの種類とバージョン -- お使いのOSの種類とバージョン -- 問題の再現手順 diff --git a/src/docs/it-IT/general/troubleshooting.md b/src/docs/it-IT/general/troubleshooting.md deleted file mode 100644 index c472aeaba..000000000 --- a/src/docs/it-IT/general/troubleshooting.md +++ /dev/null @@ -1,40 +0,0 @@ -# Risoluzione problemi -
ℹ️ よくある質問も合わせてお役立てください。
- -問題が発生したときは、まずこちらをご確認ください。 該当する項目が無い、もしくは手順を試しても効果がない場合は、サーバーの管理者に連絡するか[不具合を報告](./report-issue)してください。 - -## クライアントが起動しない -ほとんどの場合、お使いのブラウザまたはOSのバージョンが古いことが原因です。 ブラウザおよびOSのバージョンを最新のものに更新してから、再度試してみてください。 - -これは稀ですが、それでも起動しない場合は、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。 - -## ページが読み込めない -クライアントが起動するもののページが読み込めないというエラーが出る場合は、ネットワークに問題がないか確認してください。また、サーバーがダウンしていないか確認してください。 - -これは稀ですが、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。 - -まだ問題がある場合は、サーバーの問題と思われるのでサーバーの管理者に連絡してください。 - -## クライアントの動作が遅い -以下を試してみてください: - -- クライアント設定で「UIのアニメーションを減らす」を有効にする -- クライアント設定で「モーダルにぼかし効果を使用」を無効にする -- お使いのブラウザの設定でハードウェアアクセラレーションを有効にする -- お使いのデバイスのスペックを上げる - -## UIの一部の表示がおかしい(背景が透明になっている等) -アップデートによりUIの改修が行われたときに、テーマのキャッシュシステムの影響でそのような表示になることがあります。 クライアントの設定の「キャッシュをクリア」すると直ります。 -
⚠️ 「クライアントの」キャッシュクリアです。「ブラウザの」キャッシュクリアは行わないでください。
- -## 通知やアンテナ等の点滅が消えない -点滅は、未読のコンテンツがあることを示しています。通常点滅が消えない場合は、コンテンツを遡ると未読なコンテンツが残っています。 すべて既読にしたと思われるのに、それでもなお点滅が続く場合(おそらく不具合と思われます)は設定から強制的にすべて既読扱いにすることができます。 - -## Renoteができない -フォロワー限定のノートはRenoteすることはできません。 - -## UI上で特定の要素が表示されない -広告ブロッカーを使用しているとそのような不具合が発生することがあります。Misskeyではオフにしてご利用ください。 - -## UI上で未翻訳の部分がある -ほとんどの場合、単に翻訳が間に合っていないだけで、不具合ではありません。翻訳が終わるまでお待ちください。 [翻訳に参加](./misskey)していただくことも可能です。 diff --git a/src/docs/it-IT/keyboard-shortcut.md b/src/docs/it-IT/keyboard-shortcut.md deleted file mode 100644 index bb5fd328f..000000000 --- a/src/docs/it-IT/keyboard-shortcut.md +++ /dev/null @@ -1,68 +0,0 @@ -# Scorciatoie da tastiera - -## Generali -Le scorciatoie da tastiera sotto citate si possono usare praticamente ovunque. - - - - - - - - - - - -
ScorciatoiaEffettoAccesso universale
P, NNuova pubblicazionePost, New, Note
TEvidenziare l'ultima pubblicazione sulla timelineTimeline, Top
Shift + NMostrare/nascondere notificheNotifications
SCercaSearch
H, ?Visualizzare l'aiutoHelp
- -## Azioni riguardanti le pubblicazioni - - - - - - - - - - - - - - - - - - - -
ScorciatoiaEffettoAccesso universale
, K, Shift + TabSposta il focus sulla pubblicazione di sopra-
, J, TabSposta il focus sulla pubblicazione di sotto-
RApri finestra di rispostaReply
QApri finestra RinotaQuote
Ctrl + QRinota immediatamente (senza aprire finestra)-
E, A, +Apri finestra di reazioniEmote, reAction
0~9Usa reazione del numero corrispondente-
F, BAggiungi ai preferitiFavorite, Bookmark
Del, Ctrl + DElimina pubblicazioneDelete
M, OApri menù della notaMore, Other
SVisualizza o nascondi il contenuto segnato con CWShow, See
EscEsci dal focus-
- -## Finestra Rinota - - - - - - - - - - -
ScorciatoiaEffettoAccesso universale
EnterRinotare-
QAprire finestraQuote
EscChiudere finestra-
- -## Pannello reazioni -La reazione "👍" è impostata come reazione predefinita. - - - - - - - - - - - - - -
ScorciatoiaEffettoAccesso universale
, KSposta il focus sulla reazione di sopra-
, JSposta il focus sulla reazione di sotto-
, H, Shift + TabSposta il focus sulla reazione a sinistra-
, L, TabSposta il focus sulla reazione a destra-
Enter, Space, +Seleziona la reazione-
0~9Usa reazione del numero corrispondente -
EscCancella reazione-
diff --git a/src/docs/it-IT/mfm.md b/src/docs/it-IT/mfm.md deleted file mode 100644 index e237287ac..000000000 --- a/src/docs/it-IT/mfm.md +++ /dev/null @@ -1,2 +0,0 @@ -# MFM -MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます。 diff --git a/src/docs/it-IT/mute.md b/src/docs/it-IT/mute.md deleted file mode 100644 index d0fa672f4..000000000 --- a/src/docs/it-IT/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# Silenziare - -Quando si silenzia un utente, i successivi contenuti che lo riguardano non saranno più visualizzati su Misskey: - -* le pubblicazioni dell'utente sia nelle timeline che nei risultati di ricerca, così come le sue risposte e Rinote; -* le notifiche riguardo all'utente; -* la cronologia dei messaggi scambiati con l'utente nella chat. - -Per silenziare un utente, premi il pulsante "Silenzia" che si trova sulla sua pagina profilo. - -Gli utenti silenziati da te non vengono informati; nello stesso modo, tu non sarai infomat@ se vieni silenziat@ da un altr@ utente. - -Puoi controllare la lista di utenti che hai silenziato nelle Impostazioni account > "Silenziati / Bloccati". diff --git a/src/docs/it-IT/pages.md b/src/docs/it-IT/pages.md deleted file mode 100644 index 5a34971f1..000000000 --- a/src/docs/it-IT/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# Pagine - -## Variabili -変数を使うことで動的なページを作成できます。テキスト内で { 変数名 } と書くとそこに変数の値を埋め込めます。例えば Hello { thing } world! というテキストで、変数(thing)の値が ai だった場合、テキストは Hello ai world! になります。 - -変数の評価(値を算出すること)は上から下に行われるので、ある変数の中で自分より下の変数を参照することはできません。例えば上から A、B、C と3つの変数を定義したとき、Cの中でABを参照することはできますが、Aの中でBCを参照することはできません。 - -ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。 - -関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。 diff --git a/src/docs/it-IT/reaction.md b/src/docs/it-IT/reaction.md deleted file mode 100644 index f88dd99c3..000000000 --- a/src/docs/it-IT/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# Reazioni -Puoi mandare una reazione rapida alle note degli/delle altrə utenti apponendoci emoji. Per reagire, premi il pulsante "+" della nota per aprire il pannello reazioni e scegliere un emoji. Si possono anche usare gli [emoji personalizzati](./custom-emoji). - -## Personalizzare il pannello reazioni -È possibile personalizzare il pannello reazioni selezionando gli emoji che vuoi usare. Puoi cambiare i predefiniti nella scheda "Reazioni" delle impostazioni. - -## Inviare reazioni a server remoti -Siccome le reazioni sono una funzionalità originale di Misskey, vengono ricevute come semplici "Mi piace" dalla maggior parte delle istanze remote del Fediverso, a meno che non sia un'altra istanza Misskey.In genere sul Fediverso, la funzionalità "Mi piace" viene implementata come funzione "Preferiti". Inoltre, se reagisci con un emoji personalizzato verrà automaticamente inoltrato come un "👍" o simile, anche se quella destinataria è un'istanza Misskey. - -## Ricevere reazioni da server remoti -I "Mi piace" ricevuti da utenti di istanze remote vengono interpretati su Misskey come reazioni a forma di "👍". diff --git a/src/docs/it-IT/reversi-bot.md b/src/docs/it-IT/reversi-bot.md deleted file mode 100644 index 00d4a18a8..000000000 --- a/src/docs/it-IT/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# MisskeyリバーシBotの開発 -Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。 - -1. `games/reversi`ストリームに以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - -2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる - * イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている - -3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する - -4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - * `game`: `game`の`id` - -5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う - -6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する - -7. ゲームが開始すると、`started`イベントが流れてくる - * イベントの中身にはゲーム情報が含まれている - -8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述) - -9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる - * `color`として石の色が含まれている - * `pos`として位置情報が含まれている - -## 位置の計算法 -8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### X,Y座標 から インデックス に変換する -``` -pos = x + (y * mapWidth) -``` -`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます: -``` -mapWidth = map[0].length -``` - -### インデックス から X,Y座標 に変換する -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## マップ情報 -マップ情報は、ゲーム情報の`map`に入っています。 文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 それをもとにマップのデザインを知る事が出来ます: -* `(スペース)` ... マス無し -* `-` ... マス -* `b` ... 初期配置される黒石 -* `w` ... 初期配置される白石 - -例えば、4*4の次のような単純なマップがあるとします: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -この場合、マップデータはこのようになります: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## ユーザーにフォームを提示して対話可能Botを作成する -ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。 - -フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します: -```javascript -{ - type: 'init-form', - body: [フォームコントロールの配列] -} -``` - -フォームコントロールの配列については今から説明します。 フォームコントロールは、次のようなオブジェクトです: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... コントロールのID。 `type` ... コントロールの種類。後述します。 `label` ... コントロールと一緒に表記するテキスト。 `value` ... コントロールのデフォルト値。 - -### フォームの操作を受け取る -ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### フォームコントロールの種類 -#### Interruttore -type: `switch` スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。 - -##### プロパティ -`label` ... スイッチに表記するテキスト。 - -#### ラジオボタン -type: `radio` ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。 - -##### プロパティ -`items` ... ラジオボタンの選択肢。例: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '強', - value: 3 -}] -``` - -#### スライダー -type: `slider` スライダーを表示します。 - -##### プロパティ -`min` ... スライダーの下限。 `max` ... スライダーの上限。 `step` ... 入力欄で刻むステップ値。 - -#### テキストボックス -type: `textbox` テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。 - -## ユーザーにメッセージを表示する -設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 メッセージを表示するには、次のメッセージをストリームに送信します: -```javascript -{ - type: 'message', - body: { - text: 'メッセージ内容', - type: 'メッセージの種類' - } -} -``` -メッセージの種類: `success`, `info`, `warning`, `error`。 - -## 投了する -投了をするには、このエンドポイントにリクエストします。 diff --git a/src/docs/it-IT/stream.md b/src/docs/it-IT/stream.md deleted file mode 100644 index 2141b0d09..000000000 --- a/src/docs/it-IT/stream.md +++ /dev/null @@ -1,354 +0,0 @@ -# ストリーミングAPI - -ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。 - -## ストリームに接続する - -ストリーミングAPIを利用するには、まずMisskeyサーバーに**websocket**接続する必要があります。 - -以下のURLに、`i`というパラメータ名で認証情報を含めて、websocket接続してください。例: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。 - -
-

認証情報の取得については、こちらのドキュメントをご確認ください。

-
- ---- - -認証情報は省略することもできますが、その場合非ログインでの利用ということになり、受信できる情報や可能な操作は限られます。例: - -``` -%WS_URL%/streaming -``` - ---- - -ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。 - -**ストリームでのやり取りはすべてJSONです。** - -## Canale -MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。 - -### チャンネルに接続する -チャンネルに接続するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -ここで、 -* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。 -* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。 -* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。 - -
-

IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。

-
- -### チャンネルからのメッセージを受け取る -例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。 - -チャンネルがメッセージを発すると、次のようなデータがJSONでストリームに流れてきます: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。 -* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。 -* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。 - -### チャンネルに向けてメッセージを送信する -チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。 - -チャンネルにメッセージを送信するには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。 -* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。 -* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。 - -### チャンネルから切断する -チャンネルから切断するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。 - -## ストリームを経由してAPIリクエストする - -ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。 - -ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -ここで、 -* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 -* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 -* `data`には、エンドポイントのパラメータを含めます。 - -
-

APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。

-
- -### レスポンスの受信 - -APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。 - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -ここで、 -* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 -* `body`には、レスポンスが含まれています。 - -## 投稿のキャプチャ - -Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。 - -例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。 - -しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。 - -この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。 - -### 投稿をキャプチャする - -投稿をキャプチャするには、ストリームに次のようなメッセージを送信します: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャしたい投稿の`id`を設定します。 - -このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 - -例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -ここで、 -* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。 -* `body`内の`type`に、イベントの種類が設定されます。 -* `body`内の`body`に、イベントの詳細が設定されます。 - -#### イベントの種類 - -##### `reacted` -その投稿にリアクションがされた時に発生します。 - -* `reaction`に、リアクションの種類が設定されます。 -* `userId`に、リアクションを行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -その投稿が削除された時に発生します。 - -* `deletedAt`に、削除日時が設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -その投稿に添付されたアンケートに投票された時に発生します。 - -* `choice`に、選択肢IDが設定されます。 -* `userId`に、投票を行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### 投稿のキャプチャを解除する - -その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。 - -次のメッセージを送信します: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャを解除したい投稿の`id`を設定します。 - -このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 - -# チャンネル一覧 -## `main` -アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `renote` -自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。 - -#### `mention` -誰かからメンションされたときに発生するイベントです。 - -#### `readAllNotifications` -自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。 - -#### `meUpdated` -自分の情報が更新されたことを表すイベントです。 - -#### `follow` -自分が誰かをフォローしたときに発生するイベントです。 - -#### `unfollow` -自分が誰かのフォローを解除したときに発生するイベントです。 - -#### `followed` -自分が誰かにフォローされたときに発生するイベントです。 - -## `homeTimeline` -ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -タイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `localTimeline` -ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `hybridTimeline` -ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ソーシャルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `globalTimeline` -グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 diff --git a/src/docs/it-IT/theme.md b/src/docs/it-IT/theme.md deleted file mode 100644 index fd1fd6e33..000000000 --- a/src/docs/it-IT/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# Tema - -Puoi utilizzare i temi per cambiare l'aspetto del client Misskey. - -## Impostazioni tema -Impostazioni > Tema - -## Creare un tema -Il codice dei temi è scritto a forma di oggetti JSON5. I temi contengono gli oggetti sotto citati: -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... Identificativo univoco del tema. È consigliato utilizzare un UUID. -* `name` ... Nome tema -* `author` ... Autore/Autrice del tema -* `desc` ... Descrizione tema (facoltativa) -* `base` ... Imposta tema chiaro o tema scuro - * Scegli `light` per impostare un tema chiaro, e `dark` per impostare un tema scuro. - * Il tema erediterà dalle caratteristiche del tema di base impostato qui. -* `props` ... Imposta uno stile di tema. (Vedi spiegazioni sotto.) - -### Impostare uno stile di tema -Puoi configurare lo stile del tema dentro le `props`. Le chiavi diventeranno nomi di variabili CSS, il cui contenuto verrà definito dai valori associati ad esse. Inoltre, gli oggetti presenti in `props` per impostazione predefinita vengono ereditati dal tema di base. Il tema di base sarà [_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5) per una `base` `chiara`, e [_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5) per una `base` `scura`. Cioè, se non viene definita una chiave `panel` nelle `props` del tema, si terrà conto del valore <0>panel predefinito del tema usato. - -#### Sintassi dei valori -* Colori HEX - * Es.: `#00ff00` -* Colori `RGB(r, g, b)` - * Es.: `rgb(0, 255, 0)` -* Colori `RGBA(r, g, b, a)` - * Es.: `rgba(0, 255, 0, 0.5)` -* Chiamare valori di altre chiavi - * Inserisci `@{keyname}` per chiamare il valore di un'altra chiave. Bisogna sostituire il testo `{keyname}` col nome della chiave che vuoi chiamare. - * Es.: `@panel` -* Costanti (vedi sotto) - * Inserisci `${constantname}` per chiamare una costante.Bisogna sostituire il testo `{constantname}` col nome della costante che vuoi chiamare. - * Es.: `$main` -* Funzioni (vedi sotto) - * `:{functionname}<{argument}<{color}` - -#### Costanti -Può essere vantaggioso usare una costante nei casi in cui non vuoi che un valore produca una variabile CSS, perché lo vuoi utilizzare come valore di un'altra variabile CSS. In tal caso, basta aggiungere `$` davanti al nome della chiave affinché non generi variabile CSS. - -#### Funzioni -wip diff --git a/src/docs/it-IT/timelines.md b/src/docs/it-IT/timelines.md deleted file mode 100644 index 29981722b..000000000 --- a/src/docs/it-IT/timelines.md +++ /dev/null @@ -1,15 +0,0 @@ -# Confronto delle timeline - -https://docs.google.com/spreadsheets/d/1lxQ2ugKrhz58Bg96HTDK_2F98BUritkMyIiBkOByjHA/edit?usp=sharing - -## Home -Pubblicazioni degli utenti che segui. - -## Locale -Pubblicazioni degli utenti della tua istanza. Non vengono mostrate le note pubblicate con lo stato "principale". - -## Sociale -Raggruppa le timeline "home" e "locale". - -## Federata -Tutte le pubblicazioni ricevute dall'istanza, sia locali che altre. Non vengono mostrate le note pubblicate con lo stato "home". diff --git a/src/docs/ja-JP/admin/disable-timelines.md b/src/docs/ja-JP/admin/disable-timelines.md deleted file mode 100644 index 910b31bf1..000000000 --- a/src/docs/ja-JP/admin/disable-timelines.md +++ /dev/null @@ -1,11 +0,0 @@ -# LTL/STL/GTLの無効化 -Misskeyでは、LTL/STL/GTLをそれぞれ無効化することができます。有効/無効を切り替えるには、インスタンスコントロールパネルで設定します。 - -LTLやSTLは、そのインスタンス全員の投稿が見れるため、新規のユーザーにとってはユーザーを探す必要がなくなり、興味のあるユーザーを見つけやすいという利点があります。 -しかし同時に、フォロー機能が活用されなくなったり、不適切な投稿が目につきやすくなったり、チャットのようになることで内輪感が生じて逆に新規ユーザーが参加しにくくなるといったデメリットも持ち合わせています。 -サーバーによってメリット/デメリットどちらが優勢かは異なるので、オプションとして無効にできるようになっています。 -もしデメリットの方が上回っていると感じたら、それらのタイムラインを無効化することも検討してください。 - -
⚠️ 無効化を行うと、ユーザーが困惑し、短期的に見て利用者が減る可能性があります。そのため、無効化の際は影響を慎重に検討し、事前に説明してフォローを整える期間を一定程度設けることを推奨します。
- -なお、管理者/モデレーターは、これらのタイムラインの無効化状態は適用されず、引き続き利用することが可能です。 diff --git a/src/docs/ja-JP/admin/faq.md b/src/docs/ja-JP/admin/faq.md deleted file mode 100644 index 317b4e065..000000000 --- a/src/docs/ja-JP/admin/faq.md +++ /dev/null @@ -1,5 +0,0 @@ -# よくある質問 -ここでは、サーバー管理者向けのよくある質問を掲載しています。 - -## デフォルトテーマを設定したい -現在、デフォルトテーマ設定機能は実装されていません。 diff --git a/src/docs/ja-JP/advanced/aiscript.md b/src/docs/ja-JP/advanced/aiscript.md deleted file mode 100644 index 604d17daa..000000000 --- a/src/docs/ja-JP/advanced/aiscript.md +++ /dev/null @@ -1,7 +0,0 @@ -# AiScript -AiScriptは、Misskeyで使用できるスクリプト言語です。 - -
ℹ️ AiScript実装はMisskeyとは別リポジトリで、オープンソースで公開されています。
- -## 使い方 -AiScriptの構文や組み込み関数などのドキュメントは、[こちら](https://github.com/syuilo/aiscript/tree/master/docs)で公開されています。 diff --git a/src/docs/ja-JP/advanced/api.md b/src/docs/ja-JP/advanced/api.md deleted file mode 100644 index 742230716..000000000 --- a/src/docs/ja-JP/advanced/api.md +++ /dev/null @@ -1,62 +0,0 @@ -# Misskey API - -MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス、Bot等(以下「アプリケーション」と呼びます)を開発できます。 -ストリーミングAPIもあるので、リアルタイム性のあるアプリケーションを作ることも可能です。 - -APIを使い始めるには、まずアクセストークンを取得する必要があります。 -このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。 - -## アクセストークンの取得 -基本的に、APIはリクエストにはアクセストークンが必要となります。 -APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。 - -* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む -* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む - -### 自分自身のアクセストークンを手動発行する -「設定 > API」で、自分のアクセストークンを発行できます。 - -[「APIの使い方」へ進む](#APIの使い方) - -### アプリケーション利用者にアクセストークンの発行をリクエストする -アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。 - -#### Step 1 - -UUIDを生成する。以後これをセッションIDと呼びます。 - -> このセッションIDは毎回生成し、使いまわさないようにしてください。 - -#### Step 2 - -`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。 -> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます: -* `name` ... アプリケーション名 - * > 例: `MissDeck` -* `icon` ... アプリケーションのアイコン画像URL - * > 例: `https://missdeck.example.com/icon.png` -* `callback` ... 認証が終わった後にリダイレクトするURL - * > 例: `https://missdeck.example.com/callback` - * リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます -* `permission` ... アプリケーションが要求する権限 - * > 例: `write:notes,write:following,read:drive` - * 要求する権限を`,`で区切って列挙します - * どのような権限があるかは[APIリファレンス](/api-doc)で確認できます - -#### Step 3 -ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。 - -レスポンスに含まれるプロパティ: -* `token` ... ユーザーのアクセストークン -* `user` ... ユーザーの情報 - -[「APIの使い方」へ進む](#APIの使い方) - -## APIの使い方 -**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** -アクセストークンは、`i`というパラメータ名でリクエストに含めます。 - -* [APIリファレンス](/api-doc) -* [ストリーミングAPI](./stream) diff --git a/src/docs/ja-JP/advanced/create-plugin.md b/src/docs/ja-JP/advanced/create-plugin.md deleted file mode 100644 index 34678a206..000000000 --- a/src/docs/ja-JP/advanced/create-plugin.md +++ /dev/null @@ -1,90 +0,0 @@ -# プラグインの作成 -Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 -ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。 - -## メタデータ -プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 -メタデータは次のプロパティを含むオブジェクトです。 - -### name -プラグイン名 - -### author -プラグイン作者 - -### version -プラグインバージョン。数値を指定してください。 - -### description -プラグインの説明 - -### permissions -プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。 - -### config -プラグインの設定情報を表すオブジェクト。 -キーに設定名、値に以下のプロパティを含めます。 - -#### type -設定値の種類を表す文字列。以下から選択します。 -string number boolean - -#### label -ユーザーに表示する設定名 - -#### description -設定の説明 - -#### default -設定のデフォルト値 - -## APIリファレンス -AiScript標準で組み込まれているAPIは掲載しません。 - -### Mk:dialog(title text type) -ダイアログを表示します。typeには以下の値が設定できます。 -info success warn error question -省略すると info になります。 - -### Mk:confirm(title text type) -確認ダイアログを表示します。typeには以下の値が設定できます。 -info success warn error question -省略すると question になります。 -ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。 - -### Mk:api(endpoint params) -Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。 - -### Mk:save(key value) -任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。 - -### Mk:load(key) -Mk:saveで永続化した指定の名前の値を読み取ります。 - -### Plugin:register_post_form_action(title fn) -投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 -コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。 - -### Plugin:register_note_action(title fn) -ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 -コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 - -### Plugin:register_user_action(title fn) -ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 -コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。 - -### Plugin:register_note_view_interruptor(fn) -UIに表示されるノート情報を書き換えます。 -コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 -コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:register_note_post_interruptor(fn) -ノート投稿時にノート情報を書き換えます。 -コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 -コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:open_url(url) -第一引数に渡されたURLをブラウザの新しいタブで開きます。 - -### Plugin:config -プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。 diff --git a/src/docs/ja-JP/advanced/develop-bot.md b/src/docs/ja-JP/advanced/develop-bot.md deleted file mode 100644 index 2e246b7bf..000000000 --- a/src/docs/ja-JP/advanced/develop-bot.md +++ /dev/null @@ -1,7 +0,0 @@ -# Botの作成 -[Misskey API](./api)を利用してBotの開発が可能です。 -また、いくつかのBot実装が公開されているため、ぜひ参考にしてください。 - -- [syuilo/ai](https://github.com/syuilo/ai) ... Node.js上で動く、TypeScript製Bot実装 - -Botを作成したときは、プロフィール設定からBotフラグをオンにしておくことを強くおすすめします。 diff --git a/src/docs/ja-JP/advanced/reversi-bot.md b/src/docs/ja-JP/advanced/reversi-bot.md deleted file mode 100644 index 43f455cfe..000000000 --- a/src/docs/ja-JP/advanced/reversi-bot.md +++ /dev/null @@ -1,177 +0,0 @@ -# MisskeyリバーシBotの開発 -Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。 - -1. `games/reversi`ストリームに以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - -2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる - * イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている - -3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する - -4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - * `game`: `game`の`id` - -5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う - -6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する - -7. ゲームが開始すると、`started`イベントが流れてくる - * イベントの中身にはゲーム情報が含まれている - -8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述) - -9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる - * `color`として石の色が含まれている - * `pos`として位置情報が含まれている - -## 位置の計算法 -8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### X,Y座標 から インデックス に変換する -``` -pos = x + (y * mapWidth) -``` -`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます: -``` -mapWidth = map[0].length -``` - -### インデックス から X,Y座標 に変換する -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## マップ情報 -マップ情報は、ゲーム情報の`map`に入っています。 -文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 -それをもとにマップのデザインを知る事が出来ます: -* `(スペース)` ... マス無し -* `-` ... マス -* `b` ... 初期配置される黒石 -* `w` ... 初期配置される白石 - -例えば、4*4の次のような単純なマップがあるとします: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -この場合、マップデータはこのようになります: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## ユーザーにフォームを提示して対話可能Botを作成する -ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 -例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。 - -フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します: -```javascript -{ - type: 'init-form', - body: [フォームコントロールの配列] -} -``` - -フォームコントロールの配列については今から説明します。 -フォームコントロールは、次のようなオブジェクトです: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... コントロールのID。 -`type` ... コントロールの種類。後述します。 -`label` ... コントロールと一緒に表記するテキスト。 -`value` ... コントロールのデフォルト値。 - -### フォームの操作を受け取る -ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 -イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 -例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### フォームコントロールの種類 -#### スイッチ -type: `switch` -スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。 - -##### プロパティ -`label` ... スイッチに表記するテキスト。 - -#### ラジオボタン -type: `radio` -ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。 - -##### プロパティ -`items` ... ラジオボタンの選択肢。例: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '強', - value: 3 -}] -``` - -#### スライダー -type: `slider` -スライダーを表示します。 - -##### プロパティ -`min` ... スライダーの下限。 -`max` ... スライダーの上限。 -`step` ... 入力欄で刻むステップ値。 - -#### テキストボックス -type: `textbox` -テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。 - -## ユーザーにメッセージを表示する -設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 -例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 -メッセージを表示するには、次のメッセージをストリームに送信します: -```javascript -{ - type: 'message', - body: { - text: 'メッセージ内容', - type: 'メッセージの種類' - } -} -``` -メッセージの種類: `success`, `info`, `warning`, `error`。 - -## 投了する -投了をするには、このエンドポイントにリクエストします。 diff --git a/src/docs/ja-JP/advanced/share-page.md b/src/docs/ja-JP/advanced/share-page.md deleted file mode 100644 index 75a9d14d2..000000000 --- a/src/docs/ja-JP/advanced/share-page.md +++ /dev/null @@ -1,56 +0,0 @@ -# シェアページ -`/share`を開くと、共有用の投稿フォームを開くことができます。 -ここではシェアページで利用できるクエリ文字列の一覧を示します。 - -## クエリ文字列一覧 -### 文字 - -
-
title
-
タイトルです。本文の先頭に[ … ]と挿入されます。
-
text
-
本文です。
-
url
-
URLです。末尾に挿入されます。
-
- - -### リプライ情報 -以下のいずれか - -
-
replyId
-
リプライ先のノートid
-
replyUri
-
リプライ先のUrl(リモートのノートオブジェクトを指定)
-
- -### Renote情報 -以下のいずれか - -
-
renoteId
-
Renote先のノートid
-
renoteUri
-
Renote先のUrl(リモートのノートオブジェクトを指定)
-
- -### 公開範囲 -※specifiedに相当する値はvisibility=specifiedとvisibleAccts/visibleUserIdsで指定する - -
-
visibility
-
公開範囲 ['public' | 'home' | 'followers' | 'specified']
-
localOnly
-
0(false) or 1(true)
-
visibleUserIds
-
specified時のダイレクト先のユーザーid カンマ区切りで
-
visibleAccts
-
specified時のダイレクト先のacct(@?username[@host]) カンマ区切りで
-
- -### ファイル -
-
fileIds
-
添付したいファイルのid(カンマ区切りで)
-
diff --git a/src/docs/ja-JP/advanced/stream.md b/src/docs/ja-JP/advanced/stream.md deleted file mode 100644 index da6cd216a..000000000 --- a/src/docs/ja-JP/advanced/stream.md +++ /dev/null @@ -1,354 +0,0 @@ -# ストリーミングAPI - -ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。 - -## ストリームに接続する - -ストリーミングAPIを利用するには、まずMisskeyサーバーに**websocket**接続する必要があります。 - -以下のURLに、`i`というパラメータ名で認証情報を含めて、websocket接続してください。例: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。 - -
ℹ️ 認証情報の取得については、こちらのドキュメントをご確認ください。
- ---- - -認証情報は省略することもできますが、その場合非ログインでの利用ということになり、受信できる情報や可能な操作は限られます。例: - -``` -%WS_URL%/streaming -``` - ---- - -ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 -しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 -それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。 - -**ストリームでのやり取りはすべてJSONです。** - -## チャンネル -MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 -Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 -ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。 - -ひとつのストリーム上で、同時に複数のチャンネルに接続することができます。 - -### チャンネルに接続する -チャンネルに接続するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -ここで、 -* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。 -* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。 -* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。 - -
ℹ️ IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。
- -### チャンネルからのメッセージを受け取る -例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。 - -チャンネルがメッセージを発すると、次のようなデータがJSONでストリームに流れてきます: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。 -* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。 -* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。 - -### チャンネルに向けてメッセージを送信する -チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。 - -チャンネルにメッセージを送信するには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。 -* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。 -* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。 - -### チャンネルから切断する -チャンネルから切断するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。 - -## ストリームを経由してAPIリクエストする - -ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。 - -ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -ここで、 -* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 -* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 -* `data`には、エンドポイントのパラメータを含めます。 - -
ℹ️ APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。
- -### レスポンスの受信 - -APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。 - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -ここで、 -* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 -* `body`には、レスポンスが含まれています。 - -## 投稿のキャプチャ - -Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。 - -例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。 - -しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。 - -この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。 - -### 投稿をキャプチャする - -投稿をキャプチャするには、ストリームに次のようなメッセージを送信します: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャしたい投稿の`id`を設定します。 - -このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 - -例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -ここで、 -* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。 -* `body`内の`type`に、イベントの種類が設定されます。 -* `body`内の`body`に、イベントの詳細が設定されます。 - -#### イベントの種類 - -##### `reacted` -その投稿にリアクションがされた時に発生します。 - -* `reaction`に、リアクションの種類が設定されます。 -* `userId`に、リアクションを行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -その投稿が削除された時に発生します。 - -* `deletedAt`に、削除日時が設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -その投稿に添付されたアンケートに投票された時に発生します。 - -* `choice`に、選択肢IDが設定されます。 -* `userId`に、投票を行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### 投稿のキャプチャを解除する - -その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。 - -次のメッセージを送信します: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャを解除したい投稿の`id`を設定します。 - -このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 - -# チャンネル一覧 -## `main` -アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `renote` -自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。 - -#### `mention` -誰かからメンションされたときに発生するイベントです。 - -#### `readAllNotifications` -自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。 - -#### `meUpdated` -自分の情報が更新されたことを表すイベントです。 - -#### `follow` -自分が誰かをフォローしたときに発生するイベントです。 - -#### `unfollow` -自分が誰かのフォローを解除したときに発生するイベントです。 - -#### `followed` -自分が誰かにフォローされたときに発生するイベントです。 - -## `homeTimeline` -ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -タイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `localTimeline` -ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `hybridTimeline` -ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ソーシャルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `globalTimeline` -グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 diff --git a/src/docs/ja-JP/features/antenna.md b/src/docs/ja-JP/features/antenna.md deleted file mode 100644 index 94ad9e4ae..000000000 --- a/src/docs/ja-JP/features/antenna.md +++ /dev/null @@ -1,4 +0,0 @@ -# アンテナ -アンテナは、自由に条件を設定して、合致するノートを自動で収集することができる機能です。 - -条件を設定したアンテナが作成された状態で、条件に合致するノートが投稿されると、リアルタイムでそのアンテナのタイムラインにノートが追加されます。 diff --git a/src/docs/ja-JP/features/custom-emoji.md b/src/docs/ja-JP/features/custom-emoji.md deleted file mode 100644 index 4e1eb5c0e..000000000 --- a/src/docs/ja-JP/features/custom-emoji.md +++ /dev/null @@ -1,5 +0,0 @@ -# カスタム絵文字 -カスタム絵文字は、インスタンスで用意された画像を絵文字のように使える機能です。 -ノート、リアクション、チャット、自己紹介、名前などの場所で使うことができます。 -カスタム絵文字をそれらの場所で使うには、絵文字ピッカーボタン(ある場合)を押すか、`:`を入力して絵文字サジェストを表示します。 -テキスト内に`:foo:`のような形式の文字列が見つかると、`foo`の部分がカスタム絵文字名と解釈され、表示時には対応したカスタム絵文字に置き換わります。 diff --git a/src/docs/ja-JP/features/deck.md b/src/docs/ja-JP/features/deck.md deleted file mode 100644 index e37d48bc0..000000000 --- a/src/docs/ja-JP/features/deck.md +++ /dev/null @@ -1,20 +0,0 @@ -# デッキ - -デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。 - -## カラムの追加 -デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。 - -## カラムの移動 -カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。 - -## カラムの水平分割 -カラムは左右だけでなく、上下に並べることもできます。 -カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 -上下分割を解除するには、カラムメニューの「右に出す」を選択します。 - -## カラムの設定 -カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。 - -## デッキの設定 -デッキに関する設定は、[settings/deck](/settings/deck)で行えます。 diff --git a/src/docs/ja-JP/features/drive.md b/src/docs/ja-JP/features/drive.md deleted file mode 100644 index dce09a449..000000000 --- a/src/docs/ja-JP/features/drive.md +++ /dev/null @@ -1,19 +0,0 @@ -# ドライブ -ドライブは、Misskey上でファイルを管理できる機能です。 - -[ドライブのページ](/my/drive)から任意のファイルをアップロードできるほか、アバターに設定した画像や、ノートに添付したファイルなどもすべてドライブにアップロードされます。 - -
⚠️ ドライブからファイルを削除すると、そのファイルが添付されたノートも消えます。
- -ドライブにアップロードされたファイルは、いつでもダウンロードすることができるほか、ノート作成時に「ドライブからファイルを添付」することでファイルを再利用することもできます。 - -ドライブ内にフォルダを作り、複数のファイルをまとめて整理することもできます。 - -## 閲覧注意 (NSFW) -
ℹ️ この項目が閲覧注意なわけではありません
- -閲覧注意またはNSFW (Not safe for work) は、ドライブのファイルに設定することができるフラグです。 -閲覧注意フラグを設定されたファイルは、表示される際に閲覧者の操作なしには表示されなくなります。 -このフラグは、例えば職場や公共の場で閲覧するのに適切でないと思われる画像などに設定し、そのような画像が突然表示されてしまうことを防ぐ目的で使われます。 - -このフラグは手動でオンオフを切り替えられるほか、モデレーターの判断で設定される場合もあります。 diff --git a/src/docs/ja-JP/features/favorite.md b/src/docs/ja-JP/features/favorite.md deleted file mode 100644 index c788fd37e..000000000 --- a/src/docs/ja-JP/features/favorite.md +++ /dev/null @@ -1,6 +0,0 @@ -# お気に入り -[ノート](./node)をお気に入りとして登録できる機能です。 -お気に入り登録したノートは、[お気に入りページ](./my/favorites)で一覧することができます。 -お気に入りに登録したことは相手に通知されず、お気に入りは自分しか見ることができません。 - -ノートをお気に入り登録するには、ノートメニューの「お気に入り」を押します。お気に入り解除するには、ノートメニューの「お気に入り解除」を押します。 diff --git a/src/docs/ja-JP/features/follow.md b/src/docs/ja-JP/features/follow.md deleted file mode 100644 index 28a606e28..000000000 --- a/src/docs/ja-JP/features/follow.md +++ /dev/null @@ -1,3 +0,0 @@ -# フォロー -ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 -ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。 diff --git a/src/docs/ja-JP/features/keyboard-shortcut.md b/src/docs/ja-JP/features/keyboard-shortcut.md deleted file mode 100644 index 3811613db..000000000 --- a/src/docs/ja-JP/features/keyboard-shortcut.md +++ /dev/null @@ -1,66 +0,0 @@ -# キーボードショートカット - -## グローバル -これらのショートカットは基本的にどこでも使えます。 - - - - - - - - - - - -
ショートカット効果由来
P, N新規投稿Post, New, Note
Tタイムラインの最も新しい投稿にフォーカスTimeline, Top
Shift + N通知を表示/隠すNotifications
S検索Search
H, ?ヘルプを表示Help
- -## 投稿にフォーカスされた状態 - - - - - - - - - - - - - - - - - - -
ショートカット効果由来
, K, Shift + Tab上の投稿にフォーカスを移動-
, J, Tab下の投稿にフォーカスを移動-
R返信フォームを開くReply
QRenoteフォームを開くQuote
Ctrl + Q即刻Renoteする(フォームを開かずに)-
E, A, +リアクションフォームを開くEmote, reAction
0~9数字に対応したリアクションをする(対応については後述)-
F, Bお気に入りに登録Favorite, Bookmark
Del, Ctrl + D投稿を削除Delete
M, O投稿に対するメニューを開くMore, Other
SCWで隠された部分を表示 or 隠すShow, See
Escフォーカスを外す-
- -## Renoteフォーム - - - - - - - - - -
ショートカット効果由来
EnterRenoteする-
Qフォームを展開するQuote
Escフォームを閉じる-
- -## リアクションフォーム -デフォルトで「👍」にフォーカスが当たっている状態です。 - - - - - - - - - - - - - -
ショートカット効果由来
, K上のリアクションにフォーカスを移動-
, J下のリアクションにフォーカスを移動-
, H, Shift + Tab左のリアクションにフォーカスを移動-
, L, Tab右のリアクションにフォーカスを移動-
Enter, Space, +リアクション確定-
0~9数字に対応したリアクションで確定-
Escリアクションするのをやめる-
diff --git a/src/docs/ja-JP/features/mfm.md b/src/docs/ja-JP/features/mfm.md deleted file mode 100644 index 24ff6fa82..000000000 --- a/src/docs/ja-JP/features/mfm.md +++ /dev/null @@ -1,13 +0,0 @@ -# MFM -MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 -MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます。 - -## MFMが使用可能な場所の例 -- ノート本文 -- CW注釈 -- ユーザーの名前 -- ユーザーの自己紹介 - -## 開発者向け情報 -MFMのパーサー実装はライブラリとして公開されており、簡単にクライアントにMFMを組み込むことが可能です。 -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptパーサー実装 diff --git a/src/docs/ja-JP/features/mute-and-block.md b/src/docs/ja-JP/features/mute-and-block.md deleted file mode 100644 index 4a5844085..000000000 --- a/src/docs/ja-JP/features/mute-and-block.md +++ /dev/null @@ -1,43 +0,0 @@ -# ミュートとブロック -好みではないユーザーがいる場合は、ミュートを行うことでそのユーザーが自分から見えないようにすることができます。 -また、より強力な措置として、ブロックを行うことでそのユーザーから自分のコンテンツが見えないようになるほか、自分に対して関わることができないようにすることができます。 -ミュートされていることは相手は分かりませんが、ブロックされていることは相手に分かります。どちらを選ぶかはご自身の判断で行ってください。 - -
ℹ️ ミュートとブロックは併用できます。
- -
⚠️ 利用規約に違反するような、迷惑なユーザーがいる場合は運営者に報告することも検討してください。
- -設定>ミュートとブロック から、自分がミュートまたはブロックしているユーザー一覧を確認することができます。 - -## ミュート -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -- タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -- そのユーザーからの通知 -- メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 -- など - -ユーザーをミュートするには、対象のユーザーのユーザーページのメニューを開き、「ミュート」ボタンを押します。 - -
ℹ️ ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。
- -## ブロック -ユーザーをブロックすると、そのユーザーからあなたのコンテンツが見えないようになり、またあなたに対して以下のようなアクションをすることができなくなります。 - -- フォローする -- ユーザーリストに追加する -- 返信する、Renoteする -- リアクションする、アンケートに投票する -- メッセージを送信する -- など - -また、 - -- ブロックする際に既にそのユーザーからフォローされていた場合はフォローが解除されます。 -- ブロックする際に既にそのユーザーがあなたをユーザーリストに入れていた場合はそのリストからあなたが削除されます。 - -ユーザーをブロックするには、対象のユーザーのユーザーページのメニューを開き、「ブロック」ボタンを押します。 - -
⚠️ ブロックを行ったこと自体は相手に通知されませんが、フォローを行ったりなどの上記のアクションが行えなくなるので間接的にブロックされていることは分かります。
- -
⚠️ 相手から自分のコンテンツが見えなくなりますが、相手がアカウントを切り替えたりログアウト状態になれば見ることができます。あくまで簡易的、補助的なものとしてお考えください。
diff --git a/src/docs/ja-JP/features/note.md b/src/docs/ja-JP/features/note.md deleted file mode 100644 index 1d043660f..000000000 --- a/src/docs/ja-JP/features/note.md +++ /dev/null @@ -1,62 +0,0 @@ -# ノート -ノートは、Misskeyに投稿される、文章、ファイル、アンケートなどを含むコンテンツで、Misskeyの中心的概念です。また、そのノートを作成する行為自体もノートと呼ばれます。 - -ノートが作成されると、[タイムライン](./timeline)に追加され、自分の[フォロワー](./follow)やサーバーのユーザーが見れるようになります。 - -ノートには、[リアクション](./reaction)を行うことができます。また、返信や引用もできます。 - -ノートを[お気に入り](./favorite)登録することで、後で簡単に見返すことができます。 - -## ノートを作成する -ノートを作成するには、画面上にある鉛筆マークのボタンを押して、作成フォームを開きます。作成フォームに内容を入力し、「ノート」ボタンを押すことでノートが作成されます。 -ノートには、画像、動画など任意のファイルや、[アンケート](./poll)を添付することができます。また、本文中には[MFM](./mfm)が使用でき、[メンション](./mention)や[ハッシュタグ](./hashtag)を含めることもできます。 -他にも、CWや公開範囲といった設定も行えます(詳細は後述)。 -
ℹ️ コンピューターのクリップボードに画像データがある状態で、フォーム内のテキストボックスにペーストするとその画像を添付することができます。
-
ℹ️ テキストボックス内でCtrl + Enterを押すことでも投稿できます。
- -## Renote -既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノートをRenoteと呼びます。 -自分がフォローしているユーザーの、気に入ったノートを自分のフォロワーに共有したい場合や、過去の自分のノートを再度共有したい場合に使います。 -同じノートに対して無制限にRenoteを行うことができますが、あまり連続して使用すると迷惑になる場合もあるので、注意しましょう。 -
⚠️ 公開範囲がフォロワーやダイレクトのノートはRenoteできません
- -Renoteを削除するには、Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 - -## CW -Contents Warningの略で、ノートの内容を、閲覧者の操作なしには表示しないようにできる機能です。主に長大な内容を隠すためや、ネタバレ防止などに使うことができます。 -設定するには、フォームの「内容を隠す」ボタン(目のアイコン)を押します。すると新しい入力エリアが表れるので、そこに内容の要約を記入します。 - -## 公開範囲 -ノートごとに、そのノートが公開される範囲を設定することができます。フォームの「ノート」ボタンの左にあるアイコンを押すと公開範囲を以下から選択できます。 - -### パブリック -全ての人に対してノートが公開されるほか、サーバーの全てのタイムライン(ホームタイムライン、ローカルタイムライン、ソーシャルタイムライン、グローバルタイムライン)にノートが流れます。 -
⚠️ アカウントがサイレンス状態の時は、この公開範囲は使用できません。
- -### ホーム -全ての人に対してノートが公開されますが、フォロワー以外のローカルタイムライン、ソーシャルタイムライン、グローバルタイムラインにはノートは流れません。 - -### フォロワー -自分のフォロワーに対してのみノートを公開します。フォロワーの全てのタイムラインに流れます。 - -### ダイレクト -指定したユーザーに対してのみノートを公開します。指定したユーザーの全てのタイムラインに流れます。 - -### 「ローカルのみ」オプション -このオプションを有効にすると、リモートにノートを連合しなくなります。 - -### 公開範囲の比較 - - - - -
パブリックホームフォロワーダイレクト
フォロワーのLTL/STL/GTL
非フォロワーのLTL/STL/GTL
- -## ピン留め -ノートをピン留めすると、ユーザーページに常にそのノートを表示しておくことができます。 -ノートのメニューを開き、「ピン留め」を選択してピン留めできます。 -複数のノートをピン留めできます。 - -## ウォッチ -ノートをウォッチすると、自分以外のノートへのリアクションや返信などの通知を受け取ることができます。 -ノートのメニューを開き、「ウォッチ」を選択してウォッチできます。 diff --git a/src/docs/ja-JP/features/pages.md b/src/docs/ja-JP/features/pages.md deleted file mode 100644 index a7311b95e..000000000 --- a/src/docs/ja-JP/features/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# Pages - -## 変数 -変数を使うことで動的なページを作成できます。テキスト内で { 変数名 } と書くとそこに変数の値を埋め込めます。例えば Hello { thing } world! というテキストで、変数(thing)の値が ai だった場合、テキストは Hello ai world! になります。 - -変数の評価(値を算出すること)は上から下に行われるので、ある変数の中で自分より下の変数を参照することはできません。例えば上から A、B、C と3つの変数を定義したとき、Cの中でABを参照することはできますが、Aの中でBCを参照することはできません。 - -ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。 - -関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。 diff --git a/src/docs/ja-JP/features/reaction.md b/src/docs/ja-JP/features/reaction.md deleted file mode 100644 index fadce7af4..000000000 --- a/src/docs/ja-JP/features/reaction.md +++ /dev/null @@ -1,14 +0,0 @@ -# リアクション -他の人のノートに、絵文字を付けて簡単にあなたの反応を伝えられる機能です。 -リアクションするには、ノートの + アイコンをクリックしてピッカーを表示し、絵文字を選択します。 -リアクションには[カスタム絵文字](./custom-emoji)も使用できます。 - -## リアクションピッカーのカスタマイズ -ピッカーに表示される絵文字を自分好みにカスタマイズすることができます。 -設定の「リアクション」で設定します。 - -## リモート投稿へのリアクションについて -リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。 - -## リモートからのリアクションについて -リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。 diff --git a/src/docs/ja-JP/features/silence.md b/src/docs/ja-JP/features/silence.md deleted file mode 100644 index 3ac2edb9b..000000000 --- a/src/docs/ja-JP/features/silence.md +++ /dev/null @@ -1,7 +0,0 @@ -# サイレンス -サイレンスは、アカウントに設定される状態のひとつです。 - -アカウントがサイレンス状態になると、ノートの公開範囲をパブリックにできなくなります。 -ホーム、フォロワー、ダイレクトは選択可能なため、サイレンスを受けた場合でもフォロワーやあなたのユーザーページを直接訪れた場合は投稿を閲覧できますが、GTL(連合タイムライン)やLTL(ローカルタイムライン)には投稿が流れません。 - -アカウントのサイレンス状態は、サーバーのモデレーターによって有効化/無効化されます。 diff --git a/src/docs/ja-JP/features/theme.md b/src/docs/ja-JP/features/theme.md deleted file mode 100644 index 89b467120..000000000 --- a/src/docs/ja-JP/features/theme.md +++ /dev/null @@ -1,74 +0,0 @@ -# テーマ - -テーマを設定して、Misskeyクライアントの見た目を変更できます。 - -## テーマの設定 -設定 > テーマ - -## テーマを作成する -テーマコードはJSON5で記述されたテーマオブジェクトです。 -テーマは以下のようなオブジェクトです。 -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... テーマの一意なID。UUIDをおすすめします。 -* `name` ... テーマ名 -* `author` ... テーマの作者 -* `desc` ... テーマの説明(オプション) -* `base` ... 明るいテーマか、暗いテーマか - * `light`にすると明るいテーマになり、`dark`にすると暗いテーマになります。 - * テーマはここで設定されたベーステーマを継承します。 -* `props` ... テーマのスタイル定義。これから説明します。 - -### テーマのスタイル定義 -`props`下にはテーマのスタイルを定義します。 -キーがCSSの変数名になり、バリューで中身を指定します。 -なお、この`props`オブジェクトはベーステーマから継承されます。 -ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 -つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 - -#### バリューで使える構文 -* 16進数で表された色 - * 例: `#00ff00` -* `rgb(r, g, b)`形式で表された色 - * 例: `rgb(0, 255, 0)` -* `rgb(r, g, b, a)`形式で表された透明度を含む色 - * 例: `rgba(0, 255, 0, 0.5)` -* 他のキーの値の参照 - * `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。 - * 例: `@panel` -* 定数(後述)の参照 - * `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。 - * 例: `$main` -* 関数(後述) - * `:{関数名}<{引数}<{色}` - -#### 定数 -「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 -キー名を`$`で始めると、そのキーはCSS変数として出力されません。 - -#### 関数 -wip diff --git a/src/docs/ja-JP/features/timeline.md b/src/docs/ja-JP/features/timeline.md deleted file mode 100644 index 6e8ad62a0..000000000 --- a/src/docs/ja-JP/features/timeline.md +++ /dev/null @@ -1,33 +0,0 @@ -# タイムライン -タイムラインは、[ノート](./note)が時系列で表示される機能です。 -タイムラインには以下で示す種類があり、種類によって表示されるノートも異なります。 -なお、タイムラインの種類によってはサーバーにより無効になっている場合があります。 - -## ホーム -自分のフォローしているユーザーの投稿が流れます。HTLと略されます。 - -## ローカル -全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。LTLと略されます。 - -## ソーシャル -自分のフォローしているユーザーの投稿と、全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。STLと略されます。 - -## グローバル -全てのローカルユーザーの「ホーム」指定されていない投稿と、サーバーに届いた全てのリモートユーザーの「ホーム」指定されていない投稿が流れます。GTLと略されます。 - -## 比較 -| ソース | | | タイムライン | | | -|-----------------------|------------|--------|---------|------------|------------| -| ユーザー | 公開範囲 | ホーム | ローカル | ソーシャル | グローバル | -| ローカル (フォロー) | 公開 | ✔ | ✔ | ✔ | ✔ | -| | ホーム | ✔ | | ✔ | | -| | フォロワー | ✔ | ✔ | ✔ | ✔ | -| リモート (フォロー) | 公開 | ✔ | | ✔ | ✔ | -| | ホーム | ✔ | | ✔ | | -| | フォロワー | ✔ | | ✔ | ✔ | -| ローカル (未フォロー) | 公開 | | ✔ | ✔ | ✔ | -| | ホーム | | | | | -| | フォロワー | | | | | -| リモート (未フォロー) | 公開 | | | | ✔ | -| | ホーム | | | | | -| | フォロワー | | | | | diff --git a/src/docs/ja-JP/features/widgets.md b/src/docs/ja-JP/features/widgets.md deleted file mode 100644 index e9b938e8c..000000000 --- a/src/docs/ja-JP/features/widgets.md +++ /dev/null @@ -1,8 +0,0 @@ -# ウィジェット -ウィジェットは、MisskeyのUI上に設置できる小型の情報表示、操作が行えるパーツです。 - -ウィジェットを編集するには、ウィジェット編集モードに切り替えます。切り替え方法はUIによって異なります。 -ウィジェット編集モードでは、ウィジェットの追加、削除、並び替え、およびそれぞれのウィジェットの設定を行えます。 - -## 利用可能なウィジェット一覧 -todo diff --git a/src/docs/ja-JP/features/word-mute.md b/src/docs/ja-JP/features/word-mute.md deleted file mode 100644 index fa4d14346..000000000 --- a/src/docs/ja-JP/features/word-mute.md +++ /dev/null @@ -1,20 +0,0 @@ -# ワードミュート -ワードミュートの設定をすると、条件に合致したノートが表示されなくなります。 - -ワードミュートには、ソフトワードミュートとハードワードミュートの2種類があります。それぞれについて設定の方法と挙動を説明します。 - -## ソフトワードミュート -ソフトワードミュートは、クライアント(アプリ)側でミュートを判断するワードミュートです。 - -ノートが設定した条件に合致すると、「(ユーザー名)が何かを言いました」という表示で隠れます。 -クリックすると元の通りに表示されます。 - -## ハードワードミュート -ハードワードミュートは、アンテナのようにサーバーが新しいノートの本文に対して条件に合致するかどうか判断し、タイムラインから対象となったノートを除外します。 - -つまり、ハードワードミュートには、以下のような特徴があります。 - -* 条件設定後、新しい投稿のみがミュートの対象になります。 -* 条件を変更しても、過去にハードミュートされたノートはミュートされたままになります。 -* 「○○が何かを言いました」でタイムラインが埋まることがありません。 -* ソフトミュートに非対応のアプリでも、ハードミュートは適用されます。 diff --git a/src/docs/ja-JP/general/apps.md b/src/docs/ja-JP/general/apps.md deleted file mode 100644 index 1f4c85fe8..000000000 --- a/src/docs/ja-JP/general/apps.md +++ /dev/null @@ -1,6 +0,0 @@ -# サードパーティアプリのリスト -## クライアント -todo - -## 連携サービス -todo diff --git a/src/docs/ja-JP/general/changelog.md b/src/docs/ja-JP/general/changelog.md deleted file mode 100644 index 6766a63b2..000000000 --- a/src/docs/ja-JP/general/changelog.md +++ /dev/null @@ -1,5 +0,0 @@ -# 更新履歴 -
ℹ️ このサーバーの更新履歴です。Misskeyの最新のリリースについては、GitHubをご確認ください。
- - - diff --git a/src/docs/ja-JP/general/faq.md b/src/docs/ja-JP/general/faq.md deleted file mode 100644 index 60cd5fad8..000000000 --- a/src/docs/ja-JP/general/faq.md +++ /dev/null @@ -1,33 +0,0 @@ -# よくある質問 -ここでは利用上のよくある質問について掲載しています。 -Misskeyのプロジェクト自体についてのよくある質問は[こちら](./misskey)に掲載されています。 - -## iOS/Androidのアプリはありますか? -公式にはそういったOSのネイティブアプリを開発していませんが、サードパーティ製のアプリがいくつかあります。 -詳しくは[こちら](./apps)をご覧ください。 - -ただ、サードパーティ製アプリはどうしても機能への対応が遅れてしまうため、とくに拘りがなければ公式のWebクライアントの利用をおすすめします。 -なお、MisskeyのWebクライアントはPWAに対応しているので、ネイティブアプリのように動作させることも可能です。 -詳しくは[こちら](todo)をご覧ください。 - -## Mastodonクライアントでログインできないのですが? -MisskeyはMastodonのAPIと互換性がないため、一部を除きMastodonクライアントでMisskeyを利用することはできません。 - -## 他のサーバーのユーザーをフォローするときは? -メニューから検索を選び、ユーザー名をホスト込みで入力します。例: `@syuilo@misskey.io` - -## Renoteを削除するには? -Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 -Renoteについては[こちら](../features/note)をご確認ください。 - -## URLのプレビューを表示させたくない -MFMには、そのURLのプレビューを無効にする構文があります。詳細は[MFMチートシート](/mfm-cheat-sheet)をご確認ください。 - -## カスタム絵文字を追加したい -運営者のみがカスタム絵文字を追加、編集、削除できます。それらを希望する場合は運営者に依頼してください。 - -## Botを開発したい -Misskey APIを利用してBotの開発が可能です。[こちら](../advanced/develop-bot)をご確認ください。 - -## ノートの翻訳機能はどのサービスを使用していますか? -[DeepL](https://www.deepl.com/)を使用しています。 diff --git a/src/docs/ja-JP/general/glossary.md b/src/docs/ja-JP/general/glossary.md deleted file mode 100644 index 90bc1132c..000000000 --- a/src/docs/ja-JP/general/glossary.md +++ /dev/null @@ -1,99 +0,0 @@ -# 用語集 -Misskeyに関する用語集です。 - -## ActivityPub -(読み: あくてぃびてぃぱぶ) -分散型を実現するために用いられるプロトコル(仕様)。このプロトコルに則ってサーバー同士通信を行うことで、連合が行われ、Fediverseを形成しています。 - -## AiScript -(読み: あいすくりぷと) -Misskey上で使用できるプログラミング言語です。詳細は[こちら。](../advanced/aiscript) - -## API -(読み: えーぴーあい) -Misskeyのサーバーが公開している、プログラムからMisskeyを扱うためのインターフェース。詳細は[こちら。](../advanced/api) - -## Bot -(読み: ぼっと) -プログラムによって動作しているアカウント。 - -## CW -(読み: こんてんつわーにんぐ) -Contents Warningの略。ノートの内容を、操作なしには表示しないようにできる機能。主に長大な内容を隠すためや、ネタバレ防止などに使われます。 - -## Fediverse -(読み: ふぇでぃばーす) -Misskeyを含む様々な分散型ソフトウェアのサーバーで構成されたネットワーク。 - -## GTL -グローバルタイムライン(Global TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## HTL -ホームタイムライン(Home TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## LTL -ローカルタイムライン(Local TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## MFM -(読み: えむえふえむ) -Misskey Flavored Markdownの略で、Misskey上で使用できるマークアップ言語です。詳細は[こちら。](../features/mfm) - -## NSFW -(読み: のっとせーふふぉーわーく) -Not Safe For Workの略。画像を「閲覧注意」扱いにし、操作なしには表示しないようにすることができる機能。 - -## Renote -(読み: りのーと) -既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノート。詳細は[こちら。](../features/note) - -## STL -ソーシャルタイムライン(Social TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## 藍 -(読み: あい) -Misskeyの看板娘(公式キャラクター)です。 - -## アクティブユーザー -インスタンスにアカウントを作っているユーザーのうち、現在も実際にサービスを利用しているユーザーのこと。 - -## インスタンス -todo - -## カスタム絵文字 -サーバーで用意された絵文字。カスタム絵文字ではない通常の絵文字は「Unicode絵文字」と区別して呼ばれる。 - -## コントロールパネル -インスタンスの設定画面のこと。 - -## サーバー -todo - -## サイレンス -ノートをパブリックな公開範囲で投稿できなくされている状態。モデレーターの判断でユーザーごとに設定されます。詳細は[こちら。](../features/silence) - -## ジョブキュー -アクティビティ配送などを順番に行うためのシステム。 - -## 凍結 -アカウントが使用不可に設定されている状態。 - -## ドライブ -Misskeyにアップロードしたファイルを管理する機能。詳細は[こちら。](../features/drive) - -## ノート -Misskeyに投稿される、文章、ファイル、アンケートなどを含めることができるコンテンツ。詳細は[こちら。](../features/note) - -## ミスキスト -Misskeyを使う人のこと。 - -## モデレーター -スパムの凍結およびサイレンスや不適切な投稿の削除など、コミュニティ運営に関する権限を持つユーザー。 - -## リモート -他サーバーのことを指します。リモートユーザーといったように接頭辞としても使われます。ローカルの逆です。 - -## 連合 -サーバー上で作成された情報が他のサーバーに伝わること。 - -## ローカル -自サーバーのことを指します。ローカルユーザー、ローカルタイムラインといったように接頭辞としても使われます。リモートの逆です。 diff --git a/src/docs/ja-JP/general/links.md b/src/docs/ja-JP/general/links.md deleted file mode 100644 index 5ce5e1ddb..000000000 --- a/src/docs/ja-JP/general/links.md +++ /dev/null @@ -1,12 +0,0 @@ -# リンク集 - -## Webサイト -- [Official Discord](https://discord.gg/Wp8gVStHW3) - Misskey公式Discordサーバー -- [Misskey Forum](https://forum.misskey.io/) - Misskeyに関する話題を扱うフォーラム - -## アカウント -- [@repo@misskey.io](https://misskey.io/@repo) - Misskeyのリポジトリの更新を投稿するbot - -## ライブラリ -- [misskey-dev/misskey.js](https://github.com/misskey-dev/misskey.js) - JavaScriptのMisskey SDK -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptのMFMパーサー実装 diff --git a/src/docs/ja-JP/general/misskey.md b/src/docs/ja-JP/general/misskey.md deleted file mode 100644 index ea65c0723..000000000 --- a/src/docs/ja-JP/general/misskey.md +++ /dev/null @@ -1,121 +0,0 @@ -# Misskeyについて - -Misskeyはオープンソースの分散型マイクロブログプラットフォームプロジェクトです。 -開発は日本でsyuiloによって2014年から開始されました。 -ドライブ、リアクションなどの豊富な機能や、高いカスタマイズ性を備えたUIを持つことが特徴です。 - -## 歴史 -開発当初は掲示板がメインのサービスでしたが、ユーザーが短文を投稿し、それを時系列で流れるタイムライン機能を追加したところ人気が高まり、徐々にそれがメインとして開発が進むようになりました。 -当初は分散型ではありませんでしたが、2018年にActivityPubを実装し分散型になったことで、より多くの方に認知され利用されるサービスになり、現在に至ります。 -
ℹ️ Misskeyという名前は、syuiloが当時聴いていたMay'nというアーティストの楽曲、Brain Diverの歌詞に由来します。
- -誰でも開発に参加することができ、現在でも活発に開発が続いています。 - -## 分散型とは何か? -分散(distributed)型とは、非中央集権(decentralized)とも呼ばれ、コミュニティが多数のサーバーに分散して存在し、それらが相互に通信(連合、federation)することでコンテンツ共有ネットワーク(Fediverse)を形成していることが特徴のサービスです。 -単一のサーバーしか存在しない、もしくは複数存在しても互いに独立している場合は中央集権なサービスと言われ、例えばTwitterやFacebookなどほとんどのサービスがそれに該当します。 -分散型のメリットは、自分に合った運営者やテーマのサーバーを選択できることです。自分でサーバーを作成することもできます。連合するおかげで、どのサーバーを選んでも、同じコミュニティにアクセスできます。 - -## 常にオープンソース -Misskeyはこれまでもこれからも、オープンソースであり続けます。オープンソースとは、簡単に言うとソフトウェアのソースコード(プログラム)が公開されていることです。ソースコードの修正や再配布が可能であることを定義に含めることもあります。 -Misskeyのすべてのソースコードは[AGPL](https://github.com/misskey-dev/misskey/blob/develop/LICENSE)というオープンソースライセンスの下に[公開](https://github.com/misskey-dev)されていて、誰でも自由に閲覧、使用、修正、改変、再配布をすることができます。 -オープンソースは、自分で好きなように変えたり、有害な処理が含まれていないことを確認することができたり、誰でも開発に参加できるなどの、様々なメリットがあります。 -上述の分散型を実現するためにも、オープンソースであるということは必要不可欠な要素です。 -再び引き合いに出しますが、TwitterやFacebookなどの利益を得ているほとんどのサービスはオープンソースではありません。 - -
ℹ️ 技術的に言うと、MisskeyのソースコードはGitで管理されていて、リポジトリはGitHub上でホスティングされています。
- -## 開発に参加する、プロジェクトを支援する -Misskeyを気に入っていただけたら、ぜひプロジェクトを支援してください。プロジェクトに貢献するには、以下で紹介するようにいろいろな方法があります。方法によっては開発のスキルは不要なので、誰でも気軽に参加し貢献することができます。いつでもお待ちしています。 - -### 機能を追加したり、バグを修正する -ソフトウェアエンジニアのスキルをお持ちの方であれば、ソースコードを編集する形でプロジェクトに貢献することができます。 -貢献についてのガイドは[こちら](https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md)です。 - -### 議論に参加する -新しい機能、または既存の機能について意見を述べたり、不具合を報告したりすることでも貢献できます。 -そのようなディスカッションは[GitHub](https://github.com/misskey-dev)上か、[フォーラム](https://forum.misskey.io/)等で行われます。 - -### テキストを翻訳する -Misskeyは様々な言語に対応しています(i18n -internationalizationの略- と呼ばれます)。元の言語は基本的に日本語ですが、有志によって他の言語へと翻訳されています。 -その翻訳作業に加わっていただくことでもMisskeyに貢献できます。 -Misskeyは[Crowdinというサービスを使用して翻訳の管理を行っています。](https://crowdin.com/project/misskey) - -### 感想を投稿する -不具合報告等だけではなく、Misskeyの良い点、楽しい点といったポジティブな意見もぜひ共有してください。開発の励みになり、それは間接的ですがプロジェクトへの貢献です。 - -### ミスキストを増やす -ミスキストとは、Misskeyを使用する人のことです。 -知り合いに紹介するなどしてMisskeyを広めていただければ、ミスキストが増え開発のモチベーションが上がります。 - -### 寄付をする -Misskeyはビジネスではなく、利用は無料であるため、収益は皆様からの寄付のみです。(インスタンスによっては広告収入を得ているような場合もありますが、それは運営者の収入であり直接開発者への収入にはなりません) -寄付をしていただければ、今後も開発を続けることが可能になり、プロジェクトへの貢献になります。 -寄付は基本的には[Patreon](https://www.patreon.com/syuilo)で受け付けています。 -一定額寄付していただけると、Misskeyの[情報ページ](/about-misskey)に名前を記載することができます。 - -また、サーバーの運営者も、基本的には収益を得ていません。サーバーの運営にはコストがかかるので、運営者の支援をすることもご検討ください。 -開発には直接関係しませんが、サーバーがあってこそのプロジェクトなので、運営が維持されるというのは開発と同じくらい重要なことです。 - -## クレジット -Misskeyの開発者や、Misskeyに寄付をしてくださった方の一覧は[こちら](/about-misskey)で見ることができます。 - -## よくある質問 -### プロジェクトは何を目指していますか? -強いて言うと、漠然的になりますが広く使われる汎用的なプラットフォームになることを目指しています。 -Misskeyは他のプロジェクトとは違い、何らかの思想(例えば、反中央集権)やビジョンに基づいて開発が行われているわけではなく、その点ではフラットです。 -それが逆に、特定の方向性に縛られないフレキシブルさを生み出すことに繋がっていると感じています。 - - -### 企業によって開発されていますか? -いいえ。Misskeyの開発は個人で行われており、商業的でもないため、特定の企業の関りはありません。 -開発メンバーも基本的にはボランティアです。 -また、開発に対し企業のスポンサーがつくこともありますが、その場合でもやはり開発は個人のコミュニティが主体です。 - -### 誰が運営していますか? -Misskeyは分散型なため、各サーバーにそれぞれ異なった運営者がいます。従って、特定の個人や企業によって、Misskeyの全てが運営されているわけではありません。 -また、開発チームが運営を行うわけでもないため、運営に関する連絡は、お使いのサーバーの運営者に行ってください。 -サーバーの運営者は、[このページ](/about)で確認することができます。 -あなたがサーバーを作成すれば、あなたが運営者になります。 - -### どのサーバーを選べばいいですか? -[サーバー一覧が公開されています。](https://join.misskey.page/ja-JP/instances) -サーバーによってコミュニティのテーマ(特定のこと、ものが好き 等)が決められている場合があるので、自分に合ったテーマのサーバーがあれば、そこを選ぶと良いかもしれません。 -他にも、サーバーの規模、ユーザー層、国および言語、運営者が信頼できるかどうか、などの観点があります。 -なお、Misskey公式のサーバーというものはありません。自身で新しくサーバーを作成するという選択肢もあります。 - -基本的にどのサーバーを選んだとしても、他の全てのサーバーのユーザーと繋がることができます。 - -### サーバーを建てるにはどうしたらいいですか? -Misskeyサーバーの作成に興味を持っていただきありがとうございます。 -2021年現在、Misskeyのホスティングサービスは存在しないため、サーバーの作成にはある程度の知識が必要です。 -サーバーの作成方法については[こちら](todo)をご覧ください。 - -### どのような技術を使用していますか? -Misskeyは開発が進むにつれ使用する技術も大きく変わってきました。開発当初はMySQL + PHP + jQueryといった構成でしたが、現在は以下のようになっています。 -- サーバーサイド: Node.js -- データベース: PostgreSQL、Redis -- UIフレームワーク: Vue.js -- プログラミング言語: TypeScript - -また、MFMやAiScriptなどの、Misskeyから派生して独自の技術も開発しています。 - -### Mastodonのフォークですか? -いいえ。MisskeyはMastodonやその他のプロジェクトとは全く別のプロジェクトです。 -開発に関しても、Misskeyの方が昔から開発されています。ただし、分散型になったのはMastodonの登場より後です。 -同じActivityPubという分散のためのプロトコルを実装しているという点以外、両者に特に関りがあるわけでもありません。 - -### iOS/Androidのアプリはありますか? -公式にはそういったOSのネイティブアプリを開発していませんが、サードパーティ製のアプリがいくつかあります。 -詳しくは[こちら](./apps)をご覧ください。 - -ただ、サードパーティ製アプリはどうしても機能への対応が遅れてしまうため、とくに拘りがなければ公式のWebクライアントの利用をおすすめします。 -なお、MisskeyのWebクライアントはPWAに対応しているので、ネイティブアプリのように動作させることも可能です。 -詳しくは[こちら](todo)をご覧ください。 - -### Misskeyのロゴ、アイコンはどこで入手できますか? -(準備中) - -### 時折目にする猫耳の可愛い女の子は? -Misskeyの守り神、藍ちゃんです。アイチャンカワイイヤッター! -
ℹ️ 藍ちゃんについてはこちらです。
diff --git a/src/docs/ja-JP/general/report-issue.md b/src/docs/ja-JP/general/report-issue.md deleted file mode 100644 index 575ea3950..000000000 --- a/src/docs/ja-JP/general/report-issue.md +++ /dev/null @@ -1,10 +0,0 @@ -# 不具合の報告 -不具合と思われる状況に遭遇したときは、まず[トラブルシューティング](./troubleshooting)をご一読ください。 -それでも問題が解決しないときは、以下の情報を含めて[フォーラム](https://forum.misskey.io/)に投稿してください。 -投稿することで、解決策が見つかったり、不具合と判断されれば開発チームによって修正が行われます。 - -## 含める情報 -- Misskeyのバージョン([情報ページ](/about)で確認できます) -- お使いのブラウザの種類とバージョン -- お使いのOSの種類とバージョン -- 問題の再現手順 diff --git a/src/docs/ja-JP/general/troubleshooting.md b/src/docs/ja-JP/general/troubleshooting.md deleted file mode 100644 index 55302cc8f..000000000 --- a/src/docs/ja-JP/general/troubleshooting.md +++ /dev/null @@ -1,45 +0,0 @@ -# トラブルシューティング -
ℹ️ よくある質問も合わせてお役立てください。
- -問題が発生したときは、まずこちらをご確認ください。 -該当する項目が無い、もしくは手順を試しても効果がない場合は、サーバーの管理者に連絡するか[不具合を報告](./report-issue)してください。 - -## クライアントが起動しない -ほとんどの場合、お使いのブラウザまたはOSのバージョンが古いことが原因です。 -ブラウザおよびOSのバージョンを最新のものに更新してから、再度試してみてください。 - -これは稀ですが、それでも起動しない場合は、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。 - -## ページが読み込めない -クライアントが起動するもののページが読み込めないというエラーが出る場合は、ネットワークに問題がないか確認してください。また、サーバーがダウンしていないか確認してください。 - -これは稀ですが、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。 - -まだ問題がある場合は、サーバーの問題と思われるのでサーバーの管理者に連絡してください。 - -## クライアントの動作が遅い -以下を試してみてください: - -- クライアント設定で「UIのアニメーションを減らす」を有効にする -- クライアント設定で「モーダルにぼかし効果を使用」を無効にする -- お使いのブラウザの設定でハードウェアアクセラレーションを有効にする -- お使いのデバイスのスペックを上げる - -## UIの一部の表示がおかしい(背景が透明になっている等) -アップデートによりUIの改修が行われたときに、テーマのキャッシュシステムの影響でそのような表示になることがあります。 -クライアントの設定の「キャッシュをクリア」すると直ります。 -
⚠️ 「クライアントの」キャッシュクリアです。「ブラウザの」キャッシュクリアは行わないでください。
- -## 通知やアンテナ等の点滅が消えない -点滅は、未読のコンテンツがあることを示しています。通常点滅が消えない場合は、コンテンツを遡ると未読なコンテンツが残っています。 -すべて既読にしたと思われるのに、それでもなお点滅が続く場合(おそらく不具合と思われます)は設定から強制的にすべて既読扱いにすることができます。 - -## Renoteができない -フォロワー限定のノートはRenoteすることはできません。 - -## UI上で特定の要素が表示されない -広告ブロッカーを使用しているとそのような不具合が発生することがあります。Misskeyではオフにしてご利用ください。 - -## UI上で未翻訳の部分がある -ほとんどの場合、単に翻訳が間に合っていないだけで、不具合ではありません。翻訳が終わるまでお待ちください。 -[翻訳に参加](./misskey)していただくことも可能です。 diff --git a/src/docs/ja-KS/admin/disable-timelines.md b/src/docs/ja-KS/admin/disable-timelines.md deleted file mode 100644 index 55e902365..000000000 --- a/src/docs/ja-KS/admin/disable-timelines.md +++ /dev/null @@ -1,8 +0,0 @@ -# LTL/STL/GTLの無効化 -Misskeyでは、LTL/STL/GTLをそれぞれ無効化することができるで。有効/無効を切り替えるんは、インスタンスコントロールパネルで設定しいや。 - -LTLやSTLでは、そのインスタンス全員の投稿が見えるから、新規のユーザーにとってはユーザー探す必要がのうなって、興味のあるユーザーを見つけやすいゆう利点があるで。 でも同時にな、フォロー機能が活用されんくなったり、不適切な投稿が目につきやすうなったり、チャットみたいにのうて内輪感ができて逆に新規ユーザーがあんまし参加せんようなるないなデメリットも持ち合わせとうで。 サーバーによってメリット/デメリットどっちがようさんあるかはちゃうから、オプションとして無効にできるようなっとんねん。 デメリットの方が上回っとう思たら、それらのタイムラインを無効化することも検討しいや。 - -
⚠️無効化したら、ユーザーがややこしがって短期的に見て利用者が減るかもわからへん。せやから、無効化するゆう時は影響をよう検討して、事前に説明してフォローを整える期間を一定程度設けるんを推奨するで。
- -ちなみに、管理者/モデレーターは、これらのタイムラインの無効化状態は適用されんと、引き続き利用できるで。 diff --git a/src/docs/ja-KS/admin/faq.md b/src/docs/ja-KS/admin/faq.md deleted file mode 100644 index ac98c469a..000000000 --- a/src/docs/ja-KS/admin/faq.md +++ /dev/null @@ -1,5 +0,0 @@ -# ようある質問 -ここでは、サーバー管理者向けのようある質問を掲載しとうで。 - -## デフォルトテーマを設定したい -今んとこ、デフォルトテーマ設定機能は実装されとらへん。 diff --git a/src/docs/ja-KS/advanced/aiscript.md b/src/docs/ja-KS/advanced/aiscript.md deleted file mode 100644 index 0d98036d0..000000000 --- a/src/docs/ja-KS/advanced/aiscript.md +++ /dev/null @@ -1,7 +0,0 @@ -# AiScript -AiScriptは、Misskeyで使用できるスクリプト言語や。 - -
ℹ️ AiScript実装はMisskeyとは別リポジトリで、オープンソースで公開されようで。
- -## どないして使うん? -AiScriptの構文や組み込み関数などのドキュメントは、[こちら](https://github.com/syuilo/aiscript/tree/master/docs)で公開されよる。 diff --git a/src/docs/ja-KS/advanced/api.md b/src/docs/ja-KS/advanced/api.md deleted file mode 100644 index 76019b614..000000000 --- a/src/docs/ja-KS/advanced/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス、Bot等(以下「アプリケーション」と呼びます)を開発できます。 ストリーミングAPIもあるので、リアルタイム性のあるアプリケーションを作ることも可能です。 - -APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。 - -## アクセストークンの取得 -基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。 - -* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む -* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む - -### 自分自身のアクセストークンを手動発行する -「設定 > API」で、自分のアクセストークンを発行できます。 - -[「APIの使い方」へ進む](#APIの使い方) - -### アプリケーション利用者にアクセストークンの発行をリクエストする -アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。 - -#### Step 1 - -UUIDを生成する。以後これをセッションIDと呼びます。 - -> このセッションIDは毎回生成し、使いまわさないようにしてください。 - -#### Step 2 - -`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。 -> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます: -* `name` ... アプリケーション名 - * > 例: `MissDeck` -* `icon` ... アプリケーションのアイコン画像URL - * > 例: `https://missdeck.example.com/icon.png` -* `callback` ... 認証が終わった後にリダイレクトするURL - * > 例: `https://missdeck.example.com/callback` - * リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます -* `permission` ... アプリケーションが要求する権限 - * > 例: `write:notes,write:following,read:drive` - * 要求する権限を`,`で区切って列挙します - * どのような権限があるかは[APIリファレンス](/api-doc)で確認できます - -#### Step 3 -ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。 - -レスポンスに含まれるプロパティ: -* `token` ... ユーザーのアクセストークン -* `user` ... ユーザーの情報 - -[「APIの使い方」へ進む](#APIの使い方) - -## APIの使い方 -**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。 - -* [APIリファレンス](/api-doc) -* [ストリーミングAPI](./stream) diff --git a/src/docs/ja-KS/advanced/create-plugin.md b/src/docs/ja-KS/advanced/create-plugin.md deleted file mode 100644 index 0d2fa1917..000000000 --- a/src/docs/ja-KS/advanced/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# プラグインの作成 -Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。 - -## メタデータ -プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。 - -### name -プラグイン名 - -### author -プラグイン作者 - -### version -プラグインバージョン。数値を指定してください。 - -### description -プラグインの説明 - -### permissions -プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。 - -### config -プラグインの設定情報を表すオブジェクト。 キーに設定名、値に以下のプロパティを含めます。 - -#### type -設定値の種類を表す文字列。以下から選択します。 string number boolean - -#### label -ユーザーに表示する設定名 - -#### description -設定の説明 - -#### default -設定のデフォルト値 - -## APIリファレンス -AiScript標準で組み込まれているAPIは掲載しません。 - -### Mk:dialog(title text type) -ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。 - -### Mk:confirm(title text type) -確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。 - -### Mk:api(endpoint params) -Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。 - -### Mk:save(key value) -任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。 - -### Mk:load(key) -Mk:saveで永続化した指定の名前の値を読み取ります。 - -### Plugin:register_post_form_action(title fn) -投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。 - -### Plugin:register_note_action(title fn) -ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 - -### Plugin:register_user_action(title fn) -ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。 - -### Plugin:register_note_view_interruptor(fn) -UIに表示されるノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:register_note_post_interruptor(fn) -ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:open_url(url) -第一引数に渡されたURLをブラウザの新しいタブで開きます。 - -### Plugin:config -プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。 diff --git a/src/docs/ja-KS/advanced/develop-bot.md b/src/docs/ja-KS/advanced/develop-bot.md deleted file mode 100644 index 7f825e9bc..000000000 --- a/src/docs/ja-KS/advanced/develop-bot.md +++ /dev/null @@ -1,6 +0,0 @@ -# Botの作成 -[Misskey API](./api)を利用してBotの開発が可能です。 また、いくつかのBot実装が公開されているため、ぜひ参考にしてください。 - -- [syuilo/ai](https://github.com/syuilo/ai) ... Node.js上で動く、TypeScript製Bot実装 - -Botを作成したときは、プロフィール設定からBotフラグをオンにしておくことを強くおすすめします。 diff --git a/src/docs/ja-KS/advanced/reversi-bot.md b/src/docs/ja-KS/advanced/reversi-bot.md deleted file mode 100644 index 7ab2a7212..000000000 --- a/src/docs/ja-KS/advanced/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# MisskeyリバーシBotの開発 -Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。 - -1. `games/reversi`ストリームに以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - -2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる - * イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている - -3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する - -4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - * `game`: `game`の`id` - -5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う - -6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する - -7. ゲームが開始すると、`started`イベントが流れてくる - * イベントの中身にはゲーム情報が含まれている - -8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述) - -9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる - * `color`として石の色が含まれている - * `pos`として位置情報が含まれている - -## 位置の計算法 -8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### X,Y座標 から インデックス に変換する -``` -pos = x + (y * mapWidth) -``` -`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます: -``` -mapWidth = map[0].length -``` - -### インデックス から X,Y座標 に変換する -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## マップ情報 -マップ情報は、ゲーム情報の`map`に入っています。 文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 それをもとにマップのデザインを知る事が出来ます: -* `(スペース)` ... マス無し -* `-` ... マス -* `b` ... 初期配置される黒石 -* `w` ... 初期配置される白石 - -例えば、4*4の次のような単純なマップがあるとします: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -この場合、マップデータはこのようになります: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## ユーザーにフォームを提示して対話可能Botを作成する -ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。 - -フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します: -```javascript -{ - type: 'init-form', - body: [フォームコントロールの配列] -} -``` - -フォームコントロールの配列については今から説明します。 フォームコントロールは、次のようなオブジェクトです: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... コントロールのID。 `type` ... コントロールの種類。後述します。 `label` ... コントロールと一緒に表記するテキスト。 `value` ... コントロールのデフォルト値。 - -### フォームの操作を受け取る -ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### フォームコントロールの種類 -#### スイッチ -type: `switch` スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。 - -##### プロパティ -`label` ... スイッチに表記するテキスト。 - -#### ラジオボタン -type: `radio` ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。 - -##### プロパティ -`items` ... ラジオボタンの選択肢。例: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '強', - value: 3 -}] -``` - -#### スライダー -type: `slider` スライダーを表示します。 - -##### プロパティ -`min` ... スライダーの下限。 `max` ... スライダーの上限。 `step` ... 入力欄で刻むステップ値。 - -#### テキストボックス -type: `textbox` テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。 - -## ユーザーにメッセージを表示する -設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 メッセージを表示するには、次のメッセージをストリームに送信します: -```javascript -{ - type: 'message', - body: { - text: 'メッセージ内容', - type: 'メッセージの種類' - } -} -``` -メッセージの種類: `success`, `info`, `warning`, `error`。 - -## 投了する -投了をするには、このエンドポイントにリクエストします。 diff --git a/src/docs/ja-KS/advanced/share-page.md b/src/docs/ja-KS/advanced/share-page.md deleted file mode 100644 index 4fb7ded0b..000000000 --- a/src/docs/ja-KS/advanced/share-page.md +++ /dev/null @@ -1,54 +0,0 @@ -# シェアページ -`/share`を開くと、共有用の投稿フォームを開くことができます。 ここではシェアページで利用できるクエリ文字列の一覧を示します。 - -## クエリ文字列一覧 -### 文字 - -
-
title
-
タイトルです。本文の先頭に[ … ]と挿入されます。
-
text
-
本文です。
-
url
-
URLです。末尾に挿入されます。
-
- -### リプライ情報 -以下のいずれか - -
-
replyId
-
リプライ先のノートid
-
replyUri
-
リプライ先のUrl(リモートのノートオブジェクトを指定)
-
- -### Renote情報 -以下のいずれか - -
-
renoteId
-
Renote先のノートid
-
renoteUri
-
Renote先のUrl(リモートのノートオブジェクトを指定)
-
- -### 公開範囲 -※specifiedに相当する値はvisibility=specifiedとvisibleAccts/visibleUserIdsで指定する - -
-
visibility
-
公開範囲 ['public' | 'home' | 'followers' | 'specified']
-
localOnly
-
0(false) or 1(true)
-
visibleUserIds
-
specified時のダイレクト先のユーザーid カンマ区切りで
-
visibleAccts
-
specified時のダイレクト先のacct(@?username[@host]) カンマ区切りで
-
- -### ファイル -
-
fileIds
-
添付したいファイルのid(カンマ区切りで)
-
diff --git a/src/docs/ja-KS/advanced/stream.md b/src/docs/ja-KS/advanced/stream.md deleted file mode 100644 index 0e5edd2b0..000000000 --- a/src/docs/ja-KS/advanced/stream.md +++ /dev/null @@ -1,350 +0,0 @@ -# ストリーミングAPI - -ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。 - -## ストリームに接続する - -ストリーミングAPIを利用するには、まずMisskeyサーバーに**websocket**接続する必要があります。 - -以下のURLに、`i`というパラメータ名で認証情報を含めて、websocket接続してください。例: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。 - -
ℹ️ 認証情報の取得については、こちらのドキュメントをご確認ください。
- ---- - -認証情報は省略することもできますが、その場合非ログインでの利用ということになり、受信できる情報や可能な操作は限られます。例: - -``` -%WS_URL%/streaming -``` - ---- - -ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。 - -**ストリームでのやり取りはすべてJSONです。** - -## チャンネル -MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。 - -ひとつのストリーム上で、同時に複数のチャンネルに接続することができます。 - -### チャンネルに接続する -チャンネルに接続するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -ここで、 -* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。 -* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。 -* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。 - -
ℹ️ IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。
- -### チャンネルからのメッセージを受け取る -例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。 - -チャンネルがメッセージを発すると、次のようなデータがJSONでストリームに流れてきます: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。 -* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。 -* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。 - -### チャンネルに向けてメッセージを送信する -チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。 - -チャンネルにメッセージを送信するには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。 -* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。 -* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。 - -### チャンネルから切断する -チャンネルから切断するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。 - -## ストリームを経由してAPIリクエストする - -ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。 - -ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -ここで、 -* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 -* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 -* `data`には、エンドポイントのパラメータを含めます。 - -
ℹ️ APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。
- -### レスポンスの受信 - -APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。 - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -ここで、 -* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 -* `body`には、レスポンスが含まれています。 - -## 投稿のキャプチャ - -Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。 - -例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。 - -しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。 - -この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。 - -### 投稿をキャプチャする - -投稿をキャプチャするには、ストリームに次のようなメッセージを送信します: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャしたい投稿の`id`を設定します。 - -このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 - -例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -ここで、 -* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。 -* `body`内の`type`に、イベントの種類が設定されます。 -* `body`内の`body`に、イベントの詳細が設定されます。 - -#### イベントの種類 - -##### `reacted` -その投稿にリアクションがされた時に発生します。 - -* `reaction`に、リアクションの種類が設定されます。 -* `userId`に、リアクションを行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -その投稿が削除された時に発生します。 - -* `deletedAt`に、削除日時が設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -その投稿に添付されたアンケートに投票された時に発生します。 - -* `choice`に、選択肢IDが設定されます。 -* `userId`に、投票を行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### 投稿のキャプチャを解除する - -その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。 - -次のメッセージを送信します: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャを解除したい投稿の`id`を設定します。 - -このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 - -# チャンネル一覧 -## `main` -アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `renote` -自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。 - -#### `mention` -誰かからメンションされたときに発生するイベントです。 - -#### `readAllNotifications` -自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。 - -#### `meUpdated` -自分の情報が更新されたことを表すイベントです。 - -#### `follow` -自分が誰かをフォローしたときに発生するイベントです。 - -#### `unfollow` -自分が誰かのフォローを解除したときに発生するイベントです。 - -#### `followed` -自分が誰かにフォローされたときに発生するイベントです。 - -## `homeTimeline` -ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -タイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `localTimeline` -ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `hybridTimeline` -ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ソーシャルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `globalTimeline` -グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 diff --git a/src/docs/ja-KS/aiscript.md b/src/docs/ja-KS/aiscript.md deleted file mode 100644 index 6c28b446e..000000000 --- a/src/docs/ja-KS/aiscript.md +++ /dev/null @@ -1,4 +0,0 @@ -# AiScript - -## 関数 -デフォルトで値渡しです。 diff --git a/src/docs/ja-KS/api.md b/src/docs/ja-KS/api.md deleted file mode 100644 index 76019b614..000000000 --- a/src/docs/ja-KS/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス、Bot等(以下「アプリケーション」と呼びます)を開発できます。 ストリーミングAPIもあるので、リアルタイム性のあるアプリケーションを作ることも可能です。 - -APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。 - -## アクセストークンの取得 -基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。 - -* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む -* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む - -### 自分自身のアクセストークンを手動発行する -「設定 > API」で、自分のアクセストークンを発行できます。 - -[「APIの使い方」へ進む](#APIの使い方) - -### アプリケーション利用者にアクセストークンの発行をリクエストする -アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。 - -#### Step 1 - -UUIDを生成する。以後これをセッションIDと呼びます。 - -> このセッションIDは毎回生成し、使いまわさないようにしてください。 - -#### Step 2 - -`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。 -> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます: -* `name` ... アプリケーション名 - * > 例: `MissDeck` -* `icon` ... アプリケーションのアイコン画像URL - * > 例: `https://missdeck.example.com/icon.png` -* `callback` ... 認証が終わった後にリダイレクトするURL - * > 例: `https://missdeck.example.com/callback` - * リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます -* `permission` ... アプリケーションが要求する権限 - * > 例: `write:notes,write:following,read:drive` - * 要求する権限を`,`で区切って列挙します - * どのような権限があるかは[APIリファレンス](/api-doc)で確認できます - -#### Step 3 -ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。 - -レスポンスに含まれるプロパティ: -* `token` ... ユーザーのアクセストークン -* `user` ... ユーザーの情報 - -[「APIの使い方」へ進む](#APIの使い方) - -## APIの使い方 -**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。 - -* [APIリファレンス](/api-doc) -* [ストリーミングAPI](./stream) diff --git a/src/docs/ja-KS/create-plugin.md b/src/docs/ja-KS/create-plugin.md deleted file mode 100644 index 0d2fa1917..000000000 --- a/src/docs/ja-KS/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# プラグインの作成 -Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。 - -## メタデータ -プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。 - -### name -プラグイン名 - -### author -プラグイン作者 - -### version -プラグインバージョン。数値を指定してください。 - -### description -プラグインの説明 - -### permissions -プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。 - -### config -プラグインの設定情報を表すオブジェクト。 キーに設定名、値に以下のプロパティを含めます。 - -#### type -設定値の種類を表す文字列。以下から選択します。 string number boolean - -#### label -ユーザーに表示する設定名 - -#### description -設定の説明 - -#### default -設定のデフォルト値 - -## APIリファレンス -AiScript標準で組み込まれているAPIは掲載しません。 - -### Mk:dialog(title text type) -ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。 - -### Mk:confirm(title text type) -確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。 - -### Mk:api(endpoint params) -Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。 - -### Mk:save(key value) -任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。 - -### Mk:load(key) -Mk:saveで永続化した指定の名前の値を読み取ります。 - -### Plugin:register_post_form_action(title fn) -投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。 - -### Plugin:register_note_action(title fn) -ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 - -### Plugin:register_user_action(title fn) -ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。 - -### Plugin:register_note_view_interruptor(fn) -UIに表示されるノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:register_note_post_interruptor(fn) -ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:open_url(url) -第一引数に渡されたURLをブラウザの新しいタブで開きます。 - -### Plugin:config -プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。 diff --git a/src/docs/ja-KS/custom-emoji.md b/src/docs/ja-KS/custom-emoji.md deleted file mode 100644 index ed2e92be1..000000000 --- a/src/docs/ja-KS/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# カスタム絵文字 -カスタム絵文字は、インスタンスで用意された画像を絵文字のように使える機能です。 ノート、リアクション、チャット、自己紹介、名前などの場所で使うことができます。 カスタム絵文字をそれらの場所で使うには、絵文字ピッカーボタン(ある場合)を押すか、`:`を入力して絵文字サジェストを表示します。 テキスト内に`:foo:`のような形式の文字列が見つかると、`foo`の部分がカスタム絵文字名と解釈され、表示時には対応したカスタム絵文字に置き換わります。 diff --git a/src/docs/ja-KS/deck.md b/src/docs/ja-KS/deck.md deleted file mode 100644 index 8057e262f..000000000 --- a/src/docs/ja-KS/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# デッキ - -デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。 - -## カラムの追加 -デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。 - -## カラムの移動 -カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。 - -## カラムの水平分割 -カラムは左右だけでなく、上下に並べることもできます。 カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 上下分割を解除するには、カラムメニューの「右に出す」を選択します。 - -## カラムの設定 -カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。 - -## デッキの設定 -デッキに関する設定は、[settings/deck](/settings/deck)で行えます。 diff --git a/src/docs/ja-KS/features/antenna.md b/src/docs/ja-KS/features/antenna.md deleted file mode 100644 index 4e977f569..000000000 --- a/src/docs/ja-KS/features/antenna.md +++ /dev/null @@ -1,4 +0,0 @@ -# アンテナ -アンテナは、自由に条件を設定して、それに合うたノートを自動で集められる機能や。 - -条件の設定されとうアンテナが作成されとう状態で、それに合うたノートが投稿されたら、リアルタイムでそのアンテナのタイムラインにノートが追加されるで。 diff --git a/src/docs/ja-KS/features/custom-emoji.md b/src/docs/ja-KS/features/custom-emoji.md deleted file mode 100644 index 6480fcd43..000000000 --- a/src/docs/ja-KS/features/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# カスタム絵文字 -カスタム絵文字は、インスタンスで用意されとう画像を絵文字みたいに使える機能や。ノート、リアクション、チャット、自己紹介、名前などの場所で使えるで。カスタム絵文字をそれらの場所で使うには、絵文字ピッカーボタン(あるなら)を押すか、`:`を入力して絵文字サジェストを表示したらええ。 テキスト内に`:foo:`のような形式の絵文字が見つかったら、`foo`の部分がカスタム絵文字名と解釈されて、表示時にはそれに合うたカスタム絵文字に置き換わるで。 diff --git a/src/docs/ja-KS/features/deck.md b/src/docs/ja-KS/features/deck.md deleted file mode 100644 index 42962db76..000000000 --- a/src/docs/ja-KS/features/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# デッキ - -デッキは利用可能なUIのひとつや。「カラム」っちゅうビューを複数並べて表示さすことで、カスタマイズ性が高うて、情報量がようさんあるUIを構築できることが特徴やで。 - -## カラムの追加 -デッキの背景を右クリックして、「カラムを追加」で任意のカラムを追加できるで。 - -## カラムの移動 -カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えられる以外にも、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させられるで。 - -## カラムの水平分割 -カラムは左右だけやなく、上下にも並べられるんや。 カラムメニューを開いて、「左に重ねる」を選択したら、左のカラムの下に現在のカラムが移動すんねん。 上下分割を解除したいなら、カラムメニューの「右に出す」を選択したらええで。 - -## カラムの設定 -カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。 - -## デッキの設定 -デッキに関する設定は、[settings/deck](/settings/deck)で行えます。 diff --git a/src/docs/ja-KS/features/drive.md b/src/docs/ja-KS/features/drive.md deleted file mode 100644 index b82a41082..000000000 --- a/src/docs/ja-KS/features/drive.md +++ /dev/null @@ -1,17 +0,0 @@ -# ドライブ -ドライブは、Misskey上でファイルを管理できる機能です。 - -[ドライブのページ](/my/drive)から任意のファイルをアップロードできるほか、アバターに設定した画像や、ノートに添付したファイルなどもすべてドライブにアップロードされます。 - -
⚠️ ドライブからファイルを削除すると、そのファイルが添付されたノートも消えます。
- -ドライブにアップロードされたファイルは、いつでもダウンロードすることができるほか、ノート作成時に「ドライブからファイルを添付」することでファイルを再利用することもできます。 - -ドライブ内にフォルダを作り、複数のファイルをまとめて整理することもできます。 - -## 閲覧注意 (NSFW) -
ℹ️ この項目が閲覧注意なわけではありません
- -閲覧注意またはNSFW (Not safe for work) は、ドライブのファイルに設定することができるフラグです。 閲覧注意フラグを設定されたファイルは、表示される際に閲覧者の操作なしには表示されなくなります。 このフラグは、例えば職場や公共の場で閲覧するのに適切でないと思われる画像などに設定し、そのような画像が突然表示されてしまうことを防ぐ目的で使われます。 - -このフラグは手動でオンオフを切り替えられるほか、モデレーターの判断で設定される場合もあります。 diff --git a/src/docs/ja-KS/features/favorite.md b/src/docs/ja-KS/features/favorite.md deleted file mode 100644 index a0e5f8bf7..000000000 --- a/src/docs/ja-KS/features/favorite.md +++ /dev/null @@ -1,4 +0,0 @@ -# お気に入り -[ノート](./node)をお気に入りとして登録できる機能です。 お気に入り登録したノートは、[お気に入りページ](./my/favorites)で一覧することができます。 お気に入りに登録したことは相手に通知されず、お気に入りは自分しか見ることができません。 - -ノートをお気に入り登録するには、ノートメニューの「お気に入り」を押します。お気に入り解除するには、ノートメニューの「お気に入り解除」を押します。 diff --git a/src/docs/ja-KS/features/follow.md b/src/docs/ja-KS/features/follow.md deleted file mode 100644 index 3c1ea7bbe..000000000 --- a/src/docs/ja-KS/features/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# フォロー -ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。 diff --git a/src/docs/ja-KS/features/keyboard-shortcut.md b/src/docs/ja-KS/features/keyboard-shortcut.md deleted file mode 100644 index b4b0d53a7..000000000 --- a/src/docs/ja-KS/features/keyboard-shortcut.md +++ /dev/null @@ -1,66 +0,0 @@ -# キーボードショートカット - -## グローバル -これらのショートカットは基本的にどこでも使えます。 - - - - - - - - - - - -
ショートカット効果由来
P, N新規投稿Post, New, Note
Tタイムラインの最も新しい投稿にフォーカスTimeline, Top
Shift + N通知を表示/隠すNotifications
S探すSearch
H, ?ヘルプを表示Help
- -## 投稿にフォーカスされた状態 - - - - - - - - - - - - - - - - - - -
ショートカット効果由来
, K, Shift + Tab上の投稿にフォーカスを移動-
, J, Tab下の投稿にフォーカスを移動-
R返信フォームを開くReply
QRenoteフォームを開くQuote
Ctrl + Q即刻Renoteする(フォームを開かずに)-
E, A, +リアクションフォームを開くEmote, reAction
0~9数字に対応したリアクションをする(対応については後述)-
F, Bお気に入りに登録Favorite, Bookmark
Del, Ctrl + D投稿を削除Delete
M, O投稿に対するメニューを開くMore, Other
SCWで隠された部分を表示 or 隠すShow, See
Escフォーカスを外す-
- -## Renoteフォーム - - - - - - - - - -
ショートカット効果由来
EnterRenoteする-
Qフォームを展開するQuote
Escフォームを閉じる-
- -## リアクションフォーム -デフォルトで「👍」にフォーカスが当たっている状態です。 - - - - - - - - - - - - - -
ショートカット効果由来
, K上のリアクションにフォーカスを移動-
, J下のリアクションにフォーカスを移動-
, H, Shift + Tab左のリアクションにフォーカスを移動-
, L, Tab右のリアクションにフォーカスを移動-
Enter, Space, +リアクション確定-
0~9数字に対応したリアクションで確定-
Escリアクションするのをやめる-
diff --git a/src/docs/ja-KS/features/mfm.md b/src/docs/ja-KS/features/mfm.md deleted file mode 100644 index 5be2df4f3..000000000 --- a/src/docs/ja-KS/features/mfm.md +++ /dev/null @@ -1,12 +0,0 @@ -# MFM -MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます。 - -## MFMが使用可能な場所の例 -- ノート本文 -- CW注釈 -- ユーザーの名前 -- ユーザーの自己紹介 - -## 開発者向け情報 -MFMのパーサー実装はライブラリとして公開されており、簡単にクライアントにMFMを組み込むことが可能です。 -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptパーサー実装 diff --git a/src/docs/ja-KS/features/mute-and-block.md b/src/docs/ja-KS/features/mute-and-block.md deleted file mode 100644 index d78a7cea4..000000000 --- a/src/docs/ja-KS/features/mute-and-block.md +++ /dev/null @@ -1,41 +0,0 @@ -# ミュートとブロック -好みではないユーザーがいる場合は、ミュートを行うことでそのユーザーが自分から見えないようにすることができます。 また、より強力な措置として、ブロックを行うことでそのユーザーから自分のコンテンツが見えないようになるほか、自分に対して関わることができないようにすることができます。 ミュートされていることは相手は分かりませんが、ブロックされていることは相手に分かります。どちらを選ぶかはご自身の判断で行ってください。 - -
ℹ️ ミュートとブロックは併用できます。
- -
⚠️ 利用規約に違反するような、迷惑なユーザーがいる場合は運営者に報告することも検討してください。
- -設定>ミュートとブロック から、自分がミュートまたはブロックしているユーザー一覧を確認することができます。 - -## ミュート -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -- タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -- そのユーザーからの通知 -- メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 -- など - -ユーザーをミュートするには、対象のユーザーのユーザーページのメニューを開き、「ミュート」ボタンを押します。 - -
ℹ️ ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。
- -## ブロック -ユーザーをブロックすると、そのユーザーからあなたのコンテンツが見えないようになり、またあなたに対して以下のようなアクションをすることができなくなります。 - -- フォローする -- ユーザーリストに追加する -- 返信する、Renoteする -- リアクションする、アンケートに投票する -- メッセージを送信する -- など - -また、 - -- ブロックする際に既にそのユーザーからフォローされていた場合はフォローが解除されます。 -- ブロックする際に既にそのユーザーがあなたをユーザーリストに入れていた場合はそのリストからあなたが削除されます。 - -ユーザーをブロックするには、対象のユーザーのユーザーページのメニューを開き、「ブロック」ボタンを押します。 - -
⚠️ ブロックを行ったこと自体は相手に通知されませんが、フォローを行ったりなどの上記のアクションが行えなくなるので間接的にブロックされていることは分かります。
- -
⚠️ 相手から自分のコンテンツが見えなくなりますが、相手がアカウントを切り替えたりログアウト状態になれば見ることができます。あくまで簡易的、補助的なものとしてお考えください。
diff --git a/src/docs/ja-KS/features/mute.md b/src/docs/ja-KS/features/mute.md deleted file mode 100644 index 6a9608662..000000000 --- a/src/docs/ja-KS/features/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# ミュート - -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -* タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -* そのユーザーからの通知 -* メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 - -ユーザーをミュートするには、対象のユーザーのユーザーページに表示されている「ミュート」ボタンを押します。 - -ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。 - -設定>ミュート から、自分がミュートしているユーザー一覧を確認することができます。 diff --git a/src/docs/ja-KS/features/note.md b/src/docs/ja-KS/features/note.md deleted file mode 100644 index 531bed403..000000000 --- a/src/docs/ja-KS/features/note.md +++ /dev/null @@ -1,54 +0,0 @@ -# ノート -ノートは、Misskeyに投稿される、文章、ファイル、アンケートなどを含むコンテンツで、Misskeyの中心的概念です。また、そのノートを作成する行為自体もノートと呼ばれます。 - -ノートが作成されると、[タイムライン](./timeline)に追加され、自分の[フォロワー](./follow)やサーバーのユーザーが見れるようになります。 - -ノートには、[リアクション](./reaction)を行うことができます。また、返信や引用もできます。 - -ノートを[お気に入り](./favorite)登録することで、後で簡単に見返すことができます。 - -## ノートを作成する -ノートを作成するには、画面上にある鉛筆マークのボタンを押して、作成フォームを開きます。作成フォームに内容を入力し、「ノート」ボタンを押すことでノートが作成されます。 ノートには、画像、動画など任意のファイルや、[アンケート](./poll)を添付することができます。また、本文中には[MFM](./mfm)が使用でき、[メンション](./mention)や[ハッシュタグ](./hashtag)を含めることもできます。 他にも、CWや公開範囲といった設定も行えます(詳細は後述)。 -
ℹ️ コンピューターのクリップボードに画像データがある状態で、フォーム内のテキストボックスにペーストするとその画像を添付することができます。
-
ℹ️ テキストボックス内でCtrl + Enterを押すことでも投稿できます。
- -## Renote -既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノートをRenoteと呼びます。 自分がフォローしているユーザーの、気に入ったノートを自分のフォロワーに共有したい場合や、過去の自分のノートを再度共有したい場合に使います。 同じノートに対して無制限にRenoteを行うことができますが、あまり連続して使用すると迷惑になる場合もあるので、注意しましょう。 -
⚠️ 公開範囲がフォロワーやダイレクトのノートはRenoteできません
- -Renoteを削除するには、Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 - -## CW -Contents Warningの略で、ノートの内容を、閲覧者の操作なしには表示しないようにできる機能です。主に長大な内容を隠すためや、ネタバレ防止などに使うことができます。 設定するには、フォームの「内容を隠す」ボタン(目のアイコン)を押します。すると新しい入力エリアが表れるので、そこに内容の要約を記入します。 - -## 公開範囲 -ノートごとに、そのノートが公開される範囲を設定することができます。フォームの「ノート」ボタンの左にあるアイコンを押すと公開範囲を以下から選択できます。 - -### パブリック -全ての人に対してノートが公開されるほか、サーバーの全てのタイムライン(ホームタイムライン、ローカルタイムライン、ソーシャルタイムライン、グローバルタイムライン)にノートが流れます。 -
⚠️ アカウントがサイレンス状態の時は、この公開範囲は使用できません。
- -### ホーム -全ての人に対してノートが公開されますが、フォロワー以外のローカルタイムライン、ソーシャルタイムライン、グローバルタイムラインにはノートは流れません。 - -### フォロワー -自分のフォロワーに対してのみノートを公開します。フォロワーの全てのタイムラインに流れます。 - -### ダイレクト -指定したユーザーに対してのみノートを公開します。指定したユーザーの全てのタイムラインに流れます。 - -### 「ローカルのみ」オプション -このオプションを有効にすると、リモートにノートを連合しなくなります。 - -### 公開範囲の比較 - - - - -
パブリックホームフォロワーダイレクト
フォロワーのLTL/STL/GTL
非フォロワーのLTL/STL/GTL
- -## ピン留めしとく -ノートをピン留めすると、ユーザーページに常にそのノートを表示しておくことができます。 ノートのメニューを開き、「ピン留め」を選択してピン留めできます。 複数のノートをピン留めできます。 - -## ウォッチ -ノートをウォッチすると、自分以外のノートへのリアクションや返信などの通知を受け取ることができます。 ノートのメニューを開き、「ウォッチ」を選択してウォッチできます。 diff --git a/src/docs/ja-KS/features/pages.md b/src/docs/ja-KS/features/pages.md deleted file mode 100644 index a7311b95e..000000000 --- a/src/docs/ja-KS/features/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# Pages - -## 変数 -変数を使うことで動的なページを作成できます。テキスト内で { 変数名 } と書くとそこに変数の値を埋め込めます。例えば Hello { thing } world! というテキストで、変数(thing)の値が ai だった場合、テキストは Hello ai world! になります。 - -変数の評価(値を算出すること)は上から下に行われるので、ある変数の中で自分より下の変数を参照することはできません。例えば上から A、B、C と3つの変数を定義したとき、Cの中でABを参照することはできますが、Aの中でBCを参照することはできません。 - -ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。 - -関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。 diff --git a/src/docs/ja-KS/features/reaction.md b/src/docs/ja-KS/features/reaction.md deleted file mode 100644 index 3a3d23201..000000000 --- a/src/docs/ja-KS/features/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# リアクション -他人のノートに、絵文字を付けて簡単に自分の反応を伝えられる機能や。 リアクションすんには、ノートの + アイコンをクリックしてピッカーを表示して、絵文字を選択したらええ。 リアクションには[カスタム絵文字](./custom-emoji)も使用できんで。 - -## リアクションピッカーのカスタマイズ -ピッカーに表示されよう絵文字を自分好みにカスタマイズできるで。 設定の「リアクション」で設定しいや。 - -## リモート投稿へのリアクションについて -リアクションはMisskeyオリジナルの機能やから、リモートインスタンスがMisskeyちゃうかったら、ほとんどの場合「Like」としてアクティビティが送信されんで。一般的にLikeは「お気に入り」として実装されようみたいや。 - -## リモートからのリアクションについて -リモートから「Like」のアクティビティを受信したら、Misskeyでは「👍」のリアクションとして解釈されるで。 diff --git a/src/docs/ja-KS/features/silence.md b/src/docs/ja-KS/features/silence.md deleted file mode 100644 index 7e26feab0..000000000 --- a/src/docs/ja-KS/features/silence.md +++ /dev/null @@ -1,6 +0,0 @@ -# サイレンス -サイレンスは、アカウントに設定される状態のひとつです。 - -アカウントがサイレンス状態になると、ノートの公開範囲をパブリックにできなくなります。 ホーム、フォロワー、ダイレクトは選択可能なため、サイレンスを受けた場合でもフォロワーやあなたのユーザーページを直接訪れた場合は投稿を閲覧できますが、GTL(連合タイムライン)やLTL(ローカルタイムライン)には投稿が流れません。 - -アカウントのサイレンス状態は、サーバーのモデレーターによって有効化/無効化されます。 diff --git a/src/docs/ja-KS/features/theme.md b/src/docs/ja-KS/features/theme.md deleted file mode 100644 index a406f3433..000000000 --- a/src/docs/ja-KS/features/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# テーマ - -テーマを設定して、Misskeyクライアントの見た目を変更できます。 - -## テーマの設定 -設定 > テーマ - -## テーマを作成する -テーマコードはJSON5で記述されたテーマオブジェクトです。 テーマは以下のようなオブジェクトです。 -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... テーマの一意なID。UUIDをおすすめします。 -* `name` ... テーマ名 -* `author` ... テーマの作者 -* `desc` ... テーマの説明(オプション) -* `base` ... 明るいテーマか、暗いテーマか - * `light`にすると明るいテーマになり、`dark`にすると暗いテーマになります。 - * テーマはここで設定されたベーステーマを継承します。 -* `props` ... テーマのスタイル定義。これから説明します。 - -### テーマのスタイル定義 -`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 - -#### バリューで使える構文 -* 16進数で表された色 - * 例: `#00ff00` -* `rgb(r, g, b)`形式で表された色 - * 例: `rgb(0, 255, 0)` -* `rgb(r, g, b, a)`形式で表された透明度を含む色 - * 例: `rgba(0, 255, 0, 0.5)` -* 他のキーの値の参照 - * `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。 - * 例: `@panel` -* 定数(後述)の参照 - * `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。 - * 例: `$main` -* 関数(後述) - * `:{関数名}<{引数}<{色}` - -#### 定数 -「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 キー名を`$`で始めると、そのキーはCSS変数として出力されません。 - -#### 関数 -wip diff --git a/src/docs/ja-KS/features/timeline.md b/src/docs/ja-KS/features/timeline.md deleted file mode 100644 index f431014f8..000000000 --- a/src/docs/ja-KS/features/timeline.md +++ /dev/null @@ -1,31 +0,0 @@ -# タイムライン -タイムラインは、[ノート](./note)が時系列で表示される機能です。 タイムラインには以下で示す種類があり、種類によって表示されるノートも異なります。 なお、タイムラインの種類によってはサーバーにより無効になっている場合があります。 - -## ホーム -自分のフォローしているユーザーの投稿が流れます。HTLと略されます。 - -## ローカル -全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。LTLと略されます。 - -## ソーシャル -自分のフォローしているユーザーの投稿と、全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。STLと略されます。 - -## グローバル -全てのローカルユーザーの「ホーム」指定されていない投稿と、サーバーに届いた全てのリモートユーザーの「ホーム」指定されていない投稿が流れます。GTLと略されます。 - -## 比較 -| ソース | | | タイムライン | | | -| ------------ | ----- | --- | ------ | ----- | ----- | -| ユーザー | 公開範囲 | ホーム | ローカル | ソーシャル | グローバル | -| ローカル (フォロー) | 公開 | ✔ | ✔ | ✔ | ✔ | -| | ホーム | ✔ | | ✔ | | -| | フォロワー | ✔ | ✔ | ✔ | ✔ | -| リモート (フォロー) | 公開 | ✔ | | ✔ | ✔ | -| | ホーム | ✔ | | ✔ | | -| | フォロワー | ✔ | | ✔ | ✔ | -| ローカル (未フォロー) | 公開 | | ✔ | ✔ | ✔ | -| | ホーム | | | | | -| | フォロワー | | | | | -| リモート (未フォロー) | 公開 | | | | ✔ | -| | ホーム | | | | | -| | フォロワー | | | | | diff --git a/src/docs/ja-KS/features/widgets.md b/src/docs/ja-KS/features/widgets.md deleted file mode 100644 index a7c2c1d1d..000000000 --- a/src/docs/ja-KS/features/widgets.md +++ /dev/null @@ -1,7 +0,0 @@ -# ウィジェット -ウィジェットは、MisskeyのUI上に設置できる小型の情報表示、操作が行えるパーツです。 - -ウィジェットを編集するには、ウィジェット編集モードに切り替えます。切り替え方法はUIによって異なります。 ウィジェット編集モードでは、ウィジェットの追加、削除、並び替え、およびそれぞれのウィジェットの設定を行えます。 - -## 利用可能なウィジェット一覧 -todo diff --git a/src/docs/ja-KS/features/word-mute.md b/src/docs/ja-KS/features/word-mute.md deleted file mode 100644 index fa4d14346..000000000 --- a/src/docs/ja-KS/features/word-mute.md +++ /dev/null @@ -1,20 +0,0 @@ -# ワードミュート -ワードミュートの設定をすると、条件に合致したノートが表示されなくなります。 - -ワードミュートには、ソフトワードミュートとハードワードミュートの2種類があります。それぞれについて設定の方法と挙動を説明します。 - -## ソフトワードミュート -ソフトワードミュートは、クライアント(アプリ)側でミュートを判断するワードミュートです。 - -ノートが設定した条件に合致すると、「(ユーザー名)が何かを言いました」という表示で隠れます。 -クリックすると元の通りに表示されます。 - -## ハードワードミュート -ハードワードミュートは、アンテナのようにサーバーが新しいノートの本文に対して条件に合致するかどうか判断し、タイムラインから対象となったノートを除外します。 - -つまり、ハードワードミュートには、以下のような特徴があります。 - -* 条件設定後、新しい投稿のみがミュートの対象になります。 -* 条件を変更しても、過去にハードミュートされたノートはミュートされたままになります。 -* 「○○が何かを言いました」でタイムラインが埋まることがありません。 -* ソフトミュートに非対応のアプリでも、ハードミュートは適用されます。 diff --git a/src/docs/ja-KS/follow.md b/src/docs/ja-KS/follow.md deleted file mode 100644 index 3c1ea7bbe..000000000 --- a/src/docs/ja-KS/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# フォロー -ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。 diff --git a/src/docs/ja-KS/general/apps.md b/src/docs/ja-KS/general/apps.md deleted file mode 100644 index 1f4c85fe8..000000000 --- a/src/docs/ja-KS/general/apps.md +++ /dev/null @@ -1,6 +0,0 @@ -# サードパーティアプリのリスト -## クライアント -todo - -## 連携サービス -todo diff --git a/src/docs/ja-KS/general/changelog.md b/src/docs/ja-KS/general/changelog.md deleted file mode 100644 index 6766a63b2..000000000 --- a/src/docs/ja-KS/general/changelog.md +++ /dev/null @@ -1,5 +0,0 @@ -# 更新履歴 -
ℹ️ このサーバーの更新履歴です。Misskeyの最新のリリースについては、GitHubをご確認ください。
- - - diff --git a/src/docs/ja-KS/general/faq.md b/src/docs/ja-KS/general/faq.md deleted file mode 100644 index 7da242343..000000000 --- a/src/docs/ja-KS/general/faq.md +++ /dev/null @@ -1,28 +0,0 @@ -# ようある質問 -ここでは利用上のよくある質問について掲載しています。 Misskeyのプロジェクト自体についてのよくある質問は[こちら](./misskey)に掲載されています。 - -## iOS/Androidのアプリはありますか? -公式にはそういったOSのネイティブアプリを開発していませんが、サードパーティ製のアプリがいくつかあります。 詳しくは[こちら](./apps)をご覧ください。 - -ただ、サードパーティ製アプリはどうしても機能への対応が遅れてしまうため、とくに拘りがなければ公式のWebクライアントの利用をおすすめします。 なお、MisskeyのWebクライアントはPWAに対応しているので、ネイティブアプリのように動作させることも可能です。 詳しくは[こちら](todo)をご覧ください。 - -## Mastodonクライアントでログインできないのですが? -MisskeyはMastodonのAPIと互換性がないため、一部を除きMastodonクライアントでMisskeyを利用することはできません。 - -## 他のサーバーのユーザーをフォローするときは? -メニューから検索を選び、ユーザー名をホスト込みで入力します。例: `@syuilo@misskey.io` - -## Renoteを削除するには? -Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 Renoteについては[こちら](../features/note)をご確認ください。 - -## URLのプレビューを表示させたくない -MFMには、そのURLのプレビューを無効にする構文があります。詳細は[MFMチートシート](/mfm-cheat-sheet)をご確認ください。 - -## カスタム絵文字を追加したい -運営者のみがカスタム絵文字を追加、編集、削除できます。それらを希望する場合は運営者に依頼してください。 - -## Botを開発したい -Misskey APIを利用してBotの開発が可能です。[こちら](../advanced/develop-bot)をご確認ください。 - -## ノートの翻訳機能はどのサービスを使用していますか? -[DeepL](https://www.deepl.com/)を使用しています。 diff --git a/src/docs/ja-KS/general/glossary.md b/src/docs/ja-KS/general/glossary.md deleted file mode 100644 index bb8a24336..000000000 --- a/src/docs/ja-KS/general/glossary.md +++ /dev/null @@ -1,89 +0,0 @@ -# 用語集 -Misskeyに関する用語集です。 - -## ActivityPub -(読み: あくてぃびてぃぱぶ) 分散型を実現するために用いられるプロトコル(仕様)。このプロトコルに則ってサーバー同士通信を行うことで、連合が行われ、Fediverseを形成しています。 - -## AiScript -(読み: あいすくりぷと) Misskey上で使用できるプログラミング言語です。詳細は[こちら。](../advanced/aiscript) - -## API -(読み: えーぴーあい) Misskeyのサーバーが公開している、プログラムからMisskeyを扱うためのインターフェース。詳細は[こちら。](../advanced/api) - -## Bot -(読み: ぼっと) プログラムによって動作しているアカウント。 - -## CW -(読み: こんてんつわーにんぐ) Contents Warningの略。ノートの内容を、操作なしには表示しないようにできる機能。主に長大な内容を隠すためや、ネタバレ防止などに使われます。 - -## Fediverse -(読み: ふぇでぃばーす) Misskeyを含む様々な分散型ソフトウェアのサーバーで構成されたネットワーク。 - -## GTL -グローバルタイムライン(Global TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## HTL -ホームタイムライン(Home TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## LTL -ローカルタイムライン(Local TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## MFM -(読み: えむえふえむ) Misskey Flavored Markdownの略で、Misskey上で使用できるマークアップ言語です。詳細は[こちら。](../features/mfm) - -## NSFW -(読み: のっとせーふふぉーわーく) Not Safe For Workの略。画像を「閲覧注意」扱いにし、操作なしには表示しないようにすることができる機能。 - -## Renote -(読み: りのーと) 既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノート。詳細は[こちら。](../features/note) - -## STL -ソーシャルタイムライン(Social TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## 藍 -(読み: あい) Misskeyの看板娘(公式キャラクター)です。 - -## アクティブユーザー -インスタンスにアカウントを作っているユーザーのうち、現在も実際にサービスを利用しているユーザーのこと。 - -## インスタンス -todo - -## カスタム絵文字 -サーバーで用意された絵文字。カスタム絵文字ではない通常の絵文字は「Unicode絵文字」と区別して呼ばれる。 - -## コントロールパネル -インスタンスの設定画面のこと。 - -## サーバー -todo - -## サイレンス -ノートをパブリックな公開範囲で投稿できなくされている状態。モデレーターの判断でユーザーごとに設定されます。詳細は[こちら。](../features/silence) - -## ジョブキュー -アクティビティ配送などを順番に行うためのシステム。 - -## 凍結 -アカウントが使用不可に設定されている状態。 - -## ドライブ -Misskeyにアップロードしたファイルを管理する機能。詳細は[こちら。](../features/drive) - -## ノート -Misskeyに投稿される、文章、ファイル、アンケートなどを含めることができるコンテンツ。詳細は[こちら。](../features/note) - -## ミスキスト -Misskeyを使う人のこと。 - -## モデレーター -スパムの凍結およびサイレンスや不適切な投稿の削除など、コミュニティ運営に関する権限を持つユーザー。 - -## リモート -他サーバーのことを指します。リモートユーザーといったように接頭辞としても使われます。ローカルの逆です。 - -## 連合 -サーバー上で作成された情報が他のサーバーに伝わること。 - -## ローカル -自サーバーのことを指します。ローカルユーザー、ローカルタイムラインといったように接頭辞としても使われます。リモートの逆です。 diff --git a/src/docs/ja-KS/general/links.md b/src/docs/ja-KS/general/links.md deleted file mode 100644 index 5ce5e1ddb..000000000 --- a/src/docs/ja-KS/general/links.md +++ /dev/null @@ -1,12 +0,0 @@ -# リンク集 - -## Webサイト -- [Official Discord](https://discord.gg/Wp8gVStHW3) - Misskey公式Discordサーバー -- [Misskey Forum](https://forum.misskey.io/) - Misskeyに関する話題を扱うフォーラム - -## アカウント -- [@repo@misskey.io](https://misskey.io/@repo) - Misskeyのリポジトリの更新を投稿するbot - -## ライブラリ -- [misskey-dev/misskey.js](https://github.com/misskey-dev/misskey.js) - JavaScriptのMisskey SDK -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptのMFMパーサー実装 diff --git a/src/docs/ja-KS/general/misskey.md b/src/docs/ja-KS/general/misskey.md deleted file mode 100644 index 4bb6ca657..000000000 --- a/src/docs/ja-KS/general/misskey.md +++ /dev/null @@ -1,87 +0,0 @@ -# Misskeyってなんや? - -Misskeyはオープンソースの分散型マイクロブログプラットフォームプロジェクトです。 開発は日本でsyuiloによって2014年から開始されました。 ドライブ、リアクションなどの豊富な機能や、高いカスタマイズ性を備えたUIを持つことが特徴です。 - -## 歴史 -開発当初は掲示板がメインのサービスでしたが、ユーザーが短文を投稿し、それを時系列で流れるタイムライン機能を追加したところ人気が高まり、徐々にそれがメインとして開発が進むようになりました。 当初は分散型ではありませんでしたが、2018年にActivityPubを実装し分散型になったことで、より多くの方に認知され利用されるサービスになり、現在に至ります。 -
ℹ️ Misskeyという名前は、syuiloが当時聴いていたMay'nというアーティストの楽曲、Brain Diverの歌詞に由来します。
- -誰でも開発に参加することができ、現在でも活発に開発が続いています。 - -## 分散型とは何か? - -分散(distributed)型とは、非中央集権(decentralized)とも呼ばれ、コミュニティが多数のサーバーに分散して存在し、それらが相互に通信(連合、federation)することでコンテンツ共有ネットワーク(Fediverse)を形成していることが特徴のサービスです。 単一のサーバーしか存在しない、もしくは複数存在しても互いに独立している場合は中央集権なサービスと言われ、例えばTwitterやFacebookなどほとんどのサービスがそれに該当します。 分散型のメリットは、自分に合った運営者やテーマのサーバーを選択できることです。自分でサーバーを作成することもできます。連合するおかげで、どのサーバーを選んでも、同じコミュニティにアクセスできます。 - -## 常にオープンソース -Misskeyはこれまでもこれからも、オープンソースであり続けます。オープンソースとは、簡単に言うとソフトウェアのソースコード(プログラム)が公開されていることです。ソースコードの修正や再配布が可能であることを定義に含めることもあります。 Misskeyのすべてのソースコードは[AGPL](https://github.com/misskey-dev/misskey/blob/develop/LICENSE)というオープンソースライセンスの下に[公開](https://github.com/misskey-dev)されていて、誰でも自由に閲覧、使用、修正、改変、再配布をすることができます。 オープンソースは、自分で好きなように変えたり、有害な処理が含まれていないことを確認することができたり、誰でも開発に参加できるなどの、様々なメリットがあります。 上述の分散型を実現するためにも、オープンソースであるということは必要不可欠な要素です。 再び引き合いに出しますが、TwitterやFacebookなどの利益を得ているほとんどのサービスはオープンソースではありません。 - -
ℹ️ 技術的に言うと、MisskeyのソースコードはGitで管理されていて、リポジトリはGitHub上でホスティングされています。
- -## 開発に参加する、プロジェクトを支援する -Misskeyを気に入っていただけたら、ぜひプロジェクトを支援してください。プロジェクトに貢献するには、以下で紹介するようにいろいろな方法があります。方法によっては開発のスキルは不要なので、誰でも気軽に参加し貢献することができます。いつでもお待ちしています。 - -### 機能を追加したり、バグを修正する -ソフトウェアエンジニアのスキルをお持ちの方であれば、ソースコードを編集する形でプロジェクトに貢献することができます。 貢献についてのガイドは[こちら](https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md)です。 - -### 議論に参加する -新しい機能、または既存の機能について意見を述べたり、不具合を報告したりすることでも貢献できます。 そのようなディスカッションは[GitHub](https://github.com/misskey-dev)上か、[フォーラム](https://forum.misskey.io/)等で行われます。 - -### テキストを翻訳する -Misskeyは様々な言語に対応しています(i18n -internationalizationの略- と呼ばれます)。元の言語は基本的に日本語ですが、有志によって他の言語へと翻訳されています。 その翻訳作業に加わっていただくことでもMisskeyに貢献できます。 Misskeyは[Crowdinというサービスを使用して翻訳の管理を行っています。](https://crowdin.com/project/misskey) - -### 感想を投稿する -不具合報告等だけではなく、Misskeyの良い点、楽しい点といったポジティブな意見もぜひ共有してください。開発の励みになり、それは間接的ですがプロジェクトへの貢献です。 - -### ミスキストを増やす -ミスキストとは、Misskeyを使用する人のことです。 知り合いに紹介するなどしてMisskeyを広めていただければ、ミスキストが増え開発のモチベーションが上がります。 - -### 寄付をする -Misskeyはビジネスではなく、利用は無料であるため、収益は皆様からの寄付のみです。(インスタンスによっては広告収入を得ているような場合もありますが、それは運営者の収入であり直接開発者への収入にはなりません) 寄付をしていただければ、今後も開発を続けることが可能になり、プロジェクトへの貢献になります。 寄付は基本的には[Patreon](https://www.patreon.com/syuilo)で受け付けています。 一定額寄付していただけると、Misskeyの[情報ページ](/about-misskey)に名前を記載することができます。 - -また、サーバーの運営者も、基本的には収益を得ていません。サーバーの運営にはコストがかかるので、運営者の支援をすることもご検討ください。 開発には直接関係しませんが、サーバーがあってこそのプロジェクトなので、運営が維持されるというのは開発と同じくらい重要なことです。 - -## クレジット -Misskeyの開発者や、Misskeyに寄付をしてくださった方の一覧は[こちら](/about-misskey)で見ることができます。 - -## ようある質問 -### プロジェクトは何を目指していますか? -強いて言うと、漠然的になりますが広く使われる汎用的なプラットフォームになることを目指しています。 Misskeyは他のプロジェクトとは違い、何らかの思想(例えば、反中央集権)やビジョンに基づいて開発が行われているわけではなく、その点ではフラットです。 それが逆に、特定の方向性に縛られないフレキシブルさを生み出すことに繋がっていると感じています。 - - -### 企業によって開発されていますか? -いいえ。Misskeyの開発は個人で行われており、商業的でもないため、特定の企業の関りはありません。 開発メンバーも基本的にはボランティアです。 また、開発に対し企業のスポンサーがつくこともありますが、その場合でもやはり開発は個人のコミュニティが主体です。 - -### 誰が運営していますか? -Misskeyは分散型なため、各サーバーにそれぞれ異なった運営者がいます。従って、特定の個人や企業によって、Misskeyの全てが運営されているわけではありません。 また、開発チームが運営を行うわけでもないため、運営に関する連絡は、お使いのサーバーの運営者に行ってください。 サーバーの運営者は、[このページ](/about)で確認することができます。 あなたがサーバーを作成すれば、あなたが運営者になります。 - -### どのサーバーを選べばいいですか? -[サーバー一覧が公開されています。](https://join.misskey.page/ja-JP/instances) サーバーによってコミュニティのテーマ(特定のこと、ものが好き 等)が決められている場合があるので、自分に合ったテーマのサーバーがあれば、そこを選ぶと良いかもしれません。 他にも、サーバーの規模、ユーザー層、国および言語、運営者が信頼できるかどうか、などの観点があります。 なお、Misskey公式のサーバーというものはありません。自身で新しくサーバーを作成するという選択肢もあります。 - -基本的にどのサーバーを選んだとしても、他の全てのサーバーのユーザーと繋がることができます。 - -### サーバーを建てるにはどうしたらいいですか? -Misskeyサーバーの作成に興味を持っていただきありがとうございます。 2021年現在、Misskeyのホスティングサービスは存在しないため、サーバーの作成にはある程度の知識が必要です。 サーバーの作成方法については[こちら](todo)をご覧ください。 - -### どのような技術を使用していますか? -Misskeyは開発が進むにつれ使用する技術も大きく変わってきました。開発当初はMySQL + PHP + jQueryといった構成でしたが、現在は以下のようになっています。 -- サーバーサイド: Node.js -- データベース: PostgreSQL、Redis -- UIフレームワーク: Vue.js -- プログラミング言語: TypeScript - -また、MFMやAiScriptなどの、Misskeyから派生して独自の技術も開発しています。 - -### Mastodonのフォークですか? -いいえ。MisskeyはMastodonやその他のプロジェクトとは全く別のプロジェクトです。 開発に関しても、Misskeyの方が昔から開発されています。ただし、分散型になったのはMastodonの登場より後です。 同じActivityPubという分散のためのプロトコルを実装しているという点以外、両者に特に関りがあるわけでもありません。 - -### iOS/Androidのアプリはありますか? -公式にはそういったOSのネイティブアプリを開発していませんが、サードパーティ製のアプリがいくつかあります。 詳しくは[こちら](./apps)をご覧ください。 - -ただ、サードパーティ製アプリはどうしても機能への対応が遅れてしまうため、とくに拘りがなければ公式のWebクライアントの利用をおすすめします。 なお、MisskeyのWebクライアントはPWAに対応しているので、ネイティブアプリのように動作させることも可能です。 詳しくは[こちら](todo)をご覧ください。 - -### Misskeyのロゴ、アイコンはどこで入手できますか? -(準備中) - -### 時折目にする猫耳の可愛い女の子は? -Misskeyの守り神、藍ちゃんです。アイチャンカワイイヤッター! -
ℹ️ 藍ちゃんについてはこちらです。
diff --git a/src/docs/ja-KS/general/report-issue.md b/src/docs/ja-KS/general/report-issue.md deleted file mode 100644 index 63527e32a..000000000 --- a/src/docs/ja-KS/general/report-issue.md +++ /dev/null @@ -1,8 +0,0 @@ -# 不具合の報告 -不具合と思われる状況に遭遇したときは、まず[トラブルシューティング](./troubleshooting)をご一読ください。 それでも問題が解決しないときは、以下の情報を含めて[フォーラム](https://forum.misskey.io/)に投稿してください。 投稿することで、解決策が見つかったり、不具合と判断されれば開発チームによって修正が行われます。 - -## 含める情報 -- Misskeyのバージョン([情報ページ](/about)で確認できます) -- お使いのブラウザの種類とバージョン -- お使いのOSの種類とバージョン -- 問題の再現手順 diff --git a/src/docs/ja-KS/general/troubleshooting.md b/src/docs/ja-KS/general/troubleshooting.md deleted file mode 100644 index f895b4984..000000000 --- a/src/docs/ja-KS/general/troubleshooting.md +++ /dev/null @@ -1,40 +0,0 @@ -# トラブルシューティング -
ℹ️ よくある質問も合わせてお役立てください。
- -問題が発生したときは、まずこちらをご確認ください。 該当する項目が無い、もしくは手順を試しても効果がない場合は、サーバーの管理者に連絡するか[不具合を報告](./report-issue)してください。 - -## クライアントが起動しない -ほとんどの場合、お使いのブラウザまたはOSのバージョンが古いことが原因です。 ブラウザおよびOSのバージョンを最新のものに更新してから、再度試してみてください。 - -これは稀ですが、それでも起動しない場合は、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。 - -## ページが読み込めない -クライアントが起動するもののページが読み込めないというエラーが出る場合は、ネットワークに問題がないか確認してください。また、サーバーがダウンしていないか確認してください。 - -これは稀ですが、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。 - -まだ問題がある場合は、サーバーの問題と思われるのでサーバーの管理者に連絡してください。 - -## クライアントの動作が遅い -以下を試してみてください: - -- クライアント設定で「UIのアニメーションを減らす」を有効にする -- クライアント設定で「モーダルにぼかし効果を使用」を無効にする -- お使いのブラウザの設定でハードウェアアクセラレーションを有効にする -- お使いのデバイスのスペックを上げる - -## UIの一部の表示がおかしい(背景が透明になっている等) -アップデートによりUIの改修が行われたときに、テーマのキャッシュシステムの影響でそのような表示になることがあります。 クライアントの設定の「キャッシュをクリア」すると直ります。 -
⚠️ 「クライアントの」キャッシュクリアです。「ブラウザの」キャッシュクリアは行わないでください。
- -## 通知やアンテナ等の点滅が消えない -点滅は、未読のコンテンツがあることを示しています。通常点滅が消えない場合は、コンテンツを遡ると未読なコンテンツが残っています。 すべて既読にしたと思われるのに、それでもなお点滅が続く場合(おそらく不具合と思われます)は設定から強制的にすべて既読扱いにすることができます。 - -## Renoteができない -フォロワー限定のノートはRenoteすることはできません。 - -## UI上で特定の要素が表示されない -広告ブロッカーを使用しているとそのような不具合が発生することがあります。Misskeyではオフにしてご利用ください。 - -## UI上で未翻訳の部分がある -ほとんどの場合、単に翻訳が間に合っていないだけで、不具合ではありません。翻訳が終わるまでお待ちください。 [翻訳に参加](./misskey)していただくことも可能です。 diff --git a/src/docs/ja-KS/keyboard-shortcut.md b/src/docs/ja-KS/keyboard-shortcut.md deleted file mode 100644 index 8469098cf..000000000 --- a/src/docs/ja-KS/keyboard-shortcut.md +++ /dev/null @@ -1,68 +0,0 @@ -# キーボードショートカット - -## グローバル -これらのショートカットは基本的にどこでも使えます。 - - - - - - - - - - - -
ショートカット効果由来
P, N新規投稿Post, New, Note
Tタイムラインの最も新しい投稿にフォーカスTimeline, Top
Shift + N通知を表示/隠すNotifications
S探すSearch
H, ?ヘルプを表示Help
- -## 投稿にフォーカスされた状態 - - - - - - - - - - - - - - - - - - - -
ショートカット効果由来
, K, Shift + Tab上の投稿にフォーカスを移動-
, J, Tab下の投稿にフォーカスを移動-
R返信フォームを開くReply
QRenoteフォームを開くQuote
Ctrl + Q即刻Renoteする(フォームを開かずに)-
E, A, +リアクションフォームを開くEmote, reAction
0~9数字に対応したリアクションをする(対応については後述)-
F, Bお気に入りに登録Favorite, Bookmark
Del, Ctrl + D投稿を削除Delete
M, O投稿に対するメニューを開くMore, Other
SCWで隠された部分を表示 or 隠すShow, See
Escフォーカスを外す-
- -## Renoteフォーム - - - - - - - - - - -
ショートカット効果由来
EnterRenoteする-
Qフォームを展開するQuote
Escフォームを閉じる-
- -## リアクションフォーム -デフォルトで「👍」にフォーカスが当たっている状態です。 - - - - - - - - - - - - - -
ショートカット効果由来
, K上のリアクションにフォーカスを移動-
, J下のリアクションにフォーカスを移動-
, H, Shift + Tab左のリアクションにフォーカスを移動-
, L, Tab右のリアクションにフォーカスを移動-
Enter, Space, +リアクション確定-
0~9数字に対応したリアクションで確定-
Escリアクションするのをやめる-
diff --git a/src/docs/ja-KS/mfm.md b/src/docs/ja-KS/mfm.md deleted file mode 100644 index e237287ac..000000000 --- a/src/docs/ja-KS/mfm.md +++ /dev/null @@ -1,2 +0,0 @@ -# MFM -MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます。 diff --git a/src/docs/ja-KS/mute.md b/src/docs/ja-KS/mute.md deleted file mode 100644 index 6a9608662..000000000 --- a/src/docs/ja-KS/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# ミュート - -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -* タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -* そのユーザーからの通知 -* メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 - -ユーザーをミュートするには、対象のユーザーのユーザーページに表示されている「ミュート」ボタンを押します。 - -ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。 - -設定>ミュート から、自分がミュートしているユーザー一覧を確認することができます。 diff --git a/src/docs/ja-KS/pages.md b/src/docs/ja-KS/pages.md deleted file mode 100644 index a7311b95e..000000000 --- a/src/docs/ja-KS/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# Pages - -## 変数 -変数を使うことで動的なページを作成できます。テキスト内で { 変数名 } と書くとそこに変数の値を埋め込めます。例えば Hello { thing } world! というテキストで、変数(thing)の値が ai だった場合、テキストは Hello ai world! になります。 - -変数の評価(値を算出すること)は上から下に行われるので、ある変数の中で自分より下の変数を参照することはできません。例えば上から A、B、C と3つの変数を定義したとき、Cの中でABを参照することはできますが、Aの中でBCを参照することはできません。 - -ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。 - -関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。 diff --git a/src/docs/ja-KS/reaction.md b/src/docs/ja-KS/reaction.md deleted file mode 100644 index c26ead75b..000000000 --- a/src/docs/ja-KS/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# リアクション -他の人のノートに、絵文字を付けて簡単にあなたの反応を伝えられる機能です。 リアクションするには、ノートの + アイコンをクリックしてピッカーを表示し、絵文字を選択します。 リアクションには[カスタム絵文字](./custom-emoji)も使用できます。 - -## リアクションピッカーのカスタマイズ -ピッカーに表示される絵文字を自分好みにカスタマイズすることができます。 設定の「リアクション」で設定します。 - -## リモート投稿へのリアクションについて -リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。 また、相手がMisskeyであったとしても、カスタム絵文字リアクションは伝わらず、自動的に「👍」等にフォールバックされます。 - -## リモートからのリアクションについて -リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。 diff --git a/src/docs/ja-KS/reversi-bot.md b/src/docs/ja-KS/reversi-bot.md deleted file mode 100644 index 7ab2a7212..000000000 --- a/src/docs/ja-KS/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# MisskeyリバーシBotの開発 -Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。 - -1. `games/reversi`ストリームに以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - -2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる - * イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている - -3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する - -4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - * `game`: `game`の`id` - -5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う - -6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する - -7. ゲームが開始すると、`started`イベントが流れてくる - * イベントの中身にはゲーム情報が含まれている - -8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述) - -9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる - * `color`として石の色が含まれている - * `pos`として位置情報が含まれている - -## 位置の計算法 -8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### X,Y座標 から インデックス に変換する -``` -pos = x + (y * mapWidth) -``` -`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます: -``` -mapWidth = map[0].length -``` - -### インデックス から X,Y座標 に変換する -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## マップ情報 -マップ情報は、ゲーム情報の`map`に入っています。 文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 それをもとにマップのデザインを知る事が出来ます: -* `(スペース)` ... マス無し -* `-` ... マス -* `b` ... 初期配置される黒石 -* `w` ... 初期配置される白石 - -例えば、4*4の次のような単純なマップがあるとします: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -この場合、マップデータはこのようになります: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## ユーザーにフォームを提示して対話可能Botを作成する -ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。 - -フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します: -```javascript -{ - type: 'init-form', - body: [フォームコントロールの配列] -} -``` - -フォームコントロールの配列については今から説明します。 フォームコントロールは、次のようなオブジェクトです: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... コントロールのID。 `type` ... コントロールの種類。後述します。 `label` ... コントロールと一緒に表記するテキスト。 `value` ... コントロールのデフォルト値。 - -### フォームの操作を受け取る -ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### フォームコントロールの種類 -#### スイッチ -type: `switch` スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。 - -##### プロパティ -`label` ... スイッチに表記するテキスト。 - -#### ラジオボタン -type: `radio` ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。 - -##### プロパティ -`items` ... ラジオボタンの選択肢。例: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '強', - value: 3 -}] -``` - -#### スライダー -type: `slider` スライダーを表示します。 - -##### プロパティ -`min` ... スライダーの下限。 `max` ... スライダーの上限。 `step` ... 入力欄で刻むステップ値。 - -#### テキストボックス -type: `textbox` テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。 - -## ユーザーにメッセージを表示する -設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 メッセージを表示するには、次のメッセージをストリームに送信します: -```javascript -{ - type: 'message', - body: { - text: 'メッセージ内容', - type: 'メッセージの種類' - } -} -``` -メッセージの種類: `success`, `info`, `warning`, `error`。 - -## 投了する -投了をするには、このエンドポイントにリクエストします。 diff --git a/src/docs/ja-KS/stream.md b/src/docs/ja-KS/stream.md deleted file mode 100644 index 9011c37c5..000000000 --- a/src/docs/ja-KS/stream.md +++ /dev/null @@ -1,354 +0,0 @@ -# ストリーミングAPI - -ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。 - -## ストリームに接続する - -ストリーミングAPIを利用するには、まずMisskeyサーバーに**websocket**接続する必要があります。 - -以下のURLに、`i`というパラメータ名で認証情報を含めて、websocket接続してください。例: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。 - -
-

認証情報の取得については、こちらのドキュメントをご確認ください。

-
- ---- - -認証情報は省略することもできますが、その場合非ログインでの利用ということになり、受信できる情報や可能な操作は限られます。例: - -``` -%WS_URL%/streaming -``` - ---- - -ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。 - -**ストリームでのやり取りはすべてJSONです。** - -## チャンネル -MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。 - -### チャンネルに接続する -チャンネルに接続するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -ここで、 -* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。 -* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。 -* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。 - -
-

IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。

-
- -### チャンネルからのメッセージを受け取る -例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。 - -チャンネルがメッセージを発すると、次のようなデータがJSONでストリームに流れてきます: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。 -* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。 -* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。 - -### チャンネルに向けてメッセージを送信する -チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。 - -チャンネルにメッセージを送信するには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。 -* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。 -* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。 - -### チャンネルから切断する -チャンネルから切断するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。 - -## ストリームを経由してAPIリクエストする - -ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。 - -ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -ここで、 -* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 -* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 -* `data`には、エンドポイントのパラメータを含めます。 - -
-

APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。

-
- -### レスポンスの受信 - -APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。 - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -ここで、 -* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 -* `body`には、レスポンスが含まれています。 - -## 投稿のキャプチャ - -Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。 - -例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。 - -しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。 - -この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。 - -### 投稿をキャプチャする - -投稿をキャプチャするには、ストリームに次のようなメッセージを送信します: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャしたい投稿の`id`を設定します。 - -このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 - -例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -ここで、 -* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。 -* `body`内の`type`に、イベントの種類が設定されます。 -* `body`内の`body`に、イベントの詳細が設定されます。 - -#### イベントの種類 - -##### `reacted` -その投稿にリアクションがされた時に発生します。 - -* `reaction`に、リアクションの種類が設定されます。 -* `userId`に、リアクションを行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -その投稿が削除された時に発生します。 - -* `deletedAt`に、削除日時が設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -その投稿に添付されたアンケートに投票された時に発生します。 - -* `choice`に、選択肢IDが設定されます。 -* `userId`に、投票を行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### 投稿のキャプチャを解除する - -その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。 - -次のメッセージを送信します: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャを解除したい投稿の`id`を設定します。 - -このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 - -# チャンネル一覧 -## `main` -アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `renote` -自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。 - -#### `mention` -誰かからメンションされたときに発生するイベントです。 - -#### `readAllNotifications` -自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。 - -#### `meUpdated` -自分の情報が更新されたことを表すイベントです。 - -#### `follow` -自分が誰かをフォローしたときに発生するイベントです。 - -#### `unfollow` -自分が誰かのフォローを解除したときに発生するイベントです。 - -#### `followed` -自分が誰かにフォローされたときに発生するイベントです。 - -## `homeTimeline` -ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -タイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `localTimeline` -ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `hybridTimeline` -ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ソーシャルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `globalTimeline` -グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 diff --git a/src/docs/ja-KS/theme.md b/src/docs/ja-KS/theme.md deleted file mode 100644 index a406f3433..000000000 --- a/src/docs/ja-KS/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# テーマ - -テーマを設定して、Misskeyクライアントの見た目を変更できます。 - -## テーマの設定 -設定 > テーマ - -## テーマを作成する -テーマコードはJSON5で記述されたテーマオブジェクトです。 テーマは以下のようなオブジェクトです。 -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... テーマの一意なID。UUIDをおすすめします。 -* `name` ... テーマ名 -* `author` ... テーマの作者 -* `desc` ... テーマの説明(オプション) -* `base` ... 明るいテーマか、暗いテーマか - * `light`にすると明るいテーマになり、`dark`にすると暗いテーマになります。 - * テーマはここで設定されたベーステーマを継承します。 -* `props` ... テーマのスタイル定義。これから説明します。 - -### テーマのスタイル定義 -`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 - -#### バリューで使える構文 -* 16進数で表された色 - * 例: `#00ff00` -* `rgb(r, g, b)`形式で表された色 - * 例: `rgb(0, 255, 0)` -* `rgb(r, g, b, a)`形式で表された透明度を含む色 - * 例: `rgba(0, 255, 0, 0.5)` -* 他のキーの値の参照 - * `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。 - * 例: `@panel` -* 定数(後述)の参照 - * `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。 - * 例: `$main` -* 関数(後述) - * `:{関数名}<{引数}<{色}` - -#### 定数 -「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 キー名を`$`で始めると、そのキーはCSS変数として出力されません。 - -#### 関数 -wip diff --git a/src/docs/ja-KS/timelines.md b/src/docs/ja-KS/timelines.md deleted file mode 100644 index 36ba61bd2..000000000 --- a/src/docs/ja-KS/timelines.md +++ /dev/null @@ -1,15 +0,0 @@ -# タイムラインの比較 - -https://docs.google.com/spreadsheets/d/1lxQ2ugKrhz58Bg96HTDK_2F98BUritkMyIiBkOByjHA/edit?usp=sharing - -## ホーム -自分のフォローしているユーザーの投稿 - -## ローカル -全てのローカルユーザーの「ホーム」指定されていない投稿 - -## ソーシャル -自分のフォローしているユーザーの投稿と、全てのローカルユーザーの「ホーム」指定されていない投稿 - -## グローバル -全てのローカルユーザーの「ホーム」指定されていない投稿と、サーバーに届いた全てのリモートユーザーの「ホーム」指定されていない投稿 diff --git a/src/docs/jbo-EN/admin/disable-timelines.md b/src/docs/jbo-EN/admin/disable-timelines.md deleted file mode 100644 index b081e35ab..000000000 --- a/src/docs/jbo-EN/admin/disable-timelines.md +++ /dev/null @@ -1,8 +0,0 @@ -# LTL/STL/GTLの無効化 -Misskeyでは、LTL/STL/GTLをそれぞれ無効化することができます。有効/無効を切り替えるには、インスタンスコントロールパネルで設定します。 - -LTLやSTLは、そのインスタンス全員の投稿が見れるため、新規のユーザーにとってはユーザーを探す必要がなくなり、興味のあるユーザーを見つけやすいという利点があります。 しかし同時に、フォロー機能が活用されなくなったり、不適切な投稿が目につきやすくなったり、チャットのようになることで内輪感が生じて逆に新規ユーザーが参加しにくくなるといったデメリットも持ち合わせています。 サーバーによってメリット/デメリットどちらが優勢かは異なるので、オプションとして無効にできるようになっています。 もしデメリットの方が上回っていると感じたら、それらのタイムラインを無効化することも検討してください。 - -
⚠️ 無効化を行うと、ユーザーが困惑し、短期的に見て利用者が減る可能性があります。そのため、無効化の際は影響を慎重に検討し、事前に説明してフォローを整える期間を一定程度設けることを推奨します。
- -なお、管理者/モデレーターは、これらのタイムラインの無効化状態は適用されず、引き続き利用することが可能です。 diff --git a/src/docs/jbo-EN/admin/faq.md b/src/docs/jbo-EN/admin/faq.md deleted file mode 100644 index 317b4e065..000000000 --- a/src/docs/jbo-EN/admin/faq.md +++ /dev/null @@ -1,5 +0,0 @@ -# よくある質問 -ここでは、サーバー管理者向けのよくある質問を掲載しています。 - -## デフォルトテーマを設定したい -現在、デフォルトテーマ設定機能は実装されていません。 diff --git a/src/docs/jbo-EN/advanced/aiscript.md b/src/docs/jbo-EN/advanced/aiscript.md deleted file mode 100644 index 604d17daa..000000000 --- a/src/docs/jbo-EN/advanced/aiscript.md +++ /dev/null @@ -1,7 +0,0 @@ -# AiScript -AiScriptは、Misskeyで使用できるスクリプト言語です。 - -
ℹ️ AiScript実装はMisskeyとは別リポジトリで、オープンソースで公開されています。
- -## 使い方 -AiScriptの構文や組み込み関数などのドキュメントは、[こちら](https://github.com/syuilo/aiscript/tree/master/docs)で公開されています。 diff --git a/src/docs/jbo-EN/advanced/api.md b/src/docs/jbo-EN/advanced/api.md deleted file mode 100644 index 76019b614..000000000 --- a/src/docs/jbo-EN/advanced/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス、Bot等(以下「アプリケーション」と呼びます)を開発できます。 ストリーミングAPIもあるので、リアルタイム性のあるアプリケーションを作ることも可能です。 - -APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。 - -## アクセストークンの取得 -基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。 - -* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む -* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む - -### 自分自身のアクセストークンを手動発行する -「設定 > API」で、自分のアクセストークンを発行できます。 - -[「APIの使い方」へ進む](#APIの使い方) - -### アプリケーション利用者にアクセストークンの発行をリクエストする -アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。 - -#### Step 1 - -UUIDを生成する。以後これをセッションIDと呼びます。 - -> このセッションIDは毎回生成し、使いまわさないようにしてください。 - -#### Step 2 - -`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。 -> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます: -* `name` ... アプリケーション名 - * > 例: `MissDeck` -* `icon` ... アプリケーションのアイコン画像URL - * > 例: `https://missdeck.example.com/icon.png` -* `callback` ... 認証が終わった後にリダイレクトするURL - * > 例: `https://missdeck.example.com/callback` - * リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます -* `permission` ... アプリケーションが要求する権限 - * > 例: `write:notes,write:following,read:drive` - * 要求する権限を`,`で区切って列挙します - * どのような権限があるかは[APIリファレンス](/api-doc)で確認できます - -#### Step 3 -ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。 - -レスポンスに含まれるプロパティ: -* `token` ... ユーザーのアクセストークン -* `user` ... ユーザーの情報 - -[「APIの使い方」へ進む](#APIの使い方) - -## APIの使い方 -**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。 - -* [APIリファレンス](/api-doc) -* [ストリーミングAPI](./stream) diff --git a/src/docs/jbo-EN/advanced/create-plugin.md b/src/docs/jbo-EN/advanced/create-plugin.md deleted file mode 100644 index 0d2fa1917..000000000 --- a/src/docs/jbo-EN/advanced/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# プラグインの作成 -Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。 - -## メタデータ -プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。 - -### name -プラグイン名 - -### author -プラグイン作者 - -### version -プラグインバージョン。数値を指定してください。 - -### description -プラグインの説明 - -### permissions -プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。 - -### config -プラグインの設定情報を表すオブジェクト。 キーに設定名、値に以下のプロパティを含めます。 - -#### type -設定値の種類を表す文字列。以下から選択します。 string number boolean - -#### label -ユーザーに表示する設定名 - -#### description -設定の説明 - -#### default -設定のデフォルト値 - -## APIリファレンス -AiScript標準で組み込まれているAPIは掲載しません。 - -### Mk:dialog(title text type) -ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。 - -### Mk:confirm(title text type) -確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。 - -### Mk:api(endpoint params) -Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。 - -### Mk:save(key value) -任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。 - -### Mk:load(key) -Mk:saveで永続化した指定の名前の値を読み取ります。 - -### Plugin:register_post_form_action(title fn) -投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。 - -### Plugin:register_note_action(title fn) -ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 - -### Plugin:register_user_action(title fn) -ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。 - -### Plugin:register_note_view_interruptor(fn) -UIに表示されるノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:register_note_post_interruptor(fn) -ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:open_url(url) -第一引数に渡されたURLをブラウザの新しいタブで開きます。 - -### Plugin:config -プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。 diff --git a/src/docs/jbo-EN/advanced/develop-bot.md b/src/docs/jbo-EN/advanced/develop-bot.md deleted file mode 100644 index 7f825e9bc..000000000 --- a/src/docs/jbo-EN/advanced/develop-bot.md +++ /dev/null @@ -1,6 +0,0 @@ -# Botの作成 -[Misskey API](./api)を利用してBotの開発が可能です。 また、いくつかのBot実装が公開されているため、ぜひ参考にしてください。 - -- [syuilo/ai](https://github.com/syuilo/ai) ... Node.js上で動く、TypeScript製Bot実装 - -Botを作成したときは、プロフィール設定からBotフラグをオンにしておくことを強くおすすめします。 diff --git a/src/docs/jbo-EN/advanced/reversi-bot.md b/src/docs/jbo-EN/advanced/reversi-bot.md deleted file mode 100644 index 7ab2a7212..000000000 --- a/src/docs/jbo-EN/advanced/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# MisskeyリバーシBotの開発 -Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。 - -1. `games/reversi`ストリームに以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - -2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる - * イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている - -3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する - -4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - * `game`: `game`の`id` - -5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う - -6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する - -7. ゲームが開始すると、`started`イベントが流れてくる - * イベントの中身にはゲーム情報が含まれている - -8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述) - -9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる - * `color`として石の色が含まれている - * `pos`として位置情報が含まれている - -## 位置の計算法 -8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### X,Y座標 から インデックス に変換する -``` -pos = x + (y * mapWidth) -``` -`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます: -``` -mapWidth = map[0].length -``` - -### インデックス から X,Y座標 に変換する -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## マップ情報 -マップ情報は、ゲーム情報の`map`に入っています。 文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 それをもとにマップのデザインを知る事が出来ます: -* `(スペース)` ... マス無し -* `-` ... マス -* `b` ... 初期配置される黒石 -* `w` ... 初期配置される白石 - -例えば、4*4の次のような単純なマップがあるとします: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -この場合、マップデータはこのようになります: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## ユーザーにフォームを提示して対話可能Botを作成する -ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。 - -フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します: -```javascript -{ - type: 'init-form', - body: [フォームコントロールの配列] -} -``` - -フォームコントロールの配列については今から説明します。 フォームコントロールは、次のようなオブジェクトです: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... コントロールのID。 `type` ... コントロールの種類。後述します。 `label` ... コントロールと一緒に表記するテキスト。 `value` ... コントロールのデフォルト値。 - -### フォームの操作を受け取る -ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### フォームコントロールの種類 -#### スイッチ -type: `switch` スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。 - -##### プロパティ -`label` ... スイッチに表記するテキスト。 - -#### ラジオボタン -type: `radio` ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。 - -##### プロパティ -`items` ... ラジオボタンの選択肢。例: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '強', - value: 3 -}] -``` - -#### スライダー -type: `slider` スライダーを表示します。 - -##### プロパティ -`min` ... スライダーの下限。 `max` ... スライダーの上限。 `step` ... 入力欄で刻むステップ値。 - -#### テキストボックス -type: `textbox` テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。 - -## ユーザーにメッセージを表示する -設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 メッセージを表示するには、次のメッセージをストリームに送信します: -```javascript -{ - type: 'message', - body: { - text: 'メッセージ内容', - type: 'メッセージの種類' - } -} -``` -メッセージの種類: `success`, `info`, `warning`, `error`。 - -## 投了する -投了をするには、このエンドポイントにリクエストします。 diff --git a/src/docs/jbo-EN/advanced/share-page.md b/src/docs/jbo-EN/advanced/share-page.md deleted file mode 100644 index 4fb7ded0b..000000000 --- a/src/docs/jbo-EN/advanced/share-page.md +++ /dev/null @@ -1,54 +0,0 @@ -# シェアページ -`/share`を開くと、共有用の投稿フォームを開くことができます。 ここではシェアページで利用できるクエリ文字列の一覧を示します。 - -## クエリ文字列一覧 -### 文字 - -
-
title
-
タイトルです。本文の先頭に[ … ]と挿入されます。
-
text
-
本文です。
-
url
-
URLです。末尾に挿入されます。
-
- -### リプライ情報 -以下のいずれか - -
-
replyId
-
リプライ先のノートid
-
replyUri
-
リプライ先のUrl(リモートのノートオブジェクトを指定)
-
- -### Renote情報 -以下のいずれか - -
-
renoteId
-
Renote先のノートid
-
renoteUri
-
Renote先のUrl(リモートのノートオブジェクトを指定)
-
- -### 公開範囲 -※specifiedに相当する値はvisibility=specifiedとvisibleAccts/visibleUserIdsで指定する - -
-
visibility
-
公開範囲 ['public' | 'home' | 'followers' | 'specified']
-
localOnly
-
0(false) or 1(true)
-
visibleUserIds
-
specified時のダイレクト先のユーザーid カンマ区切りで
-
visibleAccts
-
specified時のダイレクト先のacct(@?username[@host]) カンマ区切りで
-
- -### ファイル -
-
fileIds
-
添付したいファイルのid(カンマ区切りで)
-
diff --git a/src/docs/jbo-EN/advanced/stream.md b/src/docs/jbo-EN/advanced/stream.md deleted file mode 100644 index 0e5edd2b0..000000000 --- a/src/docs/jbo-EN/advanced/stream.md +++ /dev/null @@ -1,350 +0,0 @@ -# ストリーミングAPI - -ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。 - -## ストリームに接続する - -ストリーミングAPIを利用するには、まずMisskeyサーバーに**websocket**接続する必要があります。 - -以下のURLに、`i`というパラメータ名で認証情報を含めて、websocket接続してください。例: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。 - -
ℹ️ 認証情報の取得については、こちらのドキュメントをご確認ください。
- ---- - -認証情報は省略することもできますが、その場合非ログインでの利用ということになり、受信できる情報や可能な操作は限られます。例: - -``` -%WS_URL%/streaming -``` - ---- - -ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。 - -**ストリームでのやり取りはすべてJSONです。** - -## チャンネル -MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。 - -ひとつのストリーム上で、同時に複数のチャンネルに接続することができます。 - -### チャンネルに接続する -チャンネルに接続するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -ここで、 -* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。 -* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。 -* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。 - -
ℹ️ IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。
- -### チャンネルからのメッセージを受け取る -例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。 - -チャンネルがメッセージを発すると、次のようなデータがJSONでストリームに流れてきます: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。 -* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。 -* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。 - -### チャンネルに向けてメッセージを送信する -チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。 - -チャンネルにメッセージを送信するには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。 -* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。 -* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。 - -### チャンネルから切断する -チャンネルから切断するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。 - -## ストリームを経由してAPIリクエストする - -ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。 - -ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -ここで、 -* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 -* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 -* `data`には、エンドポイントのパラメータを含めます。 - -
ℹ️ APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。
- -### レスポンスの受信 - -APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。 - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -ここで、 -* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 -* `body`には、レスポンスが含まれています。 - -## 投稿のキャプチャ - -Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。 - -例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。 - -しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。 - -この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。 - -### 投稿をキャプチャする - -投稿をキャプチャするには、ストリームに次のようなメッセージを送信します: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャしたい投稿の`id`を設定します。 - -このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 - -例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -ここで、 -* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。 -* `body`内の`type`に、イベントの種類が設定されます。 -* `body`内の`body`に、イベントの詳細が設定されます。 - -#### イベントの種類 - -##### `reacted` -その投稿にリアクションがされた時に発生します。 - -* `reaction`に、リアクションの種類が設定されます。 -* `userId`に、リアクションを行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -その投稿が削除された時に発生します。 - -* `deletedAt`に、削除日時が設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -その投稿に添付されたアンケートに投票された時に発生します。 - -* `choice`に、選択肢IDが設定されます。 -* `userId`に、投票を行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### 投稿のキャプチャを解除する - -その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。 - -次のメッセージを送信します: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャを解除したい投稿の`id`を設定します。 - -このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 - -# チャンネル一覧 -## `main` -アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `renote` -自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。 - -#### `mention` -誰かからメンションされたときに発生するイベントです。 - -#### `readAllNotifications` -自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。 - -#### `meUpdated` -自分の情報が更新されたことを表すイベントです。 - -#### `follow` -自分が誰かをフォローしたときに発生するイベントです。 - -#### `unfollow` -自分が誰かのフォローを解除したときに発生するイベントです。 - -#### `followed` -自分が誰かにフォローされたときに発生するイベントです。 - -## `homeTimeline` -ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -タイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `localTimeline` -ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `hybridTimeline` -ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ソーシャルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `globalTimeline` -グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 diff --git a/src/docs/jbo-EN/aiscript.md b/src/docs/jbo-EN/aiscript.md deleted file mode 100644 index 6c28b446e..000000000 --- a/src/docs/jbo-EN/aiscript.md +++ /dev/null @@ -1,4 +0,0 @@ -# AiScript - -## 関数 -デフォルトで値渡しです。 diff --git a/src/docs/jbo-EN/api.md b/src/docs/jbo-EN/api.md deleted file mode 100644 index 76019b614..000000000 --- a/src/docs/jbo-EN/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス、Bot等(以下「アプリケーション」と呼びます)を開発できます。 ストリーミングAPIもあるので、リアルタイム性のあるアプリケーションを作ることも可能です。 - -APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。 - -## アクセストークンの取得 -基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。 - -* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む -* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む - -### 自分自身のアクセストークンを手動発行する -「設定 > API」で、自分のアクセストークンを発行できます。 - -[「APIの使い方」へ進む](#APIの使い方) - -### アプリケーション利用者にアクセストークンの発行をリクエストする -アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。 - -#### Step 1 - -UUIDを生成する。以後これをセッションIDと呼びます。 - -> このセッションIDは毎回生成し、使いまわさないようにしてください。 - -#### Step 2 - -`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。 -> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます: -* `name` ... アプリケーション名 - * > 例: `MissDeck` -* `icon` ... アプリケーションのアイコン画像URL - * > 例: `https://missdeck.example.com/icon.png` -* `callback` ... 認証が終わった後にリダイレクトするURL - * > 例: `https://missdeck.example.com/callback` - * リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます -* `permission` ... アプリケーションが要求する権限 - * > 例: `write:notes,write:following,read:drive` - * 要求する権限を`,`で区切って列挙します - * どのような権限があるかは[APIリファレンス](/api-doc)で確認できます - -#### Step 3 -ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。 - -レスポンスに含まれるプロパティ: -* `token` ... ユーザーのアクセストークン -* `user` ... ユーザーの情報 - -[「APIの使い方」へ進む](#APIの使い方) - -## APIの使い方 -**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。 - -* [APIリファレンス](/api-doc) -* [ストリーミングAPI](./stream) diff --git a/src/docs/jbo-EN/create-plugin.md b/src/docs/jbo-EN/create-plugin.md deleted file mode 100644 index 0d2fa1917..000000000 --- a/src/docs/jbo-EN/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# プラグインの作成 -Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。 - -## メタデータ -プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。 - -### name -プラグイン名 - -### author -プラグイン作者 - -### version -プラグインバージョン。数値を指定してください。 - -### description -プラグインの説明 - -### permissions -プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。 - -### config -プラグインの設定情報を表すオブジェクト。 キーに設定名、値に以下のプロパティを含めます。 - -#### type -設定値の種類を表す文字列。以下から選択します。 string number boolean - -#### label -ユーザーに表示する設定名 - -#### description -設定の説明 - -#### default -設定のデフォルト値 - -## APIリファレンス -AiScript標準で組み込まれているAPIは掲載しません。 - -### Mk:dialog(title text type) -ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。 - -### Mk:confirm(title text type) -確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。 - -### Mk:api(endpoint params) -Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。 - -### Mk:save(key value) -任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。 - -### Mk:load(key) -Mk:saveで永続化した指定の名前の値を読み取ります。 - -### Plugin:register_post_form_action(title fn) -投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。 - -### Plugin:register_note_action(title fn) -ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 - -### Plugin:register_user_action(title fn) -ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。 - -### Plugin:register_note_view_interruptor(fn) -UIに表示されるノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:register_note_post_interruptor(fn) -ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:open_url(url) -第一引数に渡されたURLをブラウザの新しいタブで開きます。 - -### Plugin:config -プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。 diff --git a/src/docs/jbo-EN/custom-emoji.md b/src/docs/jbo-EN/custom-emoji.md deleted file mode 100644 index ed2e92be1..000000000 --- a/src/docs/jbo-EN/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# カスタム絵文字 -カスタム絵文字は、インスタンスで用意された画像を絵文字のように使える機能です。 ノート、リアクション、チャット、自己紹介、名前などの場所で使うことができます。 カスタム絵文字をそれらの場所で使うには、絵文字ピッカーボタン(ある場合)を押すか、`:`を入力して絵文字サジェストを表示します。 テキスト内に`:foo:`のような形式の文字列が見つかると、`foo`の部分がカスタム絵文字名と解釈され、表示時には対応したカスタム絵文字に置き換わります。 diff --git a/src/docs/jbo-EN/deck.md b/src/docs/jbo-EN/deck.md deleted file mode 100644 index 8057e262f..000000000 --- a/src/docs/jbo-EN/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# デッキ - -デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。 - -## カラムの追加 -デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。 - -## カラムの移動 -カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。 - -## カラムの水平分割 -カラムは左右だけでなく、上下に並べることもできます。 カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 上下分割を解除するには、カラムメニューの「右に出す」を選択します。 - -## カラムの設定 -カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。 - -## デッキの設定 -デッキに関する設定は、[settings/deck](/settings/deck)で行えます。 diff --git a/src/docs/jbo-EN/features/antenna.md b/src/docs/jbo-EN/features/antenna.md deleted file mode 100644 index 94ad9e4ae..000000000 --- a/src/docs/jbo-EN/features/antenna.md +++ /dev/null @@ -1,4 +0,0 @@ -# アンテナ -アンテナは、自由に条件を設定して、合致するノートを自動で収集することができる機能です。 - -条件を設定したアンテナが作成された状態で、条件に合致するノートが投稿されると、リアルタイムでそのアンテナのタイムラインにノートが追加されます。 diff --git a/src/docs/jbo-EN/features/custom-emoji.md b/src/docs/jbo-EN/features/custom-emoji.md deleted file mode 100644 index ed2e92be1..000000000 --- a/src/docs/jbo-EN/features/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# カスタム絵文字 -カスタム絵文字は、インスタンスで用意された画像を絵文字のように使える機能です。 ノート、リアクション、チャット、自己紹介、名前などの場所で使うことができます。 カスタム絵文字をそれらの場所で使うには、絵文字ピッカーボタン(ある場合)を押すか、`:`を入力して絵文字サジェストを表示します。 テキスト内に`:foo:`のような形式の文字列が見つかると、`foo`の部分がカスタム絵文字名と解釈され、表示時には対応したカスタム絵文字に置き換わります。 diff --git a/src/docs/jbo-EN/features/deck.md b/src/docs/jbo-EN/features/deck.md deleted file mode 100644 index 8057e262f..000000000 --- a/src/docs/jbo-EN/features/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# デッキ - -デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。 - -## カラムの追加 -デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。 - -## カラムの移動 -カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。 - -## カラムの水平分割 -カラムは左右だけでなく、上下に並べることもできます。 カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 上下分割を解除するには、カラムメニューの「右に出す」を選択します。 - -## カラムの設定 -カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。 - -## デッキの設定 -デッキに関する設定は、[settings/deck](/settings/deck)で行えます。 diff --git a/src/docs/jbo-EN/features/drive.md b/src/docs/jbo-EN/features/drive.md deleted file mode 100644 index b82a41082..000000000 --- a/src/docs/jbo-EN/features/drive.md +++ /dev/null @@ -1,17 +0,0 @@ -# ドライブ -ドライブは、Misskey上でファイルを管理できる機能です。 - -[ドライブのページ](/my/drive)から任意のファイルをアップロードできるほか、アバターに設定した画像や、ノートに添付したファイルなどもすべてドライブにアップロードされます。 - -
⚠️ ドライブからファイルを削除すると、そのファイルが添付されたノートも消えます。
- -ドライブにアップロードされたファイルは、いつでもダウンロードすることができるほか、ノート作成時に「ドライブからファイルを添付」することでファイルを再利用することもできます。 - -ドライブ内にフォルダを作り、複数のファイルをまとめて整理することもできます。 - -## 閲覧注意 (NSFW) -
ℹ️ この項目が閲覧注意なわけではありません
- -閲覧注意またはNSFW (Not safe for work) は、ドライブのファイルに設定することができるフラグです。 閲覧注意フラグを設定されたファイルは、表示される際に閲覧者の操作なしには表示されなくなります。 このフラグは、例えば職場や公共の場で閲覧するのに適切でないと思われる画像などに設定し、そのような画像が突然表示されてしまうことを防ぐ目的で使われます。 - -このフラグは手動でオンオフを切り替えられるほか、モデレーターの判断で設定される場合もあります。 diff --git a/src/docs/jbo-EN/features/favorite.md b/src/docs/jbo-EN/features/favorite.md deleted file mode 100644 index a0e5f8bf7..000000000 --- a/src/docs/jbo-EN/features/favorite.md +++ /dev/null @@ -1,4 +0,0 @@ -# お気に入り -[ノート](./node)をお気に入りとして登録できる機能です。 お気に入り登録したノートは、[お気に入りページ](./my/favorites)で一覧することができます。 お気に入りに登録したことは相手に通知されず、お気に入りは自分しか見ることができません。 - -ノートをお気に入り登録するには、ノートメニューの「お気に入り」を押します。お気に入り解除するには、ノートメニューの「お気に入り解除」を押します。 diff --git a/src/docs/jbo-EN/features/follow.md b/src/docs/jbo-EN/features/follow.md deleted file mode 100644 index 3c1ea7bbe..000000000 --- a/src/docs/jbo-EN/features/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# フォロー -ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。 diff --git a/src/docs/jbo-EN/features/keyboard-shortcut.md b/src/docs/jbo-EN/features/keyboard-shortcut.md deleted file mode 100644 index 8659ace98..000000000 --- a/src/docs/jbo-EN/features/keyboard-shortcut.md +++ /dev/null @@ -1,66 +0,0 @@ -# キーボードショートカット - -## グローバル -これらのショートカットは基本的にどこでも使えます。 - - - - - - - - - - - -
ショートカット効果由来
P, N新規投稿Post, New, Note
Tタイムラインの最も新しい投稿にフォーカスTimeline, Top
Shift + N通知を表示/隠すNotifications
S検索Search
H, ?ヘルプを表示Help
- -## 投稿にフォーカスされた状態 - - - - - - - - - - - - - - - - - - -
ショートカット効果由来
, K, Shift + Tab上の投稿にフォーカスを移動-
, J, Tab下の投稿にフォーカスを移動-
R返信フォームを開くReply
QRenoteフォームを開くQuote
Ctrl + Q即刻Renoteする(フォームを開かずに)-
E, A, +リアクションフォームを開くEmote, reAction
0~9数字に対応したリアクションをする(対応については後述)-
F, Bお気に入りに登録Favorite, Bookmark
Del, Ctrl + D投稿を削除Delete
M, O投稿に対するメニューを開くMore, Other
SCWで隠された部分を表示 or 隠すShow, See
Escフォーカスを外す-
- -## Renoteフォーム - - - - - - - - - -
ショートカット効果由来
EnterRenoteする-
Qフォームを展開するQuote
Escフォームを閉じる-
- -## リアクションフォーム -デフォルトで「👍」にフォーカスが当たっている状態です。 - - - - - - - - - - - - - -
ショートカット効果由来
, K上のリアクションにフォーカスを移動-
, J下のリアクションにフォーカスを移動-
, H, Shift + Tab左のリアクションにフォーカスを移動-
, L, Tab右のリアクションにフォーカスを移動-
Enter, Space, +リアクション確定-
0~9数字に対応したリアクションで確定-
Escリアクションするのをやめる-
diff --git a/src/docs/jbo-EN/features/mfm.md b/src/docs/jbo-EN/features/mfm.md deleted file mode 100644 index 5be2df4f3..000000000 --- a/src/docs/jbo-EN/features/mfm.md +++ /dev/null @@ -1,12 +0,0 @@ -# MFM -MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます。 - -## MFMが使用可能な場所の例 -- ノート本文 -- CW注釈 -- ユーザーの名前 -- ユーザーの自己紹介 - -## 開発者向け情報 -MFMのパーサー実装はライブラリとして公開されており、簡単にクライアントにMFMを組み込むことが可能です。 -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptパーサー実装 diff --git a/src/docs/jbo-EN/features/mute-and-block.md b/src/docs/jbo-EN/features/mute-and-block.md deleted file mode 100644 index d78a7cea4..000000000 --- a/src/docs/jbo-EN/features/mute-and-block.md +++ /dev/null @@ -1,41 +0,0 @@ -# ミュートとブロック -好みではないユーザーがいる場合は、ミュートを行うことでそのユーザーが自分から見えないようにすることができます。 また、より強力な措置として、ブロックを行うことでそのユーザーから自分のコンテンツが見えないようになるほか、自分に対して関わることができないようにすることができます。 ミュートされていることは相手は分かりませんが、ブロックされていることは相手に分かります。どちらを選ぶかはご自身の判断で行ってください。 - -
ℹ️ ミュートとブロックは併用できます。
- -
⚠️ 利用規約に違反するような、迷惑なユーザーがいる場合は運営者に報告することも検討してください。
- -設定>ミュートとブロック から、自分がミュートまたはブロックしているユーザー一覧を確認することができます。 - -## ミュート -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -- タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -- そのユーザーからの通知 -- メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 -- など - -ユーザーをミュートするには、対象のユーザーのユーザーページのメニューを開き、「ミュート」ボタンを押します。 - -
ℹ️ ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。
- -## ブロック -ユーザーをブロックすると、そのユーザーからあなたのコンテンツが見えないようになり、またあなたに対して以下のようなアクションをすることができなくなります。 - -- フォローする -- ユーザーリストに追加する -- 返信する、Renoteする -- リアクションする、アンケートに投票する -- メッセージを送信する -- など - -また、 - -- ブロックする際に既にそのユーザーからフォローされていた場合はフォローが解除されます。 -- ブロックする際に既にそのユーザーがあなたをユーザーリストに入れていた場合はそのリストからあなたが削除されます。 - -ユーザーをブロックするには、対象のユーザーのユーザーページのメニューを開き、「ブロック」ボタンを押します。 - -
⚠️ ブロックを行ったこと自体は相手に通知されませんが、フォローを行ったりなどの上記のアクションが行えなくなるので間接的にブロックされていることは分かります。
- -
⚠️ 相手から自分のコンテンツが見えなくなりますが、相手がアカウントを切り替えたりログアウト状態になれば見ることができます。あくまで簡易的、補助的なものとしてお考えください。
diff --git a/src/docs/jbo-EN/features/mute.md b/src/docs/jbo-EN/features/mute.md deleted file mode 100644 index 6a9608662..000000000 --- a/src/docs/jbo-EN/features/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# ミュート - -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -* タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -* そのユーザーからの通知 -* メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 - -ユーザーをミュートするには、対象のユーザーのユーザーページに表示されている「ミュート」ボタンを押します。 - -ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。 - -設定>ミュート から、自分がミュートしているユーザー一覧を確認することができます。 diff --git a/src/docs/jbo-EN/features/note.md b/src/docs/jbo-EN/features/note.md deleted file mode 100644 index 305ff626f..000000000 --- a/src/docs/jbo-EN/features/note.md +++ /dev/null @@ -1,54 +0,0 @@ -# ノート -ノートは、Misskeyに投稿される、文章、ファイル、アンケートなどを含むコンテンツで、Misskeyの中心的概念です。また、そのノートを作成する行為自体もノートと呼ばれます。 - -ノートが作成されると、[タイムライン](./timeline)に追加され、自分の[フォロワー](./follow)やサーバーのユーザーが見れるようになります。 - -ノートには、[リアクション](./reaction)を行うことができます。また、返信や引用もできます。 - -ノートを[お気に入り](./favorite)登録することで、後で簡単に見返すことができます。 - -## ノートを作成する -ノートを作成するには、画面上にある鉛筆マークのボタンを押して、作成フォームを開きます。作成フォームに内容を入力し、「ノート」ボタンを押すことでノートが作成されます。 ノートには、画像、動画など任意のファイルや、[アンケート](./poll)を添付することができます。また、本文中には[MFM](./mfm)が使用でき、[メンション](./mention)や[ハッシュタグ](./hashtag)を含めることもできます。 他にも、CWや公開範囲といった設定も行えます(詳細は後述)。 -
ℹ️ コンピューターのクリップボードに画像データがある状態で、フォーム内のテキストボックスにペーストするとその画像を添付することができます。
-
ℹ️ テキストボックス内でCtrl + Enterを押すことでも投稿できます。
- -## Renote -既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノートをRenoteと呼びます。 自分がフォローしているユーザーの、気に入ったノートを自分のフォロワーに共有したい場合や、過去の自分のノートを再度共有したい場合に使います。 同じノートに対して無制限にRenoteを行うことができますが、あまり連続して使用すると迷惑になる場合もあるので、注意しましょう。 -
⚠️ 公開範囲がフォロワーやダイレクトのノートはRenoteできません
- -Renoteを削除するには、Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 - -## CW -Contents Warningの略で、ノートの内容を、閲覧者の操作なしには表示しないようにできる機能です。主に長大な内容を隠すためや、ネタバレ防止などに使うことができます。 設定するには、フォームの「内容を隠す」ボタン(目のアイコン)を押します。すると新しい入力エリアが表れるので、そこに内容の要約を記入します。 - -## 公開範囲 -ノートごとに、そのノートが公開される範囲を設定することができます。フォームの「ノート」ボタンの左にあるアイコンを押すと公開範囲を以下から選択できます。 - -### パブリック -全ての人に対してノートが公開されるほか、サーバーの全てのタイムライン(ホームタイムライン、ローカルタイムライン、ソーシャルタイムライン、グローバルタイムライン)にノートが流れます。 -
⚠️ アカウントがサイレンス状態の時は、この公開範囲は使用できません。
- -### ホーム -全ての人に対してノートが公開されますが、フォロワー以外のローカルタイムライン、ソーシャルタイムライン、グローバルタイムラインにはノートは流れません。 - -### フォロワー -自分のフォロワーに対してのみノートを公開します。フォロワーの全てのタイムラインに流れます。 - -### ダイレクト -指定したユーザーに対してのみノートを公開します。指定したユーザーの全てのタイムラインに流れます。 - -### 「ローカルのみ」オプション -このオプションを有効にすると、リモートにノートを連合しなくなります。 - -### 公開範囲の比較 - - - - -
パブリックホームフォロワーダイレクト
フォロワーのLTL/STL/GTL
非フォロワーのLTL/STL/GTL
- -## ピン留め -ノートをピン留めすると、ユーザーページに常にそのノートを表示しておくことができます。 ノートのメニューを開き、「ピン留め」を選択してピン留めできます。 複数のノートをピン留めできます。 - -## ウォッチ -ノートをウォッチすると、自分以外のノートへのリアクションや返信などの通知を受け取ることができます。 ノートのメニューを開き、「ウォッチ」を選択してウォッチできます。 diff --git a/src/docs/jbo-EN/features/pages.md b/src/docs/jbo-EN/features/pages.md deleted file mode 100644 index a7311b95e..000000000 --- a/src/docs/jbo-EN/features/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# Pages - -## 変数 -変数を使うことで動的なページを作成できます。テキスト内で { 変数名 } と書くとそこに変数の値を埋め込めます。例えば Hello { thing } world! というテキストで、変数(thing)の値が ai だった場合、テキストは Hello ai world! になります。 - -変数の評価(値を算出すること)は上から下に行われるので、ある変数の中で自分より下の変数を参照することはできません。例えば上から A、B、C と3つの変数を定義したとき、Cの中でABを参照することはできますが、Aの中でBCを参照することはできません。 - -ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。 - -関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。 diff --git a/src/docs/jbo-EN/features/reaction.md b/src/docs/jbo-EN/features/reaction.md deleted file mode 100644 index 4d479fd41..000000000 --- a/src/docs/jbo-EN/features/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# リアクション -他の人のノートに、絵文字を付けて簡単にあなたの反応を伝えられる機能です。 リアクションするには、ノートの + アイコンをクリックしてピッカーを表示し、絵文字を選択します。 リアクションには[カスタム絵文字](./custom-emoji)も使用できます。 - -## リアクションピッカーのカスタマイズ -ピッカーに表示される絵文字を自分好みにカスタマイズすることができます。 設定の「リアクション」で設定します。 - -## リモート投稿へのリアクションについて -リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。 - -## リモートからのリアクションについて -リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。 diff --git a/src/docs/jbo-EN/features/silence.md b/src/docs/jbo-EN/features/silence.md deleted file mode 100644 index 7e26feab0..000000000 --- a/src/docs/jbo-EN/features/silence.md +++ /dev/null @@ -1,6 +0,0 @@ -# サイレンス -サイレンスは、アカウントに設定される状態のひとつです。 - -アカウントがサイレンス状態になると、ノートの公開範囲をパブリックにできなくなります。 ホーム、フォロワー、ダイレクトは選択可能なため、サイレンスを受けた場合でもフォロワーやあなたのユーザーページを直接訪れた場合は投稿を閲覧できますが、GTL(連合タイムライン)やLTL(ローカルタイムライン)には投稿が流れません。 - -アカウントのサイレンス状態は、サーバーのモデレーターによって有効化/無効化されます。 diff --git a/src/docs/jbo-EN/features/theme.md b/src/docs/jbo-EN/features/theme.md deleted file mode 100644 index a406f3433..000000000 --- a/src/docs/jbo-EN/features/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# テーマ - -テーマを設定して、Misskeyクライアントの見た目を変更できます。 - -## テーマの設定 -設定 > テーマ - -## テーマを作成する -テーマコードはJSON5で記述されたテーマオブジェクトです。 テーマは以下のようなオブジェクトです。 -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... テーマの一意なID。UUIDをおすすめします。 -* `name` ... テーマ名 -* `author` ... テーマの作者 -* `desc` ... テーマの説明(オプション) -* `base` ... 明るいテーマか、暗いテーマか - * `light`にすると明るいテーマになり、`dark`にすると暗いテーマになります。 - * テーマはここで設定されたベーステーマを継承します。 -* `props` ... テーマのスタイル定義。これから説明します。 - -### テーマのスタイル定義 -`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 - -#### バリューで使える構文 -* 16進数で表された色 - * 例: `#00ff00` -* `rgb(r, g, b)`形式で表された色 - * 例: `rgb(0, 255, 0)` -* `rgb(r, g, b, a)`形式で表された透明度を含む色 - * 例: `rgba(0, 255, 0, 0.5)` -* 他のキーの値の参照 - * `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。 - * 例: `@panel` -* 定数(後述)の参照 - * `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。 - * 例: `$main` -* 関数(後述) - * `:{関数名}<{引数}<{色}` - -#### 定数 -「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 キー名を`$`で始めると、そのキーはCSS変数として出力されません。 - -#### 関数 -wip diff --git a/src/docs/jbo-EN/features/timeline.md b/src/docs/jbo-EN/features/timeline.md deleted file mode 100644 index f431014f8..000000000 --- a/src/docs/jbo-EN/features/timeline.md +++ /dev/null @@ -1,31 +0,0 @@ -# タイムライン -タイムラインは、[ノート](./note)が時系列で表示される機能です。 タイムラインには以下で示す種類があり、種類によって表示されるノートも異なります。 なお、タイムラインの種類によってはサーバーにより無効になっている場合があります。 - -## ホーム -自分のフォローしているユーザーの投稿が流れます。HTLと略されます。 - -## ローカル -全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。LTLと略されます。 - -## ソーシャル -自分のフォローしているユーザーの投稿と、全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。STLと略されます。 - -## グローバル -全てのローカルユーザーの「ホーム」指定されていない投稿と、サーバーに届いた全てのリモートユーザーの「ホーム」指定されていない投稿が流れます。GTLと略されます。 - -## 比較 -| ソース | | | タイムライン | | | -| ------------ | ----- | --- | ------ | ----- | ----- | -| ユーザー | 公開範囲 | ホーム | ローカル | ソーシャル | グローバル | -| ローカル (フォロー) | 公開 | ✔ | ✔ | ✔ | ✔ | -| | ホーム | ✔ | | ✔ | | -| | フォロワー | ✔ | ✔ | ✔ | ✔ | -| リモート (フォロー) | 公開 | ✔ | | ✔ | ✔ | -| | ホーム | ✔ | | ✔ | | -| | フォロワー | ✔ | | ✔ | ✔ | -| ローカル (未フォロー) | 公開 | | ✔ | ✔ | ✔ | -| | ホーム | | | | | -| | フォロワー | | | | | -| リモート (未フォロー) | 公開 | | | | ✔ | -| | ホーム | | | | | -| | フォロワー | | | | | diff --git a/src/docs/jbo-EN/features/widgets.md b/src/docs/jbo-EN/features/widgets.md deleted file mode 100644 index a7c2c1d1d..000000000 --- a/src/docs/jbo-EN/features/widgets.md +++ /dev/null @@ -1,7 +0,0 @@ -# ウィジェット -ウィジェットは、MisskeyのUI上に設置できる小型の情報表示、操作が行えるパーツです。 - -ウィジェットを編集するには、ウィジェット編集モードに切り替えます。切り替え方法はUIによって異なります。 ウィジェット編集モードでは、ウィジェットの追加、削除、並び替え、およびそれぞれのウィジェットの設定を行えます。 - -## 利用可能なウィジェット一覧 -todo diff --git a/src/docs/jbo-EN/features/word-mute.md b/src/docs/jbo-EN/features/word-mute.md deleted file mode 100644 index fa4d14346..000000000 --- a/src/docs/jbo-EN/features/word-mute.md +++ /dev/null @@ -1,20 +0,0 @@ -# ワードミュート -ワードミュートの設定をすると、条件に合致したノートが表示されなくなります。 - -ワードミュートには、ソフトワードミュートとハードワードミュートの2種類があります。それぞれについて設定の方法と挙動を説明します。 - -## ソフトワードミュート -ソフトワードミュートは、クライアント(アプリ)側でミュートを判断するワードミュートです。 - -ノートが設定した条件に合致すると、「(ユーザー名)が何かを言いました」という表示で隠れます。 -クリックすると元の通りに表示されます。 - -## ハードワードミュート -ハードワードミュートは、アンテナのようにサーバーが新しいノートの本文に対して条件に合致するかどうか判断し、タイムラインから対象となったノートを除外します。 - -つまり、ハードワードミュートには、以下のような特徴があります。 - -* 条件設定後、新しい投稿のみがミュートの対象になります。 -* 条件を変更しても、過去にハードミュートされたノートはミュートされたままになります。 -* 「○○が何かを言いました」でタイムラインが埋まることがありません。 -* ソフトミュートに非対応のアプリでも、ハードミュートは適用されます。 diff --git a/src/docs/jbo-EN/follow.md b/src/docs/jbo-EN/follow.md deleted file mode 100644 index 3c1ea7bbe..000000000 --- a/src/docs/jbo-EN/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# フォロー -ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。 diff --git a/src/docs/jbo-EN/general/apps.md b/src/docs/jbo-EN/general/apps.md deleted file mode 100644 index 1f4c85fe8..000000000 --- a/src/docs/jbo-EN/general/apps.md +++ /dev/null @@ -1,6 +0,0 @@ -# サードパーティアプリのリスト -## クライアント -todo - -## 連携サービス -todo diff --git a/src/docs/jbo-EN/general/changelog.md b/src/docs/jbo-EN/general/changelog.md deleted file mode 100644 index 6766a63b2..000000000 --- a/src/docs/jbo-EN/general/changelog.md +++ /dev/null @@ -1,5 +0,0 @@ -# 更新履歴 -
ℹ️ このサーバーの更新履歴です。Misskeyの最新のリリースについては、GitHubをご確認ください。
- - - diff --git a/src/docs/jbo-EN/general/faq.md b/src/docs/jbo-EN/general/faq.md deleted file mode 100644 index c272b2ad4..000000000 --- a/src/docs/jbo-EN/general/faq.md +++ /dev/null @@ -1,28 +0,0 @@ -# よくある質問 -ここでは利用上のよくある質問について掲載しています。 Misskeyのプロジェクト自体についてのよくある質問は[こちら](./misskey)に掲載されています。 - -## iOS/Androidのアプリはありますか? -公式にはそういったOSのネイティブアプリを開発していませんが、サードパーティ製のアプリがいくつかあります。 詳しくは[こちら](./apps)をご覧ください。 - -ただ、サードパーティ製アプリはどうしても機能への対応が遅れてしまうため、とくに拘りがなければ公式のWebクライアントの利用をおすすめします。 なお、MisskeyのWebクライアントはPWAに対応しているので、ネイティブアプリのように動作させることも可能です。 詳しくは[こちら](todo)をご覧ください。 - -## Mastodonクライアントでログインできないのですが? -MisskeyはMastodonのAPIと互換性がないため、一部を除きMastodonクライアントでMisskeyを利用することはできません。 - -## 他のサーバーのユーザーをフォローするときは? -メニューから検索を選び、ユーザー名をホスト込みで入力します。例: `@syuilo@misskey.io` - -## Renoteを削除するには? -Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 Renoteについては[こちら](../features/note)をご確認ください。 - -## URLのプレビューを表示させたくない -MFMには、そのURLのプレビューを無効にする構文があります。詳細は[MFMチートシート](/mfm-cheat-sheet)をご確認ください。 - -## カスタム絵文字を追加したい -運営者のみがカスタム絵文字を追加、編集、削除できます。それらを希望する場合は運営者に依頼してください。 - -## Botを開発したい -Misskey APIを利用してBotの開発が可能です。[こちら](../advanced/develop-bot)をご確認ください。 - -## ノートの翻訳機能はどのサービスを使用していますか? -[DeepL](https://www.deepl.com/)を使用しています。 diff --git a/src/docs/jbo-EN/general/glossary.md b/src/docs/jbo-EN/general/glossary.md deleted file mode 100644 index bb8a24336..000000000 --- a/src/docs/jbo-EN/general/glossary.md +++ /dev/null @@ -1,89 +0,0 @@ -# 用語集 -Misskeyに関する用語集です。 - -## ActivityPub -(読み: あくてぃびてぃぱぶ) 分散型を実現するために用いられるプロトコル(仕様)。このプロトコルに則ってサーバー同士通信を行うことで、連合が行われ、Fediverseを形成しています。 - -## AiScript -(読み: あいすくりぷと) Misskey上で使用できるプログラミング言語です。詳細は[こちら。](../advanced/aiscript) - -## API -(読み: えーぴーあい) Misskeyのサーバーが公開している、プログラムからMisskeyを扱うためのインターフェース。詳細は[こちら。](../advanced/api) - -## Bot -(読み: ぼっと) プログラムによって動作しているアカウント。 - -## CW -(読み: こんてんつわーにんぐ) Contents Warningの略。ノートの内容を、操作なしには表示しないようにできる機能。主に長大な内容を隠すためや、ネタバレ防止などに使われます。 - -## Fediverse -(読み: ふぇでぃばーす) Misskeyを含む様々な分散型ソフトウェアのサーバーで構成されたネットワーク。 - -## GTL -グローバルタイムライン(Global TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## HTL -ホームタイムライン(Home TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## LTL -ローカルタイムライン(Local TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## MFM -(読み: えむえふえむ) Misskey Flavored Markdownの略で、Misskey上で使用できるマークアップ言語です。詳細は[こちら。](../features/mfm) - -## NSFW -(読み: のっとせーふふぉーわーく) Not Safe For Workの略。画像を「閲覧注意」扱いにし、操作なしには表示しないようにすることができる機能。 - -## Renote -(読み: りのーと) 既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノート。詳細は[こちら。](../features/note) - -## STL -ソーシャルタイムライン(Social TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## 藍 -(読み: あい) Misskeyの看板娘(公式キャラクター)です。 - -## アクティブユーザー -インスタンスにアカウントを作っているユーザーのうち、現在も実際にサービスを利用しているユーザーのこと。 - -## インスタンス -todo - -## カスタム絵文字 -サーバーで用意された絵文字。カスタム絵文字ではない通常の絵文字は「Unicode絵文字」と区別して呼ばれる。 - -## コントロールパネル -インスタンスの設定画面のこと。 - -## サーバー -todo - -## サイレンス -ノートをパブリックな公開範囲で投稿できなくされている状態。モデレーターの判断でユーザーごとに設定されます。詳細は[こちら。](../features/silence) - -## ジョブキュー -アクティビティ配送などを順番に行うためのシステム。 - -## 凍結 -アカウントが使用不可に設定されている状態。 - -## ドライブ -Misskeyにアップロードしたファイルを管理する機能。詳細は[こちら。](../features/drive) - -## ノート -Misskeyに投稿される、文章、ファイル、アンケートなどを含めることができるコンテンツ。詳細は[こちら。](../features/note) - -## ミスキスト -Misskeyを使う人のこと。 - -## モデレーター -スパムの凍結およびサイレンスや不適切な投稿の削除など、コミュニティ運営に関する権限を持つユーザー。 - -## リモート -他サーバーのことを指します。リモートユーザーといったように接頭辞としても使われます。ローカルの逆です。 - -## 連合 -サーバー上で作成された情報が他のサーバーに伝わること。 - -## ローカル -自サーバーのことを指します。ローカルユーザー、ローカルタイムラインといったように接頭辞としても使われます。リモートの逆です。 diff --git a/src/docs/jbo-EN/general/links.md b/src/docs/jbo-EN/general/links.md deleted file mode 100644 index 5ce5e1ddb..000000000 --- a/src/docs/jbo-EN/general/links.md +++ /dev/null @@ -1,12 +0,0 @@ -# リンク集 - -## Webサイト -- [Official Discord](https://discord.gg/Wp8gVStHW3) - Misskey公式Discordサーバー -- [Misskey Forum](https://forum.misskey.io/) - Misskeyに関する話題を扱うフォーラム - -## アカウント -- [@repo@misskey.io](https://misskey.io/@repo) - Misskeyのリポジトリの更新を投稿するbot - -## ライブラリ -- [misskey-dev/misskey.js](https://github.com/misskey-dev/misskey.js) - JavaScriptのMisskey SDK -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptのMFMパーサー実装 diff --git a/src/docs/jbo-EN/general/misskey.md b/src/docs/jbo-EN/general/misskey.md deleted file mode 100644 index d97664ddc..000000000 --- a/src/docs/jbo-EN/general/misskey.md +++ /dev/null @@ -1,87 +0,0 @@ -# Misskeyについて - -Misskeyはオープンソースの分散型マイクロブログプラットフォームプロジェクトです。 開発は日本でsyuiloによって2014年から開始されました。 ドライブ、リアクションなどの豊富な機能や、高いカスタマイズ性を備えたUIを持つことが特徴です。 - -## 歴史 -開発当初は掲示板がメインのサービスでしたが、ユーザーが短文を投稿し、それを時系列で流れるタイムライン機能を追加したところ人気が高まり、徐々にそれがメインとして開発が進むようになりました。 当初は分散型ではありませんでしたが、2018年にActivityPubを実装し分散型になったことで、より多くの方に認知され利用されるサービスになり、現在に至ります。 -
ℹ️ Misskeyという名前は、syuiloが当時聴いていたMay'nというアーティストの楽曲、Brain Diverの歌詞に由来します。
- -誰でも開発に参加することができ、現在でも活発に開発が続いています。 - -## 分散型とは何か? - -分散(distributed)型とは、非中央集権(decentralized)とも呼ばれ、コミュニティが多数のサーバーに分散して存在し、それらが相互に通信(連合、federation)することでコンテンツ共有ネットワーク(Fediverse)を形成していることが特徴のサービスです。 単一のサーバーしか存在しない、もしくは複数存在しても互いに独立している場合は中央集権なサービスと言われ、例えばTwitterやFacebookなどほとんどのサービスがそれに該当します。 分散型のメリットは、自分に合った運営者やテーマのサーバーを選択できることです。自分でサーバーを作成することもできます。連合するおかげで、どのサーバーを選んでも、同じコミュニティにアクセスできます。 - -## 常にオープンソース -Misskeyはこれまでもこれからも、オープンソースであり続けます。オープンソースとは、簡単に言うとソフトウェアのソースコード(プログラム)が公開されていることです。ソースコードの修正や再配布が可能であることを定義に含めることもあります。 Misskeyのすべてのソースコードは[AGPL](https://github.com/misskey-dev/misskey/blob/develop/LICENSE)というオープンソースライセンスの下に[公開](https://github.com/misskey-dev)されていて、誰でも自由に閲覧、使用、修正、改変、再配布をすることができます。 オープンソースは、自分で好きなように変えたり、有害な処理が含まれていないことを確認することができたり、誰でも開発に参加できるなどの、様々なメリットがあります。 上述の分散型を実現するためにも、オープンソースであるということは必要不可欠な要素です。 再び引き合いに出しますが、TwitterやFacebookなどの利益を得ているほとんどのサービスはオープンソースではありません。 - -
ℹ️ 技術的に言うと、MisskeyのソースコードはGitで管理されていて、リポジトリはGitHub上でホスティングされています。
- -## 開発に参加する、プロジェクトを支援する -Misskeyを気に入っていただけたら、ぜひプロジェクトを支援してください。プロジェクトに貢献するには、以下で紹介するようにいろいろな方法があります。方法によっては開発のスキルは不要なので、誰でも気軽に参加し貢献することができます。いつでもお待ちしています。 - -### 機能を追加したり、バグを修正する -ソフトウェアエンジニアのスキルをお持ちの方であれば、ソースコードを編集する形でプロジェクトに貢献することができます。 貢献についてのガイドは[こちら](https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md)です。 - -### 議論に参加する -新しい機能、または既存の機能について意見を述べたり、不具合を報告したりすることでも貢献できます。 そのようなディスカッションは[GitHub](https://github.com/misskey-dev)上か、[フォーラム](https://forum.misskey.io/)等で行われます。 - -### テキストを翻訳する -Misskeyは様々な言語に対応しています(i18n -internationalizationの略- と呼ばれます)。元の言語は基本的に日本語ですが、有志によって他の言語へと翻訳されています。 その翻訳作業に加わっていただくことでもMisskeyに貢献できます。 Misskeyは[Crowdinというサービスを使用して翻訳の管理を行っています。](https://crowdin.com/project/misskey) - -### 感想を投稿する -不具合報告等だけではなく、Misskeyの良い点、楽しい点といったポジティブな意見もぜひ共有してください。開発の励みになり、それは間接的ですがプロジェクトへの貢献です。 - -### ミスキストを増やす -ミスキストとは、Misskeyを使用する人のことです。 知り合いに紹介するなどしてMisskeyを広めていただければ、ミスキストが増え開発のモチベーションが上がります。 - -### 寄付をする -Misskeyはビジネスではなく、利用は無料であるため、収益は皆様からの寄付のみです。(インスタンスによっては広告収入を得ているような場合もありますが、それは運営者の収入であり直接開発者への収入にはなりません) 寄付をしていただければ、今後も開発を続けることが可能になり、プロジェクトへの貢献になります。 寄付は基本的には[Patreon](https://www.patreon.com/syuilo)で受け付けています。 一定額寄付していただけると、Misskeyの[情報ページ](/about-misskey)に名前を記載することができます。 - -また、サーバーの運営者も、基本的には収益を得ていません。サーバーの運営にはコストがかかるので、運営者の支援をすることもご検討ください。 開発には直接関係しませんが、サーバーがあってこそのプロジェクトなので、運営が維持されるというのは開発と同じくらい重要なことです。 - -## クレジット -Misskeyの開発者や、Misskeyに寄付をしてくださった方の一覧は[こちら](/about-misskey)で見ることができます。 - -## よくある質問 -### プロジェクトは何を目指していますか? -強いて言うと、漠然的になりますが広く使われる汎用的なプラットフォームになることを目指しています。 Misskeyは他のプロジェクトとは違い、何らかの思想(例えば、反中央集権)やビジョンに基づいて開発が行われているわけではなく、その点ではフラットです。 それが逆に、特定の方向性に縛られないフレキシブルさを生み出すことに繋がっていると感じています。 - - -### 企業によって開発されていますか? -いいえ。Misskeyの開発は個人で行われており、商業的でもないため、特定の企業の関りはありません。 開発メンバーも基本的にはボランティアです。 また、開発に対し企業のスポンサーがつくこともありますが、その場合でもやはり開発は個人のコミュニティが主体です。 - -### 誰が運営していますか? -Misskeyは分散型なため、各サーバーにそれぞれ異なった運営者がいます。従って、特定の個人や企業によって、Misskeyの全てが運営されているわけではありません。 また、開発チームが運営を行うわけでもないため、運営に関する連絡は、お使いのサーバーの運営者に行ってください。 サーバーの運営者は、[このページ](/about)で確認することができます。 あなたがサーバーを作成すれば、あなたが運営者になります。 - -### どのサーバーを選べばいいですか? -[サーバー一覧が公開されています。](https://join.misskey.page/ja-JP/instances) サーバーによってコミュニティのテーマ(特定のこと、ものが好き 等)が決められている場合があるので、自分に合ったテーマのサーバーがあれば、そこを選ぶと良いかもしれません。 他にも、サーバーの規模、ユーザー層、国および言語、運営者が信頼できるかどうか、などの観点があります。 なお、Misskey公式のサーバーというものはありません。自身で新しくサーバーを作成するという選択肢もあります。 - -基本的にどのサーバーを選んだとしても、他の全てのサーバーのユーザーと繋がることができます。 - -### サーバーを建てるにはどうしたらいいですか? -Misskeyサーバーの作成に興味を持っていただきありがとうございます。 2021年現在、Misskeyのホスティングサービスは存在しないため、サーバーの作成にはある程度の知識が必要です。 サーバーの作成方法については[こちら](todo)をご覧ください。 - -### どのような技術を使用していますか? -Misskeyは開発が進むにつれ使用する技術も大きく変わってきました。開発当初はMySQL + PHP + jQueryといった構成でしたが、現在は以下のようになっています。 -- サーバーサイド: Node.js -- データベース: PostgreSQL、Redis -- UIフレームワーク: Vue.js -- プログラミング言語: TypeScript - -また、MFMやAiScriptなどの、Misskeyから派生して独自の技術も開発しています。 - -### Mastodonのフォークですか? -いいえ。MisskeyはMastodonやその他のプロジェクトとは全く別のプロジェクトです。 開発に関しても、Misskeyの方が昔から開発されています。ただし、分散型になったのはMastodonの登場より後です。 同じActivityPubという分散のためのプロトコルを実装しているという点以外、両者に特に関りがあるわけでもありません。 - -### iOS/Androidのアプリはありますか? -公式にはそういったOSのネイティブアプリを開発していませんが、サードパーティ製のアプリがいくつかあります。 詳しくは[こちら](./apps)をご覧ください。 - -ただ、サードパーティ製アプリはどうしても機能への対応が遅れてしまうため、とくに拘りがなければ公式のWebクライアントの利用をおすすめします。 なお、MisskeyのWebクライアントはPWAに対応しているので、ネイティブアプリのように動作させることも可能です。 詳しくは[こちら](todo)をご覧ください。 - -### Misskeyのロゴ、アイコンはどこで入手できますか? -(準備中) - -### 時折目にする猫耳の可愛い女の子は? -Misskeyの守り神、藍ちゃんです。アイチャンカワイイヤッター! -
ℹ️ 藍ちゃんについてはこちらです。
diff --git a/src/docs/jbo-EN/general/report-issue.md b/src/docs/jbo-EN/general/report-issue.md deleted file mode 100644 index 63527e32a..000000000 --- a/src/docs/jbo-EN/general/report-issue.md +++ /dev/null @@ -1,8 +0,0 @@ -# 不具合の報告 -不具合と思われる状況に遭遇したときは、まず[トラブルシューティング](./troubleshooting)をご一読ください。 それでも問題が解決しないときは、以下の情報を含めて[フォーラム](https://forum.misskey.io/)に投稿してください。 投稿することで、解決策が見つかったり、不具合と判断されれば開発チームによって修正が行われます。 - -## 含める情報 -- Misskeyのバージョン([情報ページ](/about)で確認できます) -- お使いのブラウザの種類とバージョン -- お使いのOSの種類とバージョン -- 問題の再現手順 diff --git a/src/docs/jbo-EN/general/troubleshooting.md b/src/docs/jbo-EN/general/troubleshooting.md deleted file mode 100644 index f895b4984..000000000 --- a/src/docs/jbo-EN/general/troubleshooting.md +++ /dev/null @@ -1,40 +0,0 @@ -# トラブルシューティング -
ℹ️ よくある質問も合わせてお役立てください。
- -問題が発生したときは、まずこちらをご確認ください。 該当する項目が無い、もしくは手順を試しても効果がない場合は、サーバーの管理者に連絡するか[不具合を報告](./report-issue)してください。 - -## クライアントが起動しない -ほとんどの場合、お使いのブラウザまたはOSのバージョンが古いことが原因です。 ブラウザおよびOSのバージョンを最新のものに更新してから、再度試してみてください。 - -これは稀ですが、それでも起動しない場合は、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。 - -## ページが読み込めない -クライアントが起動するもののページが読み込めないというエラーが出る場合は、ネットワークに問題がないか確認してください。また、サーバーがダウンしていないか確認してください。 - -これは稀ですが、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。 - -まだ問題がある場合は、サーバーの問題と思われるのでサーバーの管理者に連絡してください。 - -## クライアントの動作が遅い -以下を試してみてください: - -- クライアント設定で「UIのアニメーションを減らす」を有効にする -- クライアント設定で「モーダルにぼかし効果を使用」を無効にする -- お使いのブラウザの設定でハードウェアアクセラレーションを有効にする -- お使いのデバイスのスペックを上げる - -## UIの一部の表示がおかしい(背景が透明になっている等) -アップデートによりUIの改修が行われたときに、テーマのキャッシュシステムの影響でそのような表示になることがあります。 クライアントの設定の「キャッシュをクリア」すると直ります。 -
⚠️ 「クライアントの」キャッシュクリアです。「ブラウザの」キャッシュクリアは行わないでください。
- -## 通知やアンテナ等の点滅が消えない -点滅は、未読のコンテンツがあることを示しています。通常点滅が消えない場合は、コンテンツを遡ると未読なコンテンツが残っています。 すべて既読にしたと思われるのに、それでもなお点滅が続く場合(おそらく不具合と思われます)は設定から強制的にすべて既読扱いにすることができます。 - -## Renoteができない -フォロワー限定のノートはRenoteすることはできません。 - -## UI上で特定の要素が表示されない -広告ブロッカーを使用しているとそのような不具合が発生することがあります。Misskeyではオフにしてご利用ください。 - -## UI上で未翻訳の部分がある -ほとんどの場合、単に翻訳が間に合っていないだけで、不具合ではありません。翻訳が終わるまでお待ちください。 [翻訳に参加](./misskey)していただくことも可能です。 diff --git a/src/docs/jbo-EN/keyboard-shortcut.md b/src/docs/jbo-EN/keyboard-shortcut.md deleted file mode 100644 index 957ca838c..000000000 --- a/src/docs/jbo-EN/keyboard-shortcut.md +++ /dev/null @@ -1,68 +0,0 @@ -# キーボードショートカット - -## グローバル -これらのショートカットは基本的にどこでも使えます。 - - - - - - - - - - - -
ショートカット効果由来
P, N新規投稿Post, New, Note
Tタイムラインの最も新しい投稿にフォーカスTimeline, Top
Shift + N通知を表示/隠すNotifications
S検索Search
H, ?ヘルプを表示Help
- -## 投稿にフォーカスされた状態 - - - - - - - - - - - - - - - - - - - -
ショートカット効果由来
, K, Shift + Tab上の投稿にフォーカスを移動-
, J, Tab下の投稿にフォーカスを移動-
R返信フォームを開くReply
QRenoteフォームを開くQuote
Ctrl + Q即刻Renoteする(フォームを開かずに)-
E, A, +リアクションフォームを開くEmote, reAction
0~9数字に対応したリアクションをする(対応については後述)-
F, Bお気に入りに登録Favorite, Bookmark
Del, Ctrl + D投稿を削除Delete
M, O投稿に対するメニューを開くMore, Other
SCWで隠された部分を表示 or 隠すShow, See
Escフォーカスを外す-
- -## Renoteフォーム - - - - - - - - - - -
ショートカット効果由来
EnterRenoteする-
Qフォームを展開するQuote
Escフォームを閉じる-
- -## リアクションフォーム -デフォルトで「👍」にフォーカスが当たっている状態です。 - - - - - - - - - - - - - -
ショートカット効果由来
, K上のリアクションにフォーカスを移動-
, J下のリアクションにフォーカスを移動-
, H, Shift + Tab左のリアクションにフォーカスを移動-
, L, Tab右のリアクションにフォーカスを移動-
Enter, Space, +リアクション確定-
0~9数字に対応したリアクションで確定-
Escリアクションするのをやめる-
diff --git a/src/docs/jbo-EN/mfm.md b/src/docs/jbo-EN/mfm.md deleted file mode 100644 index e237287ac..000000000 --- a/src/docs/jbo-EN/mfm.md +++ /dev/null @@ -1,2 +0,0 @@ -# MFM -MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます。 diff --git a/src/docs/jbo-EN/mute.md b/src/docs/jbo-EN/mute.md deleted file mode 100644 index 6a9608662..000000000 --- a/src/docs/jbo-EN/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# ミュート - -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -* タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -* そのユーザーからの通知 -* メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 - -ユーザーをミュートするには、対象のユーザーのユーザーページに表示されている「ミュート」ボタンを押します。 - -ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。 - -設定>ミュート から、自分がミュートしているユーザー一覧を確認することができます。 diff --git a/src/docs/jbo-EN/pages.md b/src/docs/jbo-EN/pages.md deleted file mode 100644 index a7311b95e..000000000 --- a/src/docs/jbo-EN/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# Pages - -## 変数 -変数を使うことで動的なページを作成できます。テキスト内で { 変数名 } と書くとそこに変数の値を埋め込めます。例えば Hello { thing } world! というテキストで、変数(thing)の値が ai だった場合、テキストは Hello ai world! になります。 - -変数の評価(値を算出すること)は上から下に行われるので、ある変数の中で自分より下の変数を参照することはできません。例えば上から A、B、C と3つの変数を定義したとき、Cの中でABを参照することはできますが、Aの中でBCを参照することはできません。 - -ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。 - -関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。 diff --git a/src/docs/jbo-EN/reaction.md b/src/docs/jbo-EN/reaction.md deleted file mode 100644 index c26ead75b..000000000 --- a/src/docs/jbo-EN/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# リアクション -他の人のノートに、絵文字を付けて簡単にあなたの反応を伝えられる機能です。 リアクションするには、ノートの + アイコンをクリックしてピッカーを表示し、絵文字を選択します。 リアクションには[カスタム絵文字](./custom-emoji)も使用できます。 - -## リアクションピッカーのカスタマイズ -ピッカーに表示される絵文字を自分好みにカスタマイズすることができます。 設定の「リアクション」で設定します。 - -## リモート投稿へのリアクションについて -リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。 また、相手がMisskeyであったとしても、カスタム絵文字リアクションは伝わらず、自動的に「👍」等にフォールバックされます。 - -## リモートからのリアクションについて -リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。 diff --git a/src/docs/jbo-EN/reversi-bot.md b/src/docs/jbo-EN/reversi-bot.md deleted file mode 100644 index 7ab2a7212..000000000 --- a/src/docs/jbo-EN/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# MisskeyリバーシBotの開発 -Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。 - -1. `games/reversi`ストリームに以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - -2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる - * イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている - -3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する - -4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - * `game`: `game`の`id` - -5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う - -6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する - -7. ゲームが開始すると、`started`イベントが流れてくる - * イベントの中身にはゲーム情報が含まれている - -8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述) - -9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる - * `color`として石の色が含まれている - * `pos`として位置情報が含まれている - -## 位置の計算法 -8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### X,Y座標 から インデックス に変換する -``` -pos = x + (y * mapWidth) -``` -`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます: -``` -mapWidth = map[0].length -``` - -### インデックス から X,Y座標 に変換する -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## マップ情報 -マップ情報は、ゲーム情報の`map`に入っています。 文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 それをもとにマップのデザインを知る事が出来ます: -* `(スペース)` ... マス無し -* `-` ... マス -* `b` ... 初期配置される黒石 -* `w` ... 初期配置される白石 - -例えば、4*4の次のような単純なマップがあるとします: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -この場合、マップデータはこのようになります: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## ユーザーにフォームを提示して対話可能Botを作成する -ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。 - -フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します: -```javascript -{ - type: 'init-form', - body: [フォームコントロールの配列] -} -``` - -フォームコントロールの配列については今から説明します。 フォームコントロールは、次のようなオブジェクトです: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... コントロールのID。 `type` ... コントロールの種類。後述します。 `label` ... コントロールと一緒に表記するテキスト。 `value` ... コントロールのデフォルト値。 - -### フォームの操作を受け取る -ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### フォームコントロールの種類 -#### スイッチ -type: `switch` スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。 - -##### プロパティ -`label` ... スイッチに表記するテキスト。 - -#### ラジオボタン -type: `radio` ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。 - -##### プロパティ -`items` ... ラジオボタンの選択肢。例: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '強', - value: 3 -}] -``` - -#### スライダー -type: `slider` スライダーを表示します。 - -##### プロパティ -`min` ... スライダーの下限。 `max` ... スライダーの上限。 `step` ... 入力欄で刻むステップ値。 - -#### テキストボックス -type: `textbox` テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。 - -## ユーザーにメッセージを表示する -設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 メッセージを表示するには、次のメッセージをストリームに送信します: -```javascript -{ - type: 'message', - body: { - text: 'メッセージ内容', - type: 'メッセージの種類' - } -} -``` -メッセージの種類: `success`, `info`, `warning`, `error`。 - -## 投了する -投了をするには、このエンドポイントにリクエストします。 diff --git a/src/docs/jbo-EN/stream.md b/src/docs/jbo-EN/stream.md deleted file mode 100644 index 9011c37c5..000000000 --- a/src/docs/jbo-EN/stream.md +++ /dev/null @@ -1,354 +0,0 @@ -# ストリーミングAPI - -ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。 - -## ストリームに接続する - -ストリーミングAPIを利用するには、まずMisskeyサーバーに**websocket**接続する必要があります。 - -以下のURLに、`i`というパラメータ名で認証情報を含めて、websocket接続してください。例: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。 - -
-

認証情報の取得については、こちらのドキュメントをご確認ください。

-
- ---- - -認証情報は省略することもできますが、その場合非ログインでの利用ということになり、受信できる情報や可能な操作は限られます。例: - -``` -%WS_URL%/streaming -``` - ---- - -ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。 - -**ストリームでのやり取りはすべてJSONです。** - -## チャンネル -MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。 - -### チャンネルに接続する -チャンネルに接続するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -ここで、 -* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。 -* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。 -* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。 - -
-

IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。

-
- -### チャンネルからのメッセージを受け取る -例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。 - -チャンネルがメッセージを発すると、次のようなデータがJSONでストリームに流れてきます: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。 -* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。 -* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。 - -### チャンネルに向けてメッセージを送信する -チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。 - -チャンネルにメッセージを送信するには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。 -* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。 -* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。 - -### チャンネルから切断する -チャンネルから切断するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。 - -## ストリームを経由してAPIリクエストする - -ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。 - -ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -ここで、 -* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 -* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 -* `data`には、エンドポイントのパラメータを含めます。 - -
-

APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。

-
- -### レスポンスの受信 - -APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。 - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -ここで、 -* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 -* `body`には、レスポンスが含まれています。 - -## 投稿のキャプチャ - -Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。 - -例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。 - -しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。 - -この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。 - -### 投稿をキャプチャする - -投稿をキャプチャするには、ストリームに次のようなメッセージを送信します: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャしたい投稿の`id`を設定します。 - -このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 - -例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -ここで、 -* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。 -* `body`内の`type`に、イベントの種類が設定されます。 -* `body`内の`body`に、イベントの詳細が設定されます。 - -#### イベントの種類 - -##### `reacted` -その投稿にリアクションがされた時に発生します。 - -* `reaction`に、リアクションの種類が設定されます。 -* `userId`に、リアクションを行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -その投稿が削除された時に発生します。 - -* `deletedAt`に、削除日時が設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -その投稿に添付されたアンケートに投票された時に発生します。 - -* `choice`に、選択肢IDが設定されます。 -* `userId`に、投票を行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### 投稿のキャプチャを解除する - -その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。 - -次のメッセージを送信します: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャを解除したい投稿の`id`を設定します。 - -このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 - -# チャンネル一覧 -## `main` -アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `renote` -自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。 - -#### `mention` -誰かからメンションされたときに発生するイベントです。 - -#### `readAllNotifications` -自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。 - -#### `meUpdated` -自分の情報が更新されたことを表すイベントです。 - -#### `follow` -自分が誰かをフォローしたときに発生するイベントです。 - -#### `unfollow` -自分が誰かのフォローを解除したときに発生するイベントです。 - -#### `followed` -自分が誰かにフォローされたときに発生するイベントです。 - -## `homeTimeline` -ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -タイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `localTimeline` -ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `hybridTimeline` -ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ソーシャルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `globalTimeline` -グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 diff --git a/src/docs/jbo-EN/theme.md b/src/docs/jbo-EN/theme.md deleted file mode 100644 index a406f3433..000000000 --- a/src/docs/jbo-EN/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# テーマ - -テーマを設定して、Misskeyクライアントの見た目を変更できます。 - -## テーマの設定 -設定 > テーマ - -## テーマを作成する -テーマコードはJSON5で記述されたテーマオブジェクトです。 テーマは以下のようなオブジェクトです。 -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... テーマの一意なID。UUIDをおすすめします。 -* `name` ... テーマ名 -* `author` ... テーマの作者 -* `desc` ... テーマの説明(オプション) -* `base` ... 明るいテーマか、暗いテーマか - * `light`にすると明るいテーマになり、`dark`にすると暗いテーマになります。 - * テーマはここで設定されたベーステーマを継承します。 -* `props` ... テーマのスタイル定義。これから説明します。 - -### テーマのスタイル定義 -`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 - -#### バリューで使える構文 -* 16進数で表された色 - * 例: `#00ff00` -* `rgb(r, g, b)`形式で表された色 - * 例: `rgb(0, 255, 0)` -* `rgb(r, g, b, a)`形式で表された透明度を含む色 - * 例: `rgba(0, 255, 0, 0.5)` -* 他のキーの値の参照 - * `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。 - * 例: `@panel` -* 定数(後述)の参照 - * `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。 - * 例: `$main` -* 関数(後述) - * `:{関数名}<{引数}<{色}` - -#### 定数 -「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 キー名を`$`で始めると、そのキーはCSS変数として出力されません。 - -#### 関数 -wip diff --git a/src/docs/jbo-EN/timelines.md b/src/docs/jbo-EN/timelines.md deleted file mode 100644 index 36ba61bd2..000000000 --- a/src/docs/jbo-EN/timelines.md +++ /dev/null @@ -1,15 +0,0 @@ -# タイムラインの比較 - -https://docs.google.com/spreadsheets/d/1lxQ2ugKrhz58Bg96HTDK_2F98BUritkMyIiBkOByjHA/edit?usp=sharing - -## ホーム -自分のフォローしているユーザーの投稿 - -## ローカル -全てのローカルユーザーの「ホーム」指定されていない投稿 - -## ソーシャル -自分のフォローしているユーザーの投稿と、全てのローカルユーザーの「ホーム」指定されていない投稿 - -## グローバル -全てのローカルユーザーの「ホーム」指定されていない投稿と、サーバーに届いた全てのリモートユーザーの「ホーム」指定されていない投稿 diff --git a/src/docs/kab-KAB/admin/disable-timelines.md b/src/docs/kab-KAB/admin/disable-timelines.md deleted file mode 100644 index b081e35ab..000000000 --- a/src/docs/kab-KAB/admin/disable-timelines.md +++ /dev/null @@ -1,8 +0,0 @@ -# LTL/STL/GTLの無効化 -Misskeyでは、LTL/STL/GTLをそれぞれ無効化することができます。有効/無効を切り替えるには、インスタンスコントロールパネルで設定します。 - -LTLやSTLは、そのインスタンス全員の投稿が見れるため、新規のユーザーにとってはユーザーを探す必要がなくなり、興味のあるユーザーを見つけやすいという利点があります。 しかし同時に、フォロー機能が活用されなくなったり、不適切な投稿が目につきやすくなったり、チャットのようになることで内輪感が生じて逆に新規ユーザーが参加しにくくなるといったデメリットも持ち合わせています。 サーバーによってメリット/デメリットどちらが優勢かは異なるので、オプションとして無効にできるようになっています。 もしデメリットの方が上回っていると感じたら、それらのタイムラインを無効化することも検討してください。 - -
⚠️ 無効化を行うと、ユーザーが困惑し、短期的に見て利用者が減る可能性があります。そのため、無効化の際は影響を慎重に検討し、事前に説明してフォローを整える期間を一定程度設けることを推奨します。
- -なお、管理者/モデレーターは、これらのタイムラインの無効化状態は適用されず、引き続き利用することが可能です。 diff --git a/src/docs/kab-KAB/admin/faq.md b/src/docs/kab-KAB/admin/faq.md deleted file mode 100644 index 317b4e065..000000000 --- a/src/docs/kab-KAB/admin/faq.md +++ /dev/null @@ -1,5 +0,0 @@ -# よくある質問 -ここでは、サーバー管理者向けのよくある質問を掲載しています。 - -## デフォルトテーマを設定したい -現在、デフォルトテーマ設定機能は実装されていません。 diff --git a/src/docs/kab-KAB/advanced/aiscript.md b/src/docs/kab-KAB/advanced/aiscript.md deleted file mode 100644 index 604d17daa..000000000 --- a/src/docs/kab-KAB/advanced/aiscript.md +++ /dev/null @@ -1,7 +0,0 @@ -# AiScript -AiScriptは、Misskeyで使用できるスクリプト言語です。 - -
ℹ️ AiScript実装はMisskeyとは別リポジトリで、オープンソースで公開されています。
- -## 使い方 -AiScriptの構文や組み込み関数などのドキュメントは、[こちら](https://github.com/syuilo/aiscript/tree/master/docs)で公開されています。 diff --git a/src/docs/kab-KAB/advanced/api.md b/src/docs/kab-KAB/advanced/api.md deleted file mode 100644 index 76019b614..000000000 --- a/src/docs/kab-KAB/advanced/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス、Bot等(以下「アプリケーション」と呼びます)を開発できます。 ストリーミングAPIもあるので、リアルタイム性のあるアプリケーションを作ることも可能です。 - -APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。 - -## アクセストークンの取得 -基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。 - -* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む -* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む - -### 自分自身のアクセストークンを手動発行する -「設定 > API」で、自分のアクセストークンを発行できます。 - -[「APIの使い方」へ進む](#APIの使い方) - -### アプリケーション利用者にアクセストークンの発行をリクエストする -アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。 - -#### Step 1 - -UUIDを生成する。以後これをセッションIDと呼びます。 - -> このセッションIDは毎回生成し、使いまわさないようにしてください。 - -#### Step 2 - -`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。 -> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます: -* `name` ... アプリケーション名 - * > 例: `MissDeck` -* `icon` ... アプリケーションのアイコン画像URL - * > 例: `https://missdeck.example.com/icon.png` -* `callback` ... 認証が終わった後にリダイレクトするURL - * > 例: `https://missdeck.example.com/callback` - * リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます -* `permission` ... アプリケーションが要求する権限 - * > 例: `write:notes,write:following,read:drive` - * 要求する権限を`,`で区切って列挙します - * どのような権限があるかは[APIリファレンス](/api-doc)で確認できます - -#### Step 3 -ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。 - -レスポンスに含まれるプロパティ: -* `token` ... ユーザーのアクセストークン -* `user` ... ユーザーの情報 - -[「APIの使い方」へ進む](#APIの使い方) - -## APIの使い方 -**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。 - -* [APIリファレンス](/api-doc) -* [ストリーミングAPI](./stream) diff --git a/src/docs/kab-KAB/advanced/create-plugin.md b/src/docs/kab-KAB/advanced/create-plugin.md deleted file mode 100644 index 0d2fa1917..000000000 --- a/src/docs/kab-KAB/advanced/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# プラグインの作成 -Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。 - -## メタデータ -プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。 - -### name -プラグイン名 - -### author -プラグイン作者 - -### version -プラグインバージョン。数値を指定してください。 - -### description -プラグインの説明 - -### permissions -プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。 - -### config -プラグインの設定情報を表すオブジェクト。 キーに設定名、値に以下のプロパティを含めます。 - -#### type -設定値の種類を表す文字列。以下から選択します。 string number boolean - -#### label -ユーザーに表示する設定名 - -#### description -設定の説明 - -#### default -設定のデフォルト値 - -## APIリファレンス -AiScript標準で組み込まれているAPIは掲載しません。 - -### Mk:dialog(title text type) -ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。 - -### Mk:confirm(title text type) -確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。 - -### Mk:api(endpoint params) -Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。 - -### Mk:save(key value) -任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。 - -### Mk:load(key) -Mk:saveで永続化した指定の名前の値を読み取ります。 - -### Plugin:register_post_form_action(title fn) -投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。 - -### Plugin:register_note_action(title fn) -ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 - -### Plugin:register_user_action(title fn) -ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。 - -### Plugin:register_note_view_interruptor(fn) -UIに表示されるノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:register_note_post_interruptor(fn) -ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:open_url(url) -第一引数に渡されたURLをブラウザの新しいタブで開きます。 - -### Plugin:config -プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。 diff --git a/src/docs/kab-KAB/advanced/develop-bot.md b/src/docs/kab-KAB/advanced/develop-bot.md deleted file mode 100644 index 7f825e9bc..000000000 --- a/src/docs/kab-KAB/advanced/develop-bot.md +++ /dev/null @@ -1,6 +0,0 @@ -# Botの作成 -[Misskey API](./api)を利用してBotの開発が可能です。 また、いくつかのBot実装が公開されているため、ぜひ参考にしてください。 - -- [syuilo/ai](https://github.com/syuilo/ai) ... Node.js上で動く、TypeScript製Bot実装 - -Botを作成したときは、プロフィール設定からBotフラグをオンにしておくことを強くおすすめします。 diff --git a/src/docs/kab-KAB/advanced/reversi-bot.md b/src/docs/kab-KAB/advanced/reversi-bot.md deleted file mode 100644 index 7ab2a7212..000000000 --- a/src/docs/kab-KAB/advanced/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# MisskeyリバーシBotの開発 -Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。 - -1. `games/reversi`ストリームに以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - -2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる - * イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている - -3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する - -4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - * `game`: `game`の`id` - -5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う - -6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する - -7. ゲームが開始すると、`started`イベントが流れてくる - * イベントの中身にはゲーム情報が含まれている - -8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述) - -9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる - * `color`として石の色が含まれている - * `pos`として位置情報が含まれている - -## 位置の計算法 -8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### X,Y座標 から インデックス に変換する -``` -pos = x + (y * mapWidth) -``` -`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます: -``` -mapWidth = map[0].length -``` - -### インデックス から X,Y座標 に変換する -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## マップ情報 -マップ情報は、ゲーム情報の`map`に入っています。 文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 それをもとにマップのデザインを知る事が出来ます: -* `(スペース)` ... マス無し -* `-` ... マス -* `b` ... 初期配置される黒石 -* `w` ... 初期配置される白石 - -例えば、4*4の次のような単純なマップがあるとします: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -この場合、マップデータはこのようになります: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## ユーザーにフォームを提示して対話可能Botを作成する -ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。 - -フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します: -```javascript -{ - type: 'init-form', - body: [フォームコントロールの配列] -} -``` - -フォームコントロールの配列については今から説明します。 フォームコントロールは、次のようなオブジェクトです: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... コントロールのID。 `type` ... コントロールの種類。後述します。 `label` ... コントロールと一緒に表記するテキスト。 `value` ... コントロールのデフォルト値。 - -### フォームの操作を受け取る -ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### フォームコントロールの種類 -#### スイッチ -type: `switch` スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。 - -##### プロパティ -`label` ... スイッチに表記するテキスト。 - -#### ラジオボタン -type: `radio` ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。 - -##### プロパティ -`items` ... ラジオボタンの選択肢。例: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '強', - value: 3 -}] -``` - -#### スライダー -type: `slider` スライダーを表示します。 - -##### プロパティ -`min` ... スライダーの下限。 `max` ... スライダーの上限。 `step` ... 入力欄で刻むステップ値。 - -#### テキストボックス -type: `textbox` テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。 - -## ユーザーにメッセージを表示する -設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 メッセージを表示するには、次のメッセージをストリームに送信します: -```javascript -{ - type: 'message', - body: { - text: 'メッセージ内容', - type: 'メッセージの種類' - } -} -``` -メッセージの種類: `success`, `info`, `warning`, `error`。 - -## 投了する -投了をするには、このエンドポイントにリクエストします。 diff --git a/src/docs/kab-KAB/advanced/share-page.md b/src/docs/kab-KAB/advanced/share-page.md deleted file mode 100644 index edcde489c..000000000 --- a/src/docs/kab-KAB/advanced/share-page.md +++ /dev/null @@ -1,54 +0,0 @@ -# シェアページ -`/share`を開くと、共有用の投稿フォームを開くことができます。 ここではシェアページで利用できるクエリ文字列の一覧を示します。 - -## クエリ文字列一覧 -### 文字 - -
-
title
-
タイトルです。本文の先頭に[ … ]と挿入されます。
-
text
-
本文です。
-
url
-
URLです。末尾に挿入されます。
-
- -### リプライ情報 -以下のいずれか - -
-
replyId
-
リプライ先のノートid
-
replyUri
-
リプライ先のUrl(リモートのノートオブジェクトを指定)
-
- -### Renote情報 -以下のいずれか - -
-
renoteId
-
Renote先のノートid
-
renoteUri
-
Renote先のUrl(リモートのノートオブジェクトを指定)
-
- -### 公開範囲 -※specifiedに相当する値はvisibility=specifiedとvisibleAccts/visibleUserIdsで指定する - -
-
visibility
-
公開範囲 ['public' | 'home' | 'followers' | 'specified']
-
localOnly
-
0(false) or 1(true)
-
visibleUserIds
-
specified時のダイレクト先のユーザーid カンマ区切りで
-
visibleAccts
-
specified時のダイレクト先のacct(@?username[@host]) カンマ区切りで
-
- -### Ifuyla -
-
fileIds
-
添付したいファイルのid(カンマ区切りで)
-
diff --git a/src/docs/kab-KAB/advanced/stream.md b/src/docs/kab-KAB/advanced/stream.md deleted file mode 100644 index 0e5edd2b0..000000000 --- a/src/docs/kab-KAB/advanced/stream.md +++ /dev/null @@ -1,350 +0,0 @@ -# ストリーミングAPI - -ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。 - -## ストリームに接続する - -ストリーミングAPIを利用するには、まずMisskeyサーバーに**websocket**接続する必要があります。 - -以下のURLに、`i`というパラメータ名で認証情報を含めて、websocket接続してください。例: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。 - -
ℹ️ 認証情報の取得については、こちらのドキュメントをご確認ください。
- ---- - -認証情報は省略することもできますが、その場合非ログインでの利用ということになり、受信できる情報や可能な操作は限られます。例: - -``` -%WS_URL%/streaming -``` - ---- - -ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。 - -**ストリームでのやり取りはすべてJSONです。** - -## チャンネル -MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。 - -ひとつのストリーム上で、同時に複数のチャンネルに接続することができます。 - -### チャンネルに接続する -チャンネルに接続するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -ここで、 -* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。 -* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。 -* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。 - -
ℹ️ IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。
- -### チャンネルからのメッセージを受け取る -例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。 - -チャンネルがメッセージを発すると、次のようなデータがJSONでストリームに流れてきます: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。 -* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。 -* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。 - -### チャンネルに向けてメッセージを送信する -チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。 - -チャンネルにメッセージを送信するには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。 -* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。 -* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。 - -### チャンネルから切断する -チャンネルから切断するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。 - -## ストリームを経由してAPIリクエストする - -ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。 - -ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -ここで、 -* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 -* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 -* `data`には、エンドポイントのパラメータを含めます。 - -
ℹ️ APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。
- -### レスポンスの受信 - -APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。 - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -ここで、 -* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 -* `body`には、レスポンスが含まれています。 - -## 投稿のキャプチャ - -Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。 - -例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。 - -しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。 - -この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。 - -### 投稿をキャプチャする - -投稿をキャプチャするには、ストリームに次のようなメッセージを送信します: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャしたい投稿の`id`を設定します。 - -このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 - -例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -ここで、 -* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。 -* `body`内の`type`に、イベントの種類が設定されます。 -* `body`内の`body`に、イベントの詳細が設定されます。 - -#### イベントの種類 - -##### `reacted` -その投稿にリアクションがされた時に発生します。 - -* `reaction`に、リアクションの種類が設定されます。 -* `userId`に、リアクションを行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -その投稿が削除された時に発生します。 - -* `deletedAt`に、削除日時が設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -その投稿に添付されたアンケートに投票された時に発生します。 - -* `choice`に、選択肢IDが設定されます。 -* `userId`に、投票を行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### 投稿のキャプチャを解除する - -その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。 - -次のメッセージを送信します: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャを解除したい投稿の`id`を設定します。 - -このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 - -# チャンネル一覧 -## `main` -アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `renote` -自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。 - -#### `mention` -誰かからメンションされたときに発生するイベントです。 - -#### `readAllNotifications` -自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。 - -#### `meUpdated` -自分の情報が更新されたことを表すイベントです。 - -#### `follow` -自分が誰かをフォローしたときに発生するイベントです。 - -#### `unfollow` -自分が誰かのフォローを解除したときに発生するイベントです。 - -#### `followed` -自分が誰かにフォローされたときに発生するイベントです。 - -## `homeTimeline` -ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -タイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `localTimeline` -ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `hybridTimeline` -ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ソーシャルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `globalTimeline` -グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 diff --git a/src/docs/kab-KAB/aiscript.md b/src/docs/kab-KAB/aiscript.md deleted file mode 100644 index 6c28b446e..000000000 --- a/src/docs/kab-KAB/aiscript.md +++ /dev/null @@ -1,4 +0,0 @@ -# AiScript - -## 関数 -デフォルトで値渡しです。 diff --git a/src/docs/kab-KAB/api.md b/src/docs/kab-KAB/api.md deleted file mode 100644 index 76019b614..000000000 --- a/src/docs/kab-KAB/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス、Bot等(以下「アプリケーション」と呼びます)を開発できます。 ストリーミングAPIもあるので、リアルタイム性のあるアプリケーションを作ることも可能です。 - -APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。 - -## アクセストークンの取得 -基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。 - -* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む -* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む - -### 自分自身のアクセストークンを手動発行する -「設定 > API」で、自分のアクセストークンを発行できます。 - -[「APIの使い方」へ進む](#APIの使い方) - -### アプリケーション利用者にアクセストークンの発行をリクエストする -アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。 - -#### Step 1 - -UUIDを生成する。以後これをセッションIDと呼びます。 - -> このセッションIDは毎回生成し、使いまわさないようにしてください。 - -#### Step 2 - -`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。 -> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます: -* `name` ... アプリケーション名 - * > 例: `MissDeck` -* `icon` ... アプリケーションのアイコン画像URL - * > 例: `https://missdeck.example.com/icon.png` -* `callback` ... 認証が終わった後にリダイレクトするURL - * > 例: `https://missdeck.example.com/callback` - * リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます -* `permission` ... アプリケーションが要求する権限 - * > 例: `write:notes,write:following,read:drive` - * 要求する権限を`,`で区切って列挙します - * どのような権限があるかは[APIリファレンス](/api-doc)で確認できます - -#### Step 3 -ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。 - -レスポンスに含まれるプロパティ: -* `token` ... ユーザーのアクセストークン -* `user` ... ユーザーの情報 - -[「APIの使い方」へ進む](#APIの使い方) - -## APIの使い方 -**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。 - -* [APIリファレンス](/api-doc) -* [ストリーミングAPI](./stream) diff --git a/src/docs/kab-KAB/create-plugin.md b/src/docs/kab-KAB/create-plugin.md deleted file mode 100644 index 0d2fa1917..000000000 --- a/src/docs/kab-KAB/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# プラグインの作成 -Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。 - -## メタデータ -プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。 - -### name -プラグイン名 - -### author -プラグイン作者 - -### version -プラグインバージョン。数値を指定してください。 - -### description -プラグインの説明 - -### permissions -プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。 - -### config -プラグインの設定情報を表すオブジェクト。 キーに設定名、値に以下のプロパティを含めます。 - -#### type -設定値の種類を表す文字列。以下から選択します。 string number boolean - -#### label -ユーザーに表示する設定名 - -#### description -設定の説明 - -#### default -設定のデフォルト値 - -## APIリファレンス -AiScript標準で組み込まれているAPIは掲載しません。 - -### Mk:dialog(title text type) -ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。 - -### Mk:confirm(title text type) -確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。 - -### Mk:api(endpoint params) -Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。 - -### Mk:save(key value) -任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。 - -### Mk:load(key) -Mk:saveで永続化した指定の名前の値を読み取ります。 - -### Plugin:register_post_form_action(title fn) -投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。 - -### Plugin:register_note_action(title fn) -ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 - -### Plugin:register_user_action(title fn) -ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。 - -### Plugin:register_note_view_interruptor(fn) -UIに表示されるノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:register_note_post_interruptor(fn) -ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:open_url(url) -第一引数に渡されたURLをブラウザの新しいタブで開きます。 - -### Plugin:config -プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。 diff --git a/src/docs/kab-KAB/custom-emoji.md b/src/docs/kab-KAB/custom-emoji.md deleted file mode 100644 index ed2e92be1..000000000 --- a/src/docs/kab-KAB/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# カスタム絵文字 -カスタム絵文字は、インスタンスで用意された画像を絵文字のように使える機能です。 ノート、リアクション、チャット、自己紹介、名前などの場所で使うことができます。 カスタム絵文字をそれらの場所で使うには、絵文字ピッカーボタン(ある場合)を押すか、`:`を入力して絵文字サジェストを表示します。 テキスト内に`:foo:`のような形式の文字列が見つかると、`foo`の部分がカスタム絵文字名と解釈され、表示時には対応したカスタム絵文字に置き換わります。 diff --git a/src/docs/kab-KAB/deck.md b/src/docs/kab-KAB/deck.md deleted file mode 100644 index 8057e262f..000000000 --- a/src/docs/kab-KAB/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# デッキ - -デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。 - -## カラムの追加 -デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。 - -## カラムの移動 -カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。 - -## カラムの水平分割 -カラムは左右だけでなく、上下に並べることもできます。 カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 上下分割を解除するには、カラムメニューの「右に出す」を選択します。 - -## カラムの設定 -カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。 - -## デッキの設定 -デッキに関する設定は、[settings/deck](/settings/deck)で行えます。 diff --git a/src/docs/kab-KAB/features/antenna.md b/src/docs/kab-KAB/features/antenna.md deleted file mode 100644 index 94ad9e4ae..000000000 --- a/src/docs/kab-KAB/features/antenna.md +++ /dev/null @@ -1,4 +0,0 @@ -# アンテナ -アンテナは、自由に条件を設定して、合致するノートを自動で収集することができる機能です。 - -条件を設定したアンテナが作成された状態で、条件に合致するノートが投稿されると、リアルタイムでそのアンテナのタイムラインにノートが追加されます。 diff --git a/src/docs/kab-KAB/features/custom-emoji.md b/src/docs/kab-KAB/features/custom-emoji.md deleted file mode 100644 index ed2e92be1..000000000 --- a/src/docs/kab-KAB/features/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# カスタム絵文字 -カスタム絵文字は、インスタンスで用意された画像を絵文字のように使える機能です。 ノート、リアクション、チャット、自己紹介、名前などの場所で使うことができます。 カスタム絵文字をそれらの場所で使うには、絵文字ピッカーボタン(ある場合)を押すか、`:`を入力して絵文字サジェストを表示します。 テキスト内に`:foo:`のような形式の文字列が見つかると、`foo`の部分がカスタム絵文字名と解釈され、表示時には対応したカスタム絵文字に置き換わります。 diff --git a/src/docs/kab-KAB/features/deck.md b/src/docs/kab-KAB/features/deck.md deleted file mode 100644 index 8057e262f..000000000 --- a/src/docs/kab-KAB/features/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# デッキ - -デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。 - -## カラムの追加 -デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。 - -## カラムの移動 -カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。 - -## カラムの水平分割 -カラムは左右だけでなく、上下に並べることもできます。 カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 上下分割を解除するには、カラムメニューの「右に出す」を選択します。 - -## カラムの設定 -カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。 - -## デッキの設定 -デッキに関する設定は、[settings/deck](/settings/deck)で行えます。 diff --git a/src/docs/kab-KAB/features/drive.md b/src/docs/kab-KAB/features/drive.md deleted file mode 100644 index b82a41082..000000000 --- a/src/docs/kab-KAB/features/drive.md +++ /dev/null @@ -1,17 +0,0 @@ -# ドライブ -ドライブは、Misskey上でファイルを管理できる機能です。 - -[ドライブのページ](/my/drive)から任意のファイルをアップロードできるほか、アバターに設定した画像や、ノートに添付したファイルなどもすべてドライブにアップロードされます。 - -
⚠️ ドライブからファイルを削除すると、そのファイルが添付されたノートも消えます。
- -ドライブにアップロードされたファイルは、いつでもダウンロードすることができるほか、ノート作成時に「ドライブからファイルを添付」することでファイルを再利用することもできます。 - -ドライブ内にフォルダを作り、複数のファイルをまとめて整理することもできます。 - -## 閲覧注意 (NSFW) -
ℹ️ この項目が閲覧注意なわけではありません
- -閲覧注意またはNSFW (Not safe for work) は、ドライブのファイルに設定することができるフラグです。 閲覧注意フラグを設定されたファイルは、表示される際に閲覧者の操作なしには表示されなくなります。 このフラグは、例えば職場や公共の場で閲覧するのに適切でないと思われる画像などに設定し、そのような画像が突然表示されてしまうことを防ぐ目的で使われます。 - -このフラグは手動でオンオフを切り替えられるほか、モデレーターの判断で設定される場合もあります。 diff --git a/src/docs/kab-KAB/features/favorite.md b/src/docs/kab-KAB/features/favorite.md deleted file mode 100644 index a0e5f8bf7..000000000 --- a/src/docs/kab-KAB/features/favorite.md +++ /dev/null @@ -1,4 +0,0 @@ -# お気に入り -[ノート](./node)をお気に入りとして登録できる機能です。 お気に入り登録したノートは、[お気に入りページ](./my/favorites)で一覧することができます。 お気に入りに登録したことは相手に通知されず、お気に入りは自分しか見ることができません。 - -ノートをお気に入り登録するには、ノートメニューの「お気に入り」を押します。お気に入り解除するには、ノートメニューの「お気に入り解除」を押します。 diff --git a/src/docs/kab-KAB/features/follow.md b/src/docs/kab-KAB/features/follow.md deleted file mode 100644 index 500073a4b..000000000 --- a/src/docs/kab-KAB/features/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# Ig ṭṭafaṛ -ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。 diff --git a/src/docs/kab-KAB/features/keyboard-shortcut.md b/src/docs/kab-KAB/features/keyboard-shortcut.md deleted file mode 100644 index 82cae4e1b..000000000 --- a/src/docs/kab-KAB/features/keyboard-shortcut.md +++ /dev/null @@ -1,66 +0,0 @@ -# キーボードショートカット - -## グローバル -これらのショートカットは基本的にどこでも使えます。 - - - - - - - - - - - -
ショートカット効果由来
P, N新規投稿Post, New, Note
Tタイムラインの最も新しい投稿にフォーカスTimeline, Top
Shift + N通知を表示/隠すNotifications
SNadiSearch
H, ?ヘルプを表示Help
- -## 投稿にフォーカスされた状態 - - - - - - - - - - - - - - - - - - -
ショートカット効果由来
, K, Shift + Tab上の投稿にフォーカスを移動-
, J, Tab下の投稿にフォーカスを移動-
R返信フォームを開くReply
QRenoteフォームを開くQuote
Ctrl + Q即刻Renoteする(フォームを開かずに)-
E, A, +リアクションフォームを開くEmote, reAction
0~9数字に対応したリアクションをする(対応については後述)-
F, Bお気に入りに登録Favorite, Bookmark
Del, Ctrl + D投稿を削除Delete
M, O投稿に対するメニューを開くMore, Other
SCWで隠された部分を表示 or 隠すShow, See
Escフォーカスを外す-
- -## Renoteフォーム - - - - - - - - - -
ショートカット効果由来
EnterRenoteする-
Qフォームを展開するQuote
Escフォームを閉じる-
- -## リアクションフォーム -デフォルトで「👍」にフォーカスが当たっている状態です。 - - - - - - - - - - - - - -
ショートカット効果由来
, K上のリアクションにフォーカスを移動-
, J下のリアクションにフォーカスを移動-
, H, Shift + Tab左のリアクションにフォーカスを移動-
, L, Tab右のリアクションにフォーカスを移動-
Enter, Space, +リアクション確定-
0~9数字に対応したリアクションで確定-
Escリアクションするのをやめる-
diff --git a/src/docs/kab-KAB/features/mfm.md b/src/docs/kab-KAB/features/mfm.md deleted file mode 100644 index 5be2df4f3..000000000 --- a/src/docs/kab-KAB/features/mfm.md +++ /dev/null @@ -1,12 +0,0 @@ -# MFM -MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます。 - -## MFMが使用可能な場所の例 -- ノート本文 -- CW注釈 -- ユーザーの名前 -- ユーザーの自己紹介 - -## 開発者向け情報 -MFMのパーサー実装はライブラリとして公開されており、簡単にクライアントにMFMを組み込むことが可能です。 -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptパーサー実装 diff --git a/src/docs/kab-KAB/features/mute-and-block.md b/src/docs/kab-KAB/features/mute-and-block.md deleted file mode 100644 index d78a7cea4..000000000 --- a/src/docs/kab-KAB/features/mute-and-block.md +++ /dev/null @@ -1,41 +0,0 @@ -# ミュートとブロック -好みではないユーザーがいる場合は、ミュートを行うことでそのユーザーが自分から見えないようにすることができます。 また、より強力な措置として、ブロックを行うことでそのユーザーから自分のコンテンツが見えないようになるほか、自分に対して関わることができないようにすることができます。 ミュートされていることは相手は分かりませんが、ブロックされていることは相手に分かります。どちらを選ぶかはご自身の判断で行ってください。 - -
ℹ️ ミュートとブロックは併用できます。
- -
⚠️ 利用規約に違反するような、迷惑なユーザーがいる場合は運営者に報告することも検討してください。
- -設定>ミュートとブロック から、自分がミュートまたはブロックしているユーザー一覧を確認することができます。 - -## ミュート -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -- タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -- そのユーザーからの通知 -- メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 -- など - -ユーザーをミュートするには、対象のユーザーのユーザーページのメニューを開き、「ミュート」ボタンを押します。 - -
ℹ️ ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。
- -## ブロック -ユーザーをブロックすると、そのユーザーからあなたのコンテンツが見えないようになり、またあなたに対して以下のようなアクションをすることができなくなります。 - -- フォローする -- ユーザーリストに追加する -- 返信する、Renoteする -- リアクションする、アンケートに投票する -- メッセージを送信する -- など - -また、 - -- ブロックする際に既にそのユーザーからフォローされていた場合はフォローが解除されます。 -- ブロックする際に既にそのユーザーがあなたをユーザーリストに入れていた場合はそのリストからあなたが削除されます。 - -ユーザーをブロックするには、対象のユーザーのユーザーページのメニューを開き、「ブロック」ボタンを押します。 - -
⚠️ ブロックを行ったこと自体は相手に通知されませんが、フォローを行ったりなどの上記のアクションが行えなくなるので間接的にブロックされていることは分かります。
- -
⚠️ 相手から自分のコンテンツが見えなくなりますが、相手がアカウントを切り替えたりログアウト状態になれば見ることができます。あくまで簡易的、補助的なものとしてお考えください。
diff --git a/src/docs/kab-KAB/features/mute.md b/src/docs/kab-KAB/features/mute.md deleted file mode 100644 index 6a9608662..000000000 --- a/src/docs/kab-KAB/features/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# ミュート - -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -* タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -* そのユーザーからの通知 -* メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 - -ユーザーをミュートするには、対象のユーザーのユーザーページに表示されている「ミュート」ボタンを押します。 - -ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。 - -設定>ミュート から、自分がミュートしているユーザー一覧を確認することができます。 diff --git a/src/docs/kab-KAB/features/note.md b/src/docs/kab-KAB/features/note.md deleted file mode 100644 index 4f28d063c..000000000 --- a/src/docs/kab-KAB/features/note.md +++ /dev/null @@ -1,54 +0,0 @@ -# ノート -ノートは、Misskeyに投稿される、文章、ファイル、アンケートなどを含むコンテンツで、Misskeyの中心的概念です。また、そのノートを作成する行為自体もノートと呼ばれます。 - -ノートが作成されると、[タイムライン](./timeline)に追加され、自分の[フォロワー](./follow)やサーバーのユーザーが見れるようになります。 - -ノートには、[リアクション](./reaction)を行うことができます。また、返信や引用もできます。 - -ノートを[お気に入り](./favorite)登録することで、後で簡単に見返すことができます。 - -## ノートを作成する -ノートを作成するには、画面上にある鉛筆マークのボタンを押して、作成フォームを開きます。作成フォームに内容を入力し、「ノート」ボタンを押すことでノートが作成されます。 ノートには、画像、動画など任意のファイルや、[アンケート](./poll)を添付することができます。また、本文中には[MFM](./mfm)が使用でき、[メンション](./mention)や[ハッシュタグ](./hashtag)を含めることもできます。 他にも、CWや公開範囲といった設定も行えます(詳細は後述)。 -
ℹ️ コンピューターのクリップボードに画像データがある状態で、フォーム内のテキストボックスにペーストするとその画像を添付することができます。
-
ℹ️ テキストボックス内でCtrl + Enterを押すことでも投稿できます。
- -## Renote -既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノートをRenoteと呼びます。 自分がフォローしているユーザーの、気に入ったノートを自分のフォロワーに共有したい場合や、過去の自分のノートを再度共有したい場合に使います。 同じノートに対して無制限にRenoteを行うことができますが、あまり連続して使用すると迷惑になる場合もあるので、注意しましょう。 -
⚠️ 公開範囲がフォロワーやダイレクトのノートはRenoteできません
- -Renoteを削除するには、Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 - -## CW -Contents Warningの略で、ノートの内容を、閲覧者の操作なしには表示しないようにできる機能です。主に長大な内容を隠すためや、ネタバレ防止などに使うことができます。 設定するには、フォームの「内容を隠す」ボタン(目のアイコン)を押します。すると新しい入力エリアが表れるので、そこに内容の要約を記入します。 - -## 公開範囲 -ノートごとに、そのノートが公開される範囲を設定することができます。フォームの「ノート」ボタンの左にあるアイコンを押すと公開範囲を以下から選択できます。 - -### パブリック -全ての人に対してノートが公開されるほか、サーバーの全てのタイムライン(ホームタイムライン、ローカルタイムライン、ソーシャルタイムライン、グローバルタイムライン)にノートが流れます。 -
⚠️ アカウントがサイレンス状態の時は、この公開範囲は使用できません。
- -### ホーム -全ての人に対してノートが公開されますが、フォロワー以外のローカルタイムライン、ソーシャルタイムライン、グローバルタイムラインにはノートは流れません。 - -### Imeḍfaṛen -自分のフォロワーに対してのみノートを公開します。フォロワーの全てのタイムラインに流れます。 - -### ダイレクト -指定したユーザーに対してのみノートを公開します。指定したユーザーの全てのタイムラインに流れます。 - -### 「ローカルのみ」オプション -このオプションを有効にすると、リモートにノートを連合しなくなります。 - -### 公開範囲の比較 - - - - -
パブリックホームImeḍfaṛenダイレクト
フォロワーのLTL/STL/GTL
非フォロワーのLTL/STL/GTL
- -## ピン留め -ノートをピン留めすると、ユーザーページに常にそのノートを表示しておくことができます。 ノートのメニューを開き、「ピン留め」を選択してピン留めできます。 複数のノートをピン留めできます。 - -## ウォッチ -ノートをウォッチすると、自分以外のノートへのリアクションや返信などの通知を受け取ることができます。 ノートのメニューを開き、「ウォッチ」を選択してウォッチできます。 diff --git a/src/docs/kab-KAB/features/pages.md b/src/docs/kab-KAB/features/pages.md deleted file mode 100644 index a7311b95e..000000000 --- a/src/docs/kab-KAB/features/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# Pages - -## 変数 -変数を使うことで動的なページを作成できます。テキスト内で { 変数名 } と書くとそこに変数の値を埋め込めます。例えば Hello { thing } world! というテキストで、変数(thing)の値が ai だった場合、テキストは Hello ai world! になります。 - -変数の評価(値を算出すること)は上から下に行われるので、ある変数の中で自分より下の変数を参照することはできません。例えば上から A、B、C と3つの変数を定義したとき、Cの中でABを参照することはできますが、Aの中でBCを参照することはできません。 - -ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。 - -関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。 diff --git a/src/docs/kab-KAB/features/reaction.md b/src/docs/kab-KAB/features/reaction.md deleted file mode 100644 index 4d479fd41..000000000 --- a/src/docs/kab-KAB/features/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# リアクション -他の人のノートに、絵文字を付けて簡単にあなたの反応を伝えられる機能です。 リアクションするには、ノートの + アイコンをクリックしてピッカーを表示し、絵文字を選択します。 リアクションには[カスタム絵文字](./custom-emoji)も使用できます。 - -## リアクションピッカーのカスタマイズ -ピッカーに表示される絵文字を自分好みにカスタマイズすることができます。 設定の「リアクション」で設定します。 - -## リモート投稿へのリアクションについて -リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。 - -## リモートからのリアクションについて -リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。 diff --git a/src/docs/kab-KAB/features/silence.md b/src/docs/kab-KAB/features/silence.md deleted file mode 100644 index 7e26feab0..000000000 --- a/src/docs/kab-KAB/features/silence.md +++ /dev/null @@ -1,6 +0,0 @@ -# サイレンス -サイレンスは、アカウントに設定される状態のひとつです。 - -アカウントがサイレンス状態になると、ノートの公開範囲をパブリックにできなくなります。 ホーム、フォロワー、ダイレクトは選択可能なため、サイレンスを受けた場合でもフォロワーやあなたのユーザーページを直接訪れた場合は投稿を閲覧できますが、GTL(連合タイムライン)やLTL(ローカルタイムライン)には投稿が流れません。 - -アカウントのサイレンス状態は、サーバーのモデレーターによって有効化/無効化されます。 diff --git a/src/docs/kab-KAB/features/theme.md b/src/docs/kab-KAB/features/theme.md deleted file mode 100644 index a406f3433..000000000 --- a/src/docs/kab-KAB/features/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# テーマ - -テーマを設定して、Misskeyクライアントの見た目を変更できます。 - -## テーマの設定 -設定 > テーマ - -## テーマを作成する -テーマコードはJSON5で記述されたテーマオブジェクトです。 テーマは以下のようなオブジェクトです。 -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... テーマの一意なID。UUIDをおすすめします。 -* `name` ... テーマ名 -* `author` ... テーマの作者 -* `desc` ... テーマの説明(オプション) -* `base` ... 明るいテーマか、暗いテーマか - * `light`にすると明るいテーマになり、`dark`にすると暗いテーマになります。 - * テーマはここで設定されたベーステーマを継承します。 -* `props` ... テーマのスタイル定義。これから説明します。 - -### テーマのスタイル定義 -`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 - -#### バリューで使える構文 -* 16進数で表された色 - * 例: `#00ff00` -* `rgb(r, g, b)`形式で表された色 - * 例: `rgb(0, 255, 0)` -* `rgb(r, g, b, a)`形式で表された透明度を含む色 - * 例: `rgba(0, 255, 0, 0.5)` -* 他のキーの値の参照 - * `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。 - * 例: `@panel` -* 定数(後述)の参照 - * `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。 - * 例: `$main` -* 関数(後述) - * `:{関数名}<{引数}<{色}` - -#### 定数 -「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 キー名を`$`で始めると、そのキーはCSS変数として出力されません。 - -#### 関数 -wip diff --git a/src/docs/kab-KAB/features/timeline.md b/src/docs/kab-KAB/features/timeline.md deleted file mode 100644 index 8ba0b76e4..000000000 --- a/src/docs/kab-KAB/features/timeline.md +++ /dev/null @@ -1,31 +0,0 @@ -# タイムライン -タイムラインは、[ノート](./note)が時系列で表示される機能です。 タイムラインには以下で示す種類があり、種類によって表示されるノートも異なります。 なお、タイムラインの種類によってはサーバーにより無効になっている場合があります。 - -## ホーム -自分のフォローしているユーザーの投稿が流れます。HTLと略されます。 - -## ローカル -全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。LTLと略されます。 - -## ソーシャル -自分のフォローしているユーザーの投稿と、全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。STLと略されます。 - -## グローバル -全てのローカルユーザーの「ホーム」指定されていない投稿と、サーバーに届いた全てのリモートユーザーの「ホーム」指定されていない投稿が流れます。GTLと略されます。 - -## 比較 -| ソース | | | タイムライン | | | -| ------------ | --------- | --- | ------ | ----- | ----- | -| ユーザー | 公開範囲 | ホーム | ローカル | ソーシャル | グローバル | -| ローカル (フォロー) | 公開 | ✔ | ✔ | ✔ | ✔ | -| | ホーム | ✔ | | ✔ | | -| | Imeḍfaṛen | ✔ | ✔ | ✔ | ✔ | -| リモート (フォロー) | 公開 | ✔ | | ✔ | ✔ | -| | ホーム | ✔ | | ✔ | | -| | Imeḍfaṛen | ✔ | | ✔ | ✔ | -| ローカル (未フォロー) | 公開 | | ✔ | ✔ | ✔ | -| | ホーム | | | | | -| | Imeḍfaṛen | | | | | -| リモート (未フォロー) | 公開 | | | | ✔ | -| | ホーム | | | | | -| | Imeḍfaṛen | | | | | diff --git a/src/docs/kab-KAB/features/widgets.md b/src/docs/kab-KAB/features/widgets.md deleted file mode 100644 index a7c2c1d1d..000000000 --- a/src/docs/kab-KAB/features/widgets.md +++ /dev/null @@ -1,7 +0,0 @@ -# ウィジェット -ウィジェットは、MisskeyのUI上に設置できる小型の情報表示、操作が行えるパーツです。 - -ウィジェットを編集するには、ウィジェット編集モードに切り替えます。切り替え方法はUIによって異なります。 ウィジェット編集モードでは、ウィジェットの追加、削除、並び替え、およびそれぞれのウィジェットの設定を行えます。 - -## 利用可能なウィジェット一覧 -todo diff --git a/src/docs/kab-KAB/features/word-mute.md b/src/docs/kab-KAB/features/word-mute.md deleted file mode 100644 index fa4d14346..000000000 --- a/src/docs/kab-KAB/features/word-mute.md +++ /dev/null @@ -1,20 +0,0 @@ -# ワードミュート -ワードミュートの設定をすると、条件に合致したノートが表示されなくなります。 - -ワードミュートには、ソフトワードミュートとハードワードミュートの2種類があります。それぞれについて設定の方法と挙動を説明します。 - -## ソフトワードミュート -ソフトワードミュートは、クライアント(アプリ)側でミュートを判断するワードミュートです。 - -ノートが設定した条件に合致すると、「(ユーザー名)が何かを言いました」という表示で隠れます。 -クリックすると元の通りに表示されます。 - -## ハードワードミュート -ハードワードミュートは、アンテナのようにサーバーが新しいノートの本文に対して条件に合致するかどうか判断し、タイムラインから対象となったノートを除外します。 - -つまり、ハードワードミュートには、以下のような特徴があります。 - -* 条件設定後、新しい投稿のみがミュートの対象になります。 -* 条件を変更しても、過去にハードミュートされたノートはミュートされたままになります。 -* 「○○が何かを言いました」でタイムラインが埋まることがありません。 -* ソフトミュートに非対応のアプリでも、ハードミュートは適用されます。 diff --git a/src/docs/kab-KAB/follow.md b/src/docs/kab-KAB/follow.md deleted file mode 100644 index 500073a4b..000000000 --- a/src/docs/kab-KAB/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# Ig ṭṭafaṛ -ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。 diff --git a/src/docs/kab-KAB/general/apps.md b/src/docs/kab-KAB/general/apps.md deleted file mode 100644 index 1f4c85fe8..000000000 --- a/src/docs/kab-KAB/general/apps.md +++ /dev/null @@ -1,6 +0,0 @@ -# サードパーティアプリのリスト -## クライアント -todo - -## 連携サービス -todo diff --git a/src/docs/kab-KAB/general/changelog.md b/src/docs/kab-KAB/general/changelog.md deleted file mode 100644 index 6766a63b2..000000000 --- a/src/docs/kab-KAB/general/changelog.md +++ /dev/null @@ -1,5 +0,0 @@ -# 更新履歴 -
ℹ️ このサーバーの更新履歴です。Misskeyの最新のリリースについては、GitHubをご確認ください。
- - - diff --git a/src/docs/kab-KAB/general/faq.md b/src/docs/kab-KAB/general/faq.md deleted file mode 100644 index c272b2ad4..000000000 --- a/src/docs/kab-KAB/general/faq.md +++ /dev/null @@ -1,28 +0,0 @@ -# よくある質問 -ここでは利用上のよくある質問について掲載しています。 Misskeyのプロジェクト自体についてのよくある質問は[こちら](./misskey)に掲載されています。 - -## iOS/Androidのアプリはありますか? -公式にはそういったOSのネイティブアプリを開発していませんが、サードパーティ製のアプリがいくつかあります。 詳しくは[こちら](./apps)をご覧ください。 - -ただ、サードパーティ製アプリはどうしても機能への対応が遅れてしまうため、とくに拘りがなければ公式のWebクライアントの利用をおすすめします。 なお、MisskeyのWebクライアントはPWAに対応しているので、ネイティブアプリのように動作させることも可能です。 詳しくは[こちら](todo)をご覧ください。 - -## Mastodonクライアントでログインできないのですが? -MisskeyはMastodonのAPIと互換性がないため、一部を除きMastodonクライアントでMisskeyを利用することはできません。 - -## 他のサーバーのユーザーをフォローするときは? -メニューから検索を選び、ユーザー名をホスト込みで入力します。例: `@syuilo@misskey.io` - -## Renoteを削除するには? -Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 Renoteについては[こちら](../features/note)をご確認ください。 - -## URLのプレビューを表示させたくない -MFMには、そのURLのプレビューを無効にする構文があります。詳細は[MFMチートシート](/mfm-cheat-sheet)をご確認ください。 - -## カスタム絵文字を追加したい -運営者のみがカスタム絵文字を追加、編集、削除できます。それらを希望する場合は運営者に依頼してください。 - -## Botを開発したい -Misskey APIを利用してBotの開発が可能です。[こちら](../advanced/develop-bot)をご確認ください。 - -## ノートの翻訳機能はどのサービスを使用していますか? -[DeepL](https://www.deepl.com/)を使用しています。 diff --git a/src/docs/kab-KAB/general/glossary.md b/src/docs/kab-KAB/general/glossary.md deleted file mode 100644 index bb8a24336..000000000 --- a/src/docs/kab-KAB/general/glossary.md +++ /dev/null @@ -1,89 +0,0 @@ -# 用語集 -Misskeyに関する用語集です。 - -## ActivityPub -(読み: あくてぃびてぃぱぶ) 分散型を実現するために用いられるプロトコル(仕様)。このプロトコルに則ってサーバー同士通信を行うことで、連合が行われ、Fediverseを形成しています。 - -## AiScript -(読み: あいすくりぷと) Misskey上で使用できるプログラミング言語です。詳細は[こちら。](../advanced/aiscript) - -## API -(読み: えーぴーあい) Misskeyのサーバーが公開している、プログラムからMisskeyを扱うためのインターフェース。詳細は[こちら。](../advanced/api) - -## Bot -(読み: ぼっと) プログラムによって動作しているアカウント。 - -## CW -(読み: こんてんつわーにんぐ) Contents Warningの略。ノートの内容を、操作なしには表示しないようにできる機能。主に長大な内容を隠すためや、ネタバレ防止などに使われます。 - -## Fediverse -(読み: ふぇでぃばーす) Misskeyを含む様々な分散型ソフトウェアのサーバーで構成されたネットワーク。 - -## GTL -グローバルタイムライン(Global TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## HTL -ホームタイムライン(Home TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## LTL -ローカルタイムライン(Local TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## MFM -(読み: えむえふえむ) Misskey Flavored Markdownの略で、Misskey上で使用できるマークアップ言語です。詳細は[こちら。](../features/mfm) - -## NSFW -(読み: のっとせーふふぉーわーく) Not Safe For Workの略。画像を「閲覧注意」扱いにし、操作なしには表示しないようにすることができる機能。 - -## Renote -(読み: りのーと) 既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノート。詳細は[こちら。](../features/note) - -## STL -ソーシャルタイムライン(Social TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## 藍 -(読み: あい) Misskeyの看板娘(公式キャラクター)です。 - -## アクティブユーザー -インスタンスにアカウントを作っているユーザーのうち、現在も実際にサービスを利用しているユーザーのこと。 - -## インスタンス -todo - -## カスタム絵文字 -サーバーで用意された絵文字。カスタム絵文字ではない通常の絵文字は「Unicode絵文字」と区別して呼ばれる。 - -## コントロールパネル -インスタンスの設定画面のこと。 - -## サーバー -todo - -## サイレンス -ノートをパブリックな公開範囲で投稿できなくされている状態。モデレーターの判断でユーザーごとに設定されます。詳細は[こちら。](../features/silence) - -## ジョブキュー -アクティビティ配送などを順番に行うためのシステム。 - -## 凍結 -アカウントが使用不可に設定されている状態。 - -## ドライブ -Misskeyにアップロードしたファイルを管理する機能。詳細は[こちら。](../features/drive) - -## ノート -Misskeyに投稿される、文章、ファイル、アンケートなどを含めることができるコンテンツ。詳細は[こちら。](../features/note) - -## ミスキスト -Misskeyを使う人のこと。 - -## モデレーター -スパムの凍結およびサイレンスや不適切な投稿の削除など、コミュニティ運営に関する権限を持つユーザー。 - -## リモート -他サーバーのことを指します。リモートユーザーといったように接頭辞としても使われます。ローカルの逆です。 - -## 連合 -サーバー上で作成された情報が他のサーバーに伝わること。 - -## ローカル -自サーバーのことを指します。ローカルユーザー、ローカルタイムラインといったように接頭辞としても使われます。リモートの逆です。 diff --git a/src/docs/kab-KAB/general/links.md b/src/docs/kab-KAB/general/links.md deleted file mode 100644 index 8c3cfc192..000000000 --- a/src/docs/kab-KAB/general/links.md +++ /dev/null @@ -1,12 +0,0 @@ -# リンク集 - -## Webサイト -- [Official Discord](https://discord.gg/Wp8gVStHW3) - Misskey公式Discordサーバー -- [Misskey Forum](https://forum.misskey.io/) - Misskeyに関する話題を扱うフォーラム - -## Imiḍan -- [@repo@misskey.io](https://misskey.io/@repo) - Misskeyのリポジトリの更新を投稿するbot - -## ライブラリ -- [misskey-dev/misskey.js](https://github.com/misskey-dev/misskey.js) - JavaScriptのMisskey SDK -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptのMFMパーサー実装 diff --git a/src/docs/kab-KAB/general/misskey.md b/src/docs/kab-KAB/general/misskey.md deleted file mode 100644 index d97664ddc..000000000 --- a/src/docs/kab-KAB/general/misskey.md +++ /dev/null @@ -1,87 +0,0 @@ -# Misskeyについて - -Misskeyはオープンソースの分散型マイクロブログプラットフォームプロジェクトです。 開発は日本でsyuiloによって2014年から開始されました。 ドライブ、リアクションなどの豊富な機能や、高いカスタマイズ性を備えたUIを持つことが特徴です。 - -## 歴史 -開発当初は掲示板がメインのサービスでしたが、ユーザーが短文を投稿し、それを時系列で流れるタイムライン機能を追加したところ人気が高まり、徐々にそれがメインとして開発が進むようになりました。 当初は分散型ではありませんでしたが、2018年にActivityPubを実装し分散型になったことで、より多くの方に認知され利用されるサービスになり、現在に至ります。 -
ℹ️ Misskeyという名前は、syuiloが当時聴いていたMay'nというアーティストの楽曲、Brain Diverの歌詞に由来します。
- -誰でも開発に参加することができ、現在でも活発に開発が続いています。 - -## 分散型とは何か? - -分散(distributed)型とは、非中央集権(decentralized)とも呼ばれ、コミュニティが多数のサーバーに分散して存在し、それらが相互に通信(連合、federation)することでコンテンツ共有ネットワーク(Fediverse)を形成していることが特徴のサービスです。 単一のサーバーしか存在しない、もしくは複数存在しても互いに独立している場合は中央集権なサービスと言われ、例えばTwitterやFacebookなどほとんどのサービスがそれに該当します。 分散型のメリットは、自分に合った運営者やテーマのサーバーを選択できることです。自分でサーバーを作成することもできます。連合するおかげで、どのサーバーを選んでも、同じコミュニティにアクセスできます。 - -## 常にオープンソース -Misskeyはこれまでもこれからも、オープンソースであり続けます。オープンソースとは、簡単に言うとソフトウェアのソースコード(プログラム)が公開されていることです。ソースコードの修正や再配布が可能であることを定義に含めることもあります。 Misskeyのすべてのソースコードは[AGPL](https://github.com/misskey-dev/misskey/blob/develop/LICENSE)というオープンソースライセンスの下に[公開](https://github.com/misskey-dev)されていて、誰でも自由に閲覧、使用、修正、改変、再配布をすることができます。 オープンソースは、自分で好きなように変えたり、有害な処理が含まれていないことを確認することができたり、誰でも開発に参加できるなどの、様々なメリットがあります。 上述の分散型を実現するためにも、オープンソースであるということは必要不可欠な要素です。 再び引き合いに出しますが、TwitterやFacebookなどの利益を得ているほとんどのサービスはオープンソースではありません。 - -
ℹ️ 技術的に言うと、MisskeyのソースコードはGitで管理されていて、リポジトリはGitHub上でホスティングされています。
- -## 開発に参加する、プロジェクトを支援する -Misskeyを気に入っていただけたら、ぜひプロジェクトを支援してください。プロジェクトに貢献するには、以下で紹介するようにいろいろな方法があります。方法によっては開発のスキルは不要なので、誰でも気軽に参加し貢献することができます。いつでもお待ちしています。 - -### 機能を追加したり、バグを修正する -ソフトウェアエンジニアのスキルをお持ちの方であれば、ソースコードを編集する形でプロジェクトに貢献することができます。 貢献についてのガイドは[こちら](https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md)です。 - -### 議論に参加する -新しい機能、または既存の機能について意見を述べたり、不具合を報告したりすることでも貢献できます。 そのようなディスカッションは[GitHub](https://github.com/misskey-dev)上か、[フォーラム](https://forum.misskey.io/)等で行われます。 - -### テキストを翻訳する -Misskeyは様々な言語に対応しています(i18n -internationalizationの略- と呼ばれます)。元の言語は基本的に日本語ですが、有志によって他の言語へと翻訳されています。 その翻訳作業に加わっていただくことでもMisskeyに貢献できます。 Misskeyは[Crowdinというサービスを使用して翻訳の管理を行っています。](https://crowdin.com/project/misskey) - -### 感想を投稿する -不具合報告等だけではなく、Misskeyの良い点、楽しい点といったポジティブな意見もぜひ共有してください。開発の励みになり、それは間接的ですがプロジェクトへの貢献です。 - -### ミスキストを増やす -ミスキストとは、Misskeyを使用する人のことです。 知り合いに紹介するなどしてMisskeyを広めていただければ、ミスキストが増え開発のモチベーションが上がります。 - -### 寄付をする -Misskeyはビジネスではなく、利用は無料であるため、収益は皆様からの寄付のみです。(インスタンスによっては広告収入を得ているような場合もありますが、それは運営者の収入であり直接開発者への収入にはなりません) 寄付をしていただければ、今後も開発を続けることが可能になり、プロジェクトへの貢献になります。 寄付は基本的には[Patreon](https://www.patreon.com/syuilo)で受け付けています。 一定額寄付していただけると、Misskeyの[情報ページ](/about-misskey)に名前を記載することができます。 - -また、サーバーの運営者も、基本的には収益を得ていません。サーバーの運営にはコストがかかるので、運営者の支援をすることもご検討ください。 開発には直接関係しませんが、サーバーがあってこそのプロジェクトなので、運営が維持されるというのは開発と同じくらい重要なことです。 - -## クレジット -Misskeyの開発者や、Misskeyに寄付をしてくださった方の一覧は[こちら](/about-misskey)で見ることができます。 - -## よくある質問 -### プロジェクトは何を目指していますか? -強いて言うと、漠然的になりますが広く使われる汎用的なプラットフォームになることを目指しています。 Misskeyは他のプロジェクトとは違い、何らかの思想(例えば、反中央集権)やビジョンに基づいて開発が行われているわけではなく、その点ではフラットです。 それが逆に、特定の方向性に縛られないフレキシブルさを生み出すことに繋がっていると感じています。 - - -### 企業によって開発されていますか? -いいえ。Misskeyの開発は個人で行われており、商業的でもないため、特定の企業の関りはありません。 開発メンバーも基本的にはボランティアです。 また、開発に対し企業のスポンサーがつくこともありますが、その場合でもやはり開発は個人のコミュニティが主体です。 - -### 誰が運営していますか? -Misskeyは分散型なため、各サーバーにそれぞれ異なった運営者がいます。従って、特定の個人や企業によって、Misskeyの全てが運営されているわけではありません。 また、開発チームが運営を行うわけでもないため、運営に関する連絡は、お使いのサーバーの運営者に行ってください。 サーバーの運営者は、[このページ](/about)で確認することができます。 あなたがサーバーを作成すれば、あなたが運営者になります。 - -### どのサーバーを選べばいいですか? -[サーバー一覧が公開されています。](https://join.misskey.page/ja-JP/instances) サーバーによってコミュニティのテーマ(特定のこと、ものが好き 等)が決められている場合があるので、自分に合ったテーマのサーバーがあれば、そこを選ぶと良いかもしれません。 他にも、サーバーの規模、ユーザー層、国および言語、運営者が信頼できるかどうか、などの観点があります。 なお、Misskey公式のサーバーというものはありません。自身で新しくサーバーを作成するという選択肢もあります。 - -基本的にどのサーバーを選んだとしても、他の全てのサーバーのユーザーと繋がることができます。 - -### サーバーを建てるにはどうしたらいいですか? -Misskeyサーバーの作成に興味を持っていただきありがとうございます。 2021年現在、Misskeyのホスティングサービスは存在しないため、サーバーの作成にはある程度の知識が必要です。 サーバーの作成方法については[こちら](todo)をご覧ください。 - -### どのような技術を使用していますか? -Misskeyは開発が進むにつれ使用する技術も大きく変わってきました。開発当初はMySQL + PHP + jQueryといった構成でしたが、現在は以下のようになっています。 -- サーバーサイド: Node.js -- データベース: PostgreSQL、Redis -- UIフレームワーク: Vue.js -- プログラミング言語: TypeScript - -また、MFMやAiScriptなどの、Misskeyから派生して独自の技術も開発しています。 - -### Mastodonのフォークですか? -いいえ。MisskeyはMastodonやその他のプロジェクトとは全く別のプロジェクトです。 開発に関しても、Misskeyの方が昔から開発されています。ただし、分散型になったのはMastodonの登場より後です。 同じActivityPubという分散のためのプロトコルを実装しているという点以外、両者に特に関りがあるわけでもありません。 - -### iOS/Androidのアプリはありますか? -公式にはそういったOSのネイティブアプリを開発していませんが、サードパーティ製のアプリがいくつかあります。 詳しくは[こちら](./apps)をご覧ください。 - -ただ、サードパーティ製アプリはどうしても機能への対応が遅れてしまうため、とくに拘りがなければ公式のWebクライアントの利用をおすすめします。 なお、MisskeyのWebクライアントはPWAに対応しているので、ネイティブアプリのように動作させることも可能です。 詳しくは[こちら](todo)をご覧ください。 - -### Misskeyのロゴ、アイコンはどこで入手できますか? -(準備中) - -### 時折目にする猫耳の可愛い女の子は? -Misskeyの守り神、藍ちゃんです。アイチャンカワイイヤッター! -
ℹ️ 藍ちゃんについてはこちらです。
diff --git a/src/docs/kab-KAB/general/report-issue.md b/src/docs/kab-KAB/general/report-issue.md deleted file mode 100644 index 63527e32a..000000000 --- a/src/docs/kab-KAB/general/report-issue.md +++ /dev/null @@ -1,8 +0,0 @@ -# 不具合の報告 -不具合と思われる状況に遭遇したときは、まず[トラブルシューティング](./troubleshooting)をご一読ください。 それでも問題が解決しないときは、以下の情報を含めて[フォーラム](https://forum.misskey.io/)に投稿してください。 投稿することで、解決策が見つかったり、不具合と判断されれば開発チームによって修正が行われます。 - -## 含める情報 -- Misskeyのバージョン([情報ページ](/about)で確認できます) -- お使いのブラウザの種類とバージョン -- お使いのOSの種類とバージョン -- 問題の再現手順 diff --git a/src/docs/kab-KAB/general/troubleshooting.md b/src/docs/kab-KAB/general/troubleshooting.md deleted file mode 100644 index f895b4984..000000000 --- a/src/docs/kab-KAB/general/troubleshooting.md +++ /dev/null @@ -1,40 +0,0 @@ -# トラブルシューティング -
ℹ️ よくある質問も合わせてお役立てください。
- -問題が発生したときは、まずこちらをご確認ください。 該当する項目が無い、もしくは手順を試しても効果がない場合は、サーバーの管理者に連絡するか[不具合を報告](./report-issue)してください。 - -## クライアントが起動しない -ほとんどの場合、お使いのブラウザまたはOSのバージョンが古いことが原因です。 ブラウザおよびOSのバージョンを最新のものに更新してから、再度試してみてください。 - -これは稀ですが、それでも起動しない場合は、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。 - -## ページが読み込めない -クライアントが起動するもののページが読み込めないというエラーが出る場合は、ネットワークに問題がないか確認してください。また、サーバーがダウンしていないか確認してください。 - -これは稀ですが、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。 - -まだ問題がある場合は、サーバーの問題と思われるのでサーバーの管理者に連絡してください。 - -## クライアントの動作が遅い -以下を試してみてください: - -- クライアント設定で「UIのアニメーションを減らす」を有効にする -- クライアント設定で「モーダルにぼかし効果を使用」を無効にする -- お使いのブラウザの設定でハードウェアアクセラレーションを有効にする -- お使いのデバイスのスペックを上げる - -## UIの一部の表示がおかしい(背景が透明になっている等) -アップデートによりUIの改修が行われたときに、テーマのキャッシュシステムの影響でそのような表示になることがあります。 クライアントの設定の「キャッシュをクリア」すると直ります。 -
⚠️ 「クライアントの」キャッシュクリアです。「ブラウザの」キャッシュクリアは行わないでください。
- -## 通知やアンテナ等の点滅が消えない -点滅は、未読のコンテンツがあることを示しています。通常点滅が消えない場合は、コンテンツを遡ると未読なコンテンツが残っています。 すべて既読にしたと思われるのに、それでもなお点滅が続く場合(おそらく不具合と思われます)は設定から強制的にすべて既読扱いにすることができます。 - -## Renoteができない -フォロワー限定のノートはRenoteすることはできません。 - -## UI上で特定の要素が表示されない -広告ブロッカーを使用しているとそのような不具合が発生することがあります。Misskeyではオフにしてご利用ください。 - -## UI上で未翻訳の部分がある -ほとんどの場合、単に翻訳が間に合っていないだけで、不具合ではありません。翻訳が終わるまでお待ちください。 [翻訳に参加](./misskey)していただくことも可能です。 diff --git a/src/docs/kab-KAB/keyboard-shortcut.md b/src/docs/kab-KAB/keyboard-shortcut.md deleted file mode 100644 index 3b15afa68..000000000 --- a/src/docs/kab-KAB/keyboard-shortcut.md +++ /dev/null @@ -1,68 +0,0 @@ -# キーボードショートカット - -## グローバル -これらのショートカットは基本的にどこでも使えます。 - - - - - - - - - - - -
ショートカット効果由来
P, N新規投稿Post, New, Note
Tタイムラインの最も新しい投稿にフォーカスTimeline, Top
Shift + N通知を表示/隠すNotifications
SNadiSearch
H, ?ヘルプを表示Help
- -## 投稿にフォーカスされた状態 - - - - - - - - - - - - - - - - - - - -
ショートカット効果由来
, K, Shift + Tab上の投稿にフォーカスを移動-
, J, Tab下の投稿にフォーカスを移動-
R返信フォームを開くReply
QRenoteフォームを開くQuote
Ctrl + Q即刻Renoteする(フォームを開かずに)-
E, A, +リアクションフォームを開くEmote, reAction
0~9数字に対応したリアクションをする(対応については後述)-
F, Bお気に入りに登録Favorite, Bookmark
Del, Ctrl + D投稿を削除Delete
M, O投稿に対するメニューを開くMore, Other
SCWで隠された部分を表示 or 隠すShow, See
Escフォーカスを外す-
- -## Renoteフォーム - - - - - - - - - - -
ショートカット効果由来
EnterRenoteする-
Qフォームを展開するQuote
Escフォームを閉じる-
- -## リアクションフォーム -デフォルトで「👍」にフォーカスが当たっている状態です。 - - - - - - - - - - - - - -
ショートカット効果由来
, K上のリアクションにフォーカスを移動-
, J下のリアクションにフォーカスを移動-
, H, Shift + Tab左のリアクションにフォーカスを移動-
, L, Tab右のリアクションにフォーカスを移動-
Enter, Space, +リアクション確定-
0~9数字に対応したリアクションで確定-
Escリアクションするのをやめる-
diff --git a/src/docs/kab-KAB/mfm.md b/src/docs/kab-KAB/mfm.md deleted file mode 100644 index e237287ac..000000000 --- a/src/docs/kab-KAB/mfm.md +++ /dev/null @@ -1,2 +0,0 @@ -# MFM -MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます。 diff --git a/src/docs/kab-KAB/mute.md b/src/docs/kab-KAB/mute.md deleted file mode 100644 index 6a9608662..000000000 --- a/src/docs/kab-KAB/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# ミュート - -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -* タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -* そのユーザーからの通知 -* メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 - -ユーザーをミュートするには、対象のユーザーのユーザーページに表示されている「ミュート」ボタンを押します。 - -ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。 - -設定>ミュート から、自分がミュートしているユーザー一覧を確認することができます。 diff --git a/src/docs/kab-KAB/pages.md b/src/docs/kab-KAB/pages.md deleted file mode 100644 index a7311b95e..000000000 --- a/src/docs/kab-KAB/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# Pages - -## 変数 -変数を使うことで動的なページを作成できます。テキスト内で { 変数名 } と書くとそこに変数の値を埋め込めます。例えば Hello { thing } world! というテキストで、変数(thing)の値が ai だった場合、テキストは Hello ai world! になります。 - -変数の評価(値を算出すること)は上から下に行われるので、ある変数の中で自分より下の変数を参照することはできません。例えば上から A、B、C と3つの変数を定義したとき、Cの中でABを参照することはできますが、Aの中でBCを参照することはできません。 - -ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。 - -関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。 diff --git a/src/docs/kab-KAB/reaction.md b/src/docs/kab-KAB/reaction.md deleted file mode 100644 index c26ead75b..000000000 --- a/src/docs/kab-KAB/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# リアクション -他の人のノートに、絵文字を付けて簡単にあなたの反応を伝えられる機能です。 リアクションするには、ノートの + アイコンをクリックしてピッカーを表示し、絵文字を選択します。 リアクションには[カスタム絵文字](./custom-emoji)も使用できます。 - -## リアクションピッカーのカスタマイズ -ピッカーに表示される絵文字を自分好みにカスタマイズすることができます。 設定の「リアクション」で設定します。 - -## リモート投稿へのリアクションについて -リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。 また、相手がMisskeyであったとしても、カスタム絵文字リアクションは伝わらず、自動的に「👍」等にフォールバックされます。 - -## リモートからのリアクションについて -リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。 diff --git a/src/docs/kab-KAB/reversi-bot.md b/src/docs/kab-KAB/reversi-bot.md deleted file mode 100644 index 7ab2a7212..000000000 --- a/src/docs/kab-KAB/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# MisskeyリバーシBotの開発 -Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。 - -1. `games/reversi`ストリームに以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - -2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる - * イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている - -3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する - -4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - * `game`: `game`の`id` - -5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う - -6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する - -7. ゲームが開始すると、`started`イベントが流れてくる - * イベントの中身にはゲーム情報が含まれている - -8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述) - -9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる - * `color`として石の色が含まれている - * `pos`として位置情報が含まれている - -## 位置の計算法 -8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### X,Y座標 から インデックス に変換する -``` -pos = x + (y * mapWidth) -``` -`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます: -``` -mapWidth = map[0].length -``` - -### インデックス から X,Y座標 に変換する -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## マップ情報 -マップ情報は、ゲーム情報の`map`に入っています。 文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 それをもとにマップのデザインを知る事が出来ます: -* `(スペース)` ... マス無し -* `-` ... マス -* `b` ... 初期配置される黒石 -* `w` ... 初期配置される白石 - -例えば、4*4の次のような単純なマップがあるとします: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -この場合、マップデータはこのようになります: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## ユーザーにフォームを提示して対話可能Botを作成する -ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。 - -フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します: -```javascript -{ - type: 'init-form', - body: [フォームコントロールの配列] -} -``` - -フォームコントロールの配列については今から説明します。 フォームコントロールは、次のようなオブジェクトです: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... コントロールのID。 `type` ... コントロールの種類。後述します。 `label` ... コントロールと一緒に表記するテキスト。 `value` ... コントロールのデフォルト値。 - -### フォームの操作を受け取る -ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### フォームコントロールの種類 -#### スイッチ -type: `switch` スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。 - -##### プロパティ -`label` ... スイッチに表記するテキスト。 - -#### ラジオボタン -type: `radio` ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。 - -##### プロパティ -`items` ... ラジオボタンの選択肢。例: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '強', - value: 3 -}] -``` - -#### スライダー -type: `slider` スライダーを表示します。 - -##### プロパティ -`min` ... スライダーの下限。 `max` ... スライダーの上限。 `step` ... 入力欄で刻むステップ値。 - -#### テキストボックス -type: `textbox` テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。 - -## ユーザーにメッセージを表示する -設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 メッセージを表示するには、次のメッセージをストリームに送信します: -```javascript -{ - type: 'message', - body: { - text: 'メッセージ内容', - type: 'メッセージの種類' - } -} -``` -メッセージの種類: `success`, `info`, `warning`, `error`。 - -## 投了する -投了をするには、このエンドポイントにリクエストします。 diff --git a/src/docs/kab-KAB/stream.md b/src/docs/kab-KAB/stream.md deleted file mode 100644 index 9011c37c5..000000000 --- a/src/docs/kab-KAB/stream.md +++ /dev/null @@ -1,354 +0,0 @@ -# ストリーミングAPI - -ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。 - -## ストリームに接続する - -ストリーミングAPIを利用するには、まずMisskeyサーバーに**websocket**接続する必要があります。 - -以下のURLに、`i`というパラメータ名で認証情報を含めて、websocket接続してください。例: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。 - -
-

認証情報の取得については、こちらのドキュメントをご確認ください。

-
- ---- - -認証情報は省略することもできますが、その場合非ログインでの利用ということになり、受信できる情報や可能な操作は限られます。例: - -``` -%WS_URL%/streaming -``` - ---- - -ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。 - -**ストリームでのやり取りはすべてJSONです。** - -## チャンネル -MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。 - -### チャンネルに接続する -チャンネルに接続するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -ここで、 -* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。 -* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。 -* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。 - -
-

IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。

-
- -### チャンネルからのメッセージを受け取る -例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。 - -チャンネルがメッセージを発すると、次のようなデータがJSONでストリームに流れてきます: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。 -* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。 -* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。 - -### チャンネルに向けてメッセージを送信する -チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。 - -チャンネルにメッセージを送信するには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。 -* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。 -* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。 - -### チャンネルから切断する -チャンネルから切断するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。 - -## ストリームを経由してAPIリクエストする - -ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。 - -ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -ここで、 -* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 -* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 -* `data`には、エンドポイントのパラメータを含めます。 - -
-

APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。

-
- -### レスポンスの受信 - -APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。 - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -ここで、 -* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 -* `body`には、レスポンスが含まれています。 - -## 投稿のキャプチャ - -Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。 - -例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。 - -しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。 - -この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。 - -### 投稿をキャプチャする - -投稿をキャプチャするには、ストリームに次のようなメッセージを送信します: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャしたい投稿の`id`を設定します。 - -このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 - -例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -ここで、 -* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。 -* `body`内の`type`に、イベントの種類が設定されます。 -* `body`内の`body`に、イベントの詳細が設定されます。 - -#### イベントの種類 - -##### `reacted` -その投稿にリアクションがされた時に発生します。 - -* `reaction`に、リアクションの種類が設定されます。 -* `userId`に、リアクションを行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -その投稿が削除された時に発生します。 - -* `deletedAt`に、削除日時が設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -その投稿に添付されたアンケートに投票された時に発生します。 - -* `choice`に、選択肢IDが設定されます。 -* `userId`に、投票を行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### 投稿のキャプチャを解除する - -その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。 - -次のメッセージを送信します: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャを解除したい投稿の`id`を設定します。 - -このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 - -# チャンネル一覧 -## `main` -アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `renote` -自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。 - -#### `mention` -誰かからメンションされたときに発生するイベントです。 - -#### `readAllNotifications` -自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。 - -#### `meUpdated` -自分の情報が更新されたことを表すイベントです。 - -#### `follow` -自分が誰かをフォローしたときに発生するイベントです。 - -#### `unfollow` -自分が誰かのフォローを解除したときに発生するイベントです。 - -#### `followed` -自分が誰かにフォローされたときに発生するイベントです。 - -## `homeTimeline` -ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -タイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `localTimeline` -ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `hybridTimeline` -ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ソーシャルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `globalTimeline` -グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 diff --git a/src/docs/kab-KAB/theme.md b/src/docs/kab-KAB/theme.md deleted file mode 100644 index a406f3433..000000000 --- a/src/docs/kab-KAB/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# テーマ - -テーマを設定して、Misskeyクライアントの見た目を変更できます。 - -## テーマの設定 -設定 > テーマ - -## テーマを作成する -テーマコードはJSON5で記述されたテーマオブジェクトです。 テーマは以下のようなオブジェクトです。 -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... テーマの一意なID。UUIDをおすすめします。 -* `name` ... テーマ名 -* `author` ... テーマの作者 -* `desc` ... テーマの説明(オプション) -* `base` ... 明るいテーマか、暗いテーマか - * `light`にすると明るいテーマになり、`dark`にすると暗いテーマになります。 - * テーマはここで設定されたベーステーマを継承します。 -* `props` ... テーマのスタイル定義。これから説明します。 - -### テーマのスタイル定義 -`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 - -#### バリューで使える構文 -* 16進数で表された色 - * 例: `#00ff00` -* `rgb(r, g, b)`形式で表された色 - * 例: `rgb(0, 255, 0)` -* `rgb(r, g, b, a)`形式で表された透明度を含む色 - * 例: `rgba(0, 255, 0, 0.5)` -* 他のキーの値の参照 - * `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。 - * 例: `@panel` -* 定数(後述)の参照 - * `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。 - * 例: `$main` -* 関数(後述) - * `:{関数名}<{引数}<{色}` - -#### 定数 -「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 キー名を`$`で始めると、そのキーはCSS変数として出力されません。 - -#### 関数 -wip diff --git a/src/docs/kab-KAB/timelines.md b/src/docs/kab-KAB/timelines.md deleted file mode 100644 index 36ba61bd2..000000000 --- a/src/docs/kab-KAB/timelines.md +++ /dev/null @@ -1,15 +0,0 @@ -# タイムラインの比較 - -https://docs.google.com/spreadsheets/d/1lxQ2ugKrhz58Bg96HTDK_2F98BUritkMyIiBkOByjHA/edit?usp=sharing - -## ホーム -自分のフォローしているユーザーの投稿 - -## ローカル -全てのローカルユーザーの「ホーム」指定されていない投稿 - -## ソーシャル -自分のフォローしているユーザーの投稿と、全てのローカルユーザーの「ホーム」指定されていない投稿 - -## グローバル -全てのローカルユーザーの「ホーム」指定されていない投稿と、サーバーに届いた全てのリモートユーザーの「ホーム」指定されていない投稿 diff --git a/src/docs/kn-IN/admin/disable-timelines.md b/src/docs/kn-IN/admin/disable-timelines.md deleted file mode 100644 index b081e35ab..000000000 --- a/src/docs/kn-IN/admin/disable-timelines.md +++ /dev/null @@ -1,8 +0,0 @@ -# LTL/STL/GTLの無効化 -Misskeyでは、LTL/STL/GTLをそれぞれ無効化することができます。有効/無効を切り替えるには、インスタンスコントロールパネルで設定します。 - -LTLやSTLは、そのインスタンス全員の投稿が見れるため、新規のユーザーにとってはユーザーを探す必要がなくなり、興味のあるユーザーを見つけやすいという利点があります。 しかし同時に、フォロー機能が活用されなくなったり、不適切な投稿が目につきやすくなったり、チャットのようになることで内輪感が生じて逆に新規ユーザーが参加しにくくなるといったデメリットも持ち合わせています。 サーバーによってメリット/デメリットどちらが優勢かは異なるので、オプションとして無効にできるようになっています。 もしデメリットの方が上回っていると感じたら、それらのタイムラインを無効化することも検討してください。 - -
⚠️ 無効化を行うと、ユーザーが困惑し、短期的に見て利用者が減る可能性があります。そのため、無効化の際は影響を慎重に検討し、事前に説明してフォローを整える期間を一定程度設けることを推奨します。
- -なお、管理者/モデレーターは、これらのタイムラインの無効化状態は適用されず、引き続き利用することが可能です。 diff --git a/src/docs/kn-IN/admin/faq.md b/src/docs/kn-IN/admin/faq.md deleted file mode 100644 index 317b4e065..000000000 --- a/src/docs/kn-IN/admin/faq.md +++ /dev/null @@ -1,5 +0,0 @@ -# よくある質問 -ここでは、サーバー管理者向けのよくある質問を掲載しています。 - -## デフォルトテーマを設定したい -現在、デフォルトテーマ設定機能は実装されていません。 diff --git a/src/docs/kn-IN/advanced/aiscript.md b/src/docs/kn-IN/advanced/aiscript.md deleted file mode 100644 index 604d17daa..000000000 --- a/src/docs/kn-IN/advanced/aiscript.md +++ /dev/null @@ -1,7 +0,0 @@ -# AiScript -AiScriptは、Misskeyで使用できるスクリプト言語です。 - -
ℹ️ AiScript実装はMisskeyとは別リポジトリで、オープンソースで公開されています。
- -## 使い方 -AiScriptの構文や組み込み関数などのドキュメントは、[こちら](https://github.com/syuilo/aiscript/tree/master/docs)で公開されています。 diff --git a/src/docs/kn-IN/advanced/api.md b/src/docs/kn-IN/advanced/api.md deleted file mode 100644 index 76019b614..000000000 --- a/src/docs/kn-IN/advanced/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス、Bot等(以下「アプリケーション」と呼びます)を開発できます。 ストリーミングAPIもあるので、リアルタイム性のあるアプリケーションを作ることも可能です。 - -APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。 - -## アクセストークンの取得 -基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。 - -* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む -* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む - -### 自分自身のアクセストークンを手動発行する -「設定 > API」で、自分のアクセストークンを発行できます。 - -[「APIの使い方」へ進む](#APIの使い方) - -### アプリケーション利用者にアクセストークンの発行をリクエストする -アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。 - -#### Step 1 - -UUIDを生成する。以後これをセッションIDと呼びます。 - -> このセッションIDは毎回生成し、使いまわさないようにしてください。 - -#### Step 2 - -`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。 -> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます: -* `name` ... アプリケーション名 - * > 例: `MissDeck` -* `icon` ... アプリケーションのアイコン画像URL - * > 例: `https://missdeck.example.com/icon.png` -* `callback` ... 認証が終わった後にリダイレクトするURL - * > 例: `https://missdeck.example.com/callback` - * リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます -* `permission` ... アプリケーションが要求する権限 - * > 例: `write:notes,write:following,read:drive` - * 要求する権限を`,`で区切って列挙します - * どのような権限があるかは[APIリファレンス](/api-doc)で確認できます - -#### Step 3 -ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。 - -レスポンスに含まれるプロパティ: -* `token` ... ユーザーのアクセストークン -* `user` ... ユーザーの情報 - -[「APIの使い方」へ進む](#APIの使い方) - -## APIの使い方 -**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。 - -* [APIリファレンス](/api-doc) -* [ストリーミングAPI](./stream) diff --git a/src/docs/kn-IN/advanced/create-plugin.md b/src/docs/kn-IN/advanced/create-plugin.md deleted file mode 100644 index 0d2fa1917..000000000 --- a/src/docs/kn-IN/advanced/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# プラグインの作成 -Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。 - -## メタデータ -プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。 - -### name -プラグイン名 - -### author -プラグイン作者 - -### version -プラグインバージョン。数値を指定してください。 - -### description -プラグインの説明 - -### permissions -プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。 - -### config -プラグインの設定情報を表すオブジェクト。 キーに設定名、値に以下のプロパティを含めます。 - -#### type -設定値の種類を表す文字列。以下から選択します。 string number boolean - -#### label -ユーザーに表示する設定名 - -#### description -設定の説明 - -#### default -設定のデフォルト値 - -## APIリファレンス -AiScript標準で組み込まれているAPIは掲載しません。 - -### Mk:dialog(title text type) -ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。 - -### Mk:confirm(title text type) -確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。 - -### Mk:api(endpoint params) -Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。 - -### Mk:save(key value) -任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。 - -### Mk:load(key) -Mk:saveで永続化した指定の名前の値を読み取ります。 - -### Plugin:register_post_form_action(title fn) -投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。 - -### Plugin:register_note_action(title fn) -ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 - -### Plugin:register_user_action(title fn) -ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。 - -### Plugin:register_note_view_interruptor(fn) -UIに表示されるノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:register_note_post_interruptor(fn) -ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:open_url(url) -第一引数に渡されたURLをブラウザの新しいタブで開きます。 - -### Plugin:config -プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。 diff --git a/src/docs/kn-IN/advanced/develop-bot.md b/src/docs/kn-IN/advanced/develop-bot.md deleted file mode 100644 index 7f825e9bc..000000000 --- a/src/docs/kn-IN/advanced/develop-bot.md +++ /dev/null @@ -1,6 +0,0 @@ -# Botの作成 -[Misskey API](./api)を利用してBotの開発が可能です。 また、いくつかのBot実装が公開されているため、ぜひ参考にしてください。 - -- [syuilo/ai](https://github.com/syuilo/ai) ... Node.js上で動く、TypeScript製Bot実装 - -Botを作成したときは、プロフィール設定からBotフラグをオンにしておくことを強くおすすめします。 diff --git a/src/docs/kn-IN/advanced/reversi-bot.md b/src/docs/kn-IN/advanced/reversi-bot.md deleted file mode 100644 index 7ab2a7212..000000000 --- a/src/docs/kn-IN/advanced/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# MisskeyリバーシBotの開発 -Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。 - -1. `games/reversi`ストリームに以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - -2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる - * イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている - -3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する - -4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - * `game`: `game`の`id` - -5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う - -6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する - -7. ゲームが開始すると、`started`イベントが流れてくる - * イベントの中身にはゲーム情報が含まれている - -8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述) - -9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる - * `color`として石の色が含まれている - * `pos`として位置情報が含まれている - -## 位置の計算法 -8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### X,Y座標 から インデックス に変換する -``` -pos = x + (y * mapWidth) -``` -`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます: -``` -mapWidth = map[0].length -``` - -### インデックス から X,Y座標 に変換する -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## マップ情報 -マップ情報は、ゲーム情報の`map`に入っています。 文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 それをもとにマップのデザインを知る事が出来ます: -* `(スペース)` ... マス無し -* `-` ... マス -* `b` ... 初期配置される黒石 -* `w` ... 初期配置される白石 - -例えば、4*4の次のような単純なマップがあるとします: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -この場合、マップデータはこのようになります: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## ユーザーにフォームを提示して対話可能Botを作成する -ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。 - -フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します: -```javascript -{ - type: 'init-form', - body: [フォームコントロールの配列] -} -``` - -フォームコントロールの配列については今から説明します。 フォームコントロールは、次のようなオブジェクトです: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... コントロールのID。 `type` ... コントロールの種類。後述します。 `label` ... コントロールと一緒に表記するテキスト。 `value` ... コントロールのデフォルト値。 - -### フォームの操作を受け取る -ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### フォームコントロールの種類 -#### スイッチ -type: `switch` スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。 - -##### プロパティ -`label` ... スイッチに表記するテキスト。 - -#### ラジオボタン -type: `radio` ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。 - -##### プロパティ -`items` ... ラジオボタンの選択肢。例: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '強', - value: 3 -}] -``` - -#### スライダー -type: `slider` スライダーを表示します。 - -##### プロパティ -`min` ... スライダーの下限。 `max` ... スライダーの上限。 `step` ... 入力欄で刻むステップ値。 - -#### テキストボックス -type: `textbox` テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。 - -## ユーザーにメッセージを表示する -設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 メッセージを表示するには、次のメッセージをストリームに送信します: -```javascript -{ - type: 'message', - body: { - text: 'メッセージ内容', - type: 'メッセージの種類' - } -} -``` -メッセージの種類: `success`, `info`, `warning`, `error`。 - -## 投了する -投了をするには、このエンドポイントにリクエストします。 diff --git a/src/docs/kn-IN/advanced/share-page.md b/src/docs/kn-IN/advanced/share-page.md deleted file mode 100644 index 481b488d7..000000000 --- a/src/docs/kn-IN/advanced/share-page.md +++ /dev/null @@ -1,54 +0,0 @@ -# シェアページ -`/share`を開くと、共有用の投稿フォームを開くことができます。 ここではシェアページで利用できるクエリ文字列の一覧を示します。 - -## クエリ文字列一覧 -### 文字 - -
-
title
-
タイトルです。本文の先頭に[ … ]と挿入されます。
-
text
-
本文です。
-
url
-
URLです。末尾に挿入されます。
-
- -### リプライ情報 -以下のいずれか - -
-
replyId
-
リプライ先のノートid
-
replyUri
-
リプライ先のUrl(リモートのノートオブジェクトを指定)
-
- -### Renote情報 -以下のいずれか - -
-
renoteId
-
Renote先のノートid
-
renoteUri
-
Renote先のUrl(リモートのノートオブジェクトを指定)
-
- -### 公開範囲 -※specifiedに相当する値はvisibility=specifiedとvisibleAccts/visibleUserIdsで指定する - -
-
visibility
-
公開範囲 ['public' | 'home' | 'followers' | 'specified']
-
localOnly
-
0(false) or 1(true)
-
visibleUserIds
-
specified時のダイレクト先のユーザーid カンマ区切りで
-
visibleAccts
-
specified時のダイレクト先のacct(@?username[@host]) カンマ区切りで
-
- -### ಕಡತಗಳು -
-
fileIds
-
添付したいファイルのid(カンマ区切りで)
-
diff --git a/src/docs/kn-IN/advanced/stream.md b/src/docs/kn-IN/advanced/stream.md deleted file mode 100644 index 0e5edd2b0..000000000 --- a/src/docs/kn-IN/advanced/stream.md +++ /dev/null @@ -1,350 +0,0 @@ -# ストリーミングAPI - -ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。 - -## ストリームに接続する - -ストリーミングAPIを利用するには、まずMisskeyサーバーに**websocket**接続する必要があります。 - -以下のURLに、`i`というパラメータ名で認証情報を含めて、websocket接続してください。例: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。 - -
ℹ️ 認証情報の取得については、こちらのドキュメントをご確認ください。
- ---- - -認証情報は省略することもできますが、その場合非ログインでの利用ということになり、受信できる情報や可能な操作は限られます。例: - -``` -%WS_URL%/streaming -``` - ---- - -ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。 - -**ストリームでのやり取りはすべてJSONです。** - -## チャンネル -MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。 - -ひとつのストリーム上で、同時に複数のチャンネルに接続することができます。 - -### チャンネルに接続する -チャンネルに接続するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -ここで、 -* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。 -* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。 -* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。 - -
ℹ️ IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。
- -### チャンネルからのメッセージを受け取る -例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。 - -チャンネルがメッセージを発すると、次のようなデータがJSONでストリームに流れてきます: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。 -* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。 -* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。 - -### チャンネルに向けてメッセージを送信する -チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。 - -チャンネルにメッセージを送信するには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。 -* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。 -* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。 - -### チャンネルから切断する -チャンネルから切断するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。 - -## ストリームを経由してAPIリクエストする - -ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。 - -ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -ここで、 -* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 -* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 -* `data`には、エンドポイントのパラメータを含めます。 - -
ℹ️ APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。
- -### レスポンスの受信 - -APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。 - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -ここで、 -* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 -* `body`には、レスポンスが含まれています。 - -## 投稿のキャプチャ - -Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。 - -例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。 - -しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。 - -この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。 - -### 投稿をキャプチャする - -投稿をキャプチャするには、ストリームに次のようなメッセージを送信します: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャしたい投稿の`id`を設定します。 - -このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 - -例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -ここで、 -* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。 -* `body`内の`type`に、イベントの種類が設定されます。 -* `body`内の`body`に、イベントの詳細が設定されます。 - -#### イベントの種類 - -##### `reacted` -その投稿にリアクションがされた時に発生します。 - -* `reaction`に、リアクションの種類が設定されます。 -* `userId`に、リアクションを行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -その投稿が削除された時に発生します。 - -* `deletedAt`に、削除日時が設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -その投稿に添付されたアンケートに投票された時に発生します。 - -* `choice`に、選択肢IDが設定されます。 -* `userId`に、投票を行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### 投稿のキャプチャを解除する - -その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。 - -次のメッセージを送信します: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャを解除したい投稿の`id`を設定します。 - -このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 - -# チャンネル一覧 -## `main` -アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `renote` -自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。 - -#### `mention` -誰かからメンションされたときに発生するイベントです。 - -#### `readAllNotifications` -自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。 - -#### `meUpdated` -自分の情報が更新されたことを表すイベントです。 - -#### `follow` -自分が誰かをフォローしたときに発生するイベントです。 - -#### `unfollow` -自分が誰かのフォローを解除したときに発生するイベントです。 - -#### `followed` -自分が誰かにフォローされたときに発生するイベントです。 - -## `homeTimeline` -ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -タイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `localTimeline` -ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `hybridTimeline` -ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ソーシャルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `globalTimeline` -グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 diff --git a/src/docs/kn-IN/aiscript.md b/src/docs/kn-IN/aiscript.md deleted file mode 100644 index 6c28b446e..000000000 --- a/src/docs/kn-IN/aiscript.md +++ /dev/null @@ -1,4 +0,0 @@ -# AiScript - -## 関数 -デフォルトで値渡しです。 diff --git a/src/docs/kn-IN/api.md b/src/docs/kn-IN/api.md deleted file mode 100644 index 76019b614..000000000 --- a/src/docs/kn-IN/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス、Bot等(以下「アプリケーション」と呼びます)を開発できます。 ストリーミングAPIもあるので、リアルタイム性のあるアプリケーションを作ることも可能です。 - -APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。 - -## アクセストークンの取得 -基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。 - -* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む -* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む - -### 自分自身のアクセストークンを手動発行する -「設定 > API」で、自分のアクセストークンを発行できます。 - -[「APIの使い方」へ進む](#APIの使い方) - -### アプリケーション利用者にアクセストークンの発行をリクエストする -アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。 - -#### Step 1 - -UUIDを生成する。以後これをセッションIDと呼びます。 - -> このセッションIDは毎回生成し、使いまわさないようにしてください。 - -#### Step 2 - -`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。 -> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます: -* `name` ... アプリケーション名 - * > 例: `MissDeck` -* `icon` ... アプリケーションのアイコン画像URL - * > 例: `https://missdeck.example.com/icon.png` -* `callback` ... 認証が終わった後にリダイレクトするURL - * > 例: `https://missdeck.example.com/callback` - * リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます -* `permission` ... アプリケーションが要求する権限 - * > 例: `write:notes,write:following,read:drive` - * 要求する権限を`,`で区切って列挙します - * どのような権限があるかは[APIリファレンス](/api-doc)で確認できます - -#### Step 3 -ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。 - -レスポンスに含まれるプロパティ: -* `token` ... ユーザーのアクセストークン -* `user` ... ユーザーの情報 - -[「APIの使い方」へ進む](#APIの使い方) - -## APIの使い方 -**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。 - -* [APIリファレンス](/api-doc) -* [ストリーミングAPI](./stream) diff --git a/src/docs/kn-IN/create-plugin.md b/src/docs/kn-IN/create-plugin.md deleted file mode 100644 index 0d2fa1917..000000000 --- a/src/docs/kn-IN/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# プラグインの作成 -Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。 - -## メタデータ -プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。 - -### name -プラグイン名 - -### author -プラグイン作者 - -### version -プラグインバージョン。数値を指定してください。 - -### description -プラグインの説明 - -### permissions -プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。 - -### config -プラグインの設定情報を表すオブジェクト。 キーに設定名、値に以下のプロパティを含めます。 - -#### type -設定値の種類を表す文字列。以下から選択します。 string number boolean - -#### label -ユーザーに表示する設定名 - -#### description -設定の説明 - -#### default -設定のデフォルト値 - -## APIリファレンス -AiScript標準で組み込まれているAPIは掲載しません。 - -### Mk:dialog(title text type) -ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。 - -### Mk:confirm(title text type) -確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。 - -### Mk:api(endpoint params) -Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。 - -### Mk:save(key value) -任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。 - -### Mk:load(key) -Mk:saveで永続化した指定の名前の値を読み取ります。 - -### Plugin:register_post_form_action(title fn) -投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。 - -### Plugin:register_note_action(title fn) -ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 - -### Plugin:register_user_action(title fn) -ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。 - -### Plugin:register_note_view_interruptor(fn) -UIに表示されるノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:register_note_post_interruptor(fn) -ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:open_url(url) -第一引数に渡されたURLをブラウザの新しいタブで開きます。 - -### Plugin:config -プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。 diff --git a/src/docs/kn-IN/custom-emoji.md b/src/docs/kn-IN/custom-emoji.md deleted file mode 100644 index ed2e92be1..000000000 --- a/src/docs/kn-IN/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# カスタム絵文字 -カスタム絵文字は、インスタンスで用意された画像を絵文字のように使える機能です。 ノート、リアクション、チャット、自己紹介、名前などの場所で使うことができます。 カスタム絵文字をそれらの場所で使うには、絵文字ピッカーボタン(ある場合)を押すか、`:`を入力して絵文字サジェストを表示します。 テキスト内に`:foo:`のような形式の文字列が見つかると、`foo`の部分がカスタム絵文字名と解釈され、表示時には対応したカスタム絵文字に置き換わります。 diff --git a/src/docs/kn-IN/deck.md b/src/docs/kn-IN/deck.md deleted file mode 100644 index 8057e262f..000000000 --- a/src/docs/kn-IN/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# デッキ - -デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。 - -## カラムの追加 -デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。 - -## カラムの移動 -カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。 - -## カラムの水平分割 -カラムは左右だけでなく、上下に並べることもできます。 カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 上下分割を解除するには、カラムメニューの「右に出す」を選択します。 - -## カラムの設定 -カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。 - -## デッキの設定 -デッキに関する設定は、[settings/deck](/settings/deck)で行えます。 diff --git a/src/docs/kn-IN/features/antenna.md b/src/docs/kn-IN/features/antenna.md deleted file mode 100644 index 94ad9e4ae..000000000 --- a/src/docs/kn-IN/features/antenna.md +++ /dev/null @@ -1,4 +0,0 @@ -# アンテナ -アンテナは、自由に条件を設定して、合致するノートを自動で収集することができる機能です。 - -条件を設定したアンテナが作成された状態で、条件に合致するノートが投稿されると、リアルタイムでそのアンテナのタイムラインにノートが追加されます。 diff --git a/src/docs/kn-IN/features/custom-emoji.md b/src/docs/kn-IN/features/custom-emoji.md deleted file mode 100644 index ed2e92be1..000000000 --- a/src/docs/kn-IN/features/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# カスタム絵文字 -カスタム絵文字は、インスタンスで用意された画像を絵文字のように使える機能です。 ノート、リアクション、チャット、自己紹介、名前などの場所で使うことができます。 カスタム絵文字をそれらの場所で使うには、絵文字ピッカーボタン(ある場合)を押すか、`:`を入力して絵文字サジェストを表示します。 テキスト内に`:foo:`のような形式の文字列が見つかると、`foo`の部分がカスタム絵文字名と解釈され、表示時には対応したカスタム絵文字に置き換わります。 diff --git a/src/docs/kn-IN/features/deck.md b/src/docs/kn-IN/features/deck.md deleted file mode 100644 index 8057e262f..000000000 --- a/src/docs/kn-IN/features/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# デッキ - -デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。 - -## カラムの追加 -デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。 - -## カラムの移動 -カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。 - -## カラムの水平分割 -カラムは左右だけでなく、上下に並べることもできます。 カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 上下分割を解除するには、カラムメニューの「右に出す」を選択します。 - -## カラムの設定 -カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。 - -## デッキの設定 -デッキに関する設定は、[settings/deck](/settings/deck)で行えます。 diff --git a/src/docs/kn-IN/features/drive.md b/src/docs/kn-IN/features/drive.md deleted file mode 100644 index b82a41082..000000000 --- a/src/docs/kn-IN/features/drive.md +++ /dev/null @@ -1,17 +0,0 @@ -# ドライブ -ドライブは、Misskey上でファイルを管理できる機能です。 - -[ドライブのページ](/my/drive)から任意のファイルをアップロードできるほか、アバターに設定した画像や、ノートに添付したファイルなどもすべてドライブにアップロードされます。 - -
⚠️ ドライブからファイルを削除すると、そのファイルが添付されたノートも消えます。
- -ドライブにアップロードされたファイルは、いつでもダウンロードすることができるほか、ノート作成時に「ドライブからファイルを添付」することでファイルを再利用することもできます。 - -ドライブ内にフォルダを作り、複数のファイルをまとめて整理することもできます。 - -## 閲覧注意 (NSFW) -
ℹ️ この項目が閲覧注意なわけではありません
- -閲覧注意またはNSFW (Not safe for work) は、ドライブのファイルに設定することができるフラグです。 閲覧注意フラグを設定されたファイルは、表示される際に閲覧者の操作なしには表示されなくなります。 このフラグは、例えば職場や公共の場で閲覧するのに適切でないと思われる画像などに設定し、そのような画像が突然表示されてしまうことを防ぐ目的で使われます。 - -このフラグは手動でオンオフを切り替えられるほか、モデレーターの判断で設定される場合もあります。 diff --git a/src/docs/kn-IN/features/favorite.md b/src/docs/kn-IN/features/favorite.md deleted file mode 100644 index 8549bab4b..000000000 --- a/src/docs/kn-IN/features/favorite.md +++ /dev/null @@ -1,4 +0,0 @@ -# ಮೆಚ್ಚಿನ -[ノート](./node)をお気に入りとして登録できる機能です。 お気に入り登録したノートは、[お気に入りページ](./my/favorites)で一覧することができます。 お気に入りに登録したことは相手に通知されず、お気に入りは自分しか見ることができません。 - -ノートをお気に入り登録するには、ノートメニューの「お気に入り」を押します。お気に入り解除するには、ノートメニューの「お気に入り解除」を押します。 diff --git a/src/docs/kn-IN/features/follow.md b/src/docs/kn-IN/features/follow.md deleted file mode 100644 index 3c1ea7bbe..000000000 --- a/src/docs/kn-IN/features/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# フォロー -ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。 diff --git a/src/docs/kn-IN/features/keyboard-shortcut.md b/src/docs/kn-IN/features/keyboard-shortcut.md deleted file mode 100644 index 7430ad7fe..000000000 --- a/src/docs/kn-IN/features/keyboard-shortcut.md +++ /dev/null @@ -1,66 +0,0 @@ -# キーボードショートカット - -## グローバル -これらのショートカットは基本的にどこでも使えます。 - - - - - - - - - - - -
ショートカット効果由来
P, N新規投稿Post, New, Note
Tタイムラインの最も新しい投稿にフォーカスTimeline, Top
Shift + N通知を表示/隠すNotifications
SಹುಡುಕುSearch
H, ?ヘルプを表示Help
- -## 投稿にフォーカスされた状態 - - - - - - - - - - - - - - - - - - -
ショートカット効果由来
, K, Shift + Tab上の投稿にフォーカスを移動-
, J, Tab下の投稿にフォーカスを移動-
R返信フォームを開くReply
QRenoteフォームを開くQuote
Ctrl + Q即刻Renoteする(フォームを開かずに)-
E, A, +リアクションフォームを開くEmote, reAction
0~9数字に対応したリアクションをする(対応については後述)-
F, Bお気に入りに登録Favorite, Bookmark
Del, Ctrl + D投稿を削除Delete
M, O投稿に対するメニューを開くMore, Other
SCWで隠された部分を表示 or 隠すShow, See
Escフォーカスを外す-
- -## Renoteフォーム - - - - - - - - - -
ショートカット効果由来
EnterRenoteする-
Qフォームを展開するQuote
Escフォームを閉じる-
- -## リアクションフォーム -デフォルトで「👍」にフォーカスが当たっている状態です。 - - - - - - - - - - - - - -
ショートカット効果由来
, K上のリアクションにフォーカスを移動-
, J下のリアクションにフォーカスを移動-
, H, Shift + Tab左のリアクションにフォーカスを移動-
, L, Tab右のリアクションにフォーカスを移動-
Enter, Space, +リアクション確定-
0~9数字に対応したリアクションで確定-
Escリアクションするのをやめる-
diff --git a/src/docs/kn-IN/features/mfm.md b/src/docs/kn-IN/features/mfm.md deleted file mode 100644 index 5be2df4f3..000000000 --- a/src/docs/kn-IN/features/mfm.md +++ /dev/null @@ -1,12 +0,0 @@ -# MFM -MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます。 - -## MFMが使用可能な場所の例 -- ノート本文 -- CW注釈 -- ユーザーの名前 -- ユーザーの自己紹介 - -## 開発者向け情報 -MFMのパーサー実装はライブラリとして公開されており、簡単にクライアントにMFMを組み込むことが可能です。 -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptパーサー実装 diff --git a/src/docs/kn-IN/features/mute-and-block.md b/src/docs/kn-IN/features/mute-and-block.md deleted file mode 100644 index d78a7cea4..000000000 --- a/src/docs/kn-IN/features/mute-and-block.md +++ /dev/null @@ -1,41 +0,0 @@ -# ミュートとブロック -好みではないユーザーがいる場合は、ミュートを行うことでそのユーザーが自分から見えないようにすることができます。 また、より強力な措置として、ブロックを行うことでそのユーザーから自分のコンテンツが見えないようになるほか、自分に対して関わることができないようにすることができます。 ミュートされていることは相手は分かりませんが、ブロックされていることは相手に分かります。どちらを選ぶかはご自身の判断で行ってください。 - -
ℹ️ ミュートとブロックは併用できます。
- -
⚠️ 利用規約に違反するような、迷惑なユーザーがいる場合は運営者に報告することも検討してください。
- -設定>ミュートとブロック から、自分がミュートまたはブロックしているユーザー一覧を確認することができます。 - -## ミュート -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -- タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -- そのユーザーからの通知 -- メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 -- など - -ユーザーをミュートするには、対象のユーザーのユーザーページのメニューを開き、「ミュート」ボタンを押します。 - -
ℹ️ ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。
- -## ブロック -ユーザーをブロックすると、そのユーザーからあなたのコンテンツが見えないようになり、またあなたに対して以下のようなアクションをすることができなくなります。 - -- フォローする -- ユーザーリストに追加する -- 返信する、Renoteする -- リアクションする、アンケートに投票する -- メッセージを送信する -- など - -また、 - -- ブロックする際に既にそのユーザーからフォローされていた場合はフォローが解除されます。 -- ブロックする際に既にそのユーザーがあなたをユーザーリストに入れていた場合はそのリストからあなたが削除されます。 - -ユーザーをブロックするには、対象のユーザーのユーザーページのメニューを開き、「ブロック」ボタンを押します。 - -
⚠️ ブロックを行ったこと自体は相手に通知されませんが、フォローを行ったりなどの上記のアクションが行えなくなるので間接的にブロックされていることは分かります。
- -
⚠️ 相手から自分のコンテンツが見えなくなりますが、相手がアカウントを切り替えたりログアウト状態になれば見ることができます。あくまで簡易的、補助的なものとしてお考えください。
diff --git a/src/docs/kn-IN/features/mute.md b/src/docs/kn-IN/features/mute.md deleted file mode 100644 index 6a9608662..000000000 --- a/src/docs/kn-IN/features/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# ミュート - -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -* タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -* そのユーザーからの通知 -* メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 - -ユーザーをミュートするには、対象のユーザーのユーザーページに表示されている「ミュート」ボタンを押します。 - -ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。 - -設定>ミュート から、自分がミュートしているユーザー一覧を確認することができます。 diff --git a/src/docs/kn-IN/features/note.md b/src/docs/kn-IN/features/note.md deleted file mode 100644 index a6b813fda..000000000 --- a/src/docs/kn-IN/features/note.md +++ /dev/null @@ -1,54 +0,0 @@ -# ノート -ノートは、Misskeyに投稿される、文章、ファイル、アンケートなどを含むコンテンツで、Misskeyの中心的概念です。また、そのノートを作成する行為自体もノートと呼ばれます。 - -ノートが作成されると、[タイムライン](./timeline)に追加され、自分の[フォロワー](./follow)やサーバーのユーザーが見れるようになります。 - -ノートには、[リアクション](./reaction)を行うことができます。また、返信や引用もできます。 - -ノートを[お気に入り](./favorite)登録することで、後で簡単に見返すことができます。 - -## ノートを作成する -ノートを作成するには、画面上にある鉛筆マークのボタンを押して、作成フォームを開きます。作成フォームに内容を入力し、「ノート」ボタンを押すことでノートが作成されます。 ノートには、画像、動画など任意のファイルや、[アンケート](./poll)を添付することができます。また、本文中には[MFM](./mfm)が使用でき、[メンション](./mention)や[ハッシュタグ](./hashtag)を含めることもできます。 他にも、CWや公開範囲といった設定も行えます(詳細は後述)。 -
ℹ️ コンピューターのクリップボードに画像データがある状態で、フォーム内のテキストボックスにペーストするとその画像を添付することができます。
-
ℹ️ テキストボックス内でCtrl + Enterを押すことでも投稿できます。
- -## Renote -既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノートをRenoteと呼びます。 自分がフォローしているユーザーの、気に入ったノートを自分のフォロワーに共有したい場合や、過去の自分のノートを再度共有したい場合に使います。 同じノートに対して無制限にRenoteを行うことができますが、あまり連続して使用すると迷惑になる場合もあるので、注意しましょう。 -
⚠️ 公開範囲がフォロワーやダイレクトのノートはRenoteできません
- -Renoteを削除するには、Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 - -## CW -Contents Warningの略で、ノートの内容を、閲覧者の操作なしには表示しないようにできる機能です。主に長大な内容を隠すためや、ネタバレ防止などに使うことができます。 設定するには、フォームの「内容を隠す」ボタン(目のアイコン)を押します。すると新しい入力エリアが表れるので、そこに内容の要約を記入します。 - -## 公開範囲 -ノートごとに、そのノートが公開される範囲を設定することができます。フォームの「ノート」ボタンの左にあるアイコンを押すと公開範囲を以下から選択できます。 - -### パブリック -全ての人に対してノートが公開されるほか、サーバーの全てのタイムライン(ホームタイムライン、ローカルタイムライン、ソーシャルタイムライン、グローバルタイムライン)にノートが流れます。 -
⚠️ アカウントがサイレンス状態の時は、この公開範囲は使用できません。
- -### ホーム -全ての人に対してノートが公開されますが、フォロワー以外のローカルタイムライン、ソーシャルタイムライン、グローバルタイムラインにはノートは流れません。 - -### フォロワー -自分のフォロワーに対してのみノートを公開します。フォロワーの全てのタイムラインに流れます。 - -### ダイレクト -指定したユーザーに対してのみノートを公開します。指定したユーザーの全てのタイムラインに流れます。 - -### 「ローカルのみ」オプション -このオプションを有効にすると、リモートにノートを連合しなくなります。 - -### 公開範囲の比較 - - - - -
パブリックホームフォロワーダイレクト
フォロワーのLTL/STL/GTL
非フォロワーのLTL/STL/GTL
- -## ಪ್ರೊಫ಼ೈಲಿಗೆ ಅಂಟಿಸು -ノートをピン留めすると、ユーザーページに常にそのノートを表示しておくことができます。 ノートのメニューを開き、「ピン留め」を選択してピン留めできます。 複数のノートをピン留めできます。 - -## ウォッチ -ノートをウォッチすると、自分以外のノートへのリアクションや返信などの通知を受け取ることができます。 ノートのメニューを開き、「ウォッチ」を選択してウォッチできます。 diff --git a/src/docs/kn-IN/features/pages.md b/src/docs/kn-IN/features/pages.md deleted file mode 100644 index a7311b95e..000000000 --- a/src/docs/kn-IN/features/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# Pages - -## 変数 -変数を使うことで動的なページを作成できます。テキスト内で { 変数名 } と書くとそこに変数の値を埋め込めます。例えば Hello { thing } world! というテキストで、変数(thing)の値が ai だった場合、テキストは Hello ai world! になります。 - -変数の評価(値を算出すること)は上から下に行われるので、ある変数の中で自分より下の変数を参照することはできません。例えば上から A、B、C と3つの変数を定義したとき、Cの中でABを参照することはできますが、Aの中でBCを参照することはできません。 - -ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。 - -関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。 diff --git a/src/docs/kn-IN/features/reaction.md b/src/docs/kn-IN/features/reaction.md deleted file mode 100644 index 4d479fd41..000000000 --- a/src/docs/kn-IN/features/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# リアクション -他の人のノートに、絵文字を付けて簡単にあなたの反応を伝えられる機能です。 リアクションするには、ノートの + アイコンをクリックしてピッカーを表示し、絵文字を選択します。 リアクションには[カスタム絵文字](./custom-emoji)も使用できます。 - -## リアクションピッカーのカスタマイズ -ピッカーに表示される絵文字を自分好みにカスタマイズすることができます。 設定の「リアクション」で設定します。 - -## リモート投稿へのリアクションについて -リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。 - -## リモートからのリアクションについて -リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。 diff --git a/src/docs/kn-IN/features/silence.md b/src/docs/kn-IN/features/silence.md deleted file mode 100644 index 7e26feab0..000000000 --- a/src/docs/kn-IN/features/silence.md +++ /dev/null @@ -1,6 +0,0 @@ -# サイレンス -サイレンスは、アカウントに設定される状態のひとつです。 - -アカウントがサイレンス状態になると、ノートの公開範囲をパブリックにできなくなります。 ホーム、フォロワー、ダイレクトは選択可能なため、サイレンスを受けた場合でもフォロワーやあなたのユーザーページを直接訪れた場合は投稿を閲覧できますが、GTL(連合タイムライン)やLTL(ローカルタイムライン)には投稿が流れません。 - -アカウントのサイレンス状態は、サーバーのモデレーターによって有効化/無効化されます。 diff --git a/src/docs/kn-IN/features/theme.md b/src/docs/kn-IN/features/theme.md deleted file mode 100644 index a406f3433..000000000 --- a/src/docs/kn-IN/features/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# テーマ - -テーマを設定して、Misskeyクライアントの見た目を変更できます。 - -## テーマの設定 -設定 > テーマ - -## テーマを作成する -テーマコードはJSON5で記述されたテーマオブジェクトです。 テーマは以下のようなオブジェクトです。 -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... テーマの一意なID。UUIDをおすすめします。 -* `name` ... テーマ名 -* `author` ... テーマの作者 -* `desc` ... テーマの説明(オプション) -* `base` ... 明るいテーマか、暗いテーマか - * `light`にすると明るいテーマになり、`dark`にすると暗いテーマになります。 - * テーマはここで設定されたベーステーマを継承します。 -* `props` ... テーマのスタイル定義。これから説明します。 - -### テーマのスタイル定義 -`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 - -#### バリューで使える構文 -* 16進数で表された色 - * 例: `#00ff00` -* `rgb(r, g, b)`形式で表された色 - * 例: `rgb(0, 255, 0)` -* `rgb(r, g, b, a)`形式で表された透明度を含む色 - * 例: `rgba(0, 255, 0, 0.5)` -* 他のキーの値の参照 - * `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。 - * 例: `@panel` -* 定数(後述)の参照 - * `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。 - * 例: `$main` -* 関数(後述) - * `:{関数名}<{引数}<{色}` - -#### 定数 -「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 キー名を`$`で始めると、そのキーはCSS変数として出力されません。 - -#### 関数 -wip diff --git a/src/docs/kn-IN/features/timeline.md b/src/docs/kn-IN/features/timeline.md deleted file mode 100644 index 03e388d55..000000000 --- a/src/docs/kn-IN/features/timeline.md +++ /dev/null @@ -1,31 +0,0 @@ -# ಸಮಯಸಾಲು -タイムラインは、[ノート](./note)が時系列で表示される機能です。 タイムラインには以下で示す種類があり、種類によって表示されるノートも異なります。 なお、タイムラインの種類によってはサーバーにより無効になっている場合があります。 - -## ホーム -自分のフォローしているユーザーの投稿が流れます。HTLと略されます。 - -## ローカル -全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。LTLと略されます。 - -## ソーシャル -自分のフォローしているユーザーの投稿と、全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。STLと略されます。 - -## グローバル -全てのローカルユーザーの「ホーム」指定されていない投稿と、サーバーに届いた全てのリモートユーザーの「ホーム」指定されていない投稿が流れます。GTLと略されます。 - -## 比較 -| ソース | | | ಸಮಯಸಾಲು | | | -| ------------ | ----- | --- | ------- | ----- | ----- | -| ಬಳಕೆದಾರ | 公開範囲 | ホーム | ローカル | ソーシャル | グローバル | -| ローカル (フォロー) | 公開 | ✔ | ✔ | ✔ | ✔ | -| | ホーム | ✔ | | ✔ | | -| | フォロワー | ✔ | ✔ | ✔ | ✔ | -| リモート (フォロー) | 公開 | ✔ | | ✔ | ✔ | -| | ホーム | ✔ | | ✔ | | -| | フォロワー | ✔ | | ✔ | ✔ | -| ローカル (未フォロー) | 公開 | | ✔ | ✔ | ✔ | -| | ホーム | | | | | -| | フォロワー | | | | | -| リモート (未フォロー) | 公開 | | | | ✔ | -| | ホーム | | | | | -| | フォロワー | | | | | diff --git a/src/docs/kn-IN/features/widgets.md b/src/docs/kn-IN/features/widgets.md deleted file mode 100644 index a7c2c1d1d..000000000 --- a/src/docs/kn-IN/features/widgets.md +++ /dev/null @@ -1,7 +0,0 @@ -# ウィジェット -ウィジェットは、MisskeyのUI上に設置できる小型の情報表示、操作が行えるパーツです。 - -ウィジェットを編集するには、ウィジェット編集モードに切り替えます。切り替え方法はUIによって異なります。 ウィジェット編集モードでは、ウィジェットの追加、削除、並び替え、およびそれぞれのウィジェットの設定を行えます。 - -## 利用可能なウィジェット一覧 -todo diff --git a/src/docs/kn-IN/features/word-mute.md b/src/docs/kn-IN/features/word-mute.md deleted file mode 100644 index fa4d14346..000000000 --- a/src/docs/kn-IN/features/word-mute.md +++ /dev/null @@ -1,20 +0,0 @@ -# ワードミュート -ワードミュートの設定をすると、条件に合致したノートが表示されなくなります。 - -ワードミュートには、ソフトワードミュートとハードワードミュートの2種類があります。それぞれについて設定の方法と挙動を説明します。 - -## ソフトワードミュート -ソフトワードミュートは、クライアント(アプリ)側でミュートを判断するワードミュートです。 - -ノートが設定した条件に合致すると、「(ユーザー名)が何かを言いました」という表示で隠れます。 -クリックすると元の通りに表示されます。 - -## ハードワードミュート -ハードワードミュートは、アンテナのようにサーバーが新しいノートの本文に対して条件に合致するかどうか判断し、タイムラインから対象となったノートを除外します。 - -つまり、ハードワードミュートには、以下のような特徴があります。 - -* 条件設定後、新しい投稿のみがミュートの対象になります。 -* 条件を変更しても、過去にハードミュートされたノートはミュートされたままになります。 -* 「○○が何かを言いました」でタイムラインが埋まることがありません。 -* ソフトミュートに非対応のアプリでも、ハードミュートは適用されます。 diff --git a/src/docs/kn-IN/follow.md b/src/docs/kn-IN/follow.md deleted file mode 100644 index 3c1ea7bbe..000000000 --- a/src/docs/kn-IN/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# フォロー -ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。 diff --git a/src/docs/kn-IN/general/apps.md b/src/docs/kn-IN/general/apps.md deleted file mode 100644 index 1f4c85fe8..000000000 --- a/src/docs/kn-IN/general/apps.md +++ /dev/null @@ -1,6 +0,0 @@ -# サードパーティアプリのリスト -## クライアント -todo - -## 連携サービス -todo diff --git a/src/docs/kn-IN/general/changelog.md b/src/docs/kn-IN/general/changelog.md deleted file mode 100644 index 6766a63b2..000000000 --- a/src/docs/kn-IN/general/changelog.md +++ /dev/null @@ -1,5 +0,0 @@ -# 更新履歴 -
ℹ️ このサーバーの更新履歴です。Misskeyの最新のリリースについては、GitHubをご確認ください。
- - - diff --git a/src/docs/kn-IN/general/faq.md b/src/docs/kn-IN/general/faq.md deleted file mode 100644 index c272b2ad4..000000000 --- a/src/docs/kn-IN/general/faq.md +++ /dev/null @@ -1,28 +0,0 @@ -# よくある質問 -ここでは利用上のよくある質問について掲載しています。 Misskeyのプロジェクト自体についてのよくある質問は[こちら](./misskey)に掲載されています。 - -## iOS/Androidのアプリはありますか? -公式にはそういったOSのネイティブアプリを開発していませんが、サードパーティ製のアプリがいくつかあります。 詳しくは[こちら](./apps)をご覧ください。 - -ただ、サードパーティ製アプリはどうしても機能への対応が遅れてしまうため、とくに拘りがなければ公式のWebクライアントの利用をおすすめします。 なお、MisskeyのWebクライアントはPWAに対応しているので、ネイティブアプリのように動作させることも可能です。 詳しくは[こちら](todo)をご覧ください。 - -## Mastodonクライアントでログインできないのですが? -MisskeyはMastodonのAPIと互換性がないため、一部を除きMastodonクライアントでMisskeyを利用することはできません。 - -## 他のサーバーのユーザーをフォローするときは? -メニューから検索を選び、ユーザー名をホスト込みで入力します。例: `@syuilo@misskey.io` - -## Renoteを削除するには? -Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 Renoteについては[こちら](../features/note)をご確認ください。 - -## URLのプレビューを表示させたくない -MFMには、そのURLのプレビューを無効にする構文があります。詳細は[MFMチートシート](/mfm-cheat-sheet)をご確認ください。 - -## カスタム絵文字を追加したい -運営者のみがカスタム絵文字を追加、編集、削除できます。それらを希望する場合は運営者に依頼してください。 - -## Botを開発したい -Misskey APIを利用してBotの開発が可能です。[こちら](../advanced/develop-bot)をご確認ください。 - -## ノートの翻訳機能はどのサービスを使用していますか? -[DeepL](https://www.deepl.com/)を使用しています。 diff --git a/src/docs/kn-IN/general/glossary.md b/src/docs/kn-IN/general/glossary.md deleted file mode 100644 index a560d2224..000000000 --- a/src/docs/kn-IN/general/glossary.md +++ /dev/null @@ -1,89 +0,0 @@ -# 用語集 -Misskeyに関する用語集です。 - -## ActivityPub -(読み: あくてぃびてぃぱぶ) 分散型を実現するために用いられるプロトコル(仕様)。このプロトコルに則ってサーバー同士通信を行うことで、連合が行われ、Fediverseを形成しています。 - -## AiScript -(読み: あいすくりぷと) Misskey上で使用できるプログラミング言語です。詳細は[こちら。](../advanced/aiscript) - -## API -(読み: えーぴーあい) Misskeyのサーバーが公開している、プログラムからMisskeyを扱うためのインターフェース。詳細は[こちら。](../advanced/api) - -## Bot -(読み: ぼっと) プログラムによって動作しているアカウント。 - -## CW -(読み: こんてんつわーにんぐ) Contents Warningの略。ノートの内容を、操作なしには表示しないようにできる機能。主に長大な内容を隠すためや、ネタバレ防止などに使われます。 - -## Fediverse -(読み: ふぇでぃばーす) Misskeyを含む様々な分散型ソフトウェアのサーバーで構成されたネットワーク。 - -## GTL -グローバルタイムライン(Global TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## HTL -ホームタイムライン(Home TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## LTL -ローカルタイムライン(Local TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## MFM -(読み: えむえふえむ) Misskey Flavored Markdownの略で、Misskey上で使用できるマークアップ言語です。詳細は[こちら。](../features/mfm) - -## NSFW -(読み: のっとせーふふぉーわーく) Not Safe For Workの略。画像を「閲覧注意」扱いにし、操作なしには表示しないようにすることができる機能。 - -## Renote -(読み: りのーと) 既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノート。詳細は[こちら。](../features/note) - -## STL -ソーシャルタイムライン(Social TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## 藍 -(読み: あい) Misskeyの看板娘(公式キャラクター)です。 - -## アクティブユーザー -インスタンスにアカウントを作っているユーザーのうち、現在も実際にサービスを利用しているユーザーのこと。 - -## ನಿದರ್ಶನ -todo - -## カスタム絵文字 -サーバーで用意された絵文字。カスタム絵文字ではない通常の絵文字は「Unicode絵文字」と区別して呼ばれる。 - -## コントロールパネル -インスタンスの設定画面のこと。 - -## サーバー -todo - -## サイレンス -ノートをパブリックな公開範囲で投稿できなくされている状態。モデレーターの判断でユーザーごとに設定されます。詳細は[こちら。](../features/silence) - -## ジョブキュー -アクティビティ配送などを順番に行うためのシステム。 - -## 凍結 -アカウントが使用不可に設定されている状態。 - -## ドライブ -Misskeyにアップロードしたファイルを管理する機能。詳細は[こちら。](../features/drive) - -## ノート -Misskeyに投稿される、文章、ファイル、アンケートなどを含めることができるコンテンツ。詳細は[こちら。](../features/note) - -## ミスキスト -Misskeyを使う人のこと。 - -## モデレーター -スパムの凍結およびサイレンスや不適切な投稿の削除など、コミュニティ運営に関する権限を持つユーザー。 - -## リモート -他サーバーのことを指します。リモートユーザーといったように接頭辞としても使われます。ローカルの逆です。 - -## 連合 -サーバー上で作成された情報が他のサーバーに伝わること。 - -## ローカル -自サーバーのことを指します。ローカルユーザー、ローカルタイムラインといったように接頭辞としても使われます。リモートの逆です。 diff --git a/src/docs/kn-IN/general/links.md b/src/docs/kn-IN/general/links.md deleted file mode 100644 index 5ce5e1ddb..000000000 --- a/src/docs/kn-IN/general/links.md +++ /dev/null @@ -1,12 +0,0 @@ -# リンク集 - -## Webサイト -- [Official Discord](https://discord.gg/Wp8gVStHW3) - Misskey公式Discordサーバー -- [Misskey Forum](https://forum.misskey.io/) - Misskeyに関する話題を扱うフォーラム - -## アカウント -- [@repo@misskey.io](https://misskey.io/@repo) - Misskeyのリポジトリの更新を投稿するbot - -## ライブラリ -- [misskey-dev/misskey.js](https://github.com/misskey-dev/misskey.js) - JavaScriptのMisskey SDK -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptのMFMパーサー実装 diff --git a/src/docs/kn-IN/general/misskey.md b/src/docs/kn-IN/general/misskey.md deleted file mode 100644 index d97664ddc..000000000 --- a/src/docs/kn-IN/general/misskey.md +++ /dev/null @@ -1,87 +0,0 @@ -# Misskeyについて - -Misskeyはオープンソースの分散型マイクロブログプラットフォームプロジェクトです。 開発は日本でsyuiloによって2014年から開始されました。 ドライブ、リアクションなどの豊富な機能や、高いカスタマイズ性を備えたUIを持つことが特徴です。 - -## 歴史 -開発当初は掲示板がメインのサービスでしたが、ユーザーが短文を投稿し、それを時系列で流れるタイムライン機能を追加したところ人気が高まり、徐々にそれがメインとして開発が進むようになりました。 当初は分散型ではありませんでしたが、2018年にActivityPubを実装し分散型になったことで、より多くの方に認知され利用されるサービスになり、現在に至ります。 -
ℹ️ Misskeyという名前は、syuiloが当時聴いていたMay'nというアーティストの楽曲、Brain Diverの歌詞に由来します。
- -誰でも開発に参加することができ、現在でも活発に開発が続いています。 - -## 分散型とは何か? - -分散(distributed)型とは、非中央集権(decentralized)とも呼ばれ、コミュニティが多数のサーバーに分散して存在し、それらが相互に通信(連合、federation)することでコンテンツ共有ネットワーク(Fediverse)を形成していることが特徴のサービスです。 単一のサーバーしか存在しない、もしくは複数存在しても互いに独立している場合は中央集権なサービスと言われ、例えばTwitterやFacebookなどほとんどのサービスがそれに該当します。 分散型のメリットは、自分に合った運営者やテーマのサーバーを選択できることです。自分でサーバーを作成することもできます。連合するおかげで、どのサーバーを選んでも、同じコミュニティにアクセスできます。 - -## 常にオープンソース -Misskeyはこれまでもこれからも、オープンソースであり続けます。オープンソースとは、簡単に言うとソフトウェアのソースコード(プログラム)が公開されていることです。ソースコードの修正や再配布が可能であることを定義に含めることもあります。 Misskeyのすべてのソースコードは[AGPL](https://github.com/misskey-dev/misskey/blob/develop/LICENSE)というオープンソースライセンスの下に[公開](https://github.com/misskey-dev)されていて、誰でも自由に閲覧、使用、修正、改変、再配布をすることができます。 オープンソースは、自分で好きなように変えたり、有害な処理が含まれていないことを確認することができたり、誰でも開発に参加できるなどの、様々なメリットがあります。 上述の分散型を実現するためにも、オープンソースであるということは必要不可欠な要素です。 再び引き合いに出しますが、TwitterやFacebookなどの利益を得ているほとんどのサービスはオープンソースではありません。 - -
ℹ️ 技術的に言うと、MisskeyのソースコードはGitで管理されていて、リポジトリはGitHub上でホスティングされています。
- -## 開発に参加する、プロジェクトを支援する -Misskeyを気に入っていただけたら、ぜひプロジェクトを支援してください。プロジェクトに貢献するには、以下で紹介するようにいろいろな方法があります。方法によっては開発のスキルは不要なので、誰でも気軽に参加し貢献することができます。いつでもお待ちしています。 - -### 機能を追加したり、バグを修正する -ソフトウェアエンジニアのスキルをお持ちの方であれば、ソースコードを編集する形でプロジェクトに貢献することができます。 貢献についてのガイドは[こちら](https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md)です。 - -### 議論に参加する -新しい機能、または既存の機能について意見を述べたり、不具合を報告したりすることでも貢献できます。 そのようなディスカッションは[GitHub](https://github.com/misskey-dev)上か、[フォーラム](https://forum.misskey.io/)等で行われます。 - -### テキストを翻訳する -Misskeyは様々な言語に対応しています(i18n -internationalizationの略- と呼ばれます)。元の言語は基本的に日本語ですが、有志によって他の言語へと翻訳されています。 その翻訳作業に加わっていただくことでもMisskeyに貢献できます。 Misskeyは[Crowdinというサービスを使用して翻訳の管理を行っています。](https://crowdin.com/project/misskey) - -### 感想を投稿する -不具合報告等だけではなく、Misskeyの良い点、楽しい点といったポジティブな意見もぜひ共有してください。開発の励みになり、それは間接的ですがプロジェクトへの貢献です。 - -### ミスキストを増やす -ミスキストとは、Misskeyを使用する人のことです。 知り合いに紹介するなどしてMisskeyを広めていただければ、ミスキストが増え開発のモチベーションが上がります。 - -### 寄付をする -Misskeyはビジネスではなく、利用は無料であるため、収益は皆様からの寄付のみです。(インスタンスによっては広告収入を得ているような場合もありますが、それは運営者の収入であり直接開発者への収入にはなりません) 寄付をしていただければ、今後も開発を続けることが可能になり、プロジェクトへの貢献になります。 寄付は基本的には[Patreon](https://www.patreon.com/syuilo)で受け付けています。 一定額寄付していただけると、Misskeyの[情報ページ](/about-misskey)に名前を記載することができます。 - -また、サーバーの運営者も、基本的には収益を得ていません。サーバーの運営にはコストがかかるので、運営者の支援をすることもご検討ください。 開発には直接関係しませんが、サーバーがあってこそのプロジェクトなので、運営が維持されるというのは開発と同じくらい重要なことです。 - -## クレジット -Misskeyの開発者や、Misskeyに寄付をしてくださった方の一覧は[こちら](/about-misskey)で見ることができます。 - -## よくある質問 -### プロジェクトは何を目指していますか? -強いて言うと、漠然的になりますが広く使われる汎用的なプラットフォームになることを目指しています。 Misskeyは他のプロジェクトとは違い、何らかの思想(例えば、反中央集権)やビジョンに基づいて開発が行われているわけではなく、その点ではフラットです。 それが逆に、特定の方向性に縛られないフレキシブルさを生み出すことに繋がっていると感じています。 - - -### 企業によって開発されていますか? -いいえ。Misskeyの開発は個人で行われており、商業的でもないため、特定の企業の関りはありません。 開発メンバーも基本的にはボランティアです。 また、開発に対し企業のスポンサーがつくこともありますが、その場合でもやはり開発は個人のコミュニティが主体です。 - -### 誰が運営していますか? -Misskeyは分散型なため、各サーバーにそれぞれ異なった運営者がいます。従って、特定の個人や企業によって、Misskeyの全てが運営されているわけではありません。 また、開発チームが運営を行うわけでもないため、運営に関する連絡は、お使いのサーバーの運営者に行ってください。 サーバーの運営者は、[このページ](/about)で確認することができます。 あなたがサーバーを作成すれば、あなたが運営者になります。 - -### どのサーバーを選べばいいですか? -[サーバー一覧が公開されています。](https://join.misskey.page/ja-JP/instances) サーバーによってコミュニティのテーマ(特定のこと、ものが好き 等)が決められている場合があるので、自分に合ったテーマのサーバーがあれば、そこを選ぶと良いかもしれません。 他にも、サーバーの規模、ユーザー層、国および言語、運営者が信頼できるかどうか、などの観点があります。 なお、Misskey公式のサーバーというものはありません。自身で新しくサーバーを作成するという選択肢もあります。 - -基本的にどのサーバーを選んだとしても、他の全てのサーバーのユーザーと繋がることができます。 - -### サーバーを建てるにはどうしたらいいですか? -Misskeyサーバーの作成に興味を持っていただきありがとうございます。 2021年現在、Misskeyのホスティングサービスは存在しないため、サーバーの作成にはある程度の知識が必要です。 サーバーの作成方法については[こちら](todo)をご覧ください。 - -### どのような技術を使用していますか? -Misskeyは開発が進むにつれ使用する技術も大きく変わってきました。開発当初はMySQL + PHP + jQueryといった構成でしたが、現在は以下のようになっています。 -- サーバーサイド: Node.js -- データベース: PostgreSQL、Redis -- UIフレームワーク: Vue.js -- プログラミング言語: TypeScript - -また、MFMやAiScriptなどの、Misskeyから派生して独自の技術も開発しています。 - -### Mastodonのフォークですか? -いいえ。MisskeyはMastodonやその他のプロジェクトとは全く別のプロジェクトです。 開発に関しても、Misskeyの方が昔から開発されています。ただし、分散型になったのはMastodonの登場より後です。 同じActivityPubという分散のためのプロトコルを実装しているという点以外、両者に特に関りがあるわけでもありません。 - -### iOS/Androidのアプリはありますか? -公式にはそういったOSのネイティブアプリを開発していませんが、サードパーティ製のアプリがいくつかあります。 詳しくは[こちら](./apps)をご覧ください。 - -ただ、サードパーティ製アプリはどうしても機能への対応が遅れてしまうため、とくに拘りがなければ公式のWebクライアントの利用をおすすめします。 なお、MisskeyのWebクライアントはPWAに対応しているので、ネイティブアプリのように動作させることも可能です。 詳しくは[こちら](todo)をご覧ください。 - -### Misskeyのロゴ、アイコンはどこで入手できますか? -(準備中) - -### 時折目にする猫耳の可愛い女の子は? -Misskeyの守り神、藍ちゃんです。アイチャンカワイイヤッター! -
ℹ️ 藍ちゃんについてはこちらです。
diff --git a/src/docs/kn-IN/general/report-issue.md b/src/docs/kn-IN/general/report-issue.md deleted file mode 100644 index 63527e32a..000000000 --- a/src/docs/kn-IN/general/report-issue.md +++ /dev/null @@ -1,8 +0,0 @@ -# 不具合の報告 -不具合と思われる状況に遭遇したときは、まず[トラブルシューティング](./troubleshooting)をご一読ください。 それでも問題が解決しないときは、以下の情報を含めて[フォーラム](https://forum.misskey.io/)に投稿してください。 投稿することで、解決策が見つかったり、不具合と判断されれば開発チームによって修正が行われます。 - -## 含める情報 -- Misskeyのバージョン([情報ページ](/about)で確認できます) -- お使いのブラウザの種類とバージョン -- お使いのOSの種類とバージョン -- 問題の再現手順 diff --git a/src/docs/kn-IN/general/troubleshooting.md b/src/docs/kn-IN/general/troubleshooting.md deleted file mode 100644 index f895b4984..000000000 --- a/src/docs/kn-IN/general/troubleshooting.md +++ /dev/null @@ -1,40 +0,0 @@ -# トラブルシューティング -
ℹ️ よくある質問も合わせてお役立てください。
- -問題が発生したときは、まずこちらをご確認ください。 該当する項目が無い、もしくは手順を試しても効果がない場合は、サーバーの管理者に連絡するか[不具合を報告](./report-issue)してください。 - -## クライアントが起動しない -ほとんどの場合、お使いのブラウザまたはOSのバージョンが古いことが原因です。 ブラウザおよびOSのバージョンを最新のものに更新してから、再度試してみてください。 - -これは稀ですが、それでも起動しない場合は、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。 - -## ページが読み込めない -クライアントが起動するもののページが読み込めないというエラーが出る場合は、ネットワークに問題がないか確認してください。また、サーバーがダウンしていないか確認してください。 - -これは稀ですが、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。 - -まだ問題がある場合は、サーバーの問題と思われるのでサーバーの管理者に連絡してください。 - -## クライアントの動作が遅い -以下を試してみてください: - -- クライアント設定で「UIのアニメーションを減らす」を有効にする -- クライアント設定で「モーダルにぼかし効果を使用」を無効にする -- お使いのブラウザの設定でハードウェアアクセラレーションを有効にする -- お使いのデバイスのスペックを上げる - -## UIの一部の表示がおかしい(背景が透明になっている等) -アップデートによりUIの改修が行われたときに、テーマのキャッシュシステムの影響でそのような表示になることがあります。 クライアントの設定の「キャッシュをクリア」すると直ります。 -
⚠️ 「クライアントの」キャッシュクリアです。「ブラウザの」キャッシュクリアは行わないでください。
- -## 通知やアンテナ等の点滅が消えない -点滅は、未読のコンテンツがあることを示しています。通常点滅が消えない場合は、コンテンツを遡ると未読なコンテンツが残っています。 すべて既読にしたと思われるのに、それでもなお点滅が続く場合(おそらく不具合と思われます)は設定から強制的にすべて既読扱いにすることができます。 - -## Renoteができない -フォロワー限定のノートはRenoteすることはできません。 - -## UI上で特定の要素が表示されない -広告ブロッカーを使用しているとそのような不具合が発生することがあります。Misskeyではオフにしてご利用ください。 - -## UI上で未翻訳の部分がある -ほとんどの場合、単に翻訳が間に合っていないだけで、不具合ではありません。翻訳が終わるまでお待ちください。 [翻訳に参加](./misskey)していただくことも可能です。 diff --git a/src/docs/kn-IN/keyboard-shortcut.md b/src/docs/kn-IN/keyboard-shortcut.md deleted file mode 100644 index e8ba41571..000000000 --- a/src/docs/kn-IN/keyboard-shortcut.md +++ /dev/null @@ -1,68 +0,0 @@ -# キーボードショートカット - -## グローバル -これらのショートカットは基本的にどこでも使えます。 - - - - - - - - - - - -
ショートカット効果由来
P, N新規投稿Post, New, Note
Tタイムラインの最も新しい投稿にフォーカスTimeline, Top
Shift + N通知を表示/隠すNotifications
SಹುಡುಕುSearch
H, ?ヘルプを表示Help
- -## 投稿にフォーカスされた状態 - - - - - - - - - - - - - - - - - - - -
ショートカット効果由来
, K, Shift + Tab上の投稿にフォーカスを移動-
, J, Tab下の投稿にフォーカスを移動-
R返信フォームを開くReply
QRenoteフォームを開くQuote
Ctrl + Q即刻Renoteする(フォームを開かずに)-
E, A, +リアクションフォームを開くEmote, reAction
0~9数字に対応したリアクションをする(対応については後述)-
F, Bお気に入りに登録Favorite, Bookmark
Del, Ctrl + D投稿を削除Delete
M, O投稿に対するメニューを開くMore, Other
SCWで隠された部分を表示 or 隠すShow, See
Escフォーカスを外す-
- -## Renoteフォーム - - - - - - - - - - -
ショートカット効果由来
EnterRenoteする-
Qフォームを展開するQuote
Escフォームを閉じる-
- -## リアクションフォーム -デフォルトで「👍」にフォーカスが当たっている状態です。 - - - - - - - - - - - - - -
ショートカット効果由来
, K上のリアクションにフォーカスを移動-
, J下のリアクションにフォーカスを移動-
, H, Shift + Tab左のリアクションにフォーカスを移動-
, L, Tab右のリアクションにフォーカスを移動-
Enter, Space, +リアクション確定-
0~9数字に対応したリアクションで確定-
Escリアクションするのをやめる-
diff --git a/src/docs/kn-IN/mfm.md b/src/docs/kn-IN/mfm.md deleted file mode 100644 index e237287ac..000000000 --- a/src/docs/kn-IN/mfm.md +++ /dev/null @@ -1,2 +0,0 @@ -# MFM -MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます。 diff --git a/src/docs/kn-IN/mute.md b/src/docs/kn-IN/mute.md deleted file mode 100644 index 6a9608662..000000000 --- a/src/docs/kn-IN/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# ミュート - -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -* タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -* そのユーザーからの通知 -* メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 - -ユーザーをミュートするには、対象のユーザーのユーザーページに表示されている「ミュート」ボタンを押します。 - -ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。 - -設定>ミュート から、自分がミュートしているユーザー一覧を確認することができます。 diff --git a/src/docs/kn-IN/pages.md b/src/docs/kn-IN/pages.md deleted file mode 100644 index a7311b95e..000000000 --- a/src/docs/kn-IN/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# Pages - -## 変数 -変数を使うことで動的なページを作成できます。テキスト内で { 変数名 } と書くとそこに変数の値を埋め込めます。例えば Hello { thing } world! というテキストで、変数(thing)の値が ai だった場合、テキストは Hello ai world! になります。 - -変数の評価(値を算出すること)は上から下に行われるので、ある変数の中で自分より下の変数を参照することはできません。例えば上から A、B、C と3つの変数を定義したとき、Cの中でABを参照することはできますが、Aの中でBCを参照することはできません。 - -ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。 - -関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。 diff --git a/src/docs/kn-IN/reaction.md b/src/docs/kn-IN/reaction.md deleted file mode 100644 index c26ead75b..000000000 --- a/src/docs/kn-IN/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# リアクション -他の人のノートに、絵文字を付けて簡単にあなたの反応を伝えられる機能です。 リアクションするには、ノートの + アイコンをクリックしてピッカーを表示し、絵文字を選択します。 リアクションには[カスタム絵文字](./custom-emoji)も使用できます。 - -## リアクションピッカーのカスタマイズ -ピッカーに表示される絵文字を自分好みにカスタマイズすることができます。 設定の「リアクション」で設定します。 - -## リモート投稿へのリアクションについて -リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。 また、相手がMisskeyであったとしても、カスタム絵文字リアクションは伝わらず、自動的に「👍」等にフォールバックされます。 - -## リモートからのリアクションについて -リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。 diff --git a/src/docs/kn-IN/reversi-bot.md b/src/docs/kn-IN/reversi-bot.md deleted file mode 100644 index 7ab2a7212..000000000 --- a/src/docs/kn-IN/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# MisskeyリバーシBotの開発 -Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。 - -1. `games/reversi`ストリームに以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - -2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる - * イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている - -3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する - -4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - * `game`: `game`の`id` - -5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う - -6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する - -7. ゲームが開始すると、`started`イベントが流れてくる - * イベントの中身にはゲーム情報が含まれている - -8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述) - -9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる - * `color`として石の色が含まれている - * `pos`として位置情報が含まれている - -## 位置の計算法 -8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### X,Y座標 から インデックス に変換する -``` -pos = x + (y * mapWidth) -``` -`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます: -``` -mapWidth = map[0].length -``` - -### インデックス から X,Y座標 に変換する -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## マップ情報 -マップ情報は、ゲーム情報の`map`に入っています。 文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 それをもとにマップのデザインを知る事が出来ます: -* `(スペース)` ... マス無し -* `-` ... マス -* `b` ... 初期配置される黒石 -* `w` ... 初期配置される白石 - -例えば、4*4の次のような単純なマップがあるとします: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -この場合、マップデータはこのようになります: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## ユーザーにフォームを提示して対話可能Botを作成する -ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。 - -フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します: -```javascript -{ - type: 'init-form', - body: [フォームコントロールの配列] -} -``` - -フォームコントロールの配列については今から説明します。 フォームコントロールは、次のようなオブジェクトです: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... コントロールのID。 `type` ... コントロールの種類。後述します。 `label` ... コントロールと一緒に表記するテキスト。 `value` ... コントロールのデフォルト値。 - -### フォームの操作を受け取る -ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### フォームコントロールの種類 -#### スイッチ -type: `switch` スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。 - -##### プロパティ -`label` ... スイッチに表記するテキスト。 - -#### ラジオボタン -type: `radio` ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。 - -##### プロパティ -`items` ... ラジオボタンの選択肢。例: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '強', - value: 3 -}] -``` - -#### スライダー -type: `slider` スライダーを表示します。 - -##### プロパティ -`min` ... スライダーの下限。 `max` ... スライダーの上限。 `step` ... 入力欄で刻むステップ値。 - -#### テキストボックス -type: `textbox` テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。 - -## ユーザーにメッセージを表示する -設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 メッセージを表示するには、次のメッセージをストリームに送信します: -```javascript -{ - type: 'message', - body: { - text: 'メッセージ内容', - type: 'メッセージの種類' - } -} -``` -メッセージの種類: `success`, `info`, `warning`, `error`。 - -## 投了する -投了をするには、このエンドポイントにリクエストします。 diff --git a/src/docs/kn-IN/stream.md b/src/docs/kn-IN/stream.md deleted file mode 100644 index 9011c37c5..000000000 --- a/src/docs/kn-IN/stream.md +++ /dev/null @@ -1,354 +0,0 @@ -# ストリーミングAPI - -ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。 - -## ストリームに接続する - -ストリーミングAPIを利用するには、まずMisskeyサーバーに**websocket**接続する必要があります。 - -以下のURLに、`i`というパラメータ名で認証情報を含めて、websocket接続してください。例: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。 - -
-

認証情報の取得については、こちらのドキュメントをご確認ください。

-
- ---- - -認証情報は省略することもできますが、その場合非ログインでの利用ということになり、受信できる情報や可能な操作は限られます。例: - -``` -%WS_URL%/streaming -``` - ---- - -ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。 - -**ストリームでのやり取りはすべてJSONです。** - -## チャンネル -MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。 - -### チャンネルに接続する -チャンネルに接続するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -ここで、 -* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。 -* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。 -* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。 - -
-

IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。

-
- -### チャンネルからのメッセージを受け取る -例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。 - -チャンネルがメッセージを発すると、次のようなデータがJSONでストリームに流れてきます: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。 -* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。 -* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。 - -### チャンネルに向けてメッセージを送信する -チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。 - -チャンネルにメッセージを送信するには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。 -* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。 -* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。 - -### チャンネルから切断する -チャンネルから切断するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。 - -## ストリームを経由してAPIリクエストする - -ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。 - -ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -ここで、 -* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 -* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 -* `data`には、エンドポイントのパラメータを含めます。 - -
-

APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。

-
- -### レスポンスの受信 - -APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。 - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -ここで、 -* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 -* `body`には、レスポンスが含まれています。 - -## 投稿のキャプチャ - -Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。 - -例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。 - -しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。 - -この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。 - -### 投稿をキャプチャする - -投稿をキャプチャするには、ストリームに次のようなメッセージを送信します: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャしたい投稿の`id`を設定します。 - -このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 - -例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -ここで、 -* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。 -* `body`内の`type`に、イベントの種類が設定されます。 -* `body`内の`body`に、イベントの詳細が設定されます。 - -#### イベントの種類 - -##### `reacted` -その投稿にリアクションがされた時に発生します。 - -* `reaction`に、リアクションの種類が設定されます。 -* `userId`に、リアクションを行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -その投稿が削除された時に発生します。 - -* `deletedAt`に、削除日時が設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -その投稿に添付されたアンケートに投票された時に発生します。 - -* `choice`に、選択肢IDが設定されます。 -* `userId`に、投票を行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### 投稿のキャプチャを解除する - -その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。 - -次のメッセージを送信します: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャを解除したい投稿の`id`を設定します。 - -このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 - -# チャンネル一覧 -## `main` -アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `renote` -自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。 - -#### `mention` -誰かからメンションされたときに発生するイベントです。 - -#### `readAllNotifications` -自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。 - -#### `meUpdated` -自分の情報が更新されたことを表すイベントです。 - -#### `follow` -自分が誰かをフォローしたときに発生するイベントです。 - -#### `unfollow` -自分が誰かのフォローを解除したときに発生するイベントです。 - -#### `followed` -自分が誰かにフォローされたときに発生するイベントです。 - -## `homeTimeline` -ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -タイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `localTimeline` -ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `hybridTimeline` -ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ソーシャルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `globalTimeline` -グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 diff --git a/src/docs/kn-IN/theme.md b/src/docs/kn-IN/theme.md deleted file mode 100644 index a406f3433..000000000 --- a/src/docs/kn-IN/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# テーマ - -テーマを設定して、Misskeyクライアントの見た目を変更できます。 - -## テーマの設定 -設定 > テーマ - -## テーマを作成する -テーマコードはJSON5で記述されたテーマオブジェクトです。 テーマは以下のようなオブジェクトです。 -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... テーマの一意なID。UUIDをおすすめします。 -* `name` ... テーマ名 -* `author` ... テーマの作者 -* `desc` ... テーマの説明(オプション) -* `base` ... 明るいテーマか、暗いテーマか - * `light`にすると明るいテーマになり、`dark`にすると暗いテーマになります。 - * テーマはここで設定されたベーステーマを継承します。 -* `props` ... テーマのスタイル定義。これから説明します。 - -### テーマのスタイル定義 -`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 - -#### バリューで使える構文 -* 16進数で表された色 - * 例: `#00ff00` -* `rgb(r, g, b)`形式で表された色 - * 例: `rgb(0, 255, 0)` -* `rgb(r, g, b, a)`形式で表された透明度を含む色 - * 例: `rgba(0, 255, 0, 0.5)` -* 他のキーの値の参照 - * `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。 - * 例: `@panel` -* 定数(後述)の参照 - * `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。 - * 例: `$main` -* 関数(後述) - * `:{関数名}<{引数}<{色}` - -#### 定数 -「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 キー名を`$`で始めると、そのキーはCSS変数として出力されません。 - -#### 関数 -wip diff --git a/src/docs/kn-IN/timelines.md b/src/docs/kn-IN/timelines.md deleted file mode 100644 index 36ba61bd2..000000000 --- a/src/docs/kn-IN/timelines.md +++ /dev/null @@ -1,15 +0,0 @@ -# タイムラインの比較 - -https://docs.google.com/spreadsheets/d/1lxQ2ugKrhz58Bg96HTDK_2F98BUritkMyIiBkOByjHA/edit?usp=sharing - -## ホーム -自分のフォローしているユーザーの投稿 - -## ローカル -全てのローカルユーザーの「ホーム」指定されていない投稿 - -## ソーシャル -自分のフォローしているユーザーの投稿と、全てのローカルユーザーの「ホーム」指定されていない投稿 - -## グローバル -全てのローカルユーザーの「ホーム」指定されていない投稿と、サーバーに届いた全てのリモートユーザーの「ホーム」指定されていない投稿 diff --git a/src/docs/ko-KR/admin/disable-timelines.md b/src/docs/ko-KR/admin/disable-timelines.md deleted file mode 100644 index 00c6ca4d6..000000000 --- a/src/docs/ko-KR/admin/disable-timelines.md +++ /dev/null @@ -1,8 +0,0 @@ -# 타임라인의 비활성화 -Misskey에서는 로컬, 소셜, 글로벌 타임라인을 각각 비활성화할 수 있습니다. 활성화 유무는 인스턴스 설정에서 제어판에서 설정할 수 있습니다. - -로컬 타임라인이나 소셜 타임라인에서는 인스턴스에 있는 모든 유저의 게시물을 볼 수 있으므로, 신규 유저가 다른 유저를 찾고, 관심사가 비슷한 유저를 찾기 쉽다는 장점이 있습니다. 그러나, 이런 특징 때문에 팔로우 기능의 활용이 저하되거나, 부적절한 게시물이 노출되기 쉬워지고, 타임라인 대화로 인해 인스턴스가 하나의 친목 커뮤니티화되는 경우 신규 유저의 진입 장벽으로 작용할 수 있는 등의 단점 또한 존재합니다. 각 타임라인의 특성이 인스턴스에 어떠한 영향을 주는 지는 인스턴스의 특성에 따라 다르므로, 설정을 통해 활성화 또는 비활성화할 수 있도록 설계되어 있습니다. 만약 장점에 비해 단점이 더 눈에 띄는 경우, 각각의 타임라인을 비활성화하는 것을 검토해 보시기 바랍니다. - -
⚠️ 타임라인을 비활성화할 경우, 유저들의 혼란을 불러 일으키며 단기적으로 이용자가 감소할 수 있습니다. 따라서, 비활성화를 결정하기 이전에 영향에 대해 신중히 검토하고, 사전에 유저에게 공지하고 일정 기간 유예기간을 두어 유저 간 팔로우 관계가 형성되도록 하는 것을 권장합니다.
- -또한, 관리자 및 모더레이터는 타임라인 비활성화 유무에 상관없이 각각의 타임라인을 이용할 수 있습니다. diff --git a/src/docs/ko-KR/admin/faq.md b/src/docs/ko-KR/admin/faq.md deleted file mode 100644 index 2b3d148d6..000000000 --- a/src/docs/ko-KR/admin/faq.md +++ /dev/null @@ -1,5 +0,0 @@ -# 자주 묻는 질문 -여기에서는 서버 운영에 관련해서 자주 묻는 질문에 대해 다룹니다. - -## 기본 테마를 설정하고 싶어요 -현재 기본 테마를 설정하는 기능은 구현되어 있지 않습니다. diff --git a/src/docs/ko-KR/advanced/aiscript.md b/src/docs/ko-KR/advanced/aiscript.md deleted file mode 100644 index c4f21b79c..000000000 --- a/src/docs/ko-KR/advanced/aiscript.md +++ /dev/null @@ -1,7 +0,0 @@ -# AiScript -AiScript는, Misskey에서 사용할 수 있는 스크립트 언어입니다. - -
ℹ️ AiScript 기능은 Misskey와 별도 리포지토리에서 오픈소스로 공개하고 있습니다.
- -## 사용법 -AiScript의 구문이나 내장 함수에 대한 문서는 [여기에서](https://github.com/syuilo/aiscript/tree/master/docs) 확인할 수 있습니다. diff --git a/src/docs/ko-KR/advanced/api.md b/src/docs/ko-KR/advanced/api.md deleted file mode 100644 index 76019b614..000000000 --- a/src/docs/ko-KR/advanced/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス、Bot等(以下「アプリケーション」と呼びます)を開発できます。 ストリーミングAPIもあるので、リアルタイム性のあるアプリケーションを作ることも可能です。 - -APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。 - -## アクセストークンの取得 -基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。 - -* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む -* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む - -### 自分自身のアクセストークンを手動発行する -「設定 > API」で、自分のアクセストークンを発行できます。 - -[「APIの使い方」へ進む](#APIの使い方) - -### アプリケーション利用者にアクセストークンの発行をリクエストする -アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。 - -#### Step 1 - -UUIDを生成する。以後これをセッションIDと呼びます。 - -> このセッションIDは毎回生成し、使いまわさないようにしてください。 - -#### Step 2 - -`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。 -> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます: -* `name` ... アプリケーション名 - * > 例: `MissDeck` -* `icon` ... アプリケーションのアイコン画像URL - * > 例: `https://missdeck.example.com/icon.png` -* `callback` ... 認証が終わった後にリダイレクトするURL - * > 例: `https://missdeck.example.com/callback` - * リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます -* `permission` ... アプリケーションが要求する権限 - * > 例: `write:notes,write:following,read:drive` - * 要求する権限を`,`で区切って列挙します - * どのような権限があるかは[APIリファレンス](/api-doc)で確認できます - -#### Step 3 -ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。 - -レスポンスに含まれるプロパティ: -* `token` ... ユーザーのアクセストークン -* `user` ... ユーザーの情報 - -[「APIの使い方」へ進む](#APIの使い方) - -## APIの使い方 -**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。 - -* [APIリファレンス](/api-doc) -* [ストリーミングAPI](./stream) diff --git a/src/docs/ko-KR/advanced/create-plugin.md b/src/docs/ko-KR/advanced/create-plugin.md deleted file mode 100644 index 1562060d7..000000000 --- a/src/docs/ko-KR/advanced/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# プラグインの作成 -Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。 - -## 메타데이터 -プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。 - -### name -プラグイン名 - -### author -プラグイン作者 - -### version -プラグインバージョン。数値を指定してください。 - -### description -プラグインの説明 - -### permissions -プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。 - -### config -プラグインの設定情報を表すオブジェクト。 キーに設定名、値に以下のプロパティを含めます。 - -#### type -設定値の種類を表す文字列。以下から選択します。 string number boolean - -#### label -ユーザーに表示する設定名 - -#### description -設定の説明 - -#### default -設定のデフォルト値 - -## APIリファレンス -AiScript標準で組み込まれているAPIは掲載しません。 - -### Mk:dialog(title text type) -ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。 - -### Mk:confirm(title text type) -確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。 - -### Mk:api(endpoint params) -Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。 - -### Mk:save(key value) -任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。 - -### Mk:load(key) -Mk:saveで永続化した指定の名前の値を読み取ります。 - -### Plugin:register_post_form_action(title fn) -投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。 - -### Plugin:register_note_action(title fn) -ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 - -### Plugin:register_user_action(title fn) -ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。 - -### Plugin:register_note_view_interruptor(fn) -UIに表示されるノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:register_note_post_interruptor(fn) -ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:open_url(url) -第一引数に渡されたURLをブラウザの新しいタブで開きます。 - -### Plugin:config -プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。 diff --git a/src/docs/ko-KR/advanced/develop-bot.md b/src/docs/ko-KR/advanced/develop-bot.md deleted file mode 100644 index 7f825e9bc..000000000 --- a/src/docs/ko-KR/advanced/develop-bot.md +++ /dev/null @@ -1,6 +0,0 @@ -# Botの作成 -[Misskey API](./api)を利用してBotの開発が可能です。 また、いくつかのBot実装が公開されているため、ぜひ参考にしてください。 - -- [syuilo/ai](https://github.com/syuilo/ai) ... Node.js上で動く、TypeScript製Bot実装 - -Botを作成したときは、プロフィール設定からBotフラグをオンにしておくことを強くおすすめします。 diff --git a/src/docs/ko-KR/advanced/reversi-bot.md b/src/docs/ko-KR/advanced/reversi-bot.md deleted file mode 100644 index aef450f2d..000000000 --- a/src/docs/ko-KR/advanced/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# MisskeyリバーシBotの開発 -Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。 - -1. `games/reversi`ストリームに以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - -2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる - * イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている - -3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する - -4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - * `game`: `game`の`id` - -5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う - -6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する - -7. ゲームが開始すると、`started`イベントが流れてくる - * イベントの中身にはゲーム情報が含まれている - -8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述) - -9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる - * `color`として石の色が含まれている - * `pos`として位置情報が含まれている - -## 位置の計算法 -8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### X,Y座標 から インデックス に変換する -``` -pos = x + (y * mapWidth) -``` -`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます: -``` -mapWidth = map[0].length -``` - -### インデックス から X,Y座標 に変換する -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## マップ情報 -マップ情報は、ゲーム情報の`map`に入っています。 文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 それをもとにマップのデザインを知る事が出来ます: -* `(スペース)` ... マス無し -* `-` ... マス -* `b` ... 初期配置される黒石 -* `w` ... 初期配置される白石 - -例えば、4*4の次のような単純なマップがあるとします: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -この場合、マップデータはこのようになります: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## ユーザーにフォームを提示して対話可能Botを作成する -ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。 - -フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します: -```javascript -{ - type: 'init-form', - body: [フォームコントロールの配列] -} -``` - -フォームコントロールの配列については今から説明します。 フォームコントロールは、次のようなオブジェクトです: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... コントロールのID。 `type` ... コントロールの種類。後述します。 `label` ... コントロールと一緒に表記するテキスト。 `value` ... コントロールのデフォルト値。 - -### フォームの操作を受け取る -ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### フォームコントロールの種類 -#### 스위치 -type: `switch` スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。 - -##### プロパティ -`label` ... スイッチに表記するテキスト。 - -#### ラジオボタン -type: `radio` ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。 - -##### プロパティ -`items` ... ラジオボタンの選択肢。例: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '強', - value: 3 -}] -``` - -#### スライダー -type: `slider` スライダーを表示します。 - -##### プロパティ -`min` ... スライダーの下限。 `max` ... スライダーの上限。 `step` ... 入力欄で刻むステップ値。 - -#### テキストボックス -type: `textbox` テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。 - -## ユーザーにメッセージを表示する -設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 メッセージを表示するには、次のメッセージをストリームに送信します: -```javascript -{ - type: 'message', - body: { - text: 'メッセージ内容', - type: 'メッセージの種類' - } -} -``` -メッセージの種類: `success`, `info`, `warning`, `error`。 - -## 投了する -投了をするには、このエンドポイントにリクエストします。 diff --git a/src/docs/ko-KR/advanced/share-page.md b/src/docs/ko-KR/advanced/share-page.md deleted file mode 100644 index 2b2747f69..000000000 --- a/src/docs/ko-KR/advanced/share-page.md +++ /dev/null @@ -1,54 +0,0 @@ -# シェアページ -`/share`を開くと、共有用の投稿フォームを開くことができます。 ここではシェアページで利用できるクエリ文字列の一覧を示します。 - -## クエリ文字列一覧 -### 텍스트 - -
-
title
-
タイトルです。本文の先頭に[ … ]と挿入されます。
-
text
-
本文です。
-
url
-
URLです。末尾に挿入されます。
-
- -### リプライ情報 -以下のいずれか - -
-
replyId
-
リプライ先のノートid
-
replyUri
-
リプライ先のUrl(リモートのノートオブジェクトを指定)
-
- -### Renote情報 -以下のいずれか - -
-
renoteId
-
Renote先のノートid
-
renoteUri
-
Renote先のUrl(リモートのノートオブジェクトを指定)
-
- -### 공개 범위 -※specifiedに相当する値はvisibility=specifiedとvisibleAccts/visibleUserIdsで指定する - -
-
visibility
-
公開範囲 ['public' | 'home' | 'followers' | 'specified']
-
localOnly
-
0(false) or 1(true)
-
visibleUserIds
-
specified時のダイレクト先のユーザーid カンマ区切りで
-
visibleAccts
-
specified時のダイレクト先のacct(@?username[@host]) カンマ区切りで
-
- -### 파일 -
-
fileIds
-
添付したいファイルのid(カンマ区切りで)
-
diff --git a/src/docs/ko-KR/advanced/stream.md b/src/docs/ko-KR/advanced/stream.md deleted file mode 100644 index 291fb9271..000000000 --- a/src/docs/ko-KR/advanced/stream.md +++ /dev/null @@ -1,350 +0,0 @@ -# ストリーミングAPI - -ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。 - -## ストリームに接続する - -ストリーミングAPIを利用するには、まずMisskeyサーバーに**websocket**接続する必要があります。 - -以下のURLに、`i`というパラメータ名で認証情報を含めて、websocket接続してください。例: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。 - -
ℹ️ 認証情報の取得については、こちらのドキュメントをご確認ください。
- ---- - -認証情報は省略することもできますが、その場合非ログインでの利用ということになり、受信できる情報や可能な操作は限られます。例: - -``` -%WS_URL%/streaming -``` - ---- - -ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。 - -**ストリームでのやり取りはすべてJSONです。** - -## 채널 -MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。 - -ひとつのストリーム上で、同時に複数のチャンネルに接続することができます。 - -### チャンネルに接続する -チャンネルに接続するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -ここで、 -* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。 -* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。 -* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。 - -
ℹ️ IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。
- -### チャンネルからのメッセージを受け取る -例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。 - -チャンネルがメッセージを発すると、次のようなデータがJSONでストリームに流れてきます: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。 -* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。 -* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。 - -### チャンネルに向けてメッセージを送信する -チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。 - -チャンネルにメッセージを送信するには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。 -* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。 -* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。 - -### チャンネルから切断する -チャンネルから切断するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。 - -## ストリームを経由してAPIリクエストする - -ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。 - -ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -ここで、 -* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 -* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 -* `data`には、エンドポイントのパラメータを含めます。 - -
ℹ️ APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。
- -### レスポンスの受信 - -APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。 - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -ここで、 -* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 -* `body`には、レスポンスが含まれています。 - -## 投稿のキャプチャ - -Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。 - -例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。 - -しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。 - -この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。 - -### 投稿をキャプチャする - -投稿をキャプチャするには、ストリームに次のようなメッセージを送信します: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャしたい投稿の`id`を設定します。 - -このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 - -例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -ここで、 -* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。 -* `body`内の`type`に、イベントの種類が設定されます。 -* `body`内の`body`に、イベントの詳細が設定されます。 - -#### イベントの種類 - -##### `reacted` -その投稿にリアクションがされた時に発生します。 - -* `reaction`に、リアクションの種類が設定されます。 -* `userId`に、リアクションを行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -その投稿が削除された時に発生します。 - -* `deletedAt`に、削除日時が設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -その投稿に添付されたアンケートに投票された時に発生します。 - -* `choice`に、選択肢IDが設定されます。 -* `userId`に、投票を行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### 投稿のキャプチャを解除する - -その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。 - -次のメッセージを送信します: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャを解除したい投稿の`id`を設定します。 - -このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 - -# チャンネル一覧 -## `main` -アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `renote` -自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。 - -#### `mention` -誰かからメンションされたときに発生するイベントです。 - -#### `readAllNotifications` -自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。 - -#### `meUpdated` -自分の情報が更新されたことを表すイベントです。 - -#### `follow` -自分が誰かをフォローしたときに発生するイベントです。 - -#### `unfollow` -自分が誰かのフォローを解除したときに発生するイベントです。 - -#### `followed` -自分が誰かにフォローされたときに発生するイベントです。 - -## `homeTimeline` -ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -タイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `localTimeline` -ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `hybridTimeline` -ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ソーシャルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `globalTimeline` -グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 diff --git a/src/docs/ko-KR/aiscript.md b/src/docs/ko-KR/aiscript.md deleted file mode 100644 index 6fd316fe2..000000000 --- a/src/docs/ko-KR/aiscript.md +++ /dev/null @@ -1,4 +0,0 @@ -# AiScript - -## 함수 -기본값은 값에 의한 호출입니다. diff --git a/src/docs/ko-KR/api.md b/src/docs/ko-KR/api.md deleted file mode 100644 index 7d39479c1..000000000 --- a/src/docs/ko-KR/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -Misskey API를 사용하여 Misskey 클라이언트, Misskey 연계 웹 서비스, 봇 등(이하 "애플리케이션"이라고 부릅니다)을 개발할 수 있습니다. 스트리밍 API도 있기 때문에 실시간 애플리케이션을 만들 수도 있습니다. - -API를 사용하려면 먼저 액세스 토큰을 취득해야 합니다. 이 문서에서는 액세스 토큰을 취득하는 절차를 설명한 후 기본적인 API 사용법을 설명합니다. - -## 액세스 토큰 가져오기 -기본적으로 API는 요청 시에 액세스 토큰이 필요합니다. API에 요청하는 것이 자기 자신인지, 불특정한 유저에게 사용하는 애플리케이션인지에 따라 취득 절차가 달라집니다. - -* 전자의 경우: [「자기 자신의 액세스 토큰을 수동으로 발급하기」](#自分自身のアクセストークンを手動発行する)로 진행 -* 후자의 경우: [「애플리케이션 사용자에게 액세스 토큰 발급을 요청하기」](#アプリケーション利用者にアクセストークンの発行をリクエストする)로 진행 - -### 자기 자신의 액세스 토큰을 수동으로 발급하기 -「설정 > API」에서 자신의 액세스 토큰을 발급할 수 있습니다. - -[「API 사용 방법」으로 이동](#APIの使い方) - -### 애플리케이션 사용자에게 액세스 토큰 발급을 요청하기 -애플리케이션 사용자의 액세스 토큰을 취득하려면, 다음 순서로 발급을 요청합니다. - -#### 1 단계 - -UUID를 생성합니다. 이것을 세션 ID라고 부릅니다. - -> 이 세션 ID는 매번 새로 생성하는 것이 아닙니다. - -#### 2 단계 - -`{_URL_}/miauth/{session}`을 사용자의 브라우저에 입력합니다. `{session}` 부분은 세션 ID로 대체해서 입력합니다. -> 예: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -표시할 때 URL에 쿼리 매개변수로 몇 가지 옵션을 설정할 수 있습니다: -* `name` ... 애플리케이션 이름 - * > 예: `MissDeck` -* `icon` ... 애플리케이션 아이콘의 이미지 URL - * > 예: `https://missdeck.example.com/icon.png` -* `callback` ... 인증이 끝난 후 리디렉션되는 URL - * > 예: `https://missdeck.example.com/callback` - * 리디렉션 할 시, `session`이라는 쿼리 매개변수로 세션 ID가 붙습니다. -* `permission` ... 애플리케이션이 요구하는 권한 - * > 예: `write:notes,write:following,read:drive` - * 요구하는 권한을 `,`으로 구분해서 작성합니다. - * 권한의 종류에 대해서는 [API 레퍼런스](/api-doc)에서 확인할 수 있습니다. - -#### 3 단계 -사용자가 발급을 허용한 후, `{_URL_}/api/miauth/{session}/check`에 POST 요청을 하면 응답으로 액세스 토큰을 포함한 JSON이 반환됩니다. - -응답에 포함되는 속성: -* `token` ... 유저의 액세스 토큰 -* `user` ... 유저 정보 - -[「API 사용 방법」으로 이동](#APIの使い方) - -## API 사용 방법 -**API는 모두 POST 방식이며, 요청/응답 모두 JSON 형식입니다. REST가 아닙니다.** 액세스 토큰은 `i`라는 매개변수로 요청에 포함됩니다. - -* [API 레퍼런스](/api-doc) -* [스트리밍 API](./stream) diff --git a/src/docs/ko-KR/create-plugin.md b/src/docs/ko-KR/create-plugin.md deleted file mode 100644 index 3c93eb053..000000000 --- a/src/docs/ko-KR/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# 플러그인 제작 -Misskey 웹 클라이언트의 플러그인 기능을 사용하면, 클라이언트를 확장하고 다양한 기능을 추가할 수 있습니다. 여기에서는 플러그인의 제작에 있어서 메타데이터 정의, AiScript API 레퍼런스를 소개합니다. - -## 메타데이터 -플러그인은 AiScript의 메타데이터 내장 기능을 사용하며, 기본적으로 플러그인의 메타데이터를 정의해야 합니다. - -### name -플러그인 이름 - -### author -플러그인 제작자 - -### version -플러그인 버전. 값을 지정해 주세요. - -### description -플러그인에 대한 설명 - -### permissions -플러그인이 요구하는 권한. Misskey API에 요청할 때 사용됩니다. - -### config -플러그인의 설정 정보를 나타내는 객체. 키 값에 설정명을, 값에는 다음 속성을 포함할 수 있습니다. - -#### type -설정값의 종류를 나타내는 문자열. 아래 항목들을 사용할 수 있습니다. string number boolean - -#### label -사용자에게 표시할 설정 이름 - -#### description -설정의 설명 - -#### default -설정의 기본값 - -## API 레퍼런스 -AiScript 표준으로 내장되어 있는 API는 소개하지 않습니다. - -### Mk:dialog(title text type) -대화 상자를 표시합니다. type에는 아래 항목들을 사용할 수 있습니다. info success warn error question 생략하면 info로 설정됩니다. - -### Mk:confirm(title text type) -확인 대화 상자를 표시합니다. type에는 아래 항목들을 사용할 수 있습니다. info success warn error question 생략하면 question으로 설정됩니다. 사용자가 "OK"를 선택한 경우 true를, "취소"를 선택한 경우 false가 반환됩니다. - -### Mk:api(endpoint params) -Misskey API에 요청합니다. 첫 번째 인수에 엔드포인트 이름, 두 번째 인수에 매개변수 객체를 전달합니다. - -### Mk:save(key value) -임의의 값에 임의의 이름을 붙여 영속화합니다. 영속화한 값은 AiScript 컨텍스트가 종료되어도 남아서 Mk:load 작업을 수행합니다. - -### Mk:load(key) -Mk:save에서 영속화된 지정값을 읽습니다. - -### Plugin:register_post_form_action(title fn) -게시 양식에 작업을 추가합니다. 첫 번째 인수로 작업 이름, 두 번째 인수로 작업이 선택되었을 때의 콜백 함수를 전달합니다. 콜백 함수에는 첫 번째 인수로 게시 양식 객체가 전달됩니다. - -### Plugin:register_note_action(title fn) -노트 메뉴에 항목을 추가합니다. 첫 번째 인수로 항목명, 두 번째 인수로 항목이 선택되었을 때의 콜백 함수를 전달합니다. 콜백 함수에는 첫 번째 인수로 대상 노트 객체가 전달됩니다. - -### Plugin:register_user_action(title fn) -유저 메뉴에 항목을 추가합니다. 첫 번째 인수로 항목명, 두 번째 인수로 항목이 선택되었을 때의 콜백 함수를 전달합니다. 콜백 함수에는 첫 번째 인수로 대상 유저 객체가 전달됩니다. - -### Plugin:register_note_view_interruptor(fn) -UI에 표시되는 노트 정보를 변경합니다. 콜백 함수는 첫 번째 인수로 해당되는 노트 객체를 전달합니다. 콜백 함수의 반환값으로 노트가 변경됩니다. - -### Plugin:register_note_post_interruptor(fn) -노트를 게시할 때의 노트 정보를 변경합니다. 콜백 함수는 첫 번째 인수로 해당되는 노트 객체를 전달합니다. 콜백 함수의 반환값으로 노트가 변경됩니다. - -### Plugin:open_url(url) -첫 번째 인수로 전달된 URL을 브라우저의 새 탭에서 엽니다. - -### Plugin:config -플러그인의 설정이 저장되는 객체. 플러그인 정의 config에서 설정한 키로 값이 저장됩니다. diff --git a/src/docs/ko-KR/custom-emoji.md b/src/docs/ko-KR/custom-emoji.md deleted file mode 100644 index bc6fbafa6..000000000 --- a/src/docs/ko-KR/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# 커스텀 이모지 -커스텀 이모지는 인스턴스에 준비된 이미지를 이모지와 같이 사용할 수 있는 기능입니다. 노트, 리액션, 채팅, 자기소개, 이름 등에서 사용할 수 있습니다. 커스텀 이모지를 사용하려면, 커스텀 이모지 선택기 버튼(있는 경우)을 누르거나, `:`를 입력해 이모지 추천을 표시합니다. 텍스트 내에 `:foo:`와 같은 형식의 문자열이 발견되면, `foo` 부분이 커스텀 이모지명으로 해석되며, 표기는 대응하는 커스텀 이모지로 대체됩니다. diff --git a/src/docs/ko-KR/deck.md b/src/docs/ko-KR/deck.md deleted file mode 100644 index bf5dc84a5..000000000 --- a/src/docs/ko-KR/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# 덱 - -덱은 이용 가능한 UI 중 하나입니다. 「칼럼」이라고 불리는 여러 뷰를 나열하여 표시함으로써, 맞춤성이 높고 정보량이 많은 UI를 구축할 수 있다는 특징이 있습니다. - -## 칼럼 추가 -덱의 배경을 우클릭 한 뒤, 「칼럼 추가」를 눌러 원하는 칼럼을 추가할 수 있습니다. - -## 칼럼 이동 -칼럼은 드래그 앤 드롭으로 다른 칼럼과 위치를 바꿀 수 있으며, 칼럼 메뉴(칼럼의 헤더 오른쪽 클릭)에서도 위치를 이동할 수 있습니다. - -## 칼럼 수평 분할 -칼럼은 좌우뿐만 아니라, 상하로도 정렬할 수 있습니다. 칼럼 메뉴를 열고 「왼쪽에 쌓기」를 선택하면 왼쪽 칼럼 아래로 현재 칼럼이 이동합니다. 수평 분할을 해제하려면 칼럼 메뉴의 「오른쪽으로 빼기」를 선택합니다. - -## 칼럼 설정 -칼럼 메뉴의 「편집」을 클릭하면 칼럼의 설정을 편집할 수 있습니다. 칼럼의 이름을 변경하거나, 너비를 조절할 수 있습니다. - -## 덱 설정 -덱에 관한 설정은 [settings/deck](/settings/deck)에서 할 수 있습니다. diff --git a/src/docs/ko-KR/features/antenna.md b/src/docs/ko-KR/features/antenna.md deleted file mode 100644 index 9457015f6..000000000 --- a/src/docs/ko-KR/features/antenna.md +++ /dev/null @@ -1,4 +0,0 @@ -# 안테나 -アンテナは、自由に条件を設定して、合致するノートを自動で収集することができる機能です。 - -条件を設定したアンテナが作成された状態で、条件に合致するノートが投稿されると、リアルタイムでそのアンテナのタイムラインにノートが追加されます。 diff --git a/src/docs/ko-KR/features/custom-emoji.md b/src/docs/ko-KR/features/custom-emoji.md deleted file mode 100644 index 6aa3a0fe4..000000000 --- a/src/docs/ko-KR/features/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# 커스텀 이모지 -カスタム絵文字は、インスタンスで用意された画像を絵文字のように使える機能です。 ノート、リアクション、チャット、自己紹介、名前などの場所で使うことができます。 カスタム絵文字をそれらの場所で使うには、絵文字ピッカーボタン(ある場合)を押すか、`:`を入力して絵文字サジェストを表示します。 テキスト内に`:foo:`のような形式の文字列が見つかると、`foo`の部分がカスタム絵文字名と解釈され、表示時には対応したカスタム絵文字に置き換わります。 diff --git a/src/docs/ko-KR/features/deck.md b/src/docs/ko-KR/features/deck.md deleted file mode 100644 index 87c95d45b..000000000 --- a/src/docs/ko-KR/features/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# 덱 - -デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。 - -## カラムの追加 -デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。 - -## カラムの移動 -カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。 - -## カラムの水平分割 -カラムは左右だけでなく、上下に並べることもできます。 カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 上下分割を解除するには、カラムメニューの「右に出す」を選択します。 - -## カラムの設定 -カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。 - -## デッキの設定 -デッキに関する設定は、[settings/deck](/settings/deck)で行えます。 diff --git a/src/docs/ko-KR/features/drive.md b/src/docs/ko-KR/features/drive.md deleted file mode 100644 index 9c1d604da..000000000 --- a/src/docs/ko-KR/features/drive.md +++ /dev/null @@ -1,17 +0,0 @@ -# 드라이브 -ドライブは、Misskey上でファイルを管理できる機能です。 - -[ドライブのページ](/my/drive)から任意のファイルをアップロードできるほか、アバターに設定した画像や、ノートに添付したファイルなどもすべてドライブにアップロードされます。 - -
⚠️ ドライブからファイルを削除すると、そのファイルが添付されたノートも消えます。
- -ドライブにアップロードされたファイルは、いつでもダウンロードすることができるほか、ノート作成時に「ドライブからファイルを添付」することでファイルを再利用することもできます。 - -ドライブ内にフォルダを作り、複数のファイルをまとめて整理することもできます。 - -## 閲覧注意 (NSFW) -
ℹ️ この項目が閲覧注意なわけではありません
- -閲覧注意またはNSFW (Not safe for work) は、ドライブのファイルに設定することができるフラグです。 閲覧注意フラグを設定されたファイルは、表示される際に閲覧者の操作なしには表示されなくなります。 このフラグは、例えば職場や公共の場で閲覧するのに適切でないと思われる画像などに設定し、そのような画像が突然表示されてしまうことを防ぐ目的で使われます。 - -このフラグは手動でオンオフを切り替えられるほか、モデレーターの判断で設定される場合もあります。 diff --git a/src/docs/ko-KR/features/favorite.md b/src/docs/ko-KR/features/favorite.md deleted file mode 100644 index c6a3b413d..000000000 --- a/src/docs/ko-KR/features/favorite.md +++ /dev/null @@ -1,4 +0,0 @@ -# 즐겨찾기 -[ノート](./node)をお気に入りとして登録できる機能です。 お気に入り登録したノートは、[お気に入りページ](./my/favorites)で一覧することができます。 お気に入りに登録したことは相手に通知されず、お気に入りは自分しか見ることができません。 - -ノートをお気に入り登録するには、ノートメニューの「お気に入り」を押します。お気に入り解除するには、ノートメニューの「お気に入り解除」を押します。 diff --git a/src/docs/ko-KR/features/follow.md b/src/docs/ko-KR/features/follow.md deleted file mode 100644 index 197aee13c..000000000 --- a/src/docs/ko-KR/features/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# 팔로잉 -ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。 diff --git a/src/docs/ko-KR/features/keyboard-shortcut.md b/src/docs/ko-KR/features/keyboard-shortcut.md deleted file mode 100644 index 95cb81884..000000000 --- a/src/docs/ko-KR/features/keyboard-shortcut.md +++ /dev/null @@ -1,66 +0,0 @@ -# キーボードショートカット - -## 글로벌 -これらのショートカットは基本的にどこでも使えます。 - - - - - - - - - - - -
ショートカット効果由来
P, N新規投稿Post, New, Note
Tタイムラインの最も新しい投稿にフォーカスTimeline, Top
Shift + N通知を表示/隠すNotifications
S검색Search
H, ?ヘルプを表示Help
- -## 投稿にフォーカスされた状態 - - - - - - - - - - - - - - - - - - -
ショートカット効果由来
, K, Shift + Tab上の投稿にフォーカスを移動-
, J, Tab下の投稿にフォーカスを移動-
R返信フォームを開くReply
QRenoteフォームを開くQuote
Ctrl + Q即刻Renoteする(フォームを開かずに)-
E, A, +リアクションフォームを開くEmote, reAction
0~9数字に対応したリアクションをする(対応については後述)-
F, Bお気に入りに登録Favorite, Bookmark
Del, Ctrl + D投稿を削除Delete
M, O投稿に対するメニューを開くMore, Other
SCWで隠された部分を表示 or 隠すShow, See
Escフォーカスを外す-
- -## Renoteフォーム - - - - - - - - - -
ショートカット効果由来
EnterRenoteする-
Qフォームを展開するQuote
Escフォームを閉じる-
- -## リアクションフォーム -デフォルトで「👍」にフォーカスが当たっている状態です。 - - - - - - - - - - - - - -
ショートカット効果由来
, K上のリアクションにフォーカスを移動-
, J下のリアクションにフォーカスを移動-
, H, Shift + Tab左のリアクションにフォーカスを移動-
, L, Tab右のリアクションにフォーカスを移動-
Enter, Space, +リアクション確定-
0~9数字に対応したリアクションで確定-
Escリアクションするのをやめる-
diff --git a/src/docs/ko-KR/features/mfm.md b/src/docs/ko-KR/features/mfm.md deleted file mode 100644 index 5be2df4f3..000000000 --- a/src/docs/ko-KR/features/mfm.md +++ /dev/null @@ -1,12 +0,0 @@ -# MFM -MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます。 - -## MFMが使用可能な場所の例 -- ノート本文 -- CW注釈 -- ユーザーの名前 -- ユーザーの自己紹介 - -## 開発者向け情報 -MFMのパーサー実装はライブラリとして公開されており、簡単にクライアントにMFMを組み込むことが可能です。 -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptパーサー実装 diff --git a/src/docs/ko-KR/features/mute-and-block.md b/src/docs/ko-KR/features/mute-and-block.md deleted file mode 100644 index fa063cc2d..000000000 --- a/src/docs/ko-KR/features/mute-and-block.md +++ /dev/null @@ -1,41 +0,0 @@ -# 뮤트 및 차단 -好みではないユーザーがいる場合は、ミュートを行うことでそのユーザーが自分から見えないようにすることができます。 また、より強力な措置として、ブロックを行うことでそのユーザーから自分のコンテンツが見えないようになるほか、自分に対して関わることができないようにすることができます。 ミュートされていることは相手は分かりませんが、ブロックされていることは相手に分かります。どちらを選ぶかはご自身の判断で行ってください。 - -
ℹ️ ミュートとブロックは併用できます。
- -
⚠️ 利用規約に違反するような、迷惑なユーザーがいる場合は運営者に報告することも検討してください。
- -設定>ミュートとブロック から、自分がミュートまたはブロックしているユーザー一覧を確認することができます。 - -## 뮤트 -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -- タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -- そのユーザーからの通知 -- メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 -- など - -ユーザーをミュートするには、対象のユーザーのユーザーページのメニューを開き、「ミュート」ボタンを押します。 - -
ℹ️ ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。
- -## 차단 -ユーザーをブロックすると、そのユーザーからあなたのコンテンツが見えないようになり、またあなたに対して以下のようなアクションをすることができなくなります。 - -- フォローする -- ユーザーリストに追加する -- 返信する、Renoteする -- リアクションする、アンケートに投票する -- メッセージを送信する -- など - -また、 - -- ブロックする際に既にそのユーザーからフォローされていた場合はフォローが解除されます。 -- ブロックする際に既にそのユーザーがあなたをユーザーリストに入れていた場合はそのリストからあなたが削除されます。 - -ユーザーをブロックするには、対象のユーザーのユーザーページのメニューを開き、「ブロック」ボタンを押します。 - -
⚠️ ブロックを行ったこと自体は相手に通知されませんが、フォローを行ったりなどの上記のアクションが行えなくなるので間接的にブロックされていることは分かります。
- -
⚠️ 相手から自分のコンテンツが見えなくなりますが、相手がアカウントを切り替えたりログアウト状態になれば見ることができます。あくまで簡易的、補助的なものとしてお考えください。
diff --git a/src/docs/ko-KR/features/mute.md b/src/docs/ko-KR/features/mute.md deleted file mode 100644 index 89195bb10..000000000 --- a/src/docs/ko-KR/features/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# 뮤트 - -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -* タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -* そのユーザーからの通知 -* メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 - -ユーザーをミュートするには、対象のユーザーのユーザーページに表示されている「ミュート」ボタンを押します。 - -ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。 - -設定>ミュート から、自分がミュートしているユーザー一覧を確認することができます。 diff --git a/src/docs/ko-KR/features/note.md b/src/docs/ko-KR/features/note.md deleted file mode 100644 index 974691c46..000000000 --- a/src/docs/ko-KR/features/note.md +++ /dev/null @@ -1,54 +0,0 @@ -# 노트 -ノートは、Misskeyに投稿される、文章、ファイル、アンケートなどを含むコンテンツで、Misskeyの中心的概念です。また、そのノートを作成する行為自体もノートと呼ばれます。 - -ノートが作成されると、[タイムライン](./timeline)に追加され、自分の[フォロワー](./follow)やサーバーのユーザーが見れるようになります。 - -ノートには、[リアクション](./reaction)を行うことができます。また、返信や引用もできます。 - -ノートを[お気に入り](./favorite)登録することで、後で簡単に見返すことができます。 - -## ノートを作成する -ノートを作成するには、画面上にある鉛筆マークのボタンを押して、作成フォームを開きます。作成フォームに内容を入力し、「ノート」ボタンを押すことでノートが作成されます。 ノートには、画像、動画など任意のファイルや、[アンケート](./poll)を添付することができます。また、本文中には[MFM](./mfm)が使用でき、[メンション](./mention)や[ハッシュタグ](./hashtag)を含めることもできます。 他にも、CWや公開範囲といった設定も行えます(詳細は後述)。 -
ℹ️ コンピューターのクリップボードに画像データがある状態で、フォーム内のテキストボックスにペーストするとその画像を添付することができます。
-
ℹ️ テキストボックス内でCtrl + Enterを押すことでも投稿できます。
- -## Renote -既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノートをRenoteと呼びます。 自分がフォローしているユーザーの、気に入ったノートを自分のフォロワーに共有したい場合や、過去の自分のノートを再度共有したい場合に使います。 同じノートに対して無制限にRenoteを行うことができますが、あまり連続して使用すると迷惑になる場合もあるので、注意しましょう。 -
⚠️ 公開範囲がフォロワーやダイレクトのノートはRenoteできません
- -Renoteを削除するには、Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 - -## CW -Contents Warningの略で、ノートの内容を、閲覧者の操作なしには表示しないようにできる機能です。主に長大な内容を隠すためや、ネタバレ防止などに使うことができます。 設定するには、フォームの「内容を隠す」ボタン(目のアイコン)を押します。すると新しい入力エリアが表れるので、そこに内容の要約を記入します。 - -## 공개 범위 -ノートごとに、そのノートが公開される範囲を設定することができます。フォームの「ノート」ボタンの左にあるアイコンを押すと公開範囲を以下から選択できます。 - -### 공개 -全ての人に対してノートが公開されるほか、サーバーの全てのタイムライン(ホームタイムライン、ローカルタイムライン、ソーシャルタイムライン、グローバルタイムライン)にノートが流れます。 -
⚠️ アカウントがサイレンス状態の時は、この公開範囲は使用できません。
- -### 홈 -全ての人に対してノートが公開されますが、フォロワー以外のローカルタイムライン、ソーシャルタイムライン、グローバルタイムラインにはノートは流れません。 - -### 팔로워 -自分のフォロワーに対してのみノートを公開します。フォロワーの全てのタイムラインに流れます。 - -### 다이렉트 -指定したユーザーに対してのみノートを公開します。指定したユーザーの全てのタイムラインに流れます。 - -### 「ローカルのみ」オプション -このオプションを有効にすると、リモートにノートを連合しなくなります。 - -### 公開範囲の比較 - - - - -
공개팔로워다이렉트
フォロワーのLTL/STL/GTL
非フォロワーのLTL/STL/GTL
- -## 프로필에 고정 -ノートをピン留めすると、ユーザーページに常にそのノートを表示しておくことができます。 ノートのメニューを開き、「ピン留め」を選択してピン留めできます。 複数のノートをピン留めできます。 - -## 지켜보기 -ノートをウォッチすると、自分以外のノートへのリアクションや返信などの通知を受け取ることができます。 ノートのメニューを開き、「ウォッチ」を選択してウォッチできます。 diff --git a/src/docs/ko-KR/features/pages.md b/src/docs/ko-KR/features/pages.md deleted file mode 100644 index 54bc85371..000000000 --- a/src/docs/ko-KR/features/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# Pages - -## 변수 -変数を使うことで動的なページを作成できます。テキスト内で { 変数名 } と書くとそこに変数の値を埋め込めます。例えば Hello { thing } world! というテキストで、変数(thing)の値が ai だった場合、テキストは Hello ai world! になります。 - -変数の評価(値を算出すること)は上から下に行われるので、ある変数の中で自分より下の変数を参照することはできません。例えば上から A、B、C と3つの変数を定義したとき、Cの中でABを参照することはできますが、Aの中でBCを参照することはできません。 - -ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。 - -関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。 diff --git a/src/docs/ko-KR/features/reaction.md b/src/docs/ko-KR/features/reaction.md deleted file mode 100644 index 260258f93..000000000 --- a/src/docs/ko-KR/features/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# 리액션 -他の人のノートに、絵文字を付けて簡単にあなたの反応を伝えられる機能です。 リアクションするには、ノートの + アイコンをクリックしてピッカーを表示し、絵文字を選択します。 リアクションには[カスタム絵文字](./custom-emoji)も使用できます。 - -## リアクションピッカーのカスタマイズ -ピッカーに表示される絵文字を自分好みにカスタマイズすることができます。 設定の「リアクション」で設定します。 - -## リモート投稿へのリアクションについて -リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。 - -## リモートからのリアクションについて -リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。 diff --git a/src/docs/ko-KR/features/silence.md b/src/docs/ko-KR/features/silence.md deleted file mode 100644 index 756aa9840..000000000 --- a/src/docs/ko-KR/features/silence.md +++ /dev/null @@ -1,6 +0,0 @@ -# 사일런스 -サイレンスは、アカウントに設定される状態のひとつです。 - -アカウントがサイレンス状態になると、ノートの公開範囲をパブリックにできなくなります。 ホーム、フォロワー、ダイレクトは選択可能なため、サイレンスを受けた場合でもフォロワーやあなたのユーザーページを直接訪れた場合は投稿を閲覧できますが、GTL(連合タイムライン)やLTL(ローカルタイムライン)には投稿が流れません。 - -アカウントのサイレンス状態は、サーバーのモデレーターによって有効化/無効化されます。 diff --git a/src/docs/ko-KR/features/theme.md b/src/docs/ko-KR/features/theme.md deleted file mode 100644 index e01133b83..000000000 --- a/src/docs/ko-KR/features/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# 테마 - -テーマを設定して、Misskeyクライアントの見た目を変更できます。 - -## テーマの設定 -設定 > テーマ - -## テーマを作成する -テーマコードはJSON5で記述されたテーマオブジェクトです。 テーマは以下のようなオブジェクトです。 -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... テーマの一意なID。UUIDをおすすめします。 -* `name` ... テーマ名 -* `author` ... テーマの作者 -* `desc` ... テーマの説明(オプション) -* `base` ... 明るいテーマか、暗いテーマか - * `light`にすると明るいテーマになり、`dark`にすると暗いテーマになります。 - * テーマはここで設定されたベーステーマを継承します。 -* `props` ... テーマのスタイル定義。これから説明します。 - -### テーマのスタイル定義 -`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 - -#### バリューで使える構文 -* 16進数で表された色 - * 例: `#00ff00` -* `rgb(r, g, b)`形式で表された色 - * 例: `rgb(0, 255, 0)` -* `rgb(r, g, b, a)`形式で表された透明度を含む色 - * 例: `rgba(0, 255, 0, 0.5)` -* 他のキーの値の参照 - * `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。 - * 例: `@panel` -* 定数(後述)の参照 - * `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。 - * 例: `$main` -* 関数(後述) - * `:{関数名}<{引数}<{色}` - -#### 상수 -「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 キー名を`$`で始めると、そのキーはCSS変数として出力されません。 - -#### 함수 -wip diff --git a/src/docs/ko-KR/features/timeline.md b/src/docs/ko-KR/features/timeline.md deleted file mode 100644 index 6598c0656..000000000 --- a/src/docs/ko-KR/features/timeline.md +++ /dev/null @@ -1,31 +0,0 @@ -# 타임라인 -タイムラインは、[ノート](./note)が時系列で表示される機能です。 タイムラインには以下で示す種類があり、種類によって表示されるノートも異なります。 なお、タイムラインの種類によってはサーバーにより無効になっている場合があります。 - -## 홈 -自分のフォローしているユーザーの投稿が流れます。HTLと略されます。 - -## 로컬 -全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。LTLと略されます。 - -## 소셜 -自分のフォローしているユーザーの投稿と、全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。STLと略されます。 - -## 글로벌 -全てのローカルユーザーの「ホーム」指定されていない投稿と、サーバーに届いた全てのリモートユーザーの「ホーム」指定されていない投稿が流れます。GTLと略されます。 - -## 비교 -| ソース | | | 타임라인 | | | -| ------------ | ----- | - | ---- | -- | --- | -| 유저 | 공개 범위 | 홈 | 로컬 | 소셜 | 글로벌 | -| ローカル (フォロー) | 게시 | ✔ | ✔ | ✔ | ✔ | -| | 홈 | ✔ | | ✔ | | -| | 팔로워 | ✔ | ✔ | ✔ | ✔ | -| リモート (フォロー) | 게시 | ✔ | | ✔ | ✔ | -| | 홈 | ✔ | | ✔ | | -| | 팔로워 | ✔ | | ✔ | ✔ | -| ローカル (未フォロー) | 게시 | | ✔ | ✔ | ✔ | -| | 홈 | | | | | -| | 팔로워 | | | | | -| リモート (未フォロー) | 게시 | | | | ✔ | -| | 홈 | | | | | -| | 팔로워 | | | | | diff --git a/src/docs/ko-KR/features/widgets.md b/src/docs/ko-KR/features/widgets.md deleted file mode 100644 index 5372866d1..000000000 --- a/src/docs/ko-KR/features/widgets.md +++ /dev/null @@ -1,7 +0,0 @@ -# 위젯 -ウィジェットは、MisskeyのUI上に設置できる小型の情報表示、操作が行えるパーツです。 - -ウィジェットを編集するには、ウィジェット編集モードに切り替えます。切り替え方法はUIによって異なります。 ウィジェット編集モードでは、ウィジェットの追加、削除、並び替え、およびそれぞれのウィジェットの設定を行えます。 - -## 利用可能なウィジェット一覧 -todo diff --git a/src/docs/ko-KR/features/word-mute.md b/src/docs/ko-KR/features/word-mute.md deleted file mode 100644 index 0138224db..000000000 --- a/src/docs/ko-KR/features/word-mute.md +++ /dev/null @@ -1,20 +0,0 @@ -# 단어 뮤트 -ワードミュートの設定をすると、条件に合致したノートが表示されなくなります。 - -ワードミュートには、ソフトワードミュートとハードワードミュートの2種類があります。それぞれについて設定の方法と挙動を説明します。 - -## ソフトワードミュート -ソフトワードミュートは、クライアント(アプリ)側でミュートを判断するワードミュートです。 - -ノートが設定した条件に合致すると、「(ユーザー名)が何かを言いました」という表示で隠れます。 -クリックすると元の通りに表示されます。 - -## ハードワードミュート -ハードワードミュートは、アンテナのようにサーバーが新しいノートの本文に対して条件に合致するかどうか判断し、タイムラインから対象となったノートを除外します。 - -つまり、ハードワードミュートには、以下のような特徴があります。 - -* 条件設定後、新しい投稿のみがミュートの対象になります。 -* 条件を変更しても、過去にハードミュートされたノートはミュートされたままになります。 -* 「○○が何かを言いました」でタイムラインが埋まることがありません。 -* ソフトミュートに非対応のアプリでも、ハードミュートは適用されます。 diff --git a/src/docs/ko-KR/follow.md b/src/docs/ko-KR/follow.md deleted file mode 100644 index 66cfdac3e..000000000 --- a/src/docs/ko-KR/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# 팔로우 -유저를 팔로우하게 되면 타임라인에 해당 유저의 글이 뜨게 됩니다. 단, 다른 유저에 대한 회신은 포함되지 않습니다. 유저를 팔로우 하려면, 유저 페이지의 「팔로우」 버튼을 클릭합니다. 팔로우를 해제하려면 다시 클릭합니다. diff --git a/src/docs/ko-KR/general/apps.md b/src/docs/ko-KR/general/apps.md deleted file mode 100644 index a71f37748..000000000 --- a/src/docs/ko-KR/general/apps.md +++ /dev/null @@ -1,6 +0,0 @@ -# 서드파티 어플리케이션 목록 -## 클라이언트 -todo - -## 연동 서비스 -todo diff --git a/src/docs/ko-KR/general/changelog.md b/src/docs/ko-KR/general/changelog.md deleted file mode 100644 index f850f5c7b..000000000 --- a/src/docs/ko-KR/general/changelog.md +++ /dev/null @@ -1,5 +0,0 @@ -# 업데이트 정보 -
ℹ️ 이 서버의 업데이트 정보입니다. Misskey 최신 버전의 업데이트 정보는 Github에서 확인할 수 있습니다.
- - - diff --git a/src/docs/ko-KR/general/faq.md b/src/docs/ko-KR/general/faq.md deleted file mode 100644 index ed858b0e5..000000000 --- a/src/docs/ko-KR/general/faq.md +++ /dev/null @@ -1,28 +0,0 @@ -# 자주 묻는 질문 -여기에서는 Misskey 이용에 대해서 자주 묻는 질문에 대해 다룹니다. Misskey 프로젝트 자체에 대한 질문은 [여기에서](./misskey) 다루고 있습니다. - -## iOS/Android용 어플리케이션이 있나요? -공식 어플리케이션은 없지만, 비공식 서드파티 어플리케이션을 사용하실 수 있습니다. 자세한 사항은 [여기를](./apps) 참조해 주세요. - -단, 비공식 어플리케이션의 경우 최신 기능을 사용할 수 있기까지 시간이 걸릴 수 있으므로, 대부분의 경우 공식 Web 클라이언트를 사용하시는 것을 추천드립니다. 또한, Misskey의 Web 클라이언트는 PWA를 지원하여, 브라우저에서 지원하는 경우 네이티브 앱처럼 사용할 수 있습니다. 자세한 사항은 [여기를](todo) 참조해 주세요. - -## Mastodon 클라이언트로는 로그인할 수 없나요? -Misskey는 Mastdon의 API와 호환성이 없기 때문에, 일부를 제외한 Mastodon 클라이언트에서는 Misskey를 이용하실 수 없습니다. - -## 다른 서버의 유저를 팔로우하고 싶어요 -메뉴에서 검색을 선택해서, 유저명과 호스트(도메인)을 입력하세요. 예시: `@syuilo@misskey.io` - -## Renote를 취소할래요 -Renote한 시간 옆에 있는 '...'를 누르고, "Renote 취소"를 선택하세요. Renote에 대해서는 [여기를](../features/note) 참조해 주세요. - -## URL의 미리보기를 숨기고 싶어요 -MFM를 이용하여 URL의 미리보기를 숨길 수 있습니다. 자세한 사항은 [MFM 도움말](/mfm-cheat-sheet)을 확인해 주세요. - -## 커스텀 이모지를 추가하고 싶어요 -커스텀 이모지의 추가, 편집 및 삭제는 운영자만 할 수 있습니다. 커스텀 이모지에 대해서는 각 인스턴스의 운영자에게 문의해 주세요. - -## Bot을 개발하고 싶어요 -Misskey API를 이용하여 Bot을 개발할 수 있습니다. 자세한 사항은 [여기를](../advanced/develop-bot) 참조해 주세요. - -## 노트 번역 기능은 어떤 서비스를 사용하나요? -노트 번역에는 [DeepL](https://www.deepl.com/)을 사용하고 있습니다. diff --git a/src/docs/ko-KR/general/glossary.md b/src/docs/ko-KR/general/glossary.md deleted file mode 100644 index 26634cca0..000000000 --- a/src/docs/ko-KR/general/glossary.md +++ /dev/null @@ -1,89 +0,0 @@ -# 용어 사전 -Misskey에서 사용하는 용어 모음입니다. - -## ActivityPub -분산형 서비스를 구현하기 위해 사용되는 프로토콜(통신 규약). 이 프로토콜을 통해 다른 서버와 통신하여 연합을 이루고, 이들이 모여 연합우주(Fediverse)를 이룹니다. - -## AiScript -아이스크립트. Misskey에서 사용할 수 있는 프로그래밍 언어. 자세한 내용은 [여기로](../advanced/aiscript) - -## API -에이-피-아이. 프로그램이 Misskey와 상호 작용하는 데에 사용하는 인터페이스. 자세한 내용은 [여기로](../advanced/api) - -## Bot (봇) -프로그램 또는 기타 자동화된 수단으로 운영되는 계정. - -## CW -'Contents Warning'의 줄임말. 제목를 설정하여 노트의 내용을 숨기는 기능. 본문이 길 때, 또는 스포일러 등 상대방이 불쾌해할 수 있는 내용을 감추는 데에 주로 사용합니다. - -## 연합우주 (Fediverse) -Misskey를 비롯한 분산형 서비스 사이의 통신 및 정보 교환으로 이루어지는 네트워크. - -## GTL -글로벌 타임라인(Global TimeLine)의 줄임말. 타임라인에 대한 자세한 내용은 [여기로.](../features/timeline) - -## HTL -홈 타임라인(Home TimeLine)의 줄임말. 타임라인에 대한 자세한 내용은 [여기로.](../features/timeline) - -## LTL -로컬 타임라인(Local TimeLine)의 줄임말. 타임라인에 대한 자세한 내용은 [여기로.](../features/timeline) - -## MFM -Misskey Flavored Markdown의 줄임말. Misskey에서 사용할 수 있는 마크업 언어. 자세한 사항은 [여기로.](../features/mfm) - -## NSFW -Not Safe For Work의 줄임말. 열람 시 주의가 필요한 사진을 감추어, 바로 표시되지 않게 하는 기능. - -## Renote -이미 존재하는 노트를 인용, 또는 새로 작성한 노트처럼 타임라인에 공유하는 것. 또는 이를 통해 새로 작성된 노트를 가리키는 말. 자세한 사항은 [여기로.](../features/note) - -## STL -소셜 타임라인(Social TimeLine)의 줄임말. 타임라인에 대한 자세한 내용은 [여기로.](../features/timeline) - -## 아이(Ai) -Misskey의 공식 마스코트입니다. - -## 활성 사용자 -인스턴스에 계정을 생성한 유저 중에서, 현재 실질적으로 서비스를 이용 중인 사용자를 일컫는 말. - -## 인스턴스 -todo - -## 커스텀 이모지 -서버 자체적으로 사용할 수 있는 이모지. 커스텀 이모지 이외의 일반적인 이모지는 '유니코드 이모지'로 불린다. - -## 제어판 -인스턴스 설정 화면을 가리키는 말. - -## 서버 -todo - -## 사일런스 -노트를 공개 범위로 게시할 수 없게 된 상태. 관리자가 유저별로 설정할 수 있습니다. 자세한 사항은 [여기로.](../features/silence) - -## 작업 대기열 -액티비티 전송 등의 작업을 차례대로 수행하기 위한 시스템. - -## 정지 -계정을 사용할 수 없게 된 상태. - -## 드라이브 -Misskey에 업로드된 파일을 관리하는 기능. 자세한 사항은 [여기로.](../features/drive) - -## 노트 -Misskey에서 글, 파일, 투표 등을 포함하여 작성할 수 있는 콘텐츠. 자세한 사항은 [여기로.](../features/note) - -## 미스키스트 (Misskist) -미스키를 사용하는 사람을 일컫는 말. - -## 모더레이터 -스팸 계정의 정지 및 사일런스, 부적절한 게시물을 삭제하는 등 커뮤니티 운영에 대한 권한을 가진 유저. - -## 리모트 -자신이 속한 서버와 구별하여, 다른 서버를 가리키는 말. '리모트 유저'와 같이 접두사처럼 사용하기도 합니다. 반대말로는 '로컬'이 있습니다. - -## 연합 -서버에서 작성된 정보가 다른 서버로 전달되는 것을 이르는 말. - -## 로컬 -자신이 속한 서버를 가리키는 말. '로컬 유저', '로컬 타임라인'과 같이 접두사처럼 사용하기도 합니다. 반대말로는 '로컬'이 있습니다. diff --git a/src/docs/ko-KR/general/links.md b/src/docs/ko-KR/general/links.md deleted file mode 100644 index 12c5f8c8b..000000000 --- a/src/docs/ko-KR/general/links.md +++ /dev/null @@ -1,12 +0,0 @@ -# 참고할 만한 링크 - -## 웹 사이트 -- [Official Discord](https://discord.gg/Wp8gVStHW3) - Misskey 공식 Discord 서버 -- [Misskey Forum](https://forum.misskey.io/) - Misskey에 대한 이야기를 나누는 포럼 - -## 계정 -- [@repo@misskey.io](https://misskey.io/@repo) - Misskey 리포지터리의 변경 사항을 게시하는 Bot - -## 라이브러리 -- [misskey-dev/misskey.js](https://github.com/misskey-dev/misskey.js) - Javascript용 Misskey SDK -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - Javascript 기반 MFM 구문 해석기 diff --git a/src/docs/ko-KR/general/misskey.md b/src/docs/ko-KR/general/misskey.md deleted file mode 100644 index decd983e7..000000000 --- a/src/docs/ko-KR/general/misskey.md +++ /dev/null @@ -1,87 +0,0 @@ -# Misskey에 대하여 - -Misskey는 오픈소스 분산형 마이크로블로깅 플랫폼 프로젝트입니다. 개발은 2014년부터 일본의 syuilo의 주도로 시작되었습니다. 드라이브, 리액션 등의 풍부한 기능과, 다양한 커스터마이징 기능을 가진 UI를 가진 것이 특징입니다. - -## 역사 -개발 초기에는 게시판 형태의 서비스였으나, 유저가 게시한 짧은 글이 시간 순서대로 흘러가는 타임라인 기능을 추가함으로 인기를 받게 되어, 이후 이를 중심으로 개발이 진행되었습니다. 초기에는 분산형이 아니었지만, 2018년에 ActivityPub 프로토콜을 지원함으로써 분산형 SNS로 발돋움하여 널리 알려지게 되었습니다. -
ℹ️ Misskey라는 이름은 syuilo가 당시 듣고 있던 May'n의 노래, Brain Diver의 가사에서 유래했습니다.
- -누구나 개발에 참가할 수 있으며, 현재도 활발한 개발이 이루어지고 있습니다. - -## 분산형이 뭐예요? - -분산형(distributed), 또는 탈중앙화(decentralized) 서비스의 특징은, 다양한 커뮤니티에 흩어져 있는 유저들이 서로 교류(연합, federation)하여 서로의 정보를 주고 받는 네트워크(연합우주, Fediverse)를 이루는 것입니다. 이에 대비되어 서버가 하나밖에 없거나, 여러 서버가 있더라도 독립되어 있는 경우는 중앙집권 서비스라고 하여, Twitter나 Facebook 등이 이에 속합니다. 분산형 서비스의 장점은 자신에게 맞는 운영자나 테마를 자유롭게 선택할 수 있는 것입니다. 직접 서버를 운영할 수도 있습니다. 다양한 서버가 연합한다는 특성으로, 어떤 서버를 고르더라도 같은 커뮤니티에 접근할 수 있습니다. - -## 常にオープンソース -Misskeyはこれまでもこれからも、オープンソースであり続けます。オープンソースとは、簡単に言うとソフトウェアのソースコード(プログラム)が公開されていることです。ソースコードの修正や再配布が可能であることを定義に含めることもあります。 Misskeyのすべてのソースコードは[AGPL](https://github.com/misskey-dev/misskey/blob/develop/LICENSE)というオープンソースライセンスの下に[公開](https://github.com/misskey-dev)されていて、誰でも自由に閲覧、使用、修正、改変、再配布をすることができます。 オープンソースは、自分で好きなように変えたり、有害な処理が含まれていないことを確認することができたり、誰でも開発に参加できるなどの、様々なメリットがあります。 上述の分散型を実現するためにも、オープンソースであるということは必要不可欠な要素です。 再び引き合いに出しますが、TwitterやFacebookなどの利益を得ているほとんどのサービスはオープンソースではありません。 - -
ℹ️ 技術的に言うと、MisskeyのソースコードはGitで管理されていて、リポジトリはGitHub上でホスティングされています。
- -## 開発に参加する、プロジェクトを支援する -Misskeyを気に入っていただけたら、ぜひプロジェクトを支援してください。プロジェクトに貢献するには、以下で紹介するようにいろいろな方法があります。方法によっては開発のスキルは不要なので、誰でも気軽に参加し貢献することができます。いつでもお待ちしています。 - -### 機能を追加したり、バグを修正する -ソフトウェアエンジニアのスキルをお持ちの方であれば、ソースコードを編集する形でプロジェクトに貢献することができます。 貢献についてのガイドは[こちら](https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md)です。 - -### 議論に参加する -新しい機能、または既存の機能について意見を述べたり、不具合を報告したりすることでも貢献できます。 そのようなディスカッションは[GitHub](https://github.com/misskey-dev)上か、[フォーラム](https://forum.misskey.io/)等で行われます。 - -### テキストを翻訳する -Misskeyは様々な言語に対応しています(i18n -internationalizationの略- と呼ばれます)。元の言語は基本的に日本語ですが、有志によって他の言語へと翻訳されています。 その翻訳作業に加わっていただくことでもMisskeyに貢献できます。 Misskeyは[Crowdinというサービスを使用して翻訳の管理を行っています。](https://crowdin.com/project/misskey) - -### 感想を投稿する -不具合報告等だけではなく、Misskeyの良い点、楽しい点といったポジティブな意見もぜひ共有してください。開発の励みになり、それは間接的ですがプロジェクトへの貢献です。 - -### ミスキストを増やす -ミスキストとは、Misskeyを使用する人のことです。 知り合いに紹介するなどしてMisskeyを広めていただければ、ミスキストが増え開発のモチベーションが上がります。 - -### 寄付をする -Misskeyはビジネスではなく、利用は無料であるため、収益は皆様からの寄付のみです。(インスタンスによっては広告収入を得ているような場合もありますが、それは運営者の収入であり直接開発者への収入にはなりません) 寄付をしていただければ、今後も開発を続けることが可能になり、プロジェクトへの貢献になります。 寄付は基本的には[Patreon](https://www.patreon.com/syuilo)で受け付けています。 一定額寄付していただけると、Misskeyの[情報ページ](/about-misskey)に名前を記載することができます。 - -また、サーバーの運営者も、基本的には収益を得ていません。サーバーの運営にはコストがかかるので、運営者の支援をすることもご検討ください。 開発には直接関係しませんが、サーバーがあってこそのプロジェクトなので、運営が維持されるというのは開発と同じくらい重要なことです。 - -## クレジット -Misskeyの開発者や、Misskeyに寄付をしてくださった方の一覧は[こちら](/about-misskey)で見ることができます。 - -## 자주 묻는 질문 -### プロジェクトは何を目指していますか? -強いて言うと、漠然的になりますが広く使われる汎用的なプラットフォームになることを目指しています。 Misskeyは他のプロジェクトとは違い、何らかの思想(例えば、反中央集権)やビジョンに基づいて開発が行われているわけではなく、その点ではフラットです。 それが逆に、特定の方向性に縛られないフレキシブルさを生み出すことに繋がっていると感じています。 - - -### 企業によって開発されていますか? -いいえ。Misskeyの開発は個人で行われており、商業的でもないため、特定の企業の関りはありません。 開発メンバーも基本的にはボランティアです。 また、開発に対し企業のスポンサーがつくこともありますが、その場合でもやはり開発は個人のコミュニティが主体です。 - -### 誰が運営していますか? -Misskeyは分散型なため、各サーバーにそれぞれ異なった運営者がいます。従って、特定の個人や企業によって、Misskeyの全てが運営されているわけではありません。 また、開発チームが運営を行うわけでもないため、運営に関する連絡は、お使いのサーバーの運営者に行ってください。 サーバーの運営者は、[このページ](/about)で確認することができます。 あなたがサーバーを作成すれば、あなたが運営者になります。 - -### どのサーバーを選べばいいですか? -[サーバー一覧が公開されています。](https://join.misskey.page/ja-JP/instances) サーバーによってコミュニティのテーマ(特定のこと、ものが好き 等)が決められている場合があるので、自分に合ったテーマのサーバーがあれば、そこを選ぶと良いかもしれません。 他にも、サーバーの規模、ユーザー層、国および言語、運営者が信頼できるかどうか、などの観点があります。 なお、Misskey公式のサーバーというものはありません。自身で新しくサーバーを作成するという選択肢もあります。 - -基本的にどのサーバーを選んだとしても、他の全てのサーバーのユーザーと繋がることができます。 - -### サーバーを建てるにはどうしたらいいですか? -Misskeyサーバーの作成に興味を持っていただきありがとうございます。 2021年現在、Misskeyのホスティングサービスは存在しないため、サーバーの作成にはある程度の知識が必要です。 サーバーの作成方法については[こちら](todo)をご覧ください。 - -### どのような技術を使用していますか? -Misskeyは開発が進むにつれ使用する技術も大きく変わってきました。開発当初はMySQL + PHP + jQueryといった構成でしたが、現在は以下のようになっています。 -- サーバーサイド: Node.js -- データベース: PostgreSQL、Redis -- UIフレームワーク: Vue.js -- プログラミング言語: TypeScript - -また、MFMやAiScriptなどの、Misskeyから派生して独自の技術も開発しています。 - -### Mastodonのフォークですか? -いいえ。MisskeyはMastodonやその他のプロジェクトとは全く別のプロジェクトです。 開発に関しても、Misskeyの方が昔から開発されています。ただし、分散型になったのはMastodonの登場より後です。 同じActivityPubという分散のためのプロトコルを実装しているという点以外、両者に特に関りがあるわけでもありません。 - -### iOS/Android용 어플리케이션이 있나요? -공식 어플리케이션은 없지만, 비공식 서드파티 어플리케이션을 사용하실 수 있습니다. 자세한 사항은 [여기를](./apps) 참조해 주세요. - -단, 비공식 어플리케이션의 경우 최신 기능을 사용할 수 있기까지 시간이 걸릴 수 있으므로, 대부분의 경우 공식 Web 클라이언트를 사용하시는 것을 추천드립니다. 또한, Misskey의 Web 클라이언트는 PWA를 지원하여, 브라우저에서 지원하는 경우 네이티브 앱처럼 사용할 수 있습니다. 자세한 사항은 [여기를](todo) 참조해 주세요. - -### Misskeyのロゴ、アイコンはどこで入手できますか? -(準備中) - -### 時折目にする猫耳の可愛い女の子は? -Misskeyの守り神、藍ちゃんです。アイチャンカワイイヤッター! -
ℹ️ 藍ちゃんについてはこちらです。
diff --git a/src/docs/ko-KR/general/report-issue.md b/src/docs/ko-KR/general/report-issue.md deleted file mode 100644 index 63527e32a..000000000 --- a/src/docs/ko-KR/general/report-issue.md +++ /dev/null @@ -1,8 +0,0 @@ -# 不具合の報告 -不具合と思われる状況に遭遇したときは、まず[トラブルシューティング](./troubleshooting)をご一読ください。 それでも問題が解決しないときは、以下の情報を含めて[フォーラム](https://forum.misskey.io/)に投稿してください。 投稿することで、解決策が見つかったり、不具合と判断されれば開発チームによって修正が行われます。 - -## 含める情報 -- Misskeyのバージョン([情報ページ](/about)で確認できます) -- お使いのブラウザの種類とバージョン -- お使いのOSの種類とバージョン -- 問題の再現手順 diff --git a/src/docs/ko-KR/general/troubleshooting.md b/src/docs/ko-KR/general/troubleshooting.md deleted file mode 100644 index aac96a981..000000000 --- a/src/docs/ko-KR/general/troubleshooting.md +++ /dev/null @@ -1,40 +0,0 @@ -# 문제 해결 -
ℹ️ よくある質問も合わせてお役立てください。
- -問題が発生したときは、まずこちらをご確認ください。 該当する項目が無い、もしくは手順を試しても効果がない場合は、サーバーの管理者に連絡するか[不具合を報告](./report-issue)してください。 - -## クライアントが起動しない -ほとんどの場合、お使いのブラウザまたはOSのバージョンが古いことが原因です。 ブラウザおよびOSのバージョンを最新のものに更新してから、再度試してみてください。 - -これは稀ですが、それでも起動しない場合は、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。 - -## ページが読み込めない -クライアントが起動するもののページが読み込めないというエラーが出る場合は、ネットワークに問題がないか確認してください。また、サーバーがダウンしていないか確認してください。 - -これは稀ですが、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。 - -まだ問題がある場合は、サーバーの問題と思われるのでサーバーの管理者に連絡してください。 - -## クライアントの動作が遅い -以下を試してみてください: - -- クライアント設定で「UIのアニメーションを減らす」を有効にする -- クライアント設定で「モーダルにぼかし効果を使用」を無効にする -- お使いのブラウザの設定でハードウェアアクセラレーションを有効にする -- お使いのデバイスのスペックを上げる - -## UIの一部の表示がおかしい(背景が透明になっている等) -アップデートによりUIの改修が行われたときに、テーマのキャッシュシステムの影響でそのような表示になることがあります。 クライアントの設定の「キャッシュをクリア」すると直ります。 -
⚠️ 「クライアントの」キャッシュクリアです。「ブラウザの」キャッシュクリアは行わないでください。
- -## 通知やアンテナ等の点滅が消えない -点滅は、未読のコンテンツがあることを示しています。通常点滅が消えない場合は、コンテンツを遡ると未読なコンテンツが残っています。 すべて既読にしたと思われるのに、それでもなお点滅が続く場合(おそらく不具合と思われます)は設定から強制的にすべて既読扱いにすることができます。 - -## Renoteができない -フォロワー限定のノートはRenoteすることはできません。 - -## UI上で特定の要素が表示されない -広告ブロッカーを使用しているとそのような不具合が発生することがあります。Misskeyではオフにしてご利用ください。 - -## UI上で未翻訳の部分がある -ほとんどの場合、単に翻訳が間に合っていないだけで、不具合ではありません。翻訳が終わるまでお待ちください。 [翻訳に参加](./misskey)していただくことも可能です。 diff --git a/src/docs/ko-KR/keyboard-shortcut.md b/src/docs/ko-KR/keyboard-shortcut.md deleted file mode 100644 index acc5daf87..000000000 --- a/src/docs/ko-KR/keyboard-shortcut.md +++ /dev/null @@ -1,68 +0,0 @@ -# 키보드 단축키 - -## 글로벌 -아래 단축키는 어디서든 사용할 수 있습니다. - - - - - - - - - - - -
단축키동작
P, N새 노트 작성Post, New, Note
T타임라인에서 가장 최근에 올라온 노트로 이동Timeline, Top
Shift + N알림 표시/숨기기Notifications
S검색Search
H, ?도움말 표시Help
- -## 노트를 선택한 상태 - - - - - - - - - - - - - - - - - - - -
단축키동작
, K, Shift + Tab위쪽 노트로 이동-
, J, Tab아래쪽 노트로 이동-
R답글창 열기Reply
Q인용창 열기Quote
Ctrl + Q즉시 Renote 하기(창을 열지 않음)-
E, A, +리액션 창 열기Emote, reAction
0~9숫자에 대응하는 리액션(대응에 대해서는 후술)-
F, B즐겨찾기에 등록Favorite, Bookmark
Del, Ctrl + D노트 삭제Delete
M, O노트 추가 메뉴 열기More, Other
SCW로 가려진 부분을 표시 또는 가리기Show, See
Esc노트 선택을 해제-
- -## Renote 창 - - - - - - - - - - -
단축키동작
EnterRenote 하기-
Q창 펼치기Quote
Esc창 닫기-
- -## 리액션 창 -기본으로 「👍」가 선택되어 있습니다. - - - - - - - - - - - - - -
단축키동작
, K위쪽 리액션으로 이동-
, J아래쪽 리액션으로 이동-
, H, Shift + Tab왼쪽 리액션으로 이동-
, L, Tab오른쪽 리액션으로 이동-
Enter, Space, +리액션 확정-
0~9숫자에 대응하는 리액션으로 확정-
Esc리액션 그만두기-
diff --git a/src/docs/ko-KR/mfm.md b/src/docs/ko-KR/mfm.md deleted file mode 100644 index c9e8a5a4d..000000000 --- a/src/docs/ko-KR/mfm.md +++ /dev/null @@ -1,2 +0,0 @@ -# MFM -MFM은 Misskey Flavored Markdown의 약자로, Misskey의 다양한 장소에서 사용할 수 있는 전용 마크업 언어입니다. MFM로 사용 가능한 구문은 [MFM 치트 시트](/mfm-cheat-sheet)에서 확인할 수 있습니다. diff --git a/src/docs/ko-KR/mute.md b/src/docs/ko-KR/mute.md deleted file mode 100644 index 74a3485d3..000000000 --- a/src/docs/ko-KR/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# 뮤트 - -유저를 뮤트하면, 해당 유저에 대해서 다음 콘텐츠가 Misskey에 표시되지 않습니다: - -* 타임라인이나 노트 검색 결과에서 해당 유저의 노트(및 해당 노트의 답글이나 Renote) -* 해당 유저가 보내는 알림 -* 다이렉트 노트 기록에서의 해당 유저가 보낸 다이렉트 메시지 기록 - -유저를 뮤트하려면, 해당 유저의 유저 페이지에 표시되어 있는 뮤트 버튼을 누릅니다. - -자신이 뮤트한 것은 상대방에게 알려지지 않으며, 뮤트되어 있다는 것을 알 수 없습니다. - -설정 > 뮤트에서 현재 뮤트하고 있는 유저 목록을 확인할 수 있습니다. diff --git a/src/docs/ko-KR/pages.md b/src/docs/ko-KR/pages.md deleted file mode 100644 index 6b6d09c49..000000000 --- a/src/docs/ko-KR/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# 페이지 - -## 변수 -변수를 사용하여 동적 페이지를 생성할 수 있습니다. 텍스트 내에서 { 변수명 }을 쓰면 해당 위치에 변수의 값을 설정할 수 있습니다. 예를 들면 Hello { thing } world! 라는 텍스트에서 변수(things)의 값이 ai였을 경우, 텍스트는 Hello ai world!가 됩니다. - -변수의 평가(값을 산출하는 것)는 위에서 아래로 이루어지기 때문에, 어떤 변수든 자신보다 아래에 있는 변수를 참조할 수 없습니다. 예를 들어, 위에서 A, B, C라는 3가지 변수를 정의했을 때, C에서 AB를 참조할 수는 있지만, A에서 BC를 참조할 수는 없습니다. - -사용자의 입력을 받기 위해서는, 페이지에 「유저 입력」 블럭을 설치하고, 「변수명」에 입력을 저장하려는 변수 이름을 설정합니다(변수는 자동으로 생성됩니다). 이 변수를 이용해, 사용자가 입력한 내용에 대응하는 동작을 실행할 수 있습니다. - -함수를 사용하면 값 산출 처리를 다시 사용 가능한 형태로 정리할 수 있습니다. 함수를 만들려면, 「함수」 유형의 변수를 만듭니다. 함수에는 슬롯(인수)을 설정할 수 있으며, 슬롯 값은 함수 내에서 변수로 이용할 수 있습니다. 또한, 함수의 인수를 취하는 함수(고계함수라 불립니다)도 존재합니다. 함수는 미리 정의해 두는 것 외에, 이러한 고계함수의 슬롯에 직접 설정할 수도 있습니다. diff --git a/src/docs/ko-KR/reaction.md b/src/docs/ko-KR/reaction.md deleted file mode 100644 index 7c4e15625..000000000 --- a/src/docs/ko-KR/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# 리액션 -다른 사람의 노트에 이모지를 붙여 간단하게 자신의 반응을 전달할 수 있는 기능입니다. 리액션 하려면, 노트의 + 아이콘을 클릭해서 선택기를 열고, 이모지를 선택합니다. 리액션에는 [커스텀 이모지](./custom-emoji)도 사용할 수 있습니다. - -## 리액션 선택기의 사용자화 -선택기에 표시되는 이모지를 취향에 맞게 커스텀할 수 있습니다. 설정의 「리액션」에서 설정할 수 있습니다. - -## 리모트 인스턴스에서의 리액션에 대해서 -리액션은 Misskey의 자체 기능이기 때문에, 리모트 인스턴스가 Misskey가 아니면 「Like」로 액티비티가 전송됩니다. 일반적으로 Like는 「마음에 들어요」 정도의 의미를 가지고 있는 것 같습니다. 또, 상대방이 Misskey를 이용하고 있었다고 해도, 커스텀 이모지는 전달되지 않고 자동으로 「👍」 등으로 보여집니다. - -## 리모트 인스턴스로부터의 리액션에 대해서 -리모트 인스턴스에서 「Like」 액티비티를 수신했다면, Misskey에서는 「👍」로 표시됩니다. diff --git a/src/docs/ko-KR/reversi-bot.md b/src/docs/ko-KR/reversi-bot.md deleted file mode 100644 index 77d33b957..000000000 --- a/src/docs/ko-KR/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# Misskey 리버시 봇 개발 -Misskey의 리버시 기능을 지원하는 봇의 개발 방법을 소개합니다. - -1. `games/reversi` 스트림에 다음 매개변수를 붙여 접속합니다: - * `i`: 봇 계정의 API 키 - -2. 대국 초대가 오면 스트림에서 `invited` 이벤트가 발생합니다 - * 이벤트 내용에 `parent`라는 이름으로 대국 신청을 한 유저의 정보가 포함되어 있습니다 - -3. `games/reversi/match`에 `user_id`로 `parent`의 `id`가 포함된 요청을 전송합니다 - -4. 문제가 없으면 게임 정보가 반환되므로, `games/reversi-game` 스트림에 아래의 매개변수를 붙여 접속합니다: - * `i`: 봇 계정의 API 키 - * `game`: `game`의 `id` - -5. 상대방이 게임의 설정을 변경할 때 마다 `update-settings` 이벤트가 발생하므로, 필요에 따라 별도의 처리 과정을 진행할 수 있습니다 - -6. 설정에 동의하면 `{ type: 'accept' }` 메시지를 스트림으로 전달합니다 - -7. 게임이 시작되면 `started` 이벤트가 발생합니다 - * 이벤트 내용에는 게임 정보가 포함됩니다 - -8. 돌을 치려면, 스트림에 `{ type: 'set', pos: <위치> }`를 전달합니다(위치 계산 방법은 후술) - -9. 상대방 또는 자신이 돌을 치면 스트림에서 `set` 이벤트가 발생합니다 - * `color` 에는 돌의 색상이 포함되어 있음 - * `pos` 에는 위치 정보가 포함되어 있음 - -## 위치 계산 방법 -8x8 크기의 맵을 생각할 경우, 각 칸의 위치(인덱스라고 부릅니다)는 다음과 같습니다: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### X,Y 좌표를 인덱스로 변환 -``` -pos = x + (y * mapWidth) -``` -`mapWidth`는 게임 정보의 `map`에서 다음과 같이 계산할 수 있습니다: -``` -mapWidth = map[0].length -``` - -### 인덱스에서 X,Y 좌표로 변환 -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## 맵 정보 -맵 정보는 게임 정보의 `map`에 들어있습니다. 문자열이 배열되어 있어서 각 글자가 칸 정보를 나타냅니다. 이것을 바탕으로 맵의 디자인을 알 수 있습니다: -* `(공간)` ... 칸 없음 -* `-` ... 칸 -* `b` ... 처음 배치되는 흑돌 -* `w` ... 처음 배치되는 백돌 - -예를 들어, 4*4 와 같은 단순한 맵이 있다고 가정합니다: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -이 경우, 맵 데이터는 아래와 같습니다: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## 사용자에게 폼을 제시하여 소통할 수 있는 봇 제작 -사용자와 소통을 위해, 게임 설정 화면을 통해서 사용자에게 폼을 제시할 수 있습니다. 예를 들어, 봇의 난이도를 사용자가 설정할 수 있도록 하는 등의 구현이 가능합니다. - -폼을 제시하려면, `reversi-game` 스트림으로 다음 메시지를 전송합니다: -```javascript -{ - type: 'init-form', - body: [폼 제어 배열] -} -``` - -폼 제어 배열에 대해서는 지금부터 설명하겠습니다. 폼 제어는 다음과 같은 개체입니다: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... 제어 ID. `type` ... 제어 종류. 후술합니다. `label` ... 제어와 함께 표시할 텍스트. `value` ... 제어 기본값. - -### 폼 조작값 받기 -사용자가 폼을 조작하면, 스트림에서 `update-form` 이벤트가 발생합니다. 이벤트의 내용에는 제어 ID와 사용자가 설정한 값이 포함되어 있습니다. 예를 들어, 위에서 나타낸 스위치를 사용자가 켰다면, 다음 이벤트가 발생합니다: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### 폼 제어 종류 -#### 스위치 -type: `switch` 스위치를 표시합니다. 어떠한 기능을 켜거나 끄고 싶은 경우에 사용합니다. - -##### 속성 -`label` ... 스위치에 표시되는 텍스트. - -#### 라디오 버튼 -type: `radio` 라디오 버튼을 표시합니다. 선택지를 표시할 때 사용할 수 있습니다. 예를 들면, 봇의 난이도를 설정하는 등에 사용됩니다. - -##### 속성 -`items` ... 라디오 버튼 선택지. 예: -```javascript -items: [{ - label: '약', - value: 1 -}, { - label: '중', - value: 2 -}, { - label: '강', - value: 3 -}] -``` - -#### 슬라이더 -type: `slider` 슬라이더를 표시합니다. - -##### 속성 -`min` ... 슬라이더의 최소값. `max` ... 슬라이더의 최대값. `step` ... 입력란에 기입되는 스텝 값. - -#### 텍스트 상자 -type: `textbox` 텍스트 상자를 표시합니다. 사용자에게 어떠한 것을 입력하도록 하는 일반적인 용도로 사용할 수 있습니다. - -## 사용자에게 메시지 표시하기 -설정 화면에서 사용자와 대화하는 것 이외에, 또 다른 방법입니다. 사용자에게 메시지를 표시할 수 있습니다. 예를 들어, 사용자가 봇이 지원하지 않는 모드나 지도를 선택했을 때, 경고를 표시하는 등으로 사용됩니다. 메시지를 표시하려면, 다음 메시지를 스트림으로 전송합니다: -```javascript -{ - type: 'message', - body: { - text: '메시지 내용', - type: '메시지 종류' - } -} -``` -메시지 종류: `success`, `info`, `warning`, `error`。 - -## 거두기 -거두기를 하려면, 이 엔드포인트에 요청합니다. diff --git a/src/docs/ko-KR/stream.md b/src/docs/ko-KR/stream.md deleted file mode 100644 index b32176494..000000000 --- a/src/docs/ko-KR/stream.md +++ /dev/null @@ -1,354 +0,0 @@ -# 스트리밍 API - -스트리밍 API를 사용하면, 실시간으로 다양한 정보(예를 들어 타임라인에 새로운 노트가 올라왔다거나, 메시지가 도착했다거나 팔로우 되었다거나 등)를 받거나, 다양한 작업을 할 수 있습니다. - -## 스트림에 접속하기 - -스트리밍 API를 이용하려면, 먼저 Misskey 서버에 **websocket** 접속이 필요합니다. - -아래 URL에, `i` 라고 하는 매개변수명으로 인증 정보를 포함해서, websocket에 접속해주세요. 예: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -인증 정보는 자신의 API 키나 애플리케이션에서 스트림에 접속할 때, 사용자의 접속 토큰을 뜻합니다. - -
-

인증 정보 발급에 대해서는, 해당 문서를 참고해 주세요.

-
- ---- - -인증 정보는 생략할 수 있지만, 이렇게 하면 게스트로 작동하기 때문에, 수신할 수 있는 정보나 조작이 한정됩니다. 예: - -``` -%WS_URL%/streaming -``` - ---- - -스트림에 접속하면, 뒤에서 서술하는 API 조작 및 노트 구독을 할 수 있습니다. 그러나 아직 이 단계에서는, 타임라인에 새로운 노트를 확인하는 등의 행동을 할 수 없습니다. 이것을 하기 위해서는, 스트림 상에서 후술하는 **채널**에 접속할 필요가 있습니다. - -**스트림에서 주고 받는 정보는 모두 JSON 입니다.** - -## 채널 -Misskey의 스트리밍 API에는 채널이라는 개념이 있습니다. 이것은 송수신하는 정보를 분리하기 위한 구조입니다. Misskey의 스트림 연결만으로는, 아직 실시간으로 타임라인의 노트를 수신할 수 없습니다. 스트림 상에서 채널에 접속함으로써, 다양한 정보를 받거나 보낼 수 있게 됩니다. - -### 채널에 접속하기 -채널에 접속하려면, 다음 데이터를 JSON으로 스트림에 전송합니다: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -여기서, -* `channel`에는 접속하고자 하는 채널명을 입력합니다. 채널의 종류에 대해서는 후술하겠습니다. -* `id`에는 해당 채널과 주고받기 위한 임의의 ID를 입력합니다. 스트림에서는 다양한 메시지가 나오기 때문에, 그 메시지가 어떤 채널에서 나오는 것인지 식별할 수 있어야 합니다. ID는 UUID나 난수 같은 것이면 됩니다. -* `params`는 채널에 접속할 때의 매개변수입니다. 채널에 따라서 접속 시 필요한 매개변수는 다릅니다. 매개변수가 필요없는 채널에 접속할 때는, 이 속성은 생략할 수 있습니다. - -
-

ID는 채널별로 설정하는 것이 아니라, 「채널에 접속하는 스트림마다」 설정해야 합니다. 왜냐하면, 같은 채널에 다른 매개변수로 다중 접속하는 경우도 존재하기 때문입니다.

-
- -### 채널에서 메시지 수신하기 -예를 들어, 타임라인 채널이라면. 새로운 노트가 올라왔을 때 메시지를 보냅니다. 메시지를 받음으로써, 타임라인에 새로운 노트가 올라온 것을 실시간으로 알 수 있습니다. - -채널에서 메시지를 보내면, 다음 데이터가 JSON에서 스트림으로 전달됩니다: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -여기서, -* `id`에는 앞서 말한 채널에 접속할 때 설정한 ID를 입력합니다. 이제 이 메시지가 어느 채널에서 온 것인지 알 수 있습니다. -* `type`에는 메시지의 종류를 입력합니다. 채널에 따라 어떤 종류의 메시지가 나오는지가 달라집니다. -* `body`에는 메시지 내용을 입력합니다. 채널에 따라, 어떤 내용의 메시지가 나오는지가 달라집니다. - -### 채널에 메시지 보내기 -채널에 따라서는, 메시지를 받을 뿐만 아니라, 반대로 메시지를 발송해서 특정한 동작을 실행할 수도 있습니다. - -채널에 메시지를 보내려면, 다음 데이터를 JSON으로 스트림에 보냅니다: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -여기서, -* `id`에는 앞서 말한 채널에 접속할 때 설정한 ID를 입력합니다. 이제 이 메시지가 어느 채널로 갈 것인지 알 수 있습니다. -* `type`에는 메시지 종류를 입력합니다. 채널에 따라 어떤 종류의 메시지를 수신할지는 다릅니다. -* `body`에는 메시지 내용을 입력합니다. 채널에 따라, 어떤 내용의 메시지를 수신할지가 달라집니다. - -### 채널 접속 끊기 -채널 접속을 끊으려면, 다음 데이터를 JSON으로 스트림에 전송합니다: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -여기서, -* `id`에는 앞서 말한 채널에 접속할 때 설정한 ID를 입력합니다. - -## 스트림을 경유하여 API 요청하기 - -스트림을 통해 API를 요청하면, HTTP 요청을 발생시키지 않고 API를 이용할 수 있습니다. 이렇게 하면, 코드를 간결하게 만들거나, 성능을 향상시킬 수 있을지도 모릅니다. - -스트림을 통해 API를 요청하려면, 다음 데이터를 JSON으로 스트림에 전송합니다: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -여기서, -* `id`에는 API의 응답을 식별할 수 있는 API 요청별 핵심 ID를 입력해야 합니다. UUID나 간단한 난수 같은 것으로 설정해도 됩니다. -* `endpoint`에는 내가 요청하려는 API의 엔드포인트를 입력합니다. -* `data`에는 엔드포인트의 매개변수를 입력합니다. - -
-

API의 엔드포인트 및 매개변수는 API 레퍼런스를 확인하시기 바랍니다.

-
- -### 응답 수신 - -API로 요청하면, 응답이 스트림에서 다음 형식으로 전달됩니다. - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -여기서, -* `xxxxxxxxxxxxxxxx` 부분에는, 요청 시 설정된 `id`가 포함되어 있습니다. 이를 통해, 어떤 요청에 대한 응답인지 판별할 수 있습니다. -* `body`에는 응답이 포함되어 있습니다. - -## 노트 캡처 - -Misskey는 게시한 노트를 캡처할 수 있는 시스템을 제공하고 있습니다. 이것은 지정한 노트의 이벤트를 스트림으로 받을 수 있는 기능입니다. - -예를 들어, 타임라인을 불러와 유저에게 표시했습니다. 여기서 누군가가 그 타임라인에 포함된 어떤 노트에 대해서 리액션을 했다고 가정합니다. - -그러나, 클라이언트가 보기에 어떤 글에 리액션이 붙었는지 등은 알 수가 없기 때문에, 실시간으로 리액션을 타임라인 상의 노트에 반영해서 표시하는 것은 불가능합니다. - -이 문제를 해결하기 위해, Misskey는 게시 캡처 도구를 제공하고 있습니다. 노트를 캡처하면, 해당 노트에 대한 이벤트를 받을 수 있기 때문에, 실시간으로 리액션을 반영할 수 있습니다. - -### 노트 게시 캡처 - -노트를 캡처하려면, 스트림에 다음 메시지를 발송합니다: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -여기서, -* `id`에 캡처하려는 노트의 `id`를 입력합니다. - -이 메시지를 발송하면, Misskey에 캡처를 요청하게 되고, 이후, 해당 노트에 대한 이벤트를 불러오게 됩니다. - -예를 들면, 노트에 리액션이 붙었을 때 다음과 같은 메시지를 받습니다: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -여기서, -* `body`내에 `id`에는 이벤트를 발생시킨 노트의 ID가 포함됩니다. -* `body`내에 `type`에는 이벤트 종류가 포함됩니다. -* `body`내에 `body`에는 이벤트의 상세 내용이 포함됩니다. - -#### 이벤트의 종류 - -##### `reacted` -해당 노트에 리액션이 올라갔을 때 발생합니다. - -* `reaction`에 리액션 종류가 포함됩니다. -* `userId`에 리액션을 한 유저의 ID가 포함됩니다. - -예: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -해당 노트가 삭제되었을 때 발생합니다. - -* `deletedAt`에 삭제한 날짜가 포함됩니다. - -예: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -해당 노트에 첨부된 투표에 투표했을 때 발생합니다. - -* `choice`에 선택 항목의 ID가 포함됩니다. -* `userId`에 투표한 유저의 ID가 포함됩니다. - -예: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### 노트 캡처 해제 - -노트가 더 이상 화면에 표시되지 않는 등의 이유로, 해당 노트에 대한 이벤트를 받을 필요가 없을 때는, 캡처 해제를 진행해 주세요. - -아래 메시지를 보냅니다: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -여기서, -* `id`에 캡처를 해제하고자 하는 노트의 `id`를 입력합니다. - -이 메시지를 보내면, 더 이상 해당 노트에 대한 이벤트는 발생하지 않습니다. - -# 채널 목록 -## `main` -계정에 대한 기본적인 정보를 표시됩니다. 이 채널에 대응하는 매개변수는 없습니다. - -### 발생하는 이벤트 목록 - -#### `renote` -내 노트가 Renote 되었을 때 발생하는 이벤트입니다. 내가 올린 노트를 Renote 했을 때는 발생하지 않습니다. - -#### `mention` -다른 사람이 나를 멘션 했을 때 발생하는 이벤트입니다. - -#### `readAllNotifications` -나에게 온 알림을 모두 읽었음을 나타내는 이벤트입니다. 이 이벤트를 이용해, 「알림이 있음을 나타내는 아이콘」과 같은 것을 끄는 등의 활용이 가능합니다. - -#### `meUpdated` -내 정보가 업데이트 되었음을 나타내는 이벤트입니다. - -#### `follow` -내가 누군가를 팔로우 했을 때 발생하는 이벤트입니다. - -#### `unfollow` -내가 누군가를 언팔로우 했을 때 발생하는 이벤트입니다. - -#### `followed` -다른 사람이 나를 팔로우 했을 때 발생하는 이벤트입니다. - -## `homeTimeline` -홈 타임라인에 게시된 정보가 표시됩니다. 이 채널에 대응하는 매개변수는 없습니다. - -### 발생하는 이벤트 목록 - -#### `note` -타임라인에 새로운 노트가 올라왔을 때 발생하는 이벤트입니다. - -## `localTimeline` -로컬 타임라인에 게시된 정보가 표시됩니다. 이 채널에 대응하는 매개변수는 없습니다. - -### 발생하는 이벤트 목록 - -#### `note` -로컬 타임라인에 새로운 노트가 올라왔을 때 발생하는 이벤트입니다. - -## `hybridTimeline` -소셜 타임라인에 게시된 정보가 표시됩니다. 이 채널에 대응하는 매개변수는 없습니다. - -### 발생하는 이벤트 목록 - -#### `note` -소셜 타임라인에 새로운 노트가 올라왔을 때 발생하는 이벤트입니다. - -## `globalTimeline` -글로벌 타임라인에 게시된 정보가 표시됩니다. 이 채널에 대응하는 매개변수는 없습니다. - -### 발생하는 이벤트 목록 - -#### `note` -글로벌 타임라인에 새로운 노트가 올라왔을 때 발생하는 이벤트입니다. diff --git a/src/docs/ko-KR/theme.md b/src/docs/ko-KR/theme.md deleted file mode 100644 index 21ea08541..000000000 --- a/src/docs/ko-KR/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# 테마 - -테마를 설정하여 Misskey 클라이언트의 외형을 변경할 수 있습니다. - -## 테마 설정 -설정 > 테마 - -## 테마 만들기 -테마 코드는 JSON5에 기술된 테마 객체입니다. 예시는 아래와 같습니다. -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... 테마에 지정된 고유 ID. UUID 방식을 추천합니다. -* `name` ... 테마 이름 -* `author` ... 테마 제작자 -* `desc` ... 테마 설명(옵션) -* `base` ... 밝은 테마인지, 어두운 테마인지 - * `light`로 하면 밝은 테마가 되고, `dark`로 하면 어두운 테마가 됩니다. - * 테마는 여기서 상속된 베이스 테마를 기준으로 합니다. -* `props` ... 테마 스타일 정의. 이제부터 설명하겠습니다. - -### 테마 스타일 정의 -`props`에서는 테마의 스타일을 정의합니다. 키가 CSS 변수명이 되고, 값으로 내용을 지정합니다. 덧붙여, 이 `props` 객체는 베이스 테마로부터 상속됩니다. 베이스 테마는, 이 테마의 `base`가 `light`인 경우, [_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5) 이고, `dark`라면 [_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5) 입니다. 즉, 만들려는 테마의 `props`에 `panel`라는 키가 없어도 베이스 테마로부터 상속되므로, `panel`이 존재한다고 볼 수 있습니다. - -#### 값으로 사용할 수 있는 구문 -* 16진수로 표현된 색 - * 예: `#00ff00` -* `rgb(r, g, b)` 형식으로 나타낸 색 - * 예: `rgb(0, 255, 0)` -* `rgb(r, g, b, a)` 형식으로 표시된 투명도를 포함한 색상 - * 예: `rgba(0, 255, 0, 0.5)` -* 다른 키 값 참조 - * `@{키 이름}`으로 쓰면 다른 키의 값을 참조할 수 있습니다. `{키 이름}`은 참조하려는 키의 이름으로 대체합니다. - * 예: `@panel` -* 정수(후술)의 참조 - * `${정수명}`이라고 쓰면 정수를 참조합니다. `{정수명}`은 참조하려는 정수의 이름으로 대체합니다. - * 예: `$main` -* 함수(후술) - * `:{함수명}<{인수}<{색상}` - -#### 상수 -「CSS 변수로 출력하고 싶지 않지만, 다른 CSS 변수의 값을 사용」하고 싶은 값이 있을 때는, 정수를 사용하면 편리합니다. 키의 이름 앞에 `$`를 붙이면, 키가 CSS 변수로 출력되지 않습니다. - -#### 함수 -wip diff --git a/src/docs/ko-KR/timelines.md b/src/docs/ko-KR/timelines.md deleted file mode 100644 index fca5bde9a..000000000 --- a/src/docs/ko-KR/timelines.md +++ /dev/null @@ -1,15 +0,0 @@ -# 타임라인의 비교 - -https://docs.google.com/spreadsheets/d/1uNVxlN4WUPAxrR0-5uXXeoJiUb_kDTaoGT5VLYntZpg/edit?usp=sharing - -## 홈 -자신이 팔로우하고 있는 사용자의 노트 - -## 로컬 -공개 범위가 「홈」으로 지정되지 않은 모든 로컬 유저의 노트 - -## 소셜 -자신이 팔로우하고 있는 유저의 노트와, 공개 범위가 「홈」으로 지정되지 않은 모든 로컬 유저의 노트 - -## 글로벌 -공개 범위가 「홈」으로 지정되지 않은 모든 로컬 유저의 노트와, 서버에 배달된 공개 범위가 「홈」으로 지정되지 않은 모든 리모트 유저의 노트 diff --git a/src/docs/nl-NL/admin/disable-timelines.md b/src/docs/nl-NL/admin/disable-timelines.md deleted file mode 100644 index b081e35ab..000000000 --- a/src/docs/nl-NL/admin/disable-timelines.md +++ /dev/null @@ -1,8 +0,0 @@ -# LTL/STL/GTLの無効化 -Misskeyでは、LTL/STL/GTLをそれぞれ無効化することができます。有効/無効を切り替えるには、インスタンスコントロールパネルで設定します。 - -LTLやSTLは、そのインスタンス全員の投稿が見れるため、新規のユーザーにとってはユーザーを探す必要がなくなり、興味のあるユーザーを見つけやすいという利点があります。 しかし同時に、フォロー機能が活用されなくなったり、不適切な投稿が目につきやすくなったり、チャットのようになることで内輪感が生じて逆に新規ユーザーが参加しにくくなるといったデメリットも持ち合わせています。 サーバーによってメリット/デメリットどちらが優勢かは異なるので、オプションとして無効にできるようになっています。 もしデメリットの方が上回っていると感じたら、それらのタイムラインを無効化することも検討してください。 - -
⚠️ 無効化を行うと、ユーザーが困惑し、短期的に見て利用者が減る可能性があります。そのため、無効化の際は影響を慎重に検討し、事前に説明してフォローを整える期間を一定程度設けることを推奨します。
- -なお、管理者/モデレーターは、これらのタイムラインの無効化状態は適用されず、引き続き利用することが可能です。 diff --git a/src/docs/nl-NL/admin/faq.md b/src/docs/nl-NL/admin/faq.md deleted file mode 100644 index 317b4e065..000000000 --- a/src/docs/nl-NL/admin/faq.md +++ /dev/null @@ -1,5 +0,0 @@ -# よくある質問 -ここでは、サーバー管理者向けのよくある質問を掲載しています。 - -## デフォルトテーマを設定したい -現在、デフォルトテーマ設定機能は実装されていません。 diff --git a/src/docs/nl-NL/advanced/aiscript.md b/src/docs/nl-NL/advanced/aiscript.md deleted file mode 100644 index 604d17daa..000000000 --- a/src/docs/nl-NL/advanced/aiscript.md +++ /dev/null @@ -1,7 +0,0 @@ -# AiScript -AiScriptは、Misskeyで使用できるスクリプト言語です。 - -
ℹ️ AiScript実装はMisskeyとは別リポジトリで、オープンソースで公開されています。
- -## 使い方 -AiScriptの構文や組み込み関数などのドキュメントは、[こちら](https://github.com/syuilo/aiscript/tree/master/docs)で公開されています。 diff --git a/src/docs/nl-NL/advanced/api.md b/src/docs/nl-NL/advanced/api.md deleted file mode 100644 index 76019b614..000000000 --- a/src/docs/nl-NL/advanced/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス、Bot等(以下「アプリケーション」と呼びます)を開発できます。 ストリーミングAPIもあるので、リアルタイム性のあるアプリケーションを作ることも可能です。 - -APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。 - -## アクセストークンの取得 -基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。 - -* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む -* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む - -### 自分自身のアクセストークンを手動発行する -「設定 > API」で、自分のアクセストークンを発行できます。 - -[「APIの使い方」へ進む](#APIの使い方) - -### アプリケーション利用者にアクセストークンの発行をリクエストする -アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。 - -#### Step 1 - -UUIDを生成する。以後これをセッションIDと呼びます。 - -> このセッションIDは毎回生成し、使いまわさないようにしてください。 - -#### Step 2 - -`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。 -> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます: -* `name` ... アプリケーション名 - * > 例: `MissDeck` -* `icon` ... アプリケーションのアイコン画像URL - * > 例: `https://missdeck.example.com/icon.png` -* `callback` ... 認証が終わった後にリダイレクトするURL - * > 例: `https://missdeck.example.com/callback` - * リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます -* `permission` ... アプリケーションが要求する権限 - * > 例: `write:notes,write:following,read:drive` - * 要求する権限を`,`で区切って列挙します - * どのような権限があるかは[APIリファレンス](/api-doc)で確認できます - -#### Step 3 -ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。 - -レスポンスに含まれるプロパティ: -* `token` ... ユーザーのアクセストークン -* `user` ... ユーザーの情報 - -[「APIの使い方」へ進む](#APIの使い方) - -## APIの使い方 -**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。 - -* [APIリファレンス](/api-doc) -* [ストリーミングAPI](./stream) diff --git a/src/docs/nl-NL/advanced/create-plugin.md b/src/docs/nl-NL/advanced/create-plugin.md deleted file mode 100644 index 0d2fa1917..000000000 --- a/src/docs/nl-NL/advanced/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# プラグインの作成 -Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。 - -## メタデータ -プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。 - -### name -プラグイン名 - -### author -プラグイン作者 - -### version -プラグインバージョン。数値を指定してください。 - -### description -プラグインの説明 - -### permissions -プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。 - -### config -プラグインの設定情報を表すオブジェクト。 キーに設定名、値に以下のプロパティを含めます。 - -#### type -設定値の種類を表す文字列。以下から選択します。 string number boolean - -#### label -ユーザーに表示する設定名 - -#### description -設定の説明 - -#### default -設定のデフォルト値 - -## APIリファレンス -AiScript標準で組み込まれているAPIは掲載しません。 - -### Mk:dialog(title text type) -ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。 - -### Mk:confirm(title text type) -確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。 - -### Mk:api(endpoint params) -Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。 - -### Mk:save(key value) -任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。 - -### Mk:load(key) -Mk:saveで永続化した指定の名前の値を読み取ります。 - -### Plugin:register_post_form_action(title fn) -投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。 - -### Plugin:register_note_action(title fn) -ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 - -### Plugin:register_user_action(title fn) -ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。 - -### Plugin:register_note_view_interruptor(fn) -UIに表示されるノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:register_note_post_interruptor(fn) -ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:open_url(url) -第一引数に渡されたURLをブラウザの新しいタブで開きます。 - -### Plugin:config -プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。 diff --git a/src/docs/nl-NL/advanced/develop-bot.md b/src/docs/nl-NL/advanced/develop-bot.md deleted file mode 100644 index 7f825e9bc..000000000 --- a/src/docs/nl-NL/advanced/develop-bot.md +++ /dev/null @@ -1,6 +0,0 @@ -# Botの作成 -[Misskey API](./api)を利用してBotの開発が可能です。 また、いくつかのBot実装が公開されているため、ぜひ参考にしてください。 - -- [syuilo/ai](https://github.com/syuilo/ai) ... Node.js上で動く、TypeScript製Bot実装 - -Botを作成したときは、プロフィール設定からBotフラグをオンにしておくことを強くおすすめします。 diff --git a/src/docs/nl-NL/advanced/reversi-bot.md b/src/docs/nl-NL/advanced/reversi-bot.md deleted file mode 100644 index 7ab2a7212..000000000 --- a/src/docs/nl-NL/advanced/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# MisskeyリバーシBotの開発 -Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。 - -1. `games/reversi`ストリームに以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - -2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる - * イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている - -3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する - -4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - * `game`: `game`の`id` - -5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う - -6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する - -7. ゲームが開始すると、`started`イベントが流れてくる - * イベントの中身にはゲーム情報が含まれている - -8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述) - -9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる - * `color`として石の色が含まれている - * `pos`として位置情報が含まれている - -## 位置の計算法 -8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### X,Y座標 から インデックス に変換する -``` -pos = x + (y * mapWidth) -``` -`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます: -``` -mapWidth = map[0].length -``` - -### インデックス から X,Y座標 に変換する -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## マップ情報 -マップ情報は、ゲーム情報の`map`に入っています。 文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 それをもとにマップのデザインを知る事が出来ます: -* `(スペース)` ... マス無し -* `-` ... マス -* `b` ... 初期配置される黒石 -* `w` ... 初期配置される白石 - -例えば、4*4の次のような単純なマップがあるとします: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -この場合、マップデータはこのようになります: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## ユーザーにフォームを提示して対話可能Botを作成する -ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。 - -フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します: -```javascript -{ - type: 'init-form', - body: [フォームコントロールの配列] -} -``` - -フォームコントロールの配列については今から説明します。 フォームコントロールは、次のようなオブジェクトです: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... コントロールのID。 `type` ... コントロールの種類。後述します。 `label` ... コントロールと一緒に表記するテキスト。 `value` ... コントロールのデフォルト値。 - -### フォームの操作を受け取る -ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### フォームコントロールの種類 -#### スイッチ -type: `switch` スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。 - -##### プロパティ -`label` ... スイッチに表記するテキスト。 - -#### ラジオボタン -type: `radio` ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。 - -##### プロパティ -`items` ... ラジオボタンの選択肢。例: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '強', - value: 3 -}] -``` - -#### スライダー -type: `slider` スライダーを表示します。 - -##### プロパティ -`min` ... スライダーの下限。 `max` ... スライダーの上限。 `step` ... 入力欄で刻むステップ値。 - -#### テキストボックス -type: `textbox` テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。 - -## ユーザーにメッセージを表示する -設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 メッセージを表示するには、次のメッセージをストリームに送信します: -```javascript -{ - type: 'message', - body: { - text: 'メッセージ内容', - type: 'メッセージの種類' - } -} -``` -メッセージの種類: `success`, `info`, `warning`, `error`。 - -## 投了する -投了をするには、このエンドポイントにリクエストします。 diff --git a/src/docs/nl-NL/advanced/share-page.md b/src/docs/nl-NL/advanced/share-page.md deleted file mode 100644 index 4fb7ded0b..000000000 --- a/src/docs/nl-NL/advanced/share-page.md +++ /dev/null @@ -1,54 +0,0 @@ -# シェアページ -`/share`を開くと、共有用の投稿フォームを開くことができます。 ここではシェアページで利用できるクエリ文字列の一覧を示します。 - -## クエリ文字列一覧 -### 文字 - -
-
title
-
タイトルです。本文の先頭に[ … ]と挿入されます。
-
text
-
本文です。
-
url
-
URLです。末尾に挿入されます。
-
- -### リプライ情報 -以下のいずれか - -
-
replyId
-
リプライ先のノートid
-
replyUri
-
リプライ先のUrl(リモートのノートオブジェクトを指定)
-
- -### Renote情報 -以下のいずれか - -
-
renoteId
-
Renote先のノートid
-
renoteUri
-
Renote先のUrl(リモートのノートオブジェクトを指定)
-
- -### 公開範囲 -※specifiedに相当する値はvisibility=specifiedとvisibleAccts/visibleUserIdsで指定する - -
-
visibility
-
公開範囲 ['public' | 'home' | 'followers' | 'specified']
-
localOnly
-
0(false) or 1(true)
-
visibleUserIds
-
specified時のダイレクト先のユーザーid カンマ区切りで
-
visibleAccts
-
specified時のダイレクト先のacct(@?username[@host]) カンマ区切りで
-
- -### ファイル -
-
fileIds
-
添付したいファイルのid(カンマ区切りで)
-
diff --git a/src/docs/nl-NL/advanced/stream.md b/src/docs/nl-NL/advanced/stream.md deleted file mode 100644 index 0e5edd2b0..000000000 --- a/src/docs/nl-NL/advanced/stream.md +++ /dev/null @@ -1,350 +0,0 @@ -# ストリーミングAPI - -ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。 - -## ストリームに接続する - -ストリーミングAPIを利用するには、まずMisskeyサーバーに**websocket**接続する必要があります。 - -以下のURLに、`i`というパラメータ名で認証情報を含めて、websocket接続してください。例: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。 - -
ℹ️ 認証情報の取得については、こちらのドキュメントをご確認ください。
- ---- - -認証情報は省略することもできますが、その場合非ログインでの利用ということになり、受信できる情報や可能な操作は限られます。例: - -``` -%WS_URL%/streaming -``` - ---- - -ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。 - -**ストリームでのやり取りはすべてJSONです。** - -## チャンネル -MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。 - -ひとつのストリーム上で、同時に複数のチャンネルに接続することができます。 - -### チャンネルに接続する -チャンネルに接続するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -ここで、 -* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。 -* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。 -* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。 - -
ℹ️ IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。
- -### チャンネルからのメッセージを受け取る -例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。 - -チャンネルがメッセージを発すると、次のようなデータがJSONでストリームに流れてきます: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。 -* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。 -* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。 - -### チャンネルに向けてメッセージを送信する -チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。 - -チャンネルにメッセージを送信するには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。 -* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。 -* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。 - -### チャンネルから切断する -チャンネルから切断するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。 - -## ストリームを経由してAPIリクエストする - -ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。 - -ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -ここで、 -* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 -* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 -* `data`には、エンドポイントのパラメータを含めます。 - -
ℹ️ APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。
- -### レスポンスの受信 - -APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。 - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -ここで、 -* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 -* `body`には、レスポンスが含まれています。 - -## 投稿のキャプチャ - -Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。 - -例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。 - -しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。 - -この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。 - -### 投稿をキャプチャする - -投稿をキャプチャするには、ストリームに次のようなメッセージを送信します: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャしたい投稿の`id`を設定します。 - -このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 - -例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -ここで、 -* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。 -* `body`内の`type`に、イベントの種類が設定されます。 -* `body`内の`body`に、イベントの詳細が設定されます。 - -#### イベントの種類 - -##### `reacted` -その投稿にリアクションがされた時に発生します。 - -* `reaction`に、リアクションの種類が設定されます。 -* `userId`に、リアクションを行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -その投稿が削除された時に発生します。 - -* `deletedAt`に、削除日時が設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -その投稿に添付されたアンケートに投票された時に発生します。 - -* `choice`に、選択肢IDが設定されます。 -* `userId`に、投票を行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### 投稿のキャプチャを解除する - -その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。 - -次のメッセージを送信します: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャを解除したい投稿の`id`を設定します。 - -このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 - -# チャンネル一覧 -## `main` -アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `renote` -自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。 - -#### `mention` -誰かからメンションされたときに発生するイベントです。 - -#### `readAllNotifications` -自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。 - -#### `meUpdated` -自分の情報が更新されたことを表すイベントです。 - -#### `follow` -自分が誰かをフォローしたときに発生するイベントです。 - -#### `unfollow` -自分が誰かのフォローを解除したときに発生するイベントです。 - -#### `followed` -自分が誰かにフォローされたときに発生するイベントです。 - -## `homeTimeline` -ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -タイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `localTimeline` -ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `hybridTimeline` -ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ソーシャルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `globalTimeline` -グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 diff --git a/src/docs/nl-NL/aiscript.md b/src/docs/nl-NL/aiscript.md deleted file mode 100644 index 6c28b446e..000000000 --- a/src/docs/nl-NL/aiscript.md +++ /dev/null @@ -1,4 +0,0 @@ -# AiScript - -## 関数 -デフォルトで値渡しです。 diff --git a/src/docs/nl-NL/api.md b/src/docs/nl-NL/api.md deleted file mode 100644 index 76019b614..000000000 --- a/src/docs/nl-NL/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス、Bot等(以下「アプリケーション」と呼びます)を開発できます。 ストリーミングAPIもあるので、リアルタイム性のあるアプリケーションを作ることも可能です。 - -APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。 - -## アクセストークンの取得 -基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。 - -* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む -* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む - -### 自分自身のアクセストークンを手動発行する -「設定 > API」で、自分のアクセストークンを発行できます。 - -[「APIの使い方」へ進む](#APIの使い方) - -### アプリケーション利用者にアクセストークンの発行をリクエストする -アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。 - -#### Step 1 - -UUIDを生成する。以後これをセッションIDと呼びます。 - -> このセッションIDは毎回生成し、使いまわさないようにしてください。 - -#### Step 2 - -`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。 -> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます: -* `name` ... アプリケーション名 - * > 例: `MissDeck` -* `icon` ... アプリケーションのアイコン画像URL - * > 例: `https://missdeck.example.com/icon.png` -* `callback` ... 認証が終わった後にリダイレクトするURL - * > 例: `https://missdeck.example.com/callback` - * リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます -* `permission` ... アプリケーションが要求する権限 - * > 例: `write:notes,write:following,read:drive` - * 要求する権限を`,`で区切って列挙します - * どのような権限があるかは[APIリファレンス](/api-doc)で確認できます - -#### Step 3 -ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。 - -レスポンスに含まれるプロパティ: -* `token` ... ユーザーのアクセストークン -* `user` ... ユーザーの情報 - -[「APIの使い方」へ進む](#APIの使い方) - -## APIの使い方 -**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。 - -* [APIリファレンス](/api-doc) -* [ストリーミングAPI](./stream) diff --git a/src/docs/nl-NL/create-plugin.md b/src/docs/nl-NL/create-plugin.md deleted file mode 100644 index 0d2fa1917..000000000 --- a/src/docs/nl-NL/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# プラグインの作成 -Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。 - -## メタデータ -プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。 - -### name -プラグイン名 - -### author -プラグイン作者 - -### version -プラグインバージョン。数値を指定してください。 - -### description -プラグインの説明 - -### permissions -プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。 - -### config -プラグインの設定情報を表すオブジェクト。 キーに設定名、値に以下のプロパティを含めます。 - -#### type -設定値の種類を表す文字列。以下から選択します。 string number boolean - -#### label -ユーザーに表示する設定名 - -#### description -設定の説明 - -#### default -設定のデフォルト値 - -## APIリファレンス -AiScript標準で組み込まれているAPIは掲載しません。 - -### Mk:dialog(title text type) -ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。 - -### Mk:confirm(title text type) -確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。 - -### Mk:api(endpoint params) -Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。 - -### Mk:save(key value) -任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。 - -### Mk:load(key) -Mk:saveで永続化した指定の名前の値を読み取ります。 - -### Plugin:register_post_form_action(title fn) -投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。 - -### Plugin:register_note_action(title fn) -ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 - -### Plugin:register_user_action(title fn) -ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。 - -### Plugin:register_note_view_interruptor(fn) -UIに表示されるノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:register_note_post_interruptor(fn) -ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:open_url(url) -第一引数に渡されたURLをブラウザの新しいタブで開きます。 - -### Plugin:config -プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。 diff --git a/src/docs/nl-NL/custom-emoji.md b/src/docs/nl-NL/custom-emoji.md deleted file mode 100644 index ed2e92be1..000000000 --- a/src/docs/nl-NL/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# カスタム絵文字 -カスタム絵文字は、インスタンスで用意された画像を絵文字のように使える機能です。 ノート、リアクション、チャット、自己紹介、名前などの場所で使うことができます。 カスタム絵文字をそれらの場所で使うには、絵文字ピッカーボタン(ある場合)を押すか、`:`を入力して絵文字サジェストを表示します。 テキスト内に`:foo:`のような形式の文字列が見つかると、`foo`の部分がカスタム絵文字名と解釈され、表示時には対応したカスタム絵文字に置き換わります。 diff --git a/src/docs/nl-NL/deck.md b/src/docs/nl-NL/deck.md deleted file mode 100644 index 8057e262f..000000000 --- a/src/docs/nl-NL/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# デッキ - -デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。 - -## カラムの追加 -デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。 - -## カラムの移動 -カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。 - -## カラムの水平分割 -カラムは左右だけでなく、上下に並べることもできます。 カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 上下分割を解除するには、カラムメニューの「右に出す」を選択します。 - -## カラムの設定 -カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。 - -## デッキの設定 -デッキに関する設定は、[settings/deck](/settings/deck)で行えます。 diff --git a/src/docs/nl-NL/features/antenna.md b/src/docs/nl-NL/features/antenna.md deleted file mode 100644 index 94ad9e4ae..000000000 --- a/src/docs/nl-NL/features/antenna.md +++ /dev/null @@ -1,4 +0,0 @@ -# アンテナ -アンテナは、自由に条件を設定して、合致するノートを自動で収集することができる機能です。 - -条件を設定したアンテナが作成された状態で、条件に合致するノートが投稿されると、リアルタイムでそのアンテナのタイムラインにノートが追加されます。 diff --git a/src/docs/nl-NL/features/custom-emoji.md b/src/docs/nl-NL/features/custom-emoji.md deleted file mode 100644 index ed2e92be1..000000000 --- a/src/docs/nl-NL/features/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# カスタム絵文字 -カスタム絵文字は、インスタンスで用意された画像を絵文字のように使える機能です。 ノート、リアクション、チャット、自己紹介、名前などの場所で使うことができます。 カスタム絵文字をそれらの場所で使うには、絵文字ピッカーボタン(ある場合)を押すか、`:`を入力して絵文字サジェストを表示します。 テキスト内に`:foo:`のような形式の文字列が見つかると、`foo`の部分がカスタム絵文字名と解釈され、表示時には対応したカスタム絵文字に置き換わります。 diff --git a/src/docs/nl-NL/features/deck.md b/src/docs/nl-NL/features/deck.md deleted file mode 100644 index 8057e262f..000000000 --- a/src/docs/nl-NL/features/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# デッキ - -デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。 - -## カラムの追加 -デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。 - -## カラムの移動 -カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。 - -## カラムの水平分割 -カラムは左右だけでなく、上下に並べることもできます。 カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 上下分割を解除するには、カラムメニューの「右に出す」を選択します。 - -## カラムの設定 -カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。 - -## デッキの設定 -デッキに関する設定は、[settings/deck](/settings/deck)で行えます。 diff --git a/src/docs/nl-NL/features/drive.md b/src/docs/nl-NL/features/drive.md deleted file mode 100644 index b82a41082..000000000 --- a/src/docs/nl-NL/features/drive.md +++ /dev/null @@ -1,17 +0,0 @@ -# ドライブ -ドライブは、Misskey上でファイルを管理できる機能です。 - -[ドライブのページ](/my/drive)から任意のファイルをアップロードできるほか、アバターに設定した画像や、ノートに添付したファイルなどもすべてドライブにアップロードされます。 - -
⚠️ ドライブからファイルを削除すると、そのファイルが添付されたノートも消えます。
- -ドライブにアップロードされたファイルは、いつでもダウンロードすることができるほか、ノート作成時に「ドライブからファイルを添付」することでファイルを再利用することもできます。 - -ドライブ内にフォルダを作り、複数のファイルをまとめて整理することもできます。 - -## 閲覧注意 (NSFW) -
ℹ️ この項目が閲覧注意なわけではありません
- -閲覧注意またはNSFW (Not safe for work) は、ドライブのファイルに設定することができるフラグです。 閲覧注意フラグを設定されたファイルは、表示される際に閲覧者の操作なしには表示されなくなります。 このフラグは、例えば職場や公共の場で閲覧するのに適切でないと思われる画像などに設定し、そのような画像が突然表示されてしまうことを防ぐ目的で使われます。 - -このフラグは手動でオンオフを切り替えられるほか、モデレーターの判断で設定される場合もあります。 diff --git a/src/docs/nl-NL/features/favorite.md b/src/docs/nl-NL/features/favorite.md deleted file mode 100644 index a0e5f8bf7..000000000 --- a/src/docs/nl-NL/features/favorite.md +++ /dev/null @@ -1,4 +0,0 @@ -# お気に入り -[ノート](./node)をお気に入りとして登録できる機能です。 お気に入り登録したノートは、[お気に入りページ](./my/favorites)で一覧することができます。 お気に入りに登録したことは相手に通知されず、お気に入りは自分しか見ることができません。 - -ノートをお気に入り登録するには、ノートメニューの「お気に入り」を押します。お気に入り解除するには、ノートメニューの「お気に入り解除」を押します。 diff --git a/src/docs/nl-NL/features/follow.md b/src/docs/nl-NL/features/follow.md deleted file mode 100644 index 3c1ea7bbe..000000000 --- a/src/docs/nl-NL/features/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# フォロー -ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。 diff --git a/src/docs/nl-NL/features/keyboard-shortcut.md b/src/docs/nl-NL/features/keyboard-shortcut.md deleted file mode 100644 index 8659ace98..000000000 --- a/src/docs/nl-NL/features/keyboard-shortcut.md +++ /dev/null @@ -1,66 +0,0 @@ -# キーボードショートカット - -## グローバル -これらのショートカットは基本的にどこでも使えます。 - - - - - - - - - - - -
ショートカット効果由来
P, N新規投稿Post, New, Note
Tタイムラインの最も新しい投稿にフォーカスTimeline, Top
Shift + N通知を表示/隠すNotifications
S検索Search
H, ?ヘルプを表示Help
- -## 投稿にフォーカスされた状態 - - - - - - - - - - - - - - - - - - -
ショートカット効果由来
, K, Shift + Tab上の投稿にフォーカスを移動-
, J, Tab下の投稿にフォーカスを移動-
R返信フォームを開くReply
QRenoteフォームを開くQuote
Ctrl + Q即刻Renoteする(フォームを開かずに)-
E, A, +リアクションフォームを開くEmote, reAction
0~9数字に対応したリアクションをする(対応については後述)-
F, Bお気に入りに登録Favorite, Bookmark
Del, Ctrl + D投稿を削除Delete
M, O投稿に対するメニューを開くMore, Other
SCWで隠された部分を表示 or 隠すShow, See
Escフォーカスを外す-
- -## Renoteフォーム - - - - - - - - - -
ショートカット効果由来
EnterRenoteする-
Qフォームを展開するQuote
Escフォームを閉じる-
- -## リアクションフォーム -デフォルトで「👍」にフォーカスが当たっている状態です。 - - - - - - - - - - - - - -
ショートカット効果由来
, K上のリアクションにフォーカスを移動-
, J下のリアクションにフォーカスを移動-
, H, Shift + Tab左のリアクションにフォーカスを移動-
, L, Tab右のリアクションにフォーカスを移動-
Enter, Space, +リアクション確定-
0~9数字に対応したリアクションで確定-
Escリアクションするのをやめる-
diff --git a/src/docs/nl-NL/features/mfm.md b/src/docs/nl-NL/features/mfm.md deleted file mode 100644 index 5be2df4f3..000000000 --- a/src/docs/nl-NL/features/mfm.md +++ /dev/null @@ -1,12 +0,0 @@ -# MFM -MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます。 - -## MFMが使用可能な場所の例 -- ノート本文 -- CW注釈 -- ユーザーの名前 -- ユーザーの自己紹介 - -## 開発者向け情報 -MFMのパーサー実装はライブラリとして公開されており、簡単にクライアントにMFMを組み込むことが可能です。 -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptパーサー実装 diff --git a/src/docs/nl-NL/features/mute-and-block.md b/src/docs/nl-NL/features/mute-and-block.md deleted file mode 100644 index d78a7cea4..000000000 --- a/src/docs/nl-NL/features/mute-and-block.md +++ /dev/null @@ -1,41 +0,0 @@ -# ミュートとブロック -好みではないユーザーがいる場合は、ミュートを行うことでそのユーザーが自分から見えないようにすることができます。 また、より強力な措置として、ブロックを行うことでそのユーザーから自分のコンテンツが見えないようになるほか、自分に対して関わることができないようにすることができます。 ミュートされていることは相手は分かりませんが、ブロックされていることは相手に分かります。どちらを選ぶかはご自身の判断で行ってください。 - -
ℹ️ ミュートとブロックは併用できます。
- -
⚠️ 利用規約に違反するような、迷惑なユーザーがいる場合は運営者に報告することも検討してください。
- -設定>ミュートとブロック から、自分がミュートまたはブロックしているユーザー一覧を確認することができます。 - -## ミュート -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -- タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -- そのユーザーからの通知 -- メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 -- など - -ユーザーをミュートするには、対象のユーザーのユーザーページのメニューを開き、「ミュート」ボタンを押します。 - -
ℹ️ ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。
- -## ブロック -ユーザーをブロックすると、そのユーザーからあなたのコンテンツが見えないようになり、またあなたに対して以下のようなアクションをすることができなくなります。 - -- フォローする -- ユーザーリストに追加する -- 返信する、Renoteする -- リアクションする、アンケートに投票する -- メッセージを送信する -- など - -また、 - -- ブロックする際に既にそのユーザーからフォローされていた場合はフォローが解除されます。 -- ブロックする際に既にそのユーザーがあなたをユーザーリストに入れていた場合はそのリストからあなたが削除されます。 - -ユーザーをブロックするには、対象のユーザーのユーザーページのメニューを開き、「ブロック」ボタンを押します。 - -
⚠️ ブロックを行ったこと自体は相手に通知されませんが、フォローを行ったりなどの上記のアクションが行えなくなるので間接的にブロックされていることは分かります。
- -
⚠️ 相手から自分のコンテンツが見えなくなりますが、相手がアカウントを切り替えたりログアウト状態になれば見ることができます。あくまで簡易的、補助的なものとしてお考えください。
diff --git a/src/docs/nl-NL/features/mute.md b/src/docs/nl-NL/features/mute.md deleted file mode 100644 index 6a9608662..000000000 --- a/src/docs/nl-NL/features/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# ミュート - -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -* タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -* そのユーザーからの通知 -* メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 - -ユーザーをミュートするには、対象のユーザーのユーザーページに表示されている「ミュート」ボタンを押します。 - -ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。 - -設定>ミュート から、自分がミュートしているユーザー一覧を確認することができます。 diff --git a/src/docs/nl-NL/features/note.md b/src/docs/nl-NL/features/note.md deleted file mode 100644 index 305ff626f..000000000 --- a/src/docs/nl-NL/features/note.md +++ /dev/null @@ -1,54 +0,0 @@ -# ノート -ノートは、Misskeyに投稿される、文章、ファイル、アンケートなどを含むコンテンツで、Misskeyの中心的概念です。また、そのノートを作成する行為自体もノートと呼ばれます。 - -ノートが作成されると、[タイムライン](./timeline)に追加され、自分の[フォロワー](./follow)やサーバーのユーザーが見れるようになります。 - -ノートには、[リアクション](./reaction)を行うことができます。また、返信や引用もできます。 - -ノートを[お気に入り](./favorite)登録することで、後で簡単に見返すことができます。 - -## ノートを作成する -ノートを作成するには、画面上にある鉛筆マークのボタンを押して、作成フォームを開きます。作成フォームに内容を入力し、「ノート」ボタンを押すことでノートが作成されます。 ノートには、画像、動画など任意のファイルや、[アンケート](./poll)を添付することができます。また、本文中には[MFM](./mfm)が使用でき、[メンション](./mention)や[ハッシュタグ](./hashtag)を含めることもできます。 他にも、CWや公開範囲といった設定も行えます(詳細は後述)。 -
ℹ️ コンピューターのクリップボードに画像データがある状態で、フォーム内のテキストボックスにペーストするとその画像を添付することができます。
-
ℹ️ テキストボックス内でCtrl + Enterを押すことでも投稿できます。
- -## Renote -既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノートをRenoteと呼びます。 自分がフォローしているユーザーの、気に入ったノートを自分のフォロワーに共有したい場合や、過去の自分のノートを再度共有したい場合に使います。 同じノートに対して無制限にRenoteを行うことができますが、あまり連続して使用すると迷惑になる場合もあるので、注意しましょう。 -
⚠️ 公開範囲がフォロワーやダイレクトのノートはRenoteできません
- -Renoteを削除するには、Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 - -## CW -Contents Warningの略で、ノートの内容を、閲覧者の操作なしには表示しないようにできる機能です。主に長大な内容を隠すためや、ネタバレ防止などに使うことができます。 設定するには、フォームの「内容を隠す」ボタン(目のアイコン)を押します。すると新しい入力エリアが表れるので、そこに内容の要約を記入します。 - -## 公開範囲 -ノートごとに、そのノートが公開される範囲を設定することができます。フォームの「ノート」ボタンの左にあるアイコンを押すと公開範囲を以下から選択できます。 - -### パブリック -全ての人に対してノートが公開されるほか、サーバーの全てのタイムライン(ホームタイムライン、ローカルタイムライン、ソーシャルタイムライン、グローバルタイムライン)にノートが流れます。 -
⚠️ アカウントがサイレンス状態の時は、この公開範囲は使用できません。
- -### ホーム -全ての人に対してノートが公開されますが、フォロワー以外のローカルタイムライン、ソーシャルタイムライン、グローバルタイムラインにはノートは流れません。 - -### フォロワー -自分のフォロワーに対してのみノートを公開します。フォロワーの全てのタイムラインに流れます。 - -### ダイレクト -指定したユーザーに対してのみノートを公開します。指定したユーザーの全てのタイムラインに流れます。 - -### 「ローカルのみ」オプション -このオプションを有効にすると、リモートにノートを連合しなくなります。 - -### 公開範囲の比較 - - - - -
パブリックホームフォロワーダイレクト
フォロワーのLTL/STL/GTL
非フォロワーのLTL/STL/GTL
- -## ピン留め -ノートをピン留めすると、ユーザーページに常にそのノートを表示しておくことができます。 ノートのメニューを開き、「ピン留め」を選択してピン留めできます。 複数のノートをピン留めできます。 - -## ウォッチ -ノートをウォッチすると、自分以外のノートへのリアクションや返信などの通知を受け取ることができます。 ノートのメニューを開き、「ウォッチ」を選択してウォッチできます。 diff --git a/src/docs/nl-NL/features/pages.md b/src/docs/nl-NL/features/pages.md deleted file mode 100644 index a7311b95e..000000000 --- a/src/docs/nl-NL/features/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# Pages - -## 変数 -変数を使うことで動的なページを作成できます。テキスト内で { 変数名 } と書くとそこに変数の値を埋め込めます。例えば Hello { thing } world! というテキストで、変数(thing)の値が ai だった場合、テキストは Hello ai world! になります。 - -変数の評価(値を算出すること)は上から下に行われるので、ある変数の中で自分より下の変数を参照することはできません。例えば上から A、B、C と3つの変数を定義したとき、Cの中でABを参照することはできますが、Aの中でBCを参照することはできません。 - -ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。 - -関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。 diff --git a/src/docs/nl-NL/features/reaction.md b/src/docs/nl-NL/features/reaction.md deleted file mode 100644 index 4d479fd41..000000000 --- a/src/docs/nl-NL/features/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# リアクション -他の人のノートに、絵文字を付けて簡単にあなたの反応を伝えられる機能です。 リアクションするには、ノートの + アイコンをクリックしてピッカーを表示し、絵文字を選択します。 リアクションには[カスタム絵文字](./custom-emoji)も使用できます。 - -## リアクションピッカーのカスタマイズ -ピッカーに表示される絵文字を自分好みにカスタマイズすることができます。 設定の「リアクション」で設定します。 - -## リモート投稿へのリアクションについて -リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。 - -## リモートからのリアクションについて -リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。 diff --git a/src/docs/nl-NL/features/silence.md b/src/docs/nl-NL/features/silence.md deleted file mode 100644 index 7e26feab0..000000000 --- a/src/docs/nl-NL/features/silence.md +++ /dev/null @@ -1,6 +0,0 @@ -# サイレンス -サイレンスは、アカウントに設定される状態のひとつです。 - -アカウントがサイレンス状態になると、ノートの公開範囲をパブリックにできなくなります。 ホーム、フォロワー、ダイレクトは選択可能なため、サイレンスを受けた場合でもフォロワーやあなたのユーザーページを直接訪れた場合は投稿を閲覧できますが、GTL(連合タイムライン)やLTL(ローカルタイムライン)には投稿が流れません。 - -アカウントのサイレンス状態は、サーバーのモデレーターによって有効化/無効化されます。 diff --git a/src/docs/nl-NL/features/theme.md b/src/docs/nl-NL/features/theme.md deleted file mode 100644 index a406f3433..000000000 --- a/src/docs/nl-NL/features/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# テーマ - -テーマを設定して、Misskeyクライアントの見た目を変更できます。 - -## テーマの設定 -設定 > テーマ - -## テーマを作成する -テーマコードはJSON5で記述されたテーマオブジェクトです。 テーマは以下のようなオブジェクトです。 -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... テーマの一意なID。UUIDをおすすめします。 -* `name` ... テーマ名 -* `author` ... テーマの作者 -* `desc` ... テーマの説明(オプション) -* `base` ... 明るいテーマか、暗いテーマか - * `light`にすると明るいテーマになり、`dark`にすると暗いテーマになります。 - * テーマはここで設定されたベーステーマを継承します。 -* `props` ... テーマのスタイル定義。これから説明します。 - -### テーマのスタイル定義 -`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 - -#### バリューで使える構文 -* 16進数で表された色 - * 例: `#00ff00` -* `rgb(r, g, b)`形式で表された色 - * 例: `rgb(0, 255, 0)` -* `rgb(r, g, b, a)`形式で表された透明度を含む色 - * 例: `rgba(0, 255, 0, 0.5)` -* 他のキーの値の参照 - * `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。 - * 例: `@panel` -* 定数(後述)の参照 - * `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。 - * 例: `$main` -* 関数(後述) - * `:{関数名}<{引数}<{色}` - -#### 定数 -「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 キー名を`$`で始めると、そのキーはCSS変数として出力されません。 - -#### 関数 -wip diff --git a/src/docs/nl-NL/features/timeline.md b/src/docs/nl-NL/features/timeline.md deleted file mode 100644 index f431014f8..000000000 --- a/src/docs/nl-NL/features/timeline.md +++ /dev/null @@ -1,31 +0,0 @@ -# タイムライン -タイムラインは、[ノート](./note)が時系列で表示される機能です。 タイムラインには以下で示す種類があり、種類によって表示されるノートも異なります。 なお、タイムラインの種類によってはサーバーにより無効になっている場合があります。 - -## ホーム -自分のフォローしているユーザーの投稿が流れます。HTLと略されます。 - -## ローカル -全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。LTLと略されます。 - -## ソーシャル -自分のフォローしているユーザーの投稿と、全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。STLと略されます。 - -## グローバル -全てのローカルユーザーの「ホーム」指定されていない投稿と、サーバーに届いた全てのリモートユーザーの「ホーム」指定されていない投稿が流れます。GTLと略されます。 - -## 比較 -| ソース | | | タイムライン | | | -| ------------ | ----- | --- | ------ | ----- | ----- | -| ユーザー | 公開範囲 | ホーム | ローカル | ソーシャル | グローバル | -| ローカル (フォロー) | 公開 | ✔ | ✔ | ✔ | ✔ | -| | ホーム | ✔ | | ✔ | | -| | フォロワー | ✔ | ✔ | ✔ | ✔ | -| リモート (フォロー) | 公開 | ✔ | | ✔ | ✔ | -| | ホーム | ✔ | | ✔ | | -| | フォロワー | ✔ | | ✔ | ✔ | -| ローカル (未フォロー) | 公開 | | ✔ | ✔ | ✔ | -| | ホーム | | | | | -| | フォロワー | | | | | -| リモート (未フォロー) | 公開 | | | | ✔ | -| | ホーム | | | | | -| | フォロワー | | | | | diff --git a/src/docs/nl-NL/features/widgets.md b/src/docs/nl-NL/features/widgets.md deleted file mode 100644 index a7c2c1d1d..000000000 --- a/src/docs/nl-NL/features/widgets.md +++ /dev/null @@ -1,7 +0,0 @@ -# ウィジェット -ウィジェットは、MisskeyのUI上に設置できる小型の情報表示、操作が行えるパーツです。 - -ウィジェットを編集するには、ウィジェット編集モードに切り替えます。切り替え方法はUIによって異なります。 ウィジェット編集モードでは、ウィジェットの追加、削除、並び替え、およびそれぞれのウィジェットの設定を行えます。 - -## 利用可能なウィジェット一覧 -todo diff --git a/src/docs/nl-NL/features/word-mute.md b/src/docs/nl-NL/features/word-mute.md deleted file mode 100644 index fa4d14346..000000000 --- a/src/docs/nl-NL/features/word-mute.md +++ /dev/null @@ -1,20 +0,0 @@ -# ワードミュート -ワードミュートの設定をすると、条件に合致したノートが表示されなくなります。 - -ワードミュートには、ソフトワードミュートとハードワードミュートの2種類があります。それぞれについて設定の方法と挙動を説明します。 - -## ソフトワードミュート -ソフトワードミュートは、クライアント(アプリ)側でミュートを判断するワードミュートです。 - -ノートが設定した条件に合致すると、「(ユーザー名)が何かを言いました」という表示で隠れます。 -クリックすると元の通りに表示されます。 - -## ハードワードミュート -ハードワードミュートは、アンテナのようにサーバーが新しいノートの本文に対して条件に合致するかどうか判断し、タイムラインから対象となったノートを除外します。 - -つまり、ハードワードミュートには、以下のような特徴があります。 - -* 条件設定後、新しい投稿のみがミュートの対象になります。 -* 条件を変更しても、過去にハードミュートされたノートはミュートされたままになります。 -* 「○○が何かを言いました」でタイムラインが埋まることがありません。 -* ソフトミュートに非対応のアプリでも、ハードミュートは適用されます。 diff --git a/src/docs/nl-NL/follow.md b/src/docs/nl-NL/follow.md deleted file mode 100644 index 3c1ea7bbe..000000000 --- a/src/docs/nl-NL/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# フォロー -ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。 diff --git a/src/docs/nl-NL/general/apps.md b/src/docs/nl-NL/general/apps.md deleted file mode 100644 index 1f4c85fe8..000000000 --- a/src/docs/nl-NL/general/apps.md +++ /dev/null @@ -1,6 +0,0 @@ -# サードパーティアプリのリスト -## クライアント -todo - -## 連携サービス -todo diff --git a/src/docs/nl-NL/general/changelog.md b/src/docs/nl-NL/general/changelog.md deleted file mode 100644 index 6766a63b2..000000000 --- a/src/docs/nl-NL/general/changelog.md +++ /dev/null @@ -1,5 +0,0 @@ -# 更新履歴 -
ℹ️ このサーバーの更新履歴です。Misskeyの最新のリリースについては、GitHubをご確認ください。
- - - diff --git a/src/docs/nl-NL/general/faq.md b/src/docs/nl-NL/general/faq.md deleted file mode 100644 index c272b2ad4..000000000 --- a/src/docs/nl-NL/general/faq.md +++ /dev/null @@ -1,28 +0,0 @@ -# よくある質問 -ここでは利用上のよくある質問について掲載しています。 Misskeyのプロジェクト自体についてのよくある質問は[こちら](./misskey)に掲載されています。 - -## iOS/Androidのアプリはありますか? -公式にはそういったOSのネイティブアプリを開発していませんが、サードパーティ製のアプリがいくつかあります。 詳しくは[こちら](./apps)をご覧ください。 - -ただ、サードパーティ製アプリはどうしても機能への対応が遅れてしまうため、とくに拘りがなければ公式のWebクライアントの利用をおすすめします。 なお、MisskeyのWebクライアントはPWAに対応しているので、ネイティブアプリのように動作させることも可能です。 詳しくは[こちら](todo)をご覧ください。 - -## Mastodonクライアントでログインできないのですが? -MisskeyはMastodonのAPIと互換性がないため、一部を除きMastodonクライアントでMisskeyを利用することはできません。 - -## 他のサーバーのユーザーをフォローするときは? -メニューから検索を選び、ユーザー名をホスト込みで入力します。例: `@syuilo@misskey.io` - -## Renoteを削除するには? -Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 Renoteについては[こちら](../features/note)をご確認ください。 - -## URLのプレビューを表示させたくない -MFMには、そのURLのプレビューを無効にする構文があります。詳細は[MFMチートシート](/mfm-cheat-sheet)をご確認ください。 - -## カスタム絵文字を追加したい -運営者のみがカスタム絵文字を追加、編集、削除できます。それらを希望する場合は運営者に依頼してください。 - -## Botを開発したい -Misskey APIを利用してBotの開発が可能です。[こちら](../advanced/develop-bot)をご確認ください。 - -## ノートの翻訳機能はどのサービスを使用していますか? -[DeepL](https://www.deepl.com/)を使用しています。 diff --git a/src/docs/nl-NL/general/glossary.md b/src/docs/nl-NL/general/glossary.md deleted file mode 100644 index bb8a24336..000000000 --- a/src/docs/nl-NL/general/glossary.md +++ /dev/null @@ -1,89 +0,0 @@ -# 用語集 -Misskeyに関する用語集です。 - -## ActivityPub -(読み: あくてぃびてぃぱぶ) 分散型を実現するために用いられるプロトコル(仕様)。このプロトコルに則ってサーバー同士通信を行うことで、連合が行われ、Fediverseを形成しています。 - -## AiScript -(読み: あいすくりぷと) Misskey上で使用できるプログラミング言語です。詳細は[こちら。](../advanced/aiscript) - -## API -(読み: えーぴーあい) Misskeyのサーバーが公開している、プログラムからMisskeyを扱うためのインターフェース。詳細は[こちら。](../advanced/api) - -## Bot -(読み: ぼっと) プログラムによって動作しているアカウント。 - -## CW -(読み: こんてんつわーにんぐ) Contents Warningの略。ノートの内容を、操作なしには表示しないようにできる機能。主に長大な内容を隠すためや、ネタバレ防止などに使われます。 - -## Fediverse -(読み: ふぇでぃばーす) Misskeyを含む様々な分散型ソフトウェアのサーバーで構成されたネットワーク。 - -## GTL -グローバルタイムライン(Global TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## HTL -ホームタイムライン(Home TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## LTL -ローカルタイムライン(Local TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## MFM -(読み: えむえふえむ) Misskey Flavored Markdownの略で、Misskey上で使用できるマークアップ言語です。詳細は[こちら。](../features/mfm) - -## NSFW -(読み: のっとせーふふぉーわーく) Not Safe For Workの略。画像を「閲覧注意」扱いにし、操作なしには表示しないようにすることができる機能。 - -## Renote -(読み: りのーと) 既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノート。詳細は[こちら。](../features/note) - -## STL -ソーシャルタイムライン(Social TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## 藍 -(読み: あい) Misskeyの看板娘(公式キャラクター)です。 - -## アクティブユーザー -インスタンスにアカウントを作っているユーザーのうち、現在も実際にサービスを利用しているユーザーのこと。 - -## インスタンス -todo - -## カスタム絵文字 -サーバーで用意された絵文字。カスタム絵文字ではない通常の絵文字は「Unicode絵文字」と区別して呼ばれる。 - -## コントロールパネル -インスタンスの設定画面のこと。 - -## サーバー -todo - -## サイレンス -ノートをパブリックな公開範囲で投稿できなくされている状態。モデレーターの判断でユーザーごとに設定されます。詳細は[こちら。](../features/silence) - -## ジョブキュー -アクティビティ配送などを順番に行うためのシステム。 - -## 凍結 -アカウントが使用不可に設定されている状態。 - -## ドライブ -Misskeyにアップロードしたファイルを管理する機能。詳細は[こちら。](../features/drive) - -## ノート -Misskeyに投稿される、文章、ファイル、アンケートなどを含めることができるコンテンツ。詳細は[こちら。](../features/note) - -## ミスキスト -Misskeyを使う人のこと。 - -## モデレーター -スパムの凍結およびサイレンスや不適切な投稿の削除など、コミュニティ運営に関する権限を持つユーザー。 - -## リモート -他サーバーのことを指します。リモートユーザーといったように接頭辞としても使われます。ローカルの逆です。 - -## 連合 -サーバー上で作成された情報が他のサーバーに伝わること。 - -## ローカル -自サーバーのことを指します。ローカルユーザー、ローカルタイムラインといったように接頭辞としても使われます。リモートの逆です。 diff --git a/src/docs/nl-NL/general/links.md b/src/docs/nl-NL/general/links.md deleted file mode 100644 index 5ce5e1ddb..000000000 --- a/src/docs/nl-NL/general/links.md +++ /dev/null @@ -1,12 +0,0 @@ -# リンク集 - -## Webサイト -- [Official Discord](https://discord.gg/Wp8gVStHW3) - Misskey公式Discordサーバー -- [Misskey Forum](https://forum.misskey.io/) - Misskeyに関する話題を扱うフォーラム - -## アカウント -- [@repo@misskey.io](https://misskey.io/@repo) - Misskeyのリポジトリの更新を投稿するbot - -## ライブラリ -- [misskey-dev/misskey.js](https://github.com/misskey-dev/misskey.js) - JavaScriptのMisskey SDK -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptのMFMパーサー実装 diff --git a/src/docs/nl-NL/general/misskey.md b/src/docs/nl-NL/general/misskey.md deleted file mode 100644 index d97664ddc..000000000 --- a/src/docs/nl-NL/general/misskey.md +++ /dev/null @@ -1,87 +0,0 @@ -# Misskeyについて - -Misskeyはオープンソースの分散型マイクロブログプラットフォームプロジェクトです。 開発は日本でsyuiloによって2014年から開始されました。 ドライブ、リアクションなどの豊富な機能や、高いカスタマイズ性を備えたUIを持つことが特徴です。 - -## 歴史 -開発当初は掲示板がメインのサービスでしたが、ユーザーが短文を投稿し、それを時系列で流れるタイムライン機能を追加したところ人気が高まり、徐々にそれがメインとして開発が進むようになりました。 当初は分散型ではありませんでしたが、2018年にActivityPubを実装し分散型になったことで、より多くの方に認知され利用されるサービスになり、現在に至ります。 -
ℹ️ Misskeyという名前は、syuiloが当時聴いていたMay'nというアーティストの楽曲、Brain Diverの歌詞に由来します。
- -誰でも開発に参加することができ、現在でも活発に開発が続いています。 - -## 分散型とは何か? - -分散(distributed)型とは、非中央集権(decentralized)とも呼ばれ、コミュニティが多数のサーバーに分散して存在し、それらが相互に通信(連合、federation)することでコンテンツ共有ネットワーク(Fediverse)を形成していることが特徴のサービスです。 単一のサーバーしか存在しない、もしくは複数存在しても互いに独立している場合は中央集権なサービスと言われ、例えばTwitterやFacebookなどほとんどのサービスがそれに該当します。 分散型のメリットは、自分に合った運営者やテーマのサーバーを選択できることです。自分でサーバーを作成することもできます。連合するおかげで、どのサーバーを選んでも、同じコミュニティにアクセスできます。 - -## 常にオープンソース -Misskeyはこれまでもこれからも、オープンソースであり続けます。オープンソースとは、簡単に言うとソフトウェアのソースコード(プログラム)が公開されていることです。ソースコードの修正や再配布が可能であることを定義に含めることもあります。 Misskeyのすべてのソースコードは[AGPL](https://github.com/misskey-dev/misskey/blob/develop/LICENSE)というオープンソースライセンスの下に[公開](https://github.com/misskey-dev)されていて、誰でも自由に閲覧、使用、修正、改変、再配布をすることができます。 オープンソースは、自分で好きなように変えたり、有害な処理が含まれていないことを確認することができたり、誰でも開発に参加できるなどの、様々なメリットがあります。 上述の分散型を実現するためにも、オープンソースであるということは必要不可欠な要素です。 再び引き合いに出しますが、TwitterやFacebookなどの利益を得ているほとんどのサービスはオープンソースではありません。 - -
ℹ️ 技術的に言うと、MisskeyのソースコードはGitで管理されていて、リポジトリはGitHub上でホスティングされています。
- -## 開発に参加する、プロジェクトを支援する -Misskeyを気に入っていただけたら、ぜひプロジェクトを支援してください。プロジェクトに貢献するには、以下で紹介するようにいろいろな方法があります。方法によっては開発のスキルは不要なので、誰でも気軽に参加し貢献することができます。いつでもお待ちしています。 - -### 機能を追加したり、バグを修正する -ソフトウェアエンジニアのスキルをお持ちの方であれば、ソースコードを編集する形でプロジェクトに貢献することができます。 貢献についてのガイドは[こちら](https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md)です。 - -### 議論に参加する -新しい機能、または既存の機能について意見を述べたり、不具合を報告したりすることでも貢献できます。 そのようなディスカッションは[GitHub](https://github.com/misskey-dev)上か、[フォーラム](https://forum.misskey.io/)等で行われます。 - -### テキストを翻訳する -Misskeyは様々な言語に対応しています(i18n -internationalizationの略- と呼ばれます)。元の言語は基本的に日本語ですが、有志によって他の言語へと翻訳されています。 その翻訳作業に加わっていただくことでもMisskeyに貢献できます。 Misskeyは[Crowdinというサービスを使用して翻訳の管理を行っています。](https://crowdin.com/project/misskey) - -### 感想を投稿する -不具合報告等だけではなく、Misskeyの良い点、楽しい点といったポジティブな意見もぜひ共有してください。開発の励みになり、それは間接的ですがプロジェクトへの貢献です。 - -### ミスキストを増やす -ミスキストとは、Misskeyを使用する人のことです。 知り合いに紹介するなどしてMisskeyを広めていただければ、ミスキストが増え開発のモチベーションが上がります。 - -### 寄付をする -Misskeyはビジネスではなく、利用は無料であるため、収益は皆様からの寄付のみです。(インスタンスによっては広告収入を得ているような場合もありますが、それは運営者の収入であり直接開発者への収入にはなりません) 寄付をしていただければ、今後も開発を続けることが可能になり、プロジェクトへの貢献になります。 寄付は基本的には[Patreon](https://www.patreon.com/syuilo)で受け付けています。 一定額寄付していただけると、Misskeyの[情報ページ](/about-misskey)に名前を記載することができます。 - -また、サーバーの運営者も、基本的には収益を得ていません。サーバーの運営にはコストがかかるので、運営者の支援をすることもご検討ください。 開発には直接関係しませんが、サーバーがあってこそのプロジェクトなので、運営が維持されるというのは開発と同じくらい重要なことです。 - -## クレジット -Misskeyの開発者や、Misskeyに寄付をしてくださった方の一覧は[こちら](/about-misskey)で見ることができます。 - -## よくある質問 -### プロジェクトは何を目指していますか? -強いて言うと、漠然的になりますが広く使われる汎用的なプラットフォームになることを目指しています。 Misskeyは他のプロジェクトとは違い、何らかの思想(例えば、反中央集権)やビジョンに基づいて開発が行われているわけではなく、その点ではフラットです。 それが逆に、特定の方向性に縛られないフレキシブルさを生み出すことに繋がっていると感じています。 - - -### 企業によって開発されていますか? -いいえ。Misskeyの開発は個人で行われており、商業的でもないため、特定の企業の関りはありません。 開発メンバーも基本的にはボランティアです。 また、開発に対し企業のスポンサーがつくこともありますが、その場合でもやはり開発は個人のコミュニティが主体です。 - -### 誰が運営していますか? -Misskeyは分散型なため、各サーバーにそれぞれ異なった運営者がいます。従って、特定の個人や企業によって、Misskeyの全てが運営されているわけではありません。 また、開発チームが運営を行うわけでもないため、運営に関する連絡は、お使いのサーバーの運営者に行ってください。 サーバーの運営者は、[このページ](/about)で確認することができます。 あなたがサーバーを作成すれば、あなたが運営者になります。 - -### どのサーバーを選べばいいですか? -[サーバー一覧が公開されています。](https://join.misskey.page/ja-JP/instances) サーバーによってコミュニティのテーマ(特定のこと、ものが好き 等)が決められている場合があるので、自分に合ったテーマのサーバーがあれば、そこを選ぶと良いかもしれません。 他にも、サーバーの規模、ユーザー層、国および言語、運営者が信頼できるかどうか、などの観点があります。 なお、Misskey公式のサーバーというものはありません。自身で新しくサーバーを作成するという選択肢もあります。 - -基本的にどのサーバーを選んだとしても、他の全てのサーバーのユーザーと繋がることができます。 - -### サーバーを建てるにはどうしたらいいですか? -Misskeyサーバーの作成に興味を持っていただきありがとうございます。 2021年現在、Misskeyのホスティングサービスは存在しないため、サーバーの作成にはある程度の知識が必要です。 サーバーの作成方法については[こちら](todo)をご覧ください。 - -### どのような技術を使用していますか? -Misskeyは開発が進むにつれ使用する技術も大きく変わってきました。開発当初はMySQL + PHP + jQueryといった構成でしたが、現在は以下のようになっています。 -- サーバーサイド: Node.js -- データベース: PostgreSQL、Redis -- UIフレームワーク: Vue.js -- プログラミング言語: TypeScript - -また、MFMやAiScriptなどの、Misskeyから派生して独自の技術も開発しています。 - -### Mastodonのフォークですか? -いいえ。MisskeyはMastodonやその他のプロジェクトとは全く別のプロジェクトです。 開発に関しても、Misskeyの方が昔から開発されています。ただし、分散型になったのはMastodonの登場より後です。 同じActivityPubという分散のためのプロトコルを実装しているという点以外、両者に特に関りがあるわけでもありません。 - -### iOS/Androidのアプリはありますか? -公式にはそういったOSのネイティブアプリを開発していませんが、サードパーティ製のアプリがいくつかあります。 詳しくは[こちら](./apps)をご覧ください。 - -ただ、サードパーティ製アプリはどうしても機能への対応が遅れてしまうため、とくに拘りがなければ公式のWebクライアントの利用をおすすめします。 なお、MisskeyのWebクライアントはPWAに対応しているので、ネイティブアプリのように動作させることも可能です。 詳しくは[こちら](todo)をご覧ください。 - -### Misskeyのロゴ、アイコンはどこで入手できますか? -(準備中) - -### 時折目にする猫耳の可愛い女の子は? -Misskeyの守り神、藍ちゃんです。アイチャンカワイイヤッター! -
ℹ️ 藍ちゃんについてはこちらです。
diff --git a/src/docs/nl-NL/general/report-issue.md b/src/docs/nl-NL/general/report-issue.md deleted file mode 100644 index 63527e32a..000000000 --- a/src/docs/nl-NL/general/report-issue.md +++ /dev/null @@ -1,8 +0,0 @@ -# 不具合の報告 -不具合と思われる状況に遭遇したときは、まず[トラブルシューティング](./troubleshooting)をご一読ください。 それでも問題が解決しないときは、以下の情報を含めて[フォーラム](https://forum.misskey.io/)に投稿してください。 投稿することで、解決策が見つかったり、不具合と判断されれば開発チームによって修正が行われます。 - -## 含める情報 -- Misskeyのバージョン([情報ページ](/about)で確認できます) -- お使いのブラウザの種類とバージョン -- お使いのOSの種類とバージョン -- 問題の再現手順 diff --git a/src/docs/nl-NL/general/troubleshooting.md b/src/docs/nl-NL/general/troubleshooting.md deleted file mode 100644 index f895b4984..000000000 --- a/src/docs/nl-NL/general/troubleshooting.md +++ /dev/null @@ -1,40 +0,0 @@ -# トラブルシューティング -
ℹ️ よくある質問も合わせてお役立てください。
- -問題が発生したときは、まずこちらをご確認ください。 該当する項目が無い、もしくは手順を試しても効果がない場合は、サーバーの管理者に連絡するか[不具合を報告](./report-issue)してください。 - -## クライアントが起動しない -ほとんどの場合、お使いのブラウザまたはOSのバージョンが古いことが原因です。 ブラウザおよびOSのバージョンを最新のものに更新してから、再度試してみてください。 - -これは稀ですが、それでも起動しない場合は、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。 - -## ページが読み込めない -クライアントが起動するもののページが読み込めないというエラーが出る場合は、ネットワークに問題がないか確認してください。また、サーバーがダウンしていないか確認してください。 - -これは稀ですが、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。 - -まだ問題がある場合は、サーバーの問題と思われるのでサーバーの管理者に連絡してください。 - -## クライアントの動作が遅い -以下を試してみてください: - -- クライアント設定で「UIのアニメーションを減らす」を有効にする -- クライアント設定で「モーダルにぼかし効果を使用」を無効にする -- お使いのブラウザの設定でハードウェアアクセラレーションを有効にする -- お使いのデバイスのスペックを上げる - -## UIの一部の表示がおかしい(背景が透明になっている等) -アップデートによりUIの改修が行われたときに、テーマのキャッシュシステムの影響でそのような表示になることがあります。 クライアントの設定の「キャッシュをクリア」すると直ります。 -
⚠️ 「クライアントの」キャッシュクリアです。「ブラウザの」キャッシュクリアは行わないでください。
- -## 通知やアンテナ等の点滅が消えない -点滅は、未読のコンテンツがあることを示しています。通常点滅が消えない場合は、コンテンツを遡ると未読なコンテンツが残っています。 すべて既読にしたと思われるのに、それでもなお点滅が続く場合(おそらく不具合と思われます)は設定から強制的にすべて既読扱いにすることができます。 - -## Renoteができない -フォロワー限定のノートはRenoteすることはできません。 - -## UI上で特定の要素が表示されない -広告ブロッカーを使用しているとそのような不具合が発生することがあります。Misskeyではオフにしてご利用ください。 - -## UI上で未翻訳の部分がある -ほとんどの場合、単に翻訳が間に合っていないだけで、不具合ではありません。翻訳が終わるまでお待ちください。 [翻訳に参加](./misskey)していただくことも可能です。 diff --git a/src/docs/nl-NL/keyboard-shortcut.md b/src/docs/nl-NL/keyboard-shortcut.md deleted file mode 100644 index 957ca838c..000000000 --- a/src/docs/nl-NL/keyboard-shortcut.md +++ /dev/null @@ -1,68 +0,0 @@ -# キーボードショートカット - -## グローバル -これらのショートカットは基本的にどこでも使えます。 - - - - - - - - - - - -
ショートカット効果由来
P, N新規投稿Post, New, Note
Tタイムラインの最も新しい投稿にフォーカスTimeline, Top
Shift + N通知を表示/隠すNotifications
S検索Search
H, ?ヘルプを表示Help
- -## 投稿にフォーカスされた状態 - - - - - - - - - - - - - - - - - - - -
ショートカット効果由来
, K, Shift + Tab上の投稿にフォーカスを移動-
, J, Tab下の投稿にフォーカスを移動-
R返信フォームを開くReply
QRenoteフォームを開くQuote
Ctrl + Q即刻Renoteする(フォームを開かずに)-
E, A, +リアクションフォームを開くEmote, reAction
0~9数字に対応したリアクションをする(対応については後述)-
F, Bお気に入りに登録Favorite, Bookmark
Del, Ctrl + D投稿を削除Delete
M, O投稿に対するメニューを開くMore, Other
SCWで隠された部分を表示 or 隠すShow, See
Escフォーカスを外す-
- -## Renoteフォーム - - - - - - - - - - -
ショートカット効果由来
EnterRenoteする-
Qフォームを展開するQuote
Escフォームを閉じる-
- -## リアクションフォーム -デフォルトで「👍」にフォーカスが当たっている状態です。 - - - - - - - - - - - - - -
ショートカット効果由来
, K上のリアクションにフォーカスを移動-
, J下のリアクションにフォーカスを移動-
, H, Shift + Tab左のリアクションにフォーカスを移動-
, L, Tab右のリアクションにフォーカスを移動-
Enter, Space, +リアクション確定-
0~9数字に対応したリアクションで確定-
Escリアクションするのをやめる-
diff --git a/src/docs/nl-NL/mfm.md b/src/docs/nl-NL/mfm.md deleted file mode 100644 index e237287ac..000000000 --- a/src/docs/nl-NL/mfm.md +++ /dev/null @@ -1,2 +0,0 @@ -# MFM -MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます。 diff --git a/src/docs/nl-NL/mute.md b/src/docs/nl-NL/mute.md deleted file mode 100644 index 6a9608662..000000000 --- a/src/docs/nl-NL/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# ミュート - -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -* タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -* そのユーザーからの通知 -* メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 - -ユーザーをミュートするには、対象のユーザーのユーザーページに表示されている「ミュート」ボタンを押します。 - -ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。 - -設定>ミュート から、自分がミュートしているユーザー一覧を確認することができます。 diff --git a/src/docs/nl-NL/pages.md b/src/docs/nl-NL/pages.md deleted file mode 100644 index a7311b95e..000000000 --- a/src/docs/nl-NL/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# Pages - -## 変数 -変数を使うことで動的なページを作成できます。テキスト内で { 変数名 } と書くとそこに変数の値を埋め込めます。例えば Hello { thing } world! というテキストで、変数(thing)の値が ai だった場合、テキストは Hello ai world! になります。 - -変数の評価(値を算出すること)は上から下に行われるので、ある変数の中で自分より下の変数を参照することはできません。例えば上から A、B、C と3つの変数を定義したとき、Cの中でABを参照することはできますが、Aの中でBCを参照することはできません。 - -ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。 - -関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。 diff --git a/src/docs/nl-NL/reaction.md b/src/docs/nl-NL/reaction.md deleted file mode 100644 index c26ead75b..000000000 --- a/src/docs/nl-NL/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# リアクション -他の人のノートに、絵文字を付けて簡単にあなたの反応を伝えられる機能です。 リアクションするには、ノートの + アイコンをクリックしてピッカーを表示し、絵文字を選択します。 リアクションには[カスタム絵文字](./custom-emoji)も使用できます。 - -## リアクションピッカーのカスタマイズ -ピッカーに表示される絵文字を自分好みにカスタマイズすることができます。 設定の「リアクション」で設定します。 - -## リモート投稿へのリアクションについて -リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。 また、相手がMisskeyであったとしても、カスタム絵文字リアクションは伝わらず、自動的に「👍」等にフォールバックされます。 - -## リモートからのリアクションについて -リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。 diff --git a/src/docs/nl-NL/reversi-bot.md b/src/docs/nl-NL/reversi-bot.md deleted file mode 100644 index 7ab2a7212..000000000 --- a/src/docs/nl-NL/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# MisskeyリバーシBotの開発 -Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。 - -1. `games/reversi`ストリームに以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - -2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる - * イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている - -3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する - -4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - * `game`: `game`の`id` - -5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う - -6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する - -7. ゲームが開始すると、`started`イベントが流れてくる - * イベントの中身にはゲーム情報が含まれている - -8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述) - -9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる - * `color`として石の色が含まれている - * `pos`として位置情報が含まれている - -## 位置の計算法 -8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### X,Y座標 から インデックス に変換する -``` -pos = x + (y * mapWidth) -``` -`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます: -``` -mapWidth = map[0].length -``` - -### インデックス から X,Y座標 に変換する -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## マップ情報 -マップ情報は、ゲーム情報の`map`に入っています。 文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 それをもとにマップのデザインを知る事が出来ます: -* `(スペース)` ... マス無し -* `-` ... マス -* `b` ... 初期配置される黒石 -* `w` ... 初期配置される白石 - -例えば、4*4の次のような単純なマップがあるとします: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -この場合、マップデータはこのようになります: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## ユーザーにフォームを提示して対話可能Botを作成する -ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。 - -フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します: -```javascript -{ - type: 'init-form', - body: [フォームコントロールの配列] -} -``` - -フォームコントロールの配列については今から説明します。 フォームコントロールは、次のようなオブジェクトです: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... コントロールのID。 `type` ... コントロールの種類。後述します。 `label` ... コントロールと一緒に表記するテキスト。 `value` ... コントロールのデフォルト値。 - -### フォームの操作を受け取る -ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### フォームコントロールの種類 -#### スイッチ -type: `switch` スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。 - -##### プロパティ -`label` ... スイッチに表記するテキスト。 - -#### ラジオボタン -type: `radio` ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。 - -##### プロパティ -`items` ... ラジオボタンの選択肢。例: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '強', - value: 3 -}] -``` - -#### スライダー -type: `slider` スライダーを表示します。 - -##### プロパティ -`min` ... スライダーの下限。 `max` ... スライダーの上限。 `step` ... 入力欄で刻むステップ値。 - -#### テキストボックス -type: `textbox` テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。 - -## ユーザーにメッセージを表示する -設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 メッセージを表示するには、次のメッセージをストリームに送信します: -```javascript -{ - type: 'message', - body: { - text: 'メッセージ内容', - type: 'メッセージの種類' - } -} -``` -メッセージの種類: `success`, `info`, `warning`, `error`。 - -## 投了する -投了をするには、このエンドポイントにリクエストします。 diff --git a/src/docs/nl-NL/stream.md b/src/docs/nl-NL/stream.md deleted file mode 100644 index 9011c37c5..000000000 --- a/src/docs/nl-NL/stream.md +++ /dev/null @@ -1,354 +0,0 @@ -# ストリーミングAPI - -ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。 - -## ストリームに接続する - -ストリーミングAPIを利用するには、まずMisskeyサーバーに**websocket**接続する必要があります。 - -以下のURLに、`i`というパラメータ名で認証情報を含めて、websocket接続してください。例: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。 - -
-

認証情報の取得については、こちらのドキュメントをご確認ください。

-
- ---- - -認証情報は省略することもできますが、その場合非ログインでの利用ということになり、受信できる情報や可能な操作は限られます。例: - -``` -%WS_URL%/streaming -``` - ---- - -ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。 - -**ストリームでのやり取りはすべてJSONです。** - -## チャンネル -MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。 - -### チャンネルに接続する -チャンネルに接続するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -ここで、 -* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。 -* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。 -* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。 - -
-

IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。

-
- -### チャンネルからのメッセージを受け取る -例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。 - -チャンネルがメッセージを発すると、次のようなデータがJSONでストリームに流れてきます: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。 -* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。 -* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。 - -### チャンネルに向けてメッセージを送信する -チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。 - -チャンネルにメッセージを送信するには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。 -* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。 -* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。 - -### チャンネルから切断する -チャンネルから切断するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。 - -## ストリームを経由してAPIリクエストする - -ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。 - -ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -ここで、 -* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 -* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 -* `data`には、エンドポイントのパラメータを含めます。 - -
-

APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。

-
- -### レスポンスの受信 - -APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。 - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -ここで、 -* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 -* `body`には、レスポンスが含まれています。 - -## 投稿のキャプチャ - -Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。 - -例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。 - -しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。 - -この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。 - -### 投稿をキャプチャする - -投稿をキャプチャするには、ストリームに次のようなメッセージを送信します: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャしたい投稿の`id`を設定します。 - -このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 - -例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -ここで、 -* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。 -* `body`内の`type`に、イベントの種類が設定されます。 -* `body`内の`body`に、イベントの詳細が設定されます。 - -#### イベントの種類 - -##### `reacted` -その投稿にリアクションがされた時に発生します。 - -* `reaction`に、リアクションの種類が設定されます。 -* `userId`に、リアクションを行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -その投稿が削除された時に発生します。 - -* `deletedAt`に、削除日時が設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -その投稿に添付されたアンケートに投票された時に発生します。 - -* `choice`に、選択肢IDが設定されます。 -* `userId`に、投票を行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### 投稿のキャプチャを解除する - -その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。 - -次のメッセージを送信します: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャを解除したい投稿の`id`を設定します。 - -このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 - -# チャンネル一覧 -## `main` -アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `renote` -自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。 - -#### `mention` -誰かからメンションされたときに発生するイベントです。 - -#### `readAllNotifications` -自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。 - -#### `meUpdated` -自分の情報が更新されたことを表すイベントです。 - -#### `follow` -自分が誰かをフォローしたときに発生するイベントです。 - -#### `unfollow` -自分が誰かのフォローを解除したときに発生するイベントです。 - -#### `followed` -自分が誰かにフォローされたときに発生するイベントです。 - -## `homeTimeline` -ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -タイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `localTimeline` -ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `hybridTimeline` -ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ソーシャルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `globalTimeline` -グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 diff --git a/src/docs/nl-NL/theme.md b/src/docs/nl-NL/theme.md deleted file mode 100644 index a406f3433..000000000 --- a/src/docs/nl-NL/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# テーマ - -テーマを設定して、Misskeyクライアントの見た目を変更できます。 - -## テーマの設定 -設定 > テーマ - -## テーマを作成する -テーマコードはJSON5で記述されたテーマオブジェクトです。 テーマは以下のようなオブジェクトです。 -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... テーマの一意なID。UUIDをおすすめします。 -* `name` ... テーマ名 -* `author` ... テーマの作者 -* `desc` ... テーマの説明(オプション) -* `base` ... 明るいテーマか、暗いテーマか - * `light`にすると明るいテーマになり、`dark`にすると暗いテーマになります。 - * テーマはここで設定されたベーステーマを継承します。 -* `props` ... テーマのスタイル定義。これから説明します。 - -### テーマのスタイル定義 -`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 - -#### バリューで使える構文 -* 16進数で表された色 - * 例: `#00ff00` -* `rgb(r, g, b)`形式で表された色 - * 例: `rgb(0, 255, 0)` -* `rgb(r, g, b, a)`形式で表された透明度を含む色 - * 例: `rgba(0, 255, 0, 0.5)` -* 他のキーの値の参照 - * `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。 - * 例: `@panel` -* 定数(後述)の参照 - * `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。 - * 例: `$main` -* 関数(後述) - * `:{関数名}<{引数}<{色}` - -#### 定数 -「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 キー名を`$`で始めると、そのキーはCSS変数として出力されません。 - -#### 関数 -wip diff --git a/src/docs/nl-NL/timelines.md b/src/docs/nl-NL/timelines.md deleted file mode 100644 index 36ba61bd2..000000000 --- a/src/docs/nl-NL/timelines.md +++ /dev/null @@ -1,15 +0,0 @@ -# タイムラインの比較 - -https://docs.google.com/spreadsheets/d/1lxQ2ugKrhz58Bg96HTDK_2F98BUritkMyIiBkOByjHA/edit?usp=sharing - -## ホーム -自分のフォローしているユーザーの投稿 - -## ローカル -全てのローカルユーザーの「ホーム」指定されていない投稿 - -## ソーシャル -自分のフォローしているユーザーの投稿と、全てのローカルユーザーの「ホーム」指定されていない投稿 - -## グローバル -全てのローカルユーザーの「ホーム」指定されていない投稿と、サーバーに届いた全てのリモートユーザーの「ホーム」指定されていない投稿 diff --git a/src/docs/no-NO/admin/disable-timelines.md b/src/docs/no-NO/admin/disable-timelines.md deleted file mode 100644 index b081e35ab..000000000 --- a/src/docs/no-NO/admin/disable-timelines.md +++ /dev/null @@ -1,8 +0,0 @@ -# LTL/STL/GTLの無効化 -Misskeyでは、LTL/STL/GTLをそれぞれ無効化することができます。有効/無効を切り替えるには、インスタンスコントロールパネルで設定します。 - -LTLやSTLは、そのインスタンス全員の投稿が見れるため、新規のユーザーにとってはユーザーを探す必要がなくなり、興味のあるユーザーを見つけやすいという利点があります。 しかし同時に、フォロー機能が活用されなくなったり、不適切な投稿が目につきやすくなったり、チャットのようになることで内輪感が生じて逆に新規ユーザーが参加しにくくなるといったデメリットも持ち合わせています。 サーバーによってメリット/デメリットどちらが優勢かは異なるので、オプションとして無効にできるようになっています。 もしデメリットの方が上回っていると感じたら、それらのタイムラインを無効化することも検討してください。 - -
⚠️ 無効化を行うと、ユーザーが困惑し、短期的に見て利用者が減る可能性があります。そのため、無効化の際は影響を慎重に検討し、事前に説明してフォローを整える期間を一定程度設けることを推奨します。
- -なお、管理者/モデレーターは、これらのタイムラインの無効化状態は適用されず、引き続き利用することが可能です。 diff --git a/src/docs/no-NO/admin/faq.md b/src/docs/no-NO/admin/faq.md deleted file mode 100644 index 317b4e065..000000000 --- a/src/docs/no-NO/admin/faq.md +++ /dev/null @@ -1,5 +0,0 @@ -# よくある質問 -ここでは、サーバー管理者向けのよくある質問を掲載しています。 - -## デフォルトテーマを設定したい -現在、デフォルトテーマ設定機能は実装されていません。 diff --git a/src/docs/no-NO/advanced/aiscript.md b/src/docs/no-NO/advanced/aiscript.md deleted file mode 100644 index 604d17daa..000000000 --- a/src/docs/no-NO/advanced/aiscript.md +++ /dev/null @@ -1,7 +0,0 @@ -# AiScript -AiScriptは、Misskeyで使用できるスクリプト言語です。 - -
ℹ️ AiScript実装はMisskeyとは別リポジトリで、オープンソースで公開されています。
- -## 使い方 -AiScriptの構文や組み込み関数などのドキュメントは、[こちら](https://github.com/syuilo/aiscript/tree/master/docs)で公開されています。 diff --git a/src/docs/no-NO/advanced/api.md b/src/docs/no-NO/advanced/api.md deleted file mode 100644 index 76019b614..000000000 --- a/src/docs/no-NO/advanced/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス、Bot等(以下「アプリケーション」と呼びます)を開発できます。 ストリーミングAPIもあるので、リアルタイム性のあるアプリケーションを作ることも可能です。 - -APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。 - -## アクセストークンの取得 -基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。 - -* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む -* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む - -### 自分自身のアクセストークンを手動発行する -「設定 > API」で、自分のアクセストークンを発行できます。 - -[「APIの使い方」へ進む](#APIの使い方) - -### アプリケーション利用者にアクセストークンの発行をリクエストする -アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。 - -#### Step 1 - -UUIDを生成する。以後これをセッションIDと呼びます。 - -> このセッションIDは毎回生成し、使いまわさないようにしてください。 - -#### Step 2 - -`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。 -> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます: -* `name` ... アプリケーション名 - * > 例: `MissDeck` -* `icon` ... アプリケーションのアイコン画像URL - * > 例: `https://missdeck.example.com/icon.png` -* `callback` ... 認証が終わった後にリダイレクトするURL - * > 例: `https://missdeck.example.com/callback` - * リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます -* `permission` ... アプリケーションが要求する権限 - * > 例: `write:notes,write:following,read:drive` - * 要求する権限を`,`で区切って列挙します - * どのような権限があるかは[APIリファレンス](/api-doc)で確認できます - -#### Step 3 -ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。 - -レスポンスに含まれるプロパティ: -* `token` ... ユーザーのアクセストークン -* `user` ... ユーザーの情報 - -[「APIの使い方」へ進む](#APIの使い方) - -## APIの使い方 -**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。 - -* [APIリファレンス](/api-doc) -* [ストリーミングAPI](./stream) diff --git a/src/docs/no-NO/advanced/create-plugin.md b/src/docs/no-NO/advanced/create-plugin.md deleted file mode 100644 index 0d2fa1917..000000000 --- a/src/docs/no-NO/advanced/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# プラグインの作成 -Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。 - -## メタデータ -プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。 - -### name -プラグイン名 - -### author -プラグイン作者 - -### version -プラグインバージョン。数値を指定してください。 - -### description -プラグインの説明 - -### permissions -プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。 - -### config -プラグインの設定情報を表すオブジェクト。 キーに設定名、値に以下のプロパティを含めます。 - -#### type -設定値の種類を表す文字列。以下から選択します。 string number boolean - -#### label -ユーザーに表示する設定名 - -#### description -設定の説明 - -#### default -設定のデフォルト値 - -## APIリファレンス -AiScript標準で組み込まれているAPIは掲載しません。 - -### Mk:dialog(title text type) -ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。 - -### Mk:confirm(title text type) -確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。 - -### Mk:api(endpoint params) -Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。 - -### Mk:save(key value) -任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。 - -### Mk:load(key) -Mk:saveで永続化した指定の名前の値を読み取ります。 - -### Plugin:register_post_form_action(title fn) -投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。 - -### Plugin:register_note_action(title fn) -ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 - -### Plugin:register_user_action(title fn) -ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。 - -### Plugin:register_note_view_interruptor(fn) -UIに表示されるノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:register_note_post_interruptor(fn) -ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:open_url(url) -第一引数に渡されたURLをブラウザの新しいタブで開きます。 - -### Plugin:config -プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。 diff --git a/src/docs/no-NO/advanced/develop-bot.md b/src/docs/no-NO/advanced/develop-bot.md deleted file mode 100644 index 7f825e9bc..000000000 --- a/src/docs/no-NO/advanced/develop-bot.md +++ /dev/null @@ -1,6 +0,0 @@ -# Botの作成 -[Misskey API](./api)を利用してBotの開発が可能です。 また、いくつかのBot実装が公開されているため、ぜひ参考にしてください。 - -- [syuilo/ai](https://github.com/syuilo/ai) ... Node.js上で動く、TypeScript製Bot実装 - -Botを作成したときは、プロフィール設定からBotフラグをオンにしておくことを強くおすすめします。 diff --git a/src/docs/no-NO/advanced/reversi-bot.md b/src/docs/no-NO/advanced/reversi-bot.md deleted file mode 100644 index 7ab2a7212..000000000 --- a/src/docs/no-NO/advanced/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# MisskeyリバーシBotの開発 -Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。 - -1. `games/reversi`ストリームに以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - -2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる - * イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている - -3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する - -4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - * `game`: `game`の`id` - -5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う - -6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する - -7. ゲームが開始すると、`started`イベントが流れてくる - * イベントの中身にはゲーム情報が含まれている - -8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述) - -9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる - * `color`として石の色が含まれている - * `pos`として位置情報が含まれている - -## 位置の計算法 -8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### X,Y座標 から インデックス に変換する -``` -pos = x + (y * mapWidth) -``` -`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます: -``` -mapWidth = map[0].length -``` - -### インデックス から X,Y座標 に変換する -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## マップ情報 -マップ情報は、ゲーム情報の`map`に入っています。 文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 それをもとにマップのデザインを知る事が出来ます: -* `(スペース)` ... マス無し -* `-` ... マス -* `b` ... 初期配置される黒石 -* `w` ... 初期配置される白石 - -例えば、4*4の次のような単純なマップがあるとします: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -この場合、マップデータはこのようになります: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## ユーザーにフォームを提示して対話可能Botを作成する -ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。 - -フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します: -```javascript -{ - type: 'init-form', - body: [フォームコントロールの配列] -} -``` - -フォームコントロールの配列については今から説明します。 フォームコントロールは、次のようなオブジェクトです: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... コントロールのID。 `type` ... コントロールの種類。後述します。 `label` ... コントロールと一緒に表記するテキスト。 `value` ... コントロールのデフォルト値。 - -### フォームの操作を受け取る -ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### フォームコントロールの種類 -#### スイッチ -type: `switch` スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。 - -##### プロパティ -`label` ... スイッチに表記するテキスト。 - -#### ラジオボタン -type: `radio` ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。 - -##### プロパティ -`items` ... ラジオボタンの選択肢。例: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '強', - value: 3 -}] -``` - -#### スライダー -type: `slider` スライダーを表示します。 - -##### プロパティ -`min` ... スライダーの下限。 `max` ... スライダーの上限。 `step` ... 入力欄で刻むステップ値。 - -#### テキストボックス -type: `textbox` テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。 - -## ユーザーにメッセージを表示する -設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 メッセージを表示するには、次のメッセージをストリームに送信します: -```javascript -{ - type: 'message', - body: { - text: 'メッセージ内容', - type: 'メッセージの種類' - } -} -``` -メッセージの種類: `success`, `info`, `warning`, `error`。 - -## 投了する -投了をするには、このエンドポイントにリクエストします。 diff --git a/src/docs/no-NO/advanced/share-page.md b/src/docs/no-NO/advanced/share-page.md deleted file mode 100644 index 4fb7ded0b..000000000 --- a/src/docs/no-NO/advanced/share-page.md +++ /dev/null @@ -1,54 +0,0 @@ -# シェアページ -`/share`を開くと、共有用の投稿フォームを開くことができます。 ここではシェアページで利用できるクエリ文字列の一覧を示します。 - -## クエリ文字列一覧 -### 文字 - -
-
title
-
タイトルです。本文の先頭に[ … ]と挿入されます。
-
text
-
本文です。
-
url
-
URLです。末尾に挿入されます。
-
- -### リプライ情報 -以下のいずれか - -
-
replyId
-
リプライ先のノートid
-
replyUri
-
リプライ先のUrl(リモートのノートオブジェクトを指定)
-
- -### Renote情報 -以下のいずれか - -
-
renoteId
-
Renote先のノートid
-
renoteUri
-
Renote先のUrl(リモートのノートオブジェクトを指定)
-
- -### 公開範囲 -※specifiedに相当する値はvisibility=specifiedとvisibleAccts/visibleUserIdsで指定する - -
-
visibility
-
公開範囲 ['public' | 'home' | 'followers' | 'specified']
-
localOnly
-
0(false) or 1(true)
-
visibleUserIds
-
specified時のダイレクト先のユーザーid カンマ区切りで
-
visibleAccts
-
specified時のダイレクト先のacct(@?username[@host]) カンマ区切りで
-
- -### ファイル -
-
fileIds
-
添付したいファイルのid(カンマ区切りで)
-
diff --git a/src/docs/no-NO/advanced/stream.md b/src/docs/no-NO/advanced/stream.md deleted file mode 100644 index 0e5edd2b0..000000000 --- a/src/docs/no-NO/advanced/stream.md +++ /dev/null @@ -1,350 +0,0 @@ -# ストリーミングAPI - -ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。 - -## ストリームに接続する - -ストリーミングAPIを利用するには、まずMisskeyサーバーに**websocket**接続する必要があります。 - -以下のURLに、`i`というパラメータ名で認証情報を含めて、websocket接続してください。例: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。 - -
ℹ️ 認証情報の取得については、こちらのドキュメントをご確認ください。
- ---- - -認証情報は省略することもできますが、その場合非ログインでの利用ということになり、受信できる情報や可能な操作は限られます。例: - -``` -%WS_URL%/streaming -``` - ---- - -ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。 - -**ストリームでのやり取りはすべてJSONです。** - -## チャンネル -MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。 - -ひとつのストリーム上で、同時に複数のチャンネルに接続することができます。 - -### チャンネルに接続する -チャンネルに接続するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -ここで、 -* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。 -* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。 -* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。 - -
ℹ️ IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。
- -### チャンネルからのメッセージを受け取る -例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。 - -チャンネルがメッセージを発すると、次のようなデータがJSONでストリームに流れてきます: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。 -* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。 -* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。 - -### チャンネルに向けてメッセージを送信する -チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。 - -チャンネルにメッセージを送信するには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。 -* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。 -* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。 - -### チャンネルから切断する -チャンネルから切断するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。 - -## ストリームを経由してAPIリクエストする - -ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。 - -ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -ここで、 -* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 -* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 -* `data`には、エンドポイントのパラメータを含めます。 - -
ℹ️ APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。
- -### レスポンスの受信 - -APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。 - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -ここで、 -* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 -* `body`には、レスポンスが含まれています。 - -## 投稿のキャプチャ - -Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。 - -例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。 - -しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。 - -この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。 - -### 投稿をキャプチャする - -投稿をキャプチャするには、ストリームに次のようなメッセージを送信します: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャしたい投稿の`id`を設定します。 - -このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 - -例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -ここで、 -* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。 -* `body`内の`type`に、イベントの種類が設定されます。 -* `body`内の`body`に、イベントの詳細が設定されます。 - -#### イベントの種類 - -##### `reacted` -その投稿にリアクションがされた時に発生します。 - -* `reaction`に、リアクションの種類が設定されます。 -* `userId`に、リアクションを行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -その投稿が削除された時に発生します。 - -* `deletedAt`に、削除日時が設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -その投稿に添付されたアンケートに投票された時に発生します。 - -* `choice`に、選択肢IDが設定されます。 -* `userId`に、投票を行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### 投稿のキャプチャを解除する - -その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。 - -次のメッセージを送信します: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャを解除したい投稿の`id`を設定します。 - -このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 - -# チャンネル一覧 -## `main` -アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `renote` -自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。 - -#### `mention` -誰かからメンションされたときに発生するイベントです。 - -#### `readAllNotifications` -自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。 - -#### `meUpdated` -自分の情報が更新されたことを表すイベントです。 - -#### `follow` -自分が誰かをフォローしたときに発生するイベントです。 - -#### `unfollow` -自分が誰かのフォローを解除したときに発生するイベントです。 - -#### `followed` -自分が誰かにフォローされたときに発生するイベントです。 - -## `homeTimeline` -ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -タイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `localTimeline` -ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `hybridTimeline` -ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ソーシャルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `globalTimeline` -グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 diff --git a/src/docs/no-NO/aiscript.md b/src/docs/no-NO/aiscript.md deleted file mode 100644 index 6c28b446e..000000000 --- a/src/docs/no-NO/aiscript.md +++ /dev/null @@ -1,4 +0,0 @@ -# AiScript - -## 関数 -デフォルトで値渡しです。 diff --git a/src/docs/no-NO/api.md b/src/docs/no-NO/api.md deleted file mode 100644 index 76019b614..000000000 --- a/src/docs/no-NO/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス、Bot等(以下「アプリケーション」と呼びます)を開発できます。 ストリーミングAPIもあるので、リアルタイム性のあるアプリケーションを作ることも可能です。 - -APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。 - -## アクセストークンの取得 -基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。 - -* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む -* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む - -### 自分自身のアクセストークンを手動発行する -「設定 > API」で、自分のアクセストークンを発行できます。 - -[「APIの使い方」へ進む](#APIの使い方) - -### アプリケーション利用者にアクセストークンの発行をリクエストする -アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。 - -#### Step 1 - -UUIDを生成する。以後これをセッションIDと呼びます。 - -> このセッションIDは毎回生成し、使いまわさないようにしてください。 - -#### Step 2 - -`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。 -> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます: -* `name` ... アプリケーション名 - * > 例: `MissDeck` -* `icon` ... アプリケーションのアイコン画像URL - * > 例: `https://missdeck.example.com/icon.png` -* `callback` ... 認証が終わった後にリダイレクトするURL - * > 例: `https://missdeck.example.com/callback` - * リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます -* `permission` ... アプリケーションが要求する権限 - * > 例: `write:notes,write:following,read:drive` - * 要求する権限を`,`で区切って列挙します - * どのような権限があるかは[APIリファレンス](/api-doc)で確認できます - -#### Step 3 -ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。 - -レスポンスに含まれるプロパティ: -* `token` ... ユーザーのアクセストークン -* `user` ... ユーザーの情報 - -[「APIの使い方」へ進む](#APIの使い方) - -## APIの使い方 -**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。 - -* [APIリファレンス](/api-doc) -* [ストリーミングAPI](./stream) diff --git a/src/docs/no-NO/create-plugin.md b/src/docs/no-NO/create-plugin.md deleted file mode 100644 index 0d2fa1917..000000000 --- a/src/docs/no-NO/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# プラグインの作成 -Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。 - -## メタデータ -プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。 - -### name -プラグイン名 - -### author -プラグイン作者 - -### version -プラグインバージョン。数値を指定してください。 - -### description -プラグインの説明 - -### permissions -プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。 - -### config -プラグインの設定情報を表すオブジェクト。 キーに設定名、値に以下のプロパティを含めます。 - -#### type -設定値の種類を表す文字列。以下から選択します。 string number boolean - -#### label -ユーザーに表示する設定名 - -#### description -設定の説明 - -#### default -設定のデフォルト値 - -## APIリファレンス -AiScript標準で組み込まれているAPIは掲載しません。 - -### Mk:dialog(title text type) -ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。 - -### Mk:confirm(title text type) -確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。 - -### Mk:api(endpoint params) -Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。 - -### Mk:save(key value) -任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。 - -### Mk:load(key) -Mk:saveで永続化した指定の名前の値を読み取ります。 - -### Plugin:register_post_form_action(title fn) -投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。 - -### Plugin:register_note_action(title fn) -ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 - -### Plugin:register_user_action(title fn) -ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。 - -### Plugin:register_note_view_interruptor(fn) -UIに表示されるノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:register_note_post_interruptor(fn) -ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:open_url(url) -第一引数に渡されたURLをブラウザの新しいタブで開きます。 - -### Plugin:config -プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。 diff --git a/src/docs/no-NO/custom-emoji.md b/src/docs/no-NO/custom-emoji.md deleted file mode 100644 index ed2e92be1..000000000 --- a/src/docs/no-NO/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# カスタム絵文字 -カスタム絵文字は、インスタンスで用意された画像を絵文字のように使える機能です。 ノート、リアクション、チャット、自己紹介、名前などの場所で使うことができます。 カスタム絵文字をそれらの場所で使うには、絵文字ピッカーボタン(ある場合)を押すか、`:`を入力して絵文字サジェストを表示します。 テキスト内に`:foo:`のような形式の文字列が見つかると、`foo`の部分がカスタム絵文字名と解釈され、表示時には対応したカスタム絵文字に置き換わります。 diff --git a/src/docs/no-NO/deck.md b/src/docs/no-NO/deck.md deleted file mode 100644 index 8057e262f..000000000 --- a/src/docs/no-NO/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# デッキ - -デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。 - -## カラムの追加 -デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。 - -## カラムの移動 -カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。 - -## カラムの水平分割 -カラムは左右だけでなく、上下に並べることもできます。 カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 上下分割を解除するには、カラムメニューの「右に出す」を選択します。 - -## カラムの設定 -カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。 - -## デッキの設定 -デッキに関する設定は、[settings/deck](/settings/deck)で行えます。 diff --git a/src/docs/no-NO/features/antenna.md b/src/docs/no-NO/features/antenna.md deleted file mode 100644 index 94ad9e4ae..000000000 --- a/src/docs/no-NO/features/antenna.md +++ /dev/null @@ -1,4 +0,0 @@ -# アンテナ -アンテナは、自由に条件を設定して、合致するノートを自動で収集することができる機能です。 - -条件を設定したアンテナが作成された状態で、条件に合致するノートが投稿されると、リアルタイムでそのアンテナのタイムラインにノートが追加されます。 diff --git a/src/docs/no-NO/features/custom-emoji.md b/src/docs/no-NO/features/custom-emoji.md deleted file mode 100644 index ed2e92be1..000000000 --- a/src/docs/no-NO/features/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# カスタム絵文字 -カスタム絵文字は、インスタンスで用意された画像を絵文字のように使える機能です。 ノート、リアクション、チャット、自己紹介、名前などの場所で使うことができます。 カスタム絵文字をそれらの場所で使うには、絵文字ピッカーボタン(ある場合)を押すか、`:`を入力して絵文字サジェストを表示します。 テキスト内に`:foo:`のような形式の文字列が見つかると、`foo`の部分がカスタム絵文字名と解釈され、表示時には対応したカスタム絵文字に置き換わります。 diff --git a/src/docs/no-NO/features/deck.md b/src/docs/no-NO/features/deck.md deleted file mode 100644 index 8057e262f..000000000 --- a/src/docs/no-NO/features/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# デッキ - -デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。 - -## カラムの追加 -デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。 - -## カラムの移動 -カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。 - -## カラムの水平分割 -カラムは左右だけでなく、上下に並べることもできます。 カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 上下分割を解除するには、カラムメニューの「右に出す」を選択します。 - -## カラムの設定 -カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。 - -## デッキの設定 -デッキに関する設定は、[settings/deck](/settings/deck)で行えます。 diff --git a/src/docs/no-NO/features/drive.md b/src/docs/no-NO/features/drive.md deleted file mode 100644 index b82a41082..000000000 --- a/src/docs/no-NO/features/drive.md +++ /dev/null @@ -1,17 +0,0 @@ -# ドライブ -ドライブは、Misskey上でファイルを管理できる機能です。 - -[ドライブのページ](/my/drive)から任意のファイルをアップロードできるほか、アバターに設定した画像や、ノートに添付したファイルなどもすべてドライブにアップロードされます。 - -
⚠️ ドライブからファイルを削除すると、そのファイルが添付されたノートも消えます。
- -ドライブにアップロードされたファイルは、いつでもダウンロードすることができるほか、ノート作成時に「ドライブからファイルを添付」することでファイルを再利用することもできます。 - -ドライブ内にフォルダを作り、複数のファイルをまとめて整理することもできます。 - -## 閲覧注意 (NSFW) -
ℹ️ この項目が閲覧注意なわけではありません
- -閲覧注意またはNSFW (Not safe for work) は、ドライブのファイルに設定することができるフラグです。 閲覧注意フラグを設定されたファイルは、表示される際に閲覧者の操作なしには表示されなくなります。 このフラグは、例えば職場や公共の場で閲覧するのに適切でないと思われる画像などに設定し、そのような画像が突然表示されてしまうことを防ぐ目的で使われます。 - -このフラグは手動でオンオフを切り替えられるほか、モデレーターの判断で設定される場合もあります。 diff --git a/src/docs/no-NO/features/favorite.md b/src/docs/no-NO/features/favorite.md deleted file mode 100644 index a0e5f8bf7..000000000 --- a/src/docs/no-NO/features/favorite.md +++ /dev/null @@ -1,4 +0,0 @@ -# お気に入り -[ノート](./node)をお気に入りとして登録できる機能です。 お気に入り登録したノートは、[お気に入りページ](./my/favorites)で一覧することができます。 お気に入りに登録したことは相手に通知されず、お気に入りは自分しか見ることができません。 - -ノートをお気に入り登録するには、ノートメニューの「お気に入り」を押します。お気に入り解除するには、ノートメニューの「お気に入り解除」を押します。 diff --git a/src/docs/no-NO/features/follow.md b/src/docs/no-NO/features/follow.md deleted file mode 100644 index 3c1ea7bbe..000000000 --- a/src/docs/no-NO/features/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# フォロー -ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。 diff --git a/src/docs/no-NO/features/keyboard-shortcut.md b/src/docs/no-NO/features/keyboard-shortcut.md deleted file mode 100644 index 8659ace98..000000000 --- a/src/docs/no-NO/features/keyboard-shortcut.md +++ /dev/null @@ -1,66 +0,0 @@ -# キーボードショートカット - -## グローバル -これらのショートカットは基本的にどこでも使えます。 - - - - - - - - - - - -
ショートカット効果由来
P, N新規投稿Post, New, Note
Tタイムラインの最も新しい投稿にフォーカスTimeline, Top
Shift + N通知を表示/隠すNotifications
S検索Search
H, ?ヘルプを表示Help
- -## 投稿にフォーカスされた状態 - - - - - - - - - - - - - - - - - - -
ショートカット効果由来
, K, Shift + Tab上の投稿にフォーカスを移動-
, J, Tab下の投稿にフォーカスを移動-
R返信フォームを開くReply
QRenoteフォームを開くQuote
Ctrl + Q即刻Renoteする(フォームを開かずに)-
E, A, +リアクションフォームを開くEmote, reAction
0~9数字に対応したリアクションをする(対応については後述)-
F, Bお気に入りに登録Favorite, Bookmark
Del, Ctrl + D投稿を削除Delete
M, O投稿に対するメニューを開くMore, Other
SCWで隠された部分を表示 or 隠すShow, See
Escフォーカスを外す-
- -## Renoteフォーム - - - - - - - - - -
ショートカット効果由来
EnterRenoteする-
Qフォームを展開するQuote
Escフォームを閉じる-
- -## リアクションフォーム -デフォルトで「👍」にフォーカスが当たっている状態です。 - - - - - - - - - - - - - -
ショートカット効果由来
, K上のリアクションにフォーカスを移動-
, J下のリアクションにフォーカスを移動-
, H, Shift + Tab左のリアクションにフォーカスを移動-
, L, Tab右のリアクションにフォーカスを移動-
Enter, Space, +リアクション確定-
0~9数字に対応したリアクションで確定-
Escリアクションするのをやめる-
diff --git a/src/docs/no-NO/features/mfm.md b/src/docs/no-NO/features/mfm.md deleted file mode 100644 index 5be2df4f3..000000000 --- a/src/docs/no-NO/features/mfm.md +++ /dev/null @@ -1,12 +0,0 @@ -# MFM -MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます。 - -## MFMが使用可能な場所の例 -- ノート本文 -- CW注釈 -- ユーザーの名前 -- ユーザーの自己紹介 - -## 開発者向け情報 -MFMのパーサー実装はライブラリとして公開されており、簡単にクライアントにMFMを組み込むことが可能です。 -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptパーサー実装 diff --git a/src/docs/no-NO/features/mute-and-block.md b/src/docs/no-NO/features/mute-and-block.md deleted file mode 100644 index d78a7cea4..000000000 --- a/src/docs/no-NO/features/mute-and-block.md +++ /dev/null @@ -1,41 +0,0 @@ -# ミュートとブロック -好みではないユーザーがいる場合は、ミュートを行うことでそのユーザーが自分から見えないようにすることができます。 また、より強力な措置として、ブロックを行うことでそのユーザーから自分のコンテンツが見えないようになるほか、自分に対して関わることができないようにすることができます。 ミュートされていることは相手は分かりませんが、ブロックされていることは相手に分かります。どちらを選ぶかはご自身の判断で行ってください。 - -
ℹ️ ミュートとブロックは併用できます。
- -
⚠️ 利用規約に違反するような、迷惑なユーザーがいる場合は運営者に報告することも検討してください。
- -設定>ミュートとブロック から、自分がミュートまたはブロックしているユーザー一覧を確認することができます。 - -## ミュート -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -- タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -- そのユーザーからの通知 -- メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 -- など - -ユーザーをミュートするには、対象のユーザーのユーザーページのメニューを開き、「ミュート」ボタンを押します。 - -
ℹ️ ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。
- -## ブロック -ユーザーをブロックすると、そのユーザーからあなたのコンテンツが見えないようになり、またあなたに対して以下のようなアクションをすることができなくなります。 - -- フォローする -- ユーザーリストに追加する -- 返信する、Renoteする -- リアクションする、アンケートに投票する -- メッセージを送信する -- など - -また、 - -- ブロックする際に既にそのユーザーからフォローされていた場合はフォローが解除されます。 -- ブロックする際に既にそのユーザーがあなたをユーザーリストに入れていた場合はそのリストからあなたが削除されます。 - -ユーザーをブロックするには、対象のユーザーのユーザーページのメニューを開き、「ブロック」ボタンを押します。 - -
⚠️ ブロックを行ったこと自体は相手に通知されませんが、フォローを行ったりなどの上記のアクションが行えなくなるので間接的にブロックされていることは分かります。
- -
⚠️ 相手から自分のコンテンツが見えなくなりますが、相手がアカウントを切り替えたりログアウト状態になれば見ることができます。あくまで簡易的、補助的なものとしてお考えください。
diff --git a/src/docs/no-NO/features/mute.md b/src/docs/no-NO/features/mute.md deleted file mode 100644 index 6a9608662..000000000 --- a/src/docs/no-NO/features/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# ミュート - -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -* タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -* そのユーザーからの通知 -* メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 - -ユーザーをミュートするには、対象のユーザーのユーザーページに表示されている「ミュート」ボタンを押します。 - -ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。 - -設定>ミュート から、自分がミュートしているユーザー一覧を確認することができます。 diff --git a/src/docs/no-NO/features/note.md b/src/docs/no-NO/features/note.md deleted file mode 100644 index 305ff626f..000000000 --- a/src/docs/no-NO/features/note.md +++ /dev/null @@ -1,54 +0,0 @@ -# ノート -ノートは、Misskeyに投稿される、文章、ファイル、アンケートなどを含むコンテンツで、Misskeyの中心的概念です。また、そのノートを作成する行為自体もノートと呼ばれます。 - -ノートが作成されると、[タイムライン](./timeline)に追加され、自分の[フォロワー](./follow)やサーバーのユーザーが見れるようになります。 - -ノートには、[リアクション](./reaction)を行うことができます。また、返信や引用もできます。 - -ノートを[お気に入り](./favorite)登録することで、後で簡単に見返すことができます。 - -## ノートを作成する -ノートを作成するには、画面上にある鉛筆マークのボタンを押して、作成フォームを開きます。作成フォームに内容を入力し、「ノート」ボタンを押すことでノートが作成されます。 ノートには、画像、動画など任意のファイルや、[アンケート](./poll)を添付することができます。また、本文中には[MFM](./mfm)が使用でき、[メンション](./mention)や[ハッシュタグ](./hashtag)を含めることもできます。 他にも、CWや公開範囲といった設定も行えます(詳細は後述)。 -
ℹ️ コンピューターのクリップボードに画像データがある状態で、フォーム内のテキストボックスにペーストするとその画像を添付することができます。
-
ℹ️ テキストボックス内でCtrl + Enterを押すことでも投稿できます。
- -## Renote -既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノートをRenoteと呼びます。 自分がフォローしているユーザーの、気に入ったノートを自分のフォロワーに共有したい場合や、過去の自分のノートを再度共有したい場合に使います。 同じノートに対して無制限にRenoteを行うことができますが、あまり連続して使用すると迷惑になる場合もあるので、注意しましょう。 -
⚠️ 公開範囲がフォロワーやダイレクトのノートはRenoteできません
- -Renoteを削除するには、Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 - -## CW -Contents Warningの略で、ノートの内容を、閲覧者の操作なしには表示しないようにできる機能です。主に長大な内容を隠すためや、ネタバレ防止などに使うことができます。 設定するには、フォームの「内容を隠す」ボタン(目のアイコン)を押します。すると新しい入力エリアが表れるので、そこに内容の要約を記入します。 - -## 公開範囲 -ノートごとに、そのノートが公開される範囲を設定することができます。フォームの「ノート」ボタンの左にあるアイコンを押すと公開範囲を以下から選択できます。 - -### パブリック -全ての人に対してノートが公開されるほか、サーバーの全てのタイムライン(ホームタイムライン、ローカルタイムライン、ソーシャルタイムライン、グローバルタイムライン)にノートが流れます。 -
⚠️ アカウントがサイレンス状態の時は、この公開範囲は使用できません。
- -### ホーム -全ての人に対してノートが公開されますが、フォロワー以外のローカルタイムライン、ソーシャルタイムライン、グローバルタイムラインにはノートは流れません。 - -### フォロワー -自分のフォロワーに対してのみノートを公開します。フォロワーの全てのタイムラインに流れます。 - -### ダイレクト -指定したユーザーに対してのみノートを公開します。指定したユーザーの全てのタイムラインに流れます。 - -### 「ローカルのみ」オプション -このオプションを有効にすると、リモートにノートを連合しなくなります。 - -### 公開範囲の比較 - - - - -
パブリックホームフォロワーダイレクト
フォロワーのLTL/STL/GTL
非フォロワーのLTL/STL/GTL
- -## ピン留め -ノートをピン留めすると、ユーザーページに常にそのノートを表示しておくことができます。 ノートのメニューを開き、「ピン留め」を選択してピン留めできます。 複数のノートをピン留めできます。 - -## ウォッチ -ノートをウォッチすると、自分以外のノートへのリアクションや返信などの通知を受け取ることができます。 ノートのメニューを開き、「ウォッチ」を選択してウォッチできます。 diff --git a/src/docs/no-NO/features/pages.md b/src/docs/no-NO/features/pages.md deleted file mode 100644 index a7311b95e..000000000 --- a/src/docs/no-NO/features/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# Pages - -## 変数 -変数を使うことで動的なページを作成できます。テキスト内で { 変数名 } と書くとそこに変数の値を埋め込めます。例えば Hello { thing } world! というテキストで、変数(thing)の値が ai だった場合、テキストは Hello ai world! になります。 - -変数の評価(値を算出すること)は上から下に行われるので、ある変数の中で自分より下の変数を参照することはできません。例えば上から A、B、C と3つの変数を定義したとき、Cの中でABを参照することはできますが、Aの中でBCを参照することはできません。 - -ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。 - -関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。 diff --git a/src/docs/no-NO/features/reaction.md b/src/docs/no-NO/features/reaction.md deleted file mode 100644 index 4d479fd41..000000000 --- a/src/docs/no-NO/features/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# リアクション -他の人のノートに、絵文字を付けて簡単にあなたの反応を伝えられる機能です。 リアクションするには、ノートの + アイコンをクリックしてピッカーを表示し、絵文字を選択します。 リアクションには[カスタム絵文字](./custom-emoji)も使用できます。 - -## リアクションピッカーのカスタマイズ -ピッカーに表示される絵文字を自分好みにカスタマイズすることができます。 設定の「リアクション」で設定します。 - -## リモート投稿へのリアクションについて -リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。 - -## リモートからのリアクションについて -リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。 diff --git a/src/docs/no-NO/features/silence.md b/src/docs/no-NO/features/silence.md deleted file mode 100644 index 7e26feab0..000000000 --- a/src/docs/no-NO/features/silence.md +++ /dev/null @@ -1,6 +0,0 @@ -# サイレンス -サイレンスは、アカウントに設定される状態のひとつです。 - -アカウントがサイレンス状態になると、ノートの公開範囲をパブリックにできなくなります。 ホーム、フォロワー、ダイレクトは選択可能なため、サイレンスを受けた場合でもフォロワーやあなたのユーザーページを直接訪れた場合は投稿を閲覧できますが、GTL(連合タイムライン)やLTL(ローカルタイムライン)には投稿が流れません。 - -アカウントのサイレンス状態は、サーバーのモデレーターによって有効化/無効化されます。 diff --git a/src/docs/no-NO/features/theme.md b/src/docs/no-NO/features/theme.md deleted file mode 100644 index a406f3433..000000000 --- a/src/docs/no-NO/features/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# テーマ - -テーマを設定して、Misskeyクライアントの見た目を変更できます。 - -## テーマの設定 -設定 > テーマ - -## テーマを作成する -テーマコードはJSON5で記述されたテーマオブジェクトです。 テーマは以下のようなオブジェクトです。 -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... テーマの一意なID。UUIDをおすすめします。 -* `name` ... テーマ名 -* `author` ... テーマの作者 -* `desc` ... テーマの説明(オプション) -* `base` ... 明るいテーマか、暗いテーマか - * `light`にすると明るいテーマになり、`dark`にすると暗いテーマになります。 - * テーマはここで設定されたベーステーマを継承します。 -* `props` ... テーマのスタイル定義。これから説明します。 - -### テーマのスタイル定義 -`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 - -#### バリューで使える構文 -* 16進数で表された色 - * 例: `#00ff00` -* `rgb(r, g, b)`形式で表された色 - * 例: `rgb(0, 255, 0)` -* `rgb(r, g, b, a)`形式で表された透明度を含む色 - * 例: `rgba(0, 255, 0, 0.5)` -* 他のキーの値の参照 - * `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。 - * 例: `@panel` -* 定数(後述)の参照 - * `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。 - * 例: `$main` -* 関数(後述) - * `:{関数名}<{引数}<{色}` - -#### 定数 -「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 キー名を`$`で始めると、そのキーはCSS変数として出力されません。 - -#### 関数 -wip diff --git a/src/docs/no-NO/features/timeline.md b/src/docs/no-NO/features/timeline.md deleted file mode 100644 index f431014f8..000000000 --- a/src/docs/no-NO/features/timeline.md +++ /dev/null @@ -1,31 +0,0 @@ -# タイムライン -タイムラインは、[ノート](./note)が時系列で表示される機能です。 タイムラインには以下で示す種類があり、種類によって表示されるノートも異なります。 なお、タイムラインの種類によってはサーバーにより無効になっている場合があります。 - -## ホーム -自分のフォローしているユーザーの投稿が流れます。HTLと略されます。 - -## ローカル -全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。LTLと略されます。 - -## ソーシャル -自分のフォローしているユーザーの投稿と、全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。STLと略されます。 - -## グローバル -全てのローカルユーザーの「ホーム」指定されていない投稿と、サーバーに届いた全てのリモートユーザーの「ホーム」指定されていない投稿が流れます。GTLと略されます。 - -## 比較 -| ソース | | | タイムライン | | | -| ------------ | ----- | --- | ------ | ----- | ----- | -| ユーザー | 公開範囲 | ホーム | ローカル | ソーシャル | グローバル | -| ローカル (フォロー) | 公開 | ✔ | ✔ | ✔ | ✔ | -| | ホーム | ✔ | | ✔ | | -| | フォロワー | ✔ | ✔ | ✔ | ✔ | -| リモート (フォロー) | 公開 | ✔ | | ✔ | ✔ | -| | ホーム | ✔ | | ✔ | | -| | フォロワー | ✔ | | ✔ | ✔ | -| ローカル (未フォロー) | 公開 | | ✔ | ✔ | ✔ | -| | ホーム | | | | | -| | フォロワー | | | | | -| リモート (未フォロー) | 公開 | | | | ✔ | -| | ホーム | | | | | -| | フォロワー | | | | | diff --git a/src/docs/no-NO/features/widgets.md b/src/docs/no-NO/features/widgets.md deleted file mode 100644 index a7c2c1d1d..000000000 --- a/src/docs/no-NO/features/widgets.md +++ /dev/null @@ -1,7 +0,0 @@ -# ウィジェット -ウィジェットは、MisskeyのUI上に設置できる小型の情報表示、操作が行えるパーツです。 - -ウィジェットを編集するには、ウィジェット編集モードに切り替えます。切り替え方法はUIによって異なります。 ウィジェット編集モードでは、ウィジェットの追加、削除、並び替え、およびそれぞれのウィジェットの設定を行えます。 - -## 利用可能なウィジェット一覧 -todo diff --git a/src/docs/no-NO/features/word-mute.md b/src/docs/no-NO/features/word-mute.md deleted file mode 100644 index fa4d14346..000000000 --- a/src/docs/no-NO/features/word-mute.md +++ /dev/null @@ -1,20 +0,0 @@ -# ワードミュート -ワードミュートの設定をすると、条件に合致したノートが表示されなくなります。 - -ワードミュートには、ソフトワードミュートとハードワードミュートの2種類があります。それぞれについて設定の方法と挙動を説明します。 - -## ソフトワードミュート -ソフトワードミュートは、クライアント(アプリ)側でミュートを判断するワードミュートです。 - -ノートが設定した条件に合致すると、「(ユーザー名)が何かを言いました」という表示で隠れます。 -クリックすると元の通りに表示されます。 - -## ハードワードミュート -ハードワードミュートは、アンテナのようにサーバーが新しいノートの本文に対して条件に合致するかどうか判断し、タイムラインから対象となったノートを除外します。 - -つまり、ハードワードミュートには、以下のような特徴があります。 - -* 条件設定後、新しい投稿のみがミュートの対象になります。 -* 条件を変更しても、過去にハードミュートされたノートはミュートされたままになります。 -* 「○○が何かを言いました」でタイムラインが埋まることがありません。 -* ソフトミュートに非対応のアプリでも、ハードミュートは適用されます。 diff --git a/src/docs/no-NO/follow.md b/src/docs/no-NO/follow.md deleted file mode 100644 index 3c1ea7bbe..000000000 --- a/src/docs/no-NO/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# フォロー -ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。 diff --git a/src/docs/no-NO/general/apps.md b/src/docs/no-NO/general/apps.md deleted file mode 100644 index 1f4c85fe8..000000000 --- a/src/docs/no-NO/general/apps.md +++ /dev/null @@ -1,6 +0,0 @@ -# サードパーティアプリのリスト -## クライアント -todo - -## 連携サービス -todo diff --git a/src/docs/no-NO/general/changelog.md b/src/docs/no-NO/general/changelog.md deleted file mode 100644 index 6766a63b2..000000000 --- a/src/docs/no-NO/general/changelog.md +++ /dev/null @@ -1,5 +0,0 @@ -# 更新履歴 -
ℹ️ このサーバーの更新履歴です。Misskeyの最新のリリースについては、GitHubをご確認ください。
- - - diff --git a/src/docs/no-NO/general/faq.md b/src/docs/no-NO/general/faq.md deleted file mode 100644 index c272b2ad4..000000000 --- a/src/docs/no-NO/general/faq.md +++ /dev/null @@ -1,28 +0,0 @@ -# よくある質問 -ここでは利用上のよくある質問について掲載しています。 Misskeyのプロジェクト自体についてのよくある質問は[こちら](./misskey)に掲載されています。 - -## iOS/Androidのアプリはありますか? -公式にはそういったOSのネイティブアプリを開発していませんが、サードパーティ製のアプリがいくつかあります。 詳しくは[こちら](./apps)をご覧ください。 - -ただ、サードパーティ製アプリはどうしても機能への対応が遅れてしまうため、とくに拘りがなければ公式のWebクライアントの利用をおすすめします。 なお、MisskeyのWebクライアントはPWAに対応しているので、ネイティブアプリのように動作させることも可能です。 詳しくは[こちら](todo)をご覧ください。 - -## Mastodonクライアントでログインできないのですが? -MisskeyはMastodonのAPIと互換性がないため、一部を除きMastodonクライアントでMisskeyを利用することはできません。 - -## 他のサーバーのユーザーをフォローするときは? -メニューから検索を選び、ユーザー名をホスト込みで入力します。例: `@syuilo@misskey.io` - -## Renoteを削除するには? -Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 Renoteについては[こちら](../features/note)をご確認ください。 - -## URLのプレビューを表示させたくない -MFMには、そのURLのプレビューを無効にする構文があります。詳細は[MFMチートシート](/mfm-cheat-sheet)をご確認ください。 - -## カスタム絵文字を追加したい -運営者のみがカスタム絵文字を追加、編集、削除できます。それらを希望する場合は運営者に依頼してください。 - -## Botを開発したい -Misskey APIを利用してBotの開発が可能です。[こちら](../advanced/develop-bot)をご確認ください。 - -## ノートの翻訳機能はどのサービスを使用していますか? -[DeepL](https://www.deepl.com/)を使用しています。 diff --git a/src/docs/no-NO/general/glossary.md b/src/docs/no-NO/general/glossary.md deleted file mode 100644 index bb8a24336..000000000 --- a/src/docs/no-NO/general/glossary.md +++ /dev/null @@ -1,89 +0,0 @@ -# 用語集 -Misskeyに関する用語集です。 - -## ActivityPub -(読み: あくてぃびてぃぱぶ) 分散型を実現するために用いられるプロトコル(仕様)。このプロトコルに則ってサーバー同士通信を行うことで、連合が行われ、Fediverseを形成しています。 - -## AiScript -(読み: あいすくりぷと) Misskey上で使用できるプログラミング言語です。詳細は[こちら。](../advanced/aiscript) - -## API -(読み: えーぴーあい) Misskeyのサーバーが公開している、プログラムからMisskeyを扱うためのインターフェース。詳細は[こちら。](../advanced/api) - -## Bot -(読み: ぼっと) プログラムによって動作しているアカウント。 - -## CW -(読み: こんてんつわーにんぐ) Contents Warningの略。ノートの内容を、操作なしには表示しないようにできる機能。主に長大な内容を隠すためや、ネタバレ防止などに使われます。 - -## Fediverse -(読み: ふぇでぃばーす) Misskeyを含む様々な分散型ソフトウェアのサーバーで構成されたネットワーク。 - -## GTL -グローバルタイムライン(Global TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## HTL -ホームタイムライン(Home TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## LTL -ローカルタイムライン(Local TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## MFM -(読み: えむえふえむ) Misskey Flavored Markdownの略で、Misskey上で使用できるマークアップ言語です。詳細は[こちら。](../features/mfm) - -## NSFW -(読み: のっとせーふふぉーわーく) Not Safe For Workの略。画像を「閲覧注意」扱いにし、操作なしには表示しないようにすることができる機能。 - -## Renote -(読み: りのーと) 既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノート。詳細は[こちら。](../features/note) - -## STL -ソーシャルタイムライン(Social TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## 藍 -(読み: あい) Misskeyの看板娘(公式キャラクター)です。 - -## アクティブユーザー -インスタンスにアカウントを作っているユーザーのうち、現在も実際にサービスを利用しているユーザーのこと。 - -## インスタンス -todo - -## カスタム絵文字 -サーバーで用意された絵文字。カスタム絵文字ではない通常の絵文字は「Unicode絵文字」と区別して呼ばれる。 - -## コントロールパネル -インスタンスの設定画面のこと。 - -## サーバー -todo - -## サイレンス -ノートをパブリックな公開範囲で投稿できなくされている状態。モデレーターの判断でユーザーごとに設定されます。詳細は[こちら。](../features/silence) - -## ジョブキュー -アクティビティ配送などを順番に行うためのシステム。 - -## 凍結 -アカウントが使用不可に設定されている状態。 - -## ドライブ -Misskeyにアップロードしたファイルを管理する機能。詳細は[こちら。](../features/drive) - -## ノート -Misskeyに投稿される、文章、ファイル、アンケートなどを含めることができるコンテンツ。詳細は[こちら。](../features/note) - -## ミスキスト -Misskeyを使う人のこと。 - -## モデレーター -スパムの凍結およびサイレンスや不適切な投稿の削除など、コミュニティ運営に関する権限を持つユーザー。 - -## リモート -他サーバーのことを指します。リモートユーザーといったように接頭辞としても使われます。ローカルの逆です。 - -## 連合 -サーバー上で作成された情報が他のサーバーに伝わること。 - -## ローカル -自サーバーのことを指します。ローカルユーザー、ローカルタイムラインといったように接頭辞としても使われます。リモートの逆です。 diff --git a/src/docs/no-NO/general/links.md b/src/docs/no-NO/general/links.md deleted file mode 100644 index 5ce5e1ddb..000000000 --- a/src/docs/no-NO/general/links.md +++ /dev/null @@ -1,12 +0,0 @@ -# リンク集 - -## Webサイト -- [Official Discord](https://discord.gg/Wp8gVStHW3) - Misskey公式Discordサーバー -- [Misskey Forum](https://forum.misskey.io/) - Misskeyに関する話題を扱うフォーラム - -## アカウント -- [@repo@misskey.io](https://misskey.io/@repo) - Misskeyのリポジトリの更新を投稿するbot - -## ライブラリ -- [misskey-dev/misskey.js](https://github.com/misskey-dev/misskey.js) - JavaScriptのMisskey SDK -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptのMFMパーサー実装 diff --git a/src/docs/no-NO/general/misskey.md b/src/docs/no-NO/general/misskey.md deleted file mode 100644 index d97664ddc..000000000 --- a/src/docs/no-NO/general/misskey.md +++ /dev/null @@ -1,87 +0,0 @@ -# Misskeyについて - -Misskeyはオープンソースの分散型マイクロブログプラットフォームプロジェクトです。 開発は日本でsyuiloによって2014年から開始されました。 ドライブ、リアクションなどの豊富な機能や、高いカスタマイズ性を備えたUIを持つことが特徴です。 - -## 歴史 -開発当初は掲示板がメインのサービスでしたが、ユーザーが短文を投稿し、それを時系列で流れるタイムライン機能を追加したところ人気が高まり、徐々にそれがメインとして開発が進むようになりました。 当初は分散型ではありませんでしたが、2018年にActivityPubを実装し分散型になったことで、より多くの方に認知され利用されるサービスになり、現在に至ります。 -
ℹ️ Misskeyという名前は、syuiloが当時聴いていたMay'nというアーティストの楽曲、Brain Diverの歌詞に由来します。
- -誰でも開発に参加することができ、現在でも活発に開発が続いています。 - -## 分散型とは何か? - -分散(distributed)型とは、非中央集権(decentralized)とも呼ばれ、コミュニティが多数のサーバーに分散して存在し、それらが相互に通信(連合、federation)することでコンテンツ共有ネットワーク(Fediverse)を形成していることが特徴のサービスです。 単一のサーバーしか存在しない、もしくは複数存在しても互いに独立している場合は中央集権なサービスと言われ、例えばTwitterやFacebookなどほとんどのサービスがそれに該当します。 分散型のメリットは、自分に合った運営者やテーマのサーバーを選択できることです。自分でサーバーを作成することもできます。連合するおかげで、どのサーバーを選んでも、同じコミュニティにアクセスできます。 - -## 常にオープンソース -Misskeyはこれまでもこれからも、オープンソースであり続けます。オープンソースとは、簡単に言うとソフトウェアのソースコード(プログラム)が公開されていることです。ソースコードの修正や再配布が可能であることを定義に含めることもあります。 Misskeyのすべてのソースコードは[AGPL](https://github.com/misskey-dev/misskey/blob/develop/LICENSE)というオープンソースライセンスの下に[公開](https://github.com/misskey-dev)されていて、誰でも自由に閲覧、使用、修正、改変、再配布をすることができます。 オープンソースは、自分で好きなように変えたり、有害な処理が含まれていないことを確認することができたり、誰でも開発に参加できるなどの、様々なメリットがあります。 上述の分散型を実現するためにも、オープンソースであるということは必要不可欠な要素です。 再び引き合いに出しますが、TwitterやFacebookなどの利益を得ているほとんどのサービスはオープンソースではありません。 - -
ℹ️ 技術的に言うと、MisskeyのソースコードはGitで管理されていて、リポジトリはGitHub上でホスティングされています。
- -## 開発に参加する、プロジェクトを支援する -Misskeyを気に入っていただけたら、ぜひプロジェクトを支援してください。プロジェクトに貢献するには、以下で紹介するようにいろいろな方法があります。方法によっては開発のスキルは不要なので、誰でも気軽に参加し貢献することができます。いつでもお待ちしています。 - -### 機能を追加したり、バグを修正する -ソフトウェアエンジニアのスキルをお持ちの方であれば、ソースコードを編集する形でプロジェクトに貢献することができます。 貢献についてのガイドは[こちら](https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md)です。 - -### 議論に参加する -新しい機能、または既存の機能について意見を述べたり、不具合を報告したりすることでも貢献できます。 そのようなディスカッションは[GitHub](https://github.com/misskey-dev)上か、[フォーラム](https://forum.misskey.io/)等で行われます。 - -### テキストを翻訳する -Misskeyは様々な言語に対応しています(i18n -internationalizationの略- と呼ばれます)。元の言語は基本的に日本語ですが、有志によって他の言語へと翻訳されています。 その翻訳作業に加わっていただくことでもMisskeyに貢献できます。 Misskeyは[Crowdinというサービスを使用して翻訳の管理を行っています。](https://crowdin.com/project/misskey) - -### 感想を投稿する -不具合報告等だけではなく、Misskeyの良い点、楽しい点といったポジティブな意見もぜひ共有してください。開発の励みになり、それは間接的ですがプロジェクトへの貢献です。 - -### ミスキストを増やす -ミスキストとは、Misskeyを使用する人のことです。 知り合いに紹介するなどしてMisskeyを広めていただければ、ミスキストが増え開発のモチベーションが上がります。 - -### 寄付をする -Misskeyはビジネスではなく、利用は無料であるため、収益は皆様からの寄付のみです。(インスタンスによっては広告収入を得ているような場合もありますが、それは運営者の収入であり直接開発者への収入にはなりません) 寄付をしていただければ、今後も開発を続けることが可能になり、プロジェクトへの貢献になります。 寄付は基本的には[Patreon](https://www.patreon.com/syuilo)で受け付けています。 一定額寄付していただけると、Misskeyの[情報ページ](/about-misskey)に名前を記載することができます。 - -また、サーバーの運営者も、基本的には収益を得ていません。サーバーの運営にはコストがかかるので、運営者の支援をすることもご検討ください。 開発には直接関係しませんが、サーバーがあってこそのプロジェクトなので、運営が維持されるというのは開発と同じくらい重要なことです。 - -## クレジット -Misskeyの開発者や、Misskeyに寄付をしてくださった方の一覧は[こちら](/about-misskey)で見ることができます。 - -## よくある質問 -### プロジェクトは何を目指していますか? -強いて言うと、漠然的になりますが広く使われる汎用的なプラットフォームになることを目指しています。 Misskeyは他のプロジェクトとは違い、何らかの思想(例えば、反中央集権)やビジョンに基づいて開発が行われているわけではなく、その点ではフラットです。 それが逆に、特定の方向性に縛られないフレキシブルさを生み出すことに繋がっていると感じています。 - - -### 企業によって開発されていますか? -いいえ。Misskeyの開発は個人で行われており、商業的でもないため、特定の企業の関りはありません。 開発メンバーも基本的にはボランティアです。 また、開発に対し企業のスポンサーがつくこともありますが、その場合でもやはり開発は個人のコミュニティが主体です。 - -### 誰が運営していますか? -Misskeyは分散型なため、各サーバーにそれぞれ異なった運営者がいます。従って、特定の個人や企業によって、Misskeyの全てが運営されているわけではありません。 また、開発チームが運営を行うわけでもないため、運営に関する連絡は、お使いのサーバーの運営者に行ってください。 サーバーの運営者は、[このページ](/about)で確認することができます。 あなたがサーバーを作成すれば、あなたが運営者になります。 - -### どのサーバーを選べばいいですか? -[サーバー一覧が公開されています。](https://join.misskey.page/ja-JP/instances) サーバーによってコミュニティのテーマ(特定のこと、ものが好き 等)が決められている場合があるので、自分に合ったテーマのサーバーがあれば、そこを選ぶと良いかもしれません。 他にも、サーバーの規模、ユーザー層、国および言語、運営者が信頼できるかどうか、などの観点があります。 なお、Misskey公式のサーバーというものはありません。自身で新しくサーバーを作成するという選択肢もあります。 - -基本的にどのサーバーを選んだとしても、他の全てのサーバーのユーザーと繋がることができます。 - -### サーバーを建てるにはどうしたらいいですか? -Misskeyサーバーの作成に興味を持っていただきありがとうございます。 2021年現在、Misskeyのホスティングサービスは存在しないため、サーバーの作成にはある程度の知識が必要です。 サーバーの作成方法については[こちら](todo)をご覧ください。 - -### どのような技術を使用していますか? -Misskeyは開発が進むにつれ使用する技術も大きく変わってきました。開発当初はMySQL + PHP + jQueryといった構成でしたが、現在は以下のようになっています。 -- サーバーサイド: Node.js -- データベース: PostgreSQL、Redis -- UIフレームワーク: Vue.js -- プログラミング言語: TypeScript - -また、MFMやAiScriptなどの、Misskeyから派生して独自の技術も開発しています。 - -### Mastodonのフォークですか? -いいえ。MisskeyはMastodonやその他のプロジェクトとは全く別のプロジェクトです。 開発に関しても、Misskeyの方が昔から開発されています。ただし、分散型になったのはMastodonの登場より後です。 同じActivityPubという分散のためのプロトコルを実装しているという点以外、両者に特に関りがあるわけでもありません。 - -### iOS/Androidのアプリはありますか? -公式にはそういったOSのネイティブアプリを開発していませんが、サードパーティ製のアプリがいくつかあります。 詳しくは[こちら](./apps)をご覧ください。 - -ただ、サードパーティ製アプリはどうしても機能への対応が遅れてしまうため、とくに拘りがなければ公式のWebクライアントの利用をおすすめします。 なお、MisskeyのWebクライアントはPWAに対応しているので、ネイティブアプリのように動作させることも可能です。 詳しくは[こちら](todo)をご覧ください。 - -### Misskeyのロゴ、アイコンはどこで入手できますか? -(準備中) - -### 時折目にする猫耳の可愛い女の子は? -Misskeyの守り神、藍ちゃんです。アイチャンカワイイヤッター! -
ℹ️ 藍ちゃんについてはこちらです。
diff --git a/src/docs/no-NO/general/report-issue.md b/src/docs/no-NO/general/report-issue.md deleted file mode 100644 index 63527e32a..000000000 --- a/src/docs/no-NO/general/report-issue.md +++ /dev/null @@ -1,8 +0,0 @@ -# 不具合の報告 -不具合と思われる状況に遭遇したときは、まず[トラブルシューティング](./troubleshooting)をご一読ください。 それでも問題が解決しないときは、以下の情報を含めて[フォーラム](https://forum.misskey.io/)に投稿してください。 投稿することで、解決策が見つかったり、不具合と判断されれば開発チームによって修正が行われます。 - -## 含める情報 -- Misskeyのバージョン([情報ページ](/about)で確認できます) -- お使いのブラウザの種類とバージョン -- お使いのOSの種類とバージョン -- 問題の再現手順 diff --git a/src/docs/no-NO/general/troubleshooting.md b/src/docs/no-NO/general/troubleshooting.md deleted file mode 100644 index f895b4984..000000000 --- a/src/docs/no-NO/general/troubleshooting.md +++ /dev/null @@ -1,40 +0,0 @@ -# トラブルシューティング -
ℹ️ よくある質問も合わせてお役立てください。
- -問題が発生したときは、まずこちらをご確認ください。 該当する項目が無い、もしくは手順を試しても効果がない場合は、サーバーの管理者に連絡するか[不具合を報告](./report-issue)してください。 - -## クライアントが起動しない -ほとんどの場合、お使いのブラウザまたはOSのバージョンが古いことが原因です。 ブラウザおよびOSのバージョンを最新のものに更新してから、再度試してみてください。 - -これは稀ですが、それでも起動しない場合は、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。 - -## ページが読み込めない -クライアントが起動するもののページが読み込めないというエラーが出る場合は、ネットワークに問題がないか確認してください。また、サーバーがダウンしていないか確認してください。 - -これは稀ですが、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。 - -まだ問題がある場合は、サーバーの問題と思われるのでサーバーの管理者に連絡してください。 - -## クライアントの動作が遅い -以下を試してみてください: - -- クライアント設定で「UIのアニメーションを減らす」を有効にする -- クライアント設定で「モーダルにぼかし効果を使用」を無効にする -- お使いのブラウザの設定でハードウェアアクセラレーションを有効にする -- お使いのデバイスのスペックを上げる - -## UIの一部の表示がおかしい(背景が透明になっている等) -アップデートによりUIの改修が行われたときに、テーマのキャッシュシステムの影響でそのような表示になることがあります。 クライアントの設定の「キャッシュをクリア」すると直ります。 -
⚠️ 「クライアントの」キャッシュクリアです。「ブラウザの」キャッシュクリアは行わないでください。
- -## 通知やアンテナ等の点滅が消えない -点滅は、未読のコンテンツがあることを示しています。通常点滅が消えない場合は、コンテンツを遡ると未読なコンテンツが残っています。 すべて既読にしたと思われるのに、それでもなお点滅が続く場合(おそらく不具合と思われます)は設定から強制的にすべて既読扱いにすることができます。 - -## Renoteができない -フォロワー限定のノートはRenoteすることはできません。 - -## UI上で特定の要素が表示されない -広告ブロッカーを使用しているとそのような不具合が発生することがあります。Misskeyではオフにしてご利用ください。 - -## UI上で未翻訳の部分がある -ほとんどの場合、単に翻訳が間に合っていないだけで、不具合ではありません。翻訳が終わるまでお待ちください。 [翻訳に参加](./misskey)していただくことも可能です。 diff --git a/src/docs/no-NO/keyboard-shortcut.md b/src/docs/no-NO/keyboard-shortcut.md deleted file mode 100644 index 957ca838c..000000000 --- a/src/docs/no-NO/keyboard-shortcut.md +++ /dev/null @@ -1,68 +0,0 @@ -# キーボードショートカット - -## グローバル -これらのショートカットは基本的にどこでも使えます。 - - - - - - - - - - - -
ショートカット効果由来
P, N新規投稿Post, New, Note
Tタイムラインの最も新しい投稿にフォーカスTimeline, Top
Shift + N通知を表示/隠すNotifications
S検索Search
H, ?ヘルプを表示Help
- -## 投稿にフォーカスされた状態 - - - - - - - - - - - - - - - - - - - -
ショートカット効果由来
, K, Shift + Tab上の投稿にフォーカスを移動-
, J, Tab下の投稿にフォーカスを移動-
R返信フォームを開くReply
QRenoteフォームを開くQuote
Ctrl + Q即刻Renoteする(フォームを開かずに)-
E, A, +リアクションフォームを開くEmote, reAction
0~9数字に対応したリアクションをする(対応については後述)-
F, Bお気に入りに登録Favorite, Bookmark
Del, Ctrl + D投稿を削除Delete
M, O投稿に対するメニューを開くMore, Other
SCWで隠された部分を表示 or 隠すShow, See
Escフォーカスを外す-
- -## Renoteフォーム - - - - - - - - - - -
ショートカット効果由来
EnterRenoteする-
Qフォームを展開するQuote
Escフォームを閉じる-
- -## リアクションフォーム -デフォルトで「👍」にフォーカスが当たっている状態です。 - - - - - - - - - - - - - -
ショートカット効果由来
, K上のリアクションにフォーカスを移動-
, J下のリアクションにフォーカスを移動-
, H, Shift + Tab左のリアクションにフォーカスを移動-
, L, Tab右のリアクションにフォーカスを移動-
Enter, Space, +リアクション確定-
0~9数字に対応したリアクションで確定-
Escリアクションするのをやめる-
diff --git a/src/docs/no-NO/mfm.md b/src/docs/no-NO/mfm.md deleted file mode 100644 index e237287ac..000000000 --- a/src/docs/no-NO/mfm.md +++ /dev/null @@ -1,2 +0,0 @@ -# MFM -MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます。 diff --git a/src/docs/no-NO/mute.md b/src/docs/no-NO/mute.md deleted file mode 100644 index 6a9608662..000000000 --- a/src/docs/no-NO/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# ミュート - -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -* タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -* そのユーザーからの通知 -* メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 - -ユーザーをミュートするには、対象のユーザーのユーザーページに表示されている「ミュート」ボタンを押します。 - -ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。 - -設定>ミュート から、自分がミュートしているユーザー一覧を確認することができます。 diff --git a/src/docs/no-NO/pages.md b/src/docs/no-NO/pages.md deleted file mode 100644 index a7311b95e..000000000 --- a/src/docs/no-NO/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# Pages - -## 変数 -変数を使うことで動的なページを作成できます。テキスト内で { 変数名 } と書くとそこに変数の値を埋め込めます。例えば Hello { thing } world! というテキストで、変数(thing)の値が ai だった場合、テキストは Hello ai world! になります。 - -変数の評価(値を算出すること)は上から下に行われるので、ある変数の中で自分より下の変数を参照することはできません。例えば上から A、B、C と3つの変数を定義したとき、Cの中でABを参照することはできますが、Aの中でBCを参照することはできません。 - -ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。 - -関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。 diff --git a/src/docs/no-NO/reaction.md b/src/docs/no-NO/reaction.md deleted file mode 100644 index c26ead75b..000000000 --- a/src/docs/no-NO/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# リアクション -他の人のノートに、絵文字を付けて簡単にあなたの反応を伝えられる機能です。 リアクションするには、ノートの + アイコンをクリックしてピッカーを表示し、絵文字を選択します。 リアクションには[カスタム絵文字](./custom-emoji)も使用できます。 - -## リアクションピッカーのカスタマイズ -ピッカーに表示される絵文字を自分好みにカスタマイズすることができます。 設定の「リアクション」で設定します。 - -## リモート投稿へのリアクションについて -リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。 また、相手がMisskeyであったとしても、カスタム絵文字リアクションは伝わらず、自動的に「👍」等にフォールバックされます。 - -## リモートからのリアクションについて -リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。 diff --git a/src/docs/no-NO/reversi-bot.md b/src/docs/no-NO/reversi-bot.md deleted file mode 100644 index 7ab2a7212..000000000 --- a/src/docs/no-NO/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# MisskeyリバーシBotの開発 -Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。 - -1. `games/reversi`ストリームに以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - -2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる - * イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている - -3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する - -4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - * `game`: `game`の`id` - -5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う - -6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する - -7. ゲームが開始すると、`started`イベントが流れてくる - * イベントの中身にはゲーム情報が含まれている - -8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述) - -9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる - * `color`として石の色が含まれている - * `pos`として位置情報が含まれている - -## 位置の計算法 -8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### X,Y座標 から インデックス に変換する -``` -pos = x + (y * mapWidth) -``` -`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます: -``` -mapWidth = map[0].length -``` - -### インデックス から X,Y座標 に変換する -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## マップ情報 -マップ情報は、ゲーム情報の`map`に入っています。 文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 それをもとにマップのデザインを知る事が出来ます: -* `(スペース)` ... マス無し -* `-` ... マス -* `b` ... 初期配置される黒石 -* `w` ... 初期配置される白石 - -例えば、4*4の次のような単純なマップがあるとします: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -この場合、マップデータはこのようになります: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## ユーザーにフォームを提示して対話可能Botを作成する -ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。 - -フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します: -```javascript -{ - type: 'init-form', - body: [フォームコントロールの配列] -} -``` - -フォームコントロールの配列については今から説明します。 フォームコントロールは、次のようなオブジェクトです: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... コントロールのID。 `type` ... コントロールの種類。後述します。 `label` ... コントロールと一緒に表記するテキスト。 `value` ... コントロールのデフォルト値。 - -### フォームの操作を受け取る -ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### フォームコントロールの種類 -#### スイッチ -type: `switch` スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。 - -##### プロパティ -`label` ... スイッチに表記するテキスト。 - -#### ラジオボタン -type: `radio` ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。 - -##### プロパティ -`items` ... ラジオボタンの選択肢。例: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '強', - value: 3 -}] -``` - -#### スライダー -type: `slider` スライダーを表示します。 - -##### プロパティ -`min` ... スライダーの下限。 `max` ... スライダーの上限。 `step` ... 入力欄で刻むステップ値。 - -#### テキストボックス -type: `textbox` テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。 - -## ユーザーにメッセージを表示する -設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 メッセージを表示するには、次のメッセージをストリームに送信します: -```javascript -{ - type: 'message', - body: { - text: 'メッセージ内容', - type: 'メッセージの種類' - } -} -``` -メッセージの種類: `success`, `info`, `warning`, `error`。 - -## 投了する -投了をするには、このエンドポイントにリクエストします。 diff --git a/src/docs/no-NO/stream.md b/src/docs/no-NO/stream.md deleted file mode 100644 index 9011c37c5..000000000 --- a/src/docs/no-NO/stream.md +++ /dev/null @@ -1,354 +0,0 @@ -# ストリーミングAPI - -ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。 - -## ストリームに接続する - -ストリーミングAPIを利用するには、まずMisskeyサーバーに**websocket**接続する必要があります。 - -以下のURLに、`i`というパラメータ名で認証情報を含めて、websocket接続してください。例: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。 - -
-

認証情報の取得については、こちらのドキュメントをご確認ください。

-
- ---- - -認証情報は省略することもできますが、その場合非ログインでの利用ということになり、受信できる情報や可能な操作は限られます。例: - -``` -%WS_URL%/streaming -``` - ---- - -ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。 - -**ストリームでのやり取りはすべてJSONです。** - -## チャンネル -MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。 - -### チャンネルに接続する -チャンネルに接続するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -ここで、 -* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。 -* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。 -* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。 - -
-

IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。

-
- -### チャンネルからのメッセージを受け取る -例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。 - -チャンネルがメッセージを発すると、次のようなデータがJSONでストリームに流れてきます: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。 -* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。 -* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。 - -### チャンネルに向けてメッセージを送信する -チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。 - -チャンネルにメッセージを送信するには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。 -* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。 -* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。 - -### チャンネルから切断する -チャンネルから切断するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。 - -## ストリームを経由してAPIリクエストする - -ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。 - -ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -ここで、 -* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 -* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 -* `data`には、エンドポイントのパラメータを含めます。 - -
-

APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。

-
- -### レスポンスの受信 - -APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。 - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -ここで、 -* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 -* `body`には、レスポンスが含まれています。 - -## 投稿のキャプチャ - -Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。 - -例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。 - -しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。 - -この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。 - -### 投稿をキャプチャする - -投稿をキャプチャするには、ストリームに次のようなメッセージを送信します: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャしたい投稿の`id`を設定します。 - -このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 - -例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -ここで、 -* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。 -* `body`内の`type`に、イベントの種類が設定されます。 -* `body`内の`body`に、イベントの詳細が設定されます。 - -#### イベントの種類 - -##### `reacted` -その投稿にリアクションがされた時に発生します。 - -* `reaction`に、リアクションの種類が設定されます。 -* `userId`に、リアクションを行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -その投稿が削除された時に発生します。 - -* `deletedAt`に、削除日時が設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -その投稿に添付されたアンケートに投票された時に発生します。 - -* `choice`に、選択肢IDが設定されます。 -* `userId`に、投票を行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### 投稿のキャプチャを解除する - -その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。 - -次のメッセージを送信します: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャを解除したい投稿の`id`を設定します。 - -このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 - -# チャンネル一覧 -## `main` -アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `renote` -自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。 - -#### `mention` -誰かからメンションされたときに発生するイベントです。 - -#### `readAllNotifications` -自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。 - -#### `meUpdated` -自分の情報が更新されたことを表すイベントです。 - -#### `follow` -自分が誰かをフォローしたときに発生するイベントです。 - -#### `unfollow` -自分が誰かのフォローを解除したときに発生するイベントです。 - -#### `followed` -自分が誰かにフォローされたときに発生するイベントです。 - -## `homeTimeline` -ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -タイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `localTimeline` -ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `hybridTimeline` -ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ソーシャルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `globalTimeline` -グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 diff --git a/src/docs/no-NO/theme.md b/src/docs/no-NO/theme.md deleted file mode 100644 index a406f3433..000000000 --- a/src/docs/no-NO/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# テーマ - -テーマを設定して、Misskeyクライアントの見た目を変更できます。 - -## テーマの設定 -設定 > テーマ - -## テーマを作成する -テーマコードはJSON5で記述されたテーマオブジェクトです。 テーマは以下のようなオブジェクトです。 -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... テーマの一意なID。UUIDをおすすめします。 -* `name` ... テーマ名 -* `author` ... テーマの作者 -* `desc` ... テーマの説明(オプション) -* `base` ... 明るいテーマか、暗いテーマか - * `light`にすると明るいテーマになり、`dark`にすると暗いテーマになります。 - * テーマはここで設定されたベーステーマを継承します。 -* `props` ... テーマのスタイル定義。これから説明します。 - -### テーマのスタイル定義 -`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 - -#### バリューで使える構文 -* 16進数で表された色 - * 例: `#00ff00` -* `rgb(r, g, b)`形式で表された色 - * 例: `rgb(0, 255, 0)` -* `rgb(r, g, b, a)`形式で表された透明度を含む色 - * 例: `rgba(0, 255, 0, 0.5)` -* 他のキーの値の参照 - * `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。 - * 例: `@panel` -* 定数(後述)の参照 - * `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。 - * 例: `$main` -* 関数(後述) - * `:{関数名}<{引数}<{色}` - -#### 定数 -「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 キー名を`$`で始めると、そのキーはCSS変数として出力されません。 - -#### 関数 -wip diff --git a/src/docs/no-NO/timelines.md b/src/docs/no-NO/timelines.md deleted file mode 100644 index 36ba61bd2..000000000 --- a/src/docs/no-NO/timelines.md +++ /dev/null @@ -1,15 +0,0 @@ -# タイムラインの比較 - -https://docs.google.com/spreadsheets/d/1lxQ2ugKrhz58Bg96HTDK_2F98BUritkMyIiBkOByjHA/edit?usp=sharing - -## ホーム -自分のフォローしているユーザーの投稿 - -## ローカル -全てのローカルユーザーの「ホーム」指定されていない投稿 - -## ソーシャル -自分のフォローしているユーザーの投稿と、全てのローカルユーザーの「ホーム」指定されていない投稿 - -## グローバル -全てのローカルユーザーの「ホーム」指定されていない投稿と、サーバーに届いた全てのリモートユーザーの「ホーム」指定されていない投稿 diff --git a/src/docs/pl-PL/admin/disable-timelines.md b/src/docs/pl-PL/admin/disable-timelines.md deleted file mode 100644 index b081e35ab..000000000 --- a/src/docs/pl-PL/admin/disable-timelines.md +++ /dev/null @@ -1,8 +0,0 @@ -# LTL/STL/GTLの無効化 -Misskeyでは、LTL/STL/GTLをそれぞれ無効化することができます。有効/無効を切り替えるには、インスタンスコントロールパネルで設定します。 - -LTLやSTLは、そのインスタンス全員の投稿が見れるため、新規のユーザーにとってはユーザーを探す必要がなくなり、興味のあるユーザーを見つけやすいという利点があります。 しかし同時に、フォロー機能が活用されなくなったり、不適切な投稿が目につきやすくなったり、チャットのようになることで内輪感が生じて逆に新規ユーザーが参加しにくくなるといったデメリットも持ち合わせています。 サーバーによってメリット/デメリットどちらが優勢かは異なるので、オプションとして無効にできるようになっています。 もしデメリットの方が上回っていると感じたら、それらのタイムラインを無効化することも検討してください。 - -
⚠️ 無効化を行うと、ユーザーが困惑し、短期的に見て利用者が減る可能性があります。そのため、無効化の際は影響を慎重に検討し、事前に説明してフォローを整える期間を一定程度設けることを推奨します。
- -なお、管理者/モデレーターは、これらのタイムラインの無効化状態は適用されず、引き続き利用することが可能です。 diff --git a/src/docs/pl-PL/admin/faq.md b/src/docs/pl-PL/admin/faq.md deleted file mode 100644 index 317b4e065..000000000 --- a/src/docs/pl-PL/admin/faq.md +++ /dev/null @@ -1,5 +0,0 @@ -# よくある質問 -ここでは、サーバー管理者向けのよくある質問を掲載しています。 - -## デフォルトテーマを設定したい -現在、デフォルトテーマ設定機能は実装されていません。 diff --git a/src/docs/pl-PL/advanced/aiscript.md b/src/docs/pl-PL/advanced/aiscript.md deleted file mode 100644 index 604d17daa..000000000 --- a/src/docs/pl-PL/advanced/aiscript.md +++ /dev/null @@ -1,7 +0,0 @@ -# AiScript -AiScriptは、Misskeyで使用できるスクリプト言語です。 - -
ℹ️ AiScript実装はMisskeyとは別リポジトリで、オープンソースで公開されています。
- -## 使い方 -AiScriptの構文や組み込み関数などのドキュメントは、[こちら](https://github.com/syuilo/aiscript/tree/master/docs)で公開されています。 diff --git a/src/docs/pl-PL/advanced/api.md b/src/docs/pl-PL/advanced/api.md deleted file mode 100644 index 76019b614..000000000 --- a/src/docs/pl-PL/advanced/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス、Bot等(以下「アプリケーション」と呼びます)を開発できます。 ストリーミングAPIもあるので、リアルタイム性のあるアプリケーションを作ることも可能です。 - -APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。 - -## アクセストークンの取得 -基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。 - -* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む -* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む - -### 自分自身のアクセストークンを手動発行する -「設定 > API」で、自分のアクセストークンを発行できます。 - -[「APIの使い方」へ進む](#APIの使い方) - -### アプリケーション利用者にアクセストークンの発行をリクエストする -アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。 - -#### Step 1 - -UUIDを生成する。以後これをセッションIDと呼びます。 - -> このセッションIDは毎回生成し、使いまわさないようにしてください。 - -#### Step 2 - -`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。 -> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます: -* `name` ... アプリケーション名 - * > 例: `MissDeck` -* `icon` ... アプリケーションのアイコン画像URL - * > 例: `https://missdeck.example.com/icon.png` -* `callback` ... 認証が終わった後にリダイレクトするURL - * > 例: `https://missdeck.example.com/callback` - * リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます -* `permission` ... アプリケーションが要求する権限 - * > 例: `write:notes,write:following,read:drive` - * 要求する権限を`,`で区切って列挙します - * どのような権限があるかは[APIリファレンス](/api-doc)で確認できます - -#### Step 3 -ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。 - -レスポンスに含まれるプロパティ: -* `token` ... ユーザーのアクセストークン -* `user` ... ユーザーの情報 - -[「APIの使い方」へ進む](#APIの使い方) - -## APIの使い方 -**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。 - -* [APIリファレンス](/api-doc) -* [ストリーミングAPI](./stream) diff --git a/src/docs/pl-PL/advanced/create-plugin.md b/src/docs/pl-PL/advanced/create-plugin.md deleted file mode 100644 index 31d89416d..000000000 --- a/src/docs/pl-PL/advanced/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# プラグインの作成 -Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。 - -## Metadane -プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。 - -### name -プラグイン名 - -### author -プラグイン作者 - -### version -プラグインバージョン。数値を指定してください。 - -### description -プラグインの説明 - -### permissions -プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。 - -### config -プラグインの設定情報を表すオブジェクト。 キーに設定名、値に以下のプロパティを含めます。 - -#### type -設定値の種類を表す文字列。以下から選択します。 string number boolean - -#### label -ユーザーに表示する設定名 - -#### description -設定の説明 - -#### default -設定のデフォルト値 - -## APIリファレンス -AiScript標準で組み込まれているAPIは掲載しません。 - -### Mk:dialog(title text type) -ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。 - -### Mk:confirm(title text type) -確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。 - -### Mk:api(endpoint params) -Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。 - -### Mk:save(key value) -任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。 - -### Mk:load(key) -Mk:saveで永続化した指定の名前の値を読み取ります。 - -### Plugin:register_post_form_action(title fn) -投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。 - -### Plugin:register_note_action(title fn) -ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 - -### Plugin:register_user_action(title fn) -ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。 - -### Plugin:register_note_view_interruptor(fn) -UIに表示されるノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:register_note_post_interruptor(fn) -ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:open_url(url) -第一引数に渡されたURLをブラウザの新しいタブで開きます。 - -### Plugin:config -プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。 diff --git a/src/docs/pl-PL/advanced/develop-bot.md b/src/docs/pl-PL/advanced/develop-bot.md deleted file mode 100644 index 7f825e9bc..000000000 --- a/src/docs/pl-PL/advanced/develop-bot.md +++ /dev/null @@ -1,6 +0,0 @@ -# Botの作成 -[Misskey API](./api)を利用してBotの開発が可能です。 また、いくつかのBot実装が公開されているため、ぜひ参考にしてください。 - -- [syuilo/ai](https://github.com/syuilo/ai) ... Node.js上で動く、TypeScript製Bot実装 - -Botを作成したときは、プロフィール設定からBotフラグをオンにしておくことを強くおすすめします。 diff --git a/src/docs/pl-PL/advanced/reversi-bot.md b/src/docs/pl-PL/advanced/reversi-bot.md deleted file mode 100644 index da76db7d1..000000000 --- a/src/docs/pl-PL/advanced/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# MisskeyリバーシBotの開発 -Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。 - -1. `games/reversi`ストリームに以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - -2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる - * イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている - -3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する - -4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - * `game`: `game`の`id` - -5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う - -6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する - -7. ゲームが開始すると、`started`イベントが流れてくる - * イベントの中身にはゲーム情報が含まれている - -8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述) - -9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる - * `color`として石の色が含まれている - * `pos`として位置情報が含まれている - -## 位置の計算法 -8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### X,Y座標 から インデックス に変換する -``` -pos = x + (y * mapWidth) -``` -`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます: -``` -mapWidth = map[0].length -``` - -### インデックス から X,Y座標 に変換する -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## マップ情報 -マップ情報は、ゲーム情報の`map`に入っています。 文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 それをもとにマップのデザインを知る事が出来ます: -* `(スペース)` ... マス無し -* `-` ... マス -* `b` ... 初期配置される黒石 -* `w` ... 初期配置される白石 - -例えば、4*4の次のような単純なマップがあるとします: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -この場合、マップデータはこのようになります: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## ユーザーにフォームを提示して対話可能Botを作成する -ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。 - -フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します: -```javascript -{ - type: 'init-form', - body: [フォームコントロールの配列] -} -``` - -フォームコントロールの配列については今から説明します。 フォームコントロールは、次のようなオブジェクトです: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... コントロールのID。 `type` ... コントロールの種類。後述します。 `label` ... コントロールと一緒に表記するテキスト。 `value` ... コントロールのデフォルト値。 - -### フォームの操作を受け取る -ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### フォームコントロールの種類 -#### Przełącznik -type: `switch` スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。 - -##### プロパティ -`label` ... スイッチに表記するテキスト。 - -#### ラジオボタン -type: `radio` ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。 - -##### プロパティ -`items` ... ラジオボタンの選択肢。例: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '強', - value: 3 -}] -``` - -#### スライダー -type: `slider` スライダーを表示します。 - -##### プロパティ -`min` ... スライダーの下限。 `max` ... スライダーの上限。 `step` ... 入力欄で刻むステップ値。 - -#### テキストボックス -type: `textbox` テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。 - -## ユーザーにメッセージを表示する -設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 メッセージを表示するには、次のメッセージをストリームに送信します: -```javascript -{ - type: 'message', - body: { - text: 'メッセージ内容', - type: 'メッセージの種類' - } -} -``` -メッセージの種類: `success`, `info`, `warning`, `error`。 - -## 投了する -投了をするには、このエンドポイントにリクエストします。 diff --git a/src/docs/pl-PL/advanced/share-page.md b/src/docs/pl-PL/advanced/share-page.md deleted file mode 100644 index d5ee9906a..000000000 --- a/src/docs/pl-PL/advanced/share-page.md +++ /dev/null @@ -1,54 +0,0 @@ -# シェアページ -`/share`を開くと、共有用の投稿フォームを開くことができます。 ここではシェアページで利用できるクエリ文字列の一覧を示します。 - -## クエリ文字列一覧 -### Tekst - -
-
title
-
タイトルです。本文の先頭に[ … ]と挿入されます。
-
text
-
本文です。
-
url
-
URLです。末尾に挿入されます。
-
- -### リプライ情報 -以下のいずれか - -
-
replyId
-
リプライ先のノートid
-
replyUri
-
リプライ先のUrl(リモートのノートオブジェクトを指定)
-
- -### Renote情報 -以下のいずれか - -
-
renoteId
-
Renote先のノートid
-
renoteUri
-
Renote先のUrl(リモートのノートオブジェクトを指定)
-
- -### Widoczność -※specifiedに相当する値はvisibility=specifiedとvisibleAccts/visibleUserIdsで指定する - -
-
visibility
-
公開範囲 ['public' | 'home' | 'followers' | 'specified']
-
localOnly
-
0(false) or 1(true)
-
visibleUserIds
-
specified時のダイレクト先のユーザーid カンマ区切りで
-
visibleAccts
-
specified時のダイレクト先のacct(@?username[@host]) カンマ区切りで
-
- -### Pliki -
-
fileIds
-
添付したいファイルのid(カンマ区切りで)
-
diff --git a/src/docs/pl-PL/advanced/stream.md b/src/docs/pl-PL/advanced/stream.md deleted file mode 100644 index 99653e263..000000000 --- a/src/docs/pl-PL/advanced/stream.md +++ /dev/null @@ -1,350 +0,0 @@ -# ストリーミングAPI - -ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。 - -## ストリームに接続する - -ストリーミングAPIを利用するには、まずMisskeyサーバーに**websocket**接続する必要があります。 - -以下のURLに、`i`というパラメータ名で認証情報を含めて、websocket接続してください。例: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。 - -
ℹ️ 認証情報の取得については、こちらのドキュメントをご確認ください。
- ---- - -認証情報は省略することもできますが、その場合非ログインでの利用ということになり、受信できる情報や可能な操作は限られます。例: - -``` -%WS_URL%/streaming -``` - ---- - -ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。 - -**ストリームでのやり取りはすべてJSONです。** - -## Kanały -MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。 - -ひとつのストリーム上で、同時に複数のチャンネルに接続することができます。 - -### チャンネルに接続する -チャンネルに接続するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -ここで、 -* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。 -* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。 -* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。 - -
ℹ️ IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。
- -### チャンネルからのメッセージを受け取る -例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。 - -チャンネルがメッセージを発すると、次のようなデータがJSONでストリームに流れてきます: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。 -* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。 -* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。 - -### チャンネルに向けてメッセージを送信する -チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。 - -チャンネルにメッセージを送信するには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。 -* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。 -* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。 - -### チャンネルから切断する -チャンネルから切断するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。 - -## ストリームを経由してAPIリクエストする - -ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。 - -ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -ここで、 -* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 -* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 -* `data`には、エンドポイントのパラメータを含めます。 - -
ℹ️ APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。
- -### レスポンスの受信 - -APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。 - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -ここで、 -* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 -* `body`には、レスポンスが含まれています。 - -## 投稿のキャプチャ - -Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。 - -例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。 - -しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。 - -この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。 - -### 投稿をキャプチャする - -投稿をキャプチャするには、ストリームに次のようなメッセージを送信します: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャしたい投稿の`id`を設定します。 - -このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 - -例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -ここで、 -* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。 -* `body`内の`type`に、イベントの種類が設定されます。 -* `body`内の`body`に、イベントの詳細が設定されます。 - -#### イベントの種類 - -##### `reacted` -その投稿にリアクションがされた時に発生します。 - -* `reaction`に、リアクションの種類が設定されます。 -* `userId`に、リアクションを行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -その投稿が削除された時に発生します。 - -* `deletedAt`に、削除日時が設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -その投稿に添付されたアンケートに投票された時に発生します。 - -* `choice`に、選択肢IDが設定されます。 -* `userId`に、投票を行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### 投稿のキャプチャを解除する - -その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。 - -次のメッセージを送信します: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャを解除したい投稿の`id`を設定します。 - -このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 - -# チャンネル一覧 -## `main` -アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `renote` -自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。 - -#### `mention` -誰かからメンションされたときに発生するイベントです。 - -#### `readAllNotifications` -自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。 - -#### `meUpdated` -自分の情報が更新されたことを表すイベントです。 - -#### `follow` -自分が誰かをフォローしたときに発生するイベントです。 - -#### `unfollow` -自分が誰かのフォローを解除したときに発生するイベントです。 - -#### `followed` -自分が誰かにフォローされたときに発生するイベントです。 - -## `homeTimeline` -ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -タイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `localTimeline` -ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `hybridTimeline` -ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ソーシャルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `globalTimeline` -グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 diff --git a/src/docs/pl-PL/aiscript.md b/src/docs/pl-PL/aiscript.md deleted file mode 100644 index c8959d593..000000000 --- a/src/docs/pl-PL/aiscript.md +++ /dev/null @@ -1,4 +0,0 @@ -# AiScript - -## Funkcje -デフォルトで値渡しです。 diff --git a/src/docs/pl-PL/api.md b/src/docs/pl-PL/api.md deleted file mode 100644 index 76019b614..000000000 --- a/src/docs/pl-PL/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス、Bot等(以下「アプリケーション」と呼びます)を開発できます。 ストリーミングAPIもあるので、リアルタイム性のあるアプリケーションを作ることも可能です。 - -APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。 - -## アクセストークンの取得 -基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。 - -* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む -* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む - -### 自分自身のアクセストークンを手動発行する -「設定 > API」で、自分のアクセストークンを発行できます。 - -[「APIの使い方」へ進む](#APIの使い方) - -### アプリケーション利用者にアクセストークンの発行をリクエストする -アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。 - -#### Step 1 - -UUIDを生成する。以後これをセッションIDと呼びます。 - -> このセッションIDは毎回生成し、使いまわさないようにしてください。 - -#### Step 2 - -`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。 -> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます: -* `name` ... アプリケーション名 - * > 例: `MissDeck` -* `icon` ... アプリケーションのアイコン画像URL - * > 例: `https://missdeck.example.com/icon.png` -* `callback` ... 認証が終わった後にリダイレクトするURL - * > 例: `https://missdeck.example.com/callback` - * リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます -* `permission` ... アプリケーションが要求する権限 - * > 例: `write:notes,write:following,read:drive` - * 要求する権限を`,`で区切って列挙します - * どのような権限があるかは[APIリファレンス](/api-doc)で確認できます - -#### Step 3 -ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。 - -レスポンスに含まれるプロパティ: -* `token` ... ユーザーのアクセストークン -* `user` ... ユーザーの情報 - -[「APIの使い方」へ進む](#APIの使い方) - -## APIの使い方 -**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。 - -* [APIリファレンス](/api-doc) -* [ストリーミングAPI](./stream) diff --git a/src/docs/pl-PL/create-plugin.md b/src/docs/pl-PL/create-plugin.md deleted file mode 100644 index 31d89416d..000000000 --- a/src/docs/pl-PL/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# プラグインの作成 -Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。 - -## Metadane -プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。 - -### name -プラグイン名 - -### author -プラグイン作者 - -### version -プラグインバージョン。数値を指定してください。 - -### description -プラグインの説明 - -### permissions -プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。 - -### config -プラグインの設定情報を表すオブジェクト。 キーに設定名、値に以下のプロパティを含めます。 - -#### type -設定値の種類を表す文字列。以下から選択します。 string number boolean - -#### label -ユーザーに表示する設定名 - -#### description -設定の説明 - -#### default -設定のデフォルト値 - -## APIリファレンス -AiScript標準で組み込まれているAPIは掲載しません。 - -### Mk:dialog(title text type) -ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。 - -### Mk:confirm(title text type) -確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。 - -### Mk:api(endpoint params) -Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。 - -### Mk:save(key value) -任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。 - -### Mk:load(key) -Mk:saveで永続化した指定の名前の値を読み取ります。 - -### Plugin:register_post_form_action(title fn) -投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。 - -### Plugin:register_note_action(title fn) -ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 - -### Plugin:register_user_action(title fn) -ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。 - -### Plugin:register_note_view_interruptor(fn) -UIに表示されるノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:register_note_post_interruptor(fn) -ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:open_url(url) -第一引数に渡されたURLをブラウザの新しいタブで開きます。 - -### Plugin:config -プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。 diff --git a/src/docs/pl-PL/custom-emoji.md b/src/docs/pl-PL/custom-emoji.md deleted file mode 100644 index 3f71205a6..000000000 --- a/src/docs/pl-PL/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# Niestandardowe emoji -カスタム絵文字は、インスタンスで用意された画像を絵文字のように使える機能です。 ノート、リアクション、チャット、自己紹介、名前などの場所で使うことができます。 カスタム絵文字をそれらの場所で使うには、絵文字ピッカーボタン(ある場合)を押すか、`:`を入力して絵文字サジェストを表示します。 テキスト内に`:foo:`のような形式の文字列が見つかると、`foo`の部分がカスタム絵文字名と解釈され、表示時には対応したカスタム絵文字に置き換わります。 diff --git a/src/docs/pl-PL/deck.md b/src/docs/pl-PL/deck.md deleted file mode 100644 index aa879d7df..000000000 --- a/src/docs/pl-PL/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# Tablica - -デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。 - -## カラムの追加 -デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。 - -## カラムの移動 -カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。 - -## カラムの水平分割 -カラムは左右だけでなく、上下に並べることもできます。 カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 上下分割を解除するには、カラムメニューの「右に出す」を選択します。 - -## カラムの設定 -カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。 - -## デッキの設定 -デッキに関する設定は、[settings/deck](/settings/deck)で行えます。 diff --git a/src/docs/pl-PL/features/antenna.md b/src/docs/pl-PL/features/antenna.md deleted file mode 100644 index 39f782c9a..000000000 --- a/src/docs/pl-PL/features/antenna.md +++ /dev/null @@ -1,4 +0,0 @@ -# Anteny -アンテナは、自由に条件を設定して、合致するノートを自動で収集することができる機能です。 - -条件を設定したアンテナが作成された状態で、条件に合致するノートが投稿されると、リアルタイムでそのアンテナのタイムラインにノートが追加されます。 diff --git a/src/docs/pl-PL/features/custom-emoji.md b/src/docs/pl-PL/features/custom-emoji.md deleted file mode 100644 index 3f71205a6..000000000 --- a/src/docs/pl-PL/features/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# Niestandardowe emoji -カスタム絵文字は、インスタンスで用意された画像を絵文字のように使える機能です。 ノート、リアクション、チャット、自己紹介、名前などの場所で使うことができます。 カスタム絵文字をそれらの場所で使うには、絵文字ピッカーボタン(ある場合)を押すか、`:`を入力して絵文字サジェストを表示します。 テキスト内に`:foo:`のような形式の文字列が見つかると、`foo`の部分がカスタム絵文字名と解釈され、表示時には対応したカスタム絵文字に置き換わります。 diff --git a/src/docs/pl-PL/features/deck.md b/src/docs/pl-PL/features/deck.md deleted file mode 100644 index aa879d7df..000000000 --- a/src/docs/pl-PL/features/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# Tablica - -デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。 - -## カラムの追加 -デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。 - -## カラムの移動 -カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。 - -## カラムの水平分割 -カラムは左右だけでなく、上下に並べることもできます。 カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 上下分割を解除するには、カラムメニューの「右に出す」を選択します。 - -## カラムの設定 -カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。 - -## デッキの設定 -デッキに関する設定は、[settings/deck](/settings/deck)で行えます。 diff --git a/src/docs/pl-PL/features/drive.md b/src/docs/pl-PL/features/drive.md deleted file mode 100644 index c49ea4f65..000000000 --- a/src/docs/pl-PL/features/drive.md +++ /dev/null @@ -1,17 +0,0 @@ -# Dysk -ドライブは、Misskey上でファイルを管理できる機能です。 - -[ドライブのページ](/my/drive)から任意のファイルをアップロードできるほか、アバターに設定した画像や、ノートに添付したファイルなどもすべてドライブにアップロードされます。 - -
⚠️ ドライブからファイルを削除すると、そのファイルが添付されたノートも消えます。
- -ドライブにアップロードされたファイルは、いつでもダウンロードすることができるほか、ノート作成時に「ドライブからファイルを添付」することでファイルを再利用することもできます。 - -ドライブ内にフォルダを作り、複数のファイルをまとめて整理することもできます。 - -## 閲覧注意 (NSFW) -
ℹ️ この項目が閲覧注意なわけではありません
- -閲覧注意またはNSFW (Not safe for work) は、ドライブのファイルに設定することができるフラグです。 閲覧注意フラグを設定されたファイルは、表示される際に閲覧者の操作なしには表示されなくなります。 このフラグは、例えば職場や公共の場で閲覧するのに適切でないと思われる画像などに設定し、そのような画像が突然表示されてしまうことを防ぐ目的で使われます。 - -このフラグは手動でオンオフを切り替えられるほか、モデレーターの判断で設定される場合もあります。 diff --git a/src/docs/pl-PL/features/favorite.md b/src/docs/pl-PL/features/favorite.md deleted file mode 100644 index 82d782b7c..000000000 --- a/src/docs/pl-PL/features/favorite.md +++ /dev/null @@ -1,4 +0,0 @@ -# Dodaj do ulubionych -[ノート](./node)をお気に入りとして登録できる機能です。 お気に入り登録したノートは、[お気に入りページ](./my/favorites)で一覧することができます。 お気に入りに登録したことは相手に通知されず、お気に入りは自分しか見ることができません。 - -ノートをお気に入り登録するには、ノートメニューの「お気に入り」を押します。お気に入り解除するには、ノートメニューの「お気に入り解除」を押します。 diff --git a/src/docs/pl-PL/features/follow.md b/src/docs/pl-PL/features/follow.md deleted file mode 100644 index 3b5ce84dc..000000000 --- a/src/docs/pl-PL/features/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# Obserwowani -ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。 diff --git a/src/docs/pl-PL/features/keyboard-shortcut.md b/src/docs/pl-PL/features/keyboard-shortcut.md deleted file mode 100644 index d351a6630..000000000 --- a/src/docs/pl-PL/features/keyboard-shortcut.md +++ /dev/null @@ -1,66 +0,0 @@ -# キーボードショートカット - -## Globalna -これらのショートカットは基本的にどこでも使えます。 - - - - - - - - - - - -
ショートカット効果由来
P, N新規投稿Post, New, Note
Tタイムラインの最も新しい投稿にフォーカスTimeline, Top
Shift + N通知を表示/隠すNotifications
SSzukajSearch
H, ?ヘルプを表示Help
- -## 投稿にフォーカスされた状態 - - - - - - - - - - - - - - - - - - -
ショートカット効果由来
, K, Shift + Tab上の投稿にフォーカスを移動-
, J, Tab下の投稿にフォーカスを移動-
R返信フォームを開くReply
QRenoteフォームを開くQuote
Ctrl + Q即刻Renoteする(フォームを開かずに)-
E, A, +リアクションフォームを開くEmote, reAction
0~9数字に対応したリアクションをする(対応については後述)-
F, Bお気に入りに登録Favorite, Bookmark
Del, Ctrl + D投稿を削除Delete
M, O投稿に対するメニューを開くMore, Other
SCWで隠された部分を表示 or 隠すShow, See
Escフォーカスを外す-
- -## Renoteフォーム - - - - - - - - - -
ショートカット効果由来
EnterRenoteする-
Qフォームを展開するQuote
Escフォームを閉じる-
- -## リアクションフォーム -デフォルトで「👍」にフォーカスが当たっている状態です。 - - - - - - - - - - - - - -
ショートカット効果由来
, K上のリアクションにフォーカスを移動-
, J下のリアクションにフォーカスを移動-
, H, Shift + Tab左のリアクションにフォーカスを移動-
, L, Tab右のリアクションにフォーカスを移動-
Enter, Space, +リアクション確定-
0~9数字に対応したリアクションで確定-
Escリアクションするのをやめる-
diff --git a/src/docs/pl-PL/features/mfm.md b/src/docs/pl-PL/features/mfm.md deleted file mode 100644 index 5be2df4f3..000000000 --- a/src/docs/pl-PL/features/mfm.md +++ /dev/null @@ -1,12 +0,0 @@ -# MFM -MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます。 - -## MFMが使用可能な場所の例 -- ノート本文 -- CW注釈 -- ユーザーの名前 -- ユーザーの自己紹介 - -## 開発者向け情報 -MFMのパーサー実装はライブラリとして公開されており、簡単にクライアントにMFMを組み込むことが可能です。 -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptパーサー実装 diff --git a/src/docs/pl-PL/features/mute-and-block.md b/src/docs/pl-PL/features/mute-and-block.md deleted file mode 100644 index dab2d2fc3..000000000 --- a/src/docs/pl-PL/features/mute-and-block.md +++ /dev/null @@ -1,41 +0,0 @@ -# Wycisz / Zablokuj -好みではないユーザーがいる場合は、ミュートを行うことでそのユーザーが自分から見えないようにすることができます。 また、より強力な措置として、ブロックを行うことでそのユーザーから自分のコンテンツが見えないようになるほか、自分に対して関わることができないようにすることができます。 ミュートされていることは相手は分かりませんが、ブロックされていることは相手に分かります。どちらを選ぶかはご自身の判断で行ってください。 - -
ℹ️ ミュートとブロックは併用できます。
- -
⚠️ 利用規約に違反するような、迷惑なユーザーがいる場合は運営者に報告することも検討してください。
- -設定>ミュートとブロック から、自分がミュートまたはブロックしているユーザー一覧を確認することができます。 - -## Wycisz -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -- タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -- そのユーザーからの通知 -- メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 -- など - -ユーザーをミュートするには、対象のユーザーのユーザーページのメニューを開き、「ミュート」ボタンを押します。 - -
ℹ️ ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。
- -## Zablokuj -ユーザーをブロックすると、そのユーザーからあなたのコンテンツが見えないようになり、またあなたに対して以下のようなアクションをすることができなくなります。 - -- フォローする -- ユーザーリストに追加する -- 返信する、Renoteする -- リアクションする、アンケートに投票する -- メッセージを送信する -- など - -また、 - -- ブロックする際に既にそのユーザーからフォローされていた場合はフォローが解除されます。 -- ブロックする際に既にそのユーザーがあなたをユーザーリストに入れていた場合はそのリストからあなたが削除されます。 - -ユーザーをブロックするには、対象のユーザーのユーザーページのメニューを開き、「ブロック」ボタンを押します。 - -
⚠️ ブロックを行ったこと自体は相手に通知されませんが、フォローを行ったりなどの上記のアクションが行えなくなるので間接的にブロックされていることは分かります。
- -
⚠️ 相手から自分のコンテンツが見えなくなりますが、相手がアカウントを切り替えたりログアウト状態になれば見ることができます。あくまで簡易的、補助的なものとしてお考えください。
diff --git a/src/docs/pl-PL/features/mute.md b/src/docs/pl-PL/features/mute.md deleted file mode 100644 index 8daf9f68a..000000000 --- a/src/docs/pl-PL/features/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# Wycisz - -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -* タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -* そのユーザーからの通知 -* メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 - -ユーザーをミュートするには、対象のユーザーのユーザーページに表示されている「ミュート」ボタンを押します。 - -ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。 - -設定>ミュート から、自分がミュートしているユーザー一覧を確認することができます。 diff --git a/src/docs/pl-PL/features/note.md b/src/docs/pl-PL/features/note.md deleted file mode 100644 index 6a9976fc1..000000000 --- a/src/docs/pl-PL/features/note.md +++ /dev/null @@ -1,54 +0,0 @@ -# Wpisy -ノートは、Misskeyに投稿される、文章、ファイル、アンケートなどを含むコンテンツで、Misskeyの中心的概念です。また、そのノートを作成する行為自体もノートと呼ばれます。 - -ノートが作成されると、[タイムライン](./timeline)に追加され、自分の[フォロワー](./follow)やサーバーのユーザーが見れるようになります。 - -ノートには、[リアクション](./reaction)を行うことができます。また、返信や引用もできます。 - -ノートを[お気に入り](./favorite)登録することで、後で簡単に見返すことができます。 - -## ノートを作成する -ノートを作成するには、画面上にある鉛筆マークのボタンを押して、作成フォームを開きます。作成フォームに内容を入力し、「ノート」ボタンを押すことでノートが作成されます。 ノートには、画像、動画など任意のファイルや、[アンケート](./poll)を添付することができます。また、本文中には[MFM](./mfm)が使用でき、[メンション](./mention)や[ハッシュタグ](./hashtag)を含めることもできます。 他にも、CWや公開範囲といった設定も行えます(詳細は後述)。 -
ℹ️ コンピューターのクリップボードに画像データがある状態で、フォーム内のテキストボックスにペーストするとその画像を添付することができます。
-
ℹ️ テキストボックス内でCtrl + Enterを押すことでも投稿できます。
- -## Udostępnij -既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノートをRenoteと呼びます。 自分がフォローしているユーザーの、気に入ったノートを自分のフォロワーに共有したい場合や、過去の自分のノートを再度共有したい場合に使います。 同じノートに対して無制限にRenoteを行うことができますが、あまり連続して使用すると迷惑になる場合もあるので、注意しましょう。 -
⚠️ 公開範囲がフォロワーやダイレクトのノートはRenoteできません
- -Renoteを削除するには、Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 - -## CW -Contents Warningの略で、ノートの内容を、閲覧者の操作なしには表示しないようにできる機能です。主に長大な内容を隠すためや、ネタバレ防止などに使うことができます。 設定するには、フォームの「内容を隠す」ボタン(目のアイコン)を押します。すると新しい入力エリアが表れるので、そこに内容の要約を記入します。 - -## Widoczność -ノートごとに、そのノートが公開される範囲を設定することができます。フォームの「ノート」ボタンの左にあるアイコンを押すと公開範囲を以下から選択できます。 - -### Publiczny -全ての人に対してノートが公開されるほか、サーバーの全てのタイムライン(ホームタイムライン、ローカルタイムライン、ソーシャルタイムライン、グローバルタイムライン)にノートが流れます。 -
⚠️ アカウントがサイレンス状態の時は、この公開範囲は使用できません。
- -### Strona główna -全ての人に対してノートが公開されますが、フォロワー以外のローカルタイムライン、ソーシャルタイムライン、グローバルタイムラインにはノートは流れません。 - -### Obserwujący -自分のフォロワーに対してのみノートを公開します。フォロワーの全てのタイムラインに流れます。 - -### Bezpośredni -指定したユーザーに対してのみノートを公開します。指定したユーザーの全てのタイムラインに流れます。 - -### 「ローカルのみ」オプション -このオプションを有効にすると、リモートにノートを連合しなくなります。 - -### 公開範囲の比較 - - - - -
PublicznyStrona głównaObserwującyBezpośredni
フォロワーのLTL/STL/GTL
非フォロワーのLTL/STL/GTL
- -## Przypnij do profilu -ノートをピン留めすると、ユーザーページに常にそのノートを表示しておくことができます。 ノートのメニューを開き、「ピン留め」を選択してピン留めできます。 複数のノートをピン留めできます。 - -## Śledź -ノートをウォッチすると、自分以外のノートへのリアクションや返信などの通知を受け取ることができます。 ノートのメニューを開き、「ウォッチ」を選択してウォッチできます。 diff --git a/src/docs/pl-PL/features/pages.md b/src/docs/pl-PL/features/pages.md deleted file mode 100644 index efa18263f..000000000 --- a/src/docs/pl-PL/features/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# Pages - -## Zmienne -変数を使うことで動的なページを作成できます。テキスト内で { 変数名 } と書くとそこに変数の値を埋め込めます。例えば Hello { thing } world! というテキストで、変数(thing)の値が ai だった場合、テキストは Hello ai world! になります。 - -変数の評価(値を算出すること)は上から下に行われるので、ある変数の中で自分より下の変数を参照することはできません。例えば上から A、B、C と3つの変数を定義したとき、Cの中でABを参照することはできますが、Aの中でBCを参照することはできません。 - -ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。 - -関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。 diff --git a/src/docs/pl-PL/features/reaction.md b/src/docs/pl-PL/features/reaction.md deleted file mode 100644 index 0f292d9c0..000000000 --- a/src/docs/pl-PL/features/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# Reakcja -他の人のノートに、絵文字を付けて簡単にあなたの反応を伝えられる機能です。 リアクションするには、ノートの + アイコンをクリックしてピッカーを表示し、絵文字を選択します。 リアクションには[カスタム絵文字](./custom-emoji)も使用できます。 - -## リアクションピッカーのカスタマイズ -ピッカーに表示される絵文字を自分好みにカスタマイズすることができます。 設定の「リアクション」で設定します。 - -## リモート投稿へのリアクションについて -リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。 - -## リモートからのリアクションについて -リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。 diff --git a/src/docs/pl-PL/features/silence.md b/src/docs/pl-PL/features/silence.md deleted file mode 100644 index c90bbe6ff..000000000 --- a/src/docs/pl-PL/features/silence.md +++ /dev/null @@ -1,6 +0,0 @@ -# Wycisz -サイレンスは、アカウントに設定される状態のひとつです。 - -アカウントがサイレンス状態になると、ノートの公開範囲をパブリックにできなくなります。 ホーム、フォロワー、ダイレクトは選択可能なため、サイレンスを受けた場合でもフォロワーやあなたのユーザーページを直接訪れた場合は投稿を閲覧できますが、GTL(連合タイムライン)やLTL(ローカルタイムライン)には投稿が流れません。 - -アカウントのサイレンス状態は、サーバーのモデレーターによって有効化/無効化されます。 diff --git a/src/docs/pl-PL/features/theme.md b/src/docs/pl-PL/features/theme.md deleted file mode 100644 index e31cb4a09..000000000 --- a/src/docs/pl-PL/features/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# Motywy - -テーマを設定して、Misskeyクライアントの見た目を変更できます。 - -## テーマの設定 -設定 > テーマ - -## テーマを作成する -テーマコードはJSON5で記述されたテーマオブジェクトです。 テーマは以下のようなオブジェクトです。 -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... テーマの一意なID。UUIDをおすすめします。 -* `name` ... テーマ名 -* `author` ... テーマの作者 -* `desc` ... テーマの説明(オプション) -* `base` ... 明るいテーマか、暗いテーマか - * `light`にすると明るいテーマになり、`dark`にすると暗いテーマになります。 - * テーマはここで設定されたベーステーマを継承します。 -* `props` ... テーマのスタイル定義。これから説明します。 - -### テーマのスタイル定義 -`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 - -#### バリューで使える構文 -* 16進数で表された色 - * 例: `#00ff00` -* `rgb(r, g, b)`形式で表された色 - * 例: `rgb(0, 255, 0)` -* `rgb(r, g, b, a)`形式で表された透明度を含む色 - * 例: `rgba(0, 255, 0, 0.5)` -* 他のキーの値の参照 - * `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。 - * 例: `@panel` -* 定数(後述)の参照 - * `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。 - * 例: `$main` -* 関数(後述) - * `:{関数名}<{引数}<{色}` - -#### Stała -「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 キー名を`$`で始めると、そのキーはCSS変数として出力されません。 - -#### Funkcje -wip diff --git a/src/docs/pl-PL/features/timeline.md b/src/docs/pl-PL/features/timeline.md deleted file mode 100644 index 6bcd605cb..000000000 --- a/src/docs/pl-PL/features/timeline.md +++ /dev/null @@ -1,31 +0,0 @@ -# Oś czasu -タイムラインは、[ノート](./note)が時系列で表示される機能です。 タイムラインには以下で示す種類があり、種類によって表示されるノートも異なります。 なお、タイムラインの種類によってはサーバーにより無効になっている場合があります。 - -## Strona główna -自分のフォローしているユーザーの投稿が流れます。HTLと略されます。 - -## Lokalne -全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。LTLと略されます。 - -## Społeczność -自分のフォローしているユーザーの投稿と、全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。STLと略されます。 - -## Globalna -全てのローカルユーザーの「ホーム」指定されていない投稿と、サーバーに届いた全てのリモートユーザーの「ホーム」指定されていない投稿が流れます。GTLと略されます。 - -## Porównanie -| ソース | | | Oś czasu | | | -| ------------ | ------------- | ------------- | -------- | ----------- | -------- | -| Użytkownicy | Widoczność | Strona główna | Lokalne | Społeczność | Globalna | -| ローカル (フォロー) | Publikuj | ✔ | ✔ | ✔ | ✔ | -| | Strona główna | ✔ | | ✔ | | -| | Obserwujący | ✔ | ✔ | ✔ | ✔ | -| リモート (フォロー) | Publikuj | ✔ | | ✔ | ✔ | -| | Strona główna | ✔ | | ✔ | | -| | Obserwujący | ✔ | | ✔ | ✔ | -| ローカル (未フォロー) | Publikuj | | ✔ | ✔ | ✔ | -| | Strona główna | | | | | -| | Obserwujący | | | | | -| リモート (未フォロー) | Publikuj | | | | ✔ | -| | Strona główna | | | | | -| | Obserwujący | | | | | diff --git a/src/docs/pl-PL/features/widgets.md b/src/docs/pl-PL/features/widgets.md deleted file mode 100644 index 976c3bb6f..000000000 --- a/src/docs/pl-PL/features/widgets.md +++ /dev/null @@ -1,7 +0,0 @@ -# Widżety -ウィジェットは、MisskeyのUI上に設置できる小型の情報表示、操作が行えるパーツです。 - -ウィジェットを編集するには、ウィジェット編集モードに切り替えます。切り替え方法はUIによって異なります。 ウィジェット編集モードでは、ウィジェットの追加、削除、並び替え、およびそれぞれのウィジェットの設定を行えます。 - -## 利用可能なウィジェット一覧 -todo diff --git a/src/docs/pl-PL/features/word-mute.md b/src/docs/pl-PL/features/word-mute.md deleted file mode 100644 index 6896b5374..000000000 --- a/src/docs/pl-PL/features/word-mute.md +++ /dev/null @@ -1,20 +0,0 @@ -# Wyciszenie słowa -ワードミュートの設定をすると、条件に合致したノートが表示されなくなります。 - -ワードミュートには、ソフトワードミュートとハードワードミュートの2種類があります。それぞれについて設定の方法と挙動を説明します。 - -## ソフトワードミュート -ソフトワードミュートは、クライアント(アプリ)側でミュートを判断するワードミュートです。 - -ノートが設定した条件に合致すると、「(ユーザー名)が何かを言いました」という表示で隠れます。 -クリックすると元の通りに表示されます。 - -## ハードワードミュート -ハードワードミュートは、アンテナのようにサーバーが新しいノートの本文に対して条件に合致するかどうか判断し、タイムラインから対象となったノートを除外します。 - -つまり、ハードワードミュートには、以下のような特徴があります。 - -* 条件設定後、新しい投稿のみがミュートの対象になります。 -* 条件を変更しても、過去にハードミュートされたノートはミュートされたままになります。 -* 「○○が何かを言いました」でタイムラインが埋まることがありません。 -* ソフトミュートに非対応のアプリでも、ハードミュートは適用されます。 diff --git a/src/docs/pl-PL/follow.md b/src/docs/pl-PL/follow.md deleted file mode 100644 index 3b5ce84dc..000000000 --- a/src/docs/pl-PL/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# Obserwowani -ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。 diff --git a/src/docs/pl-PL/general/apps.md b/src/docs/pl-PL/general/apps.md deleted file mode 100644 index 1f4c85fe8..000000000 --- a/src/docs/pl-PL/general/apps.md +++ /dev/null @@ -1,6 +0,0 @@ -# サードパーティアプリのリスト -## クライアント -todo - -## 連携サービス -todo diff --git a/src/docs/pl-PL/general/changelog.md b/src/docs/pl-PL/general/changelog.md deleted file mode 100644 index 6766a63b2..000000000 --- a/src/docs/pl-PL/general/changelog.md +++ /dev/null @@ -1,5 +0,0 @@ -# 更新履歴 -
ℹ️ このサーバーの更新履歴です。Misskeyの最新のリリースについては、GitHubをご確認ください。
- - - diff --git a/src/docs/pl-PL/general/faq.md b/src/docs/pl-PL/general/faq.md deleted file mode 100644 index c272b2ad4..000000000 --- a/src/docs/pl-PL/general/faq.md +++ /dev/null @@ -1,28 +0,0 @@ -# よくある質問 -ここでは利用上のよくある質問について掲載しています。 Misskeyのプロジェクト自体についてのよくある質問は[こちら](./misskey)に掲載されています。 - -## iOS/Androidのアプリはありますか? -公式にはそういったOSのネイティブアプリを開発していませんが、サードパーティ製のアプリがいくつかあります。 詳しくは[こちら](./apps)をご覧ください。 - -ただ、サードパーティ製アプリはどうしても機能への対応が遅れてしまうため、とくに拘りがなければ公式のWebクライアントの利用をおすすめします。 なお、MisskeyのWebクライアントはPWAに対応しているので、ネイティブアプリのように動作させることも可能です。 詳しくは[こちら](todo)をご覧ください。 - -## Mastodonクライアントでログインできないのですが? -MisskeyはMastodonのAPIと互換性がないため、一部を除きMastodonクライアントでMisskeyを利用することはできません。 - -## 他のサーバーのユーザーをフォローするときは? -メニューから検索を選び、ユーザー名をホスト込みで入力します。例: `@syuilo@misskey.io` - -## Renoteを削除するには? -Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 Renoteについては[こちら](../features/note)をご確認ください。 - -## URLのプレビューを表示させたくない -MFMには、そのURLのプレビューを無効にする構文があります。詳細は[MFMチートシート](/mfm-cheat-sheet)をご確認ください。 - -## カスタム絵文字を追加したい -運営者のみがカスタム絵文字を追加、編集、削除できます。それらを希望する場合は運営者に依頼してください。 - -## Botを開発したい -Misskey APIを利用してBotの開発が可能です。[こちら](../advanced/develop-bot)をご確認ください。 - -## ノートの翻訳機能はどのサービスを使用していますか? -[DeepL](https://www.deepl.com/)を使用しています。 diff --git a/src/docs/pl-PL/general/glossary.md b/src/docs/pl-PL/general/glossary.md deleted file mode 100644 index 9e51aaa52..000000000 --- a/src/docs/pl-PL/general/glossary.md +++ /dev/null @@ -1,89 +0,0 @@ -# 用語集 -Misskeyに関する用語集です。 - -## ActivityPub -(読み: あくてぃびてぃぱぶ) 分散型を実現するために用いられるプロトコル(仕様)。このプロトコルに則ってサーバー同士通信を行うことで、連合が行われ、Fediverseを形成しています。 - -## AiScript -(読み: あいすくりぷと) Misskey上で使用できるプログラミング言語です。詳細は[こちら。](../advanced/aiscript) - -## API -(読み: えーぴーあい) Misskeyのサーバーが公開している、プログラムからMisskeyを扱うためのインターフェース。詳細は[こちら。](../advanced/api) - -## Bot -(読み: ぼっと) プログラムによって動作しているアカウント。 - -## CW -(読み: こんてんつわーにんぐ) Contents Warningの略。ノートの内容を、操作なしには表示しないようにできる機能。主に長大な内容を隠すためや、ネタバレ防止などに使われます。 - -## Fediverse -(読み: ふぇでぃばーす) Misskeyを含む様々な分散型ソフトウェアのサーバーで構成されたネットワーク。 - -## GTL -グローバルタイムライン(Global TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## HTL -ホームタイムライン(Home TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## LTL -ローカルタイムライン(Local TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## MFM -(読み: えむえふえむ) Misskey Flavored Markdownの略で、Misskey上で使用できるマークアップ言語です。詳細は[こちら。](../features/mfm) - -## NSFW -(読み: のっとせーふふぉーわーく) Not Safe For Workの略。画像を「閲覧注意」扱いにし、操作なしには表示しないようにすることができる機能。 - -## Udostępnij -(読み: りのーと) 既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノート。詳細は[こちら。](../features/note) - -## STL -ソーシャルタイムライン(Social TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## 藍 -(読み: あい) Misskeyの看板娘(公式キャラクター)です。 - -## アクティブユーザー -インスタンスにアカウントを作っているユーザーのうち、現在も実際にサービスを利用しているユーザーのこと。 - -## Instancja -todo - -## Niestandardowe emoji -サーバーで用意された絵文字。カスタム絵文字ではない通常の絵文字は「Unicode絵文字」と区別して呼ばれる。 - -## コントロールパネル -インスタンスの設定画面のこと。 - -## Serwery -todo - -## Wycisz -ノートをパブリックな公開範囲で投稿できなくされている状態。モデレーターの判断でユーザーごとに設定されます。詳細は[こちら。](../features/silence) - -## Kolejka zadań -アクティビティ配送などを順番に行うためのシステム。 - -## Zawieś -アカウントが使用不可に設定されている状態。 - -## Dysk -Misskeyにアップロードしたファイルを管理する機能。詳細は[こちら。](../features/drive) - -## Wpisy -Misskeyに投稿される、文章、ファイル、アンケートなどを含めることができるコンテンツ。詳細は[こちら。](../features/note) - -## ミスキスト -Misskeyを使う人のこと。 - -## Moderator -スパムの凍結およびサイレンスや不適切な投稿の削除など、コミュニティ運営に関する権限を持つユーザー。 - -## Zdalny -他サーバーのことを指します。リモートユーザーといったように接頭辞としても使われます。ローカルの逆です。 - -## Federacja -サーバー上で作成された情報が他のサーバーに伝わること。 - -## Lokalne -自サーバーのことを指します。ローカルユーザー、ローカルタイムラインといったように接頭辞としても使われます。リモートの逆です。 diff --git a/src/docs/pl-PL/general/links.md b/src/docs/pl-PL/general/links.md deleted file mode 100644 index 69e224239..000000000 --- a/src/docs/pl-PL/general/links.md +++ /dev/null @@ -1,12 +0,0 @@ -# リンク集 - -## Webサイト -- [Official Discord](https://discord.gg/Wp8gVStHW3) - Misskey公式Discordサーバー -- [Misskey Forum](https://forum.misskey.io/) - Misskeyに関する話題を扱うフォーラム - -## Konta -- [@repo@misskey.io](https://misskey.io/@repo) - Misskeyのリポジトリの更新を投稿するbot - -## ライブラリ -- [misskey-dev/misskey.js](https://github.com/misskey-dev/misskey.js) - JavaScriptのMisskey SDK -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptのMFMパーサー実装 diff --git a/src/docs/pl-PL/general/misskey.md b/src/docs/pl-PL/general/misskey.md deleted file mode 100644 index 65ac31f86..000000000 --- a/src/docs/pl-PL/general/misskey.md +++ /dev/null @@ -1,87 +0,0 @@ -# O Misskey - -Misskeyはオープンソースの分散型マイクロブログプラットフォームプロジェクトです。 開発は日本でsyuiloによって2014年から開始されました。 ドライブ、リアクションなどの豊富な機能や、高いカスタマイズ性を備えたUIを持つことが特徴です。 - -## 歴史 -開発当初は掲示板がメインのサービスでしたが、ユーザーが短文を投稿し、それを時系列で流れるタイムライン機能を追加したところ人気が高まり、徐々にそれがメインとして開発が進むようになりました。 当初は分散型ではありませんでしたが、2018年にActivityPubを実装し分散型になったことで、より多くの方に認知され利用されるサービスになり、現在に至ります。 -
ℹ️ Misskeyという名前は、syuiloが当時聴いていたMay'nというアーティストの楽曲、Brain Diverの歌詞に由来します。
- -誰でも開発に参加することができ、現在でも活発に開発が続いています。 - -## 分散型とは何か? - -分散(distributed)型とは、非中央集権(decentralized)とも呼ばれ、コミュニティが多数のサーバーに分散して存在し、それらが相互に通信(連合、federation)することでコンテンツ共有ネットワーク(Fediverse)を形成していることが特徴のサービスです。 単一のサーバーしか存在しない、もしくは複数存在しても互いに独立している場合は中央集権なサービスと言われ、例えばTwitterやFacebookなどほとんどのサービスがそれに該当します。 分散型のメリットは、自分に合った運営者やテーマのサーバーを選択できることです。自分でサーバーを作成することもできます。連合するおかげで、どのサーバーを選んでも、同じコミュニティにアクセスできます。 - -## 常にオープンソース -Misskeyはこれまでもこれからも、オープンソースであり続けます。オープンソースとは、簡単に言うとソフトウェアのソースコード(プログラム)が公開されていることです。ソースコードの修正や再配布が可能であることを定義に含めることもあります。 Misskeyのすべてのソースコードは[AGPL](https://github.com/misskey-dev/misskey/blob/develop/LICENSE)というオープンソースライセンスの下に[公開](https://github.com/misskey-dev)されていて、誰でも自由に閲覧、使用、修正、改変、再配布をすることができます。 オープンソースは、自分で好きなように変えたり、有害な処理が含まれていないことを確認することができたり、誰でも開発に参加できるなどの、様々なメリットがあります。 上述の分散型を実現するためにも、オープンソースであるということは必要不可欠な要素です。 再び引き合いに出しますが、TwitterやFacebookなどの利益を得ているほとんどのサービスはオープンソースではありません。 - -
ℹ️ 技術的に言うと、MisskeyのソースコードはGitで管理されていて、リポジトリはGitHub上でホスティングされています。
- -## 開発に参加する、プロジェクトを支援する -Misskeyを気に入っていただけたら、ぜひプロジェクトを支援してください。プロジェクトに貢献するには、以下で紹介するようにいろいろな方法があります。方法によっては開発のスキルは不要なので、誰でも気軽に参加し貢献することができます。いつでもお待ちしています。 - -### 機能を追加したり、バグを修正する -ソフトウェアエンジニアのスキルをお持ちの方であれば、ソースコードを編集する形でプロジェクトに貢献することができます。 貢献についてのガイドは[こちら](https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md)です。 - -### 議論に参加する -新しい機能、または既存の機能について意見を述べたり、不具合を報告したりすることでも貢献できます。 そのようなディスカッションは[GitHub](https://github.com/misskey-dev)上か、[フォーラム](https://forum.misskey.io/)等で行われます。 - -### テキストを翻訳する -Misskeyは様々な言語に対応しています(i18n -internationalizationの略- と呼ばれます)。元の言語は基本的に日本語ですが、有志によって他の言語へと翻訳されています。 その翻訳作業に加わっていただくことでもMisskeyに貢献できます。 Misskeyは[Crowdinというサービスを使用して翻訳の管理を行っています。](https://crowdin.com/project/misskey) - -### 感想を投稿する -不具合報告等だけではなく、Misskeyの良い点、楽しい点といったポジティブな意見もぜひ共有してください。開発の励みになり、それは間接的ですがプロジェクトへの貢献です。 - -### ミスキストを増やす -ミスキストとは、Misskeyを使用する人のことです。 知り合いに紹介するなどしてMisskeyを広めていただければ、ミスキストが増え開発のモチベーションが上がります。 - -### 寄付をする -Misskeyはビジネスではなく、利用は無料であるため、収益は皆様からの寄付のみです。(インスタンスによっては広告収入を得ているような場合もありますが、それは運営者の収入であり直接開発者への収入にはなりません) 寄付をしていただければ、今後も開発を続けることが可能になり、プロジェクトへの貢献になります。 寄付は基本的には[Patreon](https://www.patreon.com/syuilo)で受け付けています。 一定額寄付していただけると、Misskeyの[情報ページ](/about-misskey)に名前を記載することができます。 - -また、サーバーの運営者も、基本的には収益を得ていません。サーバーの運営にはコストがかかるので、運営者の支援をすることもご検討ください。 開発には直接関係しませんが、サーバーがあってこそのプロジェクトなので、運営が維持されるというのは開発と同じくらい重要なことです。 - -## クレジット -Misskeyの開発者や、Misskeyに寄付をしてくださった方の一覧は[こちら](/about-misskey)で見ることができます。 - -## よくある質問 -### プロジェクトは何を目指していますか? -強いて言うと、漠然的になりますが広く使われる汎用的なプラットフォームになることを目指しています。 Misskeyは他のプロジェクトとは違い、何らかの思想(例えば、反中央集権)やビジョンに基づいて開発が行われているわけではなく、その点ではフラットです。 それが逆に、特定の方向性に縛られないフレキシブルさを生み出すことに繋がっていると感じています。 - - -### 企業によって開発されていますか? -いいえ。Misskeyの開発は個人で行われており、商業的でもないため、特定の企業の関りはありません。 開発メンバーも基本的にはボランティアです。 また、開発に対し企業のスポンサーがつくこともありますが、その場合でもやはり開発は個人のコミュニティが主体です。 - -### 誰が運営していますか? -Misskeyは分散型なため、各サーバーにそれぞれ異なった運営者がいます。従って、特定の個人や企業によって、Misskeyの全てが運営されているわけではありません。 また、開発チームが運営を行うわけでもないため、運営に関する連絡は、お使いのサーバーの運営者に行ってください。 サーバーの運営者は、[このページ](/about)で確認することができます。 あなたがサーバーを作成すれば、あなたが運営者になります。 - -### どのサーバーを選べばいいですか? -[サーバー一覧が公開されています。](https://join.misskey.page/ja-JP/instances) サーバーによってコミュニティのテーマ(特定のこと、ものが好き 等)が決められている場合があるので、自分に合ったテーマのサーバーがあれば、そこを選ぶと良いかもしれません。 他にも、サーバーの規模、ユーザー層、国および言語、運営者が信頼できるかどうか、などの観点があります。 なお、Misskey公式のサーバーというものはありません。自身で新しくサーバーを作成するという選択肢もあります。 - -基本的にどのサーバーを選んだとしても、他の全てのサーバーのユーザーと繋がることができます。 - -### サーバーを建てるにはどうしたらいいですか? -Misskeyサーバーの作成に興味を持っていただきありがとうございます。 2021年現在、Misskeyのホスティングサービスは存在しないため、サーバーの作成にはある程度の知識が必要です。 サーバーの作成方法については[こちら](todo)をご覧ください。 - -### どのような技術を使用していますか? -Misskeyは開発が進むにつれ使用する技術も大きく変わってきました。開発当初はMySQL + PHP + jQueryといった構成でしたが、現在は以下のようになっています。 -- サーバーサイド: Node.js -- データベース: PostgreSQL、Redis -- UIフレームワーク: Vue.js -- プログラミング言語: TypeScript - -また、MFMやAiScriptなどの、Misskeyから派生して独自の技術も開発しています。 - -### Mastodonのフォークですか? -いいえ。MisskeyはMastodonやその他のプロジェクトとは全く別のプロジェクトです。 開発に関しても、Misskeyの方が昔から開発されています。ただし、分散型になったのはMastodonの登場より後です。 同じActivityPubという分散のためのプロトコルを実装しているという点以外、両者に特に関りがあるわけでもありません。 - -### iOS/Androidのアプリはありますか? -公式にはそういったOSのネイティブアプリを開発していませんが、サードパーティ製のアプリがいくつかあります。 詳しくは[こちら](./apps)をご覧ください。 - -ただ、サードパーティ製アプリはどうしても機能への対応が遅れてしまうため、とくに拘りがなければ公式のWebクライアントの利用をおすすめします。 なお、MisskeyのWebクライアントはPWAに対応しているので、ネイティブアプリのように動作させることも可能です。 詳しくは[こちら](todo)をご覧ください。 - -### Misskeyのロゴ、アイコンはどこで入手できますか? -(準備中) - -### 時折目にする猫耳の可愛い女の子は? -Misskeyの守り神、藍ちゃんです。アイチャンカワイイヤッター! -
ℹ️ 藍ちゃんについてはこちらです。
diff --git a/src/docs/pl-PL/general/report-issue.md b/src/docs/pl-PL/general/report-issue.md deleted file mode 100644 index 63527e32a..000000000 --- a/src/docs/pl-PL/general/report-issue.md +++ /dev/null @@ -1,8 +0,0 @@ -# 不具合の報告 -不具合と思われる状況に遭遇したときは、まず[トラブルシューティング](./troubleshooting)をご一読ください。 それでも問題が解決しないときは、以下の情報を含めて[フォーラム](https://forum.misskey.io/)に投稿してください。 投稿することで、解決策が見つかったり、不具合と判断されれば開発チームによって修正が行われます。 - -## 含める情報 -- Misskeyのバージョン([情報ページ](/about)で確認できます) -- お使いのブラウザの種類とバージョン -- お使いのOSの種類とバージョン -- 問題の再現手順 diff --git a/src/docs/pl-PL/general/troubleshooting.md b/src/docs/pl-PL/general/troubleshooting.md deleted file mode 100644 index f895b4984..000000000 --- a/src/docs/pl-PL/general/troubleshooting.md +++ /dev/null @@ -1,40 +0,0 @@ -# トラブルシューティング -
ℹ️ よくある質問も合わせてお役立てください。
- -問題が発生したときは、まずこちらをご確認ください。 該当する項目が無い、もしくは手順を試しても効果がない場合は、サーバーの管理者に連絡するか[不具合を報告](./report-issue)してください。 - -## クライアントが起動しない -ほとんどの場合、お使いのブラウザまたはOSのバージョンが古いことが原因です。 ブラウザおよびOSのバージョンを最新のものに更新してから、再度試してみてください。 - -これは稀ですが、それでも起動しない場合は、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。 - -## ページが読み込めない -クライアントが起動するもののページが読み込めないというエラーが出る場合は、ネットワークに問題がないか確認してください。また、サーバーがダウンしていないか確認してください。 - -これは稀ですが、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。 - -まだ問題がある場合は、サーバーの問題と思われるのでサーバーの管理者に連絡してください。 - -## クライアントの動作が遅い -以下を試してみてください: - -- クライアント設定で「UIのアニメーションを減らす」を有効にする -- クライアント設定で「モーダルにぼかし効果を使用」を無効にする -- お使いのブラウザの設定でハードウェアアクセラレーションを有効にする -- お使いのデバイスのスペックを上げる - -## UIの一部の表示がおかしい(背景が透明になっている等) -アップデートによりUIの改修が行われたときに、テーマのキャッシュシステムの影響でそのような表示になることがあります。 クライアントの設定の「キャッシュをクリア」すると直ります。 -
⚠️ 「クライアントの」キャッシュクリアです。「ブラウザの」キャッシュクリアは行わないでください。
- -## 通知やアンテナ等の点滅が消えない -点滅は、未読のコンテンツがあることを示しています。通常点滅が消えない場合は、コンテンツを遡ると未読なコンテンツが残っています。 すべて既読にしたと思われるのに、それでもなお点滅が続く場合(おそらく不具合と思われます)は設定から強制的にすべて既読扱いにすることができます。 - -## Renoteができない -フォロワー限定のノートはRenoteすることはできません。 - -## UI上で特定の要素が表示されない -広告ブロッカーを使用しているとそのような不具合が発生することがあります。Misskeyではオフにしてご利用ください。 - -## UI上で未翻訳の部分がある -ほとんどの場合、単に翻訳が間に合っていないだけで、不具合ではありません。翻訳が終わるまでお待ちください。 [翻訳に参加](./misskey)していただくことも可能です。 diff --git a/src/docs/pl-PL/keyboard-shortcut.md b/src/docs/pl-PL/keyboard-shortcut.md deleted file mode 100644 index fb123a2ea..000000000 --- a/src/docs/pl-PL/keyboard-shortcut.md +++ /dev/null @@ -1,68 +0,0 @@ -# キーボードショートカット - -## Globalna -これらのショートカットは基本的にどこでも使えます。 - - - - - - - - - - - -
ショートカットEfektPochodzenie
P, N新規投稿Post, New, Note
Tタイムラインの最も新しい投稿にフォーカスTimeline, Top
Shift + N通知を表示/隠すNotifications
SSzukajSearch
H, ?ヘルプを表示Help
- -## 投稿にフォーカスされた状態 - - - - - - - - - - - - - - - - - - - -
ショートカットEfektPochodzenie
, K, Shift + Tab上の投稿にフォーカスを移動-
, J, Tab下の投稿にフォーカスを移動-
R返信フォームを開くReply
QRenoteフォームを開くQuote
Ctrl + Q即刻Renoteする(フォームを開かずに)-
E, A, +リアクションフォームを開くEmote, reAction
0~9数字に対応したリアクションをする(対応については後述)-
F, Bお気に入りに登録Favorite, Bookmark
Del, Ctrl + D投稿を削除Delete
M, O投稿に対するメニューを開くMore, Other
SCWで隠された部分を表示 or 隠すShow, See
Escフォーカスを外す-
- -## Renoteフォーム - - - - - - - - - - -
ショートカットEfektPochodzenie
EnterRenoteする-
Qフォームを展開するQuote
Escフォームを閉じる-
- -## リアクションフォーム -デフォルトで「👍」にフォーカスが当たっている状態です。 - - - - - - - - - - - - - -
ショートカットEfektPochodzenie
, K上のリアクションにフォーカスを移動-
, J下のリアクションにフォーカスを移動-
, H, Shift + Tab左のリアクションにフォーカスを移動-
, L, Tab右のリアクションにフォーカスを移動-
Enter, Space, +リアクション確定-
0~9数字に対応したリアクションで確定-
Escリアクションするのをやめる-
diff --git a/src/docs/pl-PL/mfm.md b/src/docs/pl-PL/mfm.md deleted file mode 100644 index e237287ac..000000000 --- a/src/docs/pl-PL/mfm.md +++ /dev/null @@ -1,2 +0,0 @@ -# MFM -MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます。 diff --git a/src/docs/pl-PL/mute.md b/src/docs/pl-PL/mute.md deleted file mode 100644 index 8daf9f68a..000000000 --- a/src/docs/pl-PL/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# Wycisz - -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -* タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -* そのユーザーからの通知 -* メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 - -ユーザーをミュートするには、対象のユーザーのユーザーページに表示されている「ミュート」ボタンを押します。 - -ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。 - -設定>ミュート から、自分がミュートしているユーザー一覧を確認することができます。 diff --git a/src/docs/pl-PL/pages.md b/src/docs/pl-PL/pages.md deleted file mode 100644 index efa18263f..000000000 --- a/src/docs/pl-PL/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# Pages - -## Zmienne -変数を使うことで動的なページを作成できます。テキスト内で { 変数名 } と書くとそこに変数の値を埋め込めます。例えば Hello { thing } world! というテキストで、変数(thing)の値が ai だった場合、テキストは Hello ai world! になります。 - -変数の評価(値を算出すること)は上から下に行われるので、ある変数の中で自分より下の変数を参照することはできません。例えば上から A、B、C と3つの変数を定義したとき、Cの中でABを参照することはできますが、Aの中でBCを参照することはできません。 - -ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。 - -関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。 diff --git a/src/docs/pl-PL/reaction.md b/src/docs/pl-PL/reaction.md deleted file mode 100644 index a471624ce..000000000 --- a/src/docs/pl-PL/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# Reakcja -他の人のノートに、絵文字を付けて簡単にあなたの反応を伝えられる機能です。 リアクションするには、ノートの + アイコンをクリックしてピッカーを表示し、絵文字を選択します。 リアクションには[カスタム絵文字](./custom-emoji)も使用できます。 - -## リアクションピッカーのカスタマイズ -ピッカーに表示される絵文字を自分好みにカスタマイズすることができます。 設定の「リアクション」で設定します。 - -## リモート投稿へのリアクションについて -リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。 また、相手がMisskeyであったとしても、カスタム絵文字リアクションは伝わらず、自動的に「👍」等にフォールバックされます。 - -## リモートからのリアクションについて -リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。 diff --git a/src/docs/pl-PL/reversi-bot.md b/src/docs/pl-PL/reversi-bot.md deleted file mode 100644 index 160c69fd6..000000000 --- a/src/docs/pl-PL/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# MisskeyリバーシBotの開発 -Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。 - -1. `games/reversi`ストリームに以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - -2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる - * イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている - -3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する - -4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - * `game`: `game`の`id` - -5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う - -6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する - -7. ゲームが開始すると、`started`イベントが流れてくる - * イベントの中身にはゲーム情報が含まれている - -8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述) - -9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる - * `color`として石の色が含まれている - * `pos`として位置情報が含まれている - -## 位置の計算法 -8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### X,Y座標 から インデックス に変換する -``` -pos = x + (y * mapWidth) -``` -`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます: -``` -mapWidth = map[0].length -``` - -### インデックス から X,Y座標 に変換する -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## マップ情報 -マップ情報は、ゲーム情報の`map`に入っています。 文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 それをもとにマップのデザインを知る事が出来ます: -* `(スペース)` ... マス無し -* `-` ... Pole -* `b` ... 初期配置される黒石 -* `w` ... 初期配置される白石 - -例えば、4*4の次のような単純なマップがあるとします: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -この場合、マップデータはこのようになります: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## ユーザーにフォームを提示して対話可能Botを作成する -ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。 - -フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します: -```javascript -{ - type: 'init-form', - body: [フォームコントロールの配列] -} -``` - -フォームコントロールの配列については今から説明します。 フォームコントロールは、次のようなオブジェクトです: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... コントロールのID。 `type` ... コントロールの種類。後述します。 `label` ... コントロールと一緒に表記するテキスト。 `value` ... コントロールのデフォルト値。 - -### フォームの操作を受け取る -ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### フォームコントロールの種類 -#### Przełącznik -type: `switch` スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。 - -##### プロパティ -`label` ... スイッチに表記するテキスト。 - -#### ラジオボタン -type: `radio` ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。 - -##### プロパティ -`items` ... ラジオボタンの選択肢。Przykład: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '強', - value: 3 -}] -``` - -#### スライダー -type: `slider` スライダーを表示します。 - -##### プロパティ -`min` ... スライダーの下限。 `max` ... スライダーの上限。 `step` ... 入力欄で刻むステップ値。 - -#### テキストボックス -type: `textbox` テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。 - -## ユーザーにメッセージを表示する -設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 メッセージを表示するには、次のメッセージをストリームに送信します: -```javascript -{ - type: 'message', - body: { - text: 'メッセージ内容', - type: 'メッセージの種類' - } -} -``` -メッセージの種類: `success`, `info`, `warning`, `error`。 - -## 投了する -投了をするには、このエンドポイントにリクエストします。 diff --git a/src/docs/pl-PL/stream.md b/src/docs/pl-PL/stream.md deleted file mode 100644 index 0bf168fca..000000000 --- a/src/docs/pl-PL/stream.md +++ /dev/null @@ -1,354 +0,0 @@ -# ストリーミングAPI - -ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。 - -## ストリームに接続する - -ストリーミングAPIを利用するには、まずMisskeyサーバーに**websocket**接続する必要があります。 - -以下のURLに、`i`というパラメータ名で認証情報を含めて、websocket接続してください。Przykład: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。 - -
-

認証情報の取得については、こちらのドキュメントをご確認ください。

-
- ---- - -認証情報は省略することもできますが、その場合非ログインでの利用ということになり、受信できる情報や可能な操作は限られます。Przykład: - -``` -%WS_URL%/streaming -``` - ---- - -ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。 - -**ストリームでのやり取りはすべてJSONです。** - -## Kanały -MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。 - -### チャンネルに接続する -チャンネルに接続するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -ここで、 -* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。 -* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。 -* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。 - -
-

IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。

-
- -### チャンネルからのメッセージを受け取る -例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。 - -チャンネルがメッセージを発すると、次のようなデータがJSONでストリームに流れてきます: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。 -* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。 -* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。 - -### チャンネルに向けてメッセージを送信する -チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。 - -チャンネルにメッセージを送信するには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。 -* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。 -* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。 - -### チャンネルから切断する -チャンネルから切断するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。 - -## ストリームを経由してAPIリクエストする - -ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。 - -ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -ここで、 -* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 -* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 -* `data`には、エンドポイントのパラメータを含めます。 - -
-

APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。

-
- -### レスポンスの受信 - -APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。 - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -ここで、 -* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 -* `body`には、レスポンスが含まれています。 - -## 投稿のキャプチャ - -Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。 - -例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。 - -しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。 - -この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。 - -### 投稿をキャプチャする - -投稿をキャプチャするには、ストリームに次のようなメッセージを送信します: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャしたい投稿の`id`を設定します。 - -このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 - -例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -ここで、 -* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。 -* `body`内の`type`に、イベントの種類が設定されます。 -* `body`内の`body`に、イベントの詳細が設定されます。 - -#### イベントの種類 - -##### `reacted` -その投稿にリアクションがされた時に発生します。 - -* `reaction`に、リアクションの種類が設定されます。 -* `userId`に、リアクションを行ったユーザーのIDが設定されます。 - -Przykład: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -その投稿が削除された時に発生します。 - -* `deletedAt`に、削除日時が設定されます。 - -Przykład: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -その投稿に添付されたアンケートに投票された時に発生します。 - -* `choice`に、選択肢IDが設定されます。 -* `userId`に、投票を行ったユーザーのIDが設定されます。 - -Przykład: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### 投稿のキャプチャを解除する - -その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。 - -次のメッセージを送信します: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャを解除したい投稿の`id`を設定します。 - -このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 - -# チャンネル一覧 -## `main` -アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `renote` -自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。 - -#### `mention` -誰かからメンションされたときに発生するイベントです。 - -#### `readAllNotifications` -自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。 - -#### `meUpdated` -自分の情報が更新されたことを表すイベントです。 - -#### `follow` -自分が誰かをフォローしたときに発生するイベントです。 - -#### `unfollow` -自分が誰かのフォローを解除したときに発生するイベントです。 - -#### `followed` -自分が誰かにフォローされたときに発生するイベントです。 - -## `homeTimeline` -ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -タイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `localTimeline` -ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `hybridTimeline` -ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ソーシャルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `globalTimeline` -グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 diff --git a/src/docs/pl-PL/theme.md b/src/docs/pl-PL/theme.md deleted file mode 100644 index 7190c39dd..000000000 --- a/src/docs/pl-PL/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# Motywy - -Możesz zmienić wygląd klienta Misskey, ustawiając motyw. - -## Ustawienia motywu -Ustawienia > Motywy - -## Tworzenie motywu -Kod motywów jest zapisywany jako obiekt JSON5 z opcjami motywu. Motywy składają się z następujących opcji. -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... Unikatowe ID motywu.Zalecane jest użycie UUID. -* `name` ... Nazwa motywu -* `author` ... Twórca motywu -* `desc` ... Opis motywu (nieobowiązkowy) -* `base` ... Określa, czy motyw jest oparty na jasnym, czy ciemnym motywie - * `light`にすると明るいテーマになり、`dark`にすると暗いテーマになります。 - * Motyw będzie dziedziczył domyślne wartości określonego tu motywu. -* `props` ... Definicje stylów motywu.これから説明します。 - -### Definicje stylów motywu. -`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 - -#### Składnia wartości -* Kolory Hex - * Np.: `#00ff00` -* Kolory RGB w składni `rgb(r, g, b)` - * Np.: `rgb(0, 255, 0)` -* Kolory RGBA w składni `rgb(r, g, b)` - * Np.: `rgba(0, 255, 0, 0.5)` -* Nawiązania do wartości innych kluczy - * `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。 - * 例: `@panel` -* 定数(後述)の参照 - * `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。 - * 例: `$main` -* 関数(後述) - * `:{関数名}<{引数}<{色}` - -#### Stała -「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 キー名を`$`で始めると、そのキーはCSS変数として出力されません。 - -#### Funkcje -wip diff --git a/src/docs/pl-PL/timelines.md b/src/docs/pl-PL/timelines.md deleted file mode 100644 index 5da219764..000000000 --- a/src/docs/pl-PL/timelines.md +++ /dev/null @@ -1,15 +0,0 @@ -# Porównanie osi czasu - -https://docs.google.com/spreadsheets/d/1lxQ2ugKrhz58Bg96HTDK_2F98BUritkMyIiBkOByjHA/edit?usp=sharing - -## Strona główna -Wpisy użytkowników, których obserwujesz - -## Lokalne -全てのローカルユーザーの「ホーム」指定されていない投稿 - -## Społeczność -自分のフォローしているユーザーの投稿と、全てのローカルユーザーの「ホーム」指定されていない投稿 - -## Globalne -全てのローカルユーザーの「ホーム」指定されていない投稿と、サーバーに届いた全てのリモートユーザーの「ホーム」指定されていない投稿 diff --git a/src/docs/pt-PT/admin/disable-timelines.md b/src/docs/pt-PT/admin/disable-timelines.md deleted file mode 100644 index b081e35ab..000000000 --- a/src/docs/pt-PT/admin/disable-timelines.md +++ /dev/null @@ -1,8 +0,0 @@ -# LTL/STL/GTLの無効化 -Misskeyでは、LTL/STL/GTLをそれぞれ無効化することができます。有効/無効を切り替えるには、インスタンスコントロールパネルで設定します。 - -LTLやSTLは、そのインスタンス全員の投稿が見れるため、新規のユーザーにとってはユーザーを探す必要がなくなり、興味のあるユーザーを見つけやすいという利点があります。 しかし同時に、フォロー機能が活用されなくなったり、不適切な投稿が目につきやすくなったり、チャットのようになることで内輪感が生じて逆に新規ユーザーが参加しにくくなるといったデメリットも持ち合わせています。 サーバーによってメリット/デメリットどちらが優勢かは異なるので、オプションとして無効にできるようになっています。 もしデメリットの方が上回っていると感じたら、それらのタイムラインを無効化することも検討してください。 - -
⚠️ 無効化を行うと、ユーザーが困惑し、短期的に見て利用者が減る可能性があります。そのため、無効化の際は影響を慎重に検討し、事前に説明してフォローを整える期間を一定程度設けることを推奨します。
- -なお、管理者/モデレーターは、これらのタイムラインの無効化状態は適用されず、引き続き利用することが可能です。 diff --git a/src/docs/pt-PT/admin/faq.md b/src/docs/pt-PT/admin/faq.md deleted file mode 100644 index 317b4e065..000000000 --- a/src/docs/pt-PT/admin/faq.md +++ /dev/null @@ -1,5 +0,0 @@ -# よくある質問 -ここでは、サーバー管理者向けのよくある質問を掲載しています。 - -## デフォルトテーマを設定したい -現在、デフォルトテーマ設定機能は実装されていません。 diff --git a/src/docs/pt-PT/advanced/aiscript.md b/src/docs/pt-PT/advanced/aiscript.md deleted file mode 100644 index 604d17daa..000000000 --- a/src/docs/pt-PT/advanced/aiscript.md +++ /dev/null @@ -1,7 +0,0 @@ -# AiScript -AiScriptは、Misskeyで使用できるスクリプト言語です。 - -
ℹ️ AiScript実装はMisskeyとは別リポジトリで、オープンソースで公開されています。
- -## 使い方 -AiScriptの構文や組み込み関数などのドキュメントは、[こちら](https://github.com/syuilo/aiscript/tree/master/docs)で公開されています。 diff --git a/src/docs/pt-PT/advanced/api.md b/src/docs/pt-PT/advanced/api.md deleted file mode 100644 index 76019b614..000000000 --- a/src/docs/pt-PT/advanced/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス、Bot等(以下「アプリケーション」と呼びます)を開発できます。 ストリーミングAPIもあるので、リアルタイム性のあるアプリケーションを作ることも可能です。 - -APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。 - -## アクセストークンの取得 -基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。 - -* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む -* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む - -### 自分自身のアクセストークンを手動発行する -「設定 > API」で、自分のアクセストークンを発行できます。 - -[「APIの使い方」へ進む](#APIの使い方) - -### アプリケーション利用者にアクセストークンの発行をリクエストする -アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。 - -#### Step 1 - -UUIDを生成する。以後これをセッションIDと呼びます。 - -> このセッションIDは毎回生成し、使いまわさないようにしてください。 - -#### Step 2 - -`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。 -> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます: -* `name` ... アプリケーション名 - * > 例: `MissDeck` -* `icon` ... アプリケーションのアイコン画像URL - * > 例: `https://missdeck.example.com/icon.png` -* `callback` ... 認証が終わった後にリダイレクトするURL - * > 例: `https://missdeck.example.com/callback` - * リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます -* `permission` ... アプリケーションが要求する権限 - * > 例: `write:notes,write:following,read:drive` - * 要求する権限を`,`で区切って列挙します - * どのような権限があるかは[APIリファレンス](/api-doc)で確認できます - -#### Step 3 -ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。 - -レスポンスに含まれるプロパティ: -* `token` ... ユーザーのアクセストークン -* `user` ... ユーザーの情報 - -[「APIの使い方」へ進む](#APIの使い方) - -## APIの使い方 -**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。 - -* [APIリファレンス](/api-doc) -* [ストリーミングAPI](./stream) diff --git a/src/docs/pt-PT/advanced/create-plugin.md b/src/docs/pt-PT/advanced/create-plugin.md deleted file mode 100644 index 0d2fa1917..000000000 --- a/src/docs/pt-PT/advanced/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# プラグインの作成 -Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。 - -## メタデータ -プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。 - -### name -プラグイン名 - -### author -プラグイン作者 - -### version -プラグインバージョン。数値を指定してください。 - -### description -プラグインの説明 - -### permissions -プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。 - -### config -プラグインの設定情報を表すオブジェクト。 キーに設定名、値に以下のプロパティを含めます。 - -#### type -設定値の種類を表す文字列。以下から選択します。 string number boolean - -#### label -ユーザーに表示する設定名 - -#### description -設定の説明 - -#### default -設定のデフォルト値 - -## APIリファレンス -AiScript標準で組み込まれているAPIは掲載しません。 - -### Mk:dialog(title text type) -ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。 - -### Mk:confirm(title text type) -確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。 - -### Mk:api(endpoint params) -Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。 - -### Mk:save(key value) -任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。 - -### Mk:load(key) -Mk:saveで永続化した指定の名前の値を読み取ります。 - -### Plugin:register_post_form_action(title fn) -投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。 - -### Plugin:register_note_action(title fn) -ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 - -### Plugin:register_user_action(title fn) -ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。 - -### Plugin:register_note_view_interruptor(fn) -UIに表示されるノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:register_note_post_interruptor(fn) -ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:open_url(url) -第一引数に渡されたURLをブラウザの新しいタブで開きます。 - -### Plugin:config -プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。 diff --git a/src/docs/pt-PT/advanced/develop-bot.md b/src/docs/pt-PT/advanced/develop-bot.md deleted file mode 100644 index 7f825e9bc..000000000 --- a/src/docs/pt-PT/advanced/develop-bot.md +++ /dev/null @@ -1,6 +0,0 @@ -# Botの作成 -[Misskey API](./api)を利用してBotの開発が可能です。 また、いくつかのBot実装が公開されているため、ぜひ参考にしてください。 - -- [syuilo/ai](https://github.com/syuilo/ai) ... Node.js上で動く、TypeScript製Bot実装 - -Botを作成したときは、プロフィール設定からBotフラグをオンにしておくことを強くおすすめします。 diff --git a/src/docs/pt-PT/advanced/reversi-bot.md b/src/docs/pt-PT/advanced/reversi-bot.md deleted file mode 100644 index 7ab2a7212..000000000 --- a/src/docs/pt-PT/advanced/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# MisskeyリバーシBotの開発 -Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。 - -1. `games/reversi`ストリームに以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - -2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる - * イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている - -3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する - -4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - * `game`: `game`の`id` - -5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う - -6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する - -7. ゲームが開始すると、`started`イベントが流れてくる - * イベントの中身にはゲーム情報が含まれている - -8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述) - -9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる - * `color`として石の色が含まれている - * `pos`として位置情報が含まれている - -## 位置の計算法 -8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### X,Y座標 から インデックス に変換する -``` -pos = x + (y * mapWidth) -``` -`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます: -``` -mapWidth = map[0].length -``` - -### インデックス から X,Y座標 に変換する -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## マップ情報 -マップ情報は、ゲーム情報の`map`に入っています。 文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 それをもとにマップのデザインを知る事が出来ます: -* `(スペース)` ... マス無し -* `-` ... マス -* `b` ... 初期配置される黒石 -* `w` ... 初期配置される白石 - -例えば、4*4の次のような単純なマップがあるとします: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -この場合、マップデータはこのようになります: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## ユーザーにフォームを提示して対話可能Botを作成する -ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。 - -フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します: -```javascript -{ - type: 'init-form', - body: [フォームコントロールの配列] -} -``` - -フォームコントロールの配列については今から説明します。 フォームコントロールは、次のようなオブジェクトです: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... コントロールのID。 `type` ... コントロールの種類。後述します。 `label` ... コントロールと一緒に表記するテキスト。 `value` ... コントロールのデフォルト値。 - -### フォームの操作を受け取る -ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### フォームコントロールの種類 -#### スイッチ -type: `switch` スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。 - -##### プロパティ -`label` ... スイッチに表記するテキスト。 - -#### ラジオボタン -type: `radio` ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。 - -##### プロパティ -`items` ... ラジオボタンの選択肢。例: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '強', - value: 3 -}] -``` - -#### スライダー -type: `slider` スライダーを表示します。 - -##### プロパティ -`min` ... スライダーの下限。 `max` ... スライダーの上限。 `step` ... 入力欄で刻むステップ値。 - -#### テキストボックス -type: `textbox` テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。 - -## ユーザーにメッセージを表示する -設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 メッセージを表示するには、次のメッセージをストリームに送信します: -```javascript -{ - type: 'message', - body: { - text: 'メッセージ内容', - type: 'メッセージの種類' - } -} -``` -メッセージの種類: `success`, `info`, `warning`, `error`。 - -## 投了する -投了をするには、このエンドポイントにリクエストします。 diff --git a/src/docs/pt-PT/advanced/share-page.md b/src/docs/pt-PT/advanced/share-page.md deleted file mode 100644 index 4fb7ded0b..000000000 --- a/src/docs/pt-PT/advanced/share-page.md +++ /dev/null @@ -1,54 +0,0 @@ -# シェアページ -`/share`を開くと、共有用の投稿フォームを開くことができます。 ここではシェアページで利用できるクエリ文字列の一覧を示します。 - -## クエリ文字列一覧 -### 文字 - -
-
title
-
タイトルです。本文の先頭に[ … ]と挿入されます。
-
text
-
本文です。
-
url
-
URLです。末尾に挿入されます。
-
- -### リプライ情報 -以下のいずれか - -
-
replyId
-
リプライ先のノートid
-
replyUri
-
リプライ先のUrl(リモートのノートオブジェクトを指定)
-
- -### Renote情報 -以下のいずれか - -
-
renoteId
-
Renote先のノートid
-
renoteUri
-
Renote先のUrl(リモートのノートオブジェクトを指定)
-
- -### 公開範囲 -※specifiedに相当する値はvisibility=specifiedとvisibleAccts/visibleUserIdsで指定する - -
-
visibility
-
公開範囲 ['public' | 'home' | 'followers' | 'specified']
-
localOnly
-
0(false) or 1(true)
-
visibleUserIds
-
specified時のダイレクト先のユーザーid カンマ区切りで
-
visibleAccts
-
specified時のダイレクト先のacct(@?username[@host]) カンマ区切りで
-
- -### ファイル -
-
fileIds
-
添付したいファイルのid(カンマ区切りで)
-
diff --git a/src/docs/pt-PT/advanced/stream.md b/src/docs/pt-PT/advanced/stream.md deleted file mode 100644 index 0e5edd2b0..000000000 --- a/src/docs/pt-PT/advanced/stream.md +++ /dev/null @@ -1,350 +0,0 @@ -# ストリーミングAPI - -ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。 - -## ストリームに接続する - -ストリーミングAPIを利用するには、まずMisskeyサーバーに**websocket**接続する必要があります。 - -以下のURLに、`i`というパラメータ名で認証情報を含めて、websocket接続してください。例: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。 - -
ℹ️ 認証情報の取得については、こちらのドキュメントをご確認ください。
- ---- - -認証情報は省略することもできますが、その場合非ログインでの利用ということになり、受信できる情報や可能な操作は限られます。例: - -``` -%WS_URL%/streaming -``` - ---- - -ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。 - -**ストリームでのやり取りはすべてJSONです。** - -## チャンネル -MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。 - -ひとつのストリーム上で、同時に複数のチャンネルに接続することができます。 - -### チャンネルに接続する -チャンネルに接続するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -ここで、 -* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。 -* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。 -* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。 - -
ℹ️ IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。
- -### チャンネルからのメッセージを受け取る -例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。 - -チャンネルがメッセージを発すると、次のようなデータがJSONでストリームに流れてきます: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。 -* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。 -* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。 - -### チャンネルに向けてメッセージを送信する -チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。 - -チャンネルにメッセージを送信するには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。 -* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。 -* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。 - -### チャンネルから切断する -チャンネルから切断するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。 - -## ストリームを経由してAPIリクエストする - -ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。 - -ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -ここで、 -* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 -* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 -* `data`には、エンドポイントのパラメータを含めます。 - -
ℹ️ APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。
- -### レスポンスの受信 - -APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。 - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -ここで、 -* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 -* `body`には、レスポンスが含まれています。 - -## 投稿のキャプチャ - -Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。 - -例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。 - -しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。 - -この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。 - -### 投稿をキャプチャする - -投稿をキャプチャするには、ストリームに次のようなメッセージを送信します: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャしたい投稿の`id`を設定します。 - -このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 - -例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -ここで、 -* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。 -* `body`内の`type`に、イベントの種類が設定されます。 -* `body`内の`body`に、イベントの詳細が設定されます。 - -#### イベントの種類 - -##### `reacted` -その投稿にリアクションがされた時に発生します。 - -* `reaction`に、リアクションの種類が設定されます。 -* `userId`に、リアクションを行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -その投稿が削除された時に発生します。 - -* `deletedAt`に、削除日時が設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -その投稿に添付されたアンケートに投票された時に発生します。 - -* `choice`に、選択肢IDが設定されます。 -* `userId`に、投票を行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### 投稿のキャプチャを解除する - -その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。 - -次のメッセージを送信します: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャを解除したい投稿の`id`を設定します。 - -このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 - -# チャンネル一覧 -## `main` -アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `renote` -自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。 - -#### `mention` -誰かからメンションされたときに発生するイベントです。 - -#### `readAllNotifications` -自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。 - -#### `meUpdated` -自分の情報が更新されたことを表すイベントです。 - -#### `follow` -自分が誰かをフォローしたときに発生するイベントです。 - -#### `unfollow` -自分が誰かのフォローを解除したときに発生するイベントです。 - -#### `followed` -自分が誰かにフォローされたときに発生するイベントです。 - -## `homeTimeline` -ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -タイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `localTimeline` -ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `hybridTimeline` -ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ソーシャルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `globalTimeline` -グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 diff --git a/src/docs/pt-PT/aiscript.md b/src/docs/pt-PT/aiscript.md deleted file mode 100644 index f38f46512..000000000 --- a/src/docs/pt-PT/aiscript.md +++ /dev/null @@ -1,4 +0,0 @@ -# AiScript - -## Funções -Por padrão, são passados por valores. diff --git a/src/docs/pt-PT/api.md b/src/docs/pt-PT/api.md deleted file mode 100644 index 76019b614..000000000 --- a/src/docs/pt-PT/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス、Bot等(以下「アプリケーション」と呼びます)を開発できます。 ストリーミングAPIもあるので、リアルタイム性のあるアプリケーションを作ることも可能です。 - -APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。 - -## アクセストークンの取得 -基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。 - -* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む -* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む - -### 自分自身のアクセストークンを手動発行する -「設定 > API」で、自分のアクセストークンを発行できます。 - -[「APIの使い方」へ進む](#APIの使い方) - -### アプリケーション利用者にアクセストークンの発行をリクエストする -アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。 - -#### Step 1 - -UUIDを生成する。以後これをセッションIDと呼びます。 - -> このセッションIDは毎回生成し、使いまわさないようにしてください。 - -#### Step 2 - -`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。 -> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます: -* `name` ... アプリケーション名 - * > 例: `MissDeck` -* `icon` ... アプリケーションのアイコン画像URL - * > 例: `https://missdeck.example.com/icon.png` -* `callback` ... 認証が終わった後にリダイレクトするURL - * > 例: `https://missdeck.example.com/callback` - * リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます -* `permission` ... アプリケーションが要求する権限 - * > 例: `write:notes,write:following,read:drive` - * 要求する権限を`,`で区切って列挙します - * どのような権限があるかは[APIリファレンス](/api-doc)で確認できます - -#### Step 3 -ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。 - -レスポンスに含まれるプロパティ: -* `token` ... ユーザーのアクセストークン -* `user` ... ユーザーの情報 - -[「APIの使い方」へ進む](#APIの使い方) - -## APIの使い方 -**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。 - -* [APIリファレンス](/api-doc) -* [ストリーミングAPI](./stream) diff --git a/src/docs/pt-PT/create-plugin.md b/src/docs/pt-PT/create-plugin.md deleted file mode 100644 index 0d2fa1917..000000000 --- a/src/docs/pt-PT/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# プラグインの作成 -Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。 - -## メタデータ -プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。 - -### name -プラグイン名 - -### author -プラグイン作者 - -### version -プラグインバージョン。数値を指定してください。 - -### description -プラグインの説明 - -### permissions -プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。 - -### config -プラグインの設定情報を表すオブジェクト。 キーに設定名、値に以下のプロパティを含めます。 - -#### type -設定値の種類を表す文字列。以下から選択します。 string number boolean - -#### label -ユーザーに表示する設定名 - -#### description -設定の説明 - -#### default -設定のデフォルト値 - -## APIリファレンス -AiScript標準で組み込まれているAPIは掲載しません。 - -### Mk:dialog(title text type) -ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。 - -### Mk:confirm(title text type) -確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。 - -### Mk:api(endpoint params) -Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。 - -### Mk:save(key value) -任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。 - -### Mk:load(key) -Mk:saveで永続化した指定の名前の値を読み取ります。 - -### Plugin:register_post_form_action(title fn) -投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。 - -### Plugin:register_note_action(title fn) -ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 - -### Plugin:register_user_action(title fn) -ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。 - -### Plugin:register_note_view_interruptor(fn) -UIに表示されるノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:register_note_post_interruptor(fn) -ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:open_url(url) -第一引数に渡されたURLをブラウザの新しいタブで開きます。 - -### Plugin:config -プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。 diff --git a/src/docs/pt-PT/custom-emoji.md b/src/docs/pt-PT/custom-emoji.md deleted file mode 100644 index ed2e92be1..000000000 --- a/src/docs/pt-PT/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# カスタム絵文字 -カスタム絵文字は、インスタンスで用意された画像を絵文字のように使える機能です。 ノート、リアクション、チャット、自己紹介、名前などの場所で使うことができます。 カスタム絵文字をそれらの場所で使うには、絵文字ピッカーボタン(ある場合)を押すか、`:`を入力して絵文字サジェストを表示します。 テキスト内に`:foo:`のような形式の文字列が見つかると、`foo`の部分がカスタム絵文字名と解釈され、表示時には対応したカスタム絵文字に置き換わります。 diff --git a/src/docs/pt-PT/deck.md b/src/docs/pt-PT/deck.md deleted file mode 100644 index 8057e262f..000000000 --- a/src/docs/pt-PT/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# デッキ - -デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。 - -## カラムの追加 -デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。 - -## カラムの移動 -カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。 - -## カラムの水平分割 -カラムは左右だけでなく、上下に並べることもできます。 カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 上下分割を解除するには、カラムメニューの「右に出す」を選択します。 - -## カラムの設定 -カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。 - -## デッキの設定 -デッキに関する設定は、[settings/deck](/settings/deck)で行えます。 diff --git a/src/docs/pt-PT/features/antenna.md b/src/docs/pt-PT/features/antenna.md deleted file mode 100644 index 94ad9e4ae..000000000 --- a/src/docs/pt-PT/features/antenna.md +++ /dev/null @@ -1,4 +0,0 @@ -# アンテナ -アンテナは、自由に条件を設定して、合致するノートを自動で収集することができる機能です。 - -条件を設定したアンテナが作成された状態で、条件に合致するノートが投稿されると、リアルタイムでそのアンテナのタイムラインにノートが追加されます。 diff --git a/src/docs/pt-PT/features/custom-emoji.md b/src/docs/pt-PT/features/custom-emoji.md deleted file mode 100644 index ba9a9743f..000000000 --- a/src/docs/pt-PT/features/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# Emojis Customizados -カスタム絵文字は、インスタンスで用意された画像を絵文字のように使える機能です。 ノート、リアクション、チャット、自己紹介、名前などの場所で使うことができます。 カスタム絵文字をそれらの場所で使うには、絵文字ピッカーボタン(ある場合)を押すか、`:`を入力して絵文字サジェストを表示します。 テキスト内に`:foo:`のような形式の文字列が見つかると、`foo`の部分がカスタム絵文字名と解釈され、表示時には対応したカスタム絵文字に置き換わります。 diff --git a/src/docs/pt-PT/features/deck.md b/src/docs/pt-PT/features/deck.md deleted file mode 100644 index 8057e262f..000000000 --- a/src/docs/pt-PT/features/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# デッキ - -デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。 - -## カラムの追加 -デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。 - -## カラムの移動 -カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。 - -## カラムの水平分割 -カラムは左右だけでなく、上下に並べることもできます。 カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 上下分割を解除するには、カラムメニューの「右に出す」を選択します。 - -## カラムの設定 -カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。 - -## デッキの設定 -デッキに関する設定は、[settings/deck](/settings/deck)で行えます。 diff --git a/src/docs/pt-PT/features/drive.md b/src/docs/pt-PT/features/drive.md deleted file mode 100644 index b82a41082..000000000 --- a/src/docs/pt-PT/features/drive.md +++ /dev/null @@ -1,17 +0,0 @@ -# ドライブ -ドライブは、Misskey上でファイルを管理できる機能です。 - -[ドライブのページ](/my/drive)から任意のファイルをアップロードできるほか、アバターに設定した画像や、ノートに添付したファイルなどもすべてドライブにアップロードされます。 - -
⚠️ ドライブからファイルを削除すると、そのファイルが添付されたノートも消えます。
- -ドライブにアップロードされたファイルは、いつでもダウンロードすることができるほか、ノート作成時に「ドライブからファイルを添付」することでファイルを再利用することもできます。 - -ドライブ内にフォルダを作り、複数のファイルをまとめて整理することもできます。 - -## 閲覧注意 (NSFW) -
ℹ️ この項目が閲覧注意なわけではありません
- -閲覧注意またはNSFW (Not safe for work) は、ドライブのファイルに設定することができるフラグです。 閲覧注意フラグを設定されたファイルは、表示される際に閲覧者の操作なしには表示されなくなります。 このフラグは、例えば職場や公共の場で閲覧するのに適切でないと思われる画像などに設定し、そのような画像が突然表示されてしまうことを防ぐ目的で使われます。 - -このフラグは手動でオンオフを切り替えられるほか、モデレーターの判断で設定される場合もあります。 diff --git a/src/docs/pt-PT/features/favorite.md b/src/docs/pt-PT/features/favorite.md deleted file mode 100644 index a194f53e0..000000000 --- a/src/docs/pt-PT/features/favorite.md +++ /dev/null @@ -1,4 +0,0 @@ -# Favoritar -[ノート](./node)をお気に入りとして登録できる機能です。 お気に入り登録したノートは、[お気に入りページ](./my/favorites)で一覧することができます。 お気に入りに登録したことは相手に通知されず、お気に入りは自分しか見ることができません。 - -ノートをお気に入り登録するには、ノートメニューの「お気に入り」を押します。お気に入り解除するには、ノートメニューの「お気に入り解除」を押します。 diff --git a/src/docs/pt-PT/features/follow.md b/src/docs/pt-PT/features/follow.md deleted file mode 100644 index 3c1ea7bbe..000000000 --- a/src/docs/pt-PT/features/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# フォロー -ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。 diff --git a/src/docs/pt-PT/features/keyboard-shortcut.md b/src/docs/pt-PT/features/keyboard-shortcut.md deleted file mode 100644 index 79a9dbceb..000000000 --- a/src/docs/pt-PT/features/keyboard-shortcut.md +++ /dev/null @@ -1,66 +0,0 @@ -# キーボードショートカット - -## グローバル -これらのショートカットは基本的にどこでも使えます。 - - - - - - - - - - - -
ショートカット効果由来
P, N新規投稿Post, New, Note
Tタイムラインの最も新しい投稿にフォーカスTimeline, Top
Shift + N通知を表示/隠すNotifications
SPesquisarSearch
H, ?ヘルプを表示Help
- -## 投稿にフォーカスされた状態 - - - - - - - - - - - - - - - - - - -
ショートカット効果由来
, K, Shift + Tab上の投稿にフォーカスを移動-
, J, Tab下の投稿にフォーカスを移動-
R返信フォームを開くReply
QRenoteフォームを開くQuote
Ctrl + Q即刻Renoteする(フォームを開かずに)-
E, A, +リアクションフォームを開くEmote, reAction
0~9数字に対応したリアクションをする(対応については後述)-
F, Bお気に入りに登録Favorite, Bookmark
Del, Ctrl + D投稿を削除Delete
M, O投稿に対するメニューを開くMore, Other
SCWで隠された部分を表示 or 隠すShow, See
Escフォーカスを外す-
- -## Renoteフォーム - - - - - - - - - -
ショートカット効果由来
EnterRenoteする-
Qフォームを展開するQuote
Escフォームを閉じる-
- -## リアクションフォーム -デフォルトで「👍」にフォーカスが当たっている状態です。 - - - - - - - - - - - - - -
ショートカット効果由来
, K上のリアクションにフォーカスを移動-
, J下のリアクションにフォーカスを移動-
, H, Shift + Tab左のリアクションにフォーカスを移動-
, L, Tab右のリアクションにフォーカスを移動-
Enter, Space, +リアクション確定-
0~9数字に対応したリアクションで確定-
Escリアクションするのをやめる-
diff --git a/src/docs/pt-PT/features/mfm.md b/src/docs/pt-PT/features/mfm.md deleted file mode 100644 index 5be2df4f3..000000000 --- a/src/docs/pt-PT/features/mfm.md +++ /dev/null @@ -1,12 +0,0 @@ -# MFM -MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます。 - -## MFMが使用可能な場所の例 -- ノート本文 -- CW注釈 -- ユーザーの名前 -- ユーザーの自己紹介 - -## 開発者向け情報 -MFMのパーサー実装はライブラリとして公開されており、簡単にクライアントにMFMを組み込むことが可能です。 -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptパーサー実装 diff --git a/src/docs/pt-PT/features/mute-and-block.md b/src/docs/pt-PT/features/mute-and-block.md deleted file mode 100644 index 9846a9ee4..000000000 --- a/src/docs/pt-PT/features/mute-and-block.md +++ /dev/null @@ -1,41 +0,0 @@ -# ミュートとブロック -好みではないユーザーがいる場合は、ミュートを行うことでそのユーザーが自分から見えないようにすることができます。 また、より強力な措置として、ブロックを行うことでそのユーザーから自分のコンテンツが見えないようになるほか、自分に対して関わることができないようにすることができます。 ミュートされていることは相手は分かりませんが、ブロックされていることは相手に分かります。どちらを選ぶかはご自身の判断で行ってください。 - -
ℹ️ ミュートとブロックは併用できます。
- -
⚠️ 利用規約に違反するような、迷惑なユーザーがいる場合は運営者に報告することも検討してください。
- -設定>ミュートとブロック から、自分がミュートまたはブロックしているユーザー一覧を確認することができます。 - -## Silenciar -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -- タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -- そのユーザーからの通知 -- メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 -- など - -ユーザーをミュートするには、対象のユーザーのユーザーページのメニューを開き、「ミュート」ボタンを押します。 - -
ℹ️ ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。
- -## ブロック -ユーザーをブロックすると、そのユーザーからあなたのコンテンツが見えないようになり、またあなたに対して以下のようなアクションをすることができなくなります。 - -- フォローする -- ユーザーリストに追加する -- 返信する、Renoteする -- リアクションする、アンケートに投票する -- メッセージを送信する -- など - -また、 - -- ブロックする際に既にそのユーザーからフォローされていた場合はフォローが解除されます。 -- ブロックする際に既にそのユーザーがあなたをユーザーリストに入れていた場合はそのリストからあなたが削除されます。 - -ユーザーをブロックするには、対象のユーザーのユーザーページのメニューを開き、「ブロック」ボタンを押します。 - -
⚠️ ブロックを行ったこと自体は相手に通知されませんが、フォローを行ったりなどの上記のアクションが行えなくなるので間接的にブロックされていることは分かります。
- -
⚠️ 相手から自分のコンテンツが見えなくなりますが、相手がアカウントを切り替えたりログアウト状態になれば見ることができます。あくまで簡易的、補助的なものとしてお考えください。
diff --git a/src/docs/pt-PT/features/mute.md b/src/docs/pt-PT/features/mute.md deleted file mode 100644 index 331e5cc10..000000000 --- a/src/docs/pt-PT/features/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# Silenciar - -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -* タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -* そのユーザーからの通知 -* メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 - -ユーザーをミュートするには、対象のユーザーのユーザーページに表示されている「ミュート」ボタンを押します。 - -ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。 - -設定>ミュート から、自分がミュートしているユーザー一覧を確認することができます。 diff --git a/src/docs/pt-PT/features/note.md b/src/docs/pt-PT/features/note.md deleted file mode 100644 index aad940ab7..000000000 --- a/src/docs/pt-PT/features/note.md +++ /dev/null @@ -1,54 +0,0 @@ -# Posts -ノートは、Misskeyに投稿される、文章、ファイル、アンケートなどを含むコンテンツで、Misskeyの中心的概念です。また、そのノートを作成する行為自体もノートと呼ばれます。 - -ノートが作成されると、[タイムライン](./timeline)に追加され、自分の[フォロワー](./follow)やサーバーのユーザーが見れるようになります。 - -ノートには、[リアクション](./reaction)を行うことができます。また、返信や引用もできます。 - -ノートを[お気に入り](./favorite)登録することで、後で簡単に見返すことができます。 - -## ノートを作成する -ノートを作成するには、画面上にある鉛筆マークのボタンを押して、作成フォームを開きます。作成フォームに内容を入力し、「ノート」ボタンを押すことでノートが作成されます。 ノートには、画像、動画など任意のファイルや、[アンケート](./poll)を添付することができます。また、本文中には[MFM](./mfm)が使用でき、[メンション](./mention)や[ハッシュタグ](./hashtag)を含めることもできます。 他にも、CWや公開範囲といった設定も行えます(詳細は後述)。 -
ℹ️ コンピューターのクリップボードに画像データがある状態で、フォーム内のテキストボックスにペーストするとその画像を添付することができます。
-
ℹ️ テキストボックス内でCtrl + Enterを押すことでも投稿できます。
- -## Repostar -既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノートをRenoteと呼びます。 自分がフォローしているユーザーの、気に入ったノートを自分のフォロワーに共有したい場合や、過去の自分のノートを再度共有したい場合に使います。 同じノートに対して無制限にRenoteを行うことができますが、あまり連続して使用すると迷惑になる場合もあるので、注意しましょう。 -
⚠️ 公開範囲がフォロワーやダイレクトのノートはRenoteできません
- -Renoteを削除するには、Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 - -## CW -Contents Warningの略で、ノートの内容を、閲覧者の操作なしには表示しないようにできる機能です。主に長大な内容を隠すためや、ネタバレ防止などに使うことができます。 設定するには、フォームの「内容を隠す」ボタン(目のアイコン)を押します。すると新しい入力エリアが表れるので、そこに内容の要約を記入します。 - -## 公開範囲 -ノートごとに、そのノートが公開される範囲を設定することができます。フォームの「ノート」ボタンの左にあるアイコンを押すと公開範囲を以下から選択できます。 - -### パブリック -全ての人に対してノートが公開されるほか、サーバーの全てのタイムライン(ホームタイムライン、ローカルタイムライン、ソーシャルタイムライン、グローバルタイムライン)にノートが流れます。 -
⚠️ アカウントがサイレンス状態の時は、この公開範囲は使用できません。
- -### ホーム -全ての人に対してノートが公開されますが、フォロワー以外のローカルタイムライン、ソーシャルタイムライン、グローバルタイムラインにはノートは流れません。 - -### フォロワー -自分のフォロワーに対してのみノートを公開します。フォロワーの全てのタイムラインに流れます。 - -### ダイレクト -指定したユーザーに対してのみノートを公開します。指定したユーザーの全てのタイムラインに流れます。 - -### 「ローカルのみ」オプション -このオプションを有効にすると、リモートにノートを連合しなくなります。 - -### 公開範囲の比較 - - - - -
パブリックホームフォロワーダイレクト
フォロワーのLTL/STL/GTL
非フォロワーのLTL/STL/GTL
- -## ピン留め -ノートをピン留めすると、ユーザーページに常にそのノートを表示しておくことができます。 ノートのメニューを開き、「ピン留め」を選択してピン留めできます。 複数のノートをピン留めできます。 - -## ウォッチ -ノートをウォッチすると、自分以外のノートへのリアクションや返信などの通知を受け取ることができます。 ノートのメニューを開き、「ウォッチ」を選択してウォッチできます。 diff --git a/src/docs/pt-PT/features/pages.md b/src/docs/pt-PT/features/pages.md deleted file mode 100644 index a7311b95e..000000000 --- a/src/docs/pt-PT/features/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# Pages - -## 変数 -変数を使うことで動的なページを作成できます。テキスト内で { 変数名 } と書くとそこに変数の値を埋め込めます。例えば Hello { thing } world! というテキストで、変数(thing)の値が ai だった場合、テキストは Hello ai world! になります。 - -変数の評価(値を算出すること)は上から下に行われるので、ある変数の中で自分より下の変数を参照することはできません。例えば上から A、B、C と3つの変数を定義したとき、Cの中でABを参照することはできますが、Aの中でBCを参照することはできません。 - -ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。 - -関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。 diff --git a/src/docs/pt-PT/features/reaction.md b/src/docs/pt-PT/features/reaction.md deleted file mode 100644 index 4d479fd41..000000000 --- a/src/docs/pt-PT/features/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# リアクション -他の人のノートに、絵文字を付けて簡単にあなたの反応を伝えられる機能です。 リアクションするには、ノートの + アイコンをクリックしてピッカーを表示し、絵文字を選択します。 リアクションには[カスタム絵文字](./custom-emoji)も使用できます。 - -## リアクションピッカーのカスタマイズ -ピッカーに表示される絵文字を自分好みにカスタマイズすることができます。 設定の「リアクション」で設定します。 - -## リモート投稿へのリアクションについて -リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。 - -## リモートからのリアクションについて -リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。 diff --git a/src/docs/pt-PT/features/silence.md b/src/docs/pt-PT/features/silence.md deleted file mode 100644 index 7e26feab0..000000000 --- a/src/docs/pt-PT/features/silence.md +++ /dev/null @@ -1,6 +0,0 @@ -# サイレンス -サイレンスは、アカウントに設定される状態のひとつです。 - -アカウントがサイレンス状態になると、ノートの公開範囲をパブリックにできなくなります。 ホーム、フォロワー、ダイレクトは選択可能なため、サイレンスを受けた場合でもフォロワーやあなたのユーザーページを直接訪れた場合は投稿を閲覧できますが、GTL(連合タイムライン)やLTL(ローカルタイムライン)には投稿が流れません。 - -アカウントのサイレンス状態は、サーバーのモデレーターによって有効化/無効化されます。 diff --git a/src/docs/pt-PT/features/theme.md b/src/docs/pt-PT/features/theme.md deleted file mode 100644 index 1da9cbee7..000000000 --- a/src/docs/pt-PT/features/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# Temas - -É possível mudar a aparência do Misskey com as configurações de tema. - -## Configurações de tema -Configurações > Temas. - -## テーマを作成する -テーマコードはJSON5で記述されたテーマオブジェクトです。 テーマは以下のようなオブジェクトです。 -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... テーマの一意なID。UUIDをおすすめします。 -* `name` ... テーマ名 -* `author` ... テーマの作者 -* `desc` ... テーマの説明(オプション) -* `base` ... 明るいテーマか、暗いテーマか - * `light`にすると明るいテーマになり、`dark`にすると暗いテーマになります。 - * テーマはここで設定されたベーステーマを継承します。 -* `props` ... テーマのスタイル定義。これから説明します。 - -### テーマのスタイル定義 -`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 - -#### バリューで使える構文 -* 16進数で表された色 - * 例: `#00ff00` -* `rgb(r, g, b)`形式で表された色 - * 例: `rgb(0, 255, 0)` -* `rgb(r, g, b, a)`形式で表された透明度を含む色 - * 例: `rgba(0, 255, 0, 0.5)` -* 他のキーの値の参照 - * `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。 - * 例: `@panel` -* 定数(後述)の参照 - * `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。 - * 例: `$main` -* 関数(後述) - * `:{関数名}<{引数}<{色}` - -#### 定数 -「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 キー名を`$`で始めると、そのキーはCSS変数として出力されません。 - -#### 関数 -wip diff --git a/src/docs/pt-PT/features/timeline.md b/src/docs/pt-PT/features/timeline.md deleted file mode 100644 index 095115703..000000000 --- a/src/docs/pt-PT/features/timeline.md +++ /dev/null @@ -1,31 +0,0 @@ -# Linha do tempo -タイムラインは、[ノート](./note)が時系列で表示される機能です。 タイムラインには以下で示す種類があり、種類によって表示されるノートも異なります。 なお、タイムラインの種類によってはサーバーにより無効になっている場合があります。 - -## Início -Postagens de usuários que você segue serão mostradas.Abreviado como HTL. - -## Local -全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。LTLと略されます。 - -## Social -自分のフォローしているユーザーの投稿と、全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。STLと略されます。 - -## Global -全てのローカルユーザーの「ホーム」指定されていない投稿と、サーバーに届いた全てのリモートユーザーの「ホーム」指定されていない投稿が流れます。GTLと略されます。 - -## Comparação -| Fonte | | | Linha do tempo | | | -| --------------- | ------------ | ------ | -------------- | ------ | ------ | -| Usuários | Visibilidade | Início | Local | Social | Global | -| Local (seguir) | Público | ✔ | ✔ | ✔ | ✔ | -| | Início | ✔ | | ✔ | | -| | Seguidores | ✔ | ✔ | ✔ | ✔ | -| Remoto (seguir) | Público | ✔ | | ✔ | ✔ | -| | Início | ✔ | | ✔ | | -| | Seguidores | ✔ | | ✔ | ✔ | -| ローカル (未フォロー) | Público | | ✔ | ✔ | ✔ | -| | Início | | | | | -| | Seguidores | | | | | -| リモート (未フォロー) | Público | | | | ✔ | -| | Início | | | | | -| | Seguidores | | | | | diff --git a/src/docs/pt-PT/features/widgets.md b/src/docs/pt-PT/features/widgets.md deleted file mode 100644 index 7c5cacb39..000000000 --- a/src/docs/pt-PT/features/widgets.md +++ /dev/null @@ -1,7 +0,0 @@ -# Widgets -ウィジェットは、MisskeyのUI上に設置できる小型の情報表示、操作が行えるパーツです。 - -ウィジェットを編集するには、ウィジェット編集モードに切り替えます。切り替え方法はUIによって異なります。 ウィジェット編集モードでは、ウィジェットの追加、削除、並び替え、およびそれぞれのウィジェットの設定を行えます。 - -## 利用可能なウィジェット一覧 -todo diff --git a/src/docs/pt-PT/features/word-mute.md b/src/docs/pt-PT/features/word-mute.md deleted file mode 100644 index fa4d14346..000000000 --- a/src/docs/pt-PT/features/word-mute.md +++ /dev/null @@ -1,20 +0,0 @@ -# ワードミュート -ワードミュートの設定をすると、条件に合致したノートが表示されなくなります。 - -ワードミュートには、ソフトワードミュートとハードワードミュートの2種類があります。それぞれについて設定の方法と挙動を説明します。 - -## ソフトワードミュート -ソフトワードミュートは、クライアント(アプリ)側でミュートを判断するワードミュートです。 - -ノートが設定した条件に合致すると、「(ユーザー名)が何かを言いました」という表示で隠れます。 -クリックすると元の通りに表示されます。 - -## ハードワードミュート -ハードワードミュートは、アンテナのようにサーバーが新しいノートの本文に対して条件に合致するかどうか判断し、タイムラインから対象となったノートを除外します。 - -つまり、ハードワードミュートには、以下のような特徴があります。 - -* 条件設定後、新しい投稿のみがミュートの対象になります。 -* 条件を変更しても、過去にハードミュートされたノートはミュートされたままになります。 -* 「○○が何かを言いました」でタイムラインが埋まることがありません。 -* ソフトミュートに非対応のアプリでも、ハードミュートは適用されます。 diff --git a/src/docs/pt-PT/follow.md b/src/docs/pt-PT/follow.md deleted file mode 100644 index 3c1ea7bbe..000000000 --- a/src/docs/pt-PT/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# フォロー -ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。 diff --git a/src/docs/pt-PT/general/apps.md b/src/docs/pt-PT/general/apps.md deleted file mode 100644 index 1f4c85fe8..000000000 --- a/src/docs/pt-PT/general/apps.md +++ /dev/null @@ -1,6 +0,0 @@ -# サードパーティアプリのリスト -## クライアント -todo - -## 連携サービス -todo diff --git a/src/docs/pt-PT/general/changelog.md b/src/docs/pt-PT/general/changelog.md deleted file mode 100644 index 6766a63b2..000000000 --- a/src/docs/pt-PT/general/changelog.md +++ /dev/null @@ -1,5 +0,0 @@ -# 更新履歴 -
ℹ️ このサーバーの更新履歴です。Misskeyの最新のリリースについては、GitHubをご確認ください。
- - - diff --git a/src/docs/pt-PT/general/faq.md b/src/docs/pt-PT/general/faq.md deleted file mode 100644 index c272b2ad4..000000000 --- a/src/docs/pt-PT/general/faq.md +++ /dev/null @@ -1,28 +0,0 @@ -# よくある質問 -ここでは利用上のよくある質問について掲載しています。 Misskeyのプロジェクト自体についてのよくある質問は[こちら](./misskey)に掲載されています。 - -## iOS/Androidのアプリはありますか? -公式にはそういったOSのネイティブアプリを開発していませんが、サードパーティ製のアプリがいくつかあります。 詳しくは[こちら](./apps)をご覧ください。 - -ただ、サードパーティ製アプリはどうしても機能への対応が遅れてしまうため、とくに拘りがなければ公式のWebクライアントの利用をおすすめします。 なお、MisskeyのWebクライアントはPWAに対応しているので、ネイティブアプリのように動作させることも可能です。 詳しくは[こちら](todo)をご覧ください。 - -## Mastodonクライアントでログインできないのですが? -MisskeyはMastodonのAPIと互換性がないため、一部を除きMastodonクライアントでMisskeyを利用することはできません。 - -## 他のサーバーのユーザーをフォローするときは? -メニューから検索を選び、ユーザー名をホスト込みで入力します。例: `@syuilo@misskey.io` - -## Renoteを削除するには? -Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 Renoteについては[こちら](../features/note)をご確認ください。 - -## URLのプレビューを表示させたくない -MFMには、そのURLのプレビューを無効にする構文があります。詳細は[MFMチートシート](/mfm-cheat-sheet)をご確認ください。 - -## カスタム絵文字を追加したい -運営者のみがカスタム絵文字を追加、編集、削除できます。それらを希望する場合は運営者に依頼してください。 - -## Botを開発したい -Misskey APIを利用してBotの開発が可能です。[こちら](../advanced/develop-bot)をご確認ください。 - -## ノートの翻訳機能はどのサービスを使用していますか? -[DeepL](https://www.deepl.com/)を使用しています。 diff --git a/src/docs/pt-PT/general/glossary.md b/src/docs/pt-PT/general/glossary.md deleted file mode 100644 index 5e31b0d4b..000000000 --- a/src/docs/pt-PT/general/glossary.md +++ /dev/null @@ -1,89 +0,0 @@ -# 用語集 -Misskeyに関する用語集です。 - -## ActivityPub -(読み: あくてぃびてぃぱぶ) 分散型を実現するために用いられるプロトコル(仕様)。このプロトコルに則ってサーバー同士通信を行うことで、連合が行われ、Fediverseを形成しています。 - -## AiScript -(読み: あいすくりぷと) Misskey上で使用できるプログラミング言語です。詳細は[こちら。](../advanced/aiscript) - -## API -(読み: えーぴーあい) Misskeyのサーバーが公開している、プログラムからMisskeyを扱うためのインターフェース。詳細は[こちら。](../advanced/api) - -## Bot -(読み: ぼっと) プログラムによって動作しているアカウント。 - -## CW -(読み: こんてんつわーにんぐ) Contents Warningの略。ノートの内容を、操作なしには表示しないようにできる機能。主に長大な内容を隠すためや、ネタバレ防止などに使われます。 - -## Fediverse -(読み: ふぇでぃばーす) Misskeyを含む様々な分散型ソフトウェアのサーバーで構成されたネットワーク。 - -## GTL -グローバルタイムライン(Global TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## HTL -ホームタイムライン(Home TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## LTL -ローカルタイムライン(Local TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## MFM -(読み: えむえふえむ) Misskey Flavored Markdownの略で、Misskey上で使用できるマークアップ言語です。詳細は[こちら。](../features/mfm) - -## NSFW -(読み: のっとせーふふぉーわーく) Not Safe For Workの略。画像を「閲覧注意」扱いにし、操作なしには表示しないようにすることができる機能。 - -## Repostar -(読み: りのーと) 既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノート。詳細は[こちら。](../features/note) - -## STL -ソーシャルタイムライン(Social TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## 藍 -(読み: あい) Misskeyの看板娘(公式キャラクター)です。 - -## アクティブユーザー -インスタンスにアカウントを作っているユーザーのうち、現在も実際にサービスを利用しているユーザーのこと。 - -## インスタンス -todo - -## カスタム絵文字 -サーバーで用意された絵文字。カスタム絵文字ではない通常の絵文字は「Unicode絵文字」と区別して呼ばれる。 - -## コントロールパネル -インスタンスの設定画面のこと。 - -## サーバー -todo - -## サイレンス -ノートをパブリックな公開範囲で投稿できなくされている状態。モデレーターの判断でユーザーごとに設定されます。詳細は[こちら。](../features/silence) - -## ジョブキュー -アクティビティ配送などを順番に行うためのシステム。 - -## 凍結 -アカウントが使用不可に設定されている状態。 - -## ドライブ -Misskeyにアップロードしたファイルを管理する機能。詳細は[こちら。](../features/drive) - -## Posts -Misskeyに投稿される、文章、ファイル、アンケートなどを含めることができるコンテンツ。詳細は[こちら。](../features/note) - -## ミスキスト -Misskeyを使う人のこと。 - -## モデレーター -スパムの凍結およびサイレンスや不適切な投稿の削除など、コミュニティ運営に関する権限を持つユーザー。 - -## リモート -他サーバーのことを指します。リモートユーザーといったように接頭辞としても使われます。ローカルの逆です。 - -## 連合 -サーバー上で作成された情報が他のサーバーに伝わること。 - -## ローカル -自サーバーのことを指します。ローカルユーザー、ローカルタイムラインといったように接頭辞としても使われます。リモートの逆です。 diff --git a/src/docs/pt-PT/general/links.md b/src/docs/pt-PT/general/links.md deleted file mode 100644 index 5ce5e1ddb..000000000 --- a/src/docs/pt-PT/general/links.md +++ /dev/null @@ -1,12 +0,0 @@ -# リンク集 - -## Webサイト -- [Official Discord](https://discord.gg/Wp8gVStHW3) - Misskey公式Discordサーバー -- [Misskey Forum](https://forum.misskey.io/) - Misskeyに関する話題を扱うフォーラム - -## アカウント -- [@repo@misskey.io](https://misskey.io/@repo) - Misskeyのリポジトリの更新を投稿するbot - -## ライブラリ -- [misskey-dev/misskey.js](https://github.com/misskey-dev/misskey.js) - JavaScriptのMisskey SDK -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptのMFMパーサー実装 diff --git a/src/docs/pt-PT/general/misskey.md b/src/docs/pt-PT/general/misskey.md deleted file mode 100644 index d97664ddc..000000000 --- a/src/docs/pt-PT/general/misskey.md +++ /dev/null @@ -1,87 +0,0 @@ -# Misskeyについて - -Misskeyはオープンソースの分散型マイクロブログプラットフォームプロジェクトです。 開発は日本でsyuiloによって2014年から開始されました。 ドライブ、リアクションなどの豊富な機能や、高いカスタマイズ性を備えたUIを持つことが特徴です。 - -## 歴史 -開発当初は掲示板がメインのサービスでしたが、ユーザーが短文を投稿し、それを時系列で流れるタイムライン機能を追加したところ人気が高まり、徐々にそれがメインとして開発が進むようになりました。 当初は分散型ではありませんでしたが、2018年にActivityPubを実装し分散型になったことで、より多くの方に認知され利用されるサービスになり、現在に至ります。 -
ℹ️ Misskeyという名前は、syuiloが当時聴いていたMay'nというアーティストの楽曲、Brain Diverの歌詞に由来します。
- -誰でも開発に参加することができ、現在でも活発に開発が続いています。 - -## 分散型とは何か? - -分散(distributed)型とは、非中央集権(decentralized)とも呼ばれ、コミュニティが多数のサーバーに分散して存在し、それらが相互に通信(連合、federation)することでコンテンツ共有ネットワーク(Fediverse)を形成していることが特徴のサービスです。 単一のサーバーしか存在しない、もしくは複数存在しても互いに独立している場合は中央集権なサービスと言われ、例えばTwitterやFacebookなどほとんどのサービスがそれに該当します。 分散型のメリットは、自分に合った運営者やテーマのサーバーを選択できることです。自分でサーバーを作成することもできます。連合するおかげで、どのサーバーを選んでも、同じコミュニティにアクセスできます。 - -## 常にオープンソース -Misskeyはこれまでもこれからも、オープンソースであり続けます。オープンソースとは、簡単に言うとソフトウェアのソースコード(プログラム)が公開されていることです。ソースコードの修正や再配布が可能であることを定義に含めることもあります。 Misskeyのすべてのソースコードは[AGPL](https://github.com/misskey-dev/misskey/blob/develop/LICENSE)というオープンソースライセンスの下に[公開](https://github.com/misskey-dev)されていて、誰でも自由に閲覧、使用、修正、改変、再配布をすることができます。 オープンソースは、自分で好きなように変えたり、有害な処理が含まれていないことを確認することができたり、誰でも開発に参加できるなどの、様々なメリットがあります。 上述の分散型を実現するためにも、オープンソースであるということは必要不可欠な要素です。 再び引き合いに出しますが、TwitterやFacebookなどの利益を得ているほとんどのサービスはオープンソースではありません。 - -
ℹ️ 技術的に言うと、MisskeyのソースコードはGitで管理されていて、リポジトリはGitHub上でホスティングされています。
- -## 開発に参加する、プロジェクトを支援する -Misskeyを気に入っていただけたら、ぜひプロジェクトを支援してください。プロジェクトに貢献するには、以下で紹介するようにいろいろな方法があります。方法によっては開発のスキルは不要なので、誰でも気軽に参加し貢献することができます。いつでもお待ちしています。 - -### 機能を追加したり、バグを修正する -ソフトウェアエンジニアのスキルをお持ちの方であれば、ソースコードを編集する形でプロジェクトに貢献することができます。 貢献についてのガイドは[こちら](https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md)です。 - -### 議論に参加する -新しい機能、または既存の機能について意見を述べたり、不具合を報告したりすることでも貢献できます。 そのようなディスカッションは[GitHub](https://github.com/misskey-dev)上か、[フォーラム](https://forum.misskey.io/)等で行われます。 - -### テキストを翻訳する -Misskeyは様々な言語に対応しています(i18n -internationalizationの略- と呼ばれます)。元の言語は基本的に日本語ですが、有志によって他の言語へと翻訳されています。 その翻訳作業に加わっていただくことでもMisskeyに貢献できます。 Misskeyは[Crowdinというサービスを使用して翻訳の管理を行っています。](https://crowdin.com/project/misskey) - -### 感想を投稿する -不具合報告等だけではなく、Misskeyの良い点、楽しい点といったポジティブな意見もぜひ共有してください。開発の励みになり、それは間接的ですがプロジェクトへの貢献です。 - -### ミスキストを増やす -ミスキストとは、Misskeyを使用する人のことです。 知り合いに紹介するなどしてMisskeyを広めていただければ、ミスキストが増え開発のモチベーションが上がります。 - -### 寄付をする -Misskeyはビジネスではなく、利用は無料であるため、収益は皆様からの寄付のみです。(インスタンスによっては広告収入を得ているような場合もありますが、それは運営者の収入であり直接開発者への収入にはなりません) 寄付をしていただければ、今後も開発を続けることが可能になり、プロジェクトへの貢献になります。 寄付は基本的には[Patreon](https://www.patreon.com/syuilo)で受け付けています。 一定額寄付していただけると、Misskeyの[情報ページ](/about-misskey)に名前を記載することができます。 - -また、サーバーの運営者も、基本的には収益を得ていません。サーバーの運営にはコストがかかるので、運営者の支援をすることもご検討ください。 開発には直接関係しませんが、サーバーがあってこそのプロジェクトなので、運営が維持されるというのは開発と同じくらい重要なことです。 - -## クレジット -Misskeyの開発者や、Misskeyに寄付をしてくださった方の一覧は[こちら](/about-misskey)で見ることができます。 - -## よくある質問 -### プロジェクトは何を目指していますか? -強いて言うと、漠然的になりますが広く使われる汎用的なプラットフォームになることを目指しています。 Misskeyは他のプロジェクトとは違い、何らかの思想(例えば、反中央集権)やビジョンに基づいて開発が行われているわけではなく、その点ではフラットです。 それが逆に、特定の方向性に縛られないフレキシブルさを生み出すことに繋がっていると感じています。 - - -### 企業によって開発されていますか? -いいえ。Misskeyの開発は個人で行われており、商業的でもないため、特定の企業の関りはありません。 開発メンバーも基本的にはボランティアです。 また、開発に対し企業のスポンサーがつくこともありますが、その場合でもやはり開発は個人のコミュニティが主体です。 - -### 誰が運営していますか? -Misskeyは分散型なため、各サーバーにそれぞれ異なった運営者がいます。従って、特定の個人や企業によって、Misskeyの全てが運営されているわけではありません。 また、開発チームが運営を行うわけでもないため、運営に関する連絡は、お使いのサーバーの運営者に行ってください。 サーバーの運営者は、[このページ](/about)で確認することができます。 あなたがサーバーを作成すれば、あなたが運営者になります。 - -### どのサーバーを選べばいいですか? -[サーバー一覧が公開されています。](https://join.misskey.page/ja-JP/instances) サーバーによってコミュニティのテーマ(特定のこと、ものが好き 等)が決められている場合があるので、自分に合ったテーマのサーバーがあれば、そこを選ぶと良いかもしれません。 他にも、サーバーの規模、ユーザー層、国および言語、運営者が信頼できるかどうか、などの観点があります。 なお、Misskey公式のサーバーというものはありません。自身で新しくサーバーを作成するという選択肢もあります。 - -基本的にどのサーバーを選んだとしても、他の全てのサーバーのユーザーと繋がることができます。 - -### サーバーを建てるにはどうしたらいいですか? -Misskeyサーバーの作成に興味を持っていただきありがとうございます。 2021年現在、Misskeyのホスティングサービスは存在しないため、サーバーの作成にはある程度の知識が必要です。 サーバーの作成方法については[こちら](todo)をご覧ください。 - -### どのような技術を使用していますか? -Misskeyは開発が進むにつれ使用する技術も大きく変わってきました。開発当初はMySQL + PHP + jQueryといった構成でしたが、現在は以下のようになっています。 -- サーバーサイド: Node.js -- データベース: PostgreSQL、Redis -- UIフレームワーク: Vue.js -- プログラミング言語: TypeScript - -また、MFMやAiScriptなどの、Misskeyから派生して独自の技術も開発しています。 - -### Mastodonのフォークですか? -いいえ。MisskeyはMastodonやその他のプロジェクトとは全く別のプロジェクトです。 開発に関しても、Misskeyの方が昔から開発されています。ただし、分散型になったのはMastodonの登場より後です。 同じActivityPubという分散のためのプロトコルを実装しているという点以外、両者に特に関りがあるわけでもありません。 - -### iOS/Androidのアプリはありますか? -公式にはそういったOSのネイティブアプリを開発していませんが、サードパーティ製のアプリがいくつかあります。 詳しくは[こちら](./apps)をご覧ください。 - -ただ、サードパーティ製アプリはどうしても機能への対応が遅れてしまうため、とくに拘りがなければ公式のWebクライアントの利用をおすすめします。 なお、MisskeyのWebクライアントはPWAに対応しているので、ネイティブアプリのように動作させることも可能です。 詳しくは[こちら](todo)をご覧ください。 - -### Misskeyのロゴ、アイコンはどこで入手できますか? -(準備中) - -### 時折目にする猫耳の可愛い女の子は? -Misskeyの守り神、藍ちゃんです。アイチャンカワイイヤッター! -
ℹ️ 藍ちゃんについてはこちらです。
diff --git a/src/docs/pt-PT/general/report-issue.md b/src/docs/pt-PT/general/report-issue.md deleted file mode 100644 index 63527e32a..000000000 --- a/src/docs/pt-PT/general/report-issue.md +++ /dev/null @@ -1,8 +0,0 @@ -# 不具合の報告 -不具合と思われる状況に遭遇したときは、まず[トラブルシューティング](./troubleshooting)をご一読ください。 それでも問題が解決しないときは、以下の情報を含めて[フォーラム](https://forum.misskey.io/)に投稿してください。 投稿することで、解決策が見つかったり、不具合と判断されれば開発チームによって修正が行われます。 - -## 含める情報 -- Misskeyのバージョン([情報ページ](/about)で確認できます) -- お使いのブラウザの種類とバージョン -- お使いのOSの種類とバージョン -- 問題の再現手順 diff --git a/src/docs/pt-PT/general/troubleshooting.md b/src/docs/pt-PT/general/troubleshooting.md deleted file mode 100644 index f895b4984..000000000 --- a/src/docs/pt-PT/general/troubleshooting.md +++ /dev/null @@ -1,40 +0,0 @@ -# トラブルシューティング -
ℹ️ よくある質問も合わせてお役立てください。
- -問題が発生したときは、まずこちらをご確認ください。 該当する項目が無い、もしくは手順を試しても効果がない場合は、サーバーの管理者に連絡するか[不具合を報告](./report-issue)してください。 - -## クライアントが起動しない -ほとんどの場合、お使いのブラウザまたはOSのバージョンが古いことが原因です。 ブラウザおよびOSのバージョンを最新のものに更新してから、再度試してみてください。 - -これは稀ですが、それでも起動しない場合は、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。 - -## ページが読み込めない -クライアントが起動するもののページが読み込めないというエラーが出る場合は、ネットワークに問題がないか確認してください。また、サーバーがダウンしていないか確認してください。 - -これは稀ですが、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。 - -まだ問題がある場合は、サーバーの問題と思われるのでサーバーの管理者に連絡してください。 - -## クライアントの動作が遅い -以下を試してみてください: - -- クライアント設定で「UIのアニメーションを減らす」を有効にする -- クライアント設定で「モーダルにぼかし効果を使用」を無効にする -- お使いのブラウザの設定でハードウェアアクセラレーションを有効にする -- お使いのデバイスのスペックを上げる - -## UIの一部の表示がおかしい(背景が透明になっている等) -アップデートによりUIの改修が行われたときに、テーマのキャッシュシステムの影響でそのような表示になることがあります。 クライアントの設定の「キャッシュをクリア」すると直ります。 -
⚠️ 「クライアントの」キャッシュクリアです。「ブラウザの」キャッシュクリアは行わないでください。
- -## 通知やアンテナ等の点滅が消えない -点滅は、未読のコンテンツがあることを示しています。通常点滅が消えない場合は、コンテンツを遡ると未読なコンテンツが残っています。 すべて既読にしたと思われるのに、それでもなお点滅が続く場合(おそらく不具合と思われます)は設定から強制的にすべて既読扱いにすることができます。 - -## Renoteができない -フォロワー限定のノートはRenoteすることはできません。 - -## UI上で特定の要素が表示されない -広告ブロッカーを使用しているとそのような不具合が発生することがあります。Misskeyではオフにしてご利用ください。 - -## UI上で未翻訳の部分がある -ほとんどの場合、単に翻訳が間に合っていないだけで、不具合ではありません。翻訳が終わるまでお待ちください。 [翻訳に参加](./misskey)していただくことも可能です。 diff --git a/src/docs/pt-PT/keyboard-shortcut.md b/src/docs/pt-PT/keyboard-shortcut.md deleted file mode 100644 index ac974ccd1..000000000 --- a/src/docs/pt-PT/keyboard-shortcut.md +++ /dev/null @@ -1,68 +0,0 @@ -# キーボードショートカット - -## グローバル -これらのショートカットは基本的にどこでも使えます。 - - - - - - - - - - - -
ショートカット効果由来
P, N新規投稿Post, New, Note
Tタイムラインの最も新しい投稿にフォーカスTimeline, Top
Shift + N通知を表示/隠すNotifications
SPesquisarSearch
H, ?ヘルプを表示Help
- -## 投稿にフォーカスされた状態 - - - - - - - - - - - - - - - - - - - -
ショートカット効果由来
, K, Shift + Tab上の投稿にフォーカスを移動-
, J, Tab下の投稿にフォーカスを移動-
R返信フォームを開くReply
QRenoteフォームを開くQuote
Ctrl + Q即刻Renoteする(フォームを開かずに)-
E, A, +リアクションフォームを開くEmote, reAction
0~9数字に対応したリアクションをする(対応については後述)-
F, Bお気に入りに登録Favorite, Bookmark
Del, Ctrl + D投稿を削除Delete
M, O投稿に対するメニューを開くMore, Other
SCWで隠された部分を表示 or 隠すShow, See
Escフォーカスを外す-
- -## Renoteフォーム - - - - - - - - - - -
ショートカット効果由来
EnterRenoteする-
Qフォームを展開するQuote
Escフォームを閉じる-
- -## リアクションフォーム -デフォルトで「👍」にフォーカスが当たっている状態です。 - - - - - - - - - - - - - -
ショートカット効果由来
, K上のリアクションにフォーカスを移動-
, J下のリアクションにフォーカスを移動-
, H, Shift + Tab左のリアクションにフォーカスを移動-
, L, Tab右のリアクションにフォーカスを移動-
Enter, Space, +リアクション確定-
0~9数字に対応したリアクションで確定-
Escリアクションするのをやめる-
diff --git a/src/docs/pt-PT/mfm.md b/src/docs/pt-PT/mfm.md deleted file mode 100644 index e237287ac..000000000 --- a/src/docs/pt-PT/mfm.md +++ /dev/null @@ -1,2 +0,0 @@ -# MFM -MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます。 diff --git a/src/docs/pt-PT/mute.md b/src/docs/pt-PT/mute.md deleted file mode 100644 index 331e5cc10..000000000 --- a/src/docs/pt-PT/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# Silenciar - -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -* タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -* そのユーザーからの通知 -* メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 - -ユーザーをミュートするには、対象のユーザーのユーザーページに表示されている「ミュート」ボタンを押します。 - -ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。 - -設定>ミュート から、自分がミュートしているユーザー一覧を確認することができます。 diff --git a/src/docs/pt-PT/pages.md b/src/docs/pt-PT/pages.md deleted file mode 100644 index a7311b95e..000000000 --- a/src/docs/pt-PT/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# Pages - -## 変数 -変数を使うことで動的なページを作成できます。テキスト内で { 変数名 } と書くとそこに変数の値を埋め込めます。例えば Hello { thing } world! というテキストで、変数(thing)の値が ai だった場合、テキストは Hello ai world! になります。 - -変数の評価(値を算出すること)は上から下に行われるので、ある変数の中で自分より下の変数を参照することはできません。例えば上から A、B、C と3つの変数を定義したとき、Cの中でABを参照することはできますが、Aの中でBCを参照することはできません。 - -ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。 - -関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。 diff --git a/src/docs/pt-PT/reaction.md b/src/docs/pt-PT/reaction.md deleted file mode 100644 index c26ead75b..000000000 --- a/src/docs/pt-PT/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# リアクション -他の人のノートに、絵文字を付けて簡単にあなたの反応を伝えられる機能です。 リアクションするには、ノートの + アイコンをクリックしてピッカーを表示し、絵文字を選択します。 リアクションには[カスタム絵文字](./custom-emoji)も使用できます。 - -## リアクションピッカーのカスタマイズ -ピッカーに表示される絵文字を自分好みにカスタマイズすることができます。 設定の「リアクション」で設定します。 - -## リモート投稿へのリアクションについて -リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。 また、相手がMisskeyであったとしても、カスタム絵文字リアクションは伝わらず、自動的に「👍」等にフォールバックされます。 - -## リモートからのリアクションについて -リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。 diff --git a/src/docs/pt-PT/reversi-bot.md b/src/docs/pt-PT/reversi-bot.md deleted file mode 100644 index 7ab2a7212..000000000 --- a/src/docs/pt-PT/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# MisskeyリバーシBotの開発 -Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。 - -1. `games/reversi`ストリームに以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - -2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる - * イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている - -3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する - -4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - * `game`: `game`の`id` - -5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う - -6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する - -7. ゲームが開始すると、`started`イベントが流れてくる - * イベントの中身にはゲーム情報が含まれている - -8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述) - -9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる - * `color`として石の色が含まれている - * `pos`として位置情報が含まれている - -## 位置の計算法 -8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### X,Y座標 から インデックス に変換する -``` -pos = x + (y * mapWidth) -``` -`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます: -``` -mapWidth = map[0].length -``` - -### インデックス から X,Y座標 に変換する -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## マップ情報 -マップ情報は、ゲーム情報の`map`に入っています。 文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 それをもとにマップのデザインを知る事が出来ます: -* `(スペース)` ... マス無し -* `-` ... マス -* `b` ... 初期配置される黒石 -* `w` ... 初期配置される白石 - -例えば、4*4の次のような単純なマップがあるとします: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -この場合、マップデータはこのようになります: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## ユーザーにフォームを提示して対話可能Botを作成する -ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。 - -フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します: -```javascript -{ - type: 'init-form', - body: [フォームコントロールの配列] -} -``` - -フォームコントロールの配列については今から説明します。 フォームコントロールは、次のようなオブジェクトです: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... コントロールのID。 `type` ... コントロールの種類。後述します。 `label` ... コントロールと一緒に表記するテキスト。 `value` ... コントロールのデフォルト値。 - -### フォームの操作を受け取る -ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### フォームコントロールの種類 -#### スイッチ -type: `switch` スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。 - -##### プロパティ -`label` ... スイッチに表記するテキスト。 - -#### ラジオボタン -type: `radio` ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。 - -##### プロパティ -`items` ... ラジオボタンの選択肢。例: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '強', - value: 3 -}] -``` - -#### スライダー -type: `slider` スライダーを表示します。 - -##### プロパティ -`min` ... スライダーの下限。 `max` ... スライダーの上限。 `step` ... 入力欄で刻むステップ値。 - -#### テキストボックス -type: `textbox` テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。 - -## ユーザーにメッセージを表示する -設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 メッセージを表示するには、次のメッセージをストリームに送信します: -```javascript -{ - type: 'message', - body: { - text: 'メッセージ内容', - type: 'メッセージの種類' - } -} -``` -メッセージの種類: `success`, `info`, `warning`, `error`。 - -## 投了する -投了をするには、このエンドポイントにリクエストします。 diff --git a/src/docs/pt-PT/stream.md b/src/docs/pt-PT/stream.md deleted file mode 100644 index 9011c37c5..000000000 --- a/src/docs/pt-PT/stream.md +++ /dev/null @@ -1,354 +0,0 @@ -# ストリーミングAPI - -ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。 - -## ストリームに接続する - -ストリーミングAPIを利用するには、まずMisskeyサーバーに**websocket**接続する必要があります。 - -以下のURLに、`i`というパラメータ名で認証情報を含めて、websocket接続してください。例: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。 - -
-

認証情報の取得については、こちらのドキュメントをご確認ください。

-
- ---- - -認証情報は省略することもできますが、その場合非ログインでの利用ということになり、受信できる情報や可能な操作は限られます。例: - -``` -%WS_URL%/streaming -``` - ---- - -ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。 - -**ストリームでのやり取りはすべてJSONです。** - -## チャンネル -MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。 - -### チャンネルに接続する -チャンネルに接続するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -ここで、 -* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。 -* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。 -* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。 - -
-

IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。

-
- -### チャンネルからのメッセージを受け取る -例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。 - -チャンネルがメッセージを発すると、次のようなデータがJSONでストリームに流れてきます: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。 -* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。 -* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。 - -### チャンネルに向けてメッセージを送信する -チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。 - -チャンネルにメッセージを送信するには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。 -* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。 -* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。 - -### チャンネルから切断する -チャンネルから切断するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。 - -## ストリームを経由してAPIリクエストする - -ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。 - -ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -ここで、 -* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 -* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 -* `data`には、エンドポイントのパラメータを含めます。 - -
-

APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。

-
- -### レスポンスの受信 - -APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。 - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -ここで、 -* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 -* `body`には、レスポンスが含まれています。 - -## 投稿のキャプチャ - -Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。 - -例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。 - -しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。 - -この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。 - -### 投稿をキャプチャする - -投稿をキャプチャするには、ストリームに次のようなメッセージを送信します: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャしたい投稿の`id`を設定します。 - -このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 - -例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -ここで、 -* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。 -* `body`内の`type`に、イベントの種類が設定されます。 -* `body`内の`body`に、イベントの詳細が設定されます。 - -#### イベントの種類 - -##### `reacted` -その投稿にリアクションがされた時に発生します。 - -* `reaction`に、リアクションの種類が設定されます。 -* `userId`に、リアクションを行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -その投稿が削除された時に発生します。 - -* `deletedAt`に、削除日時が設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -その投稿に添付されたアンケートに投票された時に発生します。 - -* `choice`に、選択肢IDが設定されます。 -* `userId`に、投票を行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### 投稿のキャプチャを解除する - -その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。 - -次のメッセージを送信します: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャを解除したい投稿の`id`を設定します。 - -このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 - -# チャンネル一覧 -## `main` -アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `renote` -自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。 - -#### `mention` -誰かからメンションされたときに発生するイベントです。 - -#### `readAllNotifications` -自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。 - -#### `meUpdated` -自分の情報が更新されたことを表すイベントです。 - -#### `follow` -自分が誰かをフォローしたときに発生するイベントです。 - -#### `unfollow` -自分が誰かのフォローを解除したときに発生するイベントです。 - -#### `followed` -自分が誰かにフォローされたときに発生するイベントです。 - -## `homeTimeline` -ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -タイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `localTimeline` -ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `hybridTimeline` -ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ソーシャルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `globalTimeline` -グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 diff --git a/src/docs/pt-PT/theme.md b/src/docs/pt-PT/theme.md deleted file mode 100644 index a406f3433..000000000 --- a/src/docs/pt-PT/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# テーマ - -テーマを設定して、Misskeyクライアントの見た目を変更できます。 - -## テーマの設定 -設定 > テーマ - -## テーマを作成する -テーマコードはJSON5で記述されたテーマオブジェクトです。 テーマは以下のようなオブジェクトです。 -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... テーマの一意なID。UUIDをおすすめします。 -* `name` ... テーマ名 -* `author` ... テーマの作者 -* `desc` ... テーマの説明(オプション) -* `base` ... 明るいテーマか、暗いテーマか - * `light`にすると明るいテーマになり、`dark`にすると暗いテーマになります。 - * テーマはここで設定されたベーステーマを継承します。 -* `props` ... テーマのスタイル定義。これから説明します。 - -### テーマのスタイル定義 -`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 - -#### バリューで使える構文 -* 16進数で表された色 - * 例: `#00ff00` -* `rgb(r, g, b)`形式で表された色 - * 例: `rgb(0, 255, 0)` -* `rgb(r, g, b, a)`形式で表された透明度を含む色 - * 例: `rgba(0, 255, 0, 0.5)` -* 他のキーの値の参照 - * `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。 - * 例: `@panel` -* 定数(後述)の参照 - * `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。 - * 例: `$main` -* 関数(後述) - * `:{関数名}<{引数}<{色}` - -#### 定数 -「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 キー名を`$`で始めると、そのキーはCSS変数として出力されません。 - -#### 関数 -wip diff --git a/src/docs/pt-PT/timelines.md b/src/docs/pt-PT/timelines.md deleted file mode 100644 index 36ba61bd2..000000000 --- a/src/docs/pt-PT/timelines.md +++ /dev/null @@ -1,15 +0,0 @@ -# タイムラインの比較 - -https://docs.google.com/spreadsheets/d/1lxQ2ugKrhz58Bg96HTDK_2F98BUritkMyIiBkOByjHA/edit?usp=sharing - -## ホーム -自分のフォローしているユーザーの投稿 - -## ローカル -全てのローカルユーザーの「ホーム」指定されていない投稿 - -## ソーシャル -自分のフォローしているユーザーの投稿と、全てのローカルユーザーの「ホーム」指定されていない投稿 - -## グローバル -全てのローカルユーザーの「ホーム」指定されていない投稿と、サーバーに届いた全てのリモートユーザーの「ホーム」指定されていない投稿 diff --git a/src/docs/ru-RU/admin/disable-timelines.md b/src/docs/ru-RU/admin/disable-timelines.md deleted file mode 100644 index b081e35ab..000000000 --- a/src/docs/ru-RU/admin/disable-timelines.md +++ /dev/null @@ -1,8 +0,0 @@ -# LTL/STL/GTLの無効化 -Misskeyでは、LTL/STL/GTLをそれぞれ無効化することができます。有効/無効を切り替えるには、インスタンスコントロールパネルで設定します。 - -LTLやSTLは、そのインスタンス全員の投稿が見れるため、新規のユーザーにとってはユーザーを探す必要がなくなり、興味のあるユーザーを見つけやすいという利点があります。 しかし同時に、フォロー機能が活用されなくなったり、不適切な投稿が目につきやすくなったり、チャットのようになることで内輪感が生じて逆に新規ユーザーが参加しにくくなるといったデメリットも持ち合わせています。 サーバーによってメリット/デメリットどちらが優勢かは異なるので、オプションとして無効にできるようになっています。 もしデメリットの方が上回っていると感じたら、それらのタイムラインを無効化することも検討してください。 - -
⚠️ 無効化を行うと、ユーザーが困惑し、短期的に見て利用者が減る可能性があります。そのため、無効化の際は影響を慎重に検討し、事前に説明してフォローを整える期間を一定程度設けることを推奨します。
- -なお、管理者/モデレーターは、これらのタイムラインの無効化状態は適用されず、引き続き利用することが可能です。 diff --git a/src/docs/ru-RU/admin/faq.md b/src/docs/ru-RU/admin/faq.md deleted file mode 100644 index 317b4e065..000000000 --- a/src/docs/ru-RU/admin/faq.md +++ /dev/null @@ -1,5 +0,0 @@ -# よくある質問 -ここでは、サーバー管理者向けのよくある質問を掲載しています。 - -## デフォルトテーマを設定したい -現在、デフォルトテーマ設定機能は実装されていません。 diff --git a/src/docs/ru-RU/advanced/aiscript.md b/src/docs/ru-RU/advanced/aiscript.md deleted file mode 100644 index 604d17daa..000000000 --- a/src/docs/ru-RU/advanced/aiscript.md +++ /dev/null @@ -1,7 +0,0 @@ -# AiScript -AiScriptは、Misskeyで使用できるスクリプト言語です。 - -
ℹ️ AiScript実装はMisskeyとは別リポジトリで、オープンソースで公開されています。
- -## 使い方 -AiScriptの構文や組み込み関数などのドキュメントは、[こちら](https://github.com/syuilo/aiscript/tree/master/docs)で公開されています。 diff --git a/src/docs/ru-RU/advanced/api.md b/src/docs/ru-RU/advanced/api.md deleted file mode 100644 index 76019b614..000000000 --- a/src/docs/ru-RU/advanced/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス、Bot等(以下「アプリケーション」と呼びます)を開発できます。 ストリーミングAPIもあるので、リアルタイム性のあるアプリケーションを作ることも可能です。 - -APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。 - -## アクセストークンの取得 -基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。 - -* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む -* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む - -### 自分自身のアクセストークンを手動発行する -「設定 > API」で、自分のアクセストークンを発行できます。 - -[「APIの使い方」へ進む](#APIの使い方) - -### アプリケーション利用者にアクセストークンの発行をリクエストする -アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。 - -#### Step 1 - -UUIDを生成する。以後これをセッションIDと呼びます。 - -> このセッションIDは毎回生成し、使いまわさないようにしてください。 - -#### Step 2 - -`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。 -> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます: -* `name` ... アプリケーション名 - * > 例: `MissDeck` -* `icon` ... アプリケーションのアイコン画像URL - * > 例: `https://missdeck.example.com/icon.png` -* `callback` ... 認証が終わった後にリダイレクトするURL - * > 例: `https://missdeck.example.com/callback` - * リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます -* `permission` ... アプリケーションが要求する権限 - * > 例: `write:notes,write:following,read:drive` - * 要求する権限を`,`で区切って列挙します - * どのような権限があるかは[APIリファレンス](/api-doc)で確認できます - -#### Step 3 -ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。 - -レスポンスに含まれるプロパティ: -* `token` ... ユーザーのアクセストークン -* `user` ... ユーザーの情報 - -[「APIの使い方」へ進む](#APIの使い方) - -## APIの使い方 -**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。 - -* [APIリファレンス](/api-doc) -* [ストリーミングAPI](./stream) diff --git a/src/docs/ru-RU/advanced/create-plugin.md b/src/docs/ru-RU/advanced/create-plugin.md deleted file mode 100644 index f5baa2764..000000000 --- a/src/docs/ru-RU/advanced/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# プラグインの作成 -Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。 - -## Метаданные -プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。 - -### name -プラグイン名 - -### author -プラグイン作者 - -### version -プラグインバージョン。数値を指定してください。 - -### description -プラグインの説明 - -### permissions -プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。 - -### config -プラグインの設定情報を表すオブジェクト。 キーに設定名、値に以下のプロパティを含めます。 - -#### type -設定値の種類を表す文字列。以下から選択します。 string number boolean - -#### label -ユーザーに表示する設定名 - -#### description -設定の説明 - -#### default -設定のデフォルト値 - -## APIリファレンス -AiScript標準で組み込まれているAPIは掲載しません。 - -### Mk:dialog(title text type) -ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。 - -### Mk:confirm(title text type) -確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。 - -### Mk:api(endpoint params) -Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。 - -### Mk:save(key value) -任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。 - -### Mk:load(key) -Mk:saveで永続化した指定の名前の値を読み取ります。 - -### Plugin:register_post_form_action(title fn) -投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。 - -### Plugin:register_note_action(title fn) -ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 - -### Plugin:register_user_action(title fn) -ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。 - -### Plugin:register_note_view_interruptor(fn) -UIに表示されるノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:register_note_post_interruptor(fn) -ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:open_url(url) -第一引数に渡されたURLをブラウザの新しいタブで開きます。 - -### Plugin:config -プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。 diff --git a/src/docs/ru-RU/advanced/develop-bot.md b/src/docs/ru-RU/advanced/develop-bot.md deleted file mode 100644 index 7f825e9bc..000000000 --- a/src/docs/ru-RU/advanced/develop-bot.md +++ /dev/null @@ -1,6 +0,0 @@ -# Botの作成 -[Misskey API](./api)を利用してBotの開発が可能です。 また、いくつかのBot実装が公開されているため、ぜひ参考にしてください。 - -- [syuilo/ai](https://github.com/syuilo/ai) ... Node.js上で動く、TypeScript製Bot実装 - -Botを作成したときは、プロフィール設定からBotフラグをオンにしておくことを強くおすすめします。 diff --git a/src/docs/ru-RU/advanced/reversi-bot.md b/src/docs/ru-RU/advanced/reversi-bot.md deleted file mode 100644 index 16eb25a60..000000000 --- a/src/docs/ru-RU/advanced/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# MisskeyリバーシBotの開発 -Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。 - -1. `games/reversi`ストリームに以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - -2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる - * イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている - -3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する - -4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - * `game`: `game`の`id` - -5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う - -6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する - -7. ゲームが開始すると、`started`イベントが流れてくる - * イベントの中身にはゲーム情報が含まれている - -8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述) - -9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる - * `color`として石の色が含まれている - * `pos`として位置情報が含まれている - -## 位置の計算法 -8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### X,Y座標 から インデックス に変換する -``` -pos = x + (y * mapWidth) -``` -`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます: -``` -mapWidth = map[0].length -``` - -### インデックス から X,Y座標 に変換する -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## マップ情報 -マップ情報は、ゲーム情報の`map`に入っています。 文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 それをもとにマップのデザインを知る事が出来ます: -* `(スペース)` ... マス無し -* `-` ... マス -* `b` ... 初期配置される黒石 -* `w` ... 初期配置される白石 - -例えば、4*4の次のような単純なマップがあるとします: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -この場合、マップデータはこのようになります: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## ユーザーにフォームを提示して対話可能Botを作成する -ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。 - -フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します: -```javascript -{ - type: 'init-form', - body: [フォームコントロールの配列] -} -``` - -フォームコントロールの配列については今から説明します。 フォームコントロールは、次のようなオブジェクトです: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... コントロールのID。 `type` ... コントロールの種類。後述します。 `label` ... コントロールと一緒に表記するテキスト。 `value` ... コントロールのデフォルト値。 - -### フォームの操作を受け取る -ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### フォームコントロールの種類 -#### Выключатель -type: `switch` スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。 - -##### プロパティ -`label` ... スイッチに表記するテキスト。 - -#### ラジオボタン -type: `radio` ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。 - -##### プロパティ -`items` ... ラジオボタンの選択肢。例: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '強', - value: 3 -}] -``` - -#### スライダー -type: `slider` スライダーを表示します。 - -##### プロパティ -`min` ... スライダーの下限。 `max` ... スライダーの上限。 `step` ... 入力欄で刻むステップ値。 - -#### テキストボックス -type: `textbox` テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。 - -## ユーザーにメッセージを表示する -設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 メッセージを表示するには、次のメッセージをストリームに送信します: -```javascript -{ - type: 'message', - body: { - text: 'メッセージ内容', - type: 'メッセージの種類' - } -} -``` -メッセージの種類: `success`, `info`, `warning`, `error`。 - -## 投了する -投了をするには、このエンドポイントにリクエストします。 diff --git a/src/docs/ru-RU/advanced/share-page.md b/src/docs/ru-RU/advanced/share-page.md deleted file mode 100644 index 65ec957e9..000000000 --- a/src/docs/ru-RU/advanced/share-page.md +++ /dev/null @@ -1,54 +0,0 @@ -# シェアページ -`/share`を開くと、共有用の投稿フォームを開くことができます。 ここではシェアページで利用できるクエリ文字列の一覧を示します。 - -## クエリ文字列一覧 -### Текст - -
-
title
-
タイトルです。本文の先頭に[ … ]と挿入されます。
-
text
-
本文です。
-
url
-
URLです。末尾に挿入されます。
-
- -### リプライ情報 -以下のいずれか - -
-
replyId
-
リプライ先のノートid
-
replyUri
-
リプライ先のUrl(リモートのノートオブジェクトを指定)
-
- -### Renote情報 -以下のいずれか - -
-
renoteId
-
Renote先のノートid
-
renoteUri
-
Renote先のUrl(リモートのノートオブジェクトを指定)
-
- -### Видимость -※specifiedに相当する値はvisibility=specifiedとvisibleAccts/visibleUserIdsで指定する - -
-
visibility
-
公開範囲 ['public' | 'home' | 'followers' | 'specified']
-
localOnly
-
0(false) or 1(true)
-
visibleUserIds
-
specified時のダイレクト先のユーザーid カンマ区切りで
-
visibleAccts
-
specified時のダイレクト先のacct(@?username[@host]) カンマ区切りで
-
- -### Файлы -
-
fileIds
-
添付したいファイルのid(カンマ区切りで)
-
diff --git a/src/docs/ru-RU/advanced/stream.md b/src/docs/ru-RU/advanced/stream.md deleted file mode 100644 index eeea156e2..000000000 --- a/src/docs/ru-RU/advanced/stream.md +++ /dev/null @@ -1,350 +0,0 @@ -# ストリーミングAPI - -ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。 - -## ストリームに接続する - -ストリーミングAPIを利用するには、まずMisskeyサーバーに**websocket**接続する必要があります。 - -以下のURLに、`i`というパラメータ名で認証情報を含めて、websocket接続してください。例: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。 - -
ℹ️ 認証情報の取得については、こちらのドキュメントをご確認ください。
- ---- - -認証情報は省略することもできますが、その場合非ログインでの利用ということになり、受信できる情報や可能な操作は限られます。例: - -``` -%WS_URL%/streaming -``` - ---- - -ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。 - -**ストリームでのやり取りはすべてJSONです。** - -## Каналы -MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。 - -ひとつのストリーム上で、同時に複数のチャンネルに接続することができます。 - -### チャンネルに接続する -チャンネルに接続するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -ここで、 -* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。 -* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。 -* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。 - -
ℹ️ IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。
- -### チャンネルからのメッセージを受け取る -例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。 - -チャンネルがメッセージを発すると、次のようなデータがJSONでストリームに流れてきます: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。 -* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。 -* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。 - -### チャンネルに向けてメッセージを送信する -チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。 - -チャンネルにメッセージを送信するには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。 -* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。 -* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。 - -### チャンネルから切断する -チャンネルから切断するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。 - -## ストリームを経由してAPIリクエストする - -ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。 - -ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -ここで、 -* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 -* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 -* `data`には、エンドポイントのパラメータを含めます。 - -
ℹ️ APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。
- -### レスポンスの受信 - -APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。 - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -ここで、 -* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 -* `body`には、レスポンスが含まれています。 - -## 投稿のキャプチャ - -Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。 - -例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。 - -しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。 - -この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。 - -### 投稿をキャプチャする - -投稿をキャプチャするには、ストリームに次のようなメッセージを送信します: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャしたい投稿の`id`を設定します。 - -このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 - -例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -ここで、 -* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。 -* `body`内の`type`に、イベントの種類が設定されます。 -* `body`内の`body`に、イベントの詳細が設定されます。 - -#### イベントの種類 - -##### `reacted` -その投稿にリアクションがされた時に発生します。 - -* `reaction`に、リアクションの種類が設定されます。 -* `userId`に、リアクションを行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -その投稿が削除された時に発生します。 - -* `deletedAt`に、削除日時が設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -その投稿に添付されたアンケートに投票された時に発生します。 - -* `choice`に、選択肢IDが設定されます。 -* `userId`に、投票を行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### 投稿のキャプチャを解除する - -その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。 - -次のメッセージを送信します: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャを解除したい投稿の`id`を設定します。 - -このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 - -# チャンネル一覧 -## `main` -アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `renote` -自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。 - -#### `mention` -誰かからメンションされたときに発生するイベントです。 - -#### `readAllNotifications` -自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。 - -#### `meUpdated` -自分の情報が更新されたことを表すイベントです。 - -#### `follow` -自分が誰かをフォローしたときに発生するイベントです。 - -#### `unfollow` -自分が誰かのフォローを解除したときに発生するイベントです。 - -#### `followed` -自分が誰かにフォローされたときに発生するイベントです。 - -## `homeTimeline` -ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -タイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `localTimeline` -ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `hybridTimeline` -ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ソーシャルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `globalTimeline` -グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 diff --git a/src/docs/ru-RU/aiscript.md b/src/docs/ru-RU/aiscript.md deleted file mode 100644 index c8d3d44b6..000000000 --- a/src/docs/ru-RU/aiscript.md +++ /dev/null @@ -1,4 +0,0 @@ -# AiScript - -## Функции -デフォルトで値渡しです。 diff --git a/src/docs/ru-RU/api.md b/src/docs/ru-RU/api.md deleted file mode 100644 index 76019b614..000000000 --- a/src/docs/ru-RU/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス、Bot等(以下「アプリケーション」と呼びます)を開発できます。 ストリーミングAPIもあるので、リアルタイム性のあるアプリケーションを作ることも可能です。 - -APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。 - -## アクセストークンの取得 -基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。 - -* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む -* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む - -### 自分自身のアクセストークンを手動発行する -「設定 > API」で、自分のアクセストークンを発行できます。 - -[「APIの使い方」へ進む](#APIの使い方) - -### アプリケーション利用者にアクセストークンの発行をリクエストする -アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。 - -#### Step 1 - -UUIDを生成する。以後これをセッションIDと呼びます。 - -> このセッションIDは毎回生成し、使いまわさないようにしてください。 - -#### Step 2 - -`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。 -> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます: -* `name` ... アプリケーション名 - * > 例: `MissDeck` -* `icon` ... アプリケーションのアイコン画像URL - * > 例: `https://missdeck.example.com/icon.png` -* `callback` ... 認証が終わった後にリダイレクトするURL - * > 例: `https://missdeck.example.com/callback` - * リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます -* `permission` ... アプリケーションが要求する権限 - * > 例: `write:notes,write:following,read:drive` - * 要求する権限を`,`で区切って列挙します - * どのような権限があるかは[APIリファレンス](/api-doc)で確認できます - -#### Step 3 -ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。 - -レスポンスに含まれるプロパティ: -* `token` ... ユーザーのアクセストークン -* `user` ... ユーザーの情報 - -[「APIの使い方」へ進む](#APIの使い方) - -## APIの使い方 -**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。 - -* [APIリファレンス](/api-doc) -* [ストリーミングAPI](./stream) diff --git a/src/docs/ru-RU/create-plugin.md b/src/docs/ru-RU/create-plugin.md deleted file mode 100644 index f5baa2764..000000000 --- a/src/docs/ru-RU/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# プラグインの作成 -Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。 - -## Метаданные -プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。 - -### name -プラグイン名 - -### author -プラグイン作者 - -### version -プラグインバージョン。数値を指定してください。 - -### description -プラグインの説明 - -### permissions -プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。 - -### config -プラグインの設定情報を表すオブジェクト。 キーに設定名、値に以下のプロパティを含めます。 - -#### type -設定値の種類を表す文字列。以下から選択します。 string number boolean - -#### label -ユーザーに表示する設定名 - -#### description -設定の説明 - -#### default -設定のデフォルト値 - -## APIリファレンス -AiScript標準で組み込まれているAPIは掲載しません。 - -### Mk:dialog(title text type) -ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。 - -### Mk:confirm(title text type) -確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。 - -### Mk:api(endpoint params) -Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。 - -### Mk:save(key value) -任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。 - -### Mk:load(key) -Mk:saveで永続化した指定の名前の値を読み取ります。 - -### Plugin:register_post_form_action(title fn) -投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。 - -### Plugin:register_note_action(title fn) -ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 - -### Plugin:register_user_action(title fn) -ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。 - -### Plugin:register_note_view_interruptor(fn) -UIに表示されるノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:register_note_post_interruptor(fn) -ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:open_url(url) -第一引数に渡されたURLをブラウザの新しいタブで開きます。 - -### Plugin:config -プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。 diff --git a/src/docs/ru-RU/custom-emoji.md b/src/docs/ru-RU/custom-emoji.md deleted file mode 100644 index 6d20e36c1..000000000 --- a/src/docs/ru-RU/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# Эмодзи пользователя -カスタム絵文字は、インスタンスで用意された画像を絵文字のように使える機能です。 ノート、リアクション、チャット、自己紹介、名前などの場所で使うことができます。 カスタム絵文字をそれらの場所で使うには、絵文字ピッカーボタン(ある場合)を押すか、`:`を入力して絵文字サジェストを表示します。 テキスト内に`:foo:`のような形式の文字列が見つかると、`foo`の部分がカスタム絵文字名と解釈され、表示時には対応したカスタム絵文字に置き換わります。 diff --git a/src/docs/ru-RU/deck.md b/src/docs/ru-RU/deck.md deleted file mode 100644 index 7b109dc4f..000000000 --- a/src/docs/ru-RU/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# Пульт - -デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。 - -## カラムの追加 -デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。 - -## カラムの移動 -カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。 - -## カラムの水平分割 -カラムは左右だけでなく、上下に並べることもできます。 カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 上下分割を解除するには、カラムメニューの「右に出す」を選択します。 - -## カラムの設定 -カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。 - -## デッキの設定 -デッキに関する設定は、[settings/deck](/settings/deck)で行えます。 diff --git a/src/docs/ru-RU/features/antenna.md b/src/docs/ru-RU/features/antenna.md deleted file mode 100644 index cc46db474..000000000 --- a/src/docs/ru-RU/features/antenna.md +++ /dev/null @@ -1,4 +0,0 @@ -# Антенны -アンテナは、自由に条件を設定して、合致するノートを自動で収集することができる機能です。 - -条件を設定したアンテナが作成された状態で、条件に合致するノートが投稿されると、リアルタイムでそのアンテナのタイムラインにノートが追加されます。 diff --git a/src/docs/ru-RU/features/custom-emoji.md b/src/docs/ru-RU/features/custom-emoji.md deleted file mode 100644 index 6d20e36c1..000000000 --- a/src/docs/ru-RU/features/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# Эмодзи пользователя -カスタム絵文字は、インスタンスで用意された画像を絵文字のように使える機能です。 ノート、リアクション、チャット、自己紹介、名前などの場所で使うことができます。 カスタム絵文字をそれらの場所で使うには、絵文字ピッカーボタン(ある場合)を押すか、`:`を入力して絵文字サジェストを表示します。 テキスト内に`:foo:`のような形式の文字列が見つかると、`foo`の部分がカスタム絵文字名と解釈され、表示時には対応したカスタム絵文字に置き換わります。 diff --git a/src/docs/ru-RU/features/deck.md b/src/docs/ru-RU/features/deck.md deleted file mode 100644 index 7b109dc4f..000000000 --- a/src/docs/ru-RU/features/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# Пульт - -デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。 - -## カラムの追加 -デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。 - -## カラムの移動 -カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。 - -## カラムの水平分割 -カラムは左右だけでなく、上下に並べることもできます。 カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 上下分割を解除するには、カラムメニューの「右に出す」を選択します。 - -## カラムの設定 -カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。 - -## デッキの設定 -デッキに関する設定は、[settings/deck](/settings/deck)で行えます。 diff --git a/src/docs/ru-RU/features/drive.md b/src/docs/ru-RU/features/drive.md deleted file mode 100644 index 0ab686564..000000000 --- a/src/docs/ru-RU/features/drive.md +++ /dev/null @@ -1,17 +0,0 @@ -# Диск -ドライブは、Misskey上でファイルを管理できる機能です。 - -[ドライブのページ](/my/drive)から任意のファイルをアップロードできるほか、アバターに設定した画像や、ノートに添付したファイルなどもすべてドライブにアップロードされます。 - -
⚠️ ドライブからファイルを削除すると、そのファイルが添付されたノートも消えます。
- -ドライブにアップロードされたファイルは、いつでもダウンロードすることができるほか、ノート作成時に「ドライブからファイルを添付」することでファイルを再利用することもできます。 - -ドライブ内にフォルダを作り、複数のファイルをまとめて整理することもできます。 - -## 閲覧注意 (NSFW) -
ℹ️ この項目が閲覧注意なわけではありません
- -閲覧注意またはNSFW (Not safe for work) は、ドライブのファイルに設定することができるフラグです。 閲覧注意フラグを設定されたファイルは、表示される際に閲覧者の操作なしには表示されなくなります。 このフラグは、例えば職場や公共の場で閲覧するのに適切でないと思われる画像などに設定し、そのような画像が突然表示されてしまうことを防ぐ目的で使われます。 - -このフラグは手動でオンオフを切り替えられるほか、モデレーターの判断で設定される場合もあります。 diff --git a/src/docs/ru-RU/features/favorite.md b/src/docs/ru-RU/features/favorite.md deleted file mode 100644 index b65b99fed..000000000 --- a/src/docs/ru-RU/features/favorite.md +++ /dev/null @@ -1,4 +0,0 @@ -# В избранное -[ノート](./node)をお気に入りとして登録できる機能です。 お気に入り登録したノートは、[お気に入りページ](./my/favorites)で一覧することができます。 お気に入りに登録したことは相手に通知されず、お気に入りは自分しか見ることができません。 - -ノートをお気に入り登録するには、ノートメニューの「お気に入り」を押します。お気に入り解除するには、ノートメニューの「お気に入り解除」を押します。 diff --git a/src/docs/ru-RU/features/follow.md b/src/docs/ru-RU/features/follow.md deleted file mode 100644 index dde28b9c9..000000000 --- a/src/docs/ru-RU/features/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# Подписки -ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。 diff --git a/src/docs/ru-RU/features/keyboard-shortcut.md b/src/docs/ru-RU/features/keyboard-shortcut.md deleted file mode 100644 index cbdc57274..000000000 --- a/src/docs/ru-RU/features/keyboard-shortcut.md +++ /dev/null @@ -1,66 +0,0 @@ -# キーボードショートカット - -## Всеобщая -これらのショートカットは基本的にどこでも使えます。 - - - - - - - - - - - -
ショートカット効果由来
P, N新規投稿Post, New, Note
Tタイムラインの最も新しい投稿にフォーカスTimeline, Top
Shift + N通知を表示/隠すNotifications
SПоискSearch
H, ?ヘルプを表示Help
- -## 投稿にフォーカスされた状態 - - - - - - - - - - - - - - - - - - -
ショートカット効果由来
, K, Shift + Tab上の投稿にフォーカスを移動-
, J, Tab下の投稿にフォーカスを移動-
R返信フォームを開くReply
QRenoteフォームを開くQuote
Ctrl + Q即刻Renoteする(フォームを開かずに)-
E, A, +リアクションフォームを開くEmote, reAction
0~9数字に対応したリアクションをする(対応については後述)-
F, Bお気に入りに登録Favorite, Bookmark
Del, Ctrl + D投稿を削除Delete
M, O投稿に対するメニューを開くMore, Other
SCWで隠された部分を表示 or 隠すShow, See
Escフォーカスを外す-
- -## Renoteフォーム - - - - - - - - - -
ショートカット効果由来
EnterRenoteする-
Qフォームを展開するQuote
Escフォームを閉じる-
- -## リアクションフォーム -デフォルトで「👍」にフォーカスが当たっている状態です。 - - - - - - - - - - - - - -
ショートカット効果由来
, K上のリアクションにフォーカスを移動-
, J下のリアクションにフォーカスを移動-
, H, Shift + Tab左のリアクションにフォーカスを移動-
, L, Tab右のリアクションにフォーカスを移動-
Enter, Space, +リアクション確定-
0~9数字に対応したリアクションで確定-
Escリアクションするのをやめる-
diff --git a/src/docs/ru-RU/features/mfm.md b/src/docs/ru-RU/features/mfm.md deleted file mode 100644 index 3fb13a82b..000000000 --- a/src/docs/ru-RU/features/mfm.md +++ /dev/null @@ -1,12 +0,0 @@ -# MFM -MFM, Misskey Flavored Markdown — это язык разметки, который можно использовать для оформления текста, и он доступен много где на сайте. Есть [шпагралка по MFM](/mfm-cheat-sheet), в которой можно посмотреть синтаксис. - -## Примеры случаев, где полезен MFM -- оформление заметок; -- предупреждение для содержимого не для всех; -- имена пользователей; -- самопредставление. - -## Информация для разаботчиков -Реализация транслятора MFM опубликована в виде библиотеки, так что его несложно встроить в программу-клиент. -- реализация транслятора MFM на Javascript: [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js). diff --git a/src/docs/ru-RU/features/mute-and-block.md b/src/docs/ru-RU/features/mute-and-block.md deleted file mode 100644 index 7b2c74c26..000000000 --- a/src/docs/ru-RU/features/mute-and-block.md +++ /dev/null @@ -1,41 +0,0 @@ -# Скрытие и блокировка -好みではないユーザーがいる場合は、ミュートを行うことでそのユーザーが自分から見えないようにすることができます。 また、より強力な措置として、ブロックを行うことでそのユーザーから自分のコンテンツが見えないようになるほか、自分に対して関わることができないようにすることができます。 ミュートされていることは相手は分かりませんが、ブロックされていることは相手に分かります。どちらを選ぶかはご自身の判断で行ってください。 - -
ℹ️ ミュートとブロックは併用できます。
- -
⚠️ 利用規約に違反するような、迷惑なユーザーがいる場合は運営者に報告することも検討してください。
- -設定>ミュートとブロック から、自分がミュートまたはブロックしているユーザー一覧を確認することができます。 - -## Скрыть -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -- タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -- そのユーザーからの通知 -- メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 -- など - -ユーザーをミュートするには、対象のユーザーのユーザーページのメニューを開き、「ミュート」ボタンを押します。 - -
ℹ️ ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。
- -## Заблокировать -ユーザーをブロックすると、そのユーザーからあなたのコンテンツが見えないようになり、またあなたに対して以下のようなアクションをすることができなくなります。 - -- フォローする -- ユーザーリストに追加する -- 返信する、Renoteする -- リアクションする、アンケートに投票する -- メッセージを送信する -- など - -また、 - -- ブロックする際に既にそのユーザーからフォローされていた場合はフォローが解除されます。 -- ブロックする際に既にそのユーザーがあなたをユーザーリストに入れていた場合はそのリストからあなたが削除されます。 - -ユーザーをブロックするには、対象のユーザーのユーザーページのメニューを開き、「ブロック」ボタンを押します。 - -
⚠️ ブロックを行ったこと自体は相手に通知されませんが、フォローを行ったりなどの上記のアクションが行えなくなるので間接的にブロックされていることは分かります。
- -
⚠️ 相手から自分のコンテンツが見えなくなりますが、相手がアカウントを切り替えたりログアウト状態になれば見ることができます。あくまで簡易的、補助的なものとしてお考えください。
diff --git a/src/docs/ru-RU/features/mute.md b/src/docs/ru-RU/features/mute.md deleted file mode 100644 index 78a4bf3eb..000000000 --- a/src/docs/ru-RU/features/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# Скрыть - -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -* タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -* そのユーザーからの通知 -* メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 - -ユーザーをミュートするには、対象のユーザーのユーザーページに表示されている「ミュート」ボタンを押します。 - -ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。 - -設定>ミュート から、自分がミュートしているユーザー一覧を確認することができます。 diff --git a/src/docs/ru-RU/features/note.md b/src/docs/ru-RU/features/note.md deleted file mode 100644 index a57ef3a95..000000000 --- a/src/docs/ru-RU/features/note.md +++ /dev/null @@ -1,54 +0,0 @@ -# Заметки -ノートは、Misskeyに投稿される、文章、ファイル、アンケートなどを含むコンテンツで、Misskeyの中心的概念です。また、そのノートを作成する行為自体もノートと呼ばれます。 - -ノートが作成されると、[タイムライン](./timeline)に追加され、自分の[フォロワー](./follow)やサーバーのユーザーが見れるようになります。 - -ノートには、[リアクション](./reaction)を行うことができます。また、返信や引用もできます。 - -ノートを[お気に入り](./favorite)登録することで、後で簡単に見返すことができます。 - -## ノートを作成する -ノートを作成するには、画面上にある鉛筆マークのボタンを押して、作成フォームを開きます。作成フォームに内容を入力し、「ノート」ボタンを押すことでノートが作成されます。 ノートには、画像、動画など任意のファイルや、[アンケート](./poll)を添付することができます。また、本文中には[MFM](./mfm)が使用でき、[メンション](./mention)や[ハッシュタグ](./hashtag)を含めることもできます。 他にも、CWや公開範囲といった設定も行えます(詳細は後述)。 -
ℹ️ コンピューターのクリップボードに画像データがある状態で、フォーム内のテキストボックスにペーストするとその画像を添付することができます。
-
ℹ️ テキストボックス内でCtrl + Enterを押すことでも投稿できます。
- -## Репост -既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノートをRenoteと呼びます。 自分がフォローしているユーザーの、気に入ったノートを自分のフォロワーに共有したい場合や、過去の自分のノートを再度共有したい場合に使います。 同じノートに対して無制限にRenoteを行うことができますが、あまり連続して使用すると迷惑になる場合もあるので、注意しましょう。 -
⚠️ 公開範囲がフォロワーやダイレクトのノートはRenoteできません
- -Renoteを削除するには、Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 - -## CW -Contents Warningの略で、ノートの内容を、閲覧者の操作なしには表示しないようにできる機能です。主に長大な内容を隠すためや、ネタバレ防止などに使うことができます。 設定するには、フォームの「内容を隠す」ボタン(目のアイコン)を押します。すると新しい入力エリアが表れるので、そこに内容の要約を記入します。 - -## Видимость -ノートごとに、そのノートが公開される範囲を設定することができます。フォームの「ノート」ボタンの左にあるアイコンを押すと公開範囲を以下から選択できます。 - -### Общедоступно -全ての人に対してノートが公開されるほか、サーバーの全てのタイムライン(ホームタイムライン、ローカルタイムライン、ソーシャルタイムライン、グローバルタイムライン)にノートが流れます。 -
⚠️ アカウントがサイレンス状態の時は、この公開範囲は使用できません。
- -### Главная -全ての人に対してノートが公開されますが、フォロワー以外のローカルタイムライン、ソーシャルタイムライン、グローバルタイムラインにはノートは流れません。 - -### Подписчики -自分のフォロワーに対してのみノートを公開します。フォロワーの全てのタイムラインに流れます。 - -### Личное -指定したユーザーに対してのみノートを公開します。指定したユーザーの全てのタイムラインに流れます。 - -### 「ローカルのみ」オプション -このオプションを有効にすると、リモートにノートを連合しなくなります。 - -### 公開範囲の比較 - - - - -
ОбщедоступноГлавнаяПодписчикиЛичное
フォロワーのLTL/STL/GTL
非フォロワーのLTL/STL/GTL
- -## Закрепить в профиле -ノートをピン留めすると、ユーザーページに常にそのノートを表示しておくことができます。 ノートのメニューを開き、「ピン留め」を選択してピン留めできます。 複数のノートをピン留めできます。 - -## Следить -ノートをウォッチすると、自分以外のノートへのリアクションや返信などの通知を受け取ることができます。 ノートのメニューを開き、「ウォッチ」を選択してウォッチできます。 diff --git a/src/docs/ru-RU/features/pages.md b/src/docs/ru-RU/features/pages.md deleted file mode 100644 index ea7b15c31..000000000 --- a/src/docs/ru-RU/features/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# Pages - -## Переменные -変数を使うことで動的なページを作成できます。テキスト内で { 変数名 } と書くとそこに変数の値を埋め込めます。例えば Hello { thing } world! というテキストで、変数(thing)の値が ai だった場合、テキストは Hello ai world! になります。 - -変数の評価(値を算出すること)は上から下に行われるので、ある変数の中で自分より下の変数を参照することはできません。例えば上から A、B、C と3つの変数を定義したとき、Cの中でABを参照することはできますが、Aの中でBCを参照することはできません。 - -ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。 - -関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。 diff --git a/src/docs/ru-RU/features/reaction.md b/src/docs/ru-RU/features/reaction.md deleted file mode 100644 index 6a6994df3..000000000 --- a/src/docs/ru-RU/features/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# Реакции -他の人のノートに、絵文字を付けて簡単にあなたの反応を伝えられる機能です。 リアクションするには、ノートの + アイコンをクリックしてピッカーを表示し、絵文字を選択します。 リアクションには[カスタム絵文字](./custom-emoji)も使用できます。 - -## リアクションピッカーのカスタマイズ -ピッカーに表示される絵文字を自分好みにカスタマイズすることができます。 設定の「リアクション」で設定します。 - -## リモート投稿へのリアクションについて -リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。 - -## リモートからのリアクションについて -リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。 diff --git a/src/docs/ru-RU/features/silence.md b/src/docs/ru-RU/features/silence.md deleted file mode 100644 index a5e177788..000000000 --- a/src/docs/ru-RU/features/silence.md +++ /dev/null @@ -1,6 +0,0 @@ -# Заглушить -サイレンスは、アカウントに設定される状態のひとつです。 - -アカウントがサイレンス状態になると、ノートの公開範囲をパブリックにできなくなります。 ホーム、フォロワー、ダイレクトは選択可能なため、サイレンスを受けた場合でもフォロワーやあなたのユーザーページを直接訪れた場合は投稿を閲覧できますが、GTL(連合タイムライン)やLTL(ローカルタイムライン)には投稿が流れません。 - -アカウントのサイレンス状態は、サーバーのモデレーターによって有効化/無効化されます。 diff --git a/src/docs/ru-RU/features/theme.md b/src/docs/ru-RU/features/theme.md deleted file mode 100644 index e4661c101..000000000 --- a/src/docs/ru-RU/features/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# Тема - -テーマを設定して、Misskeyクライアントの見た目を変更できます。 - -## テーマの設定 -設定 > テーマ - -## テーマを作成する -テーマコードはJSON5で記述されたテーマオブジェクトです。 テーマは以下のようなオブジェクトです。 -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... テーマの一意なID。UUIDをおすすめします。 -* `name` ... テーマ名 -* `author` ... テーマの作者 -* `desc` ... テーマの説明(オプション) -* `base` ... 明るいテーマか、暗いテーマか - * `light`にすると明るいテーマになり、`dark`にすると暗いテーマになります。 - * テーマはここで設定されたベーステーマを継承します。 -* `props` ... テーマのスタイル定義。これから説明します。 - -### テーマのスタイル定義 -`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 - -#### バリューで使える構文 -* 16進数で表された色 - * 例: `#00ff00` -* `rgb(r, g, b)`形式で表された色 - * 例: `rgb(0, 255, 0)` -* `rgb(r, g, b, a)`形式で表された透明度を含む色 - * 例: `rgba(0, 255, 0, 0.5)` -* 他のキーの値の参照 - * `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。 - * 例: `@panel` -* 定数(後述)の参照 - * `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。 - * 例: `$main` -* 関数(後述) - * `:{関数名}<{引数}<{色}` - -#### Константа -「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 キー名を`$`で始めると、そのキーはCSS変数として出力されません。 - -#### Функции -wip diff --git a/src/docs/ru-RU/features/timeline.md b/src/docs/ru-RU/features/timeline.md deleted file mode 100644 index ce4a4e830..000000000 --- a/src/docs/ru-RU/features/timeline.md +++ /dev/null @@ -1,31 +0,0 @@ -# Лента -タイムラインは、[ノート](./note)が時系列で表示される機能です。 タイムラインには以下で示す種類があり、種類によって表示されるノートも異なります。 なお、タイムラインの種類によってはサーバーにより無効になっている場合があります。 - -## Главная -自分のフォローしているユーザーの投稿が流れます。HTLと略されます。 - -## Местная -全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。LTLと略されます。 - -## Социальная -自分のフォローしているユーザーの投稿と、全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。STLと略されます。 - -## Всеобщая -全てのローカルユーザーの「ホーム」指定されていない投稿と、サーバーに届いた全てのリモートユーザーの「ホーム」指定されていない投稿が流れます。GTLと略されます。 - -## Сравнение -| ソース | | | Лента | | | -| ------------ | ------------ | ------- | ------- | ---------- | -------- | -| Пользователи | Видимость | Главная | Местная | Социальная | Всеобщая | -| ローカル (フォロー) | Опубликовать | ✔ | ✔ | ✔ | ✔ | -| | Главная | ✔ | | ✔ | | -| | Подписчики | ✔ | ✔ | ✔ | ✔ | -| リモート (フォロー) | Опубликовать | ✔ | | ✔ | ✔ | -| | Главная | ✔ | | ✔ | | -| | Подписчики | ✔ | | ✔ | ✔ | -| ローカル (未フォロー) | Опубликовать | | ✔ | ✔ | ✔ | -| | Главная | | | | | -| | Подписчики | | | | | -| リモート (未フォロー) | Опубликовать | | | | ✔ | -| | Главная | | | | | -| | Подписчики | | | | | diff --git a/src/docs/ru-RU/features/widgets.md b/src/docs/ru-RU/features/widgets.md deleted file mode 100644 index 4d841616a..000000000 --- a/src/docs/ru-RU/features/widgets.md +++ /dev/null @@ -1,7 +0,0 @@ -# Виджеты -ウィジェットは、MisskeyのUI上に設置できる小型の情報表示、操作が行えるパーツです。 - -ウィジェットを編集するには、ウィジェット編集モードに切り替えます。切り替え方法はUIによって異なります。 ウィジェット編集モードでは、ウィジェットの追加、削除、並び替え、およびそれぞれのウィジェットの設定を行えます。 - -## 利用可能なウィジェット一覧 -todo diff --git a/src/docs/ru-RU/features/word-mute.md b/src/docs/ru-RU/features/word-mute.md deleted file mode 100644 index e8671bbc6..000000000 --- a/src/docs/ru-RU/features/word-mute.md +++ /dev/null @@ -1,20 +0,0 @@ -# Скрытие слов -ワードミュートの設定をすると、条件に合致したノートが表示されなくなります。 - -ワードミュートには、ソフトワードミュートとハードワードミュートの2種類があります。それぞれについて設定の方法と挙動を説明します。 - -## ソフトワードミュート -ソフトワードミュートは、クライアント(アプリ)側でミュートを判断するワードミュートです。 - -ノートが設定した条件に合致すると、「(ユーザー名)が何かを言いました」という表示で隠れます。 -クリックすると元の通りに表示されます。 - -## ハードワードミュート -ハードワードミュートは、アンテナのようにサーバーが新しいノートの本文に対して条件に合致するかどうか判断し、タイムラインから対象となったノートを除外します。 - -つまり、ハードワードミュートには、以下のような特徴があります。 - -* 条件設定後、新しい投稿のみがミュートの対象になります。 -* 条件を変更しても、過去にハードミュートされたノートはミュートされたままになります。 -* 「○○が何かを言いました」でタイムラインが埋まることがありません。 -* ソフトミュートに非対応のアプリでも、ハードミュートは適用されます。 diff --git a/src/docs/ru-RU/follow.md b/src/docs/ru-RU/follow.md deleted file mode 100644 index dde28b9c9..000000000 --- a/src/docs/ru-RU/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# Подписки -ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。 diff --git a/src/docs/ru-RU/general/apps.md b/src/docs/ru-RU/general/apps.md deleted file mode 100644 index 2e30a092a..000000000 --- a/src/docs/ru-RU/general/apps.md +++ /dev/null @@ -1,6 +0,0 @@ -# Список сторонних приложений -## Клиент -(пока не готово) - -## Связанные службы -(в процессе) diff --git a/src/docs/ru-RU/general/changelog.md b/src/docs/ru-RU/general/changelog.md deleted file mode 100644 index 30a4afd01..000000000 --- a/src/docs/ru-RU/general/changelog.md +++ /dev/null @@ -1,5 +0,0 @@ -# Журнал изменений -
ℹ️ Этот журнал отражает только изменения в последней версии на данном сайте.Последние изменения смотрите в репозитории на GitHub.
- - - diff --git a/src/docs/ru-RU/general/faq.md b/src/docs/ru-RU/general/faq.md deleted file mode 100644 index 0b3a1e272..000000000 --- a/src/docs/ru-RU/general/faq.md +++ /dev/null @@ -1,28 +0,0 @@ -# Часто задаваемые вопросы -Здесь собраны частые вопросы об использовании Misskey. Вопросы, касающиеся проекта как такового — на [отдельной странице](./misskey). - -## Существуют ли приложения для iOS или Android? -Мы не делаем официальных приложений Misskey для какой-либо ОС, однако существуют сторонние программы. [Посмотрите наш список приложений, если интересно.](./apps) - -Обратите внимание, что новые функции в сторонних приложениях неизбежно будут появляться с некоторой задержкой, так что, если это вас не устраивает, лучше пользуйтесь официальным веб-клиентом. Кроме того, веб-клиент Misskey полностью соответствует требованиям технологии PWA, то есть, его можно заставить работать практически так же, как обычное приложение. [По ссылке есть дополнительная информация об этом.](todo) - -## Можно ли войти в Misskey через клиент Mastodon? -Программный интерфейс Misskey за мелкими исключениями несовместим с таковым у Mastodon, так что использовать клиенты Mastodon не получится. - -## Как подписаться на пользователя с другого сайта? -Выберите «Поиск» из меню, и введите имя пользователя вместе с доменным именем сайта.Например, `@syuilo@misskey.io`. - -## Renoteを削除するには? -Нажмите три точки «•••» около даты репоста, и выберите «Отмена репоста». [Про репосты можно почитать по ссылке.](../features/note) - -## Что сделать, чтобы не отображался предварительный просмотр ссылки? -Можно убрать предварительной просмотр посредством MFM.Об этом есть в [шпаргалке по MFM](/mfm-cheat-sheet). - -## Хочу новые, собственные эмодзи! -Добавить эмодзи может только администрация сервера, как и менять и удалять их.С такими пожеланиями обращайтесь к администраторам своего сайта. - -## Желаю разрабатывать бота -Программный интерфейс Misskey позволяет делать ботов.[Есть отдельная страница для тех, кому это интересно](../advanced/develop-bot). - -## Какой сервис используется для перевода заметок? -Для этого применяется [DeepL](https://www.deepl.com/). diff --git a/src/docs/ru-RU/general/glossary.md b/src/docs/ru-RU/general/glossary.md deleted file mode 100644 index 1525e971a..000000000 --- a/src/docs/ru-RU/general/glossary.md +++ /dev/null @@ -1,89 +0,0 @@ -# Глоссарий -Это — словарь специальных терминов, используемых в Misskey. - -## ActivityPub -/экти́вити-па́б/ протокол, используемый для децентрализации Misskey.Взаимодействием серверов по этому протоколу реализуется федерация, за счёт чего и образуется Федиверс (Fediverse). - -## AiScript -/ай-скрипт/ язык программирования, доступный в Misskey.[Подробности — по ссылке.](../advanced/aiscript) - -## API -/эй-пи-ай/ интерфейс, посредством которого клиентская программа может взаимодействовать с сервером Misskey.[Смотрите подробности здесь.](../advanced/api) - -## Бот -учётная запись, которой управляет программа. - -## CW -(Content Warning) сокращение для фразы «предупреждение о содержимом не для всех».Функция, скрывающая содержимое заметки до тех пор, пока пользователь вручную не откроет его.Применяется в основном чтобы свернуть длинный текст или не показывать спойлер (неожиданный поворот сюжета). - -## Fediverse -/федиве́рс/ множество серверов, в том числе на Misskey, которые взаимодействуют друг с другом, и тем самым образуют единую распределённую сеть. - -## ВЛ (GTL) -сокращение для «всеобщая лента».[Про ленты смотрите ссылку.](../features/timeline) - -## ДЛ (HTL) -сокращение для «домашняя лента».[Про ленты смотрите ссылку.](../features/timeline) - -## МЛ (LTL) -сокращение для «местная лента»[Про ленты смотрите ссылку.](../features/timeline) - -## MFM -/эм-эф-эм/ язык разметки, используемый в Misskey (Misskey Flavored Markdown)[См. ссылку.](../features/mfm) - -## Содержимое не для всех (NSFW) -то, что может быть неприемлемо для некоторых людей.Функция пометки изображения как «не для всех» и скрытия его до тех пор, пока пользователь сам не откроет его. - -## Репост -Цитирование в неизменном виде уже существующей заметки, повторная публикация.[См. ссылку.](../features/note) - -## СЛ (STL) -сокращение для «социальная лента».[Про ленты смотрите ссылку.](../features/timeline) - -## Ай -официальный маскот Misskey. - -## Активные пользователи -пользователи, пользующиеся своей учётной записью по настоящее время. - -## Инстанс -(в планах) - -## Эмодзи пользователя -эмодзи, предоставляемые вашим сервером.Эмодзи, что не предоставляются сервером, но доступны по умолчанию, называются «юникодные эмодзи». - -## Панель управления -страница настройки инстанса. - -## Сервер -(в планах) - -## Заглушить -скрыть заметки из общих лент.Действие может применяться модераторами в отношении отдельных пользователей.[См. ссылку.](../features/silence) - -## Очередь заданий -Средство последовательной трансляции активности на другие сервера. - -## Заморозить -сделать учётную запись недоступной для пользователя. - -## Диск -средство для загрузки и хранения файлов пользователей.[См. ссылку.](../features/drive) - -## Заметка -Сообщение, могущее содержать текст, изображения, опросы и прочее, которое публикуется в Misskey.[См. ссылку.](../features/note) - -## Мискиец -пользователь Misskey. - -## Модератор -Пользователь с правами управления сообществом, который может, например, удалять недопустимые публикации, или замораживать учётные записи, с которых рассылается спам. - -## Удалённый, с другого сайта -то, что передано на данный сервер с другого.Используется также как определение для других слов: например «пользователь с другого сайта».Противоположность «местному». - -## Федерация -связь сервера с другими, позволяющая транслировать активность между ними. - -## Местный, с этого сайта -то, что относится к тому же серверу.Используется также как определение для других слов, например, «пользователь с этого сайта».Противоположность «удалённому». diff --git a/src/docs/ru-RU/general/links.md b/src/docs/ru-RU/general/links.md deleted file mode 100644 index 3b55b66ab..000000000 --- a/src/docs/ru-RU/general/links.md +++ /dev/null @@ -1,12 +0,0 @@ -# Полезные ссылки - -## Веб-сайты -- [Официальный Discord](https://discord.gg/Wp8gVStHW3) — официальный Discord-сервер Misskey. -- [Форум Misskey](https://forum.misskey.io/) — форум для обсуждения разных вопросов и Misskey. - -## Учётные записи -- [@repo@misskey.io](https://misskey.io/@repo) — бот, публикующий информацию об обновлениях в репозитории Misskey. - -## Библиотеки -- [misskey-dev/misskey.js](https://github.com/misskey-dev/misskey.js) — набор средств разработки на Javascript для Misskey. -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) — реализация транслятора MFM на Javascript. diff --git a/src/docs/ru-RU/general/misskey.md b/src/docs/ru-RU/general/misskey.md deleted file mode 100644 index 8b8c10b97..000000000 --- a/src/docs/ru-RU/general/misskey.md +++ /dev/null @@ -1,142 +0,0 @@ -# О Misskey - -Misskey (Миски) — проект распределённой площадки для микроблогов с открытым исходным кодом. Его характерные черты — обилие разнообразных функций, как например «Диск» или «Реакции», и невероятно гибко настраиваемый интерфейс пользователя. Проект родился в 2014 году благодаря программисту по имени syuilo из Японии. - -## История -В самом начале Misskey задумывался в первую очередь как доска объявлений. В какой-то момент сюда добавили хронологическую ленту для заметок, которая вдруг стала набирать популярность среди пользователей. Так постепенно разработка переместилась с доски объявлений в микроблоги. Misskey не сразу стал распределённым. Децентрализация пришла в проект вместе с реализацией протокола ActivityPub в 2018 году. Уже в таком виде он стал признан во всём мире и продолжает существовать по сей день. -
ℹ️ Название Misskey взято из песни Brain Diver певицы May'n. Её syuilo слушал в то время.
- -Сейчас каждый может присоединиться к разработке, и Misskey активно развивается при участии таких добровольцев. - -## «Децентрализация»? Что это? - -«Распределённые», или «децентрализованные» сервисы представляют собой множество независимых узлов, которые сообщаются (объединяются, federate) друг с другом, образуя единую федеративную сеть (Fediverse). -Сервисы же, представляющие собой один единственный сервер, сайт, или множество разрозненных, не связанных друг с другом, называются централизованными. К таким можно отнести бо́льшую часть существующих, и Twitter или Facebook — их характерные примеры. У распределённых сервисов есть преимущество, заключающееся в том, что у вас есть свобода выбрать сервер по собственному вкусу и отношению к тем, кто его держит.Можно поднять и свой собственный.Благодаря федеративному устройству, вы будете на связи со всем сообществом, какой бы узел не выбрали. - -## Открытый исходный код навсегда -У Misskey всегда был, есть и будет открытый исходный код.«Открытый исходный код», попросту говоря, — код программы, который свободно доступен для всех.Это определение включает также возможность изменять и распространять исходный код. Весь исходный код Misskey [распространяется под лицензией](https://github.com/misskey-dev) -AGPL, и это значит, что любой может его изучать, использовать, исправлять, менять и распространять без ограничений. Открытый исходный код вообще даёт множество ценных возможностей для каждого: менять его под свои нужды и желания, проверять на отсутствие чего-то вредоносного, участвовать в развитии проектов и множество других. Эти качества для децентрализованного проекта, которым является Misskey, жизненно необходимы. И опять, такие созданные ради прибыли сервисы, как уже упомянутые выше Twitter и Facebook, не имеют открытого кода.

- -
ℹ️ Технически исходный код Misskey находится под управлением Git, а его основной репозиторий находится на GitHub.
- -## Как принять участие в судьбе проекта - -Если вам по душе Misskey, будет здорово, если вы поддержите проект.Это можно сделать множеством способов, и дальше будет рассказано про некоторые из них.Если вы думаете, для этого надо уметь программировать, то это не так — помочь может каждый.Мы всегда рады вашему участию. - - - -### Добавить функцию и исправить ошибку - -Если вы умеете программировать, то можете непосредственно поучаствовать в разработке, внося изменения в ихсодный код. Ознакомьтесь с [руководством для разработчиков](https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md) по ссылке для этого. - - - -### Поучаствовать в обсуждении - -Если хотите поделиться соображениями о новых или уже существующих функциях, сообщить об ошибках, то добро пожаловать на [GitHub](https://github.com/misskey-dev), на [форум](https://forum.misskey.io/) и т. д. - - - -### Перевести на другой язык - -Misskey переводится на многие языки мира (так называемая i18n — интернационализация).Изначально здесь всё на японском языке, но энтузиасты делают переводы на другие языки. Перевод — это ещё один способ, которым вы можете помочь Misskey. Если готовы, переходите на [сайт Crowdin](https://crowdin.com/project/misskey) - - - -### Поделиться впечатлениями - -Не только сообщая об ошибках, но и рассказывая, за что вам нравится Misskey вы делаете его живым.Ваши слова поддерживают дух разработчиков, так что, пусть косвенно, но тоже являются вкладом в проект. - - - -### Увеличить численность мискийцев - -«Мискиец» означает того, кто пользуется Misskey. Знакомя окружающих с Misskey, вы помогаете пополнять ряды мискийцев, и это вдохновляет разработчиков делать его лучше. - - - -### Поддержать материально - -Misskey — некоммерческий проект, он бесплатен и держится на добровольных пожертвованиях.(Возможно, вы заметили, что на некоторых узлах есть реклама, но это заработок исключительно владельцев серверов, а никак не разработчиков). Деньги, которыми вы делитесь с разработчиками, позволяют развиваться проекту и дальше. Это ещё один способ поддержать проект. Основной способ такой поддержки — сайт [Patreon](https://www.patreon.com/syuilo). Если пожертвуете определённую сумму, что получите возможность указать своё имя на странице [о Misskey](/about-misskey). - -Кроме того, владельцы серверов как правило не зарабатывают на этом.Содержание сервера всё же стоит денег, поэтому ещё одной хорошей идеей будет материальная поддержка администраторов вашего узла. Это, конечно, не имеет отношения к разработке, но сохранение и развитие всей сети не менее важно, чем собственно Misskey. - - - -## Зал славы - -[Имена разработчиков и благотворителей можно увидеть по этой ссылке.](/about-misskey) - - - -## Часто задаваемые вопросы - - -### Какие у проекта цели? - -Вообще говоря, на этот вопрос нет точного ответа. В общем, Misskey пытается стать универсальной платформой для широкого применения (что бы это не значило). Misskey не похож на другие проекты в том плане, что какой-то идеи (например, децентрализации), вокруг которой строится проект, или видения его развития нет. Можно сказать, он бесцельный. С другой стороны, отсутствие рамок даёт гибкость и чувство свободы. - - -### Является ли Misskey продуктом коммерческой компании? - -Нет.Misskey разрабатывается частными лицами и не связан ни с какими компаниями с целью коммерциализации. В целом, участие в команде разработки добровольно и не предполагает оплаты. У проекта есть компании-спонсоры, однако развитие всё же в руках сообщества обычных людей. - - - -### Кто управляет Misskey? - -Вы же помните, что Misskey децентрализован? У каждого узла Misskey свои хозяева.Сладовательно, у серверов Misskey нет единого человека или компании, управляющих ими. Так что команда разработки никак контролирует все эти узлы, и на все вопросы, касающихся отдельных узлов вам сможет ответить только их администрация. [Узнать, кто управляет данным узлом, можно на специальной странице.](/about) Создав собственный узел, уже вы станете его администратором. - - - -### Какой узел выбрать? - -[По ссылке есть (неполный) список узлов.](https://join.misskey.page/ja-JP/instances) Некоторые узлы посвящены определённой тематике, например, какому-нибудь кино, или хобби. Если такое вас интересует, этот узел будет неплохим выбором. Кроме того, для вас могут быть важны размер сервера, коллектив, страна, язык, или доверяете ли вы его хозяевам. Какого-то особого «официального» сервера у Misskey нет.Ко всему прочему вы можете создать свой собственный узел на личном сервере. - -По большому счёту не важно, какой узел вы себе выберете. Независимо от этого вы будете на связи со всеми остальными узлами сети. - - - -### Как поднять свой собственный сервер? - -Для начала хотим выразить признательность за ваш интерес к созданию своего сервера. На текущий 2021 год не существует специальных провайдеров для хостинга Misskey, так что для его установки понадобится некоторое умение. [Узнать, как поднять свой сервер, можете по ссылке.](todo) - - - -### Какие технологии использует Misskey? - -По ходу развития Misskey используемые технологии успели значительно поменяться.В начале использовалась связка MySQL + PHP + jQuery, но теперь используется следующее: - -- ПО на стороне сервера: Node.js; -- система управления базой данных: PostgreSQL, Redis; -- интерфейс пользователя: Vue.js; -- язык программирования: TypeScript; - -и, кроме, того, технологии, родившиеся в самом Misskey, как например AiScript. - - - -### А не клон ли это Mastodon? - -Нет. Проект Misskey не имеет никакого отношения к Mastodon и ему подобным проектам. Что касается разработки, то она велась уже давно.Однако децентрализованным он стал уже после появления Mastodon. Помимо того, что в обоих используется протокол децентрализации ActivityPub, между этим проектами нет ничего общего. - - - -### Существуют ли приложения для iOS или Android? - -Мы не делаем официальных приложений Misskey для какой-либо ОС, однако существуют сторонние программы. [Посмотрите наш список приложений, если интересно.](./apps) - -Обратите внимание, что новые функции в сторонних приложениях неизбежно будут появляться с некоторой задержкой, так что, если это вас не устраивает, лучше пользуйтесь официальным веб-клиентом. Кроме того, веб-клиент Misskey полностью соответствует требованиям технологии PWA, то есть, его можно заставить работать практически так же, как обычное приложение. [По ссылке есть дополнительная информация об этом.](todo) - - - -### Где скачать логотип или значок Misskey? - -(Скоро будет) - - - -### Кто эта прелестная девочка с кошачьими ушками? - -Это бог-хранитель Misskey, Ай.(Ай назвали прелестной, урря!) -
ℹ️ Узнать больше об Ай можно по ссылке (если, конечно, вы знаете Японский).
diff --git a/src/docs/ru-RU/general/report-issue.md b/src/docs/ru-RU/general/report-issue.md deleted file mode 100644 index ac9a5272f..000000000 --- a/src/docs/ru-RU/general/report-issue.md +++ /dev/null @@ -1,8 +0,0 @@ -# Как сообщить об ошибке -Если вы столкнулись с чем-то, похожим на программную ошибку, сначала загляните на страницу [«Разрешение проблем»](./troubleshooting), возможно, там есть есть решение. Если после этого не смогли справиться с проблемой самостоятельно, напишите об этом на [Форуме](https://forum.misskey.io/), включив сведения, перечисленные ниже. Не исключено, что там вам помогут найти решение. Если же это и правда ошибка, команда разработчиков об этом узнает и сможет её исправить. - -## О чём писать в сообщении -- версию Misskey (её можно на странице [«О Misskey»](/about)); -- наименование и версию вашего браузера; -- наименование и версию вашей операционной системы; -- последовательность действий, которая привела к описываемой вами проблеме. diff --git a/src/docs/ru-RU/general/troubleshooting.md b/src/docs/ru-RU/general/troubleshooting.md deleted file mode 100644 index bbe13f35f..000000000 --- a/src/docs/ru-RU/general/troubleshooting.md +++ /dev/null @@ -1,40 +0,0 @@ -# Разрешение проблем -
ℹ️ Часто задаваемые вопросы также могут быть полезны.
- -При возникновении каких-либо проблем, сначала поищите решение здесь. Если не нашли подходящего пункта, или с помощью изложенного здесь не удалось решить вопрос, обратитесь к администрации своего узла или [сообщите об ошибке разработчикам](./report-issue). - -## Клиент не запускается -В большинстве случаев виной этому оказывается слишком старая версия браузера или ОС. Попробуйте обновить браузер и ОС до последней версии и попытайтесь снова. - -Иногда клиент не запускается из-за проблемы с кэшем.Очистите кэш браузера и попробуйте ещё раз. - -## Содержимое страницы не загружается -Если клиент запускается, но выдаёт сообщение, что содержимое не может быть загружено, проверьте сетевое соединение на наличие проблем.Также проверьте, что нужный сервер не отключен, например, на обслуживание. - -В редких случаях может быть дело в кэше.Очистите кэш браузера и попробуйте ещё раз. - -Остальные проблемы в основном связаны с серверной частью, так что, если написанное не помогло, постарайтесь связаться с администрацией сервера. - -## Клиент тормозит -Попробуйте следующее: - -- включите в настройках клиента пункт «Уменьшить анимацию в пользовательском интерфейсе»; -- выключите пункт «Размывка под формой поверх всего» там же; -- включите в настройках браузера аппаратное ускорение графики; -- проведите апгрейд. - -## Некоторые элементы интерфейса выглядят странно и неудобно (например, фон стал прозрачным) -Такое может происходить из-за кэширования тем, когда происходит изменение интерфейса при обновлении. Исправить это можно нажав на кнопку «Очистить кэш» в настройках клиента. -
⚠️ Очищать нужно именно кэш клиента!Очистка кэша браузера тут не поможет. Не нужно делать этого.
- -## Мигающий индикатор при «Антенне» не пропадает. -Мигающий индикатор означает, что здесь есть что-то ещё не прочитанное.Обычно такое происходит, когда непрочитанное уползает далеко из-за большого количества новых заметок. Если вы уверены, что всё прочитали, но значок всё ещё на месте (возможно, из-за ошибки), то можете явно пометить всё как прочитанное в настройках. - -## Недоступен репост. -Нельзя репостить заметки, предназначенные только для подписчиков. - -## Некоторые нужные элементы интерфейса не отображаются -Проблемы вроде этой могут проявляться при использовании блокировщика рекламы.Отключите его при использовании Misskey. - -## Некоторые элементы интерфейса на иностранном языке -Обычно это не программная ошибка, а просто перевод интерфейса отстаёт от текущей версии.Подождите, пока переводчики сделают своё дело. Или [помогите переводу](./misskey) сами. diff --git a/src/docs/ru-RU/keyboard-shortcut.md b/src/docs/ru-RU/keyboard-shortcut.md deleted file mode 100644 index 6ec2dd92c..000000000 --- a/src/docs/ru-RU/keyboard-shortcut.md +++ /dev/null @@ -1,68 +0,0 @@ -# キーボードショートカット - -## Всеобщая -これらのショートカットは基本的にどこでも使えます。 - - - - - - - - - - - -
ショートカット効果由来
P, N新規投稿Post, New, Note
Tタイムラインの最も新しい投稿にフォーカスTimeline, Top
Shift + N通知を表示/隠すNotifications
SПоискSearch
H, ?ヘルプを表示Help
- -## 投稿にフォーカスされた状態 - - - - - - - - - - - - - - - - - - - -
ショートカット効果由来
, K, Shift + Tab上の投稿にフォーカスを移動-
, J, Tab下の投稿にフォーカスを移動-
R返信フォームを開くReply
QRenoteフォームを開くQuote
Ctrl + Q即刻Renoteする(フォームを開かずに)-
E, A, +リアクションフォームを開くEmote, reAction
0~9数字に対応したリアクションをする(対応については後述)-
F, Bお気に入りに登録Favorite, Bookmark
Del, Ctrl + D投稿を削除Delete
M, O投稿に対するメニューを開くMore, Other
SCWで隠された部分を表示 or 隠すShow, See
Escフォーカスを外す-
- -## Renoteフォーム - - - - - - - - - - -
ショートカット効果由来
EnterRenoteする-
Qフォームを展開するQuote
Escフォームを閉じる-
- -## リアクションフォーム -デフォルトで「👍」にフォーカスが当たっている状態です。 - - - - - - - - - - - - - -
ショートカット効果由来
, K上のリアクションにフォーカスを移動-
, J下のリアクションにフォーカスを移動-
, H, Shift + Tab左のリアクションにフォーカスを移動-
, L, Tab右のリアクションにフォーカスを移動-
Enter, Space, +リアクション確定-
0~9数字に対応したリアクションで確定-
Escリアクションするのをやめる-
diff --git a/src/docs/ru-RU/mfm.md b/src/docs/ru-RU/mfm.md deleted file mode 100644 index e237287ac..000000000 --- a/src/docs/ru-RU/mfm.md +++ /dev/null @@ -1,2 +0,0 @@ -# MFM -MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます。 diff --git a/src/docs/ru-RU/mute.md b/src/docs/ru-RU/mute.md deleted file mode 100644 index 78a4bf3eb..000000000 --- a/src/docs/ru-RU/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# Скрыть - -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -* タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -* そのユーザーからの通知 -* メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 - -ユーザーをミュートするには、対象のユーザーのユーザーページに表示されている「ミュート」ボタンを押します。 - -ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。 - -設定>ミュート から、自分がミュートしているユーザー一覧を確認することができます。 diff --git a/src/docs/ru-RU/pages.md b/src/docs/ru-RU/pages.md deleted file mode 100644 index ea7b15c31..000000000 --- a/src/docs/ru-RU/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# Pages - -## Переменные -変数を使うことで動的なページを作成できます。テキスト内で { 変数名 } と書くとそこに変数の値を埋め込めます。例えば Hello { thing } world! というテキストで、変数(thing)の値が ai だった場合、テキストは Hello ai world! になります。 - -変数の評価(値を算出すること)は上から下に行われるので、ある変数の中で自分より下の変数を参照することはできません。例えば上から A、B、C と3つの変数を定義したとき、Cの中でABを参照することはできますが、Aの中でBCを参照することはできません。 - -ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。 - -関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。 diff --git a/src/docs/ru-RU/reaction.md b/src/docs/ru-RU/reaction.md deleted file mode 100644 index 7b315d7ec..000000000 --- a/src/docs/ru-RU/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# Реакции -他の人のノートに、絵文字を付けて簡単にあなたの反応を伝えられる機能です。 リアクションするには、ノートの + アイコンをクリックしてピッカーを表示し、絵文字を選択します。 リアクションには[カスタム絵文字](./custom-emoji)も使用できます。 - -## リアクションピッカーのカスタマイズ -ピッカーに表示される絵文字を自分好みにカスタマイズすることができます。 設定の「リアクション」で設定します。 - -## リモート投稿へのリアクションについて -リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。 また、相手がMisskeyであったとしても、カスタム絵文字リアクションは伝わらず、自動的に「👍」等にフォールバックされます。 - -## リモートからのリアクションについて -リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。 diff --git a/src/docs/ru-RU/reversi-bot.md b/src/docs/ru-RU/reversi-bot.md deleted file mode 100644 index 16eb25a60..000000000 --- a/src/docs/ru-RU/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# MisskeyリバーシBotの開発 -Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。 - -1. `games/reversi`ストリームに以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - -2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる - * イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている - -3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する - -4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - * `game`: `game`の`id` - -5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う - -6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する - -7. ゲームが開始すると、`started`イベントが流れてくる - * イベントの中身にはゲーム情報が含まれている - -8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述) - -9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる - * `color`として石の色が含まれている - * `pos`として位置情報が含まれている - -## 位置の計算法 -8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### X,Y座標 から インデックス に変換する -``` -pos = x + (y * mapWidth) -``` -`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます: -``` -mapWidth = map[0].length -``` - -### インデックス から X,Y座標 に変換する -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## マップ情報 -マップ情報は、ゲーム情報の`map`に入っています。 文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 それをもとにマップのデザインを知る事が出来ます: -* `(スペース)` ... マス無し -* `-` ... マス -* `b` ... 初期配置される黒石 -* `w` ... 初期配置される白石 - -例えば、4*4の次のような単純なマップがあるとします: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -この場合、マップデータはこのようになります: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## ユーザーにフォームを提示して対話可能Botを作成する -ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。 - -フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します: -```javascript -{ - type: 'init-form', - body: [フォームコントロールの配列] -} -``` - -フォームコントロールの配列については今から説明します。 フォームコントロールは、次のようなオブジェクトです: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... コントロールのID。 `type` ... コントロールの種類。後述します。 `label` ... コントロールと一緒に表記するテキスト。 `value` ... コントロールのデフォルト値。 - -### フォームの操作を受け取る -ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### フォームコントロールの種類 -#### Выключатель -type: `switch` スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。 - -##### プロパティ -`label` ... スイッチに表記するテキスト。 - -#### ラジオボタン -type: `radio` ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。 - -##### プロパティ -`items` ... ラジオボタンの選択肢。例: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '強', - value: 3 -}] -``` - -#### スライダー -type: `slider` スライダーを表示します。 - -##### プロパティ -`min` ... スライダーの下限。 `max` ... スライダーの上限。 `step` ... 入力欄で刻むステップ値。 - -#### テキストボックス -type: `textbox` テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。 - -## ユーザーにメッセージを表示する -設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 メッセージを表示するには、次のメッセージをストリームに送信します: -```javascript -{ - type: 'message', - body: { - text: 'メッセージ内容', - type: 'メッセージの種類' - } -} -``` -メッセージの種類: `success`, `info`, `warning`, `error`。 - -## 投了する -投了をするには、このエンドポイントにリクエストします。 diff --git a/src/docs/ru-RU/stream.md b/src/docs/ru-RU/stream.md deleted file mode 100644 index ca58db7b8..000000000 --- a/src/docs/ru-RU/stream.md +++ /dev/null @@ -1,354 +0,0 @@ -# ストリーミングAPI - -ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。 - -## ストリームに接続する - -ストリーミングAPIを利用するには、まずMisskeyサーバーに**websocket**接続する必要があります。 - -以下のURLに、`i`というパラメータ名で認証情報を含めて、websocket接続してください。例: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。 - -
-

認証情報の取得については、こちらのドキュメントをご確認ください。

-
- ---- - -認証情報は省略することもできますが、その場合非ログインでの利用ということになり、受信できる情報や可能な操作は限られます。例: - -``` -%WS_URL%/streaming -``` - ---- - -ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。 - -**ストリームでのやり取りはすべてJSONです。** - -## Каналы -MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。 - -### チャンネルに接続する -チャンネルに接続するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -ここで、 -* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。 -* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。 -* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。 - -
-

IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。

-
- -### チャンネルからのメッセージを受け取る -例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。 - -チャンネルがメッセージを発すると、次のようなデータがJSONでストリームに流れてきます: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。 -* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。 -* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。 - -### チャンネルに向けてメッセージを送信する -チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。 - -チャンネルにメッセージを送信するには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。 -* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。 -* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。 - -### チャンネルから切断する -チャンネルから切断するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。 - -## ストリームを経由してAPIリクエストする - -ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。 - -ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -ここで、 -* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 -* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 -* `data`には、エンドポイントのパラメータを含めます。 - -
-

APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。

-
- -### レスポンスの受信 - -APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。 - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -ここで、 -* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 -* `body`には、レスポンスが含まれています。 - -## 投稿のキャプチャ - -Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。 - -例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。 - -しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。 - -この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。 - -### 投稿をキャプチャする - -投稿をキャプチャするには、ストリームに次のようなメッセージを送信します: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャしたい投稿の`id`を設定します。 - -このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 - -例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -ここで、 -* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。 -* `body`内の`type`に、イベントの種類が設定されます。 -* `body`内の`body`に、イベントの詳細が設定されます。 - -#### イベントの種類 - -##### `reacted` -その投稿にリアクションがされた時に発生します。 - -* `reaction`に、リアクションの種類が設定されます。 -* `userId`に、リアクションを行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -その投稿が削除された時に発生します。 - -* `deletedAt`に、削除日時が設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -その投稿に添付されたアンケートに投票された時に発生します。 - -* `choice`に、選択肢IDが設定されます。 -* `userId`に、投票を行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### 投稿のキャプチャを解除する - -その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。 - -次のメッセージを送信します: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャを解除したい投稿の`id`を設定します。 - -このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 - -# チャンネル一覧 -## `main` -アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `renote` -自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。 - -#### `mention` -誰かからメンションされたときに発生するイベントです。 - -#### `readAllNotifications` -自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。 - -#### `meUpdated` -自分の情報が更新されたことを表すイベントです。 - -#### `follow` -自分が誰かをフォローしたときに発生するイベントです。 - -#### `unfollow` -自分が誰かのフォローを解除したときに発生するイベントです。 - -#### `followed` -自分が誰かにフォローされたときに発生するイベントです。 - -## `homeTimeline` -ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -タイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `localTimeline` -ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `hybridTimeline` -ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ソーシャルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `globalTimeline` -グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 diff --git a/src/docs/ru-RU/theme.md b/src/docs/ru-RU/theme.md deleted file mode 100644 index e4661c101..000000000 --- a/src/docs/ru-RU/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# Тема - -テーマを設定して、Misskeyクライアントの見た目を変更できます。 - -## テーマの設定 -設定 > テーマ - -## テーマを作成する -テーマコードはJSON5で記述されたテーマオブジェクトです。 テーマは以下のようなオブジェクトです。 -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... テーマの一意なID。UUIDをおすすめします。 -* `name` ... テーマ名 -* `author` ... テーマの作者 -* `desc` ... テーマの説明(オプション) -* `base` ... 明るいテーマか、暗いテーマか - * `light`にすると明るいテーマになり、`dark`にすると暗いテーマになります。 - * テーマはここで設定されたベーステーマを継承します。 -* `props` ... テーマのスタイル定義。これから説明します。 - -### テーマのスタイル定義 -`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 - -#### バリューで使える構文 -* 16進数で表された色 - * 例: `#00ff00` -* `rgb(r, g, b)`形式で表された色 - * 例: `rgb(0, 255, 0)` -* `rgb(r, g, b, a)`形式で表された透明度を含む色 - * 例: `rgba(0, 255, 0, 0.5)` -* 他のキーの値の参照 - * `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。 - * 例: `@panel` -* 定数(後述)の参照 - * `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。 - * 例: `$main` -* 関数(後述) - * `:{関数名}<{引数}<{色}` - -#### Константа -「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 キー名を`$`で始めると、そのキーはCSS変数として出力されません。 - -#### Функции -wip diff --git a/src/docs/ru-RU/timelines.md b/src/docs/ru-RU/timelines.md deleted file mode 100644 index dd6ca37c6..000000000 --- a/src/docs/ru-RU/timelines.md +++ /dev/null @@ -1,15 +0,0 @@ -# タイムラインの比較 - -https://docs.google.com/spreadsheets/d/1lxQ2ugKrhz58Bg96HTDK_2F98BUritkMyIiBkOByjHA/edit?usp=sharing - -## Главная -自分のフォローしているユーザーの投稿 - -## Местная -全てのローカルユーザーの「ホーム」指定されていない投稿 - -## Социальная -自分のフォローしているユーザーの投稿と、全てのローカルユーザーの「ホーム」指定されていない投稿 - -## Всеобщая -全てのローカルユーザーの「ホーム」指定されていない投稿と、サーバーに届いた全てのリモートユーザーの「ホーム」指定されていない投稿 diff --git a/src/docs/th-TH/admin/disable-timelines.md b/src/docs/th-TH/admin/disable-timelines.md deleted file mode 100644 index b081e35ab..000000000 --- a/src/docs/th-TH/admin/disable-timelines.md +++ /dev/null @@ -1,8 +0,0 @@ -# LTL/STL/GTLの無効化 -Misskeyでは、LTL/STL/GTLをそれぞれ無効化することができます。有効/無効を切り替えるには、インスタンスコントロールパネルで設定します。 - -LTLやSTLは、そのインスタンス全員の投稿が見れるため、新規のユーザーにとってはユーザーを探す必要がなくなり、興味のあるユーザーを見つけやすいという利点があります。 しかし同時に、フォロー機能が活用されなくなったり、不適切な投稿が目につきやすくなったり、チャットのようになることで内輪感が生じて逆に新規ユーザーが参加しにくくなるといったデメリットも持ち合わせています。 サーバーによってメリット/デメリットどちらが優勢かは異なるので、オプションとして無効にできるようになっています。 もしデメリットの方が上回っていると感じたら、それらのタイムラインを無効化することも検討してください。 - -
⚠️ 無効化を行うと、ユーザーが困惑し、短期的に見て利用者が減る可能性があります。そのため、無効化の際は影響を慎重に検討し、事前に説明してフォローを整える期間を一定程度設けることを推奨します。
- -なお、管理者/モデレーターは、これらのタイムラインの無効化状態は適用されず、引き続き利用することが可能です。 diff --git a/src/docs/th-TH/admin/faq.md b/src/docs/th-TH/admin/faq.md deleted file mode 100644 index 317b4e065..000000000 --- a/src/docs/th-TH/admin/faq.md +++ /dev/null @@ -1,5 +0,0 @@ -# よくある質問 -ここでは、サーバー管理者向けのよくある質問を掲載しています。 - -## デフォルトテーマを設定したい -現在、デフォルトテーマ設定機能は実装されていません。 diff --git a/src/docs/th-TH/advanced/aiscript.md b/src/docs/th-TH/advanced/aiscript.md deleted file mode 100644 index 604d17daa..000000000 --- a/src/docs/th-TH/advanced/aiscript.md +++ /dev/null @@ -1,7 +0,0 @@ -# AiScript -AiScriptは、Misskeyで使用できるスクリプト言語です。 - -
ℹ️ AiScript実装はMisskeyとは別リポジトリで、オープンソースで公開されています。
- -## 使い方 -AiScriptの構文や組み込み関数などのドキュメントは、[こちら](https://github.com/syuilo/aiscript/tree/master/docs)で公開されています。 diff --git a/src/docs/th-TH/advanced/api.md b/src/docs/th-TH/advanced/api.md deleted file mode 100644 index 76019b614..000000000 --- a/src/docs/th-TH/advanced/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス、Bot等(以下「アプリケーション」と呼びます)を開発できます。 ストリーミングAPIもあるので、リアルタイム性のあるアプリケーションを作ることも可能です。 - -APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。 - -## アクセストークンの取得 -基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。 - -* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む -* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む - -### 自分自身のアクセストークンを手動発行する -「設定 > API」で、自分のアクセストークンを発行できます。 - -[「APIの使い方」へ進む](#APIの使い方) - -### アプリケーション利用者にアクセストークンの発行をリクエストする -アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。 - -#### Step 1 - -UUIDを生成する。以後これをセッションIDと呼びます。 - -> このセッションIDは毎回生成し、使いまわさないようにしてください。 - -#### Step 2 - -`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。 -> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます: -* `name` ... アプリケーション名 - * > 例: `MissDeck` -* `icon` ... アプリケーションのアイコン画像URL - * > 例: `https://missdeck.example.com/icon.png` -* `callback` ... 認証が終わった後にリダイレクトするURL - * > 例: `https://missdeck.example.com/callback` - * リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます -* `permission` ... アプリケーションが要求する権限 - * > 例: `write:notes,write:following,read:drive` - * 要求する権限を`,`で区切って列挙します - * どのような権限があるかは[APIリファレンス](/api-doc)で確認できます - -#### Step 3 -ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。 - -レスポンスに含まれるプロパティ: -* `token` ... ユーザーのアクセストークン -* `user` ... ユーザーの情報 - -[「APIの使い方」へ進む](#APIの使い方) - -## APIの使い方 -**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。 - -* [APIリファレンス](/api-doc) -* [ストリーミングAPI](./stream) diff --git a/src/docs/th-TH/advanced/create-plugin.md b/src/docs/th-TH/advanced/create-plugin.md deleted file mode 100644 index 0d2fa1917..000000000 --- a/src/docs/th-TH/advanced/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# プラグインの作成 -Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。 - -## メタデータ -プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。 - -### name -プラグイン名 - -### author -プラグイン作者 - -### version -プラグインバージョン。数値を指定してください。 - -### description -プラグインの説明 - -### permissions -プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。 - -### config -プラグインの設定情報を表すオブジェクト。 キーに設定名、値に以下のプロパティを含めます。 - -#### type -設定値の種類を表す文字列。以下から選択します。 string number boolean - -#### label -ユーザーに表示する設定名 - -#### description -設定の説明 - -#### default -設定のデフォルト値 - -## APIリファレンス -AiScript標準で組み込まれているAPIは掲載しません。 - -### Mk:dialog(title text type) -ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。 - -### Mk:confirm(title text type) -確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。 - -### Mk:api(endpoint params) -Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。 - -### Mk:save(key value) -任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。 - -### Mk:load(key) -Mk:saveで永続化した指定の名前の値を読み取ります。 - -### Plugin:register_post_form_action(title fn) -投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。 - -### Plugin:register_note_action(title fn) -ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 - -### Plugin:register_user_action(title fn) -ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。 - -### Plugin:register_note_view_interruptor(fn) -UIに表示されるノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:register_note_post_interruptor(fn) -ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:open_url(url) -第一引数に渡されたURLをブラウザの新しいタブで開きます。 - -### Plugin:config -プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。 diff --git a/src/docs/th-TH/advanced/develop-bot.md b/src/docs/th-TH/advanced/develop-bot.md deleted file mode 100644 index 7f825e9bc..000000000 --- a/src/docs/th-TH/advanced/develop-bot.md +++ /dev/null @@ -1,6 +0,0 @@ -# Botの作成 -[Misskey API](./api)を利用してBotの開発が可能です。 また、いくつかのBot実装が公開されているため、ぜひ参考にしてください。 - -- [syuilo/ai](https://github.com/syuilo/ai) ... Node.js上で動く、TypeScript製Bot実装 - -Botを作成したときは、プロフィール設定からBotフラグをオンにしておくことを強くおすすめします。 diff --git a/src/docs/th-TH/advanced/reversi-bot.md b/src/docs/th-TH/advanced/reversi-bot.md deleted file mode 100644 index 7ab2a7212..000000000 --- a/src/docs/th-TH/advanced/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# MisskeyリバーシBotの開発 -Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。 - -1. `games/reversi`ストリームに以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - -2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる - * イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている - -3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する - -4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - * `game`: `game`の`id` - -5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う - -6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する - -7. ゲームが開始すると、`started`イベントが流れてくる - * イベントの中身にはゲーム情報が含まれている - -8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述) - -9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる - * `color`として石の色が含まれている - * `pos`として位置情報が含まれている - -## 位置の計算法 -8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### X,Y座標 から インデックス に変換する -``` -pos = x + (y * mapWidth) -``` -`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます: -``` -mapWidth = map[0].length -``` - -### インデックス から X,Y座標 に変換する -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## マップ情報 -マップ情報は、ゲーム情報の`map`に入っています。 文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 それをもとにマップのデザインを知る事が出来ます: -* `(スペース)` ... マス無し -* `-` ... マス -* `b` ... 初期配置される黒石 -* `w` ... 初期配置される白石 - -例えば、4*4の次のような単純なマップがあるとします: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -この場合、マップデータはこのようになります: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## ユーザーにフォームを提示して対話可能Botを作成する -ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。 - -フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します: -```javascript -{ - type: 'init-form', - body: [フォームコントロールの配列] -} -``` - -フォームコントロールの配列については今から説明します。 フォームコントロールは、次のようなオブジェクトです: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... コントロールのID。 `type` ... コントロールの種類。後述します。 `label` ... コントロールと一緒に表記するテキスト。 `value` ... コントロールのデフォルト値。 - -### フォームの操作を受け取る -ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### フォームコントロールの種類 -#### スイッチ -type: `switch` スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。 - -##### プロパティ -`label` ... スイッチに表記するテキスト。 - -#### ラジオボタン -type: `radio` ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。 - -##### プロパティ -`items` ... ラジオボタンの選択肢。例: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '強', - value: 3 -}] -``` - -#### スライダー -type: `slider` スライダーを表示します。 - -##### プロパティ -`min` ... スライダーの下限。 `max` ... スライダーの上限。 `step` ... 入力欄で刻むステップ値。 - -#### テキストボックス -type: `textbox` テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。 - -## ユーザーにメッセージを表示する -設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 メッセージを表示するには、次のメッセージをストリームに送信します: -```javascript -{ - type: 'message', - body: { - text: 'メッセージ内容', - type: 'メッセージの種類' - } -} -``` -メッセージの種類: `success`, `info`, `warning`, `error`。 - -## 投了する -投了をするには、このエンドポイントにリクエストします。 diff --git a/src/docs/th-TH/advanced/share-page.md b/src/docs/th-TH/advanced/share-page.md deleted file mode 100644 index 4fb7ded0b..000000000 --- a/src/docs/th-TH/advanced/share-page.md +++ /dev/null @@ -1,54 +0,0 @@ -# シェアページ -`/share`を開くと、共有用の投稿フォームを開くことができます。 ここではシェアページで利用できるクエリ文字列の一覧を示します。 - -## クエリ文字列一覧 -### 文字 - -
-
title
-
タイトルです。本文の先頭に[ … ]と挿入されます。
-
text
-
本文です。
-
url
-
URLです。末尾に挿入されます。
-
- -### リプライ情報 -以下のいずれか - -
-
replyId
-
リプライ先のノートid
-
replyUri
-
リプライ先のUrl(リモートのノートオブジェクトを指定)
-
- -### Renote情報 -以下のいずれか - -
-
renoteId
-
Renote先のノートid
-
renoteUri
-
Renote先のUrl(リモートのノートオブジェクトを指定)
-
- -### 公開範囲 -※specifiedに相当する値はvisibility=specifiedとvisibleAccts/visibleUserIdsで指定する - -
-
visibility
-
公開範囲 ['public' | 'home' | 'followers' | 'specified']
-
localOnly
-
0(false) or 1(true)
-
visibleUserIds
-
specified時のダイレクト先のユーザーid カンマ区切りで
-
visibleAccts
-
specified時のダイレクト先のacct(@?username[@host]) カンマ区切りで
-
- -### ファイル -
-
fileIds
-
添付したいファイルのid(カンマ区切りで)
-
diff --git a/src/docs/th-TH/advanced/stream.md b/src/docs/th-TH/advanced/stream.md deleted file mode 100644 index 0e5edd2b0..000000000 --- a/src/docs/th-TH/advanced/stream.md +++ /dev/null @@ -1,350 +0,0 @@ -# ストリーミングAPI - -ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。 - -## ストリームに接続する - -ストリーミングAPIを利用するには、まずMisskeyサーバーに**websocket**接続する必要があります。 - -以下のURLに、`i`というパラメータ名で認証情報を含めて、websocket接続してください。例: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。 - -
ℹ️ 認証情報の取得については、こちらのドキュメントをご確認ください。
- ---- - -認証情報は省略することもできますが、その場合非ログインでの利用ということになり、受信できる情報や可能な操作は限られます。例: - -``` -%WS_URL%/streaming -``` - ---- - -ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。 - -**ストリームでのやり取りはすべてJSONです。** - -## チャンネル -MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。 - -ひとつのストリーム上で、同時に複数のチャンネルに接続することができます。 - -### チャンネルに接続する -チャンネルに接続するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -ここで、 -* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。 -* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。 -* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。 - -
ℹ️ IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。
- -### チャンネルからのメッセージを受け取る -例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。 - -チャンネルがメッセージを発すると、次のようなデータがJSONでストリームに流れてきます: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。 -* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。 -* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。 - -### チャンネルに向けてメッセージを送信する -チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。 - -チャンネルにメッセージを送信するには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。 -* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。 -* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。 - -### チャンネルから切断する -チャンネルから切断するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。 - -## ストリームを経由してAPIリクエストする - -ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。 - -ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -ここで、 -* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 -* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 -* `data`には、エンドポイントのパラメータを含めます。 - -
ℹ️ APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。
- -### レスポンスの受信 - -APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。 - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -ここで、 -* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 -* `body`には、レスポンスが含まれています。 - -## 投稿のキャプチャ - -Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。 - -例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。 - -しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。 - -この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。 - -### 投稿をキャプチャする - -投稿をキャプチャするには、ストリームに次のようなメッセージを送信します: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャしたい投稿の`id`を設定します。 - -このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 - -例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -ここで、 -* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。 -* `body`内の`type`に、イベントの種類が設定されます。 -* `body`内の`body`に、イベントの詳細が設定されます。 - -#### イベントの種類 - -##### `reacted` -その投稿にリアクションがされた時に発生します。 - -* `reaction`に、リアクションの種類が設定されます。 -* `userId`に、リアクションを行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -その投稿が削除された時に発生します。 - -* `deletedAt`に、削除日時が設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -その投稿に添付されたアンケートに投票された時に発生します。 - -* `choice`に、選択肢IDが設定されます。 -* `userId`に、投票を行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### 投稿のキャプチャを解除する - -その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。 - -次のメッセージを送信します: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャを解除したい投稿の`id`を設定します。 - -このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 - -# チャンネル一覧 -## `main` -アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `renote` -自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。 - -#### `mention` -誰かからメンションされたときに発生するイベントです。 - -#### `readAllNotifications` -自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。 - -#### `meUpdated` -自分の情報が更新されたことを表すイベントです。 - -#### `follow` -自分が誰かをフォローしたときに発生するイベントです。 - -#### `unfollow` -自分が誰かのフォローを解除したときに発生するイベントです。 - -#### `followed` -自分が誰かにフォローされたときに発生するイベントです。 - -## `homeTimeline` -ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -タイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `localTimeline` -ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `hybridTimeline` -ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ソーシャルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `globalTimeline` -グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 diff --git a/src/docs/th-TH/aiscript.md b/src/docs/th-TH/aiscript.md deleted file mode 100644 index 6c28b446e..000000000 --- a/src/docs/th-TH/aiscript.md +++ /dev/null @@ -1,4 +0,0 @@ -# AiScript - -## 関数 -デフォルトで値渡しです。 diff --git a/src/docs/th-TH/api.md b/src/docs/th-TH/api.md deleted file mode 100644 index 76019b614..000000000 --- a/src/docs/th-TH/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス、Bot等(以下「アプリケーション」と呼びます)を開発できます。 ストリーミングAPIもあるので、リアルタイム性のあるアプリケーションを作ることも可能です。 - -APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。 - -## アクセストークンの取得 -基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。 - -* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む -* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む - -### 自分自身のアクセストークンを手動発行する -「設定 > API」で、自分のアクセストークンを発行できます。 - -[「APIの使い方」へ進む](#APIの使い方) - -### アプリケーション利用者にアクセストークンの発行をリクエストする -アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。 - -#### Step 1 - -UUIDを生成する。以後これをセッションIDと呼びます。 - -> このセッションIDは毎回生成し、使いまわさないようにしてください。 - -#### Step 2 - -`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。 -> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます: -* `name` ... アプリケーション名 - * > 例: `MissDeck` -* `icon` ... アプリケーションのアイコン画像URL - * > 例: `https://missdeck.example.com/icon.png` -* `callback` ... 認証が終わった後にリダイレクトするURL - * > 例: `https://missdeck.example.com/callback` - * リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます -* `permission` ... アプリケーションが要求する権限 - * > 例: `write:notes,write:following,read:drive` - * 要求する権限を`,`で区切って列挙します - * どのような権限があるかは[APIリファレンス](/api-doc)で確認できます - -#### Step 3 -ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。 - -レスポンスに含まれるプロパティ: -* `token` ... ユーザーのアクセストークン -* `user` ... ユーザーの情報 - -[「APIの使い方」へ進む](#APIの使い方) - -## APIの使い方 -**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。 - -* [APIリファレンス](/api-doc) -* [ストリーミングAPI](./stream) diff --git a/src/docs/th-TH/create-plugin.md b/src/docs/th-TH/create-plugin.md deleted file mode 100644 index 0d2fa1917..000000000 --- a/src/docs/th-TH/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# プラグインの作成 -Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。 - -## メタデータ -プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。 - -### name -プラグイン名 - -### author -プラグイン作者 - -### version -プラグインバージョン。数値を指定してください。 - -### description -プラグインの説明 - -### permissions -プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。 - -### config -プラグインの設定情報を表すオブジェクト。 キーに設定名、値に以下のプロパティを含めます。 - -#### type -設定値の種類を表す文字列。以下から選択します。 string number boolean - -#### label -ユーザーに表示する設定名 - -#### description -設定の説明 - -#### default -設定のデフォルト値 - -## APIリファレンス -AiScript標準で組み込まれているAPIは掲載しません。 - -### Mk:dialog(title text type) -ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。 - -### Mk:confirm(title text type) -確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。 - -### Mk:api(endpoint params) -Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。 - -### Mk:save(key value) -任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。 - -### Mk:load(key) -Mk:saveで永続化した指定の名前の値を読み取ります。 - -### Plugin:register_post_form_action(title fn) -投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。 - -### Plugin:register_note_action(title fn) -ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 - -### Plugin:register_user_action(title fn) -ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。 - -### Plugin:register_note_view_interruptor(fn) -UIに表示されるノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:register_note_post_interruptor(fn) -ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:open_url(url) -第一引数に渡されたURLをブラウザの新しいタブで開きます。 - -### Plugin:config -プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。 diff --git a/src/docs/th-TH/custom-emoji.md b/src/docs/th-TH/custom-emoji.md deleted file mode 100644 index ed2e92be1..000000000 --- a/src/docs/th-TH/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# カスタム絵文字 -カスタム絵文字は、インスタンスで用意された画像を絵文字のように使える機能です。 ノート、リアクション、チャット、自己紹介、名前などの場所で使うことができます。 カスタム絵文字をそれらの場所で使うには、絵文字ピッカーボタン(ある場合)を押すか、`:`を入力して絵文字サジェストを表示します。 テキスト内に`:foo:`のような形式の文字列が見つかると、`foo`の部分がカスタム絵文字名と解釈され、表示時には対応したカスタム絵文字に置き換わります。 diff --git a/src/docs/th-TH/deck.md b/src/docs/th-TH/deck.md deleted file mode 100644 index 8057e262f..000000000 --- a/src/docs/th-TH/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# デッキ - -デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。 - -## カラムの追加 -デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。 - -## カラムの移動 -カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。 - -## カラムの水平分割 -カラムは左右だけでなく、上下に並べることもできます。 カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 上下分割を解除するには、カラムメニューの「右に出す」を選択します。 - -## カラムの設定 -カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。 - -## デッキの設定 -デッキに関する設定は、[settings/deck](/settings/deck)で行えます。 diff --git a/src/docs/th-TH/features/antenna.md b/src/docs/th-TH/features/antenna.md deleted file mode 100644 index 94ad9e4ae..000000000 --- a/src/docs/th-TH/features/antenna.md +++ /dev/null @@ -1,4 +0,0 @@ -# アンテナ -アンテナは、自由に条件を設定して、合致するノートを自動で収集することができる機能です。 - -条件を設定したアンテナが作成された状態で、条件に合致するノートが投稿されると、リアルタイムでそのアンテナのタイムラインにノートが追加されます。 diff --git a/src/docs/th-TH/features/custom-emoji.md b/src/docs/th-TH/features/custom-emoji.md deleted file mode 100644 index ed2e92be1..000000000 --- a/src/docs/th-TH/features/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# カスタム絵文字 -カスタム絵文字は、インスタンスで用意された画像を絵文字のように使える機能です。 ノート、リアクション、チャット、自己紹介、名前などの場所で使うことができます。 カスタム絵文字をそれらの場所で使うには、絵文字ピッカーボタン(ある場合)を押すか、`:`を入力して絵文字サジェストを表示します。 テキスト内に`:foo:`のような形式の文字列が見つかると、`foo`の部分がカスタム絵文字名と解釈され、表示時には対応したカスタム絵文字に置き換わります。 diff --git a/src/docs/th-TH/features/deck.md b/src/docs/th-TH/features/deck.md deleted file mode 100644 index 8057e262f..000000000 --- a/src/docs/th-TH/features/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# デッキ - -デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。 - -## カラムの追加 -デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。 - -## カラムの移動 -カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。 - -## カラムの水平分割 -カラムは左右だけでなく、上下に並べることもできます。 カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 上下分割を解除するには、カラムメニューの「右に出す」を選択します。 - -## カラムの設定 -カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。 - -## デッキの設定 -デッキに関する設定は、[settings/deck](/settings/deck)で行えます。 diff --git a/src/docs/th-TH/features/drive.md b/src/docs/th-TH/features/drive.md deleted file mode 100644 index b82a41082..000000000 --- a/src/docs/th-TH/features/drive.md +++ /dev/null @@ -1,17 +0,0 @@ -# ドライブ -ドライブは、Misskey上でファイルを管理できる機能です。 - -[ドライブのページ](/my/drive)から任意のファイルをアップロードできるほか、アバターに設定した画像や、ノートに添付したファイルなどもすべてドライブにアップロードされます。 - -
⚠️ ドライブからファイルを削除すると、そのファイルが添付されたノートも消えます。
- -ドライブにアップロードされたファイルは、いつでもダウンロードすることができるほか、ノート作成時に「ドライブからファイルを添付」することでファイルを再利用することもできます。 - -ドライブ内にフォルダを作り、複数のファイルをまとめて整理することもできます。 - -## 閲覧注意 (NSFW) -
ℹ️ この項目が閲覧注意なわけではありません
- -閲覧注意またはNSFW (Not safe for work) は、ドライブのファイルに設定することができるフラグです。 閲覧注意フラグを設定されたファイルは、表示される際に閲覧者の操作なしには表示されなくなります。 このフラグは、例えば職場や公共の場で閲覧するのに適切でないと思われる画像などに設定し、そのような画像が突然表示されてしまうことを防ぐ目的で使われます。 - -このフラグは手動でオンオフを切り替えられるほか、モデレーターの判断で設定される場合もあります。 diff --git a/src/docs/th-TH/features/favorite.md b/src/docs/th-TH/features/favorite.md deleted file mode 100644 index a0e5f8bf7..000000000 --- a/src/docs/th-TH/features/favorite.md +++ /dev/null @@ -1,4 +0,0 @@ -# お気に入り -[ノート](./node)をお気に入りとして登録できる機能です。 お気に入り登録したノートは、[お気に入りページ](./my/favorites)で一覧することができます。 お気に入りに登録したことは相手に通知されず、お気に入りは自分しか見ることができません。 - -ノートをお気に入り登録するには、ノートメニューの「お気に入り」を押します。お気に入り解除するには、ノートメニューの「お気に入り解除」を押します。 diff --git a/src/docs/th-TH/features/follow.md b/src/docs/th-TH/features/follow.md deleted file mode 100644 index 3c1ea7bbe..000000000 --- a/src/docs/th-TH/features/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# フォロー -ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。 diff --git a/src/docs/th-TH/features/keyboard-shortcut.md b/src/docs/th-TH/features/keyboard-shortcut.md deleted file mode 100644 index 8659ace98..000000000 --- a/src/docs/th-TH/features/keyboard-shortcut.md +++ /dev/null @@ -1,66 +0,0 @@ -# キーボードショートカット - -## グローバル -これらのショートカットは基本的にどこでも使えます。 - - - - - - - - - - - -
ショートカット効果由来
P, N新規投稿Post, New, Note
Tタイムラインの最も新しい投稿にフォーカスTimeline, Top
Shift + N通知を表示/隠すNotifications
S検索Search
H, ?ヘルプを表示Help
- -## 投稿にフォーカスされた状態 - - - - - - - - - - - - - - - - - - -
ショートカット効果由来
, K, Shift + Tab上の投稿にフォーカスを移動-
, J, Tab下の投稿にフォーカスを移動-
R返信フォームを開くReply
QRenoteフォームを開くQuote
Ctrl + Q即刻Renoteする(フォームを開かずに)-
E, A, +リアクションフォームを開くEmote, reAction
0~9数字に対応したリアクションをする(対応については後述)-
F, Bお気に入りに登録Favorite, Bookmark
Del, Ctrl + D投稿を削除Delete
M, O投稿に対するメニューを開くMore, Other
SCWで隠された部分を表示 or 隠すShow, See
Escフォーカスを外す-
- -## Renoteフォーム - - - - - - - - - -
ショートカット効果由来
EnterRenoteする-
Qフォームを展開するQuote
Escフォームを閉じる-
- -## リアクションフォーム -デフォルトで「👍」にフォーカスが当たっている状態です。 - - - - - - - - - - - - - -
ショートカット効果由来
, K上のリアクションにフォーカスを移動-
, J下のリアクションにフォーカスを移動-
, H, Shift + Tab左のリアクションにフォーカスを移動-
, L, Tab右のリアクションにフォーカスを移動-
Enter, Space, +リアクション確定-
0~9数字に対応したリアクションで確定-
Escリアクションするのをやめる-
diff --git a/src/docs/th-TH/features/mfm.md b/src/docs/th-TH/features/mfm.md deleted file mode 100644 index 5be2df4f3..000000000 --- a/src/docs/th-TH/features/mfm.md +++ /dev/null @@ -1,12 +0,0 @@ -# MFM -MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます。 - -## MFMが使用可能な場所の例 -- ノート本文 -- CW注釈 -- ユーザーの名前 -- ユーザーの自己紹介 - -## 開発者向け情報 -MFMのパーサー実装はライブラリとして公開されており、簡単にクライアントにMFMを組み込むことが可能です。 -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptパーサー実装 diff --git a/src/docs/th-TH/features/mute-and-block.md b/src/docs/th-TH/features/mute-and-block.md deleted file mode 100644 index d78a7cea4..000000000 --- a/src/docs/th-TH/features/mute-and-block.md +++ /dev/null @@ -1,41 +0,0 @@ -# ミュートとブロック -好みではないユーザーがいる場合は、ミュートを行うことでそのユーザーが自分から見えないようにすることができます。 また、より強力な措置として、ブロックを行うことでそのユーザーから自分のコンテンツが見えないようになるほか、自分に対して関わることができないようにすることができます。 ミュートされていることは相手は分かりませんが、ブロックされていることは相手に分かります。どちらを選ぶかはご自身の判断で行ってください。 - -
ℹ️ ミュートとブロックは併用できます。
- -
⚠️ 利用規約に違反するような、迷惑なユーザーがいる場合は運営者に報告することも検討してください。
- -設定>ミュートとブロック から、自分がミュートまたはブロックしているユーザー一覧を確認することができます。 - -## ミュート -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -- タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -- そのユーザーからの通知 -- メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 -- など - -ユーザーをミュートするには、対象のユーザーのユーザーページのメニューを開き、「ミュート」ボタンを押します。 - -
ℹ️ ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。
- -## ブロック -ユーザーをブロックすると、そのユーザーからあなたのコンテンツが見えないようになり、またあなたに対して以下のようなアクションをすることができなくなります。 - -- フォローする -- ユーザーリストに追加する -- 返信する、Renoteする -- リアクションする、アンケートに投票する -- メッセージを送信する -- など - -また、 - -- ブロックする際に既にそのユーザーからフォローされていた場合はフォローが解除されます。 -- ブロックする際に既にそのユーザーがあなたをユーザーリストに入れていた場合はそのリストからあなたが削除されます。 - -ユーザーをブロックするには、対象のユーザーのユーザーページのメニューを開き、「ブロック」ボタンを押します。 - -
⚠️ ブロックを行ったこと自体は相手に通知されませんが、フォローを行ったりなどの上記のアクションが行えなくなるので間接的にブロックされていることは分かります。
- -
⚠️ 相手から自分のコンテンツが見えなくなりますが、相手がアカウントを切り替えたりログアウト状態になれば見ることができます。あくまで簡易的、補助的なものとしてお考えください。
diff --git a/src/docs/th-TH/features/mute.md b/src/docs/th-TH/features/mute.md deleted file mode 100644 index 6a9608662..000000000 --- a/src/docs/th-TH/features/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# ミュート - -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -* タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -* そのユーザーからの通知 -* メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 - -ユーザーをミュートするには、対象のユーザーのユーザーページに表示されている「ミュート」ボタンを押します。 - -ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。 - -設定>ミュート から、自分がミュートしているユーザー一覧を確認することができます。 diff --git a/src/docs/th-TH/features/note.md b/src/docs/th-TH/features/note.md deleted file mode 100644 index 305ff626f..000000000 --- a/src/docs/th-TH/features/note.md +++ /dev/null @@ -1,54 +0,0 @@ -# ノート -ノートは、Misskeyに投稿される、文章、ファイル、アンケートなどを含むコンテンツで、Misskeyの中心的概念です。また、そのノートを作成する行為自体もノートと呼ばれます。 - -ノートが作成されると、[タイムライン](./timeline)に追加され、自分の[フォロワー](./follow)やサーバーのユーザーが見れるようになります。 - -ノートには、[リアクション](./reaction)を行うことができます。また、返信や引用もできます。 - -ノートを[お気に入り](./favorite)登録することで、後で簡単に見返すことができます。 - -## ノートを作成する -ノートを作成するには、画面上にある鉛筆マークのボタンを押して、作成フォームを開きます。作成フォームに内容を入力し、「ノート」ボタンを押すことでノートが作成されます。 ノートには、画像、動画など任意のファイルや、[アンケート](./poll)を添付することができます。また、本文中には[MFM](./mfm)が使用でき、[メンション](./mention)や[ハッシュタグ](./hashtag)を含めることもできます。 他にも、CWや公開範囲といった設定も行えます(詳細は後述)。 -
ℹ️ コンピューターのクリップボードに画像データがある状態で、フォーム内のテキストボックスにペーストするとその画像を添付することができます。
-
ℹ️ テキストボックス内でCtrl + Enterを押すことでも投稿できます。
- -## Renote -既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノートをRenoteと呼びます。 自分がフォローしているユーザーの、気に入ったノートを自分のフォロワーに共有したい場合や、過去の自分のノートを再度共有したい場合に使います。 同じノートに対して無制限にRenoteを行うことができますが、あまり連続して使用すると迷惑になる場合もあるので、注意しましょう。 -
⚠️ 公開範囲がフォロワーやダイレクトのノートはRenoteできません
- -Renoteを削除するには、Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 - -## CW -Contents Warningの略で、ノートの内容を、閲覧者の操作なしには表示しないようにできる機能です。主に長大な内容を隠すためや、ネタバレ防止などに使うことができます。 設定するには、フォームの「内容を隠す」ボタン(目のアイコン)を押します。すると新しい入力エリアが表れるので、そこに内容の要約を記入します。 - -## 公開範囲 -ノートごとに、そのノートが公開される範囲を設定することができます。フォームの「ノート」ボタンの左にあるアイコンを押すと公開範囲を以下から選択できます。 - -### パブリック -全ての人に対してノートが公開されるほか、サーバーの全てのタイムライン(ホームタイムライン、ローカルタイムライン、ソーシャルタイムライン、グローバルタイムライン)にノートが流れます。 -
⚠️ アカウントがサイレンス状態の時は、この公開範囲は使用できません。
- -### ホーム -全ての人に対してノートが公開されますが、フォロワー以外のローカルタイムライン、ソーシャルタイムライン、グローバルタイムラインにはノートは流れません。 - -### フォロワー -自分のフォロワーに対してのみノートを公開します。フォロワーの全てのタイムラインに流れます。 - -### ダイレクト -指定したユーザーに対してのみノートを公開します。指定したユーザーの全てのタイムラインに流れます。 - -### 「ローカルのみ」オプション -このオプションを有効にすると、リモートにノートを連合しなくなります。 - -### 公開範囲の比較 - - - - -
パブリックホームフォロワーダイレクト
フォロワーのLTL/STL/GTL
非フォロワーのLTL/STL/GTL
- -## ピン留め -ノートをピン留めすると、ユーザーページに常にそのノートを表示しておくことができます。 ノートのメニューを開き、「ピン留め」を選択してピン留めできます。 複数のノートをピン留めできます。 - -## ウォッチ -ノートをウォッチすると、自分以外のノートへのリアクションや返信などの通知を受け取ることができます。 ノートのメニューを開き、「ウォッチ」を選択してウォッチできます。 diff --git a/src/docs/th-TH/features/pages.md b/src/docs/th-TH/features/pages.md deleted file mode 100644 index a7311b95e..000000000 --- a/src/docs/th-TH/features/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# Pages - -## 変数 -変数を使うことで動的なページを作成できます。テキスト内で { 変数名 } と書くとそこに変数の値を埋め込めます。例えば Hello { thing } world! というテキストで、変数(thing)の値が ai だった場合、テキストは Hello ai world! になります。 - -変数の評価(値を算出すること)は上から下に行われるので、ある変数の中で自分より下の変数を参照することはできません。例えば上から A、B、C と3つの変数を定義したとき、Cの中でABを参照することはできますが、Aの中でBCを参照することはできません。 - -ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。 - -関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。 diff --git a/src/docs/th-TH/features/reaction.md b/src/docs/th-TH/features/reaction.md deleted file mode 100644 index 4d479fd41..000000000 --- a/src/docs/th-TH/features/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# リアクション -他の人のノートに、絵文字を付けて簡単にあなたの反応を伝えられる機能です。 リアクションするには、ノートの + アイコンをクリックしてピッカーを表示し、絵文字を選択します。 リアクションには[カスタム絵文字](./custom-emoji)も使用できます。 - -## リアクションピッカーのカスタマイズ -ピッカーに表示される絵文字を自分好みにカスタマイズすることができます。 設定の「リアクション」で設定します。 - -## リモート投稿へのリアクションについて -リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。 - -## リモートからのリアクションについて -リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。 diff --git a/src/docs/th-TH/features/silence.md b/src/docs/th-TH/features/silence.md deleted file mode 100644 index 7e26feab0..000000000 --- a/src/docs/th-TH/features/silence.md +++ /dev/null @@ -1,6 +0,0 @@ -# サイレンス -サイレンスは、アカウントに設定される状態のひとつです。 - -アカウントがサイレンス状態になると、ノートの公開範囲をパブリックにできなくなります。 ホーム、フォロワー、ダイレクトは選択可能なため、サイレンスを受けた場合でもフォロワーやあなたのユーザーページを直接訪れた場合は投稿を閲覧できますが、GTL(連合タイムライン)やLTL(ローカルタイムライン)には投稿が流れません。 - -アカウントのサイレンス状態は、サーバーのモデレーターによって有効化/無効化されます。 diff --git a/src/docs/th-TH/features/theme.md b/src/docs/th-TH/features/theme.md deleted file mode 100644 index a406f3433..000000000 --- a/src/docs/th-TH/features/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# テーマ - -テーマを設定して、Misskeyクライアントの見た目を変更できます。 - -## テーマの設定 -設定 > テーマ - -## テーマを作成する -テーマコードはJSON5で記述されたテーマオブジェクトです。 テーマは以下のようなオブジェクトです。 -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... テーマの一意なID。UUIDをおすすめします。 -* `name` ... テーマ名 -* `author` ... テーマの作者 -* `desc` ... テーマの説明(オプション) -* `base` ... 明るいテーマか、暗いテーマか - * `light`にすると明るいテーマになり、`dark`にすると暗いテーマになります。 - * テーマはここで設定されたベーステーマを継承します。 -* `props` ... テーマのスタイル定義。これから説明します。 - -### テーマのスタイル定義 -`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 - -#### バリューで使える構文 -* 16進数で表された色 - * 例: `#00ff00` -* `rgb(r, g, b)`形式で表された色 - * 例: `rgb(0, 255, 0)` -* `rgb(r, g, b, a)`形式で表された透明度を含む色 - * 例: `rgba(0, 255, 0, 0.5)` -* 他のキーの値の参照 - * `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。 - * 例: `@panel` -* 定数(後述)の参照 - * `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。 - * 例: `$main` -* 関数(後述) - * `:{関数名}<{引数}<{色}` - -#### 定数 -「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 キー名を`$`で始めると、そのキーはCSS変数として出力されません。 - -#### 関数 -wip diff --git a/src/docs/th-TH/features/timeline.md b/src/docs/th-TH/features/timeline.md deleted file mode 100644 index f431014f8..000000000 --- a/src/docs/th-TH/features/timeline.md +++ /dev/null @@ -1,31 +0,0 @@ -# タイムライン -タイムラインは、[ノート](./note)が時系列で表示される機能です。 タイムラインには以下で示す種類があり、種類によって表示されるノートも異なります。 なお、タイムラインの種類によってはサーバーにより無効になっている場合があります。 - -## ホーム -自分のフォローしているユーザーの投稿が流れます。HTLと略されます。 - -## ローカル -全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。LTLと略されます。 - -## ソーシャル -自分のフォローしているユーザーの投稿と、全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。STLと略されます。 - -## グローバル -全てのローカルユーザーの「ホーム」指定されていない投稿と、サーバーに届いた全てのリモートユーザーの「ホーム」指定されていない投稿が流れます。GTLと略されます。 - -## 比較 -| ソース | | | タイムライン | | | -| ------------ | ----- | --- | ------ | ----- | ----- | -| ユーザー | 公開範囲 | ホーム | ローカル | ソーシャル | グローバル | -| ローカル (フォロー) | 公開 | ✔ | ✔ | ✔ | ✔ | -| | ホーム | ✔ | | ✔ | | -| | フォロワー | ✔ | ✔ | ✔ | ✔ | -| リモート (フォロー) | 公開 | ✔ | | ✔ | ✔ | -| | ホーム | ✔ | | ✔ | | -| | フォロワー | ✔ | | ✔ | ✔ | -| ローカル (未フォロー) | 公開 | | ✔ | ✔ | ✔ | -| | ホーム | | | | | -| | フォロワー | | | | | -| リモート (未フォロー) | 公開 | | | | ✔ | -| | ホーム | | | | | -| | フォロワー | | | | | diff --git a/src/docs/th-TH/features/widgets.md b/src/docs/th-TH/features/widgets.md deleted file mode 100644 index a7c2c1d1d..000000000 --- a/src/docs/th-TH/features/widgets.md +++ /dev/null @@ -1,7 +0,0 @@ -# ウィジェット -ウィジェットは、MisskeyのUI上に設置できる小型の情報表示、操作が行えるパーツです。 - -ウィジェットを編集するには、ウィジェット編集モードに切り替えます。切り替え方法はUIによって異なります。 ウィジェット編集モードでは、ウィジェットの追加、削除、並び替え、およびそれぞれのウィジェットの設定を行えます。 - -## 利用可能なウィジェット一覧 -todo diff --git a/src/docs/th-TH/features/word-mute.md b/src/docs/th-TH/features/word-mute.md deleted file mode 100644 index fa4d14346..000000000 --- a/src/docs/th-TH/features/word-mute.md +++ /dev/null @@ -1,20 +0,0 @@ -# ワードミュート -ワードミュートの設定をすると、条件に合致したノートが表示されなくなります。 - -ワードミュートには、ソフトワードミュートとハードワードミュートの2種類があります。それぞれについて設定の方法と挙動を説明します。 - -## ソフトワードミュート -ソフトワードミュートは、クライアント(アプリ)側でミュートを判断するワードミュートです。 - -ノートが設定した条件に合致すると、「(ユーザー名)が何かを言いました」という表示で隠れます。 -クリックすると元の通りに表示されます。 - -## ハードワードミュート -ハードワードミュートは、アンテナのようにサーバーが新しいノートの本文に対して条件に合致するかどうか判断し、タイムラインから対象となったノートを除外します。 - -つまり、ハードワードミュートには、以下のような特徴があります。 - -* 条件設定後、新しい投稿のみがミュートの対象になります。 -* 条件を変更しても、過去にハードミュートされたノートはミュートされたままになります。 -* 「○○が何かを言いました」でタイムラインが埋まることがありません。 -* ソフトミュートに非対応のアプリでも、ハードミュートは適用されます。 diff --git a/src/docs/th-TH/follow.md b/src/docs/th-TH/follow.md deleted file mode 100644 index 3c1ea7bbe..000000000 --- a/src/docs/th-TH/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# フォロー -ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。 diff --git a/src/docs/th-TH/general/apps.md b/src/docs/th-TH/general/apps.md deleted file mode 100644 index 1f4c85fe8..000000000 --- a/src/docs/th-TH/general/apps.md +++ /dev/null @@ -1,6 +0,0 @@ -# サードパーティアプリのリスト -## クライアント -todo - -## 連携サービス -todo diff --git a/src/docs/th-TH/general/changelog.md b/src/docs/th-TH/general/changelog.md deleted file mode 100644 index 6766a63b2..000000000 --- a/src/docs/th-TH/general/changelog.md +++ /dev/null @@ -1,5 +0,0 @@ -# 更新履歴 -
ℹ️ このサーバーの更新履歴です。Misskeyの最新のリリースについては、GitHubをご確認ください。
- - - diff --git a/src/docs/th-TH/general/faq.md b/src/docs/th-TH/general/faq.md deleted file mode 100644 index c272b2ad4..000000000 --- a/src/docs/th-TH/general/faq.md +++ /dev/null @@ -1,28 +0,0 @@ -# よくある質問 -ここでは利用上のよくある質問について掲載しています。 Misskeyのプロジェクト自体についてのよくある質問は[こちら](./misskey)に掲載されています。 - -## iOS/Androidのアプリはありますか? -公式にはそういったOSのネイティブアプリを開発していませんが、サードパーティ製のアプリがいくつかあります。 詳しくは[こちら](./apps)をご覧ください。 - -ただ、サードパーティ製アプリはどうしても機能への対応が遅れてしまうため、とくに拘りがなければ公式のWebクライアントの利用をおすすめします。 なお、MisskeyのWebクライアントはPWAに対応しているので、ネイティブアプリのように動作させることも可能です。 詳しくは[こちら](todo)をご覧ください。 - -## Mastodonクライアントでログインできないのですが? -MisskeyはMastodonのAPIと互換性がないため、一部を除きMastodonクライアントでMisskeyを利用することはできません。 - -## 他のサーバーのユーザーをフォローするときは? -メニューから検索を選び、ユーザー名をホスト込みで入力します。例: `@syuilo@misskey.io` - -## Renoteを削除するには? -Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 Renoteについては[こちら](../features/note)をご確認ください。 - -## URLのプレビューを表示させたくない -MFMには、そのURLのプレビューを無効にする構文があります。詳細は[MFMチートシート](/mfm-cheat-sheet)をご確認ください。 - -## カスタム絵文字を追加したい -運営者のみがカスタム絵文字を追加、編集、削除できます。それらを希望する場合は運営者に依頼してください。 - -## Botを開発したい -Misskey APIを利用してBotの開発が可能です。[こちら](../advanced/develop-bot)をご確認ください。 - -## ノートの翻訳機能はどのサービスを使用していますか? -[DeepL](https://www.deepl.com/)を使用しています。 diff --git a/src/docs/th-TH/general/glossary.md b/src/docs/th-TH/general/glossary.md deleted file mode 100644 index bb8a24336..000000000 --- a/src/docs/th-TH/general/glossary.md +++ /dev/null @@ -1,89 +0,0 @@ -# 用語集 -Misskeyに関する用語集です。 - -## ActivityPub -(読み: あくてぃびてぃぱぶ) 分散型を実現するために用いられるプロトコル(仕様)。このプロトコルに則ってサーバー同士通信を行うことで、連合が行われ、Fediverseを形成しています。 - -## AiScript -(読み: あいすくりぷと) Misskey上で使用できるプログラミング言語です。詳細は[こちら。](../advanced/aiscript) - -## API -(読み: えーぴーあい) Misskeyのサーバーが公開している、プログラムからMisskeyを扱うためのインターフェース。詳細は[こちら。](../advanced/api) - -## Bot -(読み: ぼっと) プログラムによって動作しているアカウント。 - -## CW -(読み: こんてんつわーにんぐ) Contents Warningの略。ノートの内容を、操作なしには表示しないようにできる機能。主に長大な内容を隠すためや、ネタバレ防止などに使われます。 - -## Fediverse -(読み: ふぇでぃばーす) Misskeyを含む様々な分散型ソフトウェアのサーバーで構成されたネットワーク。 - -## GTL -グローバルタイムライン(Global TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## HTL -ホームタイムライン(Home TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## LTL -ローカルタイムライン(Local TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## MFM -(読み: えむえふえむ) Misskey Flavored Markdownの略で、Misskey上で使用できるマークアップ言語です。詳細は[こちら。](../features/mfm) - -## NSFW -(読み: のっとせーふふぉーわーく) Not Safe For Workの略。画像を「閲覧注意」扱いにし、操作なしには表示しないようにすることができる機能。 - -## Renote -(読み: りのーと) 既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノート。詳細は[こちら。](../features/note) - -## STL -ソーシャルタイムライン(Social TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## 藍 -(読み: あい) Misskeyの看板娘(公式キャラクター)です。 - -## アクティブユーザー -インスタンスにアカウントを作っているユーザーのうち、現在も実際にサービスを利用しているユーザーのこと。 - -## インスタンス -todo - -## カスタム絵文字 -サーバーで用意された絵文字。カスタム絵文字ではない通常の絵文字は「Unicode絵文字」と区別して呼ばれる。 - -## コントロールパネル -インスタンスの設定画面のこと。 - -## サーバー -todo - -## サイレンス -ノートをパブリックな公開範囲で投稿できなくされている状態。モデレーターの判断でユーザーごとに設定されます。詳細は[こちら。](../features/silence) - -## ジョブキュー -アクティビティ配送などを順番に行うためのシステム。 - -## 凍結 -アカウントが使用不可に設定されている状態。 - -## ドライブ -Misskeyにアップロードしたファイルを管理する機能。詳細は[こちら。](../features/drive) - -## ノート -Misskeyに投稿される、文章、ファイル、アンケートなどを含めることができるコンテンツ。詳細は[こちら。](../features/note) - -## ミスキスト -Misskeyを使う人のこと。 - -## モデレーター -スパムの凍結およびサイレンスや不適切な投稿の削除など、コミュニティ運営に関する権限を持つユーザー。 - -## リモート -他サーバーのことを指します。リモートユーザーといったように接頭辞としても使われます。ローカルの逆です。 - -## 連合 -サーバー上で作成された情報が他のサーバーに伝わること。 - -## ローカル -自サーバーのことを指します。ローカルユーザー、ローカルタイムラインといったように接頭辞としても使われます。リモートの逆です。 diff --git a/src/docs/th-TH/general/links.md b/src/docs/th-TH/general/links.md deleted file mode 100644 index 5ce5e1ddb..000000000 --- a/src/docs/th-TH/general/links.md +++ /dev/null @@ -1,12 +0,0 @@ -# リンク集 - -## Webサイト -- [Official Discord](https://discord.gg/Wp8gVStHW3) - Misskey公式Discordサーバー -- [Misskey Forum](https://forum.misskey.io/) - Misskeyに関する話題を扱うフォーラム - -## アカウント -- [@repo@misskey.io](https://misskey.io/@repo) - Misskeyのリポジトリの更新を投稿するbot - -## ライブラリ -- [misskey-dev/misskey.js](https://github.com/misskey-dev/misskey.js) - JavaScriptのMisskey SDK -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptのMFMパーサー実装 diff --git a/src/docs/th-TH/general/misskey.md b/src/docs/th-TH/general/misskey.md deleted file mode 100644 index d97664ddc..000000000 --- a/src/docs/th-TH/general/misskey.md +++ /dev/null @@ -1,87 +0,0 @@ -# Misskeyについて - -Misskeyはオープンソースの分散型マイクロブログプラットフォームプロジェクトです。 開発は日本でsyuiloによって2014年から開始されました。 ドライブ、リアクションなどの豊富な機能や、高いカスタマイズ性を備えたUIを持つことが特徴です。 - -## 歴史 -開発当初は掲示板がメインのサービスでしたが、ユーザーが短文を投稿し、それを時系列で流れるタイムライン機能を追加したところ人気が高まり、徐々にそれがメインとして開発が進むようになりました。 当初は分散型ではありませんでしたが、2018年にActivityPubを実装し分散型になったことで、より多くの方に認知され利用されるサービスになり、現在に至ります。 -
ℹ️ Misskeyという名前は、syuiloが当時聴いていたMay'nというアーティストの楽曲、Brain Diverの歌詞に由来します。
- -誰でも開発に参加することができ、現在でも活発に開発が続いています。 - -## 分散型とは何か? - -分散(distributed)型とは、非中央集権(decentralized)とも呼ばれ、コミュニティが多数のサーバーに分散して存在し、それらが相互に通信(連合、federation)することでコンテンツ共有ネットワーク(Fediverse)を形成していることが特徴のサービスです。 単一のサーバーしか存在しない、もしくは複数存在しても互いに独立している場合は中央集権なサービスと言われ、例えばTwitterやFacebookなどほとんどのサービスがそれに該当します。 分散型のメリットは、自分に合った運営者やテーマのサーバーを選択できることです。自分でサーバーを作成することもできます。連合するおかげで、どのサーバーを選んでも、同じコミュニティにアクセスできます。 - -## 常にオープンソース -Misskeyはこれまでもこれからも、オープンソースであり続けます。オープンソースとは、簡単に言うとソフトウェアのソースコード(プログラム)が公開されていることです。ソースコードの修正や再配布が可能であることを定義に含めることもあります。 Misskeyのすべてのソースコードは[AGPL](https://github.com/misskey-dev/misskey/blob/develop/LICENSE)というオープンソースライセンスの下に[公開](https://github.com/misskey-dev)されていて、誰でも自由に閲覧、使用、修正、改変、再配布をすることができます。 オープンソースは、自分で好きなように変えたり、有害な処理が含まれていないことを確認することができたり、誰でも開発に参加できるなどの、様々なメリットがあります。 上述の分散型を実現するためにも、オープンソースであるということは必要不可欠な要素です。 再び引き合いに出しますが、TwitterやFacebookなどの利益を得ているほとんどのサービスはオープンソースではありません。 - -
ℹ️ 技術的に言うと、MisskeyのソースコードはGitで管理されていて、リポジトリはGitHub上でホスティングされています。
- -## 開発に参加する、プロジェクトを支援する -Misskeyを気に入っていただけたら、ぜひプロジェクトを支援してください。プロジェクトに貢献するには、以下で紹介するようにいろいろな方法があります。方法によっては開発のスキルは不要なので、誰でも気軽に参加し貢献することができます。いつでもお待ちしています。 - -### 機能を追加したり、バグを修正する -ソフトウェアエンジニアのスキルをお持ちの方であれば、ソースコードを編集する形でプロジェクトに貢献することができます。 貢献についてのガイドは[こちら](https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md)です。 - -### 議論に参加する -新しい機能、または既存の機能について意見を述べたり、不具合を報告したりすることでも貢献できます。 そのようなディスカッションは[GitHub](https://github.com/misskey-dev)上か、[フォーラム](https://forum.misskey.io/)等で行われます。 - -### テキストを翻訳する -Misskeyは様々な言語に対応しています(i18n -internationalizationの略- と呼ばれます)。元の言語は基本的に日本語ですが、有志によって他の言語へと翻訳されています。 その翻訳作業に加わっていただくことでもMisskeyに貢献できます。 Misskeyは[Crowdinというサービスを使用して翻訳の管理を行っています。](https://crowdin.com/project/misskey) - -### 感想を投稿する -不具合報告等だけではなく、Misskeyの良い点、楽しい点といったポジティブな意見もぜひ共有してください。開発の励みになり、それは間接的ですがプロジェクトへの貢献です。 - -### ミスキストを増やす -ミスキストとは、Misskeyを使用する人のことです。 知り合いに紹介するなどしてMisskeyを広めていただければ、ミスキストが増え開発のモチベーションが上がります。 - -### 寄付をする -Misskeyはビジネスではなく、利用は無料であるため、収益は皆様からの寄付のみです。(インスタンスによっては広告収入を得ているような場合もありますが、それは運営者の収入であり直接開発者への収入にはなりません) 寄付をしていただければ、今後も開発を続けることが可能になり、プロジェクトへの貢献になります。 寄付は基本的には[Patreon](https://www.patreon.com/syuilo)で受け付けています。 一定額寄付していただけると、Misskeyの[情報ページ](/about-misskey)に名前を記載することができます。 - -また、サーバーの運営者も、基本的には収益を得ていません。サーバーの運営にはコストがかかるので、運営者の支援をすることもご検討ください。 開発には直接関係しませんが、サーバーがあってこそのプロジェクトなので、運営が維持されるというのは開発と同じくらい重要なことです。 - -## クレジット -Misskeyの開発者や、Misskeyに寄付をしてくださった方の一覧は[こちら](/about-misskey)で見ることができます。 - -## よくある質問 -### プロジェクトは何を目指していますか? -強いて言うと、漠然的になりますが広く使われる汎用的なプラットフォームになることを目指しています。 Misskeyは他のプロジェクトとは違い、何らかの思想(例えば、反中央集権)やビジョンに基づいて開発が行われているわけではなく、その点ではフラットです。 それが逆に、特定の方向性に縛られないフレキシブルさを生み出すことに繋がっていると感じています。 - - -### 企業によって開発されていますか? -いいえ。Misskeyの開発は個人で行われており、商業的でもないため、特定の企業の関りはありません。 開発メンバーも基本的にはボランティアです。 また、開発に対し企業のスポンサーがつくこともありますが、その場合でもやはり開発は個人のコミュニティが主体です。 - -### 誰が運営していますか? -Misskeyは分散型なため、各サーバーにそれぞれ異なった運営者がいます。従って、特定の個人や企業によって、Misskeyの全てが運営されているわけではありません。 また、開発チームが運営を行うわけでもないため、運営に関する連絡は、お使いのサーバーの運営者に行ってください。 サーバーの運営者は、[このページ](/about)で確認することができます。 あなたがサーバーを作成すれば、あなたが運営者になります。 - -### どのサーバーを選べばいいですか? -[サーバー一覧が公開されています。](https://join.misskey.page/ja-JP/instances) サーバーによってコミュニティのテーマ(特定のこと、ものが好き 等)が決められている場合があるので、自分に合ったテーマのサーバーがあれば、そこを選ぶと良いかもしれません。 他にも、サーバーの規模、ユーザー層、国および言語、運営者が信頼できるかどうか、などの観点があります。 なお、Misskey公式のサーバーというものはありません。自身で新しくサーバーを作成するという選択肢もあります。 - -基本的にどのサーバーを選んだとしても、他の全てのサーバーのユーザーと繋がることができます。 - -### サーバーを建てるにはどうしたらいいですか? -Misskeyサーバーの作成に興味を持っていただきありがとうございます。 2021年現在、Misskeyのホスティングサービスは存在しないため、サーバーの作成にはある程度の知識が必要です。 サーバーの作成方法については[こちら](todo)をご覧ください。 - -### どのような技術を使用していますか? -Misskeyは開発が進むにつれ使用する技術も大きく変わってきました。開発当初はMySQL + PHP + jQueryといった構成でしたが、現在は以下のようになっています。 -- サーバーサイド: Node.js -- データベース: PostgreSQL、Redis -- UIフレームワーク: Vue.js -- プログラミング言語: TypeScript - -また、MFMやAiScriptなどの、Misskeyから派生して独自の技術も開発しています。 - -### Mastodonのフォークですか? -いいえ。MisskeyはMastodonやその他のプロジェクトとは全く別のプロジェクトです。 開発に関しても、Misskeyの方が昔から開発されています。ただし、分散型になったのはMastodonの登場より後です。 同じActivityPubという分散のためのプロトコルを実装しているという点以外、両者に特に関りがあるわけでもありません。 - -### iOS/Androidのアプリはありますか? -公式にはそういったOSのネイティブアプリを開発していませんが、サードパーティ製のアプリがいくつかあります。 詳しくは[こちら](./apps)をご覧ください。 - -ただ、サードパーティ製アプリはどうしても機能への対応が遅れてしまうため、とくに拘りがなければ公式のWebクライアントの利用をおすすめします。 なお、MisskeyのWebクライアントはPWAに対応しているので、ネイティブアプリのように動作させることも可能です。 詳しくは[こちら](todo)をご覧ください。 - -### Misskeyのロゴ、アイコンはどこで入手できますか? -(準備中) - -### 時折目にする猫耳の可愛い女の子は? -Misskeyの守り神、藍ちゃんです。アイチャンカワイイヤッター! -
ℹ️ 藍ちゃんについてはこちらです。
diff --git a/src/docs/th-TH/general/report-issue.md b/src/docs/th-TH/general/report-issue.md deleted file mode 100644 index 63527e32a..000000000 --- a/src/docs/th-TH/general/report-issue.md +++ /dev/null @@ -1,8 +0,0 @@ -# 不具合の報告 -不具合と思われる状況に遭遇したときは、まず[トラブルシューティング](./troubleshooting)をご一読ください。 それでも問題が解決しないときは、以下の情報を含めて[フォーラム](https://forum.misskey.io/)に投稿してください。 投稿することで、解決策が見つかったり、不具合と判断されれば開発チームによって修正が行われます。 - -## 含める情報 -- Misskeyのバージョン([情報ページ](/about)で確認できます) -- お使いのブラウザの種類とバージョン -- お使いのOSの種類とバージョン -- 問題の再現手順 diff --git a/src/docs/th-TH/general/troubleshooting.md b/src/docs/th-TH/general/troubleshooting.md deleted file mode 100644 index f895b4984..000000000 --- a/src/docs/th-TH/general/troubleshooting.md +++ /dev/null @@ -1,40 +0,0 @@ -# トラブルシューティング -
ℹ️ よくある質問も合わせてお役立てください。
- -問題が発生したときは、まずこちらをご確認ください。 該当する項目が無い、もしくは手順を試しても効果がない場合は、サーバーの管理者に連絡するか[不具合を報告](./report-issue)してください。 - -## クライアントが起動しない -ほとんどの場合、お使いのブラウザまたはOSのバージョンが古いことが原因です。 ブラウザおよびOSのバージョンを最新のものに更新してから、再度試してみてください。 - -これは稀ですが、それでも起動しない場合は、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。 - -## ページが読み込めない -クライアントが起動するもののページが読み込めないというエラーが出る場合は、ネットワークに問題がないか確認してください。また、サーバーがダウンしていないか確認してください。 - -これは稀ですが、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。 - -まだ問題がある場合は、サーバーの問題と思われるのでサーバーの管理者に連絡してください。 - -## クライアントの動作が遅い -以下を試してみてください: - -- クライアント設定で「UIのアニメーションを減らす」を有効にする -- クライアント設定で「モーダルにぼかし効果を使用」を無効にする -- お使いのブラウザの設定でハードウェアアクセラレーションを有効にする -- お使いのデバイスのスペックを上げる - -## UIの一部の表示がおかしい(背景が透明になっている等) -アップデートによりUIの改修が行われたときに、テーマのキャッシュシステムの影響でそのような表示になることがあります。 クライアントの設定の「キャッシュをクリア」すると直ります。 -
⚠️ 「クライアントの」キャッシュクリアです。「ブラウザの」キャッシュクリアは行わないでください。
- -## 通知やアンテナ等の点滅が消えない -点滅は、未読のコンテンツがあることを示しています。通常点滅が消えない場合は、コンテンツを遡ると未読なコンテンツが残っています。 すべて既読にしたと思われるのに、それでもなお点滅が続く場合(おそらく不具合と思われます)は設定から強制的にすべて既読扱いにすることができます。 - -## Renoteができない -フォロワー限定のノートはRenoteすることはできません。 - -## UI上で特定の要素が表示されない -広告ブロッカーを使用しているとそのような不具合が発生することがあります。Misskeyではオフにしてご利用ください。 - -## UI上で未翻訳の部分がある -ほとんどの場合、単に翻訳が間に合っていないだけで、不具合ではありません。翻訳が終わるまでお待ちください。 [翻訳に参加](./misskey)していただくことも可能です。 diff --git a/src/docs/th-TH/keyboard-shortcut.md b/src/docs/th-TH/keyboard-shortcut.md deleted file mode 100644 index 957ca838c..000000000 --- a/src/docs/th-TH/keyboard-shortcut.md +++ /dev/null @@ -1,68 +0,0 @@ -# キーボードショートカット - -## グローバル -これらのショートカットは基本的にどこでも使えます。 - - - - - - - - - - - -
ショートカット効果由来
P, N新規投稿Post, New, Note
Tタイムラインの最も新しい投稿にフォーカスTimeline, Top
Shift + N通知を表示/隠すNotifications
S検索Search
H, ?ヘルプを表示Help
- -## 投稿にフォーカスされた状態 - - - - - - - - - - - - - - - - - - - -
ショートカット効果由来
, K, Shift + Tab上の投稿にフォーカスを移動-
, J, Tab下の投稿にフォーカスを移動-
R返信フォームを開くReply
QRenoteフォームを開くQuote
Ctrl + Q即刻Renoteする(フォームを開かずに)-
E, A, +リアクションフォームを開くEmote, reAction
0~9数字に対応したリアクションをする(対応については後述)-
F, Bお気に入りに登録Favorite, Bookmark
Del, Ctrl + D投稿を削除Delete
M, O投稿に対するメニューを開くMore, Other
SCWで隠された部分を表示 or 隠すShow, See
Escフォーカスを外す-
- -## Renoteフォーム - - - - - - - - - - -
ショートカット効果由来
EnterRenoteする-
Qフォームを展開するQuote
Escフォームを閉じる-
- -## リアクションフォーム -デフォルトで「👍」にフォーカスが当たっている状態です。 - - - - - - - - - - - - - -
ショートカット効果由来
, K上のリアクションにフォーカスを移動-
, J下のリアクションにフォーカスを移動-
, H, Shift + Tab左のリアクションにフォーカスを移動-
, L, Tab右のリアクションにフォーカスを移動-
Enter, Space, +リアクション確定-
0~9数字に対応したリアクションで確定-
Escリアクションするのをやめる-
diff --git a/src/docs/th-TH/mfm.md b/src/docs/th-TH/mfm.md deleted file mode 100644 index e237287ac..000000000 --- a/src/docs/th-TH/mfm.md +++ /dev/null @@ -1,2 +0,0 @@ -# MFM -MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます。 diff --git a/src/docs/th-TH/mute.md b/src/docs/th-TH/mute.md deleted file mode 100644 index 6a9608662..000000000 --- a/src/docs/th-TH/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# ミュート - -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -* タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -* そのユーザーからの通知 -* メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 - -ユーザーをミュートするには、対象のユーザーのユーザーページに表示されている「ミュート」ボタンを押します。 - -ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。 - -設定>ミュート から、自分がミュートしているユーザー一覧を確認することができます。 diff --git a/src/docs/th-TH/pages.md b/src/docs/th-TH/pages.md deleted file mode 100644 index a7311b95e..000000000 --- a/src/docs/th-TH/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# Pages - -## 変数 -変数を使うことで動的なページを作成できます。テキスト内で { 変数名 } と書くとそこに変数の値を埋め込めます。例えば Hello { thing } world! というテキストで、変数(thing)の値が ai だった場合、テキストは Hello ai world! になります。 - -変数の評価(値を算出すること)は上から下に行われるので、ある変数の中で自分より下の変数を参照することはできません。例えば上から A、B、C と3つの変数を定義したとき、Cの中でABを参照することはできますが、Aの中でBCを参照することはできません。 - -ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。 - -関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。 diff --git a/src/docs/th-TH/reaction.md b/src/docs/th-TH/reaction.md deleted file mode 100644 index c26ead75b..000000000 --- a/src/docs/th-TH/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# リアクション -他の人のノートに、絵文字を付けて簡単にあなたの反応を伝えられる機能です。 リアクションするには、ノートの + アイコンをクリックしてピッカーを表示し、絵文字を選択します。 リアクションには[カスタム絵文字](./custom-emoji)も使用できます。 - -## リアクションピッカーのカスタマイズ -ピッカーに表示される絵文字を自分好みにカスタマイズすることができます。 設定の「リアクション」で設定します。 - -## リモート投稿へのリアクションについて -リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。 また、相手がMisskeyであったとしても、カスタム絵文字リアクションは伝わらず、自動的に「👍」等にフォールバックされます。 - -## リモートからのリアクションについて -リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。 diff --git a/src/docs/th-TH/reversi-bot.md b/src/docs/th-TH/reversi-bot.md deleted file mode 100644 index 7ab2a7212..000000000 --- a/src/docs/th-TH/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# MisskeyリバーシBotの開発 -Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。 - -1. `games/reversi`ストリームに以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - -2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる - * イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている - -3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する - -4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - * `game`: `game`の`id` - -5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う - -6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する - -7. ゲームが開始すると、`started`イベントが流れてくる - * イベントの中身にはゲーム情報が含まれている - -8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述) - -9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる - * `color`として石の色が含まれている - * `pos`として位置情報が含まれている - -## 位置の計算法 -8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### X,Y座標 から インデックス に変換する -``` -pos = x + (y * mapWidth) -``` -`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます: -``` -mapWidth = map[0].length -``` - -### インデックス から X,Y座標 に変換する -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## マップ情報 -マップ情報は、ゲーム情報の`map`に入っています。 文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 それをもとにマップのデザインを知る事が出来ます: -* `(スペース)` ... マス無し -* `-` ... マス -* `b` ... 初期配置される黒石 -* `w` ... 初期配置される白石 - -例えば、4*4の次のような単純なマップがあるとします: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -この場合、マップデータはこのようになります: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## ユーザーにフォームを提示して対話可能Botを作成する -ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。 - -フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します: -```javascript -{ - type: 'init-form', - body: [フォームコントロールの配列] -} -``` - -フォームコントロールの配列については今から説明します。 フォームコントロールは、次のようなオブジェクトです: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... コントロールのID。 `type` ... コントロールの種類。後述します。 `label` ... コントロールと一緒に表記するテキスト。 `value` ... コントロールのデフォルト値。 - -### フォームの操作を受け取る -ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### フォームコントロールの種類 -#### スイッチ -type: `switch` スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。 - -##### プロパティ -`label` ... スイッチに表記するテキスト。 - -#### ラジオボタン -type: `radio` ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。 - -##### プロパティ -`items` ... ラジオボタンの選択肢。例: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '強', - value: 3 -}] -``` - -#### スライダー -type: `slider` スライダーを表示します。 - -##### プロパティ -`min` ... スライダーの下限。 `max` ... スライダーの上限。 `step` ... 入力欄で刻むステップ値。 - -#### テキストボックス -type: `textbox` テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。 - -## ユーザーにメッセージを表示する -設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 メッセージを表示するには、次のメッセージをストリームに送信します: -```javascript -{ - type: 'message', - body: { - text: 'メッセージ内容', - type: 'メッセージの種類' - } -} -``` -メッセージの種類: `success`, `info`, `warning`, `error`。 - -## 投了する -投了をするには、このエンドポイントにリクエストします。 diff --git a/src/docs/th-TH/stream.md b/src/docs/th-TH/stream.md deleted file mode 100644 index 9011c37c5..000000000 --- a/src/docs/th-TH/stream.md +++ /dev/null @@ -1,354 +0,0 @@ -# ストリーミングAPI - -ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。 - -## ストリームに接続する - -ストリーミングAPIを利用するには、まずMisskeyサーバーに**websocket**接続する必要があります。 - -以下のURLに、`i`というパラメータ名で認証情報を含めて、websocket接続してください。例: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。 - -
-

認証情報の取得については、こちらのドキュメントをご確認ください。

-
- ---- - -認証情報は省略することもできますが、その場合非ログインでの利用ということになり、受信できる情報や可能な操作は限られます。例: - -``` -%WS_URL%/streaming -``` - ---- - -ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。 - -**ストリームでのやり取りはすべてJSONです。** - -## チャンネル -MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。 - -### チャンネルに接続する -チャンネルに接続するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -ここで、 -* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。 -* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。 -* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。 - -
-

IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。

-
- -### チャンネルからのメッセージを受け取る -例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。 - -チャンネルがメッセージを発すると、次のようなデータがJSONでストリームに流れてきます: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。 -* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。 -* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。 - -### チャンネルに向けてメッセージを送信する -チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。 - -チャンネルにメッセージを送信するには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。 -* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。 -* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。 - -### チャンネルから切断する -チャンネルから切断するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。 - -## ストリームを経由してAPIリクエストする - -ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。 - -ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -ここで、 -* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 -* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 -* `data`には、エンドポイントのパラメータを含めます。 - -
-

APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。

-
- -### レスポンスの受信 - -APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。 - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -ここで、 -* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 -* `body`には、レスポンスが含まれています。 - -## 投稿のキャプチャ - -Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。 - -例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。 - -しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。 - -この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。 - -### 投稿をキャプチャする - -投稿をキャプチャするには、ストリームに次のようなメッセージを送信します: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャしたい投稿の`id`を設定します。 - -このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 - -例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -ここで、 -* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。 -* `body`内の`type`に、イベントの種類が設定されます。 -* `body`内の`body`に、イベントの詳細が設定されます。 - -#### イベントの種類 - -##### `reacted` -その投稿にリアクションがされた時に発生します。 - -* `reaction`に、リアクションの種類が設定されます。 -* `userId`に、リアクションを行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -その投稿が削除された時に発生します。 - -* `deletedAt`に、削除日時が設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -その投稿に添付されたアンケートに投票された時に発生します。 - -* `choice`に、選択肢IDが設定されます。 -* `userId`に、投票を行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### 投稿のキャプチャを解除する - -その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。 - -次のメッセージを送信します: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャを解除したい投稿の`id`を設定します。 - -このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 - -# チャンネル一覧 -## `main` -アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `renote` -自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。 - -#### `mention` -誰かからメンションされたときに発生するイベントです。 - -#### `readAllNotifications` -自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。 - -#### `meUpdated` -自分の情報が更新されたことを表すイベントです。 - -#### `follow` -自分が誰かをフォローしたときに発生するイベントです。 - -#### `unfollow` -自分が誰かのフォローを解除したときに発生するイベントです。 - -#### `followed` -自分が誰かにフォローされたときに発生するイベントです。 - -## `homeTimeline` -ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -タイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `localTimeline` -ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `hybridTimeline` -ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ソーシャルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `globalTimeline` -グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 diff --git a/src/docs/th-TH/theme.md b/src/docs/th-TH/theme.md deleted file mode 100644 index a406f3433..000000000 --- a/src/docs/th-TH/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# テーマ - -テーマを設定して、Misskeyクライアントの見た目を変更できます。 - -## テーマの設定 -設定 > テーマ - -## テーマを作成する -テーマコードはJSON5で記述されたテーマオブジェクトです。 テーマは以下のようなオブジェクトです。 -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... テーマの一意なID。UUIDをおすすめします。 -* `name` ... テーマ名 -* `author` ... テーマの作者 -* `desc` ... テーマの説明(オプション) -* `base` ... 明るいテーマか、暗いテーマか - * `light`にすると明るいテーマになり、`dark`にすると暗いテーマになります。 - * テーマはここで設定されたベーステーマを継承します。 -* `props` ... テーマのスタイル定義。これから説明します。 - -### テーマのスタイル定義 -`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 - -#### バリューで使える構文 -* 16進数で表された色 - * 例: `#00ff00` -* `rgb(r, g, b)`形式で表された色 - * 例: `rgb(0, 255, 0)` -* `rgb(r, g, b, a)`形式で表された透明度を含む色 - * 例: `rgba(0, 255, 0, 0.5)` -* 他のキーの値の参照 - * `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。 - * 例: `@panel` -* 定数(後述)の参照 - * `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。 - * 例: `$main` -* 関数(後述) - * `:{関数名}<{引数}<{色}` - -#### 定数 -「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 キー名を`$`で始めると、そのキーはCSS変数として出力されません。 - -#### 関数 -wip diff --git a/src/docs/th-TH/timelines.md b/src/docs/th-TH/timelines.md deleted file mode 100644 index 36ba61bd2..000000000 --- a/src/docs/th-TH/timelines.md +++ /dev/null @@ -1,15 +0,0 @@ -# タイムラインの比較 - -https://docs.google.com/spreadsheets/d/1lxQ2ugKrhz58Bg96HTDK_2F98BUritkMyIiBkOByjHA/edit?usp=sharing - -## ホーム -自分のフォローしているユーザーの投稿 - -## ローカル -全てのローカルユーザーの「ホーム」指定されていない投稿 - -## ソーシャル -自分のフォローしているユーザーの投稿と、全てのローカルユーザーの「ホーム」指定されていない投稿 - -## グローバル -全てのローカルユーザーの「ホーム」指定されていない投稿と、サーバーに届いた全てのリモートユーザーの「ホーム」指定されていない投稿 diff --git a/src/docs/ug-CN/admin/disable-timelines.md b/src/docs/ug-CN/admin/disable-timelines.md deleted file mode 100644 index b081e35ab..000000000 --- a/src/docs/ug-CN/admin/disable-timelines.md +++ /dev/null @@ -1,8 +0,0 @@ -# LTL/STL/GTLの無効化 -Misskeyでは、LTL/STL/GTLをそれぞれ無効化することができます。有効/無効を切り替えるには、インスタンスコントロールパネルで設定します。 - -LTLやSTLは、そのインスタンス全員の投稿が見れるため、新規のユーザーにとってはユーザーを探す必要がなくなり、興味のあるユーザーを見つけやすいという利点があります。 しかし同時に、フォロー機能が活用されなくなったり、不適切な投稿が目につきやすくなったり、チャットのようになることで内輪感が生じて逆に新規ユーザーが参加しにくくなるといったデメリットも持ち合わせています。 サーバーによってメリット/デメリットどちらが優勢かは異なるので、オプションとして無効にできるようになっています。 もしデメリットの方が上回っていると感じたら、それらのタイムラインを無効化することも検討してください。 - -
⚠️ 無効化を行うと、ユーザーが困惑し、短期的に見て利用者が減る可能性があります。そのため、無効化の際は影響を慎重に検討し、事前に説明してフォローを整える期間を一定程度設けることを推奨します。
- -なお、管理者/モデレーターは、これらのタイムラインの無効化状態は適用されず、引き続き利用することが可能です。 diff --git a/src/docs/ug-CN/admin/faq.md b/src/docs/ug-CN/admin/faq.md deleted file mode 100644 index 317b4e065..000000000 --- a/src/docs/ug-CN/admin/faq.md +++ /dev/null @@ -1,5 +0,0 @@ -# よくある質問 -ここでは、サーバー管理者向けのよくある質問を掲載しています。 - -## デフォルトテーマを設定したい -現在、デフォルトテーマ設定機能は実装されていません。 diff --git a/src/docs/ug-CN/advanced/aiscript.md b/src/docs/ug-CN/advanced/aiscript.md deleted file mode 100644 index 604d17daa..000000000 --- a/src/docs/ug-CN/advanced/aiscript.md +++ /dev/null @@ -1,7 +0,0 @@ -# AiScript -AiScriptは、Misskeyで使用できるスクリプト言語です。 - -
ℹ️ AiScript実装はMisskeyとは別リポジトリで、オープンソースで公開されています。
- -## 使い方 -AiScriptの構文や組み込み関数などのドキュメントは、[こちら](https://github.com/syuilo/aiscript/tree/master/docs)で公開されています。 diff --git a/src/docs/ug-CN/advanced/api.md b/src/docs/ug-CN/advanced/api.md deleted file mode 100644 index 76019b614..000000000 --- a/src/docs/ug-CN/advanced/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス、Bot等(以下「アプリケーション」と呼びます)を開発できます。 ストリーミングAPIもあるので、リアルタイム性のあるアプリケーションを作ることも可能です。 - -APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。 - -## アクセストークンの取得 -基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。 - -* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む -* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む - -### 自分自身のアクセストークンを手動発行する -「設定 > API」で、自分のアクセストークンを発行できます。 - -[「APIの使い方」へ進む](#APIの使い方) - -### アプリケーション利用者にアクセストークンの発行をリクエストする -アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。 - -#### Step 1 - -UUIDを生成する。以後これをセッションIDと呼びます。 - -> このセッションIDは毎回生成し、使いまわさないようにしてください。 - -#### Step 2 - -`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。 -> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます: -* `name` ... アプリケーション名 - * > 例: `MissDeck` -* `icon` ... アプリケーションのアイコン画像URL - * > 例: `https://missdeck.example.com/icon.png` -* `callback` ... 認証が終わった後にリダイレクトするURL - * > 例: `https://missdeck.example.com/callback` - * リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます -* `permission` ... アプリケーションが要求する権限 - * > 例: `write:notes,write:following,read:drive` - * 要求する権限を`,`で区切って列挙します - * どのような権限があるかは[APIリファレンス](/api-doc)で確認できます - -#### Step 3 -ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。 - -レスポンスに含まれるプロパティ: -* `token` ... ユーザーのアクセストークン -* `user` ... ユーザーの情報 - -[「APIの使い方」へ進む](#APIの使い方) - -## APIの使い方 -**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。 - -* [APIリファレンス](/api-doc) -* [ストリーミングAPI](./stream) diff --git a/src/docs/ug-CN/advanced/create-plugin.md b/src/docs/ug-CN/advanced/create-plugin.md deleted file mode 100644 index 0d2fa1917..000000000 --- a/src/docs/ug-CN/advanced/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# プラグインの作成 -Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。 - -## メタデータ -プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。 - -### name -プラグイン名 - -### author -プラグイン作者 - -### version -プラグインバージョン。数値を指定してください。 - -### description -プラグインの説明 - -### permissions -プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。 - -### config -プラグインの設定情報を表すオブジェクト。 キーに設定名、値に以下のプロパティを含めます。 - -#### type -設定値の種類を表す文字列。以下から選択します。 string number boolean - -#### label -ユーザーに表示する設定名 - -#### description -設定の説明 - -#### default -設定のデフォルト値 - -## APIリファレンス -AiScript標準で組み込まれているAPIは掲載しません。 - -### Mk:dialog(title text type) -ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。 - -### Mk:confirm(title text type) -確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。 - -### Mk:api(endpoint params) -Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。 - -### Mk:save(key value) -任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。 - -### Mk:load(key) -Mk:saveで永続化した指定の名前の値を読み取ります。 - -### Plugin:register_post_form_action(title fn) -投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。 - -### Plugin:register_note_action(title fn) -ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 - -### Plugin:register_user_action(title fn) -ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。 - -### Plugin:register_note_view_interruptor(fn) -UIに表示されるノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:register_note_post_interruptor(fn) -ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:open_url(url) -第一引数に渡されたURLをブラウザの新しいタブで開きます。 - -### Plugin:config -プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。 diff --git a/src/docs/ug-CN/advanced/develop-bot.md b/src/docs/ug-CN/advanced/develop-bot.md deleted file mode 100644 index 7f825e9bc..000000000 --- a/src/docs/ug-CN/advanced/develop-bot.md +++ /dev/null @@ -1,6 +0,0 @@ -# Botの作成 -[Misskey API](./api)を利用してBotの開発が可能です。 また、いくつかのBot実装が公開されているため、ぜひ参考にしてください。 - -- [syuilo/ai](https://github.com/syuilo/ai) ... Node.js上で動く、TypeScript製Bot実装 - -Botを作成したときは、プロフィール設定からBotフラグをオンにしておくことを強くおすすめします。 diff --git a/src/docs/ug-CN/advanced/reversi-bot.md b/src/docs/ug-CN/advanced/reversi-bot.md deleted file mode 100644 index 7ab2a7212..000000000 --- a/src/docs/ug-CN/advanced/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# MisskeyリバーシBotの開発 -Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。 - -1. `games/reversi`ストリームに以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - -2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる - * イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている - -3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する - -4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - * `game`: `game`の`id` - -5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う - -6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する - -7. ゲームが開始すると、`started`イベントが流れてくる - * イベントの中身にはゲーム情報が含まれている - -8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述) - -9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる - * `color`として石の色が含まれている - * `pos`として位置情報が含まれている - -## 位置の計算法 -8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### X,Y座標 から インデックス に変換する -``` -pos = x + (y * mapWidth) -``` -`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます: -``` -mapWidth = map[0].length -``` - -### インデックス から X,Y座標 に変換する -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## マップ情報 -マップ情報は、ゲーム情報の`map`に入っています。 文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 それをもとにマップのデザインを知る事が出来ます: -* `(スペース)` ... マス無し -* `-` ... マス -* `b` ... 初期配置される黒石 -* `w` ... 初期配置される白石 - -例えば、4*4の次のような単純なマップがあるとします: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -この場合、マップデータはこのようになります: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## ユーザーにフォームを提示して対話可能Botを作成する -ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。 - -フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します: -```javascript -{ - type: 'init-form', - body: [フォームコントロールの配列] -} -``` - -フォームコントロールの配列については今から説明します。 フォームコントロールは、次のようなオブジェクトです: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... コントロールのID。 `type` ... コントロールの種類。後述します。 `label` ... コントロールと一緒に表記するテキスト。 `value` ... コントロールのデフォルト値。 - -### フォームの操作を受け取る -ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### フォームコントロールの種類 -#### スイッチ -type: `switch` スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。 - -##### プロパティ -`label` ... スイッチに表記するテキスト。 - -#### ラジオボタン -type: `radio` ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。 - -##### プロパティ -`items` ... ラジオボタンの選択肢。例: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '強', - value: 3 -}] -``` - -#### スライダー -type: `slider` スライダーを表示します。 - -##### プロパティ -`min` ... スライダーの下限。 `max` ... スライダーの上限。 `step` ... 入力欄で刻むステップ値。 - -#### テキストボックス -type: `textbox` テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。 - -## ユーザーにメッセージを表示する -設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 メッセージを表示するには、次のメッセージをストリームに送信します: -```javascript -{ - type: 'message', - body: { - text: 'メッセージ内容', - type: 'メッセージの種類' - } -} -``` -メッセージの種類: `success`, `info`, `warning`, `error`。 - -## 投了する -投了をするには、このエンドポイントにリクエストします。 diff --git a/src/docs/ug-CN/advanced/share-page.md b/src/docs/ug-CN/advanced/share-page.md deleted file mode 100644 index 4fb7ded0b..000000000 --- a/src/docs/ug-CN/advanced/share-page.md +++ /dev/null @@ -1,54 +0,0 @@ -# シェアページ -`/share`を開くと、共有用の投稿フォームを開くことができます。 ここではシェアページで利用できるクエリ文字列の一覧を示します。 - -## クエリ文字列一覧 -### 文字 - -
-
title
-
タイトルです。本文の先頭に[ … ]と挿入されます。
-
text
-
本文です。
-
url
-
URLです。末尾に挿入されます。
-
- -### リプライ情報 -以下のいずれか - -
-
replyId
-
リプライ先のノートid
-
replyUri
-
リプライ先のUrl(リモートのノートオブジェクトを指定)
-
- -### Renote情報 -以下のいずれか - -
-
renoteId
-
Renote先のノートid
-
renoteUri
-
Renote先のUrl(リモートのノートオブジェクトを指定)
-
- -### 公開範囲 -※specifiedに相当する値はvisibility=specifiedとvisibleAccts/visibleUserIdsで指定する - -
-
visibility
-
公開範囲 ['public' | 'home' | 'followers' | 'specified']
-
localOnly
-
0(false) or 1(true)
-
visibleUserIds
-
specified時のダイレクト先のユーザーid カンマ区切りで
-
visibleAccts
-
specified時のダイレクト先のacct(@?username[@host]) カンマ区切りで
-
- -### ファイル -
-
fileIds
-
添付したいファイルのid(カンマ区切りで)
-
diff --git a/src/docs/ug-CN/advanced/stream.md b/src/docs/ug-CN/advanced/stream.md deleted file mode 100644 index 0e5edd2b0..000000000 --- a/src/docs/ug-CN/advanced/stream.md +++ /dev/null @@ -1,350 +0,0 @@ -# ストリーミングAPI - -ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。 - -## ストリームに接続する - -ストリーミングAPIを利用するには、まずMisskeyサーバーに**websocket**接続する必要があります。 - -以下のURLに、`i`というパラメータ名で認証情報を含めて、websocket接続してください。例: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。 - -
ℹ️ 認証情報の取得については、こちらのドキュメントをご確認ください。
- ---- - -認証情報は省略することもできますが、その場合非ログインでの利用ということになり、受信できる情報や可能な操作は限られます。例: - -``` -%WS_URL%/streaming -``` - ---- - -ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。 - -**ストリームでのやり取りはすべてJSONです。** - -## チャンネル -MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。 - -ひとつのストリーム上で、同時に複数のチャンネルに接続することができます。 - -### チャンネルに接続する -チャンネルに接続するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -ここで、 -* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。 -* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。 -* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。 - -
ℹ️ IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。
- -### チャンネルからのメッセージを受け取る -例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。 - -チャンネルがメッセージを発すると、次のようなデータがJSONでストリームに流れてきます: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。 -* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。 -* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。 - -### チャンネルに向けてメッセージを送信する -チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。 - -チャンネルにメッセージを送信するには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。 -* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。 -* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。 - -### チャンネルから切断する -チャンネルから切断するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。 - -## ストリームを経由してAPIリクエストする - -ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。 - -ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -ここで、 -* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 -* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 -* `data`には、エンドポイントのパラメータを含めます。 - -
ℹ️ APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。
- -### レスポンスの受信 - -APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。 - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -ここで、 -* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 -* `body`には、レスポンスが含まれています。 - -## 投稿のキャプチャ - -Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。 - -例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。 - -しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。 - -この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。 - -### 投稿をキャプチャする - -投稿をキャプチャするには、ストリームに次のようなメッセージを送信します: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャしたい投稿の`id`を設定します。 - -このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 - -例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -ここで、 -* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。 -* `body`内の`type`に、イベントの種類が設定されます。 -* `body`内の`body`に、イベントの詳細が設定されます。 - -#### イベントの種類 - -##### `reacted` -その投稿にリアクションがされた時に発生します。 - -* `reaction`に、リアクションの種類が設定されます。 -* `userId`に、リアクションを行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -その投稿が削除された時に発生します。 - -* `deletedAt`に、削除日時が設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -その投稿に添付されたアンケートに投票された時に発生します。 - -* `choice`に、選択肢IDが設定されます。 -* `userId`に、投票を行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### 投稿のキャプチャを解除する - -その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。 - -次のメッセージを送信します: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャを解除したい投稿の`id`を設定します。 - -このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 - -# チャンネル一覧 -## `main` -アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `renote` -自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。 - -#### `mention` -誰かからメンションされたときに発生するイベントです。 - -#### `readAllNotifications` -自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。 - -#### `meUpdated` -自分の情報が更新されたことを表すイベントです。 - -#### `follow` -自分が誰かをフォローしたときに発生するイベントです。 - -#### `unfollow` -自分が誰かのフォローを解除したときに発生するイベントです。 - -#### `followed` -自分が誰かにフォローされたときに発生するイベントです。 - -## `homeTimeline` -ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -タイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `localTimeline` -ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `hybridTimeline` -ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ソーシャルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `globalTimeline` -グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 diff --git a/src/docs/ug-CN/aiscript.md b/src/docs/ug-CN/aiscript.md deleted file mode 100644 index 6c28b446e..000000000 --- a/src/docs/ug-CN/aiscript.md +++ /dev/null @@ -1,4 +0,0 @@ -# AiScript - -## 関数 -デフォルトで値渡しです。 diff --git a/src/docs/ug-CN/api.md b/src/docs/ug-CN/api.md deleted file mode 100644 index 76019b614..000000000 --- a/src/docs/ug-CN/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス、Bot等(以下「アプリケーション」と呼びます)を開発できます。 ストリーミングAPIもあるので、リアルタイム性のあるアプリケーションを作ることも可能です。 - -APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。 - -## アクセストークンの取得 -基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。 - -* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む -* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む - -### 自分自身のアクセストークンを手動発行する -「設定 > API」で、自分のアクセストークンを発行できます。 - -[「APIの使い方」へ進む](#APIの使い方) - -### アプリケーション利用者にアクセストークンの発行をリクエストする -アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。 - -#### Step 1 - -UUIDを生成する。以後これをセッションIDと呼びます。 - -> このセッションIDは毎回生成し、使いまわさないようにしてください。 - -#### Step 2 - -`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。 -> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます: -* `name` ... アプリケーション名 - * > 例: `MissDeck` -* `icon` ... アプリケーションのアイコン画像URL - * > 例: `https://missdeck.example.com/icon.png` -* `callback` ... 認証が終わった後にリダイレクトするURL - * > 例: `https://missdeck.example.com/callback` - * リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます -* `permission` ... アプリケーションが要求する権限 - * > 例: `write:notes,write:following,read:drive` - * 要求する権限を`,`で区切って列挙します - * どのような権限があるかは[APIリファレンス](/api-doc)で確認できます - -#### Step 3 -ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。 - -レスポンスに含まれるプロパティ: -* `token` ... ユーザーのアクセストークン -* `user` ... ユーザーの情報 - -[「APIの使い方」へ進む](#APIの使い方) - -## APIの使い方 -**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。 - -* [APIリファレンス](/api-doc) -* [ストリーミングAPI](./stream) diff --git a/src/docs/ug-CN/create-plugin.md b/src/docs/ug-CN/create-plugin.md deleted file mode 100644 index 0d2fa1917..000000000 --- a/src/docs/ug-CN/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# プラグインの作成 -Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。 - -## メタデータ -プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。 - -### name -プラグイン名 - -### author -プラグイン作者 - -### version -プラグインバージョン。数値を指定してください。 - -### description -プラグインの説明 - -### permissions -プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。 - -### config -プラグインの設定情報を表すオブジェクト。 キーに設定名、値に以下のプロパティを含めます。 - -#### type -設定値の種類を表す文字列。以下から選択します。 string number boolean - -#### label -ユーザーに表示する設定名 - -#### description -設定の説明 - -#### default -設定のデフォルト値 - -## APIリファレンス -AiScript標準で組み込まれているAPIは掲載しません。 - -### Mk:dialog(title text type) -ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。 - -### Mk:confirm(title text type) -確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。 - -### Mk:api(endpoint params) -Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。 - -### Mk:save(key value) -任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。 - -### Mk:load(key) -Mk:saveで永続化した指定の名前の値を読み取ります。 - -### Plugin:register_post_form_action(title fn) -投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。 - -### Plugin:register_note_action(title fn) -ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 - -### Plugin:register_user_action(title fn) -ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。 - -### Plugin:register_note_view_interruptor(fn) -UIに表示されるノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:register_note_post_interruptor(fn) -ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:open_url(url) -第一引数に渡されたURLをブラウザの新しいタブで開きます。 - -### Plugin:config -プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。 diff --git a/src/docs/ug-CN/custom-emoji.md b/src/docs/ug-CN/custom-emoji.md deleted file mode 100644 index ed2e92be1..000000000 --- a/src/docs/ug-CN/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# カスタム絵文字 -カスタム絵文字は、インスタンスで用意された画像を絵文字のように使える機能です。 ノート、リアクション、チャット、自己紹介、名前などの場所で使うことができます。 カスタム絵文字をそれらの場所で使うには、絵文字ピッカーボタン(ある場合)を押すか、`:`を入力して絵文字サジェストを表示します。 テキスト内に`:foo:`のような形式の文字列が見つかると、`foo`の部分がカスタム絵文字名と解釈され、表示時には対応したカスタム絵文字に置き換わります。 diff --git a/src/docs/ug-CN/deck.md b/src/docs/ug-CN/deck.md deleted file mode 100644 index 8057e262f..000000000 --- a/src/docs/ug-CN/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# デッキ - -デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。 - -## カラムの追加 -デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。 - -## カラムの移動 -カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。 - -## カラムの水平分割 -カラムは左右だけでなく、上下に並べることもできます。 カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 上下分割を解除するには、カラムメニューの「右に出す」を選択します。 - -## カラムの設定 -カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。 - -## デッキの設定 -デッキに関する設定は、[settings/deck](/settings/deck)で行えます。 diff --git a/src/docs/ug-CN/features/antenna.md b/src/docs/ug-CN/features/antenna.md deleted file mode 100644 index 94ad9e4ae..000000000 --- a/src/docs/ug-CN/features/antenna.md +++ /dev/null @@ -1,4 +0,0 @@ -# アンテナ -アンテナは、自由に条件を設定して、合致するノートを自動で収集することができる機能です。 - -条件を設定したアンテナが作成された状態で、条件に合致するノートが投稿されると、リアルタイムでそのアンテナのタイムラインにノートが追加されます。 diff --git a/src/docs/ug-CN/features/custom-emoji.md b/src/docs/ug-CN/features/custom-emoji.md deleted file mode 100644 index ed2e92be1..000000000 --- a/src/docs/ug-CN/features/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# カスタム絵文字 -カスタム絵文字は、インスタンスで用意された画像を絵文字のように使える機能です。 ノート、リアクション、チャット、自己紹介、名前などの場所で使うことができます。 カスタム絵文字をそれらの場所で使うには、絵文字ピッカーボタン(ある場合)を押すか、`:`を入力して絵文字サジェストを表示します。 テキスト内に`:foo:`のような形式の文字列が見つかると、`foo`の部分がカスタム絵文字名と解釈され、表示時には対応したカスタム絵文字に置き換わります。 diff --git a/src/docs/ug-CN/features/deck.md b/src/docs/ug-CN/features/deck.md deleted file mode 100644 index 8057e262f..000000000 --- a/src/docs/ug-CN/features/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# デッキ - -デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。 - -## カラムの追加 -デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。 - -## カラムの移動 -カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。 - -## カラムの水平分割 -カラムは左右だけでなく、上下に並べることもできます。 カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 上下分割を解除するには、カラムメニューの「右に出す」を選択します。 - -## カラムの設定 -カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。 - -## デッキの設定 -デッキに関する設定は、[settings/deck](/settings/deck)で行えます。 diff --git a/src/docs/ug-CN/features/drive.md b/src/docs/ug-CN/features/drive.md deleted file mode 100644 index b82a41082..000000000 --- a/src/docs/ug-CN/features/drive.md +++ /dev/null @@ -1,17 +0,0 @@ -# ドライブ -ドライブは、Misskey上でファイルを管理できる機能です。 - -[ドライブのページ](/my/drive)から任意のファイルをアップロードできるほか、アバターに設定した画像や、ノートに添付したファイルなどもすべてドライブにアップロードされます。 - -
⚠️ ドライブからファイルを削除すると、そのファイルが添付されたノートも消えます。
- -ドライブにアップロードされたファイルは、いつでもダウンロードすることができるほか、ノート作成時に「ドライブからファイルを添付」することでファイルを再利用することもできます。 - -ドライブ内にフォルダを作り、複数のファイルをまとめて整理することもできます。 - -## 閲覧注意 (NSFW) -
ℹ️ この項目が閲覧注意なわけではありません
- -閲覧注意またはNSFW (Not safe for work) は、ドライブのファイルに設定することができるフラグです。 閲覧注意フラグを設定されたファイルは、表示される際に閲覧者の操作なしには表示されなくなります。 このフラグは、例えば職場や公共の場で閲覧するのに適切でないと思われる画像などに設定し、そのような画像が突然表示されてしまうことを防ぐ目的で使われます。 - -このフラグは手動でオンオフを切り替えられるほか、モデレーターの判断で設定される場合もあります。 diff --git a/src/docs/ug-CN/features/favorite.md b/src/docs/ug-CN/features/favorite.md deleted file mode 100644 index a0e5f8bf7..000000000 --- a/src/docs/ug-CN/features/favorite.md +++ /dev/null @@ -1,4 +0,0 @@ -# お気に入り -[ノート](./node)をお気に入りとして登録できる機能です。 お気に入り登録したノートは、[お気に入りページ](./my/favorites)で一覧することができます。 お気に入りに登録したことは相手に通知されず、お気に入りは自分しか見ることができません。 - -ノートをお気に入り登録するには、ノートメニューの「お気に入り」を押します。お気に入り解除するには、ノートメニューの「お気に入り解除」を押します。 diff --git a/src/docs/ug-CN/features/follow.md b/src/docs/ug-CN/features/follow.md deleted file mode 100644 index 3c1ea7bbe..000000000 --- a/src/docs/ug-CN/features/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# フォロー -ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。 diff --git a/src/docs/ug-CN/features/keyboard-shortcut.md b/src/docs/ug-CN/features/keyboard-shortcut.md deleted file mode 100644 index cde62f29c..000000000 --- a/src/docs/ug-CN/features/keyboard-shortcut.md +++ /dev/null @@ -1,66 +0,0 @@ -# キーボードショートカット - -## グローバル -これらのショートカットは基本的にどこでも使えます。 - - - - - - - - - - - -
ショートカット効果由来
P, N新規投稿Post, New, Note
Tタイムラインの最も新しい投稿にフォーカスTimeline, Top
Shift + N通知を表示/隠すNotifications
SئىزدەشSearch
H, ?ヘルプを表示Help
- -## 投稿にフォーカスされた状態 - - - - - - - - - - - - - - - - - - -
ショートカット効果由来
, K, Shift + Tab上の投稿にフォーカスを移動-
, J, Tab下の投稿にフォーカスを移動-
R返信フォームを開くReply
QRenoteフォームを開くQuote
Ctrl + Q即刻Renoteする(フォームを開かずに)-
E, A, +リアクションフォームを開くEmote, reAction
0~9数字に対応したリアクションをする(対応については後述)-
F, Bお気に入りに登録Favorite, Bookmark
Del, Ctrl + D投稿を削除Delete
M, O投稿に対するメニューを開くMore, Other
SCWで隠された部分を表示 or 隠すShow, See
Escフォーカスを外す-
- -## Renoteフォーム - - - - - - - - - -
ショートカット効果由来
EnterRenoteする-
Qフォームを展開するQuote
Escフォームを閉じる-
- -## リアクションフォーム -デフォルトで「👍」にフォーカスが当たっている状態です。 - - - - - - - - - - - - - -
ショートカット効果由来
, K上のリアクションにフォーカスを移動-
, J下のリアクションにフォーカスを移動-
, H, Shift + Tab左のリアクションにフォーカスを移動-
, L, Tab右のリアクションにフォーカスを移動-
Enter, Space, +リアクション確定-
0~9数字に対応したリアクションで確定-
Escリアクションするのをやめる-
diff --git a/src/docs/ug-CN/features/mfm.md b/src/docs/ug-CN/features/mfm.md deleted file mode 100644 index 5be2df4f3..000000000 --- a/src/docs/ug-CN/features/mfm.md +++ /dev/null @@ -1,12 +0,0 @@ -# MFM -MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます。 - -## MFMが使用可能な場所の例 -- ノート本文 -- CW注釈 -- ユーザーの名前 -- ユーザーの自己紹介 - -## 開発者向け情報 -MFMのパーサー実装はライブラリとして公開されており、簡単にクライアントにMFMを組み込むことが可能です。 -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptパーサー実装 diff --git a/src/docs/ug-CN/features/mute-and-block.md b/src/docs/ug-CN/features/mute-and-block.md deleted file mode 100644 index d78a7cea4..000000000 --- a/src/docs/ug-CN/features/mute-and-block.md +++ /dev/null @@ -1,41 +0,0 @@ -# ミュートとブロック -好みではないユーザーがいる場合は、ミュートを行うことでそのユーザーが自分から見えないようにすることができます。 また、より強力な措置として、ブロックを行うことでそのユーザーから自分のコンテンツが見えないようになるほか、自分に対して関わることができないようにすることができます。 ミュートされていることは相手は分かりませんが、ブロックされていることは相手に分かります。どちらを選ぶかはご自身の判断で行ってください。 - -
ℹ️ ミュートとブロックは併用できます。
- -
⚠️ 利用規約に違反するような、迷惑なユーザーがいる場合は運営者に報告することも検討してください。
- -設定>ミュートとブロック から、自分がミュートまたはブロックしているユーザー一覧を確認することができます。 - -## ミュート -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -- タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -- そのユーザーからの通知 -- メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 -- など - -ユーザーをミュートするには、対象のユーザーのユーザーページのメニューを開き、「ミュート」ボタンを押します。 - -
ℹ️ ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。
- -## ブロック -ユーザーをブロックすると、そのユーザーからあなたのコンテンツが見えないようになり、またあなたに対して以下のようなアクションをすることができなくなります。 - -- フォローする -- ユーザーリストに追加する -- 返信する、Renoteする -- リアクションする、アンケートに投票する -- メッセージを送信する -- など - -また、 - -- ブロックする際に既にそのユーザーからフォローされていた場合はフォローが解除されます。 -- ブロックする際に既にそのユーザーがあなたをユーザーリストに入れていた場合はそのリストからあなたが削除されます。 - -ユーザーをブロックするには、対象のユーザーのユーザーページのメニューを開き、「ブロック」ボタンを押します。 - -
⚠️ ブロックを行ったこと自体は相手に通知されませんが、フォローを行ったりなどの上記のアクションが行えなくなるので間接的にブロックされていることは分かります。
- -
⚠️ 相手から自分のコンテンツが見えなくなりますが、相手がアカウントを切り替えたりログアウト状態になれば見ることができます。あくまで簡易的、補助的なものとしてお考えください。
diff --git a/src/docs/ug-CN/features/mute.md b/src/docs/ug-CN/features/mute.md deleted file mode 100644 index 6a9608662..000000000 --- a/src/docs/ug-CN/features/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# ミュート - -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -* タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -* そのユーザーからの通知 -* メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 - -ユーザーをミュートするには、対象のユーザーのユーザーページに表示されている「ミュート」ボタンを押します。 - -ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。 - -設定>ミュート から、自分がミュートしているユーザー一覧を確認することができます。 diff --git a/src/docs/ug-CN/features/note.md b/src/docs/ug-CN/features/note.md deleted file mode 100644 index 305ff626f..000000000 --- a/src/docs/ug-CN/features/note.md +++ /dev/null @@ -1,54 +0,0 @@ -# ノート -ノートは、Misskeyに投稿される、文章、ファイル、アンケートなどを含むコンテンツで、Misskeyの中心的概念です。また、そのノートを作成する行為自体もノートと呼ばれます。 - -ノートが作成されると、[タイムライン](./timeline)に追加され、自分の[フォロワー](./follow)やサーバーのユーザーが見れるようになります。 - -ノートには、[リアクション](./reaction)を行うことができます。また、返信や引用もできます。 - -ノートを[お気に入り](./favorite)登録することで、後で簡単に見返すことができます。 - -## ノートを作成する -ノートを作成するには、画面上にある鉛筆マークのボタンを押して、作成フォームを開きます。作成フォームに内容を入力し、「ノート」ボタンを押すことでノートが作成されます。 ノートには、画像、動画など任意のファイルや、[アンケート](./poll)を添付することができます。また、本文中には[MFM](./mfm)が使用でき、[メンション](./mention)や[ハッシュタグ](./hashtag)を含めることもできます。 他にも、CWや公開範囲といった設定も行えます(詳細は後述)。 -
ℹ️ コンピューターのクリップボードに画像データがある状態で、フォーム内のテキストボックスにペーストするとその画像を添付することができます。
-
ℹ️ テキストボックス内でCtrl + Enterを押すことでも投稿できます。
- -## Renote -既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノートをRenoteと呼びます。 自分がフォローしているユーザーの、気に入ったノートを自分のフォロワーに共有したい場合や、過去の自分のノートを再度共有したい場合に使います。 同じノートに対して無制限にRenoteを行うことができますが、あまり連続して使用すると迷惑になる場合もあるので、注意しましょう。 -
⚠️ 公開範囲がフォロワーやダイレクトのノートはRenoteできません
- -Renoteを削除するには、Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 - -## CW -Contents Warningの略で、ノートの内容を、閲覧者の操作なしには表示しないようにできる機能です。主に長大な内容を隠すためや、ネタバレ防止などに使うことができます。 設定するには、フォームの「内容を隠す」ボタン(目のアイコン)を押します。すると新しい入力エリアが表れるので、そこに内容の要約を記入します。 - -## 公開範囲 -ノートごとに、そのノートが公開される範囲を設定することができます。フォームの「ノート」ボタンの左にあるアイコンを押すと公開範囲を以下から選択できます。 - -### パブリック -全ての人に対してノートが公開されるほか、サーバーの全てのタイムライン(ホームタイムライン、ローカルタイムライン、ソーシャルタイムライン、グローバルタイムライン)にノートが流れます。 -
⚠️ アカウントがサイレンス状態の時は、この公開範囲は使用できません。
- -### ホーム -全ての人に対してノートが公開されますが、フォロワー以外のローカルタイムライン、ソーシャルタイムライン、グローバルタイムラインにはノートは流れません。 - -### フォロワー -自分のフォロワーに対してのみノートを公開します。フォロワーの全てのタイムラインに流れます。 - -### ダイレクト -指定したユーザーに対してのみノートを公開します。指定したユーザーの全てのタイムラインに流れます。 - -### 「ローカルのみ」オプション -このオプションを有効にすると、リモートにノートを連合しなくなります。 - -### 公開範囲の比較 - - - - -
パブリックホームフォロワーダイレクト
フォロワーのLTL/STL/GTL
非フォロワーのLTL/STL/GTL
- -## ピン留め -ノートをピン留めすると、ユーザーページに常にそのノートを表示しておくことができます。 ノートのメニューを開き、「ピン留め」を選択してピン留めできます。 複数のノートをピン留めできます。 - -## ウォッチ -ノートをウォッチすると、自分以外のノートへのリアクションや返信などの通知を受け取ることができます。 ノートのメニューを開き、「ウォッチ」を選択してウォッチできます。 diff --git a/src/docs/ug-CN/features/pages.md b/src/docs/ug-CN/features/pages.md deleted file mode 100644 index a7311b95e..000000000 --- a/src/docs/ug-CN/features/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# Pages - -## 変数 -変数を使うことで動的なページを作成できます。テキスト内で { 変数名 } と書くとそこに変数の値を埋め込めます。例えば Hello { thing } world! というテキストで、変数(thing)の値が ai だった場合、テキストは Hello ai world! になります。 - -変数の評価(値を算出すること)は上から下に行われるので、ある変数の中で自分より下の変数を参照することはできません。例えば上から A、B、C と3つの変数を定義したとき、Cの中でABを参照することはできますが、Aの中でBCを参照することはできません。 - -ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。 - -関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。 diff --git a/src/docs/ug-CN/features/reaction.md b/src/docs/ug-CN/features/reaction.md deleted file mode 100644 index 4d479fd41..000000000 --- a/src/docs/ug-CN/features/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# リアクション -他の人のノートに、絵文字を付けて簡単にあなたの反応を伝えられる機能です。 リアクションするには、ノートの + アイコンをクリックしてピッカーを表示し、絵文字を選択します。 リアクションには[カスタム絵文字](./custom-emoji)も使用できます。 - -## リアクションピッカーのカスタマイズ -ピッカーに表示される絵文字を自分好みにカスタマイズすることができます。 設定の「リアクション」で設定します。 - -## リモート投稿へのリアクションについて -リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。 - -## リモートからのリアクションについて -リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。 diff --git a/src/docs/ug-CN/features/silence.md b/src/docs/ug-CN/features/silence.md deleted file mode 100644 index 7e26feab0..000000000 --- a/src/docs/ug-CN/features/silence.md +++ /dev/null @@ -1,6 +0,0 @@ -# サイレンス -サイレンスは、アカウントに設定される状態のひとつです。 - -アカウントがサイレンス状態になると、ノートの公開範囲をパブリックにできなくなります。 ホーム、フォロワー、ダイレクトは選択可能なため、サイレンスを受けた場合でもフォロワーやあなたのユーザーページを直接訪れた場合は投稿を閲覧できますが、GTL(連合タイムライン)やLTL(ローカルタイムライン)には投稿が流れません。 - -アカウントのサイレンス状態は、サーバーのモデレーターによって有効化/無効化されます。 diff --git a/src/docs/ug-CN/features/theme.md b/src/docs/ug-CN/features/theme.md deleted file mode 100644 index a406f3433..000000000 --- a/src/docs/ug-CN/features/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# テーマ - -テーマを設定して、Misskeyクライアントの見た目を変更できます。 - -## テーマの設定 -設定 > テーマ - -## テーマを作成する -テーマコードはJSON5で記述されたテーマオブジェクトです。 テーマは以下のようなオブジェクトです。 -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... テーマの一意なID。UUIDをおすすめします。 -* `name` ... テーマ名 -* `author` ... テーマの作者 -* `desc` ... テーマの説明(オプション) -* `base` ... 明るいテーマか、暗いテーマか - * `light`にすると明るいテーマになり、`dark`にすると暗いテーマになります。 - * テーマはここで設定されたベーステーマを継承します。 -* `props` ... テーマのスタイル定義。これから説明します。 - -### テーマのスタイル定義 -`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 - -#### バリューで使える構文 -* 16進数で表された色 - * 例: `#00ff00` -* `rgb(r, g, b)`形式で表された色 - * 例: `rgb(0, 255, 0)` -* `rgb(r, g, b, a)`形式で表された透明度を含む色 - * 例: `rgba(0, 255, 0, 0.5)` -* 他のキーの値の参照 - * `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。 - * 例: `@panel` -* 定数(後述)の参照 - * `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。 - * 例: `$main` -* 関数(後述) - * `:{関数名}<{引数}<{色}` - -#### 定数 -「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 キー名を`$`で始めると、そのキーはCSS変数として出力されません。 - -#### 関数 -wip diff --git a/src/docs/ug-CN/features/timeline.md b/src/docs/ug-CN/features/timeline.md deleted file mode 100644 index f431014f8..000000000 --- a/src/docs/ug-CN/features/timeline.md +++ /dev/null @@ -1,31 +0,0 @@ -# タイムライン -タイムラインは、[ノート](./note)が時系列で表示される機能です。 タイムラインには以下で示す種類があり、種類によって表示されるノートも異なります。 なお、タイムラインの種類によってはサーバーにより無効になっている場合があります。 - -## ホーム -自分のフォローしているユーザーの投稿が流れます。HTLと略されます。 - -## ローカル -全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。LTLと略されます。 - -## ソーシャル -自分のフォローしているユーザーの投稿と、全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。STLと略されます。 - -## グローバル -全てのローカルユーザーの「ホーム」指定されていない投稿と、サーバーに届いた全てのリモートユーザーの「ホーム」指定されていない投稿が流れます。GTLと略されます。 - -## 比較 -| ソース | | | タイムライン | | | -| ------------ | ----- | --- | ------ | ----- | ----- | -| ユーザー | 公開範囲 | ホーム | ローカル | ソーシャル | グローバル | -| ローカル (フォロー) | 公開 | ✔ | ✔ | ✔ | ✔ | -| | ホーム | ✔ | | ✔ | | -| | フォロワー | ✔ | ✔ | ✔ | ✔ | -| リモート (フォロー) | 公開 | ✔ | | ✔ | ✔ | -| | ホーム | ✔ | | ✔ | | -| | フォロワー | ✔ | | ✔ | ✔ | -| ローカル (未フォロー) | 公開 | | ✔ | ✔ | ✔ | -| | ホーム | | | | | -| | フォロワー | | | | | -| リモート (未フォロー) | 公開 | | | | ✔ | -| | ホーム | | | | | -| | フォロワー | | | | | diff --git a/src/docs/ug-CN/features/widgets.md b/src/docs/ug-CN/features/widgets.md deleted file mode 100644 index a7c2c1d1d..000000000 --- a/src/docs/ug-CN/features/widgets.md +++ /dev/null @@ -1,7 +0,0 @@ -# ウィジェット -ウィジェットは、MisskeyのUI上に設置できる小型の情報表示、操作が行えるパーツです。 - -ウィジェットを編集するには、ウィジェット編集モードに切り替えます。切り替え方法はUIによって異なります。 ウィジェット編集モードでは、ウィジェットの追加、削除、並び替え、およびそれぞれのウィジェットの設定を行えます。 - -## 利用可能なウィジェット一覧 -todo diff --git a/src/docs/ug-CN/features/word-mute.md b/src/docs/ug-CN/features/word-mute.md deleted file mode 100644 index fa4d14346..000000000 --- a/src/docs/ug-CN/features/word-mute.md +++ /dev/null @@ -1,20 +0,0 @@ -# ワードミュート -ワードミュートの設定をすると、条件に合致したノートが表示されなくなります。 - -ワードミュートには、ソフトワードミュートとハードワードミュートの2種類があります。それぞれについて設定の方法と挙動を説明します。 - -## ソフトワードミュート -ソフトワードミュートは、クライアント(アプリ)側でミュートを判断するワードミュートです。 - -ノートが設定した条件に合致すると、「(ユーザー名)が何かを言いました」という表示で隠れます。 -クリックすると元の通りに表示されます。 - -## ハードワードミュート -ハードワードミュートは、アンテナのようにサーバーが新しいノートの本文に対して条件に合致するかどうか判断し、タイムラインから対象となったノートを除外します。 - -つまり、ハードワードミュートには、以下のような特徴があります。 - -* 条件設定後、新しい投稿のみがミュートの対象になります。 -* 条件を変更しても、過去にハードミュートされたノートはミュートされたままになります。 -* 「○○が何かを言いました」でタイムラインが埋まることがありません。 -* ソフトミュートに非対応のアプリでも、ハードミュートは適用されます。 diff --git a/src/docs/ug-CN/follow.md b/src/docs/ug-CN/follow.md deleted file mode 100644 index 3c1ea7bbe..000000000 --- a/src/docs/ug-CN/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# フォロー -ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。 diff --git a/src/docs/ug-CN/general/apps.md b/src/docs/ug-CN/general/apps.md deleted file mode 100644 index 1f4c85fe8..000000000 --- a/src/docs/ug-CN/general/apps.md +++ /dev/null @@ -1,6 +0,0 @@ -# サードパーティアプリのリスト -## クライアント -todo - -## 連携サービス -todo diff --git a/src/docs/ug-CN/general/changelog.md b/src/docs/ug-CN/general/changelog.md deleted file mode 100644 index 6766a63b2..000000000 --- a/src/docs/ug-CN/general/changelog.md +++ /dev/null @@ -1,5 +0,0 @@ -# 更新履歴 -
ℹ️ このサーバーの更新履歴です。Misskeyの最新のリリースについては、GitHubをご確認ください。
- - - diff --git a/src/docs/ug-CN/general/faq.md b/src/docs/ug-CN/general/faq.md deleted file mode 100644 index c272b2ad4..000000000 --- a/src/docs/ug-CN/general/faq.md +++ /dev/null @@ -1,28 +0,0 @@ -# よくある質問 -ここでは利用上のよくある質問について掲載しています。 Misskeyのプロジェクト自体についてのよくある質問は[こちら](./misskey)に掲載されています。 - -## iOS/Androidのアプリはありますか? -公式にはそういったOSのネイティブアプリを開発していませんが、サードパーティ製のアプリがいくつかあります。 詳しくは[こちら](./apps)をご覧ください。 - -ただ、サードパーティ製アプリはどうしても機能への対応が遅れてしまうため、とくに拘りがなければ公式のWebクライアントの利用をおすすめします。 なお、MisskeyのWebクライアントはPWAに対応しているので、ネイティブアプリのように動作させることも可能です。 詳しくは[こちら](todo)をご覧ください。 - -## Mastodonクライアントでログインできないのですが? -MisskeyはMastodonのAPIと互換性がないため、一部を除きMastodonクライアントでMisskeyを利用することはできません。 - -## 他のサーバーのユーザーをフォローするときは? -メニューから検索を選び、ユーザー名をホスト込みで入力します。例: `@syuilo@misskey.io` - -## Renoteを削除するには? -Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 Renoteについては[こちら](../features/note)をご確認ください。 - -## URLのプレビューを表示させたくない -MFMには、そのURLのプレビューを無効にする構文があります。詳細は[MFMチートシート](/mfm-cheat-sheet)をご確認ください。 - -## カスタム絵文字を追加したい -運営者のみがカスタム絵文字を追加、編集、削除できます。それらを希望する場合は運営者に依頼してください。 - -## Botを開発したい -Misskey APIを利用してBotの開発が可能です。[こちら](../advanced/develop-bot)をご確認ください。 - -## ノートの翻訳機能はどのサービスを使用していますか? -[DeepL](https://www.deepl.com/)を使用しています。 diff --git a/src/docs/ug-CN/general/glossary.md b/src/docs/ug-CN/general/glossary.md deleted file mode 100644 index bb8a24336..000000000 --- a/src/docs/ug-CN/general/glossary.md +++ /dev/null @@ -1,89 +0,0 @@ -# 用語集 -Misskeyに関する用語集です。 - -## ActivityPub -(読み: あくてぃびてぃぱぶ) 分散型を実現するために用いられるプロトコル(仕様)。このプロトコルに則ってサーバー同士通信を行うことで、連合が行われ、Fediverseを形成しています。 - -## AiScript -(読み: あいすくりぷと) Misskey上で使用できるプログラミング言語です。詳細は[こちら。](../advanced/aiscript) - -## API -(読み: えーぴーあい) Misskeyのサーバーが公開している、プログラムからMisskeyを扱うためのインターフェース。詳細は[こちら。](../advanced/api) - -## Bot -(読み: ぼっと) プログラムによって動作しているアカウント。 - -## CW -(読み: こんてんつわーにんぐ) Contents Warningの略。ノートの内容を、操作なしには表示しないようにできる機能。主に長大な内容を隠すためや、ネタバレ防止などに使われます。 - -## Fediverse -(読み: ふぇでぃばーす) Misskeyを含む様々な分散型ソフトウェアのサーバーで構成されたネットワーク。 - -## GTL -グローバルタイムライン(Global TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## HTL -ホームタイムライン(Home TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## LTL -ローカルタイムライン(Local TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## MFM -(読み: えむえふえむ) Misskey Flavored Markdownの略で、Misskey上で使用できるマークアップ言語です。詳細は[こちら。](../features/mfm) - -## NSFW -(読み: のっとせーふふぉーわーく) Not Safe For Workの略。画像を「閲覧注意」扱いにし、操作なしには表示しないようにすることができる機能。 - -## Renote -(読み: りのーと) 既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノート。詳細は[こちら。](../features/note) - -## STL -ソーシャルタイムライン(Social TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## 藍 -(読み: あい) Misskeyの看板娘(公式キャラクター)です。 - -## アクティブユーザー -インスタンスにアカウントを作っているユーザーのうち、現在も実際にサービスを利用しているユーザーのこと。 - -## インスタンス -todo - -## カスタム絵文字 -サーバーで用意された絵文字。カスタム絵文字ではない通常の絵文字は「Unicode絵文字」と区別して呼ばれる。 - -## コントロールパネル -インスタンスの設定画面のこと。 - -## サーバー -todo - -## サイレンス -ノートをパブリックな公開範囲で投稿できなくされている状態。モデレーターの判断でユーザーごとに設定されます。詳細は[こちら。](../features/silence) - -## ジョブキュー -アクティビティ配送などを順番に行うためのシステム。 - -## 凍結 -アカウントが使用不可に設定されている状態。 - -## ドライブ -Misskeyにアップロードしたファイルを管理する機能。詳細は[こちら。](../features/drive) - -## ノート -Misskeyに投稿される、文章、ファイル、アンケートなどを含めることができるコンテンツ。詳細は[こちら。](../features/note) - -## ミスキスト -Misskeyを使う人のこと。 - -## モデレーター -スパムの凍結およびサイレンスや不適切な投稿の削除など、コミュニティ運営に関する権限を持つユーザー。 - -## リモート -他サーバーのことを指します。リモートユーザーといったように接頭辞としても使われます。ローカルの逆です。 - -## 連合 -サーバー上で作成された情報が他のサーバーに伝わること。 - -## ローカル -自サーバーのことを指します。ローカルユーザー、ローカルタイムラインといったように接頭辞としても使われます。リモートの逆です。 diff --git a/src/docs/ug-CN/general/links.md b/src/docs/ug-CN/general/links.md deleted file mode 100644 index 5ce5e1ddb..000000000 --- a/src/docs/ug-CN/general/links.md +++ /dev/null @@ -1,12 +0,0 @@ -# リンク集 - -## Webサイト -- [Official Discord](https://discord.gg/Wp8gVStHW3) - Misskey公式Discordサーバー -- [Misskey Forum](https://forum.misskey.io/) - Misskeyに関する話題を扱うフォーラム - -## アカウント -- [@repo@misskey.io](https://misskey.io/@repo) - Misskeyのリポジトリの更新を投稿するbot - -## ライブラリ -- [misskey-dev/misskey.js](https://github.com/misskey-dev/misskey.js) - JavaScriptのMisskey SDK -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptのMFMパーサー実装 diff --git a/src/docs/ug-CN/general/misskey.md b/src/docs/ug-CN/general/misskey.md deleted file mode 100644 index d97664ddc..000000000 --- a/src/docs/ug-CN/general/misskey.md +++ /dev/null @@ -1,87 +0,0 @@ -# Misskeyについて - -Misskeyはオープンソースの分散型マイクロブログプラットフォームプロジェクトです。 開発は日本でsyuiloによって2014年から開始されました。 ドライブ、リアクションなどの豊富な機能や、高いカスタマイズ性を備えたUIを持つことが特徴です。 - -## 歴史 -開発当初は掲示板がメインのサービスでしたが、ユーザーが短文を投稿し、それを時系列で流れるタイムライン機能を追加したところ人気が高まり、徐々にそれがメインとして開発が進むようになりました。 当初は分散型ではありませんでしたが、2018年にActivityPubを実装し分散型になったことで、より多くの方に認知され利用されるサービスになり、現在に至ります。 -
ℹ️ Misskeyという名前は、syuiloが当時聴いていたMay'nというアーティストの楽曲、Brain Diverの歌詞に由来します。
- -誰でも開発に参加することができ、現在でも活発に開発が続いています。 - -## 分散型とは何か? - -分散(distributed)型とは、非中央集権(decentralized)とも呼ばれ、コミュニティが多数のサーバーに分散して存在し、それらが相互に通信(連合、federation)することでコンテンツ共有ネットワーク(Fediverse)を形成していることが特徴のサービスです。 単一のサーバーしか存在しない、もしくは複数存在しても互いに独立している場合は中央集権なサービスと言われ、例えばTwitterやFacebookなどほとんどのサービスがそれに該当します。 分散型のメリットは、自分に合った運営者やテーマのサーバーを選択できることです。自分でサーバーを作成することもできます。連合するおかげで、どのサーバーを選んでも、同じコミュニティにアクセスできます。 - -## 常にオープンソース -Misskeyはこれまでもこれからも、オープンソースであり続けます。オープンソースとは、簡単に言うとソフトウェアのソースコード(プログラム)が公開されていることです。ソースコードの修正や再配布が可能であることを定義に含めることもあります。 Misskeyのすべてのソースコードは[AGPL](https://github.com/misskey-dev/misskey/blob/develop/LICENSE)というオープンソースライセンスの下に[公開](https://github.com/misskey-dev)されていて、誰でも自由に閲覧、使用、修正、改変、再配布をすることができます。 オープンソースは、自分で好きなように変えたり、有害な処理が含まれていないことを確認することができたり、誰でも開発に参加できるなどの、様々なメリットがあります。 上述の分散型を実現するためにも、オープンソースであるということは必要不可欠な要素です。 再び引き合いに出しますが、TwitterやFacebookなどの利益を得ているほとんどのサービスはオープンソースではありません。 - -
ℹ️ 技術的に言うと、MisskeyのソースコードはGitで管理されていて、リポジトリはGitHub上でホスティングされています。
- -## 開発に参加する、プロジェクトを支援する -Misskeyを気に入っていただけたら、ぜひプロジェクトを支援してください。プロジェクトに貢献するには、以下で紹介するようにいろいろな方法があります。方法によっては開発のスキルは不要なので、誰でも気軽に参加し貢献することができます。いつでもお待ちしています。 - -### 機能を追加したり、バグを修正する -ソフトウェアエンジニアのスキルをお持ちの方であれば、ソースコードを編集する形でプロジェクトに貢献することができます。 貢献についてのガイドは[こちら](https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md)です。 - -### 議論に参加する -新しい機能、または既存の機能について意見を述べたり、不具合を報告したりすることでも貢献できます。 そのようなディスカッションは[GitHub](https://github.com/misskey-dev)上か、[フォーラム](https://forum.misskey.io/)等で行われます。 - -### テキストを翻訳する -Misskeyは様々な言語に対応しています(i18n -internationalizationの略- と呼ばれます)。元の言語は基本的に日本語ですが、有志によって他の言語へと翻訳されています。 その翻訳作業に加わっていただくことでもMisskeyに貢献できます。 Misskeyは[Crowdinというサービスを使用して翻訳の管理を行っています。](https://crowdin.com/project/misskey) - -### 感想を投稿する -不具合報告等だけではなく、Misskeyの良い点、楽しい点といったポジティブな意見もぜひ共有してください。開発の励みになり、それは間接的ですがプロジェクトへの貢献です。 - -### ミスキストを増やす -ミスキストとは、Misskeyを使用する人のことです。 知り合いに紹介するなどしてMisskeyを広めていただければ、ミスキストが増え開発のモチベーションが上がります。 - -### 寄付をする -Misskeyはビジネスではなく、利用は無料であるため、収益は皆様からの寄付のみです。(インスタンスによっては広告収入を得ているような場合もありますが、それは運営者の収入であり直接開発者への収入にはなりません) 寄付をしていただければ、今後も開発を続けることが可能になり、プロジェクトへの貢献になります。 寄付は基本的には[Patreon](https://www.patreon.com/syuilo)で受け付けています。 一定額寄付していただけると、Misskeyの[情報ページ](/about-misskey)に名前を記載することができます。 - -また、サーバーの運営者も、基本的には収益を得ていません。サーバーの運営にはコストがかかるので、運営者の支援をすることもご検討ください。 開発には直接関係しませんが、サーバーがあってこそのプロジェクトなので、運営が維持されるというのは開発と同じくらい重要なことです。 - -## クレジット -Misskeyの開発者や、Misskeyに寄付をしてくださった方の一覧は[こちら](/about-misskey)で見ることができます。 - -## よくある質問 -### プロジェクトは何を目指していますか? -強いて言うと、漠然的になりますが広く使われる汎用的なプラットフォームになることを目指しています。 Misskeyは他のプロジェクトとは違い、何らかの思想(例えば、反中央集権)やビジョンに基づいて開発が行われているわけではなく、その点ではフラットです。 それが逆に、特定の方向性に縛られないフレキシブルさを生み出すことに繋がっていると感じています。 - - -### 企業によって開発されていますか? -いいえ。Misskeyの開発は個人で行われており、商業的でもないため、特定の企業の関りはありません。 開発メンバーも基本的にはボランティアです。 また、開発に対し企業のスポンサーがつくこともありますが、その場合でもやはり開発は個人のコミュニティが主体です。 - -### 誰が運営していますか? -Misskeyは分散型なため、各サーバーにそれぞれ異なった運営者がいます。従って、特定の個人や企業によって、Misskeyの全てが運営されているわけではありません。 また、開発チームが運営を行うわけでもないため、運営に関する連絡は、お使いのサーバーの運営者に行ってください。 サーバーの運営者は、[このページ](/about)で確認することができます。 あなたがサーバーを作成すれば、あなたが運営者になります。 - -### どのサーバーを選べばいいですか? -[サーバー一覧が公開されています。](https://join.misskey.page/ja-JP/instances) サーバーによってコミュニティのテーマ(特定のこと、ものが好き 等)が決められている場合があるので、自分に合ったテーマのサーバーがあれば、そこを選ぶと良いかもしれません。 他にも、サーバーの規模、ユーザー層、国および言語、運営者が信頼できるかどうか、などの観点があります。 なお、Misskey公式のサーバーというものはありません。自身で新しくサーバーを作成するという選択肢もあります。 - -基本的にどのサーバーを選んだとしても、他の全てのサーバーのユーザーと繋がることができます。 - -### サーバーを建てるにはどうしたらいいですか? -Misskeyサーバーの作成に興味を持っていただきありがとうございます。 2021年現在、Misskeyのホスティングサービスは存在しないため、サーバーの作成にはある程度の知識が必要です。 サーバーの作成方法については[こちら](todo)をご覧ください。 - -### どのような技術を使用していますか? -Misskeyは開発が進むにつれ使用する技術も大きく変わってきました。開発当初はMySQL + PHP + jQueryといった構成でしたが、現在は以下のようになっています。 -- サーバーサイド: Node.js -- データベース: PostgreSQL、Redis -- UIフレームワーク: Vue.js -- プログラミング言語: TypeScript - -また、MFMやAiScriptなどの、Misskeyから派生して独自の技術も開発しています。 - -### Mastodonのフォークですか? -いいえ。MisskeyはMastodonやその他のプロジェクトとは全く別のプロジェクトです。 開発に関しても、Misskeyの方が昔から開発されています。ただし、分散型になったのはMastodonの登場より後です。 同じActivityPubという分散のためのプロトコルを実装しているという点以外、両者に特に関りがあるわけでもありません。 - -### iOS/Androidのアプリはありますか? -公式にはそういったOSのネイティブアプリを開発していませんが、サードパーティ製のアプリがいくつかあります。 詳しくは[こちら](./apps)をご覧ください。 - -ただ、サードパーティ製アプリはどうしても機能への対応が遅れてしまうため、とくに拘りがなければ公式のWebクライアントの利用をおすすめします。 なお、MisskeyのWebクライアントはPWAに対応しているので、ネイティブアプリのように動作させることも可能です。 詳しくは[こちら](todo)をご覧ください。 - -### Misskeyのロゴ、アイコンはどこで入手できますか? -(準備中) - -### 時折目にする猫耳の可愛い女の子は? -Misskeyの守り神、藍ちゃんです。アイチャンカワイイヤッター! -
ℹ️ 藍ちゃんについてはこちらです。
diff --git a/src/docs/ug-CN/general/report-issue.md b/src/docs/ug-CN/general/report-issue.md deleted file mode 100644 index 63527e32a..000000000 --- a/src/docs/ug-CN/general/report-issue.md +++ /dev/null @@ -1,8 +0,0 @@ -# 不具合の報告 -不具合と思われる状況に遭遇したときは、まず[トラブルシューティング](./troubleshooting)をご一読ください。 それでも問題が解決しないときは、以下の情報を含めて[フォーラム](https://forum.misskey.io/)に投稿してください。 投稿することで、解決策が見つかったり、不具合と判断されれば開発チームによって修正が行われます。 - -## 含める情報 -- Misskeyのバージョン([情報ページ](/about)で確認できます) -- お使いのブラウザの種類とバージョン -- お使いのOSの種類とバージョン -- 問題の再現手順 diff --git a/src/docs/ug-CN/general/troubleshooting.md b/src/docs/ug-CN/general/troubleshooting.md deleted file mode 100644 index f895b4984..000000000 --- a/src/docs/ug-CN/general/troubleshooting.md +++ /dev/null @@ -1,40 +0,0 @@ -# トラブルシューティング -
ℹ️ よくある質問も合わせてお役立てください。
- -問題が発生したときは、まずこちらをご確認ください。 該当する項目が無い、もしくは手順を試しても効果がない場合は、サーバーの管理者に連絡するか[不具合を報告](./report-issue)してください。 - -## クライアントが起動しない -ほとんどの場合、お使いのブラウザまたはOSのバージョンが古いことが原因です。 ブラウザおよびOSのバージョンを最新のものに更新してから、再度試してみてください。 - -これは稀ですが、それでも起動しない場合は、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。 - -## ページが読み込めない -クライアントが起動するもののページが読み込めないというエラーが出る場合は、ネットワークに問題がないか確認してください。また、サーバーがダウンしていないか確認してください。 - -これは稀ですが、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。 - -まだ問題がある場合は、サーバーの問題と思われるのでサーバーの管理者に連絡してください。 - -## クライアントの動作が遅い -以下を試してみてください: - -- クライアント設定で「UIのアニメーションを減らす」を有効にする -- クライアント設定で「モーダルにぼかし効果を使用」を無効にする -- お使いのブラウザの設定でハードウェアアクセラレーションを有効にする -- お使いのデバイスのスペックを上げる - -## UIの一部の表示がおかしい(背景が透明になっている等) -アップデートによりUIの改修が行われたときに、テーマのキャッシュシステムの影響でそのような表示になることがあります。 クライアントの設定の「キャッシュをクリア」すると直ります。 -
⚠️ 「クライアントの」キャッシュクリアです。「ブラウザの」キャッシュクリアは行わないでください。
- -## 通知やアンテナ等の点滅が消えない -点滅は、未読のコンテンツがあることを示しています。通常点滅が消えない場合は、コンテンツを遡ると未読なコンテンツが残っています。 すべて既読にしたと思われるのに、それでもなお点滅が続く場合(おそらく不具合と思われます)は設定から強制的にすべて既読扱いにすることができます。 - -## Renoteができない -フォロワー限定のノートはRenoteすることはできません。 - -## UI上で特定の要素が表示されない -広告ブロッカーを使用しているとそのような不具合が発生することがあります。Misskeyではオフにしてご利用ください。 - -## UI上で未翻訳の部分がある -ほとんどの場合、単に翻訳が間に合っていないだけで、不具合ではありません。翻訳が終わるまでお待ちください。 [翻訳に参加](./misskey)していただくことも可能です。 diff --git a/src/docs/ug-CN/keyboard-shortcut.md b/src/docs/ug-CN/keyboard-shortcut.md deleted file mode 100644 index 04ba792aa..000000000 --- a/src/docs/ug-CN/keyboard-shortcut.md +++ /dev/null @@ -1,68 +0,0 @@ -# キーボードショートカット - -## グローバル -これらのショートカットは基本的にどこでも使えます。 - - - - - - - - - - - -
ショートカット効果由来
P, N新規投稿Post, New, Note
Tタイムラインの最も新しい投稿にフォーカスTimeline, Top
Shift + N通知を表示/隠すNotifications
SئىزدەشSearch
H, ?ヘルプを表示Help
- -## 投稿にフォーカスされた状態 - - - - - - - - - - - - - - - - - - - -
ショートカット効果由来
, K, Shift + Tab上の投稿にフォーカスを移動-
, J, Tab下の投稿にフォーカスを移動-
R返信フォームを開くReply
QRenoteフォームを開くQuote
Ctrl + Q即刻Renoteする(フォームを開かずに)-
E, A, +リアクションフォームを開くEmote, reAction
0~9数字に対応したリアクションをする(対応については後述)-
F, Bお気に入りに登録Favorite, Bookmark
Del, Ctrl + D投稿を削除Delete
M, O投稿に対するメニューを開くMore, Other
SCWで隠された部分を表示 or 隠すShow, See
Escフォーカスを外す-
- -## Renoteフォーム - - - - - - - - - - -
ショートカット効果由来
EnterRenoteする-
Qフォームを展開するQuote
Escフォームを閉じる-
- -## リアクションフォーム -デフォルトで「👍」にフォーカスが当たっている状態です。 - - - - - - - - - - - - - -
ショートカット効果由来
, K上のリアクションにフォーカスを移動-
, J下のリアクションにフォーカスを移動-
, H, Shift + Tab左のリアクションにフォーカスを移動-
, L, Tab右のリアクションにフォーカスを移動-
Enter, Space, +リアクション確定-
0~9数字に対応したリアクションで確定-
Escリアクションするのをやめる-
diff --git a/src/docs/ug-CN/mfm.md b/src/docs/ug-CN/mfm.md deleted file mode 100644 index e237287ac..000000000 --- a/src/docs/ug-CN/mfm.md +++ /dev/null @@ -1,2 +0,0 @@ -# MFM -MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます。 diff --git a/src/docs/ug-CN/mute.md b/src/docs/ug-CN/mute.md deleted file mode 100644 index 6a9608662..000000000 --- a/src/docs/ug-CN/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# ミュート - -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -* タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -* そのユーザーからの通知 -* メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 - -ユーザーをミュートするには、対象のユーザーのユーザーページに表示されている「ミュート」ボタンを押します。 - -ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。 - -設定>ミュート から、自分がミュートしているユーザー一覧を確認することができます。 diff --git a/src/docs/ug-CN/pages.md b/src/docs/ug-CN/pages.md deleted file mode 100644 index a7311b95e..000000000 --- a/src/docs/ug-CN/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# Pages - -## 変数 -変数を使うことで動的なページを作成できます。テキスト内で { 変数名 } と書くとそこに変数の値を埋め込めます。例えば Hello { thing } world! というテキストで、変数(thing)の値が ai だった場合、テキストは Hello ai world! になります。 - -変数の評価(値を算出すること)は上から下に行われるので、ある変数の中で自分より下の変数を参照することはできません。例えば上から A、B、C と3つの変数を定義したとき、Cの中でABを参照することはできますが、Aの中でBCを参照することはできません。 - -ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。 - -関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。 diff --git a/src/docs/ug-CN/reaction.md b/src/docs/ug-CN/reaction.md deleted file mode 100644 index c26ead75b..000000000 --- a/src/docs/ug-CN/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# リアクション -他の人のノートに、絵文字を付けて簡単にあなたの反応を伝えられる機能です。 リアクションするには、ノートの + アイコンをクリックしてピッカーを表示し、絵文字を選択します。 リアクションには[カスタム絵文字](./custom-emoji)も使用できます。 - -## リアクションピッカーのカスタマイズ -ピッカーに表示される絵文字を自分好みにカスタマイズすることができます。 設定の「リアクション」で設定します。 - -## リモート投稿へのリアクションについて -リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。 また、相手がMisskeyであったとしても、カスタム絵文字リアクションは伝わらず、自動的に「👍」等にフォールバックされます。 - -## リモートからのリアクションについて -リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。 diff --git a/src/docs/ug-CN/reversi-bot.md b/src/docs/ug-CN/reversi-bot.md deleted file mode 100644 index 7ab2a7212..000000000 --- a/src/docs/ug-CN/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# MisskeyリバーシBotの開発 -Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。 - -1. `games/reversi`ストリームに以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - -2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる - * イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている - -3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する - -4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - * `game`: `game`の`id` - -5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う - -6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する - -7. ゲームが開始すると、`started`イベントが流れてくる - * イベントの中身にはゲーム情報が含まれている - -8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述) - -9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる - * `color`として石の色が含まれている - * `pos`として位置情報が含まれている - -## 位置の計算法 -8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### X,Y座標 から インデックス に変換する -``` -pos = x + (y * mapWidth) -``` -`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます: -``` -mapWidth = map[0].length -``` - -### インデックス から X,Y座標 に変換する -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## マップ情報 -マップ情報は、ゲーム情報の`map`に入っています。 文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 それをもとにマップのデザインを知る事が出来ます: -* `(スペース)` ... マス無し -* `-` ... マス -* `b` ... 初期配置される黒石 -* `w` ... 初期配置される白石 - -例えば、4*4の次のような単純なマップがあるとします: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -この場合、マップデータはこのようになります: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## ユーザーにフォームを提示して対話可能Botを作成する -ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。 - -フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します: -```javascript -{ - type: 'init-form', - body: [フォームコントロールの配列] -} -``` - -フォームコントロールの配列については今から説明します。 フォームコントロールは、次のようなオブジェクトです: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... コントロールのID。 `type` ... コントロールの種類。後述します。 `label` ... コントロールと一緒に表記するテキスト。 `value` ... コントロールのデフォルト値。 - -### フォームの操作を受け取る -ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### フォームコントロールの種類 -#### スイッチ -type: `switch` スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。 - -##### プロパティ -`label` ... スイッチに表記するテキスト。 - -#### ラジオボタン -type: `radio` ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。 - -##### プロパティ -`items` ... ラジオボタンの選択肢。例: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '強', - value: 3 -}] -``` - -#### スライダー -type: `slider` スライダーを表示します。 - -##### プロパティ -`min` ... スライダーの下限。 `max` ... スライダーの上限。 `step` ... 入力欄で刻むステップ値。 - -#### テキストボックス -type: `textbox` テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。 - -## ユーザーにメッセージを表示する -設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 メッセージを表示するには、次のメッセージをストリームに送信します: -```javascript -{ - type: 'message', - body: { - text: 'メッセージ内容', - type: 'メッセージの種類' - } -} -``` -メッセージの種類: `success`, `info`, `warning`, `error`。 - -## 投了する -投了をするには、このエンドポイントにリクエストします。 diff --git a/src/docs/ug-CN/stream.md b/src/docs/ug-CN/stream.md deleted file mode 100644 index 9011c37c5..000000000 --- a/src/docs/ug-CN/stream.md +++ /dev/null @@ -1,354 +0,0 @@ -# ストリーミングAPI - -ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。 - -## ストリームに接続する - -ストリーミングAPIを利用するには、まずMisskeyサーバーに**websocket**接続する必要があります。 - -以下のURLに、`i`というパラメータ名で認証情報を含めて、websocket接続してください。例: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。 - -
-

認証情報の取得については、こちらのドキュメントをご確認ください。

-
- ---- - -認証情報は省略することもできますが、その場合非ログインでの利用ということになり、受信できる情報や可能な操作は限られます。例: - -``` -%WS_URL%/streaming -``` - ---- - -ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。 - -**ストリームでのやり取りはすべてJSONです。** - -## チャンネル -MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。 - -### チャンネルに接続する -チャンネルに接続するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -ここで、 -* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。 -* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。 -* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。 - -
-

IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。

-
- -### チャンネルからのメッセージを受け取る -例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。 - -チャンネルがメッセージを発すると、次のようなデータがJSONでストリームに流れてきます: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。 -* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。 -* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。 - -### チャンネルに向けてメッセージを送信する -チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。 - -チャンネルにメッセージを送信するには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。 -* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。 -* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。 - -### チャンネルから切断する -チャンネルから切断するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。 - -## ストリームを経由してAPIリクエストする - -ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。 - -ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -ここで、 -* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 -* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 -* `data`には、エンドポイントのパラメータを含めます。 - -
-

APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。

-
- -### レスポンスの受信 - -APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。 - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -ここで、 -* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 -* `body`には、レスポンスが含まれています。 - -## 投稿のキャプチャ - -Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。 - -例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。 - -しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。 - -この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。 - -### 投稿をキャプチャする - -投稿をキャプチャするには、ストリームに次のようなメッセージを送信します: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャしたい投稿の`id`を設定します。 - -このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 - -例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -ここで、 -* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。 -* `body`内の`type`に、イベントの種類が設定されます。 -* `body`内の`body`に、イベントの詳細が設定されます。 - -#### イベントの種類 - -##### `reacted` -その投稿にリアクションがされた時に発生します。 - -* `reaction`に、リアクションの種類が設定されます。 -* `userId`に、リアクションを行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -その投稿が削除された時に発生します。 - -* `deletedAt`に、削除日時が設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -その投稿に添付されたアンケートに投票された時に発生します。 - -* `choice`に、選択肢IDが設定されます。 -* `userId`に、投票を行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### 投稿のキャプチャを解除する - -その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。 - -次のメッセージを送信します: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャを解除したい投稿の`id`を設定します。 - -このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 - -# チャンネル一覧 -## `main` -アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `renote` -自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。 - -#### `mention` -誰かからメンションされたときに発生するイベントです。 - -#### `readAllNotifications` -自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。 - -#### `meUpdated` -自分の情報が更新されたことを表すイベントです。 - -#### `follow` -自分が誰かをフォローしたときに発生するイベントです。 - -#### `unfollow` -自分が誰かのフォローを解除したときに発生するイベントです。 - -#### `followed` -自分が誰かにフォローされたときに発生するイベントです。 - -## `homeTimeline` -ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -タイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `localTimeline` -ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `hybridTimeline` -ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ソーシャルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `globalTimeline` -グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 diff --git a/src/docs/ug-CN/theme.md b/src/docs/ug-CN/theme.md deleted file mode 100644 index a406f3433..000000000 --- a/src/docs/ug-CN/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# テーマ - -テーマを設定して、Misskeyクライアントの見た目を変更できます。 - -## テーマの設定 -設定 > テーマ - -## テーマを作成する -テーマコードはJSON5で記述されたテーマオブジェクトです。 テーマは以下のようなオブジェクトです。 -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... テーマの一意なID。UUIDをおすすめします。 -* `name` ... テーマ名 -* `author` ... テーマの作者 -* `desc` ... テーマの説明(オプション) -* `base` ... 明るいテーマか、暗いテーマか - * `light`にすると明るいテーマになり、`dark`にすると暗いテーマになります。 - * テーマはここで設定されたベーステーマを継承します。 -* `props` ... テーマのスタイル定義。これから説明します。 - -### テーマのスタイル定義 -`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 - -#### バリューで使える構文 -* 16進数で表された色 - * 例: `#00ff00` -* `rgb(r, g, b)`形式で表された色 - * 例: `rgb(0, 255, 0)` -* `rgb(r, g, b, a)`形式で表された透明度を含む色 - * 例: `rgba(0, 255, 0, 0.5)` -* 他のキーの値の参照 - * `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。 - * 例: `@panel` -* 定数(後述)の参照 - * `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。 - * 例: `$main` -* 関数(後述) - * `:{関数名}<{引数}<{色}` - -#### 定数 -「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 キー名を`$`で始めると、そのキーはCSS変数として出力されません。 - -#### 関数 -wip diff --git a/src/docs/ug-CN/timelines.md b/src/docs/ug-CN/timelines.md deleted file mode 100644 index 36ba61bd2..000000000 --- a/src/docs/ug-CN/timelines.md +++ /dev/null @@ -1,15 +0,0 @@ -# タイムラインの比較 - -https://docs.google.com/spreadsheets/d/1lxQ2ugKrhz58Bg96HTDK_2F98BUritkMyIiBkOByjHA/edit?usp=sharing - -## ホーム -自分のフォローしているユーザーの投稿 - -## ローカル -全てのローカルユーザーの「ホーム」指定されていない投稿 - -## ソーシャル -自分のフォローしているユーザーの投稿と、全てのローカルユーザーの「ホーム」指定されていない投稿 - -## グローバル -全てのローカルユーザーの「ホーム」指定されていない投稿と、サーバーに届いた全てのリモートユーザーの「ホーム」指定されていない投稿 diff --git a/src/docs/uk-UA/admin/disable-timelines.md b/src/docs/uk-UA/admin/disable-timelines.md deleted file mode 100644 index b081e35ab..000000000 --- a/src/docs/uk-UA/admin/disable-timelines.md +++ /dev/null @@ -1,8 +0,0 @@ -# LTL/STL/GTLの無効化 -Misskeyでは、LTL/STL/GTLをそれぞれ無効化することができます。有効/無効を切り替えるには、インスタンスコントロールパネルで設定します。 - -LTLやSTLは、そのインスタンス全員の投稿が見れるため、新規のユーザーにとってはユーザーを探す必要がなくなり、興味のあるユーザーを見つけやすいという利点があります。 しかし同時に、フォロー機能が活用されなくなったり、不適切な投稿が目につきやすくなったり、チャットのようになることで内輪感が生じて逆に新規ユーザーが参加しにくくなるといったデメリットも持ち合わせています。 サーバーによってメリット/デメリットどちらが優勢かは異なるので、オプションとして無効にできるようになっています。 もしデメリットの方が上回っていると感じたら、それらのタイムラインを無効化することも検討してください。 - -
⚠️ 無効化を行うと、ユーザーが困惑し、短期的に見て利用者が減る可能性があります。そのため、無効化の際は影響を慎重に検討し、事前に説明してフォローを整える期間を一定程度設けることを推奨します。
- -なお、管理者/モデレーターは、これらのタイムラインの無効化状態は適用されず、引き続き利用することが可能です。 diff --git a/src/docs/uk-UA/admin/faq.md b/src/docs/uk-UA/admin/faq.md deleted file mode 100644 index 317b4e065..000000000 --- a/src/docs/uk-UA/admin/faq.md +++ /dev/null @@ -1,5 +0,0 @@ -# よくある質問 -ここでは、サーバー管理者向けのよくある質問を掲載しています。 - -## デフォルトテーマを設定したい -現在、デフォルトテーマ設定機能は実装されていません。 diff --git a/src/docs/uk-UA/advanced/aiscript.md b/src/docs/uk-UA/advanced/aiscript.md deleted file mode 100644 index 604d17daa..000000000 --- a/src/docs/uk-UA/advanced/aiscript.md +++ /dev/null @@ -1,7 +0,0 @@ -# AiScript -AiScriptは、Misskeyで使用できるスクリプト言語です。 - -
ℹ️ AiScript実装はMisskeyとは別リポジトリで、オープンソースで公開されています。
- -## 使い方 -AiScriptの構文や組み込み関数などのドキュメントは、[こちら](https://github.com/syuilo/aiscript/tree/master/docs)で公開されています。 diff --git a/src/docs/uk-UA/advanced/api.md b/src/docs/uk-UA/advanced/api.md deleted file mode 100644 index 76019b614..000000000 --- a/src/docs/uk-UA/advanced/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス、Bot等(以下「アプリケーション」と呼びます)を開発できます。 ストリーミングAPIもあるので、リアルタイム性のあるアプリケーションを作ることも可能です。 - -APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。 - -## アクセストークンの取得 -基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。 - -* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む -* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む - -### 自分自身のアクセストークンを手動発行する -「設定 > API」で、自分のアクセストークンを発行できます。 - -[「APIの使い方」へ進む](#APIの使い方) - -### アプリケーション利用者にアクセストークンの発行をリクエストする -アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。 - -#### Step 1 - -UUIDを生成する。以後これをセッションIDと呼びます。 - -> このセッションIDは毎回生成し、使いまわさないようにしてください。 - -#### Step 2 - -`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。 -> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます: -* `name` ... アプリケーション名 - * > 例: `MissDeck` -* `icon` ... アプリケーションのアイコン画像URL - * > 例: `https://missdeck.example.com/icon.png` -* `callback` ... 認証が終わった後にリダイレクトするURL - * > 例: `https://missdeck.example.com/callback` - * リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます -* `permission` ... アプリケーションが要求する権限 - * > 例: `write:notes,write:following,read:drive` - * 要求する権限を`,`で区切って列挙します - * どのような権限があるかは[APIリファレンス](/api-doc)で確認できます - -#### Step 3 -ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。 - -レスポンスに含まれるプロパティ: -* `token` ... ユーザーのアクセストークン -* `user` ... ユーザーの情報 - -[「APIの使い方」へ進む](#APIの使い方) - -## APIの使い方 -**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。 - -* [APIリファレンス](/api-doc) -* [ストリーミングAPI](./stream) diff --git a/src/docs/uk-UA/advanced/create-plugin.md b/src/docs/uk-UA/advanced/create-plugin.md deleted file mode 100644 index 5c60b4780..000000000 --- a/src/docs/uk-UA/advanced/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# プラグインの作成 -Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。 - -## Метадані -プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。 - -### name -プラグイン名 - -### author -プラグイン作者 - -### version -プラグインバージョン。数値を指定してください。 - -### description -プラグインの説明 - -### permissions -プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。 - -### config -プラグインの設定情報を表すオブジェクト。 キーに設定名、値に以下のプロパティを含めます。 - -#### type -設定値の種類を表す文字列。以下から選択します。 string number boolean - -#### label -ユーザーに表示する設定名 - -#### description -設定の説明 - -#### default -設定のデフォルト値 - -## APIリファレンス -AiScript標準で組み込まれているAPIは掲載しません。 - -### Mk:dialog(title text type) -ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。 - -### Mk:confirm(title text type) -確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。 - -### Mk:api(endpoint params) -Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。 - -### Mk:save(key value) -任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。 - -### Mk:load(key) -Mk:saveで永続化した指定の名前の値を読み取ります。 - -### Plugin:register_post_form_action(title fn) -投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。 - -### Plugin:register_note_action(title fn) -ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 - -### Plugin:register_user_action(title fn) -ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。 - -### Plugin:register_note_view_interruptor(fn) -UIに表示されるノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:register_note_post_interruptor(fn) -ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:open_url(url) -第一引数に渡されたURLをブラウザの新しいタブで開きます。 - -### Plugin:config -プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。 diff --git a/src/docs/uk-UA/advanced/develop-bot.md b/src/docs/uk-UA/advanced/develop-bot.md deleted file mode 100644 index 7f825e9bc..000000000 --- a/src/docs/uk-UA/advanced/develop-bot.md +++ /dev/null @@ -1,6 +0,0 @@ -# Botの作成 -[Misskey API](./api)を利用してBotの開発が可能です。 また、いくつかのBot実装が公開されているため、ぜひ参考にしてください。 - -- [syuilo/ai](https://github.com/syuilo/ai) ... Node.js上で動く、TypeScript製Bot実装 - -Botを作成したときは、プロフィール設定からBotフラグをオンにしておくことを強くおすすめします。 diff --git a/src/docs/uk-UA/advanced/reversi-bot.md b/src/docs/uk-UA/advanced/reversi-bot.md deleted file mode 100644 index ae4980119..000000000 --- a/src/docs/uk-UA/advanced/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# MisskeyリバーシBotの開発 -Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。 - -1. `games/reversi`ストリームに以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - -2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる - * イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている - -3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する - -4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - * `game`: `game`の`id` - -5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う - -6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する - -7. ゲームが開始すると、`started`イベントが流れてくる - * イベントの中身にはゲーム情報が含まれている - -8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述) - -9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる - * `color`として石の色が含まれている - * `pos`として位置情報が含まれている - -## 位置の計算法 -8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### X,Y座標 から インデックス に変換する -``` -pos = x + (y * mapWidth) -``` -`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます: -``` -mapWidth = map[0].length -``` - -### インデックス から X,Y座標 に変換する -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## マップ情報 -マップ情報は、ゲーム情報の`map`に入っています。 文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 それをもとにマップのデザインを知る事が出来ます: -* `(スペース)` ... マス無し -* `-` ... マス -* `b` ... 初期配置される黒石 -* `w` ... 初期配置される白石 - -例えば、4*4の次のような単純なマップがあるとします: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -この場合、マップデータはこのようになります: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## ユーザーにフォームを提示して対話可能Botを作成する -ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。 - -フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します: -```javascript -{ - type: 'init-form', - body: [フォームコントロールの配列] -} -``` - -フォームコントロールの配列については今から説明します。 フォームコントロールは、次のようなオブジェクトです: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... コントロールのID。 `type` ... コントロールの種類。後述します。 `label` ... コントロールと一緒に表記するテキスト。 `value` ... コントロールのデフォルト値。 - -### フォームの操作を受け取る -ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### フォームコントロールの種類 -#### Перемикач -type: `switch` スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。 - -##### プロパティ -`label` ... スイッチに表記するテキスト。 - -#### ラジオボタン -type: `radio` ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。 - -##### プロパティ -`items` ... ラジオボタンの選択肢。例: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '強', - value: 3 -}] -``` - -#### スライダー -type: `slider` スライダーを表示します。 - -##### プロパティ -`min` ... スライダーの下限。 `max` ... スライダーの上限。 `step` ... 入力欄で刻むステップ値。 - -#### テキストボックス -type: `textbox` テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。 - -## ユーザーにメッセージを表示する -設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 メッセージを表示するには、次のメッセージをストリームに送信します: -```javascript -{ - type: 'message', - body: { - text: 'メッセージ内容', - type: 'メッセージの種類' - } -} -``` -メッセージの種類: `success`, `info`, `warning`, `error`。 - -## 投了する -投了をするには、このエンドポイントにリクエストします。 diff --git a/src/docs/uk-UA/advanced/share-page.md b/src/docs/uk-UA/advanced/share-page.md deleted file mode 100644 index 55c0e1803..000000000 --- a/src/docs/uk-UA/advanced/share-page.md +++ /dev/null @@ -1,54 +0,0 @@ -# シェアページ -`/share`を開くと、共有用の投稿フォームを開くことができます。 ここではシェアページで利用できるクエリ文字列の一覧を示します。 - -## クエリ文字列一覧 -### Текст - -
-
title
-
タイトルです。本文の先頭に[ … ]と挿入されます。
-
text
-
本文です。
-
url
-
URLです。末尾に挿入されます。
-
- -### リプライ情報 -以下のいずれか - -
-
replyId
-
リプライ先のノートid
-
replyUri
-
リプライ先のUrl(リモートのノートオブジェクトを指定)
-
- -### Renote情報 -以下のいずれか - -
-
renoteId
-
Renote先のノートid
-
renoteUri
-
Renote先のUrl(リモートのノートオブジェクトを指定)
-
- -### Видимість -※specifiedに相当する値はvisibility=specifiedとvisibleAccts/visibleUserIdsで指定する - -
-
visibility
-
公開範囲 ['public' | 'home' | 'followers' | 'specified']
-
localOnly
-
0(false) or 1(true)
-
visibleUserIds
-
specified時のダイレクト先のユーザーid カンマ区切りで
-
visibleAccts
-
specified時のダイレクト先のacct(@?username[@host]) カンマ区切りで
-
- -### Файли -
-
fileIds
-
添付したいファイルのid(カンマ区切りで)
-
diff --git a/src/docs/uk-UA/advanced/stream.md b/src/docs/uk-UA/advanced/stream.md deleted file mode 100644 index 978df6a21..000000000 --- a/src/docs/uk-UA/advanced/stream.md +++ /dev/null @@ -1,350 +0,0 @@ -# ストリーミングAPI - -ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。 - -## ストリームに接続する - -ストリーミングAPIを利用するには、まずMisskeyサーバーに**websocket**接続する必要があります。 - -以下のURLに、`i`というパラメータ名で認証情報を含めて、websocket接続してください。例: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。 - -
ℹ️ 認証情報の取得については、こちらのドキュメントをご確認ください。
- ---- - -認証情報は省略することもできますが、その場合非ログインでの利用ということになり、受信できる情報や可能な操作は限られます。例: - -``` -%WS_URL%/streaming -``` - ---- - -ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。 - -**ストリームでのやり取りはすべてJSONです。** - -## Канали -MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。 - -ひとつのストリーム上で、同時に複数のチャンネルに接続することができます。 - -### チャンネルに接続する -チャンネルに接続するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -ここで、 -* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。 -* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。 -* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。 - -
ℹ️ IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。
- -### チャンネルからのメッセージを受け取る -例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。 - -チャンネルがメッセージを発すると、次のようなデータがJSONでストリームに流れてきます: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。 -* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。 -* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。 - -### チャンネルに向けてメッセージを送信する -チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。 - -チャンネルにメッセージを送信するには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。 -* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。 -* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。 - -### チャンネルから切断する -チャンネルから切断するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。 - -## ストリームを経由してAPIリクエストする - -ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。 - -ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -ここで、 -* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 -* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 -* `data`には、エンドポイントのパラメータを含めます。 - -
ℹ️ APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。
- -### レスポンスの受信 - -APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。 - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -ここで、 -* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 -* `body`には、レスポンスが含まれています。 - -## 投稿のキャプチャ - -Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。 - -例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。 - -しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。 - -この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。 - -### 投稿をキャプチャする - -投稿をキャプチャするには、ストリームに次のようなメッセージを送信します: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャしたい投稿の`id`を設定します。 - -このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 - -例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -ここで、 -* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。 -* `body`内の`type`に、イベントの種類が設定されます。 -* `body`内の`body`に、イベントの詳細が設定されます。 - -#### イベントの種類 - -##### `reacted` -その投稿にリアクションがされた時に発生します。 - -* `reaction`に、リアクションの種類が設定されます。 -* `userId`に、リアクションを行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -その投稿が削除された時に発生します。 - -* `deletedAt`に、削除日時が設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -その投稿に添付されたアンケートに投票された時に発生します。 - -* `choice`に、選択肢IDが設定されます。 -* `userId`に、投票を行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### 投稿のキャプチャを解除する - -その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。 - -次のメッセージを送信します: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャを解除したい投稿の`id`を設定します。 - -このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 - -# チャンネル一覧 -## `main` -アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `renote` -自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。 - -#### `mention` -誰かからメンションされたときに発生するイベントです。 - -#### `readAllNotifications` -自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。 - -#### `meUpdated` -自分の情報が更新されたことを表すイベントです。 - -#### `follow` -自分が誰かをフォローしたときに発生するイベントです。 - -#### `unfollow` -自分が誰かのフォローを解除したときに発生するイベントです。 - -#### `followed` -自分が誰かにフォローされたときに発生するイベントです。 - -## `homeTimeline` -ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -タイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `localTimeline` -ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `hybridTimeline` -ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ソーシャルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `globalTimeline` -グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 diff --git a/src/docs/uk-UA/aiscript.md b/src/docs/uk-UA/aiscript.md deleted file mode 100644 index 1cbbf71e5..000000000 --- a/src/docs/uk-UA/aiscript.md +++ /dev/null @@ -1,4 +0,0 @@ -# AiScript - -## Функції -デフォルトで値渡しです。 diff --git a/src/docs/uk-UA/api.md b/src/docs/uk-UA/api.md deleted file mode 100644 index 432525b0a..000000000 --- a/src/docs/uk-UA/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス、Bot等(以下「アプリケーション」と呼びます)を開発できます。 ストリーミングAPIもあるので、リアルタイム性のあるアプリケーションを作ることも可能です。 - -APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。 - -## アクセストークンの取得 -基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。 - -* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む -* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む - -### 自分自身のアクセストークンを手動発行する -「設定 > API」で、自分のアクセストークンを発行できます。 - -[「APIの使い方」へ進む](#APIの使い方) - -### アプリケーション利用者にアクセストークンの発行をリクエストする -アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。 - -#### Крок 1 - -Створити UUID.以後これをセッションIDと呼びます。 - -> このセッションIDは毎回生成し、使いまわさないようにしてください。 - -#### Крок 2 - -`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。 -> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます: -* `name` ... Назва додатка - * > 例: `MissDeck` -* `icon` ... URL піктограми додатка - * > 例: `https://missdeck.example.com/icon.png` -* `callback` ... 認証が終わった後にリダイレクトするURL - * > 例: `https://missdeck.example.com/callback` - * リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます -* `permission` ... アプリケーションが要求する権限 - * > 例: `write:notes,write:following,read:drive` - * 要求する権限を`,`で区切って列挙します - * どのような権限があるかは[APIリファレンス](/api-doc)で確認できます - -#### Крок 3 -ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。 - -レスポンスに含まれるプロパティ: -* `token` ... ユーザーのアクセストークン -* `user` ... ユーザーの情報 - -[「APIの使い方」へ進む](#APIの使い方) - -## Використання API -**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。Підтримка REST відсутня.** アクセストークンは、`i`というパラメータ名でリクエストに含めます。 - -* [Довідник API](/api-doc) -* [Потокове API](./stream) diff --git a/src/docs/uk-UA/create-plugin.md b/src/docs/uk-UA/create-plugin.md deleted file mode 100644 index 17b42f70a..000000000 --- a/src/docs/uk-UA/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# Створення плагінів -Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。 - -## Метадані -プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。 - -### name -プラグイン名 - -### author -プラグイン作者 - -### version -プラグインバージョン。数値を指定してください。 - -### description -プラグインの説明 - -### permissions -プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。 - -### config -プラグインの設定情報を表すオブジェクト。 キーに設定名、値に以下のプロパティを含めます。 - -#### type -設定値の種類を表す文字列。以下から選択します。 string number boolean - -#### label -ユーザーに表示する設定名 - -#### description -設定の説明 - -#### default -設定のデフォルト値 - -## Довідник API -AiScript標準で組み込まれているAPIは掲載しません。 - -### Mk:dialog(title text type) -ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。 - -### Mk:confirm(title text type) -確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。 - -### Mk:api(endpoint params) -Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。 - -### Mk:save(key value) -任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。 - -### Mk:load(key) -Mk:saveで永続化した指定の名前の値を読み取ります。 - -### Plugin:register_post_form_action(title fn) -投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。 - -### Plugin:register_note_action(title fn) -ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 - -### Plugin:register_user_action(title fn) -ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。 - -### Plugin:register_note_view_interruptor(fn) -UIに表示されるノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:register_note_post_interruptor(fn) -ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:open_url(url) -第一引数に渡されたURLをブラウザの新しいタブで開きます。 - -### Plugin:config -プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。 diff --git a/src/docs/uk-UA/custom-emoji.md b/src/docs/uk-UA/custom-emoji.md deleted file mode 100644 index 2a130cb1d..000000000 --- a/src/docs/uk-UA/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# Кастомні емоджі -カスタム絵文字は、インスタンスで用意された画像を絵文字のように使える機能です。 ノート、リアクション、チャット、自己紹介、名前などの場所で使うことができます。 カスタム絵文字をそれらの場所で使うには、絵文字ピッカーボタン(ある場合)を押すか、`:`を入力して絵文字サジェストを表示します。 テキスト内に`:foo:`のような形式の文字列が見つかると、`foo`の部分がカスタム絵文字名と解釈され、表示時には対応したカスタム絵文字に置き換わります。 diff --git a/src/docs/uk-UA/deck.md b/src/docs/uk-UA/deck.md deleted file mode 100644 index acb80815c..000000000 --- a/src/docs/uk-UA/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# Дек - -デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。 - -## カラムの追加 -デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。 - -## カラムの移動 -カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。 - -## カラムの水平分割 -カラムは左右だけでなく、上下に並べることもできます。 カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 上下分割を解除するには、カラムメニューの「右に出す」を選択します。 - -## カラムの設定 -カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。 - -## デッキの設定 -デッキに関する設定は、[settings/deck](/settings/deck)で行えます。 diff --git a/src/docs/uk-UA/features/antenna.md b/src/docs/uk-UA/features/antenna.md deleted file mode 100644 index 68a72648f..000000000 --- a/src/docs/uk-UA/features/antenna.md +++ /dev/null @@ -1,4 +0,0 @@ -# Антени -アンテナは、自由に条件を設定して、合致するノートを自動で収集することができる機能です。 - -条件を設定したアンテナが作成された状態で、条件に合致するノートが投稿されると、リアルタイムでそのアンテナのタイムラインにノートが追加されます。 diff --git a/src/docs/uk-UA/features/custom-emoji.md b/src/docs/uk-UA/features/custom-emoji.md deleted file mode 100644 index 2a130cb1d..000000000 --- a/src/docs/uk-UA/features/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# Кастомні емоджі -カスタム絵文字は、インスタンスで用意された画像を絵文字のように使える機能です。 ノート、リアクション、チャット、自己紹介、名前などの場所で使うことができます。 カスタム絵文字をそれらの場所で使うには、絵文字ピッカーボタン(ある場合)を押すか、`:`を入力して絵文字サジェストを表示します。 テキスト内に`:foo:`のような形式の文字列が見つかると、`foo`の部分がカスタム絵文字名と解釈され、表示時には対応したカスタム絵文字に置き換わります。 diff --git a/src/docs/uk-UA/features/deck.md b/src/docs/uk-UA/features/deck.md deleted file mode 100644 index acb80815c..000000000 --- a/src/docs/uk-UA/features/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# Дек - -デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。 - -## カラムの追加 -デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。 - -## カラムの移動 -カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。 - -## カラムの水平分割 -カラムは左右だけでなく、上下に並べることもできます。 カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 上下分割を解除するには、カラムメニューの「右に出す」を選択します。 - -## カラムの設定 -カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。 - -## デッキの設定 -デッキに関する設定は、[settings/deck](/settings/deck)で行えます。 diff --git a/src/docs/uk-UA/features/drive.md b/src/docs/uk-UA/features/drive.md deleted file mode 100644 index 0ab686564..000000000 --- a/src/docs/uk-UA/features/drive.md +++ /dev/null @@ -1,17 +0,0 @@ -# Диск -ドライブは、Misskey上でファイルを管理できる機能です。 - -[ドライブのページ](/my/drive)から任意のファイルをアップロードできるほか、アバターに設定した画像や、ノートに添付したファイルなどもすべてドライブにアップロードされます。 - -
⚠️ ドライブからファイルを削除すると、そのファイルが添付されたノートも消えます。
- -ドライブにアップロードされたファイルは、いつでもダウンロードすることができるほか、ノート作成時に「ドライブからファイルを添付」することでファイルを再利用することもできます。 - -ドライブ内にフォルダを作り、複数のファイルをまとめて整理することもできます。 - -## 閲覧注意 (NSFW) -
ℹ️ この項目が閲覧注意なわけではありません
- -閲覧注意またはNSFW (Not safe for work) は、ドライブのファイルに設定することができるフラグです。 閲覧注意フラグを設定されたファイルは、表示される際に閲覧者の操作なしには表示されなくなります。 このフラグは、例えば職場や公共の場で閲覧するのに適切でないと思われる画像などに設定し、そのような画像が突然表示されてしまうことを防ぐ目的で使われます。 - -このフラグは手動でオンオフを切り替えられるほか、モデレーターの判断で設定される場合もあります。 diff --git a/src/docs/uk-UA/features/favorite.md b/src/docs/uk-UA/features/favorite.md deleted file mode 100644 index 31f7835fc..000000000 --- a/src/docs/uk-UA/features/favorite.md +++ /dev/null @@ -1,4 +0,0 @@ -# Обране -[ノート](./node)をお気に入りとして登録できる機能です。 お気に入り登録したノートは、[お気に入りページ](./my/favorites)で一覧することができます。 お気に入りに登録したことは相手に通知されず、お気に入りは自分しか見ることができません。 - -ノートをお気に入り登録するには、ノートメニューの「お気に入り」を押します。お気に入り解除するには、ノートメニューの「お気に入り解除」を押します。 diff --git a/src/docs/uk-UA/features/follow.md b/src/docs/uk-UA/features/follow.md deleted file mode 100644 index db2a4c331..000000000 --- a/src/docs/uk-UA/features/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# Підписки -ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。 diff --git a/src/docs/uk-UA/features/keyboard-shortcut.md b/src/docs/uk-UA/features/keyboard-shortcut.md deleted file mode 100644 index 86820bd5f..000000000 --- a/src/docs/uk-UA/features/keyboard-shortcut.md +++ /dev/null @@ -1,66 +0,0 @@ -# キーボードショートカット - -## Глобальна -これらのショートカットは基本的にどこでも使えます。 - - - - - - - - - - - -
ショートカット効果由来
P, N新規投稿Post, New, Note
Tタイムラインの最も新しい投稿にフォーカスTimeline, Top
Shift + N通知を表示/隠すNotifications
SПошукSearch
H, ?ヘルプを表示Help
- -## 投稿にフォーカスされた状態 - - - - - - - - - - - - - - - - - - -
ショートカット効果由来
, K, Shift + Tab上の投稿にフォーカスを移動-
, J, Tab下の投稿にフォーカスを移動-
R返信フォームを開くReply
QRenoteフォームを開くQuote
Ctrl + Q即刻Renoteする(フォームを開かずに)-
E, A, +リアクションフォームを開くEmote, reAction
0~9数字に対応したリアクションをする(対応については後述)-
F, Bお気に入りに登録Favorite, Bookmark
Del, Ctrl + D投稿を削除Delete
M, O投稿に対するメニューを開くMore, Other
SCWで隠された部分を表示 or 隠すShow, See
Escフォーカスを外す-
- -## Renoteフォーム - - - - - - - - - -
ショートカット効果由来
EnterRenoteする-
Qフォームを展開するQuote
Escフォームを閉じる-
- -## リアクションフォーム -デフォルトで「👍」にフォーカスが当たっている状態です。 - - - - - - - - - - - - - -
ショートカット効果由来
, K上のリアクションにフォーカスを移動-
, J下のリアクションにフォーカスを移動-
, H, Shift + Tab左のリアクションにフォーカスを移動-
, L, Tab右のリアクションにフォーカスを移動-
Enter, Space, +リアクション確定-
0~9数字に対応したリアクションで確定-
Escリアクションするのをやめる-
diff --git a/src/docs/uk-UA/features/mfm.md b/src/docs/uk-UA/features/mfm.md deleted file mode 100644 index 5be2df4f3..000000000 --- a/src/docs/uk-UA/features/mfm.md +++ /dev/null @@ -1,12 +0,0 @@ -# MFM -MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます。 - -## MFMが使用可能な場所の例 -- ノート本文 -- CW注釈 -- ユーザーの名前 -- ユーザーの自己紹介 - -## 開発者向け情報 -MFMのパーサー実装はライブラリとして公開されており、簡単にクライアントにMFMを組み込むことが可能です。 -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptパーサー実装 diff --git a/src/docs/uk-UA/features/mute-and-block.md b/src/docs/uk-UA/features/mute-and-block.md deleted file mode 100644 index f9f6f0cb8..000000000 --- a/src/docs/uk-UA/features/mute-and-block.md +++ /dev/null @@ -1,41 +0,0 @@ -# Заглушення і блокування -好みではないユーザーがいる場合は、ミュートを行うことでそのユーザーが自分から見えないようにすることができます。 また、より強力な措置として、ブロックを行うことでそのユーザーから自分のコンテンツが見えないようになるほか、自分に対して関わることができないようにすることができます。 ミュートされていることは相手は分かりませんが、ブロックされていることは相手に分かります。どちらを選ぶかはご自身の判断で行ってください。 - -
ℹ️ ミュートとブロックは併用できます。
- -
⚠️ 利用規約に違反するような、迷惑なユーザーがいる場合は運営者に報告することも検討してください。
- -設定>ミュートとブロック から、自分がミュートまたはブロックしているユーザー一覧を確認することができます。 - -## Ігнорувати -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -- タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -- そのユーザーからの通知 -- メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 -- など - -ユーザーをミュートするには、対象のユーザーのユーザーページのメニューを開き、「ミュート」ボタンを押します。 - -
ℹ️ ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。
- -## Заблокувати -ユーザーをブロックすると、そのユーザーからあなたのコンテンツが見えないようになり、またあなたに対して以下のようなアクションをすることができなくなります。 - -- フォローする -- ユーザーリストに追加する -- 返信する、Renoteする -- リアクションする、アンケートに投票する -- メッセージを送信する -- など - -また、 - -- ブロックする際に既にそのユーザーからフォローされていた場合はフォローが解除されます。 -- ブロックする際に既にそのユーザーがあなたをユーザーリストに入れていた場合はそのリストからあなたが削除されます。 - -ユーザーをブロックするには、対象のユーザーのユーザーページのメニューを開き、「ブロック」ボタンを押します。 - -
⚠️ ブロックを行ったこと自体は相手に通知されませんが、フォローを行ったりなどの上記のアクションが行えなくなるので間接的にブロックされていることは分かります。
- -
⚠️ 相手から自分のコンテンツが見えなくなりますが、相手がアカウントを切り替えたりログアウト状態になれば見ることができます。あくまで簡易的、補助的なものとしてお考えください。
diff --git a/src/docs/uk-UA/features/mute.md b/src/docs/uk-UA/features/mute.md deleted file mode 100644 index da3cfcc36..000000000 --- a/src/docs/uk-UA/features/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# Ігнорувати - -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -* タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -* そのユーザーからの通知 -* メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 - -ユーザーをミュートするには、対象のユーザーのユーザーページに表示されている「ミュート」ボタンを押します。 - -ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。 - -設定>ミュート から、自分がミュートしているユーザー一覧を確認することができます。 diff --git a/src/docs/uk-UA/features/note.md b/src/docs/uk-UA/features/note.md deleted file mode 100644 index cac4e1cd4..000000000 --- a/src/docs/uk-UA/features/note.md +++ /dev/null @@ -1,54 +0,0 @@ -# Записи -ノートは、Misskeyに投稿される、文章、ファイル、アンケートなどを含むコンテンツで、Misskeyの中心的概念です。また、そのノートを作成する行為自体もノートと呼ばれます。 - -ノートが作成されると、[タイムライン](./timeline)に追加され、自分の[フォロワー](./follow)やサーバーのユーザーが見れるようになります。 - -ノートには、[リアクション](./reaction)を行うことができます。また、返信や引用もできます。 - -ノートを[お気に入り](./favorite)登録することで、後で簡単に見返すことができます。 - -## ノートを作成する -ノートを作成するには、画面上にある鉛筆マークのボタンを押して、作成フォームを開きます。作成フォームに内容を入力し、「ノート」ボタンを押すことでノートが作成されます。 ノートには、画像、動画など任意のファイルや、[アンケート](./poll)を添付することができます。また、本文中には[MFM](./mfm)が使用でき、[メンション](./mention)や[ハッシュタグ](./hashtag)を含めることもできます。 他にも、CWや公開範囲といった設定も行えます(詳細は後述)。 -
ℹ️ コンピューターのクリップボードに画像データがある状態で、フォーム内のテキストボックスにペーストするとその画像を添付することができます。
-
ℹ️ テキストボックス内でCtrl + Enterを押すことでも投稿できます。
- -## Поширити -既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノートをRenoteと呼びます。 自分がフォローしているユーザーの、気に入ったノートを自分のフォロワーに共有したい場合や、過去の自分のノートを再度共有したい場合に使います。 同じノートに対して無制限にRenoteを行うことができますが、あまり連続して使用すると迷惑になる場合もあるので、注意しましょう。 -
⚠️ 公開範囲がフォロワーやダイレクトのノートはRenoteできません
- -Renoteを削除するには、Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 - -## CW -Contents Warningの略で、ノートの内容を、閲覧者の操作なしには表示しないようにできる機能です。主に長大な内容を隠すためや、ネタバレ防止などに使うことができます。 設定するには、フォームの「内容を隠す」ボタン(目のアイコン)を押します。すると新しい入力エリアが表れるので、そこに内容の要約を記入します。 - -## Видимість -ノートごとに、そのノートが公開される範囲を設定することができます。フォームの「ノート」ボタンの左にあるアイコンを押すと公開範囲を以下から選択できます。 - -### Публічний -全ての人に対してノートが公開されるほか、サーバーの全てのタイムライン(ホームタイムライン、ローカルタイムライン、ソーシャルタイムライン、グローバルタイムライン)にノートが流れます。 -
⚠️ アカウントがサイレンス状態の時は、この公開範囲は使用できません。
- -### Домівка -全ての人に対してノートが公開されますが、フォロワー以外のローカルタイムライン、ソーシャルタイムライン、グローバルタイムラインにはノートは流れません。 - -### Підписники -自分のフォロワーに対してのみノートを公開します。フォロワーの全てのタイムラインに流れます。 - -### Особисто -指定したユーザーに対してのみノートを公開します。指定したユーザーの全てのタイムラインに流れます。 - -### 「ローカルのみ」オプション -このオプションを有効にすると、リモートにノートを連合しなくなります。 - -### 公開範囲の比較 - - - - -
ПублічнийДомівкаПідписникиОсобисто
フォロワーのLTL/STL/GTL
非フォロワーのLTL/STL/GTL
- -## Закріпити -ノートをピン留めすると、ユーザーページに常にそのノートを表示しておくことができます。 ノートのメニューを開き、「ピン留め」を選択してピン留めできます。 複数のノートをピン留めできます。 - -## Стежити -ノートをウォッチすると、自分以外のノートへのリアクションや返信などの通知を受け取ることができます。 ノートのメニューを開き、「ウォッチ」を選択してウォッチできます。 diff --git a/src/docs/uk-UA/features/pages.md b/src/docs/uk-UA/features/pages.md deleted file mode 100644 index 55cd74544..000000000 --- a/src/docs/uk-UA/features/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# Pages - -## Змінні -変数を使うことで動的なページを作成できます。テキスト内で { 変数名 } と書くとそこに変数の値を埋め込めます。例えば Hello { thing } world! というテキストで、変数(thing)の値が ai だった場合、テキストは Hello ai world! になります。 - -変数の評価(値を算出すること)は上から下に行われるので、ある変数の中で自分より下の変数を参照することはできません。例えば上から A、B、C と3つの変数を定義したとき、Cの中でABを参照することはできますが、Aの中でBCを参照することはできません。 - -ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。 - -関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。 diff --git a/src/docs/uk-UA/features/reaction.md b/src/docs/uk-UA/features/reaction.md deleted file mode 100644 index b73f7bf1d..000000000 --- a/src/docs/uk-UA/features/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# Реакції -他の人のノートに、絵文字を付けて簡単にあなたの反応を伝えられる機能です。 リアクションするには、ノートの + アイコンをクリックしてピッカーを表示し、絵文字を選択します。 リアクションには[カスタム絵文字](./custom-emoji)も使用できます。 - -## リアクションピッカーのカスタマイズ -ピッカーに表示される絵文字を自分好みにカスタマイズすることができます。 設定の「リアクション」で設定します。 - -## リモート投稿へのリアクションについて -リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。 - -## リモートからのリアクションについて -リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。 diff --git a/src/docs/uk-UA/features/silence.md b/src/docs/uk-UA/features/silence.md deleted file mode 100644 index 654ffcaea..000000000 --- a/src/docs/uk-UA/features/silence.md +++ /dev/null @@ -1,6 +0,0 @@ -# Заглушити -サイレンスは、アカウントに設定される状態のひとつです。 - -アカウントがサイレンス状態になると、ノートの公開範囲をパブリックにできなくなります。 ホーム、フォロワー、ダイレクトは選択可能なため、サイレンスを受けた場合でもフォロワーやあなたのユーザーページを直接訪れた場合は投稿を閲覧できますが、GTL(連合タイムライン)やLTL(ローカルタイムライン)には投稿が流れません。 - -アカウントのサイレンス状態は、サーバーのモデレーターによって有効化/無効化されます。 diff --git a/src/docs/uk-UA/features/theme.md b/src/docs/uk-UA/features/theme.md deleted file mode 100644 index baa74c33e..000000000 --- a/src/docs/uk-UA/features/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# Тема - -テーマを設定して、Misskeyクライアントの見た目を変更できます。 - -## テーマの設定 -設定 > テーマ - -## テーマを作成する -テーマコードはJSON5で記述されたテーマオブジェクトです。 テーマは以下のようなオブジェクトです。 -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... テーマの一意なID。UUIDをおすすめします。 -* `name` ... テーマ名 -* `author` ... テーマの作者 -* `desc` ... テーマの説明(オプション) -* `base` ... 明るいテーマか、暗いテーマか - * `light`にすると明るいテーマになり、`dark`にすると暗いテーマになります。 - * テーマはここで設定されたベーステーマを継承します。 -* `props` ... テーマのスタイル定義。これから説明します。 - -### テーマのスタイル定義 -`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 - -#### バリューで使える構文 -* 16進数で表された色 - * 例: `#00ff00` -* `rgb(r, g, b)`形式で表された色 - * 例: `rgb(0, 255, 0)` -* `rgb(r, g, b, a)`形式で表された透明度を含む色 - * 例: `rgba(0, 255, 0, 0.5)` -* 他のキーの値の参照 - * `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。 - * 例: `@panel` -* 定数(後述)の参照 - * `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。 - * 例: `$main` -* 関数(後述) - * `:{関数名}<{引数}<{色}` - -#### 定数 -「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 キー名を`$`で始めると、そのキーはCSS変数として出力されません。 - -#### Функції -wip diff --git a/src/docs/uk-UA/features/timeline.md b/src/docs/uk-UA/features/timeline.md deleted file mode 100644 index 3acb613c7..000000000 --- a/src/docs/uk-UA/features/timeline.md +++ /dev/null @@ -1,31 +0,0 @@ -# Стрічка -タイムラインは、[ノート](./note)が時系列で表示される機能です。 タイムラインには以下で示す種類があり、種類によって表示されるノートも異なります。 なお、タイムラインの種類によってはサーバーにより無効になっている場合があります。 - -## Домівка -自分のフォローしているユーザーの投稿が流れます。HTLと略されます。 - -## Локальна -全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。LTLと略されます。 - -## Соціальна -自分のフォローしているユーザーの投稿と、全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。STLと略されます。 - -## Глобальна -全てのローカルユーザーの「ホーム」指定されていない投稿と、サーバーに届いた全てのリモートユーザーの「ホーム」指定されていない投稿が流れます。GTLと略されます。 - -## Порівняння -| ソース | | | Стрічка | | | -| ------------ | ---------- | ------- | -------- | --------- | --------- | -| Користувачі | Видимість | Домівка | Локальна | Соціальна | Глобальна | -| ローカル (フォロー) | 公開 | ✔ | ✔ | ✔ | ✔ | -| | Домівка | ✔ | | ✔ | | -| | Підписники | ✔ | ✔ | ✔ | ✔ | -| リモート (フォロー) | 公開 | ✔ | | ✔ | ✔ | -| | Домівка | ✔ | | ✔ | | -| | Підписники | ✔ | | ✔ | ✔ | -| ローカル (未フォロー) | 公開 | | ✔ | ✔ | ✔ | -| | Домівка | | | | | -| | Підписники | | | | | -| リモート (未フォロー) | 公開 | | | | ✔ | -| | Домівка | | | | | -| | Підписники | | | | | diff --git a/src/docs/uk-UA/features/widgets.md b/src/docs/uk-UA/features/widgets.md deleted file mode 100644 index 13e848fbe..000000000 --- a/src/docs/uk-UA/features/widgets.md +++ /dev/null @@ -1,7 +0,0 @@ -# Віджети -ウィジェットは、MisskeyのUI上に設置できる小型の情報表示、操作が行えるパーツです。 - -ウィジェットを編集するには、ウィジェット編集モードに切り替えます。切り替え方法はUIによって異なります。 ウィジェット編集モードでは、ウィジェットの追加、削除、並び替え、およびそれぞれのウィジェットの設定を行えます。 - -## 利用可能なウィジェット一覧 -todo diff --git a/src/docs/uk-UA/features/word-mute.md b/src/docs/uk-UA/features/word-mute.md deleted file mode 100644 index 73b41af28..000000000 --- a/src/docs/uk-UA/features/word-mute.md +++ /dev/null @@ -1,20 +0,0 @@ -# Блокування слів -ワードミュートの設定をすると、条件に合致したノートが表示されなくなります。 - -ワードミュートには、ソフトワードミュートとハードワードミュートの2種類があります。それぞれについて設定の方法と挙動を説明します。 - -## ソフトワードミュート -ソフトワードミュートは、クライアント(アプリ)側でミュートを判断するワードミュートです。 - -ノートが設定した条件に合致すると、「(ユーザー名)が何かを言いました」という表示で隠れます。 -クリックすると元の通りに表示されます。 - -## ハードワードミュート -ハードワードミュートは、アンテナのようにサーバーが新しいノートの本文に対して条件に合致するかどうか判断し、タイムラインから対象となったノートを除外します。 - -つまり、ハードワードミュートには、以下のような特徴があります。 - -* 条件設定後、新しい投稿のみがミュートの対象になります。 -* 条件を変更しても、過去にハードミュートされたノートはミュートされたままになります。 -* 「○○が何かを言いました」でタイムラインが埋まることがありません。 -* ソフトミュートに非対応のアプリでも、ハードミュートは適用されます。 diff --git a/src/docs/uk-UA/follow.md b/src/docs/uk-UA/follow.md deleted file mode 100644 index db2a4c331..000000000 --- a/src/docs/uk-UA/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# Підписки -ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。 diff --git a/src/docs/uk-UA/general/apps.md b/src/docs/uk-UA/general/apps.md deleted file mode 100644 index 1f4c85fe8..000000000 --- a/src/docs/uk-UA/general/apps.md +++ /dev/null @@ -1,6 +0,0 @@ -# サードパーティアプリのリスト -## クライアント -todo - -## 連携サービス -todo diff --git a/src/docs/uk-UA/general/changelog.md b/src/docs/uk-UA/general/changelog.md deleted file mode 100644 index 6766a63b2..000000000 --- a/src/docs/uk-UA/general/changelog.md +++ /dev/null @@ -1,5 +0,0 @@ -# 更新履歴 -
ℹ️ このサーバーの更新履歴です。Misskeyの最新のリリースについては、GitHubをご確認ください。
- - - diff --git a/src/docs/uk-UA/general/faq.md b/src/docs/uk-UA/general/faq.md deleted file mode 100644 index c272b2ad4..000000000 --- a/src/docs/uk-UA/general/faq.md +++ /dev/null @@ -1,28 +0,0 @@ -# よくある質問 -ここでは利用上のよくある質問について掲載しています。 Misskeyのプロジェクト自体についてのよくある質問は[こちら](./misskey)に掲載されています。 - -## iOS/Androidのアプリはありますか? -公式にはそういったOSのネイティブアプリを開発していませんが、サードパーティ製のアプリがいくつかあります。 詳しくは[こちら](./apps)をご覧ください。 - -ただ、サードパーティ製アプリはどうしても機能への対応が遅れてしまうため、とくに拘りがなければ公式のWebクライアントの利用をおすすめします。 なお、MisskeyのWebクライアントはPWAに対応しているので、ネイティブアプリのように動作させることも可能です。 詳しくは[こちら](todo)をご覧ください。 - -## Mastodonクライアントでログインできないのですが? -MisskeyはMastodonのAPIと互換性がないため、一部を除きMastodonクライアントでMisskeyを利用することはできません。 - -## 他のサーバーのユーザーをフォローするときは? -メニューから検索を選び、ユーザー名をホスト込みで入力します。例: `@syuilo@misskey.io` - -## Renoteを削除するには? -Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 Renoteについては[こちら](../features/note)をご確認ください。 - -## URLのプレビューを表示させたくない -MFMには、そのURLのプレビューを無効にする構文があります。詳細は[MFMチートシート](/mfm-cheat-sheet)をご確認ください。 - -## カスタム絵文字を追加したい -運営者のみがカスタム絵文字を追加、編集、削除できます。それらを希望する場合は運営者に依頼してください。 - -## Botを開発したい -Misskey APIを利用してBotの開発が可能です。[こちら](../advanced/develop-bot)をご確認ください。 - -## ノートの翻訳機能はどのサービスを使用していますか? -[DeepL](https://www.deepl.com/)を使用しています。 diff --git a/src/docs/uk-UA/general/glossary.md b/src/docs/uk-UA/general/glossary.md deleted file mode 100644 index 38f46670f..000000000 --- a/src/docs/uk-UA/general/glossary.md +++ /dev/null @@ -1,89 +0,0 @@ -# 用語集 -Misskeyに関する用語集です。 - -## ActivityPub -(読み: あくてぃびてぃぱぶ) 分散型を実現するために用いられるプロトコル(仕様)。このプロトコルに則ってサーバー同士通信を行うことで、連合が行われ、Fediverseを形成しています。 - -## AiScript -(読み: あいすくりぷと) Misskey上で使用できるプログラミング言語です。詳細は[こちら。](../advanced/aiscript) - -## API -(読み: えーぴーあい) Misskeyのサーバーが公開している、プログラムからMisskeyを扱うためのインターフェース。詳細は[こちら。](../advanced/api) - -## Bot -(読み: ぼっと) プログラムによって動作しているアカウント。 - -## CW -(読み: こんてんつわーにんぐ) Contents Warningの略。ノートの内容を、操作なしには表示しないようにできる機能。主に長大な内容を隠すためや、ネタバレ防止などに使われます。 - -## Fediverse -(読み: ふぇでぃばーす) Misskeyを含む様々な分散型ソフトウェアのサーバーで構成されたネットワーク。 - -## GTL -グローバルタイムライン(Global TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## HTL -ホームタイムライン(Home TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## LTL -ローカルタイムライン(Local TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## MFM -(読み: えむえふえむ) Misskey Flavored Markdownの略で、Misskey上で使用できるマークアップ言語です。詳細は[こちら。](../features/mfm) - -## NSFW -(読み: のっとせーふふぉーわーく) Not Safe For Workの略。画像を「閲覧注意」扱いにし、操作なしには表示しないようにすることができる機能。 - -## Поширити -(読み: りのーと) 既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノート。詳細は[こちら。](../features/note) - -## STL -ソーシャルタイムライン(Social TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## 藍 -(読み: あい) Misskeyの看板娘(公式キャラクター)です。 - -## アクティブユーザー -インスタンスにアカウントを作っているユーザーのうち、現在も実際にサービスを利用しているユーザーのこと。 - -## Інстанс -todo - -## Кастомні емоджі -サーバーで用意された絵文字。カスタム絵文字ではない通常の絵文字は「Unicode絵文字」と区別して呼ばれる。 - -## コントロールパネル -インスタンスの設定画面のこと。 - -## Сервер -todo - -## Заглушити -ノートをパブリックな公開範囲で投稿できなくされている状態。モデレーターの判断でユーザーごとに設定されます。詳細は[こちら。](../features/silence) - -## Черга завдань -アクティビティ配送などを順番に行うためのシステム。 - -## Призупинити -アカウントが使用不可に設定されている状態。 - -## Диск -Misskeyにアップロードしたファイルを管理する機能。詳細は[こちら。](../features/drive) - -## Записи -Misskeyに投稿される、文章、ファイル、アンケートなどを含めることができるコンテンツ。詳細は[こちら。](../features/note) - -## ミスキスト -Misskeyを使う人のこと。 - -## Модератор -スパムの凍結およびサイレンスや不適切な投稿の削除など、コミュニティ運営に関する権限を持つユーザー。 - -## Віддалені -他サーバーのことを指します。リモートユーザーといったように接頭辞としても使われます。ローカルの逆です。 - -## Федіверс -サーバー上で作成された情報が他のサーバーに伝わること。 - -## Локальна -自サーバーのことを指します。ローカルユーザー、ローカルタイムラインといったように接頭辞としても使われます。リモートの逆です。 diff --git a/src/docs/uk-UA/general/links.md b/src/docs/uk-UA/general/links.md deleted file mode 100644 index 5ce5e1ddb..000000000 --- a/src/docs/uk-UA/general/links.md +++ /dev/null @@ -1,12 +0,0 @@ -# リンク集 - -## Webサイト -- [Official Discord](https://discord.gg/Wp8gVStHW3) - Misskey公式Discordサーバー -- [Misskey Forum](https://forum.misskey.io/) - Misskeyに関する話題を扱うフォーラム - -## アカウント -- [@repo@misskey.io](https://misskey.io/@repo) - Misskeyのリポジトリの更新を投稿するbot - -## ライブラリ -- [misskey-dev/misskey.js](https://github.com/misskey-dev/misskey.js) - JavaScriptのMisskey SDK -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptのMFMパーサー実装 diff --git a/src/docs/uk-UA/general/misskey.md b/src/docs/uk-UA/general/misskey.md deleted file mode 100644 index 2c229c749..000000000 --- a/src/docs/uk-UA/general/misskey.md +++ /dev/null @@ -1,87 +0,0 @@ -# Про Misskey - -Misskeyはオープンソースの分散型マイクロブログプラットフォームプロジェクトです。 開発は日本でsyuiloによって2014年から開始されました。 ドライブ、リアクションなどの豊富な機能や、高いカスタマイズ性を備えたUIを持つことが特徴です。 - -## 歴史 -開発当初は掲示板がメインのサービスでしたが、ユーザーが短文を投稿し、それを時系列で流れるタイムライン機能を追加したところ人気が高まり、徐々にそれがメインとして開発が進むようになりました。 当初は分散型ではありませんでしたが、2018年にActivityPubを実装し分散型になったことで、より多くの方に認知され利用されるサービスになり、現在に至ります。 -
ℹ️ Misskeyという名前は、syuiloが当時聴いていたMay'nというアーティストの楽曲、Brain Diverの歌詞に由来します。
- -誰でも開発に参加することができ、現在でも活発に開発が続いています。 - -## 分散型とは何か? - -分散(distributed)型とは、非中央集権(decentralized)とも呼ばれ、コミュニティが多数のサーバーに分散して存在し、それらが相互に通信(連合、federation)することでコンテンツ共有ネットワーク(Fediverse)を形成していることが特徴のサービスです。 単一のサーバーしか存在しない、もしくは複数存在しても互いに独立している場合は中央集権なサービスと言われ、例えばTwitterやFacebookなどほとんどのサービスがそれに該当します。 分散型のメリットは、自分に合った運営者やテーマのサーバーを選択できることです。自分でサーバーを作成することもできます。連合するおかげで、どのサーバーを選んでも、同じコミュニティにアクセスできます。 - -## 常にオープンソース -Misskeyはこれまでもこれからも、オープンソースであり続けます。オープンソースとは、簡単に言うとソフトウェアのソースコード(プログラム)が公開されていることです。ソースコードの修正や再配布が可能であることを定義に含めることもあります。 Misskeyのすべてのソースコードは[AGPL](https://github.com/misskey-dev/misskey/blob/develop/LICENSE)というオープンソースライセンスの下に[公開](https://github.com/misskey-dev)されていて、誰でも自由に閲覧、使用、修正、改変、再配布をすることができます。 オープンソースは、自分で好きなように変えたり、有害な処理が含まれていないことを確認することができたり、誰でも開発に参加できるなどの、様々なメリットがあります。 上述の分散型を実現するためにも、オープンソースであるということは必要不可欠な要素です。 再び引き合いに出しますが、TwitterやFacebookなどの利益を得ているほとんどのサービスはオープンソースではありません。 - -
ℹ️ 技術的に言うと、MisskeyのソースコードはGitで管理されていて、リポジトリはGitHub上でホスティングされています。
- -## 開発に参加する、プロジェクトを支援する -Misskeyを気に入っていただけたら、ぜひプロジェクトを支援してください。プロジェクトに貢献するには、以下で紹介するようにいろいろな方法があります。方法によっては開発のスキルは不要なので、誰でも気軽に参加し貢献することができます。いつでもお待ちしています。 - -### 機能を追加したり、バグを修正する -ソフトウェアエンジニアのスキルをお持ちの方であれば、ソースコードを編集する形でプロジェクトに貢献することができます。 貢献についてのガイドは[こちら](https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md)です。 - -### 議論に参加する -新しい機能、または既存の機能について意見を述べたり、不具合を報告したりすることでも貢献できます。 そのようなディスカッションは[GitHub](https://github.com/misskey-dev)上か、[フォーラム](https://forum.misskey.io/)等で行われます。 - -### テキストを翻訳する -Misskeyは様々な言語に対応しています(i18n -internationalizationの略- と呼ばれます)。元の言語は基本的に日本語ですが、有志によって他の言語へと翻訳されています。 その翻訳作業に加わっていただくことでもMisskeyに貢献できます。 Misskeyは[Crowdinというサービスを使用して翻訳の管理を行っています。](https://crowdin.com/project/misskey) - -### 感想を投稿する -不具合報告等だけではなく、Misskeyの良い点、楽しい点といったポジティブな意見もぜひ共有してください。開発の励みになり、それは間接的ですがプロジェクトへの貢献です。 - -### ミスキストを増やす -ミスキストとは、Misskeyを使用する人のことです。 知り合いに紹介するなどしてMisskeyを広めていただければ、ミスキストが増え開発のモチベーションが上がります。 - -### 寄付をする -Misskeyはビジネスではなく、利用は無料であるため、収益は皆様からの寄付のみです。(インスタンスによっては広告収入を得ているような場合もありますが、それは運営者の収入であり直接開発者への収入にはなりません) 寄付をしていただければ、今後も開発を続けることが可能になり、プロジェクトへの貢献になります。 寄付は基本的には[Patreon](https://www.patreon.com/syuilo)で受け付けています。 一定額寄付していただけると、Misskeyの[情報ページ](/about-misskey)に名前を記載することができます。 - -また、サーバーの運営者も、基本的には収益を得ていません。サーバーの運営にはコストがかかるので、運営者の支援をすることもご検討ください。 開発には直接関係しませんが、サーバーがあってこそのプロジェクトなので、運営が維持されるというのは開発と同じくらい重要なことです。 - -## クレジット -Misskeyの開発者や、Misskeyに寄付をしてくださった方の一覧は[こちら](/about-misskey)で見ることができます。 - -## よくある質問 -### プロジェクトは何を目指していますか? -強いて言うと、漠然的になりますが広く使われる汎用的なプラットフォームになることを目指しています。 Misskeyは他のプロジェクトとは違い、何らかの思想(例えば、反中央集権)やビジョンに基づいて開発が行われているわけではなく、その点ではフラットです。 それが逆に、特定の方向性に縛られないフレキシブルさを生み出すことに繋がっていると感じています。 - - -### 企業によって開発されていますか? -いいえ。Misskeyの開発は個人で行われており、商業的でもないため、特定の企業の関りはありません。 開発メンバーも基本的にはボランティアです。 また、開発に対し企業のスポンサーがつくこともありますが、その場合でもやはり開発は個人のコミュニティが主体です。 - -### 誰が運営していますか? -Misskeyは分散型なため、各サーバーにそれぞれ異なった運営者がいます。従って、特定の個人や企業によって、Misskeyの全てが運営されているわけではありません。 また、開発チームが運営を行うわけでもないため、運営に関する連絡は、お使いのサーバーの運営者に行ってください。 サーバーの運営者は、[このページ](/about)で確認することができます。 あなたがサーバーを作成すれば、あなたが運営者になります。 - -### どのサーバーを選べばいいですか? -[サーバー一覧が公開されています。](https://join.misskey.page/ja-JP/instances) サーバーによってコミュニティのテーマ(特定のこと、ものが好き 等)が決められている場合があるので、自分に合ったテーマのサーバーがあれば、そこを選ぶと良いかもしれません。 他にも、サーバーの規模、ユーザー層、国および言語、運営者が信頼できるかどうか、などの観点があります。 なお、Misskey公式のサーバーというものはありません。自身で新しくサーバーを作成するという選択肢もあります。 - -基本的にどのサーバーを選んだとしても、他の全てのサーバーのユーザーと繋がることができます。 - -### サーバーを建てるにはどうしたらいいですか? -Misskeyサーバーの作成に興味を持っていただきありがとうございます。 2021年現在、Misskeyのホスティングサービスは存在しないため、サーバーの作成にはある程度の知識が必要です。 サーバーの作成方法については[こちら](todo)をご覧ください。 - -### どのような技術を使用していますか? -Misskeyは開発が進むにつれ使用する技術も大きく変わってきました。開発当初はMySQL + PHP + jQueryといった構成でしたが、現在は以下のようになっています。 -- サーバーサイド: Node.js -- データベース: PostgreSQL、Redis -- UIフレームワーク: Vue.js -- プログラミング言語: TypeScript - -また、MFMやAiScriptなどの、Misskeyから派生して独自の技術も開発しています。 - -### Mastodonのフォークですか? -いいえ。MisskeyはMastodonやその他のプロジェクトとは全く別のプロジェクトです。 開発に関しても、Misskeyの方が昔から開発されています。ただし、分散型になったのはMastodonの登場より後です。 同じActivityPubという分散のためのプロトコルを実装しているという点以外、両者に特に関りがあるわけでもありません。 - -### iOS/Androidのアプリはありますか? -公式にはそういったOSのネイティブアプリを開発していませんが、サードパーティ製のアプリがいくつかあります。 詳しくは[こちら](./apps)をご覧ください。 - -ただ、サードパーティ製アプリはどうしても機能への対応が遅れてしまうため、とくに拘りがなければ公式のWebクライアントの利用をおすすめします。 なお、MisskeyのWebクライアントはPWAに対応しているので、ネイティブアプリのように動作させることも可能です。 詳しくは[こちら](todo)をご覧ください。 - -### Misskeyのロゴ、アイコンはどこで入手できますか? -(準備中) - -### 時折目にする猫耳の可愛い女の子は? -Misskeyの守り神、藍ちゃんです。アイチャンカワイイヤッター! -
ℹ️ 藍ちゃんについてはこちらです。
diff --git a/src/docs/uk-UA/general/report-issue.md b/src/docs/uk-UA/general/report-issue.md deleted file mode 100644 index 63527e32a..000000000 --- a/src/docs/uk-UA/general/report-issue.md +++ /dev/null @@ -1,8 +0,0 @@ -# 不具合の報告 -不具合と思われる状況に遭遇したときは、まず[トラブルシューティング](./troubleshooting)をご一読ください。 それでも問題が解決しないときは、以下の情報を含めて[フォーラム](https://forum.misskey.io/)に投稿してください。 投稿することで、解決策が見つかったり、不具合と判断されれば開発チームによって修正が行われます。 - -## 含める情報 -- Misskeyのバージョン([情報ページ](/about)で確認できます) -- お使いのブラウザの種類とバージョン -- お使いのOSの種類とバージョン -- 問題の再現手順 diff --git a/src/docs/uk-UA/general/troubleshooting.md b/src/docs/uk-UA/general/troubleshooting.md deleted file mode 100644 index f895b4984..000000000 --- a/src/docs/uk-UA/general/troubleshooting.md +++ /dev/null @@ -1,40 +0,0 @@ -# トラブルシューティング -
ℹ️ よくある質問も合わせてお役立てください。
- -問題が発生したときは、まずこちらをご確認ください。 該当する項目が無い、もしくは手順を試しても効果がない場合は、サーバーの管理者に連絡するか[不具合を報告](./report-issue)してください。 - -## クライアントが起動しない -ほとんどの場合、お使いのブラウザまたはOSのバージョンが古いことが原因です。 ブラウザおよびOSのバージョンを最新のものに更新してから、再度試してみてください。 - -これは稀ですが、それでも起動しない場合は、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。 - -## ページが読み込めない -クライアントが起動するもののページが読み込めないというエラーが出る場合は、ネットワークに問題がないか確認してください。また、サーバーがダウンしていないか確認してください。 - -これは稀ですが、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。 - -まだ問題がある場合は、サーバーの問題と思われるのでサーバーの管理者に連絡してください。 - -## クライアントの動作が遅い -以下を試してみてください: - -- クライアント設定で「UIのアニメーションを減らす」を有効にする -- クライアント設定で「モーダルにぼかし効果を使用」を無効にする -- お使いのブラウザの設定でハードウェアアクセラレーションを有効にする -- お使いのデバイスのスペックを上げる - -## UIの一部の表示がおかしい(背景が透明になっている等) -アップデートによりUIの改修が行われたときに、テーマのキャッシュシステムの影響でそのような表示になることがあります。 クライアントの設定の「キャッシュをクリア」すると直ります。 -
⚠️ 「クライアントの」キャッシュクリアです。「ブラウザの」キャッシュクリアは行わないでください。
- -## 通知やアンテナ等の点滅が消えない -点滅は、未読のコンテンツがあることを示しています。通常点滅が消えない場合は、コンテンツを遡ると未読なコンテンツが残っています。 すべて既読にしたと思われるのに、それでもなお点滅が続く場合(おそらく不具合と思われます)は設定から強制的にすべて既読扱いにすることができます。 - -## Renoteができない -フォロワー限定のノートはRenoteすることはできません。 - -## UI上で特定の要素が表示されない -広告ブロッカーを使用しているとそのような不具合が発生することがあります。Misskeyではオフにしてご利用ください。 - -## UI上で未翻訳の部分がある -ほとんどの場合、単に翻訳が間に合っていないだけで、不具合ではありません。翻訳が終わるまでお待ちください。 [翻訳に参加](./misskey)していただくことも可能です。 diff --git a/src/docs/uk-UA/keyboard-shortcut.md b/src/docs/uk-UA/keyboard-shortcut.md deleted file mode 100644 index 7105fc419..000000000 --- a/src/docs/uk-UA/keyboard-shortcut.md +++ /dev/null @@ -1,68 +0,0 @@ -# キーボードショートカット - -## Глобальна -これらのショートカットは基本的にどこでも使えます。 - - - - - - - - - - - -
ショートカット効果由来
P, N新規投稿Post, New, Note
Tタイムラインの最も新しい投稿にフォーカスTimeline, Top
Shift + N通知を表示/隠すNotifications
SПошукSearch
H, ?ヘルプを表示Help
- -## 投稿にフォーカスされた状態 - - - - - - - - - - - - - - - - - - - -
ショートカット効果由来
, K, Shift + Tab上の投稿にフォーカスを移動-
, J, Tab下の投稿にフォーカスを移動-
R返信フォームを開くReply
QRenoteフォームを開くQuote
Ctrl + Q即刻Renoteする(フォームを開かずに)-
E, A, +リアクションフォームを開くEmote, reAction
0~9数字に対応したリアクションをする(対応については後述)-
F, Bお気に入りに登録Favorite, Bookmark
Del, Ctrl + D投稿を削除Delete
M, O投稿に対するメニューを開くMore, Other
SCWで隠された部分を表示 or 隠すShow, See
Escフォーカスを外す-
- -## Renoteフォーム - - - - - - - - - - -
ショートカット効果由来
EnterRenoteする-
Qフォームを展開するQuote
Escフォームを閉じる-
- -## リアクションフォーム -デフォルトで「👍」にフォーカスが当たっている状態です。 - - - - - - - - - - - - - -
ショートカット効果由来
, K上のリアクションにフォーカスを移動-
, J下のリアクションにフォーカスを移動-
, H, Shift + Tab左のリアクションにフォーカスを移動-
, L, Tab右のリアクションにフォーカスを移動-
Enter, Space, +リアクション確定-
0~9数字に対応したリアクションで確定-
Escリアクションするのをやめる-
diff --git a/src/docs/uk-UA/mfm.md b/src/docs/uk-UA/mfm.md deleted file mode 100644 index e237287ac..000000000 --- a/src/docs/uk-UA/mfm.md +++ /dev/null @@ -1,2 +0,0 @@ -# MFM -MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます。 diff --git a/src/docs/uk-UA/mute.md b/src/docs/uk-UA/mute.md deleted file mode 100644 index da3cfcc36..000000000 --- a/src/docs/uk-UA/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# Ігнорувати - -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -* タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -* そのユーザーからの通知 -* メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 - -ユーザーをミュートするには、対象のユーザーのユーザーページに表示されている「ミュート」ボタンを押します。 - -ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。 - -設定>ミュート から、自分がミュートしているユーザー一覧を確認することができます。 diff --git a/src/docs/uk-UA/pages.md b/src/docs/uk-UA/pages.md deleted file mode 100644 index 55cd74544..000000000 --- a/src/docs/uk-UA/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# Pages - -## Змінні -変数を使うことで動的なページを作成できます。テキスト内で { 変数名 } と書くとそこに変数の値を埋め込めます。例えば Hello { thing } world! というテキストで、変数(thing)の値が ai だった場合、テキストは Hello ai world! になります。 - -変数の評価(値を算出すること)は上から下に行われるので、ある変数の中で自分より下の変数を参照することはできません。例えば上から A、B、C と3つの変数を定義したとき、Cの中でABを参照することはできますが、Aの中でBCを参照することはできません。 - -ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。 - -関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。 diff --git a/src/docs/uk-UA/reaction.md b/src/docs/uk-UA/reaction.md deleted file mode 100644 index 2b4dcd586..000000000 --- a/src/docs/uk-UA/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# Реакції -他の人のノートに、絵文字を付けて簡単にあなたの反応を伝えられる機能です。 リアクションするには、ノートの + アイコンをクリックしてピッカーを表示し、絵文字を選択します。 リアクションには[カスタム絵文字](./custom-emoji)も使用できます。 - -## リアクションピッカーのカスタマイズ -ピッカーに表示される絵文字を自分好みにカスタマイズすることができます。 設定の「リアクション」で設定します。 - -## リモート投稿へのリアクションについて -リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。 また、相手がMisskeyであったとしても、カスタム絵文字リアクションは伝わらず、自動的に「👍」等にフォールバックされます。 - -## リモートからのリアクションについて -リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。 diff --git a/src/docs/uk-UA/reversi-bot.md b/src/docs/uk-UA/reversi-bot.md deleted file mode 100644 index ae4980119..000000000 --- a/src/docs/uk-UA/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# MisskeyリバーシBotの開発 -Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。 - -1. `games/reversi`ストリームに以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - -2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる - * イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている - -3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する - -4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - * `game`: `game`の`id` - -5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う - -6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する - -7. ゲームが開始すると、`started`イベントが流れてくる - * イベントの中身にはゲーム情報が含まれている - -8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述) - -9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる - * `color`として石の色が含まれている - * `pos`として位置情報が含まれている - -## 位置の計算法 -8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### X,Y座標 から インデックス に変換する -``` -pos = x + (y * mapWidth) -``` -`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます: -``` -mapWidth = map[0].length -``` - -### インデックス から X,Y座標 に変換する -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## マップ情報 -マップ情報は、ゲーム情報の`map`に入っています。 文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 それをもとにマップのデザインを知る事が出来ます: -* `(スペース)` ... マス無し -* `-` ... マス -* `b` ... 初期配置される黒石 -* `w` ... 初期配置される白石 - -例えば、4*4の次のような単純なマップがあるとします: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -この場合、マップデータはこのようになります: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## ユーザーにフォームを提示して対話可能Botを作成する -ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。 - -フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します: -```javascript -{ - type: 'init-form', - body: [フォームコントロールの配列] -} -``` - -フォームコントロールの配列については今から説明します。 フォームコントロールは、次のようなオブジェクトです: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... コントロールのID。 `type` ... コントロールの種類。後述します。 `label` ... コントロールと一緒に表記するテキスト。 `value` ... コントロールのデフォルト値。 - -### フォームの操作を受け取る -ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### フォームコントロールの種類 -#### Перемикач -type: `switch` スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。 - -##### プロパティ -`label` ... スイッチに表記するテキスト。 - -#### ラジオボタン -type: `radio` ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。 - -##### プロパティ -`items` ... ラジオボタンの選択肢。例: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '強', - value: 3 -}] -``` - -#### スライダー -type: `slider` スライダーを表示します。 - -##### プロパティ -`min` ... スライダーの下限。 `max` ... スライダーの上限。 `step` ... 入力欄で刻むステップ値。 - -#### テキストボックス -type: `textbox` テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。 - -## ユーザーにメッセージを表示する -設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 メッセージを表示するには、次のメッセージをストリームに送信します: -```javascript -{ - type: 'message', - body: { - text: 'メッセージ内容', - type: 'メッセージの種類' - } -} -``` -メッセージの種類: `success`, `info`, `warning`, `error`。 - -## 投了する -投了をするには、このエンドポイントにリクエストします。 diff --git a/src/docs/uk-UA/stream.md b/src/docs/uk-UA/stream.md deleted file mode 100644 index bb9c4fbc3..000000000 --- a/src/docs/uk-UA/stream.md +++ /dev/null @@ -1,354 +0,0 @@ -# Потокове API - -ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。 - -## ストリームに接続する - -ストリーミングAPIを利用するには、まずMisskeyサーバーに**websocket**接続する必要があります。 - -以下のURLに、`i`というパラメータ名で認証情報を含めて、websocket接続してください。例: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。 - -
-

認証情報の取得については、こちらのドキュメントをご確認ください。

-
- ---- - -認証情報は省略することもできますが、その場合非ログインでの利用ということになり、受信できる情報や可能な操作は限られます。例: - -``` -%WS_URL%/streaming -``` - ---- - -ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。 - -**ストリームでのやり取りはすべてJSONです。** - -## Канали -MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。 - -### チャンネルに接続する -チャンネルに接続するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -ここで、 -* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。 -* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。 -* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。 - -
-

IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。

-
- -### チャンネルからのメッセージを受け取る -例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。 - -チャンネルがメッセージを発すると、次のようなデータがJSONでストリームに流れてきます: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。 -* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。 -* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。 - -### チャンネルに向けてメッセージを送信する -チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。 - -チャンネルにメッセージを送信するには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。 -* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。 -* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。 - -### チャンネルから切断する -チャンネルから切断するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。 - -## ストリームを経由してAPIリクエストする - -ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。 - -ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -ここで、 -* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 -* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 -* `data`には、エンドポイントのパラメータを含めます。 - -
-

APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。

-
- -### レスポンスの受信 - -APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。 - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -ここで、 -* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 -* `body`には、レスポンスが含まれています。 - -## 投稿のキャプチャ - -Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。 - -例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。 - -しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。 - -この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。 - -### 投稿をキャプチャする - -投稿をキャプチャするには、ストリームに次のようなメッセージを送信します: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャしたい投稿の`id`を設定します。 - -このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 - -例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -ここで、 -* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。 -* `body`内の`type`に、イベントの種類が設定されます。 -* `body`内の`body`に、イベントの詳細が設定されます。 - -#### イベントの種類 - -##### `reacted` -その投稿にリアクションがされた時に発生します。 - -* `reaction`に、リアクションの種類が設定されます。 -* `userId`に、リアクションを行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -その投稿が削除された時に発生します。 - -* `deletedAt`に、削除日時が設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -その投稿に添付されたアンケートに投票された時に発生します。 - -* `choice`に、選択肢IDが設定されます。 -* `userId`に、投票を行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### 投稿のキャプチャを解除する - -その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。 - -次のメッセージを送信します: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャを解除したい投稿の`id`を設定します。 - -このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 - -# チャンネル一覧 -## `main` -アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `renote` -自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。 - -#### `mention` -誰かからメンションされたときに発生するイベントです。 - -#### `readAllNotifications` -自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。 - -#### `meUpdated` -自分の情報が更新されたことを表すイベントです。 - -#### `follow` -自分が誰かをフォローしたときに発生するイベントです。 - -#### `unfollow` -自分が誰かのフォローを解除したときに発生するイベントです。 - -#### `followed` -自分が誰かにフォローされたときに発生するイベントです。 - -## `homeTimeline` -ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -タイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `localTimeline` -ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `hybridTimeline` -ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ソーシャルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `globalTimeline` -グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 diff --git a/src/docs/uk-UA/theme.md b/src/docs/uk-UA/theme.md deleted file mode 100644 index baa74c33e..000000000 --- a/src/docs/uk-UA/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# Тема - -テーマを設定して、Misskeyクライアントの見た目を変更できます。 - -## テーマの設定 -設定 > テーマ - -## テーマを作成する -テーマコードはJSON5で記述されたテーマオブジェクトです。 テーマは以下のようなオブジェクトです。 -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... テーマの一意なID。UUIDをおすすめします。 -* `name` ... テーマ名 -* `author` ... テーマの作者 -* `desc` ... テーマの説明(オプション) -* `base` ... 明るいテーマか、暗いテーマか - * `light`にすると明るいテーマになり、`dark`にすると暗いテーマになります。 - * テーマはここで設定されたベーステーマを継承します。 -* `props` ... テーマのスタイル定義。これから説明します。 - -### テーマのスタイル定義 -`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 - -#### バリューで使える構文 -* 16進数で表された色 - * 例: `#00ff00` -* `rgb(r, g, b)`形式で表された色 - * 例: `rgb(0, 255, 0)` -* `rgb(r, g, b, a)`形式で表された透明度を含む色 - * 例: `rgba(0, 255, 0, 0.5)` -* 他のキーの値の参照 - * `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。 - * 例: `@panel` -* 定数(後述)の参照 - * `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。 - * 例: `$main` -* 関数(後述) - * `:{関数名}<{引数}<{色}` - -#### 定数 -「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 キー名を`$`で始めると、そのキーはCSS変数として出力されません。 - -#### Функції -wip diff --git a/src/docs/uk-UA/timelines.md b/src/docs/uk-UA/timelines.md deleted file mode 100644 index 92cf394d6..000000000 --- a/src/docs/uk-UA/timelines.md +++ /dev/null @@ -1,15 +0,0 @@ -# タイムラインの比較 - -https://docs.google.com/spreadsheets/d/1lxQ2ugKrhz58Bg96HTDK_2F98BUritkMyIiBkOByjHA/edit?usp=sharing - -## Домівка -自分のフォローしているユーザーの投稿 - -## Локальна -全てのローカルユーザーの「ホーム」指定されていない投稿 - -## Соціальна -自分のフォローしているユーザーの投稿と、全てのローカルユーザーの「ホーム」指定されていない投稿 - -## Глобальна -全てのローカルユーザーの「ホーム」指定されていない投稿と、サーバーに届いた全てのリモートユーザーの「ホーム」指定されていない投稿 diff --git a/src/docs/zh-CN/admin/disable-timelines.md b/src/docs/zh-CN/admin/disable-timelines.md deleted file mode 100644 index fdc66a689..000000000 --- a/src/docs/zh-CN/admin/disable-timelines.md +++ /dev/null @@ -1,8 +0,0 @@ -# 禁用 LTL/STL/GTL -Misskey 允许您禁用 LTL/STL/GTL。如果需要启用/禁用,请在实例控制面板中进行设置。 - -LTL 和 STL 的优点是新用户不必寻找用户,因为他们可以查看来自所有实例的帖子,从而更容易找到感兴趣的用户。 但同时它也存在着诸多缺点,例如无法使用关注,容易看到不适宜的帖子,感觉像小圈子内部对话一样而使新用户难以参与等等。 不同的服务器会有不同的优缺点,因此可以选择禁用它们。 如果您认为弊大于利,请考虑禁用这些时间线。 - -
⚠️ 禁用后可能会使用户感到困惑,并导致短期内的用户数量减少。因此,建议在禁用时慎重考虑影响。建议事先发布声明并留出一定时间作为过渡。
- -请注意,这些时间线的禁用状态不适用于管理员/版主,这些用户可以继续使用。 diff --git a/src/docs/zh-CN/admin/faq.md b/src/docs/zh-CN/admin/faq.md deleted file mode 100644 index 00d0b5e8c..000000000 --- a/src/docs/zh-CN/admin/faq.md +++ /dev/null @@ -1,5 +0,0 @@ -# 常见问题 -这里会列出对于服务器管理员的一些常见问题。 - -## 希望设置默认主题 -目前尚未实现默认主题设置功能。 diff --git a/src/docs/zh-CN/advanced/aiscript.md b/src/docs/zh-CN/advanced/aiscript.md deleted file mode 100644 index 5622a8232..000000000 --- a/src/docs/zh-CN/advanced/aiscript.md +++ /dev/null @@ -1,7 +0,0 @@ -# AiScript -AiScript是Misskey所使用的脚本语言。 - -
AiScript 的实现独立于 Misskey 的存储库,并且是 开源的。
- -## 用法 -AiScript 语法和内置函数等文档会在 [ 这里 ](https://github.com/syuilo/aiscript/tree/master/docs) 发布。 diff --git a/src/docs/zh-CN/advanced/api.md b/src/docs/zh-CN/advanced/api.md deleted file mode 100644 index a1ca2f470..000000000 --- a/src/docs/zh-CN/advanced/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -您可以使用Misskey API来开发Misskey客户端、与Misskey链接的Web服务、Bot等应用(以下称为“应用程序”)。 另外还有一个流式API,因此还可以用来创建实时性的应用程序。 - -开始使用API前​​,您首先需要获取访问令牌。 本文档将向您介绍获取访问令牌所需的步骤,以及API的基本使用方法。 - -## 访问令牌的获取 -总的来说,API请求需要访问令牌。 获取方式则根据请求的API或者非特定用户所使用的应用程序而有所不同。 - -* 对于前者:请转到[“手动发放自己的访问令牌”](#自分自身のアクセストークンを手動発行する) -* 对于后者:请转到[“请求应用程序用户发放访问令牌”](#アプリケーション利用者にアクセストークンの発行をリクエストする) - -### 手动发放自己的访问令牌 -您可以在“设置 > API”中发放自己的访问令牌。 - -[请转到“API使用方法”](#APIの使い方) - -### 请求应用程序用户发放访问令牌 -要获取应用程序用户的访问令牌,请按照以下步骤请求发放。 - -#### 步骤 1 - -生成UUID。以下将其称为会话ID。 - -> 此会话ID需要每次重新生成,请勿重复使用。 - -#### 步骤 2 - -在用户的浏览器中显示`{_URL_}/miauth/{session}`。将`{session}`的部分替换为会话ID。 -> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -显示时,可以在URL中设置一些选项作为查询参数: -* `name` ... 应用程序名称 - * > 例: `MissDeck` -* `icon` ... 应用程序图标URL - * > 例: `https://missdeck.example.com/icon.png` -* `callback` ... 认证后重定向的URL - * > 例: `https://missdeck.example.com/callback` - * 重定向时,会话ID将添加查询参数`session` -* `permission` ... 应用程序要求的权限 - * > 例: `write:notes,write:following,read:drive` - * 要求的权限需要以`,`分隔 - * 您可以在[API参考](/api-doc)中确认您所拥有的权限。 - -#### 步骤 3 -用户允许发行后,对`{_URL_}/api/miauth/{session}/check`的POST请求所返回的是一个包含访问令牌的JSON格式的响应。 - -响应中包含的属性: -* `token` ... 用户的访问令牌 -* `user` ... 用户信息 - -[请转到“API使用方法”](#APIの使い方) - -## API使用方法 -**所有API均为POST,并且请求/响应均为JSON格式。不是REST。** 访问令牌包含在请求中,参数名为`i`。 - -* [API 参考](/api-doc) -* [流式API](./stream) diff --git a/src/docs/zh-CN/advanced/create-plugin.md b/src/docs/zh-CN/advanced/create-plugin.md deleted file mode 100644 index a32d36fa8..000000000 --- a/src/docs/zh-CN/advanced/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# 插件开发 -Misskey Web客户端插件功能使您可以扩展客户端并添加各种功能。 我们在这里给出用于创建插件的元数据定义和AiScript API参考。 - -## 元数据 -插件必须使用AiScript的元数据嵌入功能将插件的元数据定义为默认值。 元数据是一个包含以下属性的对象: - -### name -插件名称 - -### author -插件作者 - -### version -插件版本。请使用数字。 - -### description -插件说明 - -### permissions -插件要求的权限。需要在发送Misskey API请求时使用。 - -### config -表示插件设置信息的对象。 在键名中包含设置名称,在键值中包含以下属性。 - -#### type -代表设置值的类型的字符串。从下列项中选择: string number boolean - -#### label -向用户显示的设置名称 - -#### description -设置说明 - -#### default -设置的默认值 - -## API 参考 -AiScript标准内置API将不会公布。 - -### Mk:dialog(title text type) -显示一个对话框。type可以设置为以下值: info success warn error question 默认值为info。 - -### Mk:confirm(title text type) -显示确认对话框。type可以设置为以下值: info success warn error question 默认值为question。 如果用户选择“OK”,则返回true;如果用户选择“取消”,则返回false。 - -### Mk:api(endpoint params) -通过Misskey API发送请求。在第一个参数中传入终端名称,在第二个参数中传入参数对象。 - -### Mk:save(key value) -给任意对象名赋值,并使其持久化。所谓的持久化的值,指的是该值即使在AiScript上下文结束后仍然保留,并且可以通过Mk:load读取。 - -### Mk:load(key) -读取由Mk:save生成的持久化的值。 - -### Plugin:register_post_form_action(title fn) -将操作添加到发布表单。第一个参数是操作名,第二个参数是该操作对应的回调函数。 帖子表单对象作为第一个参数传给回调函数。 - -### Plugin:register_note_action(title fn) -将项目添加到帖子菜单。第一个参数是菜单项名字,第二个参数是该菜单项对应的回调函数。 目标项目对象作为第一个参数传给回调函数。 - -### Plugin:register_user_action(title fn) -将项目添加到用户菜单。第一个参数是菜单项名字,第二个参数是该菜单项对应的回调函数。 目标用户对象作为第一个参数传给回调函数。 - -### Plugin:register_note_view_interruptor(fn) -改写显示在UI上的帖子信息。 目标帖子对象作为第一个参数传给回调函数。 该帖子将会使用回调函数的返回值进行改写。 - -### Plugin:register_note_post_interruptor(fn) -发贴时改写帖子信息。 目标帖子对象作为第一个参数传给回调函数。 该帖子将会使用回调函数的返回值进行改写。 - -### Plugin:open_url(url) -在浏览器的新标签页中打开第一个参数传入的URL。 - -### Plugin:config -存储插件设置的对象。该值是通过插件定义的配置中设置的键值来传入的。 diff --git a/src/docs/zh-CN/advanced/develop-bot.md b/src/docs/zh-CN/advanced/develop-bot.md deleted file mode 100644 index 593c61891..000000000 --- a/src/docs/zh-CN/advanced/develop-bot.md +++ /dev/null @@ -1,6 +0,0 @@ -# 新建 Bot -您可以使用 [Misskey API](./api)来开发Bot机器人。此外,一些机器人已经公开发布,您可以把它们作为参考。 - -- [syuilo/ai](https://github.com/syuilo/ai) ... 运行在Node.js上的TypeScript实现的Bot - -创建机器人时,我们强烈建议您在个人资料设置中启用Bot机器人标志。 diff --git a/src/docs/zh-CN/advanced/reversi-bot.md b/src/docs/zh-CN/advanced/reversi-bot.md deleted file mode 100644 index 96a252b38..000000000 --- a/src/docs/zh-CN/advanced/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# Misskey黑白棋机器人开发 -下面列出的是为 Misskey 黑白棋功能开发一个Bot机器人的方法。 - -1. 使用以下参数来连接到`games/reversi`流: - * `i`: bot账号的API Key - -2. 当出现对局邀请时,流中会触发`invited`事件 - * 事件内容中包含邀请您参加游戏的用户信息,用户名字为`parent`。 - -3. 向`games/reversi/match`发送请求,其中`user_id`包含`parent`的`id` - -4. 请求成功时将返回游戏信息,可以使用以下参数连接到`games/reversi-game`流: - * `i`: bot账号的API Key - * `game`: `game`的`id` - -5. 与此同时,每次对手更改游戏设置时,都会触发`update-settings`事件,如果有必要的话,需要对其进行处理。 - -6. 满足设定条件时,向流发送`{ type: 'accept' }`消息 - -7. 游戏开始时会触发`started`事件 - * 游戏状态信息会包含在该事件中 - -8. 要放置棋子,向流发送`{ type: 'set', pos: <位置> }`(后面会说明位置的计算方法) - -9. 当对方或者您放置棋子时,会触发`set`事件 - * `color`中包含该棋子的颜色 - * `pos`中包含该棋子的位置 - -## 位置计算方法 -当棋盘尺寸为8x8时,每个方格的位置(称为索引)如下所示: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### 从X,Y坐标转换为索引 -``` -pos = x + (y * mapWidth) -``` -`mapWidth`可以根据游戏信息中的`map`,通过如下方法计算出来: -``` -mapWidth = map[0].length -``` - -### 从索引转换为X,Y坐标 -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## 棋盘信息 -棋盘信息包含在游戏信息的`map`中。 它是一个字符串数组,每个字符代表一块格子的信息。 您可以根据这些来了解地图如何设计: -* `(空)` ... 没有格子 -* `-` ... 格子 -* `b` ... 黑子先下 -* `w` ... 白子先下 - -以下面这个4*4的简单棋盘为例: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -这种情况下,棋盘数据是这样的: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## 能和用户互动的交互式Bot机器人的创建 -要和用户交互,您可以在游戏设置屏幕上向用户显示提示窗口。 例如,可以让用户选择Bot机器人的难度。 - -要显示窗口,需要向`reversi-game`流发送下列消息: -```javascript -{ - type: 'init-form', - body: [表单控件数组] -} -``` - -下面说明窗口控件数组的结构。 窗口控件指的是如下面所示的对象: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... 控件ID。 `type` ... 控件类型。说明详见后文。 `label` ... 控件元素上显示的文字。 `value` ... 控件元素的默认值。 - -### 控件行为的处理 -当用户与对话框交互时将会触发流的`update-form`事件。 事件的内容包含控件的ID和用户设置的值。 例如,如果用户将上面显示的开关控件打开,则将触发以下事件: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### 窗口控件的类型 -#### 开关 -type: `switch` 显示一个开关。当您想要打开/关闭某些功能时非常有用。 - -##### 属性 -`label` ... 开关上显示的文字。 - -#### 单选按钮 -type: `radio` 显示一个单选按钮。用来表示单项选择。例如,可以选择Bot机器人的难度。 - -##### 属性 -`items` ... 单元按钮的选择项。例: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '强', - value: 3 -}] -``` - -#### 滑块 -type: `slider` 显示一个滑块。 - -##### 属性 -`min` ... 滑块最小值。 `max` ... 滑块最大值。 `step` ... 滑块值的步长。 - -#### 文本框 -type: `textbox` 显示一个文本框。可以在各种需要用户输入的地方使用。 - -## 向用户显示消息 -设置屏幕上与用户交互,是除了对话框外的另一种方法。您可以向用户显示一条消息。 例如,当用户选择Bot机器人不支持的模式或棋盘时显示警告。 要显示消息,请将以下消息发送到流: -```javascript -{ - type: 'message', - body: { - text: '消息内容', - type: '消息类型' - } -} -``` -消息类型:`success`, `info`, `warning`, `error`。 - -## 认输 -要认输,请发送请求到这个终端。 diff --git a/src/docs/zh-CN/advanced/share-page.md b/src/docs/zh-CN/advanced/share-page.md deleted file mode 100644 index 56f6d5ec1..000000000 --- a/src/docs/zh-CN/advanced/share-page.md +++ /dev/null @@ -1,54 +0,0 @@ -# 分享页面 -`/share`を開くと、共有用の投稿フォームを開くことができます。 ここではシェアページで利用できるクエリ文字列の一覧を示します。 - -## 查询文本列表 -### 文本 - -
-
title
-
标题。[ … ]将被插入到文本开头。
-
text
-
正文。
-
url
-
URL。它将被插入到末尾。
-
- -### リプライ情報 -以下のいずれか - -
-
replyId
-
リプライ先のノートid
-
replyUri
-
リプライ先のUrl(リモートのノートオブジェクトを指定)
-
- -### Renote情報 -以下のいずれか - -
-
renoteId
-
Renote先のノートid
-
renoteUri
-
Renote先のUrl(リモートのノートオブジェクトを指定)
-
- -### 可见性 -※specifiedに相当する値はvisibility=specifiedとvisibleAccts/visibleUserIdsで指定する - -
-
visibility
-
公開範囲 ['public' | 'home' | 'followers' | 'specified']
-
localOnly
-
0(false) or 1(true)
-
visibleUserIds
-
specified時のダイレクト先のユーザーid カンマ区切りで
-
visibleAccts
-
specified時のダイレクト先のacct(@?username[@host]) カンマ区切りで
-
- -### 文件 -
-
fileIds
-
添付したいファイルのid(カンマ区切りで)
-
diff --git a/src/docs/zh-CN/advanced/stream.md b/src/docs/zh-CN/advanced/stream.md deleted file mode 100644 index 16093e0b9..000000000 --- a/src/docs/zh-CN/advanced/stream.md +++ /dev/null @@ -1,350 +0,0 @@ -# 流式API - -通过流式API,您可以实时接收各种信息(例如,你的时间线中的新帖文,收到的消息,关注等),并进行各种操作。 - -## 连接到流 - -要使用流式API,您需要使用**websocket**连接到Misskey服务器。 - -请使用参数`i`连接到以下URL,并在websocket连接中包含认证信息。例如: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -认证信息是您的API密钥,从应用程序连接到流时需要引用的用户访问令牌 - -
ℹ️ 关于如何获取认证信息,请参考此文档
- ---- - -您可以省略身份验证信息。此时无需登录即可使用,但是可以接收的信息和可以执行的操作将受到限制。例: - -``` -%WS_URL%/streaming -``` - ---- - -ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。 - -**ストリームでのやり取りはすべてJSONです。** - -## 频道 -MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。 - -ひとつのストリーム上で、同時に複数のチャンネルに接続することができます。 - -### 连接到频道 -要连接到频道,请将JSON数据发送到流: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -其中: -* `channel`には接続したいチャンネル名を設定します。频道类型将在后面说明。 -* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。 -* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。 - -
ℹ️ IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。
- -### 从频道接收消息 -例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。 - -当频道发送消息时,以下数据将以JSON格式传输到流中: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -其中: -* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。 -* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。 -* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。 - -### 向频道发送消息 -チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。 - -要将消息发送到频道,请将JSON格式数据发送到流: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -其中: -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。 -* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。 -* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。 - -### 断开频道连接 -チャンネルから切断するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -其中: -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。 - -## 通过流发送API请求 - -ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。 - -ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -其中: -* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 -* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 -* `data`には、エンドポイントのパラメータを含めます。 - -
ℹ️ APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。
- -### レスポンスの受信 - -APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。 - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -其中: -* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 -* `body`には、レスポンスが含まれています。 - -## 投稿のキャプチャ - -Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。 - -例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。 - -しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。 - -この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。 - -### 投稿をキャプチャする - -投稿をキャプチャするには、ストリームに次のようなメッセージを送信します: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -其中: -* `id`にキャプチャしたい投稿の`id`を設定します。 - -このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 - -例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -其中: -* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。 -* `body`内の`type`に、イベントの種類が設定されます。 -* `body`内の`body`に、イベントの詳細が設定されます。 - -#### 事件类型 - -##### `reacted` -その投稿にリアクションがされた時に発生します。 - -* `reaction`に、リアクションの種類が設定されます。 -* `userId`に、リアクションを行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -その投稿が削除された時に発生します。 - -* `deletedAt`表示删除的日期和时间。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -その投稿に添付されたアンケートに投票された時に発生します。 - -* `choice`に、選択肢IDが設定されます。 -* `userId`に、投票を行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### 投稿のキャプチャを解除する - -その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。 - -次のメッセージを送信します: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -其中: -* `id`にキャプチャを解除したい投稿の`id`を設定します。 - -このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 - -# チャンネル一覧 -## `main` -アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `renote` -自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。 - -#### `mention` -誰かからメンションされたときに発生するイベントです。 - -#### `readAllNotifications` -自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。 - -#### `meUpdated` -自分の情報が更新されたことを表すイベントです。 - -#### `follow` -自分が誰かをフォローしたときに発生するイベントです。 - -#### `unfollow` -自分が誰かのフォローを解除したときに発生するイベントです。 - -#### `followed` -自分が誰かにフォローされたときに発生するイベントです。 - -## `homeTimeline` -ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -タイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `localTimeline` -ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `hybridTimeline` -ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ソーシャルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `globalTimeline` -グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 diff --git a/src/docs/zh-CN/aiscript.md b/src/docs/zh-CN/aiscript.md deleted file mode 100644 index 0747cf875..000000000 --- a/src/docs/zh-CN/aiscript.md +++ /dev/null @@ -1,4 +0,0 @@ -# AiScript - -## 函数 -传递默认值。 diff --git a/src/docs/zh-CN/api.md b/src/docs/zh-CN/api.md deleted file mode 100644 index 4a67622e3..000000000 --- a/src/docs/zh-CN/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -您可以使用Misskey API来开发Misskey客户端、与Misskey链接的Web服务、Bot等应用(以下称为“应用程序”)。 另外还有一个流式API,因此还可以用来创建实时性的应用程序。 - -开始使用API前​​,您首先需要获取访问令牌。 本文档将引导您完成获取访问令牌的步骤,然后介绍API的基本使用方法。 - -## 访问令牌的获取 -总的来说,API请求需要访问令牌。 获取方式则根据请求的API或者非特定用户所使用的应用程序而有所不同。 - -* 对于前者:转到[“手动发放自己的访问令牌”](#自分自身のアクセストークンを手動発行する) -* 对于后者:转到[“请求应用程序用户发放访问令牌”](#アプリケーション利用者にアクセストークンの発行をリクエストする) - -### 手动发放自己的访问令牌 -您可以在“设置 > API”中发放自己的访问令牌。 - -[转到“API使用方法”](#APIの使い方) - -### 请求应用程序用户发放访问令牌 -要获取应用程序用户的访问令牌,请按照以下步骤请求发放。 - -#### Step 1 - -生成UUID。以下将其称为会话ID。 - -> 此会话ID需要每次重新生成,请勿重复使用。 - -#### Step 2 - -在用户的浏览器中显示`{_URL_}/miauth/{session}`。将`{session}`的部分替换为会话ID。 -> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -显示时,可以在URL中设置一些选项作为查询参数: -* `name` ... 应用程序名称 - * > 例: `MissDeck` -* `icon` ... 应用程序图标URL - * > 例: `https://missdeck.example.com/icon.png` -* `callback` ... 认证后重定向的URL - * > 例: `https://missdeck.example.com/callback` - * 重定向时,会话ID将添加查询参数`session` -* `permission` ... 应用程序要求的权限 - * > 例: `write:notes,write:following,read:drive` - * 要求的权限需要以`,`分隔 - * 您可以在[API参考](/api-doc)中确认您所拥有的权限。 - -#### Step 3 -用户允许发行后,对`{_URL_}/api/miauth/{session}/check`的POST请求所返回的是一个包含访问令牌的JSON格式的响应。 - -响应中包含的属性: -* `token` ... 用户的访问令牌 -* `user` ... 用户信息 - -[转到“API使用方法”](#APIの使い方) - -## API使用方法 -**所有API均为POST,并且请求/响应均为JSON格式。不是REST。** 访问令牌包含在请求中,参数名为`i`。 - -* [API 参考](/api-doc) -* [流式API](./stream) diff --git a/src/docs/zh-CN/create-plugin.md b/src/docs/zh-CN/create-plugin.md deleted file mode 100644 index beda1c042..000000000 --- a/src/docs/zh-CN/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# 插件开发 -Misskey Web客户端插件功能使您可以扩展客户端并添加各种功能。 我们在这里给出用于创建插件的元数据定义和AiScript API参考。 - -## 元数据 -插件必须使用AiScript的元数据嵌入功能将插件的元数据定义为默认值。 元数据是一个包含以下属性的对象: - -### name -插件名称 - -### author -插件作者 - -### version -插件版本。请使用数字。 - -### description -插件说明 - -### permissions -插件要求的权限。在发送Misskey API请求时需要使用。 - -### config -表示插件设置信息的对象。 在键名中包含设置名称,在键值中包含以下属性。 - -#### type -代表设置值的类型的字符串。从下列项中选择: string number boolean - -#### label -显示给用户的设置名称 - -#### description -设置说明 - -#### default -设置的默认值 - -## API 参考 -AiScript标准的内置API不会发布。 - -### Mk:dialog(title text type) -显示一个对话框。type可以设置为以下值: info success warn error question 默认值为info。 - -### Mk:confirm(title text type) -显示确认对话框。type可以设置为以下值: info success warn error question 默认值为question。 如果用户选择“OK”,则返回true;如果用户选择“取消”,则返回false。 - -### Mk:api(endpoint params) -Misskey API请求在第一个参数中传递终端名称,在第二个参数中传递参数对象。 - -### Mk:save(key value) -给任何名称赋任何值并使其持久化。所谓的持久化的值,指的是该值即使在AiScript上下文结束后仍然保留,并且可以通过Mk:load读取。 - -### Mk:load(key) -读取由Mk:save生成的持久化的值。 - -### Plugin:register_post_form_action(title fn) -将操作添加到发布表单。第一个参数是操作名,第二个参数是该操作对应的回调函数。 帖子表单对象作为第一个参数传给回调函数。 - -### Plugin:register_note_action(title fn) -将项目添加到帖子菜单。第一个参数是菜单项名字,第二个参数是该菜单项对应的回调函数。 目标项目对象作为第一个参数传给回调函数。 - -### Plugin:register_user_action(title fn) -将项目添加到用户菜单。第一个参数是菜单项名字,第二个参数是该菜单项对应的回调函数。 目标用户对象作为第一个参数传给回调函数。 - -### Plugin:register_note_view_interruptor(fn) -改写显示在UI上的帖子信息。 目标帖子对象作为第一个参数传给回调函数。 该帖子将会使用回调函数的返回值进行改写。 - -### Plugin:register_note_post_interruptor(fn) -发贴时改写帖子信息。 目标帖子对象作为第一个参数传给回调函数。 该帖子将会使用回调函数的返回值进行改写。 - -### Plugin:open_url(url) -在浏览器的新标签页中打开第一个参数传入的URL。 - -### Plugin:config -存储插件设置的对象。该值是通过插件定义的配置中设置的键值来传入的。 diff --git a/src/docs/zh-CN/custom-emoji.md b/src/docs/zh-CN/custom-emoji.md deleted file mode 100644 index 7c55a6b40..000000000 --- a/src/docs/zh-CN/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# 自定义表情符号 -表情符号功能可以让您在各个地方使用预置的图像表情。 它可以用于发帖,回应,聊天,自我介绍和姓名等地方。 要在这些位置使用自定义表情符号,请按表情符号选择按钮(如果有)或键入`:`以显示表情符号建议。 如果在文本中找到格式为`:foo:`的字符串,则将`foo`部分解释为自定义表情符号名称,并在显示时替换为相应的自定义表情符号。 diff --git a/src/docs/zh-CN/deck.md b/src/docs/zh-CN/deck.md deleted file mode 100644 index b1f114e71..000000000 --- a/src/docs/zh-CN/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# Deck - -卡片是一种可用的用户界面。它的特点是能够通过并排显示多个视图(称为 "列")来构建高度可定制和信息丰富的用户界面。 - -## 添加列 -您可以在卡牌背景上点击右键单击「添加列」来新增任意的列。 - -## 移动列 -可以通过拖放列来与其他列互换位置,也可以从列菜单中移动列(右键单击列标题)。 - -## 水平拆分列 -列不仅可以从左到右排列,还可以垂直叠加。 如果打开列菜单,选择「向左折叠」,当前列将被移到左列下方。 要取消垂直折叠,请选择列菜单中的「向右弹出」。 - -## 列的设置 -选择列菜单的「编辑」时,可编辑当前列的设置。您可以重新命名列,或是改变列的宽度。 - -## Deck的设置 -您可以在[settings/deck](/settings/deck)行中配置您Deck相关的设置。 diff --git a/src/docs/zh-CN/features/antenna.md b/src/docs/zh-CN/features/antenna.md deleted file mode 100644 index 4645df2d6..000000000 --- a/src/docs/zh-CN/features/antenna.md +++ /dev/null @@ -1,4 +0,0 @@ -# 天线 -アンテナは、自由に条件を設定して、合致するノートを自動で収集することができる機能です。 - -条件を設定したアンテナが作成された状態で、条件に合致するノートが投稿されると、リアルタイムでそのアンテナのタイムラインにノートが追加されます。 diff --git a/src/docs/zh-CN/features/custom-emoji.md b/src/docs/zh-CN/features/custom-emoji.md deleted file mode 100644 index 9fc18a70f..000000000 --- a/src/docs/zh-CN/features/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# 自定义表情符号 -カスタム絵文字は、インスタンスで用意された画像を絵文字のように使える機能です。 ノート、リアクション、チャット、自己紹介、名前などの場所で使うことができます。 カスタム絵文字をそれらの場所で使うには、絵文字ピッカーボタン(ある場合)を押すか、`:`を入力して絵文字サジェストを表示します。 テキスト内に`:foo:`のような形式の文字列が見つかると、`foo`の部分がカスタム絵文字名と解釈され、表示時には対応したカスタム絵文字に置き換わります。 diff --git a/src/docs/zh-CN/features/deck.md b/src/docs/zh-CN/features/deck.md deleted file mode 100644 index 73e9efdaa..000000000 --- a/src/docs/zh-CN/features/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# Deck - -デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。 - -## カラムの追加 -デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。 - -## カラムの移動 -カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。 - -## カラムの水平分割 -カラムは左右だけでなく、上下に並べることもできます。 カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 上下分割を解除するには、カラムメニューの「右に出す」を選択します。 - -## カラムの設定 -カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。 - -## デッキの設定 -デッキに関する設定は、[settings/deck](/settings/deck)で行えます。 diff --git a/src/docs/zh-CN/features/drive.md b/src/docs/zh-CN/features/drive.md deleted file mode 100644 index 4728ccf65..000000000 --- a/src/docs/zh-CN/features/drive.md +++ /dev/null @@ -1,17 +0,0 @@ -# 网盘 -ドライブは、Misskey上でファイルを管理できる機能です。 - -[ドライブのページ](/my/drive)から任意のファイルをアップロードできるほか、アバターに設定した画像や、ノートに添付したファイルなどもすべてドライブにアップロードされます。 - -
⚠️ ドライブからファイルを削除すると、そのファイルが添付されたノートも消えます。
- -ドライブにアップロードされたファイルは、いつでもダウンロードすることができるほか、ノート作成時に「ドライブからファイルを添付」することでファイルを再利用することもできます。 - -ドライブ内にフォルダを作り、複数のファイルをまとめて整理することもできます。 - -## 閲覧注意 (NSFW) -
ℹ️ この項目が閲覧注意なわけではありません
- -閲覧注意またはNSFW (Not safe for work) は、ドライブのファイルに設定することができるフラグです。 閲覧注意フラグを設定されたファイルは、表示される際に閲覧者の操作なしには表示されなくなります。 このフラグは、例えば職場や公共の場で閲覧するのに適切でないと思われる画像などに設定し、そのような画像が突然表示されてしまうことを防ぐ目的で使われます。 - -このフラグは手動でオンオフを切り替えられるほか、モデレーターの判断で設定される場合もあります。 diff --git a/src/docs/zh-CN/features/favorite.md b/src/docs/zh-CN/features/favorite.md deleted file mode 100644 index 587687f77..000000000 --- a/src/docs/zh-CN/features/favorite.md +++ /dev/null @@ -1,4 +0,0 @@ -# 收藏 -[ノート](./node)をお気に入りとして登録できる機能です。 お気に入り登録したノートは、[お気に入りページ](./my/favorites)で一覧することができます。 お気に入りに登録したことは相手に通知されず、お気に入りは自分しか見ることができません。 - -ノートをお気に入り登録するには、ノートメニューの「お気に入り」を押します。お気に入り解除するには、ノートメニューの「お気に入り解除」を押します。 diff --git a/src/docs/zh-CN/features/follow.md b/src/docs/zh-CN/features/follow.md deleted file mode 100644 index 2a95aa6dc..000000000 --- a/src/docs/zh-CN/features/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# 关注 -当您关注一名用户时,您可以在您的时间线上看到该用户的发帖。但是不包含该用户对其他用户的回复。 要关注一名用户,请点击该用户页面上的“关注”按钮。如果需要取消关注,请再次点击该按钮。 diff --git a/src/docs/zh-CN/features/keyboard-shortcut.md b/src/docs/zh-CN/features/keyboard-shortcut.md deleted file mode 100644 index b555e34f4..000000000 --- a/src/docs/zh-CN/features/keyboard-shortcut.md +++ /dev/null @@ -1,66 +0,0 @@ -# キーボードショートカット - -## 全局 -これらのショートカットは基本的にどこでも使えます。 - - - - - - - - - - - -
ショートカット効果由来
P, N新規投稿Post, New, Note
Tタイムラインの最も新しい投稿にフォーカスTimeline, Top
Shift + N通知を表示/隠すNotifications
S搜索Search
H, ?ヘルプを表示Help
- -## 投稿にフォーカスされた状態 - - - - - - - - - - - - - - - - - - -
ショートカット効果由来
, K, Shift + Tab上の投稿にフォーカスを移動-
, J, Tab下の投稿にフォーカスを移動-
R返信フォームを開くReply
QRenoteフォームを開くQuote
Ctrl + Q即刻Renoteする(フォームを開かずに)-
E, A, +リアクションフォームを開くEmote, reAction
0~9数字に対応したリアクションをする(対応については後述)-
F, Bお気に入りに登録Favorite, Bookmark
Del, Ctrl + D投稿を削除Delete
M, O投稿に対するメニューを開くMore, Other
S显示或隐藏CW的隐藏部分Show, See
Escフォーカスを外す-
- -## Renoteフォーム - - - - - - - - - -
ショートカット効果由来
EnterRenoteする-
Qフォームを展開するQuote
Escフォームを閉じる-
- -## リアクションフォーム -デフォルトで「👍」にフォーカスが当たっている状態です。 - - - - - - - - - - - - - -
ショートカット効果由来
, K上のリアクションにフォーカスを移動-
, J下のリアクションにフォーカスを移動-
, H, Shift + Tab左のリアクションにフォーカスを移動-
, L, Tab右のリアクションにフォーカスを移動-
Enter, Space, +リアクション確定-
0~9数字に対応したリアクションで確定-
Escリアクションするのをやめる-
diff --git a/src/docs/zh-CN/features/mfm.md b/src/docs/zh-CN/features/mfm.md deleted file mode 100644 index 8bcaacbed..000000000 --- a/src/docs/zh-CN/features/mfm.md +++ /dev/null @@ -1,12 +0,0 @@ -# MFM -MFM是Misskey Flavored Markdown的缩写,是一种专用的标记语言,可以用在Misskey的任何地方。 MFM中可用的语法可以在[MFM代码速查表](/mfm-cheat-sheet)中找到。 - -## 使用 MFM 的位置示例 -- 帖子正文 -- CW注释 -- 用户姓名 -- 用户自我介绍 - -## 面向开发者的信息 -MFM 的解析器实现作为库发布,可以轻松地将 MFM 嵌入到客户端中。 -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScript的解析器实现 diff --git a/src/docs/zh-CN/features/mute-and-block.md b/src/docs/zh-CN/features/mute-and-block.md deleted file mode 100644 index 39ed8459d..000000000 --- a/src/docs/zh-CN/features/mute-and-block.md +++ /dev/null @@ -1,41 +0,0 @@ -# 屏蔽/拉黑 -好みではないユーザーがいる場合は、ミュートを行うことでそのユーザーが自分から見えないようにすることができます。 また、より強力な措置として、ブロックを行うことでそのユーザーから自分のコンテンツが見えないようになるほか、自分に対して関わることができないようにすることができます。 ミュートされていることは相手は分かりませんが、ブロックされていることは相手に分かります。どちらを選ぶかはご自身の判断で行ってください。 - -
ℹ️ ミュートとブロックは併用できます。
- -
⚠️ 利用規約に違反するような、迷惑なユーザーがいる場合は運営者に報告することも検討してください。
- -設定>ミュートとブロック から、自分がミュートまたはブロックしているユーザー一覧を確認することができます。 - -## 屏蔽 -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -- タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -- そのユーザーからの通知 -- メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 -- など - -ユーザーをミュートするには、対象のユーザーのユーザーページのメニューを開き、「ミュート」ボタンを押します。 - -
ℹ️ ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。
- -## 拉黑 -ユーザーをブロックすると、そのユーザーからあなたのコンテンツが見えないようになり、またあなたに対して以下のようなアクションをすることができなくなります。 - -- フォローする -- ユーザーリストに追加する -- 返信する、Renoteする -- リアクションする、アンケートに投票する -- メッセージを送信する -- など - -また、 - -- ブロックする際に既にそのユーザーからフォローされていた場合はフォローが解除されます。 -- ブロックする際に既にそのユーザーがあなたをユーザーリストに入れていた場合はそのリストからあなたが削除されます。 - -ユーザーをブロックするには、対象のユーザーのユーザーページのメニューを開き、「ブロック」ボタンを押します。 - -
⚠️ ブロックを行ったこと自体は相手に通知されませんが、フォローを行ったりなどの上記のアクションが行えなくなるので間接的にブロックされていることは分かります。
- -
⚠️ 相手から自分のコンテンツが見えなくなりますが、相手がアカウントを切り替えたりログアウト状態になれば見ることができます。あくまで簡易的、補助的なものとしてお考えください。
diff --git a/src/docs/zh-CN/features/mute.md b/src/docs/zh-CN/features/mute.md deleted file mode 100644 index 502e04ea8..000000000 --- a/src/docs/zh-CN/features/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# 屏蔽 - -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -* タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -* そのユーザーからの通知 -* メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 - -ユーザーをミュートするには、対象のユーザーのユーザーページに表示されている「ミュート」ボタンを押します。 - -ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。 - -設定>ミュート から、自分がミュートしているユーザー一覧を確認することができます。 diff --git a/src/docs/zh-CN/features/note.md b/src/docs/zh-CN/features/note.md deleted file mode 100644 index b3ed79c8e..000000000 --- a/src/docs/zh-CN/features/note.md +++ /dev/null @@ -1,54 +0,0 @@ -# 帖子 -ノートは、Misskeyに投稿される、文章、ファイル、アンケートなどを含むコンテンツで、Misskeyの中心的概念です。また、そのノートを作成する行為自体もノートと呼ばれます。 - -ノートが作成されると、[タイムライン](./timeline)に追加され、自分の[フォロワー](./follow)やサーバーのユーザーが見れるようになります。 - -ノートには、[リアクション](./reaction)を行うことができます。また、返信や引用もできます。 - -ノートを[お気に入り](./favorite)登録することで、後で簡単に見返すことができます。 - -## ノートを作成する -ノートを作成するには、画面上にある鉛筆マークのボタンを押して、作成フォームを開きます。作成フォームに内容を入力し、「ノート」ボタンを押すことでノートが作成されます。 ノートには、画像、動画など任意のファイルや、[アンケート](./poll)を添付することができます。您还可以通过在文本中使用[MFM](./mfm)来将[提及](./mention)和[Hash标签](./hashtag)包含在内。 另外还可以设置CW的可见范围等(详细说明见后文)。 -
ℹ️ コンピューターのクリップボードに画像データがある状態で、フォーム内のテキストボックスにペーストするとその画像を添付することができます。
-
ℹ️ テキストボックス内でCtrl + Enterを押すことでも投稿できます。
- -## 转发 -既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノートをRenoteと呼びます。 自分がフォローしているユーザーの、気に入ったノートを自分のフォロワーに共有したい場合や、過去の自分のノートを再度共有したい場合に使います。 同じノートに対して無制限にRenoteを行うことができますが、あまり連続して使用すると迷惑になる場合もあるので、注意しましょう。 -
⚠️ 公開範囲がフォロワーやダイレクトのノートはRenoteできません
- -Renoteを削除するには、Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 - -## CW -Contents Warningの略で、ノートの内容を、閲覧者の操作なしには表示しないようにできる機能です。主に長大な内容を隠すためや、ネタバレ防止などに使うことができます。 設定するには、フォームの「内容を隠す」ボタン(目のアイコン)を押します。すると新しい入力エリアが表れるので、そこに内容の要約を記入します。 - -## 可见性 -ノートごとに、そのノートが公開される範囲を設定することができます。フォームの「ノート」ボタンの左にあるアイコンを押すと公開範囲を以下から選択できます。 - -### 公开 -全ての人に対してノートが公開されるほか、サーバーの全てのタイムライン(ホームタイムライン、ローカルタイムライン、ソーシャルタイムライン、グローバルタイムライン)にノートが流れます。 -
⚠️ アカウントがサイレンス状態の時は、この公開範囲は使用できません。
- -### 首页 -全ての人に対してノートが公開されますが、フォロワー以外のローカルタイムライン、ソーシャルタイムライン、グローバルタイムラインにはノートは流れません。 - -### 关注者 -自分のフォロワーに対してのみノートを公開します。フォロワーの全てのタイムラインに流れます。 - -### 指定用户 -指定したユーザーに対してのみノートを公開します。指定したユーザーの全てのタイムラインに流れます。 - -### 「ローカルのみ」オプション -このオプションを有効にすると、リモートにノートを連合しなくなります。 - -### 公開範囲の比較 - - - - -
公开首页关注者指定用户
フォロワーのLTL/STL/GTL
非フォロワーのLTL/STL/GTL
- -## 置顶 -ノートをピン留めすると、ユーザーページに常にそのノートを表示しておくことができます。 ノートのメニューを開き、「ピン留め」を選択してピン留めできます。 複数のノートをピン留めできます。 - -## 关注 -ノートをウォッチすると、自分以外のノートへのリアクションや返信などの通知を受け取ることができます。 ノートのメニューを開き、「ウォッチ」を選択してウォッチできます。 diff --git a/src/docs/zh-CN/features/pages.md b/src/docs/zh-CN/features/pages.md deleted file mode 100644 index d0d20dcbe..000000000 --- a/src/docs/zh-CN/features/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# Pages - -## 变量 -変数を使うことで動的なページを作成できます。テキスト内で { 変数名 } と書くとそこに変数の値を埋め込めます。例えば Hello { thing } world! というテキストで、変数(thing)の値が ai だった場合、テキストは Hello ai world! になります。 - -変数の評価(値を算出すること)は上から下に行われるので、ある変数の中で自分より下の変数を参照することはできません。例えば上から A、B、C と3つの変数を定義したとき、Cの中でABを参照することはできますが、Aの中でBCを参照することはできません。 - -ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。 - -関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。 diff --git a/src/docs/zh-CN/features/reaction.md b/src/docs/zh-CN/features/reaction.md deleted file mode 100644 index 61e7cabaf..000000000 --- a/src/docs/zh-CN/features/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# 回应 -他の人のノートに、絵文字を付けて簡単にあなたの反応を伝えられる機能です。 リアクションするには、ノートの + アイコンをクリックしてピッカーを表示し、絵文字を選択します。 リアクションには[カスタム絵文字](./custom-emoji)も使用できます。 - -## リアクションピッカーのカスタマイズ -ピッカーに表示される絵文字を自分好みにカスタマイズすることができます。 設定の「リアクション」で設定します。 - -## リモート投稿へのリアクションについて -リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。 - -## リモートからのリアクションについて -リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。 diff --git a/src/docs/zh-CN/features/silence.md b/src/docs/zh-CN/features/silence.md deleted file mode 100644 index 846978499..000000000 --- a/src/docs/zh-CN/features/silence.md +++ /dev/null @@ -1,6 +0,0 @@ -# 禁言 -サイレンスは、アカウントに設定される状態のひとつです。 - -アカウントがサイレンス状態になると、ノートの公開範囲をパブリックにできなくなります。 ホーム、フォロワー、ダイレクトは選択可能なため、サイレンスを受けた場合でもフォロワーやあなたのユーザーページを直接訪れた場合は投稿を閲覧できますが、GTL(連合タイムライン)やLTL(ローカルタイムライン)には投稿が流れません。 - -アカウントのサイレンス状態は、サーバーのモデレーターによって有効化/無効化されます。 diff --git a/src/docs/zh-CN/features/theme.md b/src/docs/zh-CN/features/theme.md deleted file mode 100644 index 62769e5c3..000000000 --- a/src/docs/zh-CN/features/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# 主题 - -テーマを設定して、Misskeyクライアントの見た目を変更できます。 - -## テーマの設定 -設定 > テーマ - -## テーマを作成する -テーマコードはJSON5で記述されたテーマオブジェクトです。 テーマは以下のようなオブジェクトです。 -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... テーマの一意なID。UUIDをおすすめします。 -* `name` ... テーマ名 -* `author` ... テーマの作者 -* `desc` ... テーマの説明(オプション) -* `base` ... 明るいテーマか、暗いテーマか - * `light`にすると明るいテーマになり、`dark`にすると暗いテーマになります。 - * テーマはここで設定されたベーステーマを継承します。 -* `props` ... テーマのスタイル定義。これから説明します。 - -### テーマのスタイル定義 -`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 - -#### バリューで使える構文 -* 16進数で表された色 - * 例: `#00ff00` -* `rgb(r, g, b)`形式で表された色 - * 例: `rgb(0, 255, 0)` -* `rgb(r, g, b, a)`形式で表された透明度を含む色 - * 例: `rgba(0, 255, 0, 0.5)` -* 他のキーの値の参照 - * `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。 - * 例: `@panel` -* 定数(後述)の参照 - * `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。 - * 例: `$main` -* 関数(後述) - * `:{関数名}<{引数}<{色}` - -#### 常量 -「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 キー名を`$`で始めると、そのキーはCSS変数として出力されません。 - -#### 函数 -wip diff --git a/src/docs/zh-CN/features/timeline.md b/src/docs/zh-CN/features/timeline.md deleted file mode 100644 index 6aa4e8b35..000000000 --- a/src/docs/zh-CN/features/timeline.md +++ /dev/null @@ -1,31 +0,0 @@ -# 时间线 -タイムラインは、[ノート](./note)が時系列で表示される機能です。 タイムラインには以下で示す種類があり、種類によって表示されるノートも異なります。 なお、タイムラインの種類によってはサーバーにより無効になっている場合があります。 - -## 首页 -自分のフォローしているユーザーの投稿が流れます。HTLと略されます。 - -## 本地 -全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。LTLと略されます。 - -## 社交 -自分のフォローしているユーザーの投稿と、全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。STLと略されます。 - -## 全局 -全てのローカルユーザーの「ホーム」指定されていない投稿と、サーバーに届いた全てのリモートユーザーの「ホーム」指定されていない投稿が流れます。GTLと略されます。 - -## 比较 -| 来源 | | | 时间线 | | | -| ------- | --- | -- | --- | -- | -- | -| 用户 | 可见性 | 首页 | 本地 | 社交 | 全局 | -| 本地(关注) | 发布 | ✔ | ✔ | ✔ | ✔ | -| | 首页 | ✔ | | ✔ | | -| | 关注者 | ✔ | ✔ | ✔ | ✔ | -| 跨站(关注) | 发布 | ✔ | | ✔ | ✔ | -| | 首页 | ✔ | | ✔ | | -| | 关注者 | ✔ | | ✔ | ✔ | -| 本地(未关注) | 发布 | | ✔ | ✔ | ✔ | -| | 首页 | | | | | -| | 关注者 | | | | | -| 跨站(未关注) | 发布 | | | | ✔ | -| | 首页 | | | | | -| | 关注者 | | | | | diff --git a/src/docs/zh-CN/features/widgets.md b/src/docs/zh-CN/features/widgets.md deleted file mode 100644 index 015cfc768..000000000 --- a/src/docs/zh-CN/features/widgets.md +++ /dev/null @@ -1,7 +0,0 @@ -# 小工具 -ウィジェットは、MisskeyのUI上に設置できる小型の情報表示、操作が行えるパーツです。 - -ウィジェットを編集するには、ウィジェット編集モードに切り替えます。切り替え方法はUIによって異なります。 ウィジェット編集モードでは、ウィジェットの追加、削除、並び替え、およびそれぞれのウィジェットの設定を行えます。 - -## 利用可能なウィジェット一覧 -todo diff --git a/src/docs/zh-CN/features/word-mute.md b/src/docs/zh-CN/features/word-mute.md deleted file mode 100644 index a1bd1918c..000000000 --- a/src/docs/zh-CN/features/word-mute.md +++ /dev/null @@ -1,20 +0,0 @@ -# 文字屏蔽 -ワードミュートの設定をすると、条件に合致したノートが表示されなくなります。 - -ワードミュートには、ソフトワードミュートとハードワードミュートの2種類があります。それぞれについて設定の方法と挙動を説明します。 - -## ソフトワードミュート -ソフトワードミュートは、クライアント(アプリ)側でミュートを判断するワードミュートです。 - -ノートが設定した条件に合致すると、「(ユーザー名)が何かを言いました」という表示で隠れます。 -クリックすると元の通りに表示されます。 - -## ハードワードミュート -ハードワードミュートは、アンテナのようにサーバーが新しいノートの本文に対して条件に合致するかどうか判断し、タイムラインから対象となったノートを除外します。 - -つまり、ハードワードミュートには、以下のような特徴があります。 - -* 条件設定後、新しい投稿のみがミュートの対象になります。 -* 条件を変更しても、過去にハードミュートされたノートはミュートされたままになります。 -* 「○○が何かを言いました」でタイムラインが埋まることがありません。 -* ソフトミュートに非対応のアプリでも、ハードミュートは適用されます。 diff --git a/src/docs/zh-CN/follow.md b/src/docs/zh-CN/follow.md deleted file mode 100644 index ff042baff..000000000 --- a/src/docs/zh-CN/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# 关注中 -当您关注一名用户时,您可以在您的时间线上看到该用户的帖子。但是不包含该用户对其他用户的回复。 要关注一名用户,请点击该用户页面上的“关注”按钮。如果需要取消关注,请再次点击该按钮。 diff --git a/src/docs/zh-CN/general/apps.md b/src/docs/zh-CN/general/apps.md deleted file mode 100644 index 3bd88df19..000000000 --- a/src/docs/zh-CN/general/apps.md +++ /dev/null @@ -1,6 +0,0 @@ -# 第三方应用程序列表 -## 客户端 -todo - -## 链接服务 -todo diff --git a/src/docs/zh-CN/general/changelog.md b/src/docs/zh-CN/general/changelog.md deleted file mode 100644 index 53dfae95c..000000000 --- a/src/docs/zh-CN/general/changelog.md +++ /dev/null @@ -1,5 +0,0 @@ -# 更新日志 -
ℹ️ 这是该服务器的更新日志。请在 GitHub 上检查 Misskey 的最新发布版本。
- - - diff --git a/src/docs/zh-CN/general/faq.md b/src/docs/zh-CN/general/faq.md deleted file mode 100644 index b7f159c37..000000000 --- a/src/docs/zh-CN/general/faq.md +++ /dev/null @@ -1,28 +0,0 @@ -# 常见问题 -ここでは利用上のよくある質問について掲載しています。 Misskeyのプロジェクト自体についてのよくある質問は[こちら](./misskey)に掲載されています。 - -## iOS/Androidのアプリはありますか? -公式にはそういったOSのネイティブアプリを開発していませんが、サードパーティ製のアプリがいくつかあります。 詳しくは[こちら](./apps)をご覧ください。 - -ただ、サードパーティ製アプリはどうしても機能への対応が遅れてしまうため、とくに拘りがなければ公式のWebクライアントの利用をおすすめします。 なお、MisskeyのWebクライアントはPWAに対応しているので、ネイティブアプリのように動作させることも可能です。 詳しくは[こちら](todo)をご覧ください。 - -## Mastodonクライアントでログインできないのですが? -MisskeyはMastodonのAPIと互換性がないため、一部を除きMastodonクライアントでMisskeyを利用することはできません。 - -## 他のサーバーのユーザーをフォローするときは? -メニューから検索を選び、ユーザー名をホスト込みで入力します。例: `@syuilo@misskey.io` - -## Renoteを削除するには? -Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 Renoteについては[こちら](../features/note)をご確認ください。 - -## URLのプレビューを表示させたくない -MFMには、そのURLのプレビューを無効にする構文があります。詳細は[MFMチートシート](/mfm-cheat-sheet)をご確認ください。 - -## 想要添加自定义表情符号 -運営者のみがカスタム絵文字を追加、編集、削除できます。それらを希望する場合は運営者に依頼してください。 - -## 想要开发一个Bot机器人 -您可以使用 Misskey API 开发Bot机器人。[こちら](../advanced/develop-bot)をご確認ください。 - -## ノートの翻訳機能はどのサービスを使用していますか? -[DeepL](https://www.deepl.com/)を使用しています。 diff --git a/src/docs/zh-CN/general/glossary.md b/src/docs/zh-CN/general/glossary.md deleted file mode 100644 index 58cb1a9ee..000000000 --- a/src/docs/zh-CN/general/glossary.md +++ /dev/null @@ -1,89 +0,0 @@ -# 术语表 -Misskey相关术语的词汇表。 - -## ActivityPub -(読み: あくてぃびてぃぱぶ) 分散型を実現するために用いられるプロトコル(仕様)。このプロトコルに則ってサーバー同士通信を行うことで、連合が行われ、Fediverseを形成しています。 - -## AiScript -(読み: あいすくりぷと) Misskey上で使用できるプログラミング言語です。詳細は[こちら。](../advanced/aiscript) - -## API -(読み: えーぴーあい) Misskeyのサーバーが公開している、プログラムからMisskeyを扱うためのインターフェース。詳細は[こちら。](../advanced/api) - -## Bot -(読み: ぼっと) プログラムによって動作しているアカウント。 - -## CW -(読み: こんてんつわーにんぐ) Contents Warningの略。ノートの内容を、操作なしには表示しないようにできる機能。主に長大な内容を隠すためや、ネタバレ防止などに使われます。 - -## Fediverse -(読み: ふぇでぃばーす) Misskeyを含む様々な分散型ソフトウェアのサーバーで構成されたネットワーク。 - -## GTL -グローバルタイムライン(Global TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## HTL -ホームタイムライン(Home TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## LTL -ローカルタイムライン(Local TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## MFM -(読み: えむえふえむ) Misskey Flavored Markdownの略で、Misskey上で使用できるマークアップ言語です。詳細は[こちら。](../features/mfm) - -## NSFW -(読み: のっとせーふふぉーわーく) Not Safe For Workの略。画像を「閲覧注意」扱いにし、操作なしには表示しないようにすることができる機能。 - -## 转发 -(読み: りのーと) 既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノート。詳細は[こちら。](../features/note) - -## STL -ソーシャルタイムライン(Social TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## 蓝 -(読み: あい) Misskeyの看板娘(公式キャラクター)です。 - -## アクティブユーザー -インスタンスにアカウントを作っているユーザーのうち、現在も実際にサービスを利用しているユーザーのこと。 - -## 实例 -todo - -## 自定义表情符号 -サーバーで用意された絵文字。カスタム絵文字ではない通常の絵文字は「Unicode絵文字」と区別して呼ばれる。 - -## コントロールパネル -インスタンスの設定画面のこと。 - -## 服务器 -todo - -## 禁言 -ノートをパブリックな公開範囲で投稿できなくされている状態。モデレーターの判断でユーザーごとに設定されます。详情请看[这里。](../features/silence) - -## 作业队列 -アクティビティ配送などを順番に行うためのシステム。 - -## 冻结 -アカウントが使用不可に設定されている状態。 - -## 网盘 -Misskeyにアップロードしたファイルを管理する機能。详情请看[这里。](../features/drive) - -## 帖子 -Misskeyに投稿される、文章、ファイル、アンケートなどを含めることができるコンテンツ。詳細は[こちら。](../features/note) - -## ミスキスト -Misskeyを使う人のこと。 - -## 监察员 -スパムの凍結およびサイレンスや不適切な投稿の削除など、コミュニティ運営に関する権限を持つユーザー。 - -## 远程 -他サーバーのことを指します。リモートユーザーといったように接頭辞としても使われます。ローカルの逆です。 - -## 联合 -サーバー上で作成された情報が他のサーバーに伝わること。 - -## 本地 -自サーバーのことを指します。ローカルユーザー、ローカルタイムラインといったように接頭辞としても使われます。リモートの逆です。 diff --git a/src/docs/zh-CN/general/links.md b/src/docs/zh-CN/general/links.md deleted file mode 100644 index d23451176..000000000 --- a/src/docs/zh-CN/general/links.md +++ /dev/null @@ -1,12 +0,0 @@ -# 相关链接 - -## 网站 -- [Official Discord](https://discord.gg/Wp8gVStHW3) - Misskey官方Discord服务器 -- [Misskey Forum](https://forum.misskey.io/) - Misskey相关主题的论坛 - -## 账户 -- [@repo@misskey.io](https://misskey.io/@repo) - 发布Misskey的存储库更新的机器人 - -## 库 -- [misskey-dev/misskey.js](https://github.com/misskey-dev/misskey.js) - JavaScript的Misskey SDK -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScript的MFM解析器实现 diff --git a/src/docs/zh-CN/general/misskey.md b/src/docs/zh-CN/general/misskey.md deleted file mode 100644 index e6376839e..000000000 --- a/src/docs/zh-CN/general/misskey.md +++ /dev/null @@ -1,87 +0,0 @@ -# 关于 Misskey - -Misskeyはオープンソースの分散型マイクロブログプラットフォームプロジェクトです。 開発は日本でsyuiloによって2014年から開始されました。 ドライブ、リアクションなどの豊富な機能や、高いカスタマイズ性を備えたUIを持つことが特徴です。 - -## 歴史 -開発当初は掲示板がメインのサービスでしたが、ユーザーが短文を投稿し、それを時系列で流れるタイムライン機能を追加したところ人気が高まり、徐々にそれがメインとして開発が進むようになりました。 当初は分散型ではありませんでしたが、2018年にActivityPubを実装し分散型になったことで、より多くの方に認知され利用されるサービスになり、現在に至ります。 -
ℹ️ Misskeyという名前は、syuiloが当時聴いていたMay'nというアーティストの楽曲、Brain Diverの歌詞に由来します。
- -誰でも開発に参加することができ、現在でも活発に開発が続いています。 - -## 分散型とは何か? - -分散(distributed)型とは、非中央集権(decentralized)とも呼ばれ、コミュニティが多数のサーバーに分散して存在し、それらが相互に通信(連合、federation)することでコンテンツ共有ネットワーク(Fediverse)を形成していることが特徴のサービスです。 単一のサーバーしか存在しない、もしくは複数存在しても互いに独立している場合は中央集権なサービスと言われ、例えばTwitterやFacebookなどほとんどのサービスがそれに該当します。 分散型のメリットは、自分に合った運営者やテーマのサーバーを選択できることです。自分でサーバーを作成することもできます。連合するおかげで、どのサーバーを選んでも、同じコミュニティにアクセスできます。 - -## 常にオープンソース -Misskeyはこれまでもこれからも、オープンソースであり続けます。オープンソースとは、簡単に言うとソフトウェアのソースコード(プログラム)が公開されていることです。ソースコードの修正や再配布が可能であることを定義に含めることもあります。 Misskeyのすべてのソースコードは[AGPL](https://github.com/misskey-dev/misskey/blob/develop/LICENSE)というオープンソースライセンスの下に[公開](https://github.com/misskey-dev)されていて、誰でも自由に閲覧、使用、修正、改変、再配布をすることができます。 オープンソースは、自分で好きなように変えたり、有害な処理が含まれていないことを確認することができたり、誰でも開発に参加できるなどの、様々なメリットがあります。 上述の分散型を実現するためにも、オープンソースであるということは必要不可欠な要素です。 再び引き合いに出しますが、TwitterやFacebookなどの利益を得ているほとんどのサービスはオープンソースではありません。 - -
ℹ️ 技術的に言うと、MisskeyのソースコードはGitで管理されていて、リポジトリはGitHub上でホスティングされています。
- -## 開発に参加する、プロジェクトを支援する -Misskeyを気に入っていただけたら、ぜひプロジェクトを支援してください。プロジェクトに貢献するには、以下で紹介するようにいろいろな方法があります。方法によっては開発のスキルは不要なので、誰でも気軽に参加し貢献することができます。いつでもお待ちしています。 - -### 機能を追加したり、バグを修正する -ソフトウェアエンジニアのスキルをお持ちの方であれば、ソースコードを編集する形でプロジェクトに貢献することができます。 貢献についてのガイドは[こちら](https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md)です。 - -### 議論に参加する -新しい機能、または既存の機能について意見を述べたり、不具合を報告したりすることでも貢献できます。 そのようなディスカッションは[GitHub](https://github.com/misskey-dev)上か、[フォーラム](https://forum.misskey.io/)等で行われます。 - -### テキストを翻訳する -Misskeyは様々な言語に対応しています(i18n -internationalizationの略- と呼ばれます)。元の言語は基本的に日本語ですが、有志によって他の言語へと翻訳されています。 その翻訳作業に加わっていただくことでもMisskeyに貢献できます。 Misskeyは[Crowdinというサービスを使用して翻訳の管理を行っています。](https://crowdin.com/project/misskey) - -### 感想を投稿する -不具合報告等だけではなく、Misskeyの良い点、楽しい点といったポジティブな意見もぜひ共有してください。開発の励みになり、それは間接的ですがプロジェクトへの貢献です。 - -### ミスキストを増やす -ミスキストとは、Misskeyを使用する人のことです。 知り合いに紹介するなどしてMisskeyを広めていただければ、ミスキストが増え開発のモチベーションが上がります。 - -### 寄付をする -Misskeyはビジネスではなく、利用は無料であるため、収益は皆様からの寄付のみです。(インスタンスによっては広告収入を得ているような場合もありますが、それは運営者の収入であり直接開発者への収入にはなりません) 寄付をしていただければ、今後も開発を続けることが可能になり、プロジェクトへの貢献になります。 寄付は基本的には[Patreon](https://www.patreon.com/syuilo)で受け付けています。 一定額寄付していただけると、Misskeyの[情報ページ](/about-misskey)に名前を記載することができます。 - -また、サーバーの運営者も、基本的には収益を得ていません。サーバーの運営にはコストがかかるので、運営者の支援をすることもご検討ください。 開発には直接関係しませんが、サーバーがあってこそのプロジェクトなので、運営が維持されるというのは開発と同じくらい重要なことです。 - -## クレジット -Misskeyの開発者や、Misskeyに寄付をしてくださった方の一覧は[こちら](/about-misskey)で見ることができます。 - -## 常见问题 -### プロジェクトは何を目指していますか? -強いて言うと、漠然的になりますが広く使われる汎用的なプラットフォームになることを目指しています。 Misskeyは他のプロジェクトとは違い、何らかの思想(例えば、反中央集権)やビジョンに基づいて開発が行われているわけではなく、その点ではフラットです。 それが逆に、特定の方向性に縛られないフレキシブルさを生み出すことに繋がっていると感じています。 - - -### 企業によって開発されていますか? -いいえ。Misskeyの開発は個人で行われており、商業的でもないため、特定の企業の関りはありません。 開発メンバーも基本的にはボランティアです。 また、開発に対し企業のスポンサーがつくこともありますが、その場合でもやはり開発は個人のコミュニティが主体です。 - -### 誰が運営していますか? -Misskeyは分散型なため、各サーバーにそれぞれ異なった運営者がいます。従って、特定の個人や企業によって、Misskeyの全てが運営されているわけではありません。 また、開発チームが運営を行うわけでもないため、運営に関する連絡は、お使いのサーバーの運営者に行ってください。 サーバーの運営者は、[このページ](/about)で確認することができます。 あなたがサーバーを作成すれば、あなたが運営者になります。 - -### どのサーバーを選べばいいですか? -[サーバー一覧が公開されています。](https://join.misskey.page/ja-JP/instances) サーバーによってコミュニティのテーマ(特定のこと、ものが好き 等)が決められている場合があるので、自分に合ったテーマのサーバーがあれば、そこを選ぶと良いかもしれません。 他にも、サーバーの規模、ユーザー層、国および言語、運営者が信頼できるかどうか、などの観点があります。 なお、Misskey公式のサーバーというものはありません。自身で新しくサーバーを作成するという選択肢もあります。 - -基本的にどのサーバーを選んだとしても、他の全てのサーバーのユーザーと繋がることができます。 - -### サーバーを建てるにはどうしたらいいですか? -Misskeyサーバーの作成に興味を持っていただきありがとうございます。 2021年現在、Misskeyのホスティングサービスは存在しないため、サーバーの作成にはある程度の知識が必要です。 サーバーの作成方法については[こちら](todo)をご覧ください。 - -### どのような技術を使用していますか? -Misskeyは開発が進むにつれ使用する技術も大きく変わってきました。開発当初はMySQL + PHP + jQueryといった構成でしたが、現在は以下のようになっています。 -- サーバーサイド: Node.js -- データベース: PostgreSQL、Redis -- UIフレームワーク: Vue.js -- プログラミング言語: TypeScript - -また、MFMやAiScriptなどの、Misskeyから派生して独自の技術も開発しています。 - -### Mastodonのフォークですか? -いいえ。MisskeyはMastodonやその他のプロジェクトとは全く別のプロジェクトです。 開発に関しても、Misskeyの方が昔から開発されています。ただし、分散型になったのはMastodonの登場より後です。 同じActivityPubという分散のためのプロトコルを実装しているという点以外、両者に特に関りがあるわけでもありません。 - -### iOS/Androidのアプリはありますか? -公式にはそういったOSのネイティブアプリを開発していませんが、サードパーティ製のアプリがいくつかあります。 詳しくは[こちら](./apps)をご覧ください。 - -ただ、サードパーティ製アプリはどうしても機能への対応が遅れてしまうため、とくに拘りがなければ公式のWebクライアントの利用をおすすめします。 なお、MisskeyのWebクライアントはPWAに対応しているので、ネイティブアプリのように動作させることも可能です。 詳しくは[こちら](todo)をご覧ください。 - -### Misskeyのロゴ、アイコンはどこで入手できますか? -(準備中) - -### 時折目にする猫耳の可愛い女の子は? -Misskeyの守り神、藍ちゃんです。アイチャンカワイイヤッター! -
ℹ️ 藍ちゃんについてはこちらです。
diff --git a/src/docs/zh-CN/general/report-issue.md b/src/docs/zh-CN/general/report-issue.md deleted file mode 100644 index 22d97ff3d..000000000 --- a/src/docs/zh-CN/general/report-issue.md +++ /dev/null @@ -1,8 +0,0 @@ -# bug报告 -不具合と思われる状況に遭遇したときは、まず[トラブルシューティング](./troubleshooting)をご一読ください。 それでも問題が解決しないときは、以下の情報を含めて[フォーラム](https://forum.misskey.io/)に投稿してください。 投稿することで、解決策が見つかったり、不具合と判断されれば開発チームによって修正が行われます。 - -## 含める情報 -- Misskeyのバージョン([情報ページ](/about)で確認できます) -- お使いのブラウザの種類とバージョン -- お使いのOSの種類とバージョン -- 問題の再現手順 diff --git a/src/docs/zh-CN/general/troubleshooting.md b/src/docs/zh-CN/general/troubleshooting.md deleted file mode 100644 index 43ce835b1..000000000 --- a/src/docs/zh-CN/general/troubleshooting.md +++ /dev/null @@ -1,40 +0,0 @@ -# 故障排除 -
ℹ️ よくある質問も合わせてお役立てください。
- -問題が発生したときは、まずこちらをご確認ください。 該当する項目が無い、もしくは手順を試しても効果がない場合は、サーバーの管理者に連絡するか[不具合を報告](./report-issue)してください。 - -## クライアントが起動しない -ほとんどの場合、お使いのブラウザまたはOSのバージョンが古いことが原因です。 ブラウザおよびOSのバージョンを最新のものに更新してから、再度試してみてください。 - -これは稀ですが、それでも起動しない場合は、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。 - -## ページが読み込めない -クライアントが起動するもののページが読み込めないというエラーが出る場合は、ネットワークに問題がないか確認してください。また、サーバーがダウンしていないか確認してください。 - -これは稀ですが、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。 - -まだ問題がある場合は、サーバーの問題と思われるのでサーバーの管理者に連絡してください。 - -## クライアントの動作が遅い -以下を試してみてください: - -- クライアント設定で「UIのアニメーションを減らす」を有効にする -- クライアント設定で「モーダルにぼかし効果を使用」を無効にする -- お使いのブラウザの設定でハードウェアアクセラレーションを有効にする -- お使いのデバイスのスペックを上げる - -## UIの一部の表示がおかしい(背景が透明になっている等) -アップデートによりUIの改修が行われたときに、テーマのキャッシュシステムの影響でそのような表示になることがあります。 クライアントの設定の「キャッシュをクリア」すると直ります。 -
⚠️ 「クライアントの」キャッシュクリアです。「ブラウザの」キャッシュクリアは行わないでください。
- -## 通知やアンテナ等の点滅が消えない -点滅は、未読のコンテンツがあることを示しています。通常点滅が消えない場合は、コンテンツを遡ると未読なコンテンツが残っています。 すべて既読にしたと思われるのに、それでもなお点滅が続く場合(おそらく不具合と思われます)は設定から強制的にすべて既読扱いにすることができます。 - -## Renoteができない -フォロワー限定のノートはRenoteすることはできません。 - -## UI上で特定の要素が表示されない -広告ブロッカーを使用しているとそのような不具合が発生することがあります。Misskeyではオフにしてご利用ください。 - -## UI上で未翻訳の部分がある -ほとんどの場合、単に翻訳が間に合っていないだけで、不具合ではありません。翻訳が終わるまでお待ちください。 [翻訳に参加](./misskey)していただくことも可能です。 diff --git a/src/docs/zh-CN/keyboard-shortcut.md b/src/docs/zh-CN/keyboard-shortcut.md deleted file mode 100644 index 42b8188c0..000000000 --- a/src/docs/zh-CN/keyboard-shortcut.md +++ /dev/null @@ -1,68 +0,0 @@ -# 键盘快捷键 - -## 全局 -这些快捷键基本上可以在任何地方使用 - - - - - - - - - - - -
快捷键效果来源
P, N发新帖Post, New, Note
T转到时间线最新发布的内容Timeline, Top
Shift + N显示/隐藏通知Notifications
S搜索Search
H, ?显示帮助Help
- -## 帖子相关操作 - - - - - - - - - - - - - - - - - - - -
快捷键效果来源
, K, Shift + Tab移动到上一个帖子-
, J, Tab移动到下一个帖子-
R打开回复框Reply
Q打开转发框Quote
Ctrl + Q快速转发(不打开转发框)-
E, A, +打开回应框Emote, reAction
0~9根据相应数字发表回应(详情请参考相关说明)-
F, B添加到收藏夹Favorite, Bookmark
Del, Ctrl + D删除帖子Delete
M, O打开帖子菜单More, Other
S显示或隐藏CW隐藏的部分Show, See
Esc取消选中-
- -## 转发框 - - - - - - - - - - -
快捷键效果来源
Enter转发-
Q打开转发框Quote
Esc关闭转发框-
- -## 回应框 -默认使用“👍”作为回应。 - - - - - - - - - - - - - -
快捷键效果来源
, K移动到上一个回应-
, J移动到下一个回应-
, H, Shift + Tab移动到左边一个回应-
, L, Tab移动到右边一个回应-
Enter, Space, +回应确认-
0~9根据相应数字发表回应-
Esc取消回应-
diff --git a/src/docs/zh-CN/mfm.md b/src/docs/zh-CN/mfm.md deleted file mode 100644 index 39199b5e0..000000000 --- a/src/docs/zh-CN/mfm.md +++ /dev/null @@ -1,2 +0,0 @@ -# MFM -MFM是Misskey Flavored Markdown的缩写,是一种专用的标记语言,可以用在Misskey的任何地方。 MFM中可用的语法可以在[MFM代码速查表](/mfm-cheat-sheet)中找到。 diff --git a/src/docs/zh-CN/mute.md b/src/docs/zh-CN/mute.md deleted file mode 100644 index 43a6c12ff..000000000 --- a/src/docs/zh-CN/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# 屏蔽 - -当您屏蔽用户时,Misskey不再显示有关该用户的以下内容: - -* 时间线帖子搜索结果中的该用户的帖子(以及对这些帖子的回复和转发)。 -* 该用户的通知 -* 用户在消息历史记录列表中的消息历史记录 - -要屏蔽用户,请在该用户页面上点击该用户的“屏蔽”按钮。 - -不会通知对方您已将其屏蔽,并且对方也不知道自己被屏蔽。 - -您可以在“设置”>“屏蔽”下查看被屏蔽的用户列表。 diff --git a/src/docs/zh-CN/pages.md b/src/docs/zh-CN/pages.md deleted file mode 100644 index 2446c183a..000000000 --- a/src/docs/zh-CN/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# 页面 - -## 变量 -您可以使用变量创建动态页面。您可以在文本中使用{变量名}的格式来引用变量的值。例如当变量(thing)的值为ai时,字符串Hello { thing } world!的值为Hello ai world!。 - -变量的处理(计算变量的值)是从上到下执行的,因此不能引用未声明的变量。例如,如果您依次定义了 A,B,C 三个变量,则在 C 中可以引用 A B ,但 A 中不能引用 B C 。 - -为了接收来自用户的输入,页面上设有“用户输入”块,在“变量名称”中设置要在其中保存输入值的变量名(变量会自动创建)。然后您可以通过该变量使用用户输入的值进行其他操作。 - -函数时一种将可重用的计算过程组合起来的形式。要创建函数,请创建“函数”类型的变量。可以为函数设置插槽(参数),并且插槽值可以作为函数内的变量使用。另外,也可以将函数作为函数的参数(称为高阶函数)。除了预定义函数外,您也可以随时将函数定义在这类高阶功能的插槽中。 diff --git a/src/docs/zh-CN/reaction.md b/src/docs/zh-CN/reaction.md deleted file mode 100644 index 779bde238..000000000 --- a/src/docs/zh-CN/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# 回应 -通过将表情符号加到其他人的帖子上,您可以快速表达您的反应。 要做出回应,请单击帖子上的 + 图标以打开选择器并选择一个表情符号。 您也可以使用[自定义表情符号](./custom-emoji)来进行回应。 - -## 自定义回应选择器 -您可以根据自己的喜好自定义选择器中显示的表情符号。 在设置的“回应”中即可进行设置。 - -## 关于对外部发帖的回应 -回应是Misskey的原生功能,因此,除非外部实例是Misskey,否则该操作很有可能仅以“Like”的形式发送。通常,Like表现为“点赞”的功能。 另外,即使对方同样是Misskey,自定义表情符号的回应也不会被发送,而是会自动显示为“👍”等表情符号。 - -## 关于外部回应 -当从外部接收到“Like”操作时,Misskey会将其解释为“👍”回应。 diff --git a/src/docs/zh-CN/reversi-bot.md b/src/docs/zh-CN/reversi-bot.md deleted file mode 100644 index 8c2d0f255..000000000 --- a/src/docs/zh-CN/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# Misskey的黑白棋Bot开发 -本页会说明如何为Misskey的黑白棋功能开发一个Bot机器人。 - -1. 使用以下参数来连接`games/reversi`流式API: - * `i`: bot账号的API key - -2. 当出现对局邀请时,流中会触发`invited`事件 - * 事件内容中包含邀请您参加游戏的用户信息,名字为`parent`。 - -3. 向`games/reversi/match`发送请求,其中`user_id`包含`parent`的`id` - -4. 请求成功时将返回游戏信息,然后可以使用以下参数连接到`games/reversi-game`流: - * `i`: bot账号的API key - * `game`: `game`的`id` - -5. 与此同时,每次对手更改游戏设置时,都会触发`update-settings`事件,如果有必要的话,需要对其进行处理。 - -6. 一旦符合设置,则向流发送`{ type: 'accept' }`消息 - -7. 游戏开始时会触发`started`事件 - * 游戏状态信息会包含在该事件中 - -8. 要放置棋子,向流发送`{ type: 'set', pos: <位置> }`(后面会说明位置的计算方法) - -9. 当对方或者您放置棋子时,会触发`set`事件 - * `color`中包含该棋子的颜色 - * `pos`中包含该棋子的位置 - -## 位置计算方法 -当棋盘尺寸为8x8时,每个方格的位置(称为索引)如下所示: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### 从X,Y坐标转换为索引 -``` -pos = x + (y * mapWidth) -``` -`mapWidth`可以根据游戏信息中的`map`,通过如下方法计算出来: -``` -mapWidth = map[0].length -``` - -### 从索引转换为X,Y坐标 -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## 棋盘信息 -棋盘信息包含在游戏信息的`map`中。 它是一个字符串数组,每个字符代表一块格子的信息。 您可以根据这些来了解地图如何设计: -* `(空)` ... 没有格子 -* `-` ... 格子 -* `b` ... 黑子先下 -* `w` ... 白子先下 - -以下面这个4*4的简单棋盘为例: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -这种情况下,棋盘数据是这样的: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## 能和用户互动的交互式Bot机器人的创建 -要和用户交互,您可以在游戏设置屏幕上向用户显示对话框。 例如,可以让用户选择Bot机器人的难度。 - -要显示提示框,需要向`reversi-game`流发送下列消息: -```javascript -{ - type: 'init-form', - body: [表单控件数组] -} -``` - -下面说明表单控件数组的结构。 表单控件指的是如下面所示的对象: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... 控件ID。 `type` ... 控件类型。说明详见后文。 `label` ... 控件元素上显示的文字。 `value` ... 控件元素的默认值。 - -### 控件行为的处理 -当用户与对话框交互时将会触发流的`update-form`事件。 事件的内容包含控件的ID和用户设置的值。 例如,如果用户将上面显示的开关控件打开,则将触发以下事件: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### 表单控件的类型 -#### 开关 -type: `switch` 显示一个开关。当您想要打开/关闭某些功能时非常有用。 - -##### 属性 -`label` ... 开关上显示的文字。 - -#### 单选按钮 -type: `radio` 显示一个单选按钮。用来表示单项选择。例如,可以选择Bot机器人的难度。 - -##### 属性 -`items` ... 单元按钮的选择项。例: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '强', - value: 3 -}] -``` - -#### 滑块 -type: `slider` 显示一个滑块。 - -##### 属性 -`min` ... 滑块最小值。 `max` ... 滑块最大值。 `step` ... 滑块值的步长。 - -#### 文本框 -type: `textbox` 显示一个文本框。可以在各种需要用户输入的地方使用。 - -## 向用户显示消息 -设置屏幕上与用户交互,是除了对话框外的另一种方法。您可以向用户显示一条消息。 例如,当用户选择Bot机器人不支持的模式或棋盘时显示警告。 要显示消息,请将以下消息发送到流: -```javascript -{ - type: 'message', - body: { - text: '消息内容', - type: '消息类型' - } -} -``` -消息类型:`success`, `info`, `warning`, `error`。 - -## 认输 -要认输,请发送请求到这个终端。 diff --git a/src/docs/zh-CN/stream.md b/src/docs/zh-CN/stream.md deleted file mode 100644 index 8735a05f5..000000000 --- a/src/docs/zh-CN/stream.md +++ /dev/null @@ -1,354 +0,0 @@ -# 流式API - -通过流式API,您可以实时接收各种信息(例如,你的时间线中的新帖文,收到的消息,关注等),并进行各种操作。 - -## 连接到流 - -要使用流式API,您需要使用**websocket**连接到Misskey服务器。 - -请使用参数`i`连接到以下URL,并在websocket连接中包含认证信息。例如: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -认证信息是您的API密钥,从应用程序连接到流时需要引用的用户访问令牌 - -
-

关于如何获取认证信息,请参考此文档

-
- ---- - -您可以省略身份验证信息。此时无需登录即可使用,但是可以接收的信息和可以执行的操作将受到限制。例: - -``` -%WS_URL%/streaming -``` - ---- - -通过连接到流,您可以执行后文所示的API操作并订阅帖子。 但是此时例如时间线上的新帖子等还无法接收到。 要实现此功能,您需要连接到后文所述的流的**频道**。 - -**所有流交互都是JSON格式。** - -## 频道 -频道是Misskey的流API中的概念。这是一种分离发送和接收信息的机制。 您无法仅通过连接到Misskey流来实时接收时间线帖子。 需要通过连接到流中的频道,您才能够接收和发送各种消息。 - -### 连接到频道 -要连接到频道,请将JSON数据发送到流: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -其中: -* `channel`中可以设置您要连接的频道名。频道类型将在后面说明。 -* `id`设置用于与频道通信的ID。因为流中有着各种消息,因此需要确定消息来自哪个频道。该ID可以是UUID或随机数。 -* `params`是连接到频道时传的参数。连接不同的频道时需要不同的参数。连接到无需参数的频道时,该属性为可选。 - -
-

ID对应的是“频道的连接”,而不是频道。因为在某些情况下会使用不同的参数对同一频道进行多个连接。

-
- -### 从频道接收消息 -例如,当有新帖子时,时间线的频道将发送一条消息。通过接收此消息,您可以实时知道时间线上有新帖子。 - -当频道发出消息时,以下数据将以JSON格式传输到流中: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -其中: -* `id`为前文所述连接到频道时所设置的ID。因此可以知道此消息来自哪个频道。 -* `type`为所设的消息类型。不同的频道会有不同类型的消息。 -* `body`为所设的消息内容。不同的频道中的消息内容也会有不同。 - -### 向频道发送消息 -根据频道的不同,您不仅可以接收消息,而且还可以发送消息并执行某些操作。 - -要将消息发送到频道,请将JSON格式数据发送到流: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -其中: -* `id`为前文所述连接到频道时想要设置的ID。因此您可以决定此消息发送到哪个频道。 -* `type`为想要设置的消息类型。不同的频道会接受不同类型的消息。 -* `body`为想要设置的消息内容。不同的频道接受的消息内容也会不同。 - -### 断开频道连接 -要断开与频道的连接,请将JSON格式数据发送到流: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -其中: -* `id`为前文所述连接到频道时想要设置的ID。 - -## 通过流发送API请求 - -使用流的方式可以在不使用http请求的条件下来发送API请求。因此,您可以使用更简洁的代码来提高效率。 - -要通过流发送AP​​I请求,请将如下所示的JSON格式数据发送到流: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -其中: -* `id`是一个唯一的ID,用来识别不同请求所对应的回应。可以使用UUID或者简单的随机数生成方法。 -* `endpoint`包含请求要指定发送的API终端。 -* `data`包含需要发送的终端参数。 - -
-

详见API参考中的API终端和参数。

-
- -### 接收回应 - -当你向API发送请求时,会受到流发送的如下格式的回应: - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -其中: -* `xxxxxxxxxxxxxxxx`部分包含该请求之前设置过的`id`。因此,可以判断出回应是对应的哪个请求。 -* `body`包含回应的数据。 - -## 帖子抓取 - -Misskey提供一种被称为“帖子抓取”的机制。该功能以流的形式接受指定帖子的事件。 - -例如,假设您获得了时间线的数据并将其显示给用户。而现在有人对时间线中的某一个帖子做出了回应。 - -但是,由于客户端无法知道某个帖子有回应,因此无法在时间线上的帖子中反映并实时显示出来。 - -为了解决此问题,Misskey引入了帖子抓取的机制。抓取帖子时,您可以接收与该帖子相关的事件,因此您可以将帖子的回应实时反映出来。 - -### 抓取帖子 - -要抓取帖子,请向流发送下列格式的消息: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -其中: -* 请将`id`的值设置为需要抓取的帖子`id`值 - -发送此消息表示您已请求Misskey抓取该贴子,并且您将收到与该帖子有关的事件。 - -例如,如果帖子有回应,您将收到以下消息: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -其中: -* `body`里的`id`用来表示触发事件的帖子的ID。 -* `body`里的`type`用来表示事件类型。 -* `body`里的`body`用来表示事件详细内容。 - -#### 事件类型 - -##### `reacted` -在帖子有回应时触发。 - -* `reaction`用来表示回应的类型。 -* `userId`用来表示做出回应的用户的ID。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -帖子删除时触发。 - -* `deletedAt`表示删除的日期和时间。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -帖子附带的问卷调查被投票时触发。 - -* `choice`表示选择项ID。 -* `userId`表示投票的用户ID。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### 取消帖子抓取 - -如果希望该帖子不再出现在屏幕上,并且您不再需要接收与该帖子相关的事件,可以发送取消帖子抓取的请求。 - -请发送以下消息: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -其中: -* 请将`id`的值设置为需要取消抓取的帖子`id`值。 - -发送此消息后,将不再接收与该帖子相关的其他事件。 - -# 频道列表 -## `main` -将会发送帐户的基本信息。该频道没有参数。 - -### 发送的事件列表 - -#### `renote` -当您的帖子被转发时会触发该事件。转发自己的帖子不会触发。 - -#### `mention` -有人提及您时会触发该事件。 - -#### `readAllNotifications` -这个事件表示您的所有通知都被设为已读。此事件可用于关闭“未读通知图标”等情况。 - -#### `meUpdated` -该事件表示您的个人信息已更新。 - -#### `follow` -当您关注某人时会触发该事件。 - -#### `unfollow` -当您取消关注某人时会触发该事件。 - -#### `followed` -当您被某人关注时会触发该事件。 - -## `homeTimeline` -首页的时间线上发布的信息将会传到这里。该频道没有参数。 - -### 发送的事件列表 - -#### `note` -当时间线有新帖子时触发此事件。 - -## `localTimeline` -本地的时间线上发布的信息将会传到这里。该频道没有参数。 - -### 发送的事件列表 - -#### `note` -当本地的时间线有新帖子时触发此事件。 - -## `hybridTimeline` -社交时间线上发布的信息将会传到这里。该频道没有参数。 - -### 发送的事件列表 - -#### `note` -当社交时间线有新帖子时触发此事件。 - -## `globalTimeline` -全局时间线上发布的信息将会传到这里。该频道没有参数。 - -### 发送的事件列表 - -#### `note` -全局时间线有新帖子时触发此事件。 diff --git a/src/docs/zh-CN/theme.md b/src/docs/zh-CN/theme.md deleted file mode 100644 index a0d0c10bc..000000000 --- a/src/docs/zh-CN/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# 主题 - -您可以设置主题来改变您的Misskey客户端的外观和质感。 - -## 设置主题 -设置 > 主题 - -## 创建主题 -主题代码是一个由 JSON5 编写和构成的对象。下面是一个主题对象,它看起来像是这样: -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... 该主题的唯一 ID,推荐采用 UUID。 -* `name` ... 主题名称 -* `author` ... 主题作者 -* `desc` ... 主题的描述说明(可选) -* `base` ... 浅色主题还是深色主题 - * `light` 为浅色主题,`dark` 为深色主题。 - * 该主题将继承使用的基础主题集。 -* `props` ... 关于主题样式的定义,下面是详细介绍。 - -### 主题样式定义 -在 `props` 下,你可以定义主题的样式。 键是 CSS 变量名,值是指定的内容。 请注意,`props` 对象是从基础主题集继承的。 如果这个主题的 `base` 是 `light`,则基础主题为 [_light.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_light.json5);如果 `dark`,则基础主题为 [_dark.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_dark.json5)。 换句话说,即使这个主题中的 `props` 中没有定义关键的 `panel`,也会继承在基础主题中所拥有 `panel`。 - -#### 可以在值中使用的语法 -* 以十六进制表示的颜色 - * 例: `#00ff00` -* 以 `rgb(r, g, b)` 形式表示的颜色 - * 例: `rgb(0, 255, 0)` -* 以 `rgb(r, g, b, a)` 形式表示的包含透明度的颜色 - * 例: `rgba(0, 255, 0, 0.5)` -* 引用其他键的值 - * 以 `@{键名}` 对另一个键值的引用。请将 `{键名}` 替换为您要引用键名。 - * 例: `@panel` -* 参照常量(见下文) - * 以 `${常量名}` 对一个常量进行引用。请将 `{常量名}` 替换为您要引用常量名。 - * 例: `$main` -* 函数(见下文) - * `:{函数名}<{参数}<{颜色}` - -#### 常量 -“我不想把它作为一个CSS变量输出,但我想把它作为另一个CSS变量的值。” 你可以使用常量。如果你的键名以`$`开头,该键将不会作为CSS变量输出。 - -#### 函数 -wip diff --git a/src/docs/zh-CN/timelines.md b/src/docs/zh-CN/timelines.md deleted file mode 100644 index ee7db7f6b..000000000 --- a/src/docs/zh-CN/timelines.md +++ /dev/null @@ -1,15 +0,0 @@ -# 时间线的比较 - -https://docs.google.com/spreadsheets/d/1YIfTiY6-XccWLYR8SBnJWcY642Rq_jkTEL06BVlPYlQ/edit?usp=sharing - -## 首页 -您关注的用户的帖文 - -## 本地 -所有非指定为「首页」的本地用户的帖文 - -## 社交 -您关注的用户的帖文,和所有未指定为「首页」的本地用户的帖文 - -## 全局 -所有本地用户的未指定为「首页」的帖文,和所有到达服务器的远程用户的未指定为「首页」的帖文 diff --git a/src/docs/zh-TW/admin/disable-timelines.md b/src/docs/zh-TW/admin/disable-timelines.md deleted file mode 100644 index b081e35ab..000000000 --- a/src/docs/zh-TW/admin/disable-timelines.md +++ /dev/null @@ -1,8 +0,0 @@ -# LTL/STL/GTLの無効化 -Misskeyでは、LTL/STL/GTLをそれぞれ無効化することができます。有効/無効を切り替えるには、インスタンスコントロールパネルで設定します。 - -LTLやSTLは、そのインスタンス全員の投稿が見れるため、新規のユーザーにとってはユーザーを探す必要がなくなり、興味のあるユーザーを見つけやすいという利点があります。 しかし同時に、フォロー機能が活用されなくなったり、不適切な投稿が目につきやすくなったり、チャットのようになることで内輪感が生じて逆に新規ユーザーが参加しにくくなるといったデメリットも持ち合わせています。 サーバーによってメリット/デメリットどちらが優勢かは異なるので、オプションとして無効にできるようになっています。 もしデメリットの方が上回っていると感じたら、それらのタイムラインを無効化することも検討してください。 - -
⚠️ 無効化を行うと、ユーザーが困惑し、短期的に見て利用者が減る可能性があります。そのため、無効化の際は影響を慎重に検討し、事前に説明してフォローを整える期間を一定程度設けることを推奨します。
- -なお、管理者/モデレーターは、これらのタイムラインの無効化状態は適用されず、引き続き利用することが可能です。 diff --git a/src/docs/zh-TW/admin/faq.md b/src/docs/zh-TW/admin/faq.md deleted file mode 100644 index 317b4e065..000000000 --- a/src/docs/zh-TW/admin/faq.md +++ /dev/null @@ -1,5 +0,0 @@ -# よくある質問 -ここでは、サーバー管理者向けのよくある質問を掲載しています。 - -## デフォルトテーマを設定したい -現在、デフォルトテーマ設定機能は実装されていません。 diff --git a/src/docs/zh-TW/advanced/aiscript.md b/src/docs/zh-TW/advanced/aiscript.md deleted file mode 100644 index 604d17daa..000000000 --- a/src/docs/zh-TW/advanced/aiscript.md +++ /dev/null @@ -1,7 +0,0 @@ -# AiScript -AiScriptは、Misskeyで使用できるスクリプト言語です。 - -
ℹ️ AiScript実装はMisskeyとは別リポジトリで、オープンソースで公開されています。
- -## 使い方 -AiScriptの構文や組み込み関数などのドキュメントは、[こちら](https://github.com/syuilo/aiscript/tree/master/docs)で公開されています。 diff --git a/src/docs/zh-TW/advanced/api.md b/src/docs/zh-TW/advanced/api.md deleted file mode 100644 index 76019b614..000000000 --- a/src/docs/zh-TW/advanced/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス、Bot等(以下「アプリケーション」と呼びます)を開発できます。 ストリーミングAPIもあるので、リアルタイム性のあるアプリケーションを作ることも可能です。 - -APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。 - -## アクセストークンの取得 -基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。 - -* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む -* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む - -### 自分自身のアクセストークンを手動発行する -「設定 > API」で、自分のアクセストークンを発行できます。 - -[「APIの使い方」へ進む](#APIの使い方) - -### アプリケーション利用者にアクセストークンの発行をリクエストする -アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。 - -#### Step 1 - -UUIDを生成する。以後これをセッションIDと呼びます。 - -> このセッションIDは毎回生成し、使いまわさないようにしてください。 - -#### Step 2 - -`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。 -> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます: -* `name` ... アプリケーション名 - * > 例: `MissDeck` -* `icon` ... アプリケーションのアイコン画像URL - * > 例: `https://missdeck.example.com/icon.png` -* `callback` ... 認証が終わった後にリダイレクトするURL - * > 例: `https://missdeck.example.com/callback` - * リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます -* `permission` ... アプリケーションが要求する権限 - * > 例: `write:notes,write:following,read:drive` - * 要求する権限を`,`で区切って列挙します - * どのような権限があるかは[APIリファレンス](/api-doc)で確認できます - -#### Step 3 -ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。 - -レスポンスに含まれるプロパティ: -* `token` ... ユーザーのアクセストークン -* `user` ... ユーザーの情報 - -[「APIの使い方」へ進む](#APIの使い方) - -## APIの使い方 -**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。 - -* [APIリファレンス](/api-doc) -* [ストリーミングAPI](./stream) diff --git a/src/docs/zh-TW/advanced/create-plugin.md b/src/docs/zh-TW/advanced/create-plugin.md deleted file mode 100644 index 05708c001..000000000 --- a/src/docs/zh-TW/advanced/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# プラグインの作成 -Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。 - -## 元資料 -プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。 - -### name -プラグイン名 - -### author -プラグイン作者 - -### version -プラグインバージョン。数値を指定してください。 - -### description -プラグインの説明 - -### permissions -プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。 - -### config -プラグインの設定情報を表すオブジェクト。 キーに設定名、値に以下のプロパティを含めます。 - -#### type -設定値の種類を表す文字列。以下から選択します。 string number boolean - -#### label -ユーザーに表示する設定名 - -#### description -設定の説明 - -#### default -設定のデフォルト値 - -## APIリファレンス -AiScript標準で組み込まれているAPIは掲載しません。 - -### Mk:dialog(title text type) -ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。 - -### Mk:confirm(title text type) -確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。 - -### Mk:api(endpoint params) -Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。 - -### Mk:save(key value) -任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。 - -### Mk:load(key) -Mk:saveで永続化した指定の名前の値を読み取ります。 - -### Plugin:register_post_form_action(title fn) -投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。 - -### Plugin:register_note_action(title fn) -ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 - -### Plugin:register_user_action(title fn) -ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。 - -### Plugin:register_note_view_interruptor(fn) -UIに表示されるノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:register_note_post_interruptor(fn) -ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:open_url(url) -第一引数に渡されたURLをブラウザの新しいタブで開きます。 - -### Plugin:config -プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。 diff --git a/src/docs/zh-TW/advanced/develop-bot.md b/src/docs/zh-TW/advanced/develop-bot.md deleted file mode 100644 index 7f825e9bc..000000000 --- a/src/docs/zh-TW/advanced/develop-bot.md +++ /dev/null @@ -1,6 +0,0 @@ -# Botの作成 -[Misskey API](./api)を利用してBotの開発が可能です。 また、いくつかのBot実装が公開されているため、ぜひ参考にしてください。 - -- [syuilo/ai](https://github.com/syuilo/ai) ... Node.js上で動く、TypeScript製Bot実装 - -Botを作成したときは、プロフィール設定からBotフラグをオンにしておくことを強くおすすめします。 diff --git a/src/docs/zh-TW/advanced/reversi-bot.md b/src/docs/zh-TW/advanced/reversi-bot.md deleted file mode 100644 index 987b24971..000000000 --- a/src/docs/zh-TW/advanced/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# MisskeyリバーシBotの開発 -Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。 - -1. `games/reversi`ストリームに以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - -2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる - * イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている - -3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する - -4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - * `game`: `game`の`id` - -5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う - -6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する - -7. ゲームが開始すると、`started`イベントが流れてくる - * イベントの中身にはゲーム情報が含まれている - -8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述) - -9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる - * `color`として石の色が含まれている - * `pos`として位置情報が含まれている - -## 位置の計算法 -8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### X,Y座標 から インデックス に変換する -``` -pos = x + (y * mapWidth) -``` -`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます: -``` -mapWidth = map[0].length -``` - -### インデックス から X,Y座標 に変換する -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## マップ情報 -マップ情報は、ゲーム情報の`map`に入っています。 文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 それをもとにマップのデザインを知る事が出来ます: -* `(スペース)` ... マス無し -* `-` ... マス -* `b` ... 初期配置される黒石 -* `w` ... 初期配置される白石 - -例えば、4*4の次のような単純なマップがあるとします: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -この場合、マップデータはこのようになります: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## ユーザーにフォームを提示して対話可能Botを作成する -ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。 - -フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します: -```javascript -{ - type: 'init-form', - body: [フォームコントロールの配列] -} -``` - -フォームコントロールの配列については今から説明します。 フォームコントロールは、次のようなオブジェクトです: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... コントロールのID。 `type` ... コントロールの種類。後述します。 `label` ... コントロールと一緒に表記するテキスト。 `value` ... コントロールのデフォルト値。 - -### フォームの操作を受け取る -ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### フォームコントロールの種類 -#### 開關 -type: `switch` スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。 - -##### プロパティ -`label` ... スイッチに表記するテキスト。 - -#### ラジオボタン -type: `radio` ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。 - -##### プロパティ -`items` ... ラジオボタンの選択肢。例: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '強', - value: 3 -}] -``` - -#### スライダー -type: `slider` スライダーを表示します。 - -##### プロパティ -`min` ... スライダーの下限。 `max` ... スライダーの上限。 `step` ... 入力欄で刻むステップ値。 - -#### テキストボックス -type: `textbox` テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。 - -## ユーザーにメッセージを表示する -設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 メッセージを表示するには、次のメッセージをストリームに送信します: -```javascript -{ - type: 'message', - body: { - text: 'メッセージ内容', - type: 'メッセージの種類' - } -} -``` -メッセージの種類: `success`, `info`, `warning`, `error`。 - -## 投了する -投了をするには、このエンドポイントにリクエストします。 diff --git a/src/docs/zh-TW/advanced/share-page.md b/src/docs/zh-TW/advanced/share-page.md deleted file mode 100644 index cb5d04161..000000000 --- a/src/docs/zh-TW/advanced/share-page.md +++ /dev/null @@ -1,54 +0,0 @@ -# シェアページ -`/share`を開くと、共有用の投稿フォームを開くことができます。 ここではシェアページで利用できるクエリ文字列の一覧を示します。 - -## クエリ文字列一覧 -### 文本 - -
-
title
-
タイトルです。本文の先頭に[ … ]と挿入されます。
-
text
-
本文です。
-
url
-
URLです。末尾に挿入されます。
-
- -### リプライ情報 -以下のいずれか - -
-
replyId
-
リプライ先のノートid
-
replyUri
-
リプライ先のUrl(リモートのノートオブジェクトを指定)
-
- -### Renote情報 -以下のいずれか - -
-
renoteId
-
Renote先のノートid
-
renoteUri
-
Renote先のUrl(リモートのノートオブジェクトを指定)
-
- -### 可見性 -※specifiedに相当する値はvisibility=specifiedとvisibleAccts/visibleUserIdsで指定する - -
-
visibility
-
公開範囲 ['public' | 'home' | 'followers' | 'specified']
-
localOnly
-
0(false) or 1(true)
-
visibleUserIds
-
specified時のダイレクト先のユーザーid カンマ区切りで
-
visibleAccts
-
specified時のダイレクト先のacct(@?username[@host]) カンマ区切りで
-
- -### 檔案 -
-
fileIds
-
添付したいファイルのid(カンマ区切りで)
-
diff --git a/src/docs/zh-TW/advanced/stream.md b/src/docs/zh-TW/advanced/stream.md deleted file mode 100644 index d5e4f1773..000000000 --- a/src/docs/zh-TW/advanced/stream.md +++ /dev/null @@ -1,350 +0,0 @@ -# ストリーミングAPI - -ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。 - -## ストリームに接続する - -ストリーミングAPIを利用するには、まずMisskeyサーバーに**websocket**接続する必要があります。 - -以下のURLに、`i`というパラメータ名で認証情報を含めて、websocket接続してください。例: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。 - -
ℹ️ 認証情報の取得については、こちらのドキュメントをご確認ください。
- ---- - -認証情報は省略することもできますが、その場合非ログインでの利用ということになり、受信できる情報や可能な操作は限られます。例: - -``` -%WS_URL%/streaming -``` - ---- - -ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。 - -**ストリームでのやり取りはすべてJSONです。** - -## 頻道 -MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。 - -ひとつのストリーム上で、同時に複数のチャンネルに接続することができます。 - -### チャンネルに接続する -チャンネルに接続するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -ここで、 -* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。 -* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。 -* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。 - -
ℹ️ IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。
- -### チャンネルからのメッセージを受け取る -例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。 - -チャンネルがメッセージを発すると、次のようなデータがJSONでストリームに流れてきます: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。 -* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。 -* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。 - -### チャンネルに向けてメッセージを送信する -チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。 - -チャンネルにメッセージを送信するには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。 -* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。 -* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。 - -### チャンネルから切断する -チャンネルから切断するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。 - -## ストリームを経由してAPIリクエストする - -ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。 - -ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -ここで、 -* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 -* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 -* `data`には、エンドポイントのパラメータを含めます。 - -
ℹ️ APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。
- -### レスポンスの受信 - -APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。 - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -ここで、 -* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 -* `body`には、レスポンスが含まれています。 - -## 投稿のキャプチャ - -Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。 - -例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。 - -しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。 - -この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。 - -### 投稿をキャプチャする - -投稿をキャプチャするには、ストリームに次のようなメッセージを送信します: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャしたい投稿の`id`を設定します。 - -このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 - -例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -ここで、 -* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。 -* `body`内の`type`に、イベントの種類が設定されます。 -* `body`内の`body`に、イベントの詳細が設定されます。 - -#### イベントの種類 - -##### `reacted` -その投稿にリアクションがされた時に発生します。 - -* `reaction`に、リアクションの種類が設定されます。 -* `userId`に、リアクションを行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -その投稿が削除された時に発生します。 - -* `deletedAt`に、削除日時が設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -その投稿に添付されたアンケートに投票された時に発生します。 - -* `choice`に、選択肢IDが設定されます。 -* `userId`に、投票を行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### 投稿のキャプチャを解除する - -その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。 - -次のメッセージを送信します: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャを解除したい投稿の`id`を設定します。 - -このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 - -# チャンネル一覧 -## `main` -アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `renote` -自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。 - -#### `mention` -誰かからメンションされたときに発生するイベントです。 - -#### `readAllNotifications` -自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。 - -#### `meUpdated` -自分の情報が更新されたことを表すイベントです。 - -#### `follow` -自分が誰かをフォローしたときに発生するイベントです。 - -#### `unfollow` -自分が誰かのフォローを解除したときに発生するイベントです。 - -#### `followed` -自分が誰かにフォローされたときに発生するイベントです。 - -## `homeTimeline` -ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -タイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `localTimeline` -ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `hybridTimeline` -ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -ソーシャルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `globalTimeline` -グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 diff --git a/src/docs/zh-TW/aiscript.md b/src/docs/zh-TW/aiscript.md deleted file mode 100644 index 461478ddd..000000000 --- a/src/docs/zh-TW/aiscript.md +++ /dev/null @@ -1,4 +0,0 @@ -# AiScript - -## 函数 -用於傳遞預設值。 diff --git a/src/docs/zh-TW/api.md b/src/docs/zh-TW/api.md deleted file mode 100644 index fed245804..000000000 --- a/src/docs/zh-TW/api.md +++ /dev/null @@ -1,58 +0,0 @@ -# Misskey API - -使用MisskeyAPI以開發Misskey客戶端、Misskey連接的網路服務平台及機器人等(以下簡稱 「應用程式」)。 此外,還有串流媒體API,讓使用者建立具有實時性的應用程式。 - -要開始使用API​​,你首先需要獲得一個存取權杖。 本說明文件將介紹獲得存取權杖的步驟,及解釋基本的API使用方法。 - -## 取得存取權杖 -基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。 - -* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む -* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む - -### 自分自身のアクセストークンを手動発行する -「設定 > API」で、自分のアクセストークンを発行できます。 - -[「APIの使い方」へ進む](#API使用方法) - -### アプリケーション利用者にアクセストークンの発行をリクエストする -アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。 - -#### 步驟1 - -UUIDを生成する。以後これをセッションIDと呼びます。 - -> このセッションIDは毎回生成し、使いまわさないようにしてください。 - -#### 步驟2 - -`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。 -> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f` - -表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます: -* `name` ... アプリケーション名 - * > 例: `MissDeck` -* `icon` ... アプリケーションのアイコン画像URL - * > 例: `https://missdeck.example.com/icon.png` -* `callback` ... 認証が終わった後にリダイレクトするURL - * > 例: `https://missdeck.example.com/callback` - * リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます -* `permission` ... アプリケーションが要求する権限 - * > 例: `write:notes,write:following,read:drive` - * 要求する権限を`,`で区切って列挙します - * どのような権限があるかは[APIリファレンス](/api-doc)で確認できます - -#### 步驟3 -ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。 - -レスポンスに含まれるプロパティ: -* `token` ... ユーザーのアクセストークン -* `user` ... ユーザーの情報 - -[「APIの使い方」へ進む](#API使用方法) - -## API使用方法 -**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。 - -* [API 參考](/api-doc) -* [串流媒體API](./stream) diff --git a/src/docs/zh-TW/create-plugin.md b/src/docs/zh-TW/create-plugin.md deleted file mode 100644 index 4b4037513..000000000 --- a/src/docs/zh-TW/create-plugin.md +++ /dev/null @@ -1,74 +0,0 @@ -# 創建插件 -Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。 - -## 元資料 -プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。 - -### name -插件名稱 - -### author -插件的作者 - -### version -插件版本只允許數字! - -### Description -插件的說明 - -### permissions -插件所需的權限。 MisskeyAPIにリクエストする際に用いられます。 - -### config -表示插件配置資料的對象。 在鍵中包含設置名稱,在值中包含以下屬性。 - -#### type -表示設置值類型的字串。 從以下選擇。 string number boolean - -#### label -設置顯示給用戶的名稱 - -#### Description -設定的說明 - -#### default -設定的預設値 - -## API 參考 -AiScript標準で組み込まれているAPIは掲載しません。 - -### Mk:dialog(title text type) -ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。 - -### Mk:confirm(title text type) -確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。 - -### Mk:api(endpoint params) -Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。 - -### Mk:save(key value) -任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。 - -### Mk:load(key) -Mk:saveで永続化した指定の名前の値を読み取ります。 - -### Plugin:register_post_form_action(title fn) -投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。 - -### Plugin:register_note_action(title fn) -ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 - -### Plugin:register_user_action(title fn) -ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。 - -### Plugin:register_note_view_interruptor(fn) -UIに表示されるノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:register_note_post_interruptor(fn) -ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。 - -### Plugin:open_url(url) -第一引数に渡されたURLをブラウザの新しいタブで開きます。 - -### Plugin:config -プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。 diff --git a/src/docs/zh-TW/custom-emoji.md b/src/docs/zh-TW/custom-emoji.md deleted file mode 100644 index 2f25aa48c..000000000 --- a/src/docs/zh-TW/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# 自訂表情符號 -表情符號功能可以讓您在各個地方使用預置的圖像表情。 它可以用於發帖、回應、聊天、自我介紹和姓名等地方。 要在這些位置使用自定義表情符號,請按表情符號選擇按鈕(如果有)或鍵入`:`以顯示表情符號建議。 如果在文本中找到格式為`:foo:`的字符串,則將`foo`部分解釋為自定義表情符號名稱,並在顯示時替換為相應的自定義表情符號。 diff --git a/src/docs/zh-TW/deck.md b/src/docs/zh-TW/deck.md deleted file mode 100644 index a7d1aa5ab..000000000 --- a/src/docs/zh-TW/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# 多欄模式 - -デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。 - -## 添加欄位 -デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。 - -## 欄位的移動 -カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。 - -## 欄位的水平分割 -欄位可以垂直排列,也可以左右排列。 打開列欄位選單並選擇“向左放置”將當前列移動到左邊的欄位下方。 要取消垂直劃分,請從欄位選單中選擇“向右移動”。 - -## 欄位的設定 -您可以通過從欄位選單中選擇“編輯”來編輯欄位設置。您可以更改欄位的名稱和寬度。 - -## デッキの設定 -デッキに関する設定は、[settings/deck](/settings/deck)で行えます。 diff --git a/src/docs/zh-TW/features/antenna.md b/src/docs/zh-TW/features/antenna.md deleted file mode 100644 index 0ce63a7a1..000000000 --- a/src/docs/zh-TW/features/antenna.md +++ /dev/null @@ -1,4 +0,0 @@ -# 天線 -アンテナは、自由に条件を設定して、合致するノートを自動で収集することができる機能です。 - -条件を設定したアンテナが作成された状態で、条件に合致するノートが投稿されると、リアルタイムでそのアンテナのタイムラインにノートが追加されます。 diff --git a/src/docs/zh-TW/features/custom-emoji.md b/src/docs/zh-TW/features/custom-emoji.md deleted file mode 100644 index 193cf3eb4..000000000 --- a/src/docs/zh-TW/features/custom-emoji.md +++ /dev/null @@ -1,2 +0,0 @@ -# 自訂表情符號 -カスタム絵文字は、インスタンスで用意された画像を絵文字のように使える機能です。 ノート、リアクション、チャット、自己紹介、名前などの場所で使うことができます。 カスタム絵文字をそれらの場所で使うには、絵文字ピッカーボタン(ある場合)を押すか、`:`を入力して絵文字サジェストを表示します。 テキスト内に`:foo:`のような形式の文字列が見つかると、`foo`の部分がカスタム絵文字名と解釈され、表示時には対応したカスタム絵文字に置き換わります。 diff --git a/src/docs/zh-TW/features/deck.md b/src/docs/zh-TW/features/deck.md deleted file mode 100644 index 2e6161843..000000000 --- a/src/docs/zh-TW/features/deck.md +++ /dev/null @@ -1,18 +0,0 @@ -# 多欄模式 - -デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。 - -## カラムの追加 -デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。 - -## カラムの移動 -カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。 - -## カラムの水平分割 -カラムは左右だけでなく、上下に並べることもできます。 カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 上下分割を解除するには、カラムメニューの「右に出す」を選択します。 - -## カラムの設定 -カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。 - -## デッキの設定 -デッキに関する設定は、[settings/deck](/settings/deck)で行えます。 diff --git a/src/docs/zh-TW/features/drive.md b/src/docs/zh-TW/features/drive.md deleted file mode 100644 index 5a5940e71..000000000 --- a/src/docs/zh-TW/features/drive.md +++ /dev/null @@ -1,17 +0,0 @@ -# 雲端硬碟 -ドライブは、Misskey上でファイルを管理できる機能です。 - -[ドライブのページ](/my/drive)から任意のファイルをアップロードできるほか、アバターに設定した画像や、ノートに添付したファイルなどもすべてドライブにアップロードされます。 - -
⚠️ ドライブからファイルを削除すると、そのファイルが添付されたノートも消えます。
- -ドライブにアップロードされたファイルは、いつでもダウンロードすることができるほか、ノート作成時に「ドライブからファイルを添付」することでファイルを再利用することもできます。 - -ドライブ内にフォルダを作り、複数のファイルをまとめて整理することもできます。 - -## 閲覧注意 (NSFW) -
ℹ️ この項目が閲覧注意なわけではありません
- -閲覧注意またはNSFW (Not safe for work) は、ドライブのファイルに設定することができるフラグです。 閲覧注意フラグを設定されたファイルは、表示される際に閲覧者の操作なしには表示されなくなります。 このフラグは、例えば職場や公共の場で閲覧するのに適切でないと思われる画像などに設定し、そのような画像が突然表示されてしまうことを防ぐ目的で使われます。 - -このフラグは手動でオンオフを切り替えられるほか、モデレーターの判断で設定される場合もあります。 diff --git a/src/docs/zh-TW/features/favorite.md b/src/docs/zh-TW/features/favorite.md deleted file mode 100644 index 6c52ec94b..000000000 --- a/src/docs/zh-TW/features/favorite.md +++ /dev/null @@ -1,4 +0,0 @@ -# 我的最愛 -[ノート](./node)をお気に入りとして登録できる機能です。 お気に入り登録したノートは、[お気に入りページ](./my/favorites)で一覧することができます。 お気に入りに登録したことは相手に通知されず、お気に入りは自分しか見ることができません。 - -ノートをお気に入り登録するには、ノートメニューの「お気に入り」を押します。お気に入り解除するには、ノートメニューの「お気に入り解除」を押します。 diff --git a/src/docs/zh-TW/features/follow.md b/src/docs/zh-TW/features/follow.md deleted file mode 100644 index 1791f039b..000000000 --- a/src/docs/zh-TW/features/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# 追隨中 -ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。 diff --git a/src/docs/zh-TW/features/keyboard-shortcut.md b/src/docs/zh-TW/features/keyboard-shortcut.md deleted file mode 100644 index 87be6b7bc..000000000 --- a/src/docs/zh-TW/features/keyboard-shortcut.md +++ /dev/null @@ -1,66 +0,0 @@ -# キーボードショートカット - -## 公開 -これらのショートカットは基本的にどこでも使えます。 - - - - - - - - - - - -
ショートカット効果由来
P, N新規投稿Post, New, Note
Tタイムラインの最も新しい投稿にフォーカスTimeline, Top
Shift + N通知を表示/隠すNotifications
S搜尋Search
H, ?ヘルプを表示Help
- -## 投稿にフォーカスされた状態 - - - - - - - - - - - - - - - - - - -
ショートカット効果由来
, K, Shift + Tab上の投稿にフォーカスを移動-
, J, Tab下の投稿にフォーカスを移動-
R返信フォームを開くReply
QRenoteフォームを開くQuote
Ctrl + Q即刻Renoteする(フォームを開かずに)-
E, A, +リアクションフォームを開くEmote, reAction
0~9数字に対応したリアクションをする(対応については後述)-
F, Bお気に入りに登録Favorite, Bookmark
Del, Ctrl + D投稿を削除Delete
M, O投稿に対するメニューを開くMore, Other
SCWで隠された部分を表示 or 隠すShow, See
Escフォーカスを外す-
- -## Renoteフォーム - - - - - - - - - -
ショートカット効果由来
EnterRenoteする-
Qフォームを展開するQuote
Escフォームを閉じる-
- -## リアクションフォーム -デフォルトで「👍」にフォーカスが当たっている状態です。 - - - - - - - - - - - - - -
ショートカット効果由来
, K上のリアクションにフォーカスを移動-
, J下のリアクションにフォーカスを移動-
, H, Shift + Tab左のリアクションにフォーカスを移動-
, L, Tab右のリアクションにフォーカスを移動-
Enter, Space, +リアクション確定-
0~9数字に対応したリアクションで確定-
Escリアクションするのをやめる-
diff --git a/src/docs/zh-TW/features/mfm.md b/src/docs/zh-TW/features/mfm.md deleted file mode 100644 index 5be2df4f3..000000000 --- a/src/docs/zh-TW/features/mfm.md +++ /dev/null @@ -1,12 +0,0 @@ -# MFM -MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます。 - -## MFMが使用可能な場所の例 -- ノート本文 -- CW注釈 -- ユーザーの名前 -- ユーザーの自己紹介 - -## 開発者向け情報 -MFMのパーサー実装はライブラリとして公開されており、簡単にクライアントにMFMを組み込むことが可能です。 -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptパーサー実装 diff --git a/src/docs/zh-TW/features/mute-and-block.md b/src/docs/zh-TW/features/mute-and-block.md deleted file mode 100644 index baf0616a4..000000000 --- a/src/docs/zh-TW/features/mute-and-block.md +++ /dev/null @@ -1,41 +0,0 @@ -# 靜音和封鎖 -好みではないユーザーがいる場合は、ミュートを行うことでそのユーザーが自分から見えないようにすることができます。 また、より強力な措置として、ブロックを行うことでそのユーザーから自分のコンテンツが見えないようになるほか、自分に対して関わることができないようにすることができます。 ミュートされていることは相手は分かりませんが、ブロックされていることは相手に分かります。どちらを選ぶかはご自身の判断で行ってください。 - -
ℹ️ ミュートとブロックは併用できます。
- -
⚠️ 利用規約に違反するような、迷惑なユーザーがいる場合は運営者に報告することも検討してください。
- -設定>ミュートとブロック から、自分がミュートまたはブロックしているユーザー一覧を確認することができます。 - -## 靜音 -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -- タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -- そのユーザーからの通知 -- メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 -- など - -ユーザーをミュートするには、対象のユーザーのユーザーページのメニューを開き、「ミュート」ボタンを押します。 - -
ℹ️ ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。
- -## 封鎖 -ユーザーをブロックすると、そのユーザーからあなたのコンテンツが見えないようになり、またあなたに対して以下のようなアクションをすることができなくなります。 - -- フォローする -- ユーザーリストに追加する -- 返信する、Renoteする -- リアクションする、アンケートに投票する -- メッセージを送信する -- など - -また、 - -- ブロックする際に既にそのユーザーからフォローされていた場合はフォローが解除されます。 -- ブロックする際に既にそのユーザーがあなたをユーザーリストに入れていた場合はそのリストからあなたが削除されます。 - -ユーザーをブロックするには、対象のユーザーのユーザーページのメニューを開き、「ブロック」ボタンを押します。 - -
⚠️ ブロックを行ったこと自体は相手に通知されませんが、フォローを行ったりなどの上記のアクションが行えなくなるので間接的にブロックされていることは分かります。
- -
⚠️ 相手から自分のコンテンツが見えなくなりますが、相手がアカウントを切り替えたりログアウト状態になれば見ることができます。あくまで簡易的、補助的なものとしてお考えください。
diff --git a/src/docs/zh-TW/features/mute.md b/src/docs/zh-TW/features/mute.md deleted file mode 100644 index 7d17ef432..000000000 --- a/src/docs/zh-TW/features/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# 靜音 - -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -* タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -* そのユーザーからの通知 -* メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 - -ユーザーをミュートするには、対象のユーザーのユーザーページに表示されている「ミュート」ボタンを押します。 - -ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。 - -設定>ミュート から、自分がミュートしているユーザー一覧を確認することができます。 diff --git a/src/docs/zh-TW/features/note.md b/src/docs/zh-TW/features/note.md deleted file mode 100644 index 4d8a6de92..000000000 --- a/src/docs/zh-TW/features/note.md +++ /dev/null @@ -1,54 +0,0 @@ -# 貼文 -ノートは、Misskeyに投稿される、文章、ファイル、アンケートなどを含むコンテンツで、Misskeyの中心的概念です。また、そのノートを作成する行為自体もノートと呼ばれます。 - -ノートが作成されると、[タイムライン](./timeline)に追加され、自分の[フォロワー](./follow)やサーバーのユーザーが見れるようになります。 - -ノートには、[リアクション](./reaction)を行うことができます。また、返信や引用もできます。 - -ノートを[お気に入り](./favorite)登録することで、後で簡単に見返すことができます。 - -## ノートを作成する -ノートを作成するには、画面上にある鉛筆マークのボタンを押して、作成フォームを開きます。作成フォームに内容を入力し、「ノート」ボタンを押すことでノートが作成されます。 ノートには、画像、動画など任意のファイルや、[アンケート](./poll)を添付することができます。また、本文中には[MFM](./mfm)が使用でき、[メンション](./mention)や[ハッシュタグ](./hashtag)を含めることもできます。 他にも、CWや公開範囲といった設定も行えます(詳細は後述)。 -
ℹ️ コンピューターのクリップボードに画像データがある状態で、フォーム内のテキストボックスにペーストするとその画像を添付することができます。
-
ℹ️ テキストボックス内でCtrl + Enterを押すことでも投稿できます。
- -## 轉發 -既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノートをRenoteと呼びます。 自分がフォローしているユーザーの、気に入ったノートを自分のフォロワーに共有したい場合や、過去の自分のノートを再度共有したい場合に使います。 同じノートに対して無制限にRenoteを行うことができますが、あまり連続して使用すると迷惑になる場合もあるので、注意しましょう。 -
⚠️ 公開範囲がフォロワーやダイレクトのノートはRenoteできません
- -Renoteを削除するには、Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 - -## CW -Contents Warningの略で、ノートの内容を、閲覧者の操作なしには表示しないようにできる機能です。主に長大な内容を隠すためや、ネタバレ防止などに使うことができます。 設定するには、フォームの「内容を隠す」ボタン(目のアイコン)を押します。すると新しい入力エリアが表れるので、そこに内容の要約を記入します。 - -## 可見性 -ノートごとに、そのノートが公開される範囲を設定することができます。フォームの「ノート」ボタンの左にあるアイコンを押すと公開範囲を以下から選択できます。 - -### 公開 -全ての人に対してノートが公開されるほか、サーバーの全てのタイムライン(ホームタイムライン、ローカルタイムライン、ソーシャルタイムライン、グローバルタイムライン)にノートが流れます。 -
⚠️ アカウントがサイレンス状態の時は、この公開範囲は使用できません。
- -### 首頁 -全ての人に対してノートが公開されますが、フォロワー以外のローカルタイムライン、ソーシャルタイムライン、グローバルタイムラインにはノートは流れません。 - -### 追隨者 -自分のフォロワーに対してのみノートを公開します。フォロワーの全てのタイムラインに流れます。 - -### 指定使用者 -指定したユーザーに対してのみノートを公開します。指定したユーザーの全てのタイムラインに流れます。 - -### 「ローカルのみ」オプション -このオプションを有効にすると、リモートにノートを連合しなくなります。 - -### 公開範囲の比較 - - - - -
公開首頁追隨者指定使用者
フォロワーのLTL/STL/GTL
非フォロワーのLTL/STL/GTL
- -## 置頂 -ノートをピン留めすると、ユーザーページに常にそのノートを表示しておくことができます。 ノートのメニューを開き、「ピン留め」を選択してピン留めできます。 複数のノートをピン留めできます。 - -## 關注 -ノートをウォッチすると、自分以外のノートへのリアクションや返信などの通知を受け取ることができます。 ノートのメニューを開き、「ウォッチ」を選択してウォッチできます。 diff --git a/src/docs/zh-TW/features/pages.md b/src/docs/zh-TW/features/pages.md deleted file mode 100644 index 7e88aa9a4..000000000 --- a/src/docs/zh-TW/features/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# Pages - -## 變數 -変数を使うことで動的なページを作成できます。テキスト内で { 変数名 } と書くとそこに変数の値を埋め込めます。例えば Hello { thing } world! というテキストで、変数(thing)の値が ai だった場合、テキストは Hello ai world! になります。 - -変数の評価(値を算出すること)は上から下に行われるので、ある変数の中で自分より下の変数を参照することはできません。例えば上から A、B、C と3つの変数を定義したとき、Cの中でABを参照することはできますが、Aの中でBCを参照することはできません。 - -ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。 - -関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。 diff --git a/src/docs/zh-TW/features/reaction.md b/src/docs/zh-TW/features/reaction.md deleted file mode 100644 index df2a0b374..000000000 --- a/src/docs/zh-TW/features/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# 情感 -他の人のノートに、絵文字を付けて簡単にあなたの反応を伝えられる機能です。 リアクションするには、ノートの + アイコンをクリックしてピッカーを表示し、絵文字を選択します。 リアクションには[カスタム絵文字](./custom-emoji)も使用できます。 - -## リアクションピッカーのカスタマイズ -ピッカーに表示される絵文字を自分好みにカスタマイズすることができます。 設定の「リアクション」で設定します。 - -## リモート投稿へのリアクションについて -リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。 - -## リモートからのリアクションについて -リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。 diff --git a/src/docs/zh-TW/features/silence.md b/src/docs/zh-TW/features/silence.md deleted file mode 100644 index 846978499..000000000 --- a/src/docs/zh-TW/features/silence.md +++ /dev/null @@ -1,6 +0,0 @@ -# 禁言 -サイレンスは、アカウントに設定される状態のひとつです。 - -アカウントがサイレンス状態になると、ノートの公開範囲をパブリックにできなくなります。 ホーム、フォロワー、ダイレクトは選択可能なため、サイレンスを受けた場合でもフォロワーやあなたのユーザーページを直接訪れた場合は投稿を閲覧できますが、GTL(連合タイムライン)やLTL(ローカルタイムライン)には投稿が流れません。 - -アカウントのサイレンス状態は、サーバーのモデレーターによって有効化/無効化されます。 diff --git a/src/docs/zh-TW/features/theme.md b/src/docs/zh-TW/features/theme.md deleted file mode 100644 index 5c8306f09..000000000 --- a/src/docs/zh-TW/features/theme.md +++ /dev/null @@ -1,68 +0,0 @@ -# 外觀主題 - -テーマを設定して、Misskeyクライアントの見た目を変更できます。 - -## テーマの設定 -設定 > テーマ - -## テーマを作成する -テーマコードはJSON5で記述されたテーマオブジェクトです。 テーマは以下のようなオブジェクトです。 -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - -``` - -* `id` ... テーマの一意なID。UUIDをおすすめします。 -* `name` ... テーマ名 -* `author` ... テーマの作者 -* `desc` ... テーマの説明(オプション) -* `base` ... 明るいテーマか、暗いテーマか - * `light`にすると明るいテーマになり、`dark`にすると暗いテーマになります。 - * テーマはここで設定されたベーステーマを継承します。 -* `props` ... テーマのスタイル定義。これから説明します。 - -### テーマのスタイル定義 -`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 - -#### バリューで使える構文 -* 16進数で表された色 - * 例: `#00ff00` -* `rgb(r, g, b)`形式で表された色 - * 例: `rgb(0, 255, 0)` -* `rgb(r, g, b, a)`形式で表された透明度を含む色 - * 例: `rgba(0, 255, 0, 0.5)` -* 他のキーの値の参照 - * `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。 - * 例: `@panel` -* 定数(後述)の参照 - * `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。 - * 例: `$main` -* 関数(後述) - * `:{関数名}<{引数}<{色}` - -#### 常數 -「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 キー名を`$`で始めると、そのキーはCSS変数として出力されません。 - -#### 函数 -wip diff --git a/src/docs/zh-TW/features/timeline.md b/src/docs/zh-TW/features/timeline.md deleted file mode 100644 index ee3d2a8fd..000000000 --- a/src/docs/zh-TW/features/timeline.md +++ /dev/null @@ -1,31 +0,0 @@ -# 時間軸 -タイムラインは、[ノート](./note)が時系列で表示される機能です。 タイムラインには以下で示す種類があり、種類によって表示されるノートも異なります。 なお、タイムラインの種類によってはサーバーにより無効になっている場合があります。 - -## 首頁 -自分のフォローしているユーザーの投稿が流れます。HTLと略されます。 - -## 本地 -全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。LTLと略されます。 - -## 社群 -自分のフォローしているユーザーの投稿と、全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。STLと略されます。 - -## 公開 -全てのローカルユーザーの「ホーム」指定されていない投稿と、サーバーに届いた全てのリモートユーザーの「ホーム」指定されていない投稿が流れます。GTLと略されます。 - -## 對比 -| ソース | | | 時間軸 | | | -| ------------ | --- | -- | --- | -- | -- | -| 使用者 | 可見性 | 首頁 | 本地 | 社群 | 公開 | -| ローカル (フォロー) | 發佈 | ✔ | ✔ | ✔ | ✔ | -| | 首頁 | ✔ | | ✔ | | -| | 追隨者 | ✔ | ✔ | ✔ | ✔ | -| リモート (フォロー) | 發佈 | ✔ | | ✔ | ✔ | -| | 首頁 | ✔ | | ✔ | | -| | 追隨者 | ✔ | | ✔ | ✔ | -| ローカル (未フォロー) | 發佈 | | ✔ | ✔ | ✔ | -| | 首頁 | | | | | -| | 追隨者 | | | | | -| リモート (未フォロー) | 發佈 | | | | ✔ | -| | 首頁 | | | | | -| | 追隨者 | | | | | diff --git a/src/docs/zh-TW/features/widgets.md b/src/docs/zh-TW/features/widgets.md deleted file mode 100644 index 015cfc768..000000000 --- a/src/docs/zh-TW/features/widgets.md +++ /dev/null @@ -1,7 +0,0 @@ -# 小工具 -ウィジェットは、MisskeyのUI上に設置できる小型の情報表示、操作が行えるパーツです。 - -ウィジェットを編集するには、ウィジェット編集モードに切り替えます。切り替え方法はUIによって異なります。 ウィジェット編集モードでは、ウィジェットの追加、削除、並び替え、およびそれぞれのウィジェットの設定を行えます。 - -## 利用可能なウィジェット一覧 -todo diff --git a/src/docs/zh-TW/features/word-mute.md b/src/docs/zh-TW/features/word-mute.md deleted file mode 100644 index 9916b1048..000000000 --- a/src/docs/zh-TW/features/word-mute.md +++ /dev/null @@ -1,20 +0,0 @@ -# 靜音文字 -ワードミュートの設定をすると、条件に合致したノートが表示されなくなります。 - -ワードミュートには、ソフトワードミュートとハードワードミュートの2種類があります。それぞれについて設定の方法と挙動を説明します。 - -## ソフトワードミュート -ソフトワードミュートは、クライアント(アプリ)側でミュートを判断するワードミュートです。 - -ノートが設定した条件に合致すると、「(ユーザー名)が何かを言いました」という表示で隠れます。 -クリックすると元の通りに表示されます。 - -## ハードワードミュート -ハードワードミュートは、アンテナのようにサーバーが新しいノートの本文に対して条件に合致するかどうか判断し、タイムラインから対象となったノートを除外します。 - -つまり、ハードワードミュートには、以下のような特徴があります。 - -* 条件設定後、新しい投稿のみがミュートの対象になります。 -* 条件を変更しても、過去にハードミュートされたノートはミュートされたままになります。 -* 「○○が何かを言いました」でタイムラインが埋まることがありません。 -* ソフトミュートに非対応のアプリでも、ハードミュートは適用されます。 diff --git a/src/docs/zh-TW/follow.md b/src/docs/zh-TW/follow.md deleted file mode 100644 index a6997e83b..000000000 --- a/src/docs/zh-TW/follow.md +++ /dev/null @@ -1,2 +0,0 @@ -# 追隨/解除追隨 -當你追隨其他使用者時,你的時間軸上將出現他們的貼文。但是,他們對其他用戶的回覆不會被顯示。 若要追隨一個使用者,請點選其使用者頁面上的「追隨」按鈕。若要解除追隨,請再次點選「追隨」按鈕。 diff --git a/src/docs/zh-TW/general/apps.md b/src/docs/zh-TW/general/apps.md deleted file mode 100644 index 1f4c85fe8..000000000 --- a/src/docs/zh-TW/general/apps.md +++ /dev/null @@ -1,6 +0,0 @@ -# サードパーティアプリのリスト -## クライアント -todo - -## 連携サービス -todo diff --git a/src/docs/zh-TW/general/changelog.md b/src/docs/zh-TW/general/changelog.md deleted file mode 100644 index 6766a63b2..000000000 --- a/src/docs/zh-TW/general/changelog.md +++ /dev/null @@ -1,5 +0,0 @@ -# 更新履歴 -
ℹ️ このサーバーの更新履歴です。Misskeyの最新のリリースについては、GitHubをご確認ください。
- - - diff --git a/src/docs/zh-TW/general/faq.md b/src/docs/zh-TW/general/faq.md deleted file mode 100644 index c272b2ad4..000000000 --- a/src/docs/zh-TW/general/faq.md +++ /dev/null @@ -1,28 +0,0 @@ -# よくある質問 -ここでは利用上のよくある質問について掲載しています。 Misskeyのプロジェクト自体についてのよくある質問は[こちら](./misskey)に掲載されています。 - -## iOS/Androidのアプリはありますか? -公式にはそういったOSのネイティブアプリを開発していませんが、サードパーティ製のアプリがいくつかあります。 詳しくは[こちら](./apps)をご覧ください。 - -ただ、サードパーティ製アプリはどうしても機能への対応が遅れてしまうため、とくに拘りがなければ公式のWebクライアントの利用をおすすめします。 なお、MisskeyのWebクライアントはPWAに対応しているので、ネイティブアプリのように動作させることも可能です。 詳しくは[こちら](todo)をご覧ください。 - -## Mastodonクライアントでログインできないのですが? -MisskeyはMastodonのAPIと互換性がないため、一部を除きMastodonクライアントでMisskeyを利用することはできません。 - -## 他のサーバーのユーザーをフォローするときは? -メニューから検索を選び、ユーザー名をホスト込みで入力します。例: `@syuilo@misskey.io` - -## Renoteを削除するには? -Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 Renoteについては[こちら](../features/note)をご確認ください。 - -## URLのプレビューを表示させたくない -MFMには、そのURLのプレビューを無効にする構文があります。詳細は[MFMチートシート](/mfm-cheat-sheet)をご確認ください。 - -## カスタム絵文字を追加したい -運営者のみがカスタム絵文字を追加、編集、削除できます。それらを希望する場合は運営者に依頼してください。 - -## Botを開発したい -Misskey APIを利用してBotの開発が可能です。[こちら](../advanced/develop-bot)をご確認ください。 - -## ノートの翻訳機能はどのサービスを使用していますか? -[DeepL](https://www.deepl.com/)を使用しています。 diff --git a/src/docs/zh-TW/general/glossary.md b/src/docs/zh-TW/general/glossary.md deleted file mode 100644 index 3cd3dd00f..000000000 --- a/src/docs/zh-TW/general/glossary.md +++ /dev/null @@ -1,89 +0,0 @@ -# 用語集 -Misskeyに関する用語集です。 - -## ActivityPub -(読み: あくてぃびてぃぱぶ) 分散型を実現するために用いられるプロトコル(仕様)。このプロトコルに則ってサーバー同士通信を行うことで、連合が行われ、Fediverseを形成しています。 - -## AiScript -(読み: あいすくりぷと) Misskey上で使用できるプログラミング言語です。詳細は[こちら。](../advanced/aiscript) - -## API -(読み: えーぴーあい) Misskeyのサーバーが公開している、プログラムからMisskeyを扱うためのインターフェース。詳細は[こちら。](../advanced/api) - -## Bot -(読み: ぼっと) プログラムによって動作しているアカウント。 - -## CW -(読み: こんてんつわーにんぐ) Contents Warningの略。ノートの内容を、操作なしには表示しないようにできる機能。主に長大な内容を隠すためや、ネタバレ防止などに使われます。 - -## Fediverse -(読み: ふぇでぃばーす) Misskeyを含む様々な分散型ソフトウェアのサーバーで構成されたネットワーク。 - -## GTL -グローバルタイムライン(Global TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## HTL -ホームタイムライン(Home TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## LTL -ローカルタイムライン(Local TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## MFM -(読み: えむえふえむ) Misskey Flavored Markdownの略で、Misskey上で使用できるマークアップ言語です。詳細は[こちら。](../features/mfm) - -## NSFW -(読み: のっとせーふふぉーわーく) Not Safe For Workの略。画像を「閲覧注意」扱いにし、操作なしには表示しないようにすることができる機能。 - -## 轉發 -(読み: りのーと) 既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノート。詳細は[こちら。](../features/note) - -## STL -ソーシャルタイムライン(Social TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline) - -## 藍 -(読み: あい) Misskeyの看板娘(公式キャラクター)です。 - -## アクティブユーザー -インスタンスにアカウントを作っているユーザーのうち、現在も実際にサービスを利用しているユーザーのこと。 - -## 實例 -todo - -## 自訂表情符號 -サーバーで用意された絵文字。カスタム絵文字ではない通常の絵文字は「Unicode絵文字」と区別して呼ばれる。 - -## コントロールパネル -インスタンスの設定画面のこと。 - -## 伺服器 -todo - -## 禁言 -ノートをパブリックな公開範囲で投稿できなくされている状態。モデレーターの判断でユーザーごとに設定されます。詳細は[こちら。](../features/silence) - -## 佇列 -アクティビティ配送などを順番に行うためのシステム。 - -## 凍結 -アカウントが使用不可に設定されている状態。 - -## 雲端硬碟 -Misskeyにアップロードしたファイルを管理する機能。詳細は[こちら。](../features/drive) - -## 貼文 -Misskeyに投稿される、文章、ファイル、アンケートなどを含めることができるコンテンツ。詳細は[こちら。](../features/note) - -## ミスキスト -Misskeyを使う人のこと。 - -## 板主 -スパムの凍結およびサイレンスや不適切な投稿の削除など、コミュニティ運営に関する権限を持つユーザー。 - -## 遠端 -他サーバーのことを指します。リモートユーザーといったように接頭辞としても使われます。ローカルの逆です。 - -## 站台聯邦 -サーバー上で作成された情報が他のサーバーに伝わること。 - -## 本地 -自サーバーのことを指します。ローカルユーザー、ローカルタイムラインといったように接頭辞としても使われます。リモートの逆です。 diff --git a/src/docs/zh-TW/general/links.md b/src/docs/zh-TW/general/links.md deleted file mode 100644 index a3844d1db..000000000 --- a/src/docs/zh-TW/general/links.md +++ /dev/null @@ -1,12 +0,0 @@ -# リンク集 - -## Webサイト -- [Official Discord](https://discord.gg/Wp8gVStHW3) - Misskey公式Discordサーバー -- [Misskey Forum](https://forum.misskey.io/) - Misskeyに関する話題を扱うフォーラム - -## 帳戶 -- [@repo@misskey.io](https://misskey.io/@repo) - Misskeyのリポジトリの更新を投稿するbot - -## ライブラリ -- [misskey-dev/misskey.js](https://github.com/misskey-dev/misskey.js) - JavaScriptのMisskey SDK -- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptのMFMパーサー実装 diff --git a/src/docs/zh-TW/general/misskey.md b/src/docs/zh-TW/general/misskey.md deleted file mode 100644 index 915684a82..000000000 --- a/src/docs/zh-TW/general/misskey.md +++ /dev/null @@ -1,87 +0,0 @@ -# 關於 Misskey - -Misskeyはオープンソースの分散型マイクロブログプラットフォームプロジェクトです。 開発は日本でsyuiloによって2014年から開始されました。 ドライブ、リアクションなどの豊富な機能や、高いカスタマイズ性を備えたUIを持つことが特徴です。 - -## 歴史 -開発当初は掲示板がメインのサービスでしたが、ユーザーが短文を投稿し、それを時系列で流れるタイムライン機能を追加したところ人気が高まり、徐々にそれがメインとして開発が進むようになりました。 当初は分散型ではありませんでしたが、2018年にActivityPubを実装し分散型になったことで、より多くの方に認知され利用されるサービスになり、現在に至ります。 -
ℹ️ Misskeyという名前は、syuiloが当時聴いていたMay'nというアーティストの楽曲、Brain Diverの歌詞に由来します。
- -誰でも開発に参加することができ、現在でも活発に開発が続いています。 - -## 分散型とは何か? - -分散(distributed)型とは、非中央集権(decentralized)とも呼ばれ、コミュニティが多数のサーバーに分散して存在し、それらが相互に通信(連合、federation)することでコンテンツ共有ネットワーク(Fediverse)を形成していることが特徴のサービスです。 単一のサーバーしか存在しない、もしくは複数存在しても互いに独立している場合は中央集権なサービスと言われ、例えばTwitterやFacebookなどほとんどのサービスがそれに該当します。 分散型のメリットは、自分に合った運営者やテーマのサーバーを選択できることです。自分でサーバーを作成することもできます。連合するおかげで、どのサーバーを選んでも、同じコミュニティにアクセスできます。 - -## 常にオープンソース -Misskeyはこれまでもこれからも、オープンソースであり続けます。オープンソースとは、簡単に言うとソフトウェアのソースコード(プログラム)が公開されていることです。ソースコードの修正や再配布が可能であることを定義に含めることもあります。 Misskeyのすべてのソースコードは[AGPL](https://github.com/misskey-dev/misskey/blob/develop/LICENSE)というオープンソースライセンスの下に[公開](https://github.com/misskey-dev)されていて、誰でも自由に閲覧、使用、修正、改変、再配布をすることができます。 オープンソースは、自分で好きなように変えたり、有害な処理が含まれていないことを確認することができたり、誰でも開発に参加できるなどの、様々なメリットがあります。 上述の分散型を実現するためにも、オープンソースであるということは必要不可欠な要素です。 再び引き合いに出しますが、TwitterやFacebookなどの利益を得ているほとんどのサービスはオープンソースではありません。 - -
ℹ️ 技術的に言うと、MisskeyのソースコードはGitで管理されていて、リポジトリはGitHub上でホスティングされています。
- -## 開発に参加する、プロジェクトを支援する -Misskeyを気に入っていただけたら、ぜひプロジェクトを支援してください。プロジェクトに貢献するには、以下で紹介するようにいろいろな方法があります。方法によっては開発のスキルは不要なので、誰でも気軽に参加し貢献することができます。いつでもお待ちしています。 - -### 機能を追加したり、バグを修正する -ソフトウェアエンジニアのスキルをお持ちの方であれば、ソースコードを編集する形でプロジェクトに貢献することができます。 貢献についてのガイドは[こちら](https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md)です。 - -### 議論に参加する -新しい機能、または既存の機能について意見を述べたり、不具合を報告したりすることでも貢献できます。 そのようなディスカッションは[GitHub](https://github.com/misskey-dev)上か、[フォーラム](https://forum.misskey.io/)等で行われます。 - -### テキストを翻訳する -Misskeyは様々な言語に対応しています(i18n -internationalizationの略- と呼ばれます)。元の言語は基本的に日本語ですが、有志によって他の言語へと翻訳されています。 その翻訳作業に加わっていただくことでもMisskeyに貢献できます。 Misskeyは[Crowdinというサービスを使用して翻訳の管理を行っています。](https://crowdin.com/project/misskey) - -### 感想を投稿する -不具合報告等だけではなく、Misskeyの良い点、楽しい点といったポジティブな意見もぜひ共有してください。開発の励みになり、それは間接的ですがプロジェクトへの貢献です。 - -### ミスキストを増やす -ミスキストとは、Misskeyを使用する人のことです。 知り合いに紹介するなどしてMisskeyを広めていただければ、ミスキストが増え開発のモチベーションが上がります。 - -### 寄付をする -Misskeyはビジネスではなく、利用は無料であるため、収益は皆様からの寄付のみです。(インスタンスによっては広告収入を得ているような場合もありますが、それは運営者の収入であり直接開発者への収入にはなりません) 寄付をしていただければ、今後も開発を続けることが可能になり、プロジェクトへの貢献になります。 寄付は基本的には[Patreon](https://www.patreon.com/syuilo)で受け付けています。 一定額寄付していただけると、Misskeyの[情報ページ](/about-misskey)に名前を記載することができます。 - -また、サーバーの運営者も、基本的には収益を得ていません。サーバーの運営にはコストがかかるので、運営者の支援をすることもご検討ください。 開発には直接関係しませんが、サーバーがあってこそのプロジェクトなので、運営が維持されるというのは開発と同じくらい重要なことです。 - -## クレジット -Misskeyの開発者や、Misskeyに寄付をしてくださった方の一覧は[こちら](/about-misskey)で見ることができます。 - -## よくある質問 -### プロジェクトは何を目指していますか? -強いて言うと、漠然的になりますが広く使われる汎用的なプラットフォームになることを目指しています。 Misskeyは他のプロジェクトとは違い、何らかの思想(例えば、反中央集権)やビジョンに基づいて開発が行われているわけではなく、その点ではフラットです。 それが逆に、特定の方向性に縛られないフレキシブルさを生み出すことに繋がっていると感じています。 - - -### 企業によって開発されていますか? -いいえ。Misskeyの開発は個人で行われており、商業的でもないため、特定の企業の関りはありません。 開発メンバーも基本的にはボランティアです。 また、開発に対し企業のスポンサーがつくこともありますが、その場合でもやはり開発は個人のコミュニティが主体です。 - -### 誰が運営していますか? -Misskeyは分散型なため、各サーバーにそれぞれ異なった運営者がいます。従って、特定の個人や企業によって、Misskeyの全てが運営されているわけではありません。 また、開発チームが運営を行うわけでもないため、運営に関する連絡は、お使いのサーバーの運営者に行ってください。 サーバーの運営者は、[このページ](/about)で確認することができます。 あなたがサーバーを作成すれば、あなたが運営者になります。 - -### どのサーバーを選べばいいですか? -[サーバー一覧が公開されています。](https://join.misskey.page/ja-JP/instances) サーバーによってコミュニティのテーマ(特定のこと、ものが好き 等)が決められている場合があるので、自分に合ったテーマのサーバーがあれば、そこを選ぶと良いかもしれません。 他にも、サーバーの規模、ユーザー層、国および言語、運営者が信頼できるかどうか、などの観点があります。 なお、Misskey公式のサーバーというものはありません。自身で新しくサーバーを作成するという選択肢もあります。 - -基本的にどのサーバーを選んだとしても、他の全てのサーバーのユーザーと繋がることができます。 - -### サーバーを建てるにはどうしたらいいですか? -Misskeyサーバーの作成に興味を持っていただきありがとうございます。 2021年現在、Misskeyのホスティングサービスは存在しないため、サーバーの作成にはある程度の知識が必要です。 サーバーの作成方法については[こちら](todo)をご覧ください。 - -### どのような技術を使用していますか? -Misskeyは開発が進むにつれ使用する技術も大きく変わってきました。開発当初はMySQL + PHP + jQueryといった構成でしたが、現在は以下のようになっています。 -- サーバーサイド: Node.js -- データベース: PostgreSQL、Redis -- UIフレームワーク: Vue.js -- プログラミング言語: TypeScript - -また、MFMやAiScriptなどの、Misskeyから派生して独自の技術も開発しています。 - -### Mastodonのフォークですか? -いいえ。MisskeyはMastodonやその他のプロジェクトとは全く別のプロジェクトです。 開発に関しても、Misskeyの方が昔から開発されています。ただし、分散型になったのはMastodonの登場より後です。 同じActivityPubという分散のためのプロトコルを実装しているという点以外、両者に特に関りがあるわけでもありません。 - -### iOS/Androidのアプリはありますか? -公式にはそういったOSのネイティブアプリを開発していませんが、サードパーティ製のアプリがいくつかあります。 詳しくは[こちら](./apps)をご覧ください。 - -ただ、サードパーティ製アプリはどうしても機能への対応が遅れてしまうため、とくに拘りがなければ公式のWebクライアントの利用をおすすめします。 なお、MisskeyのWebクライアントはPWAに対応しているので、ネイティブアプリのように動作させることも可能です。 詳しくは[こちら](todo)をご覧ください。 - -### Misskeyのロゴ、アイコンはどこで入手できますか? -(準備中) - -### 時折目にする猫耳の可愛い女の子は? -Misskeyの守り神、藍ちゃんです。アイチャンカワイイヤッター! -
ℹ️ 藍ちゃんについてはこちらです。
diff --git a/src/docs/zh-TW/general/report-issue.md b/src/docs/zh-TW/general/report-issue.md deleted file mode 100644 index 63527e32a..000000000 --- a/src/docs/zh-TW/general/report-issue.md +++ /dev/null @@ -1,8 +0,0 @@ -# 不具合の報告 -不具合と思われる状況に遭遇したときは、まず[トラブルシューティング](./troubleshooting)をご一読ください。 それでも問題が解決しないときは、以下の情報を含めて[フォーラム](https://forum.misskey.io/)に投稿してください。 投稿することで、解決策が見つかったり、不具合と判断されれば開発チームによって修正が行われます。 - -## 含める情報 -- Misskeyのバージョン([情報ページ](/about)で確認できます) -- お使いのブラウザの種類とバージョン -- お使いのOSの種類とバージョン -- 問題の再現手順 diff --git a/src/docs/zh-TW/general/troubleshooting.md b/src/docs/zh-TW/general/troubleshooting.md deleted file mode 100644 index f895b4984..000000000 --- a/src/docs/zh-TW/general/troubleshooting.md +++ /dev/null @@ -1,40 +0,0 @@ -# トラブルシューティング -
ℹ️ よくある質問も合わせてお役立てください。
- -問題が発生したときは、まずこちらをご確認ください。 該当する項目が無い、もしくは手順を試しても効果がない場合は、サーバーの管理者に連絡するか[不具合を報告](./report-issue)してください。 - -## クライアントが起動しない -ほとんどの場合、お使いのブラウザまたはOSのバージョンが古いことが原因です。 ブラウザおよびOSのバージョンを最新のものに更新してから、再度試してみてください。 - -これは稀ですが、それでも起動しない場合は、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。 - -## ページが読み込めない -クライアントが起動するもののページが読み込めないというエラーが出る場合は、ネットワークに問題がないか確認してください。また、サーバーがダウンしていないか確認してください。 - -これは稀ですが、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。 - -まだ問題がある場合は、サーバーの問題と思われるのでサーバーの管理者に連絡してください。 - -## クライアントの動作が遅い -以下を試してみてください: - -- クライアント設定で「UIのアニメーションを減らす」を有効にする -- クライアント設定で「モーダルにぼかし効果を使用」を無効にする -- お使いのブラウザの設定でハードウェアアクセラレーションを有効にする -- お使いのデバイスのスペックを上げる - -## UIの一部の表示がおかしい(背景が透明になっている等) -アップデートによりUIの改修が行われたときに、テーマのキャッシュシステムの影響でそのような表示になることがあります。 クライアントの設定の「キャッシュをクリア」すると直ります。 -
⚠️ 「クライアントの」キャッシュクリアです。「ブラウザの」キャッシュクリアは行わないでください。
- -## 通知やアンテナ等の点滅が消えない -点滅は、未読のコンテンツがあることを示しています。通常点滅が消えない場合は、コンテンツを遡ると未読なコンテンツが残っています。 すべて既読にしたと思われるのに、それでもなお点滅が続く場合(おそらく不具合と思われます)は設定から強制的にすべて既読扱いにすることができます。 - -## Renoteができない -フォロワー限定のノートはRenoteすることはできません。 - -## UI上で特定の要素が表示されない -広告ブロッカーを使用しているとそのような不具合が発生することがあります。Misskeyではオフにしてご利用ください。 - -## UI上で未翻訳の部分がある -ほとんどの場合、単に翻訳が間に合っていないだけで、不具合ではありません。翻訳が終わるまでお待ちください。 [翻訳に参加](./misskey)していただくことも可能です。 diff --git a/src/docs/zh-TW/keyboard-shortcut.md b/src/docs/zh-TW/keyboard-shortcut.md deleted file mode 100644 index 9f8dee9db..000000000 --- a/src/docs/zh-TW/keyboard-shortcut.md +++ /dev/null @@ -1,68 +0,0 @@ -# 鍵盤快速鍵 - -## 公開 -這些快捷方式基本上可以在任何地方使用。 - - - - - - - - - - - -
快速鍵功能由來
P, N發佈貼文Post, New, Note
T轉跳至時間軸最新發佈的內容Timeline, Top
Shift + N顯示/隱藏通知Notifications
S搜尋Search
H, ?取得說明Help
- -## 投稿にフォーカスされた状態 - - - - - - - - - - - - - - - - - - - -
快速鍵功能由來
, K, Shift + Tab上の投稿にフォーカスを移動-
, J, Tab下の投稿にフォーカスを移動-
R返信フォームを開くReply
QRenoteフォームを開くQuote
Ctrl + Q即刻Renoteする(フォームを開かずに)-
E, A, +リアクションフォームを開くEmote, reAction
0~9数字に対応したリアクションをする(対応については後述)-
F, B加入至我的最愛Favorite, Bookmark
Del, Ctrl + D刪除貼文Delete
M, O顯示貼文選單More, Other
S隱藏或顯示敏感媒體Show, See
Esc取消選取-
- -## 轉發選單 - - - - - - - - - - -
快速鍵功能由來
Enter轉發貼文-
Q展開選單Quote
Esc關閉選單-
- -## 操作表單 -デフォルトで「👍」にフォーカスが当たっている状態です。 - - - - - - - - - - - - - -
快速鍵功能由來
, K上のリアクションにフォーカスを移動-
, J下のリアクションにフォーカスを移動-
, H, Shift + Tab左のリアクションにフォーカスを移動-
, L, Tab右のリアクションにフォーカスを移動-
Enter, Space, +リアクション確定-
0~9数字に対応したリアクションで確定-
Escリアクションするのをやめる-
diff --git a/src/docs/zh-TW/mfm.md b/src/docs/zh-TW/mfm.md deleted file mode 100644 index 675451784..000000000 --- a/src/docs/zh-TW/mfm.md +++ /dev/null @@ -1,2 +0,0 @@ -# MFM -MFM是Misskey Favored Markdown的縮寫,通行於Misskey的專用標記語言。 其語法可於[MFM代碼小抄](/mfm-cheat-sheet)中找到。 diff --git a/src/docs/zh-TW/mute.md b/src/docs/zh-TW/mute.md deleted file mode 100644 index cb7e8302a..000000000 --- a/src/docs/zh-TW/mute.md +++ /dev/null @@ -1,13 +0,0 @@ -# 靜音 - -當你靜音某個帳戶時,Misskey將停止推播該帳戶的以下內容: - -* 該用戶在時間軸及搜尋結果中的貼文(以及對這些貼文的回覆和轉發)。 -* 該使用者的通知 -* 使用者在訊息歷史記錄列表中的訊息歷史記錄 - -要靜音某個帳戶,可於其用戶檔案頁上點選**靜音**按鈕。 - -被您靜音的用戶不會被通知已被靜音,也不會知道您已靜音他們。 - -您可在**設定**>**靜音**中瀏覽已被您靜音的用戶。 diff --git a/src/docs/zh-TW/pages.md b/src/docs/zh-TW/pages.md deleted file mode 100644 index 538a10dad..000000000 --- a/src/docs/zh-TW/pages.md +++ /dev/null @@ -1,10 +0,0 @@ -# 頁面 - -## 變數 -您可以使用變數來創建動態頁面。 テキスト内で { 変数名 } と書くとそこに変数の値を埋め込めます。例えば Hello { thing } world! というテキストで、変数(thing)の値が ai だった場合、テキストは Hello ai world! になります。 - -変数の評価(値を算出すること)は上から下に行われるので、ある変数の中で自分より下の変数を参照することはできません。例えば上から A、B、C と3つの変数を定義したとき、Cの中でABを参照することはできますが、Aの中でBCを参照することはできません。 - -ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。 - -関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。 diff --git a/src/docs/zh-TW/reaction.md b/src/docs/zh-TW/reaction.md deleted file mode 100644 index 8640cb70a..000000000 --- a/src/docs/zh-TW/reaction.md +++ /dev/null @@ -1,11 +0,0 @@ -# 情感 -他の人のノートに、絵文字を付けて簡単にあなたの反応を伝えられる機能です。 リアクションするには、ノートの + アイコンをクリックしてピッカーを表示し、絵文字を選択します。 リアクションには[カスタム絵文字](./custom-emoji)も使用できます。 - -## リアクションピッカーのカスタマイズ -ピッカーに表示される絵文字を自分好みにカスタマイズすることができます。 設定の「リアクション」で設定します。 - -## リモート投稿へのリアクションについて -リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。 また、相手がMisskeyであったとしても、カスタム絵文字リアクションは伝わらず、自動的に「👍」等にフォールバックされます。 - -## リモートからのリアクションについて -リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。 diff --git a/src/docs/zh-TW/reversi-bot.md b/src/docs/zh-TW/reversi-bot.md deleted file mode 100644 index 987b24971..000000000 --- a/src/docs/zh-TW/reversi-bot.md +++ /dev/null @@ -1,160 +0,0 @@ -# MisskeyリバーシBotの開発 -Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。 - -1. `games/reversi`ストリームに以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - -2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる - * イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている - -3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する - -4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - * `game`: `game`の`id` - -5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う - -6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する - -7. ゲームが開始すると、`started`イベントが流れてくる - * イベントの中身にはゲーム情報が含まれている - -8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述) - -9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる - * `color`として石の色が含まれている - * `pos`として位置情報が含まれている - -## 位置の計算法 -8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### X,Y座標 から インデックス に変換する -``` -pos = x + (y * mapWidth) -``` -`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます: -``` -mapWidth = map[0].length -``` - -### インデックス から X,Y座標 に変換する -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## マップ情報 -マップ情報は、ゲーム情報の`map`に入っています。 文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 それをもとにマップのデザインを知る事が出来ます: -* `(スペース)` ... マス無し -* `-` ... マス -* `b` ... 初期配置される黒石 -* `w` ... 初期配置される白石 - -例えば、4*4の次のような単純なマップがあるとします: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -この場合、マップデータはこのようになります: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## ユーザーにフォームを提示して対話可能Botを作成する -ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。 - -フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します: -```javascript -{ - type: 'init-form', - body: [フォームコントロールの配列] -} -``` - -フォームコントロールの配列については今から説明します。 フォームコントロールは、次のようなオブジェクトです: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... コントロールのID。 `type` ... コントロールの種類。後述します。 `label` ... コントロールと一緒に表記するテキスト。 `value` ... コントロールのデフォルト値。 - -### フォームの操作を受け取る -ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### フォームコントロールの種類 -#### 開關 -type: `switch` スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。 - -##### プロパティ -`label` ... スイッチに表記するテキスト。 - -#### ラジオボタン -type: `radio` ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。 - -##### プロパティ -`items` ... ラジオボタンの選択肢。例: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '強', - value: 3 -}] -``` - -#### スライダー -type: `slider` スライダーを表示します。 - -##### プロパティ -`min` ... スライダーの下限。 `max` ... スライダーの上限。 `step` ... 入力欄で刻むステップ値。 - -#### テキストボックス -type: `textbox` テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。 - -## ユーザーにメッセージを表示する -設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 メッセージを表示するには、次のメッセージをストリームに送信します: -```javascript -{ - type: 'message', - body: { - text: 'メッセージ内容', - type: 'メッセージの種類' - } -} -``` -メッセージの種類: `success`, `info`, `warning`, `error`。 - -## 投了する -投了をするには、このエンドポイントにリクエストします。 diff --git a/src/docs/zh-TW/stream.md b/src/docs/zh-TW/stream.md deleted file mode 100644 index 72e3eec48..000000000 --- a/src/docs/zh-TW/stream.md +++ /dev/null @@ -1,354 +0,0 @@ -# 串流媒體API - -ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。 - -## ストリームに接続する - -ストリーミングAPIを利用するには、まずMisskeyサーバーに**websocket**接続する必要があります。 - -以下のURLに、`i`というパラメータ名で認証情報を含めて、websocket接続してください。例: -``` -%WS_URL%/streaming?i=xxxxxxxxxxxxxxx -``` - -認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。 - -
-

認証情報の取得については、こちらのドキュメントをご確認ください。

-
- ---- - -認証情報は省略することもできますが、その場合非ログインでの利用ということになり、受信できる情報や可能な操作は限られます。例: - -``` -%WS_URL%/streaming -``` - ---- - -ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。 - -**ストリームでのやり取りはすべてJSONです。** - -## 頻道 -MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。 - -### チャンネルに接続する -チャンネルに接続するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'connect', - body: { - channel: 'xxxxxxxx', - id: 'foobar', - params: { - ... - } - } -} -``` - -ここで、 -* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。 -* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。 -* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。 - -
-

IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。

-
- -### チャンネルからのメッセージを受け取る -例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。 - -チャンネルがメッセージを発すると、次のようなデータがJSONでストリームに流れてきます: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。 -* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。 -* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。 - -### チャンネルに向けてメッセージを送信する -チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。 - -チャンネルにメッセージを送信するには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'channel', - body: { - id: 'foobar', - type: 'something', - body: { - some: 'thing' - } - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。 -* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。 -* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。 - -### チャンネルから切断する -チャンネルから切断するには、次のようなデータをJSONでストリームに送信します: - -```json -{ - type: 'disconnect', - body: { - id: 'foobar' - } -} -``` - -ここで、 -* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。 - -## ストリームを経由してAPIリクエストする - -ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。 - -ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します: -```json -{ - type: 'api', - body: { - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } - } -} -``` - -ここで、 -* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 -* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 -* `data`には、エンドポイントのパラメータを含めます。 - -
-

APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。

-
- -### レスポンスの受信 - -APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。 - -```json -{ - type: 'api:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -ここで、 -* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 -* `body`には、レスポンスが含まれています。 - -## 投稿のキャプチャ - -Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。 - -例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。 - -しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。 - -この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。 - -### 投稿をキャプチャする - -投稿をキャプチャするには、ストリームに次のようなメッセージを送信します: - -```json -{ - type: 'subNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャしたい投稿の`id`を設定します。 - -このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 - -例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます: - -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -ここで、 -* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。 -* `body`内の`type`に、イベントの種類が設定されます。 -* `body`内の`body`に、イベントの詳細が設定されます。 - -#### イベントの種類 - -##### `reacted` -その投稿にリアクションがされた時に発生します。 - -* `reaction`に、リアクションの種類が設定されます。 -* `userId`に、リアクションを行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'reacted', - body: { - reaction: 'like', - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -##### `deleted` -その投稿が削除された時に発生します。 - -* `deletedAt`に、削除日時が設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'deleted', - body: { - deletedAt: '2018-10-22T02:17:09.703Z' - } - } -} -``` - -##### `pollVoted` -その投稿に添付されたアンケートに投票された時に発生します。 - -* `choice`に、選択肢IDが設定されます。 -* `userId`に、投票を行ったユーザーのIDが設定されます。 - -例: -```json -{ - type: 'noteUpdated', - body: { - id: 'xxxxxxxxxxxxxxxx', - type: 'pollVoted', - body: { - choice: 2, - userId: 'yyyyyyyyyyyyyyyy' - } - } -} -``` - -### 投稿のキャプチャを解除する - -その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。 - -次のメッセージを送信します: - -```json -{ - type: 'unsubNote', - body: { - id: 'xxxxxxxxxxxxxxxx' - } -} -``` - -ここで、 -* `id`にキャプチャを解除したい投稿の`id`を設定します。 - -このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 - -# チャンネル一覧 -## `main` -アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `renote` -自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。 - -#### `mention` -誰かからメンションされたときに発生するイベントです。 - -#### `readAllNotifications` -自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。 - -#### `meUpdated` -自分の情報が更新されたことを表すイベントです。 - -#### `follow` -自分が誰かをフォローしたときに発生するイベントです。 - -#### `unfollow` -自分が誰かのフォローを解除したときに発生するイベントです。 - -#### `followed` -自分が誰かにフォローされたときに発生するイベントです。 - -## `homeTimeline` -ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `note` -タイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `localTimeline` -ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `備註` -ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -## `hybridTimeline` -ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `備註` -當新貼文到達時間軸時發生的事件。 - -## `globalTimeline` -グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。 - -### 流れてくるイベント一覧 - -#### `備註` -グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。 diff --git a/src/docs/zh-TW/theme.md b/src/docs/zh-TW/theme.md deleted file mode 100644 index 6715dce72..000000000 --- a/src/docs/zh-TW/theme.md +++ /dev/null @@ -1,70 +0,0 @@ -# 外觀主題 - -テーマを設定して、Misskeyクライアントの見た目を変更できます。 - -## 佈景主題設定 -設定 > 佈景主題 - -## 製造佈景主題 -テーマコードはJSON5で記述されたテーマオブジェクトです。 テーマは以下のようなオブジェクトです。 -``` js -{ - id: '17587283-dd92-4a2c-a22c-be0637c9e22a', - - name: 'Danboard', - author: 'syuilo', - - base: 'light', - - props: { - accent: 'rgb(218, 141, 49)', - bg: 'rgb(218, 212, 190)', - fg: 'rgb(115, 108, 92)', - panel: 'rgb(236, 232, 220)', - renote: 'rgb(100, 152, 106)', - link: 'rgb(100, 152, 106)', - mention: '@accent', - hashtag: 'rgb(100, 152, 106)', - header: 'rgba(239, 227, 213, 0.75)', - navBg: 'rgb(216, 206, 182)', - inputBorder: 'rgba(0, 0, 0, 0.1)', - }, -} - - - -``` - -* `id` ... 佈景主題唯一識別碼。建議使用UUID。 -* `name` ... 佈景主題名稱 -* `author` ... 佈景主題作者 -* `desc` ... 佈景主題説明(可選) -* `base` ... 採用淺色底色/深色底色 - * `light`にすると明るいテーマになり、`dark`にすると暗いテーマになります。 - * テーマはここで設定されたベーステーマを継承します。 -* `props` ... テーマのスタイル定義。これから説明します。 - -### テーマのスタイル定義 -`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 - -#### バリューで使える構文 -* 以十六進位色碼標示 - * 例: `#00ff00` -* 以`rgb(r, g, b)`形式標示RGB顏色 - * 例: `rgb(0, 255, 0)` -* 以`rgb(r, g, b, a)`形式標示RGBA顏色 - * 例: `rgba(0, 255, 0, 0.5)` -* 他のキーの値の参照 - * `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。 - * 例: `@panel` -* 定数(後述)の参照 - * `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。 - * 例: `$main` -* 函數(見下文) - * `:{函數名稱}<{參數}<{顏色}` - -#### 常數 -「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 キー名を`$`で始めると、そのキーはCSS変数として出力されません。 - -#### 函数 -wip diff --git a/src/docs/zh-TW/timelines.md b/src/docs/zh-TW/timelines.md deleted file mode 100644 index a0ef71c60..000000000 --- a/src/docs/zh-TW/timelines.md +++ /dev/null @@ -1,15 +0,0 @@ -# 不同時間軸的差異 - -https://docs.google.com/spreadsheets/d/1lxQ2ugKrhz58Bg96HTDK_2F98BUritkMyIiBkOByjHA/edit?usp=sharing - -## 首頁 -顯示已追隨使用者的貼文 - -## 本地 -顯示所有的本地用戶的首頁貼文 - -## 社群 -顯示已追隨使用者的貼文及所有的本地用戶的貼文 - -## 公開 -顯示已追隨使用者、所有的本地用戶及遠端使用者所發佈的的貼文 diff --git a/src/index.ts b/src/index.ts deleted file mode 100644 index db1b53f51..000000000 --- a/src/index.ts +++ /dev/null @@ -1,13 +0,0 @@ -/** - * Misskey Entry Point! - */ - -Error.stackTraceLimit = Infinity; - -require('events').EventEmitter.defaultMaxListeners = 128; - -import boot from './boot/index'; - -export default function() { - return boot(); -} diff --git a/src/mfm/from-html.ts b/src/mfm/from-html.ts deleted file mode 100644 index 14279f338..000000000 --- a/src/mfm/from-html.ts +++ /dev/null @@ -1,209 +0,0 @@ -import * as parse5 from 'parse5'; -import treeAdapter = require('parse5/lib/tree-adapters/default'); -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; - - const dom = parse5.parseFragment(html); - - let text = ''; - - for (const n of dom.childNodes) { - analyze(n); - } - - return text.trim(); - - function getText(node: parse5.Node): string { - if (treeAdapter.isTextNode(node)) return node.value; - if (!treeAdapter.isElementNode(node)) return ''; - if (node.nodeName === 'br') return '\n'; - - if (node.childNodes) { - return node.childNodes.map(n => getText(n)).join(''); - } - - return ''; - } - - function appendChildren(childNodes: parse5.ChildNode[]): void { - if (childNodes) { - for (const n of childNodes) { - analyze(n); - } - } - } - - function analyze(node: parse5.Node) { - if (treeAdapter.isTextNode(node)) { - text += node.value; - return; - } - - // Skip comment or document type node - if (!treeAdapter.isElementNode(node)) return; - - switch (node.nodeName) { - case 'br': - text += '\n'; - break; - - case 'a': - { - const txt = getText(node); - const rel = node.attrs.find(x => x.name === 'rel'); - const href = node.attrs.find(x => x.name === 'href'); - - // ハッシュタグ - if (hashtagNames && href && hashtagNames.map(x => x.toLowerCase()).includes(txt.toLowerCase())) { - text += txt; - // メンション - } else if (txt.startsWith('@') && !(rel && rel.value.match(/^me /))) { - const part = txt.split('@'); - - if (part.length === 2 && href) { - //#region ホスト名部分が省略されているので復元する - const acct = `${txt}@${(new URL(href.value)).hostname}`; - text += acct; - //#endregion - } else if (part.length === 3) { - text += txt; - } - // その他 - } else { - const generateLink = () => { - if (!href && !txt) { - return ''; - } - if (!href) { - return txt; - } - if (!txt || txt === href.value) { // #6383: Missing text node - if (href.value.match(urlRegexFull)) { - return href.value; - } else { - return `<${href.value}>`; - } - } - if (href.value.match(urlRegex) && !href.value.match(urlRegexFull)) { - return `[${txt}](<${href.value}>)`; // #6846 - } else { - return `[${txt}](${href.value})`; - } - }; - - text += generateLink(); - } - break; - } - - case 'h1': - { - text += '【'; - appendChildren(node.childNodes); - text += '】\n'; - break; - } - - case 'b': - case 'strong': - { - text += '**'; - appendChildren(node.childNodes); - text += '**'; - break; - } - - case 'small': - { - text += ''; - appendChildren(node.childNodes); - text += ''; - break; - } - - case 's': - case 'del': - { - text += '~~'; - appendChildren(node.childNodes); - text += '~~'; - break; - } - - case 'i': - case 'em': - { - text += ''; - appendChildren(node.childNodes); - text += ''; - break; - } - - // block code (
)
-			case 'pre': {
-				if (node.childNodes.length === 1 && node.childNodes[0].nodeName === 'code') {
-					text += '```\n';
-					text += getText(node.childNodes[0]);
-					text += '\n```\n';
-				} else {
-					appendChildren(node.childNodes);
-				}
-				break;
-			}
-
-			// inline code ()
-			case 'code': {
-				text += '`';
-				appendChildren(node.childNodes);
-				text += '`';
-				break;
-			}
-
-			case 'blockquote': {
-				const t = getText(node);
-				if (t) {
-					text += '> ';
-					text += t.split('\n').join(`\n> `);
-				}
-				break;
-			}
-
-			case 'p':
-			case 'h2':
-			case 'h3':
-			case 'h4':
-			case 'h5':
-			case 'h6':
-			{
-				text += '\n\n';
-				appendChildren(node.childNodes);
-				break;
-			}
-
-			// other block elements
-			case 'div':
-			case 'header':
-			case 'footer':
-			case 'article':
-			case 'li':
-			case 'dt':
-			case 'dd':
-			{
-				text += '\n';
-				appendChildren(node.childNodes);
-				break;
-			}
-
-			default:	// includes inline elements
-			{
-				appendChildren(node.childNodes);
-				break;
-			}
-		}
-	}
-}
diff --git a/src/mfm/to-html.ts b/src/mfm/to-html.ts
deleted file mode 100644
index b3678a0dd..000000000
--- a/src/mfm/to-html.ts
+++ /dev/null
@@ -1,159 +0,0 @@
-import { JSDOM } from 'jsdom';
-import * as mfm from 'mfm-js';
-import config from '@/config/index';
-import { intersperse } from '@/prelude/array';
-import { IMentionedRemoteUsers } from '@/models/entities/note';
-import { wellKnownServices } from '../well-known-services';
-
-export function toHtml(nodes: mfm.MfmNode[] | null, mentionedRemoteUsers: IMentionedRemoteUsers = []) {
-	if (nodes == null) {
-		return null;
-	}
-
-	const { window } = new JSDOM('');
-
-	const doc = window.document;
-
-	function appendChildren(children: mfm.MfmNode[], targetElement: any): void {
-		if (children) {
-			for (const child of children.map(x => (handlers as any)[x.type](x))) targetElement.appendChild(child);
-		}
-	}
-
-	const handlers: { [K in mfm.MfmNode['type']]: (node: mfm.NodeType) => any } = {
-		bold(node) {
-			const el = doc.createElement('b');
-			appendChildren(node.children, el);
-			return el;
-		},
-
-		small(node) {
-			const el = doc.createElement('small');
-			appendChildren(node.children, el);
-			return el;
-		},
-
-		strike(node) {
-			const el = doc.createElement('del');
-			appendChildren(node.children, el);
-			return el;
-		},
-
-		italic(node) {
-			const el = doc.createElement('i');
-			appendChildren(node.children, el);
-			return el;
-		},
-
-		fn(node) {
-			const el = doc.createElement('i');
-			appendChildren(node.children, el);
-			return el;
-		},
-
-		blockCode(node) {
-			const pre = doc.createElement('pre');
-			const inner = doc.createElement('code');
-			inner.textContent = node.props.code;
-			pre.appendChild(inner);
-			return pre;
-		},
-
-		center(node) {
-			const el = doc.createElement('div');
-			appendChildren(node.children, el);
-			return el;
-		},
-
-		emojiCode(node) {
-			return doc.createTextNode(`\u200B:${node.props.name}:\u200B`);
-		},
-
-		unicodeEmoji(node) {
-			return doc.createTextNode(node.props.emoji);
-		},
-
-		hashtag(node) {
-			const a = doc.createElement('a');
-			a.href = `${config.url}/tags/${node.props.hashtag}`;
-			a.textContent = `#${node.props.hashtag}`;
-			a.setAttribute('rel', 'tag');
-			return a;
-		},
-
-		inlineCode(node) {
-			const el = doc.createElement('code');
-			el.textContent = node.props.code;
-			return el;
-		},
-
-		mathInline(node) {
-			const el = doc.createElement('code');
-			el.textContent = node.props.formula;
-			return el;
-		},
-
-		mathBlock(node) {
-			const el = doc.createElement('code');
-			el.textContent = node.props.formula;
-			return el;
-		},
-
-		link(node) {
-			const a = doc.createElement('a');
-			a.href = node.props.url;
-			appendChildren(node.children, a);
-			return a;
-		},
-
-		mention(node) {
-			const a = doc.createElement('a');
-			const { username, host, acct } = node.props;
-			const wellKnown = wellKnownServices.find(x => x[0] === host);
-			if (wellKnown) {
-				a.href = wellKnown[1](username);
-			} else {
-				const remoteUserInfo = mentionedRemoteUsers.find(remoteUser => remoteUser.username === username && remoteUser.host === host);
-				a.href = remoteUserInfo ? (remoteUserInfo.url ? remoteUserInfo.url : remoteUserInfo.uri) : `${config.url}/${acct}`;
-				a.className = 'u-url mention';
-			}
-			a.textContent = acct;
-			return a;
-		},
-
-		quote(node) {
-			const el = doc.createElement('blockquote');
-			appendChildren(node.children, el);
-			return el;
-		},
-
-		text(node) {
-			const el = doc.createElement('span');
-			const nodes = node.props.text.split(/\r\n|\r|\n/).map(x => doc.createTextNode(x));
-
-			for (const x of intersperse('br', nodes)) {
-				el.appendChild(x === 'br' ? doc.createElement('br') : x);
-			}
-
-			return el;
-		},
-
-		url(node) {
-			const a = doc.createElement('a');
-			a.href = node.props.url;
-			a.textContent = node.props.url;
-			return a;
-		},
-
-		search(node) {
-			const a = doc.createElement('a');
-			a.href = `https://www.google.com/search?q=${node.props.query}`;
-			a.textContent = node.props.content;
-			return a;
-		}
-	};
-
-	appendChildren(nodes, doc.body);
-
-	return `

${doc.body.innerHTML}

`; -} diff --git a/src/misc/acct.ts b/src/misc/acct.ts deleted file mode 100644 index 5106b1a09..000000000 --- a/src/misc/acct.ts +++ /dev/null @@ -1,11 +0,0 @@ -import * as Misskey from 'misskey-js'; - -export const getAcct = (user: Misskey.Acct) => { - return user.host == null ? user.username : `${user.username}@${user.host}`; -}; - -export const parseAcct = (acct: string): Misskey.Acct => { - if (acct.startsWith('@')) acct = acct.substr(1); - const split = acct.split('@', 2); - return { username: split[0], host: split[1] || null }; -}; diff --git a/src/misc/cafy-id.ts b/src/misc/cafy-id.ts deleted file mode 100644 index 39886611e..000000000 --- a/src/misc/cafy-id.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Context } from 'cafy'; - -export class ID extends Context { - public readonly name = 'ID'; - - constructor(optional = false, nullable = false) { - super(optional, nullable); - - this.push((v: any) => { - if (typeof v !== 'string') { - return new Error('must-be-an-id'); - } - return true; - }); - } - - public getType() { - return super.getType('String'); - } - - public makeOptional(): ID { - return new ID(true, false); - } - - public makeNullable(): ID { - return new ID(false, true); - } - - public makeOptionalNullable(): ID { - return new ID(true, true); - } -} diff --git a/src/misc/check-hit-antenna.ts b/src/misc/check-hit-antenna.ts deleted file mode 100644 index 3789054b2..000000000 --- a/src/misc/check-hit-antenna.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { Antenna } from '@/models/entities/antenna'; -import { Note } from '@/models/entities/note'; -import { User } from '@/models/entities/user'; -import { UserListJoinings, UserGroupJoinings } from '@/models/index'; -import { getFullApAccount } from './convert-host'; -import { parseAcct } from '@/misc/acct'; -import { Packed } from './schema'; - -/** - * noteUserFollowers / antennaUserFollowing はどちらか一方が指定されていればよい - */ -export async function checkHitAntenna(antenna: Antenna, note: (Note | Packed<'Note'>), noteUser: { username: string; host: string | null; }, noteUserFollowers?: User['id'][], antennaUserFollowing?: User['id'][]): Promise { - if (note.visibility === 'specified') return false; - - if (note.visibility === 'followers') { - if (noteUserFollowers && !noteUserFollowers.includes(antenna.userId)) return false; - if (antennaUserFollowing && !antennaUserFollowing.includes(note.userId)) return false; - } - - if (!antenna.withReplies && note.replyId != null) return false; - - if (antenna.src === 'home') { - if (noteUserFollowers && !noteUserFollowers.includes(antenna.userId)) return false; - if (antennaUserFollowing && !antennaUserFollowing.includes(note.userId)) return false; - } else if (antenna.src === 'list') { - const listUsers = (await UserListJoinings.find({ - userListId: antenna.userListId! - })).map(x => x.userId); - - if (!listUsers.includes(note.userId)) return false; - } else if (antenna.src === 'group') { - const joining = await UserGroupJoinings.findOneOrFail(antenna.userGroupJoiningId!); - - const groupUsers = (await UserGroupJoinings.find({ - userGroupId: joining.userGroupId - })).map(x => x.userId); - - if (!groupUsers.includes(note.userId)) return false; - } else if (antenna.src === 'users') { - const accts = antenna.users.map(x => { - const { username, host } = parseAcct(x); - return getFullApAccount(username, host).toLowerCase(); - }); - if (!accts.includes(getFullApAccount(noteUser.username, noteUser.host).toLowerCase())) return false; - } - - const keywords = antenna.keywords - // Clean up - .map(xs => xs.filter(x => x !== '')) - .filter(xs => xs.length > 0); - - if (keywords.length > 0) { - if (note.text == null) return false; - - const matched = keywords.some(and => - and.every(keyword => - antenna.caseSensitive - ? note.text!.includes(keyword) - : note.text!.toLowerCase().includes(keyword.toLowerCase()) - )); - - if (!matched) return false; - } - - const excludeKeywords = antenna.excludeKeywords - // Clean up - .map(xs => xs.filter(x => x !== '')) - .filter(xs => xs.length > 0); - - if (excludeKeywords.length > 0) { - if (note.text == null) return false; - - const matched = excludeKeywords.some(and => - and.every(keyword => - antenna.caseSensitive - ? note.text!.includes(keyword) - : note.text!.toLowerCase().includes(keyword.toLowerCase()) - )); - - if (matched) return false; - } - - if (antenna.withFile) { - if (note.fileIds && note.fileIds.length === 0) return false; - } - - // TODO: eval expression - - return true; -} diff --git a/src/misc/extract-url-from-mfm.ts b/src/misc/extract-url-from-mfm.ts deleted file mode 100644 index e6d5d0104..000000000 --- a/src/misc/extract-url-from-mfm.ts +++ /dev/null @@ -1,19 +0,0 @@ -import * as mfm from 'mfm-js'; -import { unique } from '@/prelude/array'; - -// unique without hash -// [ http://a/#1, http://a/#2, http://b/#3 ] => [ http://a/#1, http://b/#3 ] -const removeHash = (x: string) => x.replace(/#[^#]*$/, ''); - -export function extractUrlFromMfm(nodes: mfm.MfmNode[], respectSilentFlag = true): string[] { - const urlNodes = mfm.extract(nodes, (node) => { - return (node.type === 'url') || (node.type === 'link' && (!respectSilentFlag || !node.props.silent)); - }); - const urls: string[] = unique(urlNodes.map(x => x.props.url)); - - return urls.reduce((array, url) => { - const urlWithoutHash = removeHash(url); - if (!array.map(x => removeHash(x)).includes(urlWithoutHash)) array.push(url); - return array; - }, [] as string[]); -} diff --git a/src/misc/gen-avatar.ts b/src/misc/gen-avatar.ts deleted file mode 100644 index f03ca9f96..000000000 --- a/src/misc/gen-avatar.ts +++ /dev/null @@ -1,90 +0,0 @@ -/** - * Random avatar generator - */ - -import * as p from 'pureimage'; -import * as gen from 'random-seed'; -import { WriteStream } from 'fs'; - -const size = 256; // px -const n = 5; // resolution -const margin = (size / n); -const colors = [ - '#e57373', - '#F06292', - '#BA68C8', - '#9575CD', - '#7986CB', - '#64B5F6', - '#4FC3F7', - '#4DD0E1', - '#4DB6AC', - '#81C784', - '#8BC34A', - '#AFB42B', - '#F57F17', - '#FF5722', - '#795548', - '#455A64', -]; -const bg = '#e9e9e9'; - -const actualSize = size - (margin * 2); -const cellSize = actualSize / n; -const sideN = Math.floor(n / 2); - -/** - * Generate buffer of random avatar by seed - */ -export function genAvatar(seed: string, stream: WriteStream): Promise { - const rand = gen.create(seed); - const canvas = p.make(size, size); - const ctx = canvas.getContext('2d'); - - ctx.fillStyle = bg; - ctx.beginPath(); - ctx.fillRect(0, 0, size, size); - - ctx.fillStyle = colors[rand(colors.length)]; - - // side bitmap (filled by false) - const side: boolean[][] = new Array(sideN); - for (let i = 0; i < side.length; i++) { - side[i] = new Array(n).fill(false); - } - - // 1*n (filled by false) - const center: boolean[] = new Array(n).fill(false); - - // tslint:disable-next-line:prefer-for-of - for (let x = 0; x < side.length; x++) { - for (let y = 0; y < side[x].length; y++) { - side[x][y] = rand(3) === 0; - } - } - - for (let i = 0; i < center.length; i++) { - center[i] = rand(3) === 0; - } - - // Draw - for (let x = 0; x < n; x++) { - for (let y = 0; y < n; y++) { - const isXCenter = x === ((n - 1) / 2); - if (isXCenter && !center[y]) continue; - - const isLeftSide = x < ((n - 1) / 2); - if (isLeftSide && !side[x][y]) continue; - - const isRightSide = x > ((n - 1) / 2); - if (isRightSide && !side[sideN - (x - sideN)][y]) continue; - - const actualX = margin + (cellSize * x); - const actualY = margin + (cellSize * y); - ctx.beginPath(); - ctx.fillRect(actualX, actualY, cellSize, cellSize); - } - } - - return p.encodePNGToStream(canvas, stream); -} diff --git a/src/misc/get-note-summary.ts b/src/misc/get-note-summary.ts deleted file mode 100644 index a1866fb20..000000000 --- a/src/misc/get-note-summary.ts +++ /dev/null @@ -1,52 +0,0 @@ -/** - * 投稿を表す文字列を取得します。 - * @param {*} note (packされた)投稿 - */ -export const getNoteSummary = (note: any, locale: any): string => { - if (note.deletedAt) { - return `(${locale['deletedNote']})`; - } - - if (note.isHidden) { - return `(${locale['invisibleNote']})`; - } - - let summary = ''; - - // 本文 - if (note.cw != null) { - summary += note.cw; - } else { - summary += note.text ? note.text : ''; - } - - // ファイルが添付されているとき - if ((note.files || []).length != 0) { - summary += ` (${locale['withNFiles'].replace('{n}', note.files.length)})`; - } - - // 投票が添付されているとき - if (note.poll) { - summary += ` (${locale['poll']})`; - } - - // 返信のとき - if (note.replyId) { - if (note.reply) { - summary += `\n\nRE: ${getNoteSummary(note.reply, locale)}`; - } else { - summary += '\n\nRE: ...'; - } - } - - // Renoteのとき - if (note.renoteId) { - if (note.renote) { - summary += `\n\nRN: ${getNoteSummary(note.renote, locale)}`; - } else { - summary += '\n\nRN: ...'; - } - } - - return summary.trim(); -}; diff --git a/src/misc/get-user-name.ts b/src/misc/get-user-name.ts deleted file mode 100644 index 3545e986e..000000000 --- a/src/misc/get-user-name.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { User } from '@/models/entities/user'; - -export default function(user: User): string { - return user.name || user.username; -} diff --git a/src/misc/license.ts b/src/misc/license.ts deleted file mode 100644 index 8b12923ca..000000000 --- a/src/misc/license.ts +++ /dev/null @@ -1,19 +0,0 @@ -import * as fs from 'fs'; -import { fileURLToPath } from 'url'; -import { dirname } from 'path'; - -//const _filename = fileURLToPath(import.meta.url); -const _filename = __filename; -const _dirname = dirname(_filename); - -const license = fs.readFileSync(_dirname + '/../../LICENSE', 'utf-8'); - -const licenseHtml = license - .replace(/\r\n/g, '\n') - .replace(/(.)\n(.)/g, '$1 $2') - .replace(/(^|\n)(.*?)($|\n)/g, '

$2

'); - -export { - license, - licenseHtml -}; diff --git a/src/models/entities/note.ts b/src/models/entities/note.ts deleted file mode 100644 index 4a5411f93..000000000 --- a/src/models/entities/note.ts +++ /dev/null @@ -1,247 +0,0 @@ -import { Entity, Index, JoinColumn, Column, PrimaryColumn, ManyToOne } from 'typeorm'; -import { User } from './user'; -import { DriveFile } from './drive-file'; -import { id } from '../id'; -import { noteVisibilities } from '../../types'; -import { Channel } from './channel'; - -@Entity() -@Index('IDX_NOTE_TAGS', { synchronize: false }) -@Index('IDX_NOTE_MENTIONS', { synchronize: false }) -@Index('IDX_NOTE_VISIBLE_USER_IDS', { synchronize: false }) -export class Note { - @PrimaryColumn(id()) - public id: string; - - @Index() - @Column('timestamp with time zone', { - comment: 'The created date of the Note.' - }) - public createdAt: Date; - - @Index() - @Column({ - ...id(), - nullable: true, - comment: 'The ID of reply target.' - }) - public replyId: Note['id'] | null; - - @ManyToOne(type => Note, { - onDelete: 'CASCADE' - }) - @JoinColumn() - public reply: Note | null; - - @Index() - @Column({ - ...id(), - nullable: true, - comment: 'The ID of renote target.' - }) - public renoteId: Note['id'] | null; - - @ManyToOne(type => Note, { - onDelete: 'CASCADE' - }) - @JoinColumn() - public renote: Note | null; - - @Index() - @Column('varchar', { - length: 256, nullable: true - }) - public threadId: string | null; - - @Column('varchar', { - length: 8192, nullable: true - }) - public text: string | null; - - @Column('varchar', { - length: 256, nullable: true - }) - public name: string | null; - - @Column('varchar', { - length: 512, nullable: true - }) - public cw: string | null; - - @Index() - @Column({ - ...id(), - comment: 'The ID of author.' - }) - public userId: User['id']; - - @ManyToOne(type => User, { - onDelete: 'CASCADE' - }) - @JoinColumn() - public user: User | null; - - @Column('boolean', { - default: false - }) - public viaMobile: boolean; - - @Column('boolean', { - default: false - }) - public localOnly: boolean; - - @Column('smallint', { - default: 0 - }) - public renoteCount: number; - - @Column('smallint', { - default: 0 - }) - public repliesCount: number; - - @Column('jsonb', { - default: {} - }) - public reactions: Record; - - /** - * public ... 公開 - * home ... ホームタイムライン(ユーザーページのタイムライン含む)のみに流す - * followers ... フォロワーのみ - * specified ... visibleUserIds で指定したユーザーのみ - */ - @Column('enum', { enum: noteVisibilities }) - public visibility: typeof noteVisibilities[number]; - - @Index({ unique: true }) - @Column('varchar', { - length: 512, nullable: true, - comment: 'The URI of a note. it will be null when the note is local.' - }) - public uri: string | null; - - @Column('varchar', { - length: 512, nullable: true, - comment: 'The human readable url of a note. it will be null when the note is local.' - }) - public url: string | null; - - @Column('integer', { - default: 0, select: false - }) - public score: number; - - @Index() - @Column({ - ...id(), - array: true, default: '{}' - }) - public fileIds: DriveFile['id'][]; - - @Index() - @Column('varchar', { - length: 256, array: true, default: '{}' - }) - public attachedFileTypes: string[]; - - @Index() - @Column({ - ...id(), - array: true, default: '{}' - }) - public visibleUserIds: User['id'][]; - - @Index() - @Column({ - ...id(), - array: true, default: '{}' - }) - public mentions: User['id'][]; - - @Column('text', { - default: '[]' - }) - public mentionedRemoteUsers: string; - - @Column('varchar', { - length: 128, array: true, default: '{}' - }) - public emojis: string[]; - - @Index() - @Column('varchar', { - length: 128, array: true, default: '{}' - }) - public tags: string[]; - - @Column('boolean', { - default: false - }) - public hasPoll: boolean; - - @Index() - @Column({ - ...id(), - nullable: true, default: null, - comment: 'The ID of source channel.' - }) - public channelId: Channel['id'] | null; - - @ManyToOne(type => Channel, { - onDelete: 'CASCADE' - }) - @JoinColumn() - public channel: Channel | null; - - //#region Denormalized fields - @Index() - @Column('varchar', { - length: 128, nullable: true, - comment: '[Denormalized]' - }) - public userHost: string | null; - - @Column({ - ...id(), - nullable: true, - comment: '[Denormalized]' - }) - public replyUserId: User['id'] | null; - - @Column('varchar', { - length: 128, nullable: true, - comment: '[Denormalized]' - }) - public replyUserHost: string | null; - - @Column({ - ...id(), - nullable: true, - comment: '[Denormalized]' - }) - public renoteUserId: User['id'] | null; - - @Column('varchar', { - length: 128, nullable: true, - comment: '[Denormalized]' - }) - public renoteUserHost: string | null; - //#endregion - - constructor(data: Partial) { - if (data == null) return; - - for (const [k, v] of Object.entries(data)) { - (this as any)[k] = v; - } - } -} - -export type IMentionedRemoteUsers = { - uri: string; - url?: string; - username: string; - host: string; -}[]; diff --git a/src/models/entities/user-profile.ts b/src/models/entities/user-profile.ts deleted file mode 100644 index 1f450f223..000000000 --- a/src/models/entities/user-profile.ts +++ /dev/null @@ -1,209 +0,0 @@ -import { Entity, Column, Index, OneToOne, JoinColumn, PrimaryColumn } from 'typeorm'; -import { id } from '../id'; -import { User } from './user'; -import { Page } from './page'; -import { notificationTypes } from '@/types'; - -// TODO: このテーブルで管理している情報すべてレジストリで管理するようにしても良いかも -// ただ、「emailVerified が true なユーザーを find する」のようなクエリは書けなくなるからウーン -@Entity() -export class UserProfile { - @PrimaryColumn(id()) - public userId: User['id']; - - @OneToOne(type => User, { - onDelete: 'CASCADE' - }) - @JoinColumn() - public user: User | null; - - @Column('varchar', { - length: 128, nullable: true, - comment: 'The location of the User.' - }) - public location: string | null; - - @Column('char', { - length: 10, nullable: true, - comment: 'The birthday (YYYY-MM-DD) of the User.' - }) - public birthday: string | null; - - @Column('varchar', { - length: 2048, nullable: true, - comment: 'The description (bio) of the User.' - }) - public description: string | null; - - @Column('jsonb', { - default: [], - }) - public fields: { - name: string; - value: string; - }[]; - - @Column('varchar', { - length: 32, nullable: true, - }) - public lang: string | null; - - @Column('varchar', { - length: 512, nullable: true, - comment: 'Remote URL of the user.' - }) - public url: string | null; - - @Column('varchar', { - length: 128, nullable: true, - comment: 'The email address of the User.' - }) - public email: string | null; - - @Column('varchar', { - length: 128, nullable: true, - }) - public emailVerifyCode: string | null; - - @Column('boolean', { - default: false, - }) - public emailVerified: boolean; - - @Column('jsonb', { - default: ['follow', 'receiveFollowRequest', 'groupInvited'] - }) - public emailNotificationTypes: string[]; - - @Column('boolean', { - default: false, - }) - public publicReactions: boolean; - - @Column('varchar', { - length: 128, nullable: true, - }) - public twoFactorTempSecret: string | null; - - @Column('varchar', { - length: 128, nullable: true, - }) - public twoFactorSecret: string | null; - - @Column('boolean', { - default: false, - }) - public twoFactorEnabled: boolean; - - @Column('boolean', { - default: false, - }) - public securityKeysAvailable: boolean; - - @Column('boolean', { - default: false, - }) - public usePasswordLessLogin: boolean; - - @Column('varchar', { - length: 128, nullable: true, - comment: 'The password hash of the User. It will be null if the origin of the user is local.' - }) - public password: string | null; - - // TODO: そのうち消す - @Column('jsonb', { - default: {}, - comment: 'The client-specific data of the User.' - }) - public clientData: Record; - - @Column('jsonb', { - default: {}, - comment: 'The room data of the User.' - }) - public room: Record; - - @Column('boolean', { - default: false, - }) - public autoAcceptFollowed: boolean; - - @Column('boolean', { - default: false, - comment: 'Whether reject index by crawler.' - }) - public noCrawle: boolean; - - @Column('boolean', { - default: false, - }) - public alwaysMarkNsfw: boolean; - - @Column('boolean', { - default: false, - }) - public carefulBot: boolean; - - @Column('boolean', { - default: true, - }) - public injectFeaturedNote: boolean; - - @Column('boolean', { - default: true, - }) - public receiveAnnouncementEmail: boolean; - - @Column({ - ...id(), - nullable: true - }) - public pinnedPageId: Page['id'] | null; - - @OneToOne(type => Page, { - onDelete: 'SET NULL' - }) - @JoinColumn() - public pinnedPage: Page | null; - - @Column('jsonb', { - default: {} - }) - public integrations: Record; - - @Index() - @Column('boolean', { - default: false, select: false, - }) - public enableWordMute: boolean; - - @Column('jsonb', { - default: [] - }) - public mutedWords: string[][]; - - @Column('enum', { - enum: notificationTypes, - array: true, - default: [], - }) - public mutingNotificationTypes: typeof notificationTypes[number][]; - - //#region Denormalized fields - @Index() - @Column('varchar', { - length: 128, nullable: true, - comment: '[Denormalized]' - }) - public userHost: string | null; - //#endregion - - constructor(data: Partial) { - if (data == null) return; - - for (const [k, v] of Object.entries(data)) { - (this as any)[k] = v; - } - } -} diff --git a/src/models/repositories/note.ts b/src/models/repositories/note.ts deleted file mode 100644 index 0f00c34c9..000000000 --- a/src/models/repositories/note.ts +++ /dev/null @@ -1,512 +0,0 @@ -import { EntityRepository, Repository, In } from 'typeorm'; -import * as mfm from 'mfm-js'; -import { Note } from '@/models/entities/note'; -import { User } from '@/models/entities/user'; -import { Users, PollVotes, DriveFiles, NoteReactions, Followings, Polls, Channels } from '../index'; -import { Packed } from '@/misc/schema'; -import { nyaize } from '@/misc/nyaize'; -import { awaitAll } from '@/prelude/await-all'; -import { convertLegacyReaction, convertLegacyReactions, decodeReaction } from '@/misc/reaction-lib'; -import { NoteReaction } from '@/models/entities/note-reaction'; -import { aggregateNoteEmojis, populateEmojis, prefetchEmojis } from '@/misc/populate-emojis'; - -@EntityRepository(Note) -export class NoteRepository extends Repository { - public validateCw(x: string) { - return x.trim().length <= 100; - } - - public async isVisibleForMe(note: Note, meId: User['id'] | null): Promise { - // visibility が specified かつ自分が指定されていなかったら非表示 - if (note.visibility === 'specified') { - if (meId == null) { - return false; - } else if (meId === note.userId) { - return true; - } else { - // 指定されているかどうか - const specified = note.visibleUserIds.some((id: any) => meId === id); - - if (specified) { - return true; - } else { - return false; - } - } - } - - // visibility が followers かつ自分が投稿者のフォロワーでなかったら非表示 - if (note.visibility === 'followers') { - if (meId == null) { - return false; - } else if (meId === note.userId) { - return true; - } else if (note.reply && (meId === note.reply.userId)) { - // 自分の投稿に対するリプライ - return true; - } else if (note.mentions && note.mentions.some(id => meId === id)) { - // 自分へのメンション - return true; - } else { - // フォロワーかどうか - const following = await Followings.findOne({ - followeeId: note.userId, - followerId: meId - }); - - if (following == null) { - return false; - } else { - return true; - } - } - } - - return true; - } - - private async hideNote(packedNote: Packed<'Note'>, meId: User['id'] | null) { - // TODO: isVisibleForMe を使うようにしても良さそう(型違うけど) - let hide = false; - - // visibility が specified かつ自分が指定されていなかったら非表示 - if (packedNote.visibility === 'specified') { - if (meId == null) { - hide = true; - } else if (meId === packedNote.userId) { - hide = false; - } else { - // 指定されているかどうか - const specified = packedNote.visibleUserIds!.some((id: any) => meId === id); - - if (specified) { - hide = false; - } else { - hide = true; - } - } - } - - // visibility が followers かつ自分が投稿者のフォロワーでなかったら非表示 - if (packedNote.visibility === 'followers') { - if (meId == null) { - hide = true; - } else if (meId === packedNote.userId) { - hide = false; - } else if (packedNote.reply && (meId === packedNote.reply.userId)) { - // 自分の投稿に対するリプライ - hide = false; - } else if (packedNote.mentions && packedNote.mentions.some(id => meId === id)) { - // 自分へのメンション - hide = false; - } else { - // フォロワーかどうか - const following = await Followings.findOne({ - followeeId: packedNote.userId, - followerId: meId - }); - - if (following == null) { - hide = true; - } else { - hide = false; - } - } - } - - if (hide) { - packedNote.visibleUserIds = undefined; - packedNote.fileIds = []; - packedNote.files = []; - packedNote.text = null; - packedNote.poll = undefined; - packedNote.cw = null; - packedNote.isHidden = true; - } - } - - public async pack( - src: Note['id'] | Note, - me?: { id: User['id'] } | null | undefined, - options?: { - detail?: boolean; - skipHide?: boolean; - _hint_?: { - myReactions: Map; - }; - } - ): Promise> { - const opts = Object.assign({ - detail: true, - skipHide: false - }, options); - - const meId = me ? me.id : null; - const note = typeof src === 'object' ? src : await this.findOneOrFail(src); - const host = note.userHost; - - async function populatePoll() { - const poll = await Polls.findOneOrFail(note.id); - const choices = poll.choices.map(c => ({ - text: c, - votes: poll.votes[poll.choices.indexOf(c)], - isVoted: false - })); - - if (poll.multiple) { - const votes = await PollVotes.find({ - userId: meId!, - noteId: note.id - }); - - const myChoices = votes.map(v => v.choice); - for (const myChoice of myChoices) { - choices[myChoice].isVoted = true; - } - } else { - const vote = await PollVotes.findOne({ - userId: meId!, - noteId: note.id - }); - - if (vote) { - choices[vote.choice].isVoted = true; - } - } - - return { - multiple: poll.multiple, - expiresAt: poll.expiresAt, - choices - }; - } - - async function populateMyReaction() { - if (options?._hint_?.myReactions) { - const reaction = options._hint_.myReactions.get(note.id); - if (reaction) { - return convertLegacyReaction(reaction.reaction); - } else if (reaction === null) { - return undefined; - } - // 実装上抜けがあるだけかもしれないので、「ヒントに含まれてなかったら(=undefinedなら)return」のようにはしない - } - - const reaction = await NoteReactions.findOne({ - userId: meId!, - noteId: note.id, - }); - - if (reaction) { - return convertLegacyReaction(reaction.reaction); - } - - return undefined; - } - - let text = note.text; - - if (note.name && (note.url || note.uri)) { - text = `【${note.name}】\n${(note.text || '').trim()}\n\n${note.url || note.uri}`; - } - - const channel = note.channelId - ? note.channel - ? note.channel - : await Channels.findOne(note.channelId) - : null; - - const reactionEmojiNames = Object.keys(note.reactions).filter(x => x?.startsWith(':')).map(x => decodeReaction(x).reaction).map(x => x.replace(/:/g, '')); - - const packed = await awaitAll({ - id: note.id, - createdAt: note.createdAt.toISOString(), - userId: note.userId, - user: Users.pack(note.user || note.userId, me, { - detail: false, - }), - text: text, - cw: note.cw, - visibility: note.visibility, - localOnly: note.localOnly || undefined, - visibleUserIds: note.visibility === 'specified' ? note.visibleUserIds : undefined, - viaMobile: note.viaMobile || undefined, - renoteCount: note.renoteCount, - repliesCount: note.repliesCount, - reactions: convertLegacyReactions(note.reactions), - tags: note.tags.length > 0 ? note.tags : undefined, - emojis: populateEmojis(note.emojis.concat(reactionEmojiNames), host), - fileIds: note.fileIds, - files: DriveFiles.packMany(note.fileIds), - replyId: note.replyId, - renoteId: note.renoteId, - channelId: note.channelId || undefined, - channel: channel ? { - id: channel.id, - name: channel.name, - } : undefined, - mentions: note.mentions.length > 0 ? note.mentions : undefined, - uri: note.uri || undefined, - url: note.url || undefined, - - ...(opts.detail ? { - reply: note.replyId ? this.pack(note.reply || note.replyId, me, { - detail: false, - _hint_: options?._hint_ - }) : undefined, - - renote: note.renoteId ? this.pack(note.renote || note.renoteId, me, { - detail: true, - _hint_: options?._hint_ - }) : undefined, - - poll: note.hasPoll ? populatePoll() : undefined, - - ...(meId ? { - myReaction: populateMyReaction() - } : {}) - } : {}) - }); - - if (packed.user.isCat && packed.text) { - const tokens = packed.text ? mfm.parse(packed.text) : []; - mfm.inspect(tokens, node => { - if (node.type === 'text') { - // TODO: quoteなtextはskip - node.props.text = nyaize(node.props.text); - } - }); - packed.text = mfm.toString(tokens); - } - - if (!opts.skipHide) { - await this.hideNote(packed, meId); - } - - return packed; - } - - public async packMany( - notes: Note[], - me?: { id: User['id'] } | null | undefined, - options?: { - detail?: boolean; - skipHide?: boolean; - } - ) { - if (notes.length === 0) return []; - - const meId = me ? me.id : null; - const myReactionsMap = new Map(); - if (meId) { - const renoteIds = notes.filter(n => n.renoteId != null).map(n => n.renoteId!); - const targets = [...notes.map(n => n.id), ...renoteIds]; - const myReactions = await NoteReactions.find({ - userId: meId, - noteId: In(targets), - }); - - for (const target of targets) { - myReactionsMap.set(target, myReactions.find(reaction => reaction.noteId === target) || null); - } - } - - await prefetchEmojis(aggregateNoteEmojis(notes)); - - return await Promise.all(notes.map(n => this.pack(n, me, { - ...options, - _hint_: { - myReactions: myReactionsMap - } - }))); - } -} - -export const packedNoteSchema = { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - id: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'id', - example: 'xxxxxxxxxx', - }, - createdAt: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'date-time', - }, - text: { - type: 'string' as const, - optional: false as const, nullable: true as const, - }, - cw: { - type: 'string' as const, - optional: true as const, nullable: true as const, - }, - userId: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'id', - }, - user: { - type: 'object' as const, - ref: 'User' as const, - optional: false as const, nullable: false as const, - }, - replyId: { - type: 'string' as const, - optional: true as const, nullable: true as const, - format: 'id', - example: 'xxxxxxxxxx', - }, - renoteId: { - type: 'string' as const, - optional: true as const, nullable: true as const, - format: 'id', - example: 'xxxxxxxxxx', - }, - reply: { - type: 'object' as const, - optional: true as const, nullable: true as const, - ref: 'Note' as const, - }, - renote: { - type: 'object' as const, - optional: true as const, nullable: true as const, - ref: 'Note' as const, - }, - viaMobile: { - type: 'boolean' as const, - optional: true as const, nullable: false as const, - }, - isHidden: { - type: 'boolean' as const, - optional: true as const, nullable: false as const, - }, - visibility: { - type: 'string' as const, - optional: false as const, nullable: false as const, - }, - mentions: { - type: 'array' as const, - optional: true as const, nullable: false as const, - items: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'id' - } - }, - visibleUserIds: { - type: 'array' as const, - optional: true as const, nullable: false as const, - items: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'id' - } - }, - fileIds: { - type: 'array' as const, - optional: true as const, nullable: false as const, - items: { - type: 'string' as const, - optional: false as const, nullable: false as const, - format: 'id' - } - }, - files: { - type: 'array' as const, - optional: true as const, nullable: false as const, - items: { - type: 'object' as const, - optional: false as const, nullable: false as const, - ref: 'DriveFile' as const, - } - }, - tags: { - type: 'array' as const, - optional: true as const, nullable: false as const, - items: { - type: 'string' as const, - optional: false as const, nullable: false as const, - } - }, - poll: { - type: 'object' as const, - optional: true as const, nullable: true as const, - }, - channelId: { - type: 'string' as const, - optional: true as const, nullable: true as const, - format: 'id', - example: 'xxxxxxxxxx', - }, - channel: { - type: 'object' as const, - optional: true as const, nullable: true as const, - items: { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - id: { - type: 'string' as const, - optional: false as const, nullable: false as const, - }, - name: { - type: 'string' as const, - optional: false as const, nullable: true as const, - }, - }, - }, - }, - localOnly: { - type: 'boolean' as const, - optional: true as const, nullable: false as const, - }, - emojis: { - type: 'array' as const, - optional: false as const, nullable: false as const, - items: { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - name: { - type: 'string' as const, - optional: false as const, nullable: false as const, - }, - url: { - type: 'string' as const, - optional: false as const, nullable: true as const, - }, - }, - }, - }, - reactions: { - type: 'object' as const, - optional: false as const, nullable: false as const, - }, - renoteCount: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - repliesCount: { - type: 'number' as const, - optional: false as const, nullable: false as const, - }, - uri: { - type: 'string' as const, - optional: true as const, nullable: false as const, - }, - url: { - type: 'string' as const, - optional: true as const, nullable: false as const, - }, - - myReaction: { - type: 'object' as const, - optional: true as const, nullable: true as const, - }, - }, -}; diff --git a/src/models/repositories/user.ts b/src/models/repositories/user.ts deleted file mode 100644 index 9598e8719..000000000 --- a/src/models/repositories/user.ts +++ /dev/null @@ -1,648 +0,0 @@ -import $ from 'cafy'; -import { EntityRepository, Repository, In, Not } from 'typeorm'; -import { User, ILocalUser, IRemoteUser } from '@/models/entities/user'; -import { Notes, NoteUnreads, FollowRequests, Notifications, MessagingMessages, UserNotePinings, Followings, Blockings, Mutings, UserProfiles, UserSecurityKeys, UserGroupJoinings, Pages, Announcements, AnnouncementReads, Antennas, AntennaNotes, ChannelFollowings, Instances } from '../index'; -import config from '@/config/index'; -import { Packed } from '@/misc/schema'; -import { awaitAll } from '@/prelude/await-all'; -import { populateEmojis } from '@/misc/populate-emojis'; -import { getAntennas } from '@/misc/antenna-cache'; -import { USER_ACTIVE_THRESHOLD, USER_ONLINE_THRESHOLD } from '@/const'; - -@EntityRepository(User) -export class UserRepository extends Repository { - public async getRelation(me: User['id'], target: User['id']) { - const [following1, following2, followReq1, followReq2, toBlocking, fromBlocked, mute] = await Promise.all([ - Followings.findOne({ - followerId: me, - followeeId: target - }), - Followings.findOne({ - followerId: target, - followeeId: me - }), - FollowRequests.findOne({ - followerId: me, - followeeId: target - }), - FollowRequests.findOne({ - followerId: target, - followeeId: me - }), - Blockings.findOne({ - blockerId: me, - blockeeId: target - }), - Blockings.findOne({ - blockerId: target, - blockeeId: me - }), - Mutings.findOne({ - muterId: me, - muteeId: target - }) - ]); - - return { - id: target, - isFollowing: following1 != null, - hasPendingFollowRequestFromYou: followReq1 != null, - hasPendingFollowRequestToYou: followReq2 != null, - isFollowed: following2 != null, - isBlocking: toBlocking != null, - isBlocked: fromBlocked != null, - isMuted: mute != null - }; - } - - public async getHasUnreadMessagingMessage(userId: User['id']): Promise { - const mute = await Mutings.find({ - muterId: userId - }); - - const joinings = await UserGroupJoinings.find({ userId: userId }); - - const groupQs = Promise.all(joinings.map(j => MessagingMessages.createQueryBuilder('message') - .where(`message.groupId = :groupId`, { groupId: j.userGroupId }) - .andWhere('message.userId != :userId', { userId: userId }) - .andWhere('NOT (:userId = ANY(message.reads))', { userId: userId }) - .andWhere('message.createdAt > :joinedAt', { joinedAt: j.createdAt }) // 自分が加入する前の会話については、未読扱いしない - .getOne().then(x => x != null))); - - const [withUser, withGroups] = await Promise.all([ - MessagingMessages.count({ - where: { - recipientId: userId, - isRead: false, - ...(mute.length > 0 ? { userId: Not(In(mute.map(x => x.muteeId))) } : {}), - }, - take: 1 - }).then(count => count > 0), - groupQs - ]); - - return withUser || withGroups.some(x => x); - } - - public async getHasUnreadAnnouncement(userId: User['id']): Promise { - const reads = await AnnouncementReads.find({ - userId: userId - }); - - const count = await Announcements.count(reads.length > 0 ? { - id: Not(In(reads.map(read => read.announcementId))) - } : {}); - - return count > 0; - } - - public async getHasUnreadAntenna(userId: User['id']): Promise { - const myAntennas = (await getAntennas()).filter(a => a.userId === userId); - - const unread = myAntennas.length > 0 ? await AntennaNotes.findOne({ - antennaId: In(myAntennas.map(x => x.id)), - read: false - }) : null; - - return unread != null; - } - - public async getHasUnreadChannel(userId: User['id']): Promise { - const channels = await ChannelFollowings.find({ followerId: userId }); - - const unread = channels.length > 0 ? await NoteUnreads.findOne({ - userId: userId, - noteChannelId: In(channels.map(x => x.followeeId)), - }) : null; - - return unread != null; - } - - public async getHasUnreadNotification(userId: User['id']): Promise { - const mute = await Mutings.find({ - muterId: userId - }); - const mutedUserIds = mute.map(m => m.muteeId); - - const count = await Notifications.count({ - where: { - notifieeId: userId, - ...(mutedUserIds.length > 0 ? { notifierId: Not(In(mutedUserIds)) } : {}), - isRead: false - }, - take: 1 - }); - - return count > 0; - } - - public async getHasPendingReceivedFollowRequest(userId: User['id']): Promise { - const count = await FollowRequests.count({ - followeeId: userId - }); - - return count > 0; - } - - public getOnlineStatus(user: User): string { - if (user.hideOnlineStatus) return 'unknown'; - if (user.lastActiveDate == null) return 'unknown'; - const elapsed = Date.now() - user.lastActiveDate.getTime(); - return ( - elapsed < USER_ONLINE_THRESHOLD ? 'online' : - elapsed < USER_ACTIVE_THRESHOLD ? 'active' : - 'offline' - ); - } - - public getAvatarUrl(user: User): string { - if (user.avatarUrl) { - return user.avatarUrl; - } else { - return `${config.url}/random-avatar/${user.id}`; - } - } - - public async pack( - src: User['id'] | User, - me?: { id: User['id'] } | null | undefined, - options?: { - detail?: boolean, - includeSecrets?: boolean, - } - ): Promise> { - const opts = Object.assign({ - detail: false, - includeSecrets: false - }, options); - - const user = typeof src === 'object' ? src : await this.findOneOrFail(src); - const meId = me ? me.id : null; - - const relation = meId && (meId !== user.id) && opts.detail ? await this.getRelation(meId, user.id) : null; - const pins = opts.detail ? await UserNotePinings.createQueryBuilder('pin') - .where('pin.userId = :userId', { userId: user.id }) - .innerJoinAndSelect('pin.note', 'note') - .orderBy('pin.id', 'DESC') - .getMany() : []; - const profile = opts.detail ? await UserProfiles.findOneOrFail(user.id) : null; - - const falsy = opts.detail ? false : undefined; - - const packed = { - id: user.id, - name: user.name, - username: user.username, - host: user.host, - avatarUrl: this.getAvatarUrl(user), - avatarBlurhash: user.avatarBlurhash, - avatarColor: null, // 後方互換性のため - isAdmin: user.isAdmin || falsy, - isModerator: user.isModerator || falsy, - isBot: user.isBot || falsy, - isCat: user.isCat || falsy, - instance: user.host ? Instances.findOne({ host: user.host }).then(instance => instance ? { - name: instance.name, - softwareName: instance.softwareName, - softwareVersion: instance.softwareVersion, - iconUrl: instance.iconUrl, - faviconUrl: instance.faviconUrl, - themeColor: instance.themeColor, - } : undefined) : undefined, - emojis: populateEmojis(user.emojis, user.host), - onlineStatus: this.getOnlineStatus(user), - - ...(opts.detail ? { - url: profile!.url, - uri: user.uri, - createdAt: user.createdAt.toISOString(), - updatedAt: user.updatedAt ? user.updatedAt.toISOString() : null, - lastFetchedAt: user.lastFetchedAt?.toISOString(), - bannerUrl: user.bannerUrl, - bannerBlurhash: user.bannerBlurhash, - bannerColor: null, // 後方互換性のため - isLocked: user.isLocked, - isModerator: user.isModerator || falsy, - isSilenced: user.isSilenced || falsy, - isSuspended: user.isSuspended || falsy, - description: profile!.description, - location: profile!.location, - birthday: profile!.birthday, - lang: profile!.lang, - fields: profile!.fields, - followersCount: user.followersCount, - followingCount: user.followingCount, - notesCount: user.notesCount, - pinnedNoteIds: pins.map(pin => pin.noteId), - pinnedNotes: Notes.packMany(pins.map(pin => pin.note!), me, { - detail: true - }), - pinnedPageId: profile!.pinnedPageId, - pinnedPage: profile!.pinnedPageId ? Pages.pack(profile!.pinnedPageId, me) : null, - publicReactions: profile!.publicReactions, - twoFactorEnabled: profile!.twoFactorEnabled, - usePasswordLessLogin: profile!.usePasswordLessLogin, - securityKeys: profile!.twoFactorEnabled - ? UserSecurityKeys.count({ - userId: user.id - }).then(result => result >= 1) - : false, - } : {}), - - ...(opts.detail && meId === user.id ? { - avatarId: user.avatarId, - bannerId: user.bannerId, - injectFeaturedNote: profile!.injectFeaturedNote, - receiveAnnouncementEmail: profile!.receiveAnnouncementEmail, - alwaysMarkNsfw: profile!.alwaysMarkNsfw, - carefulBot: profile!.carefulBot, - autoAcceptFollowed: profile!.autoAcceptFollowed, - noCrawle: profile!.noCrawle, - isExplorable: user.isExplorable, - isDeleted: user.isDeleted, - hideOnlineStatus: user.hideOnlineStatus, - hasUnreadSpecifiedNotes: NoteUnreads.count({ - where: { userId: user.id, isSpecified: true }, - take: 1 - }).then(count => count > 0), - hasUnreadMentions: NoteUnreads.count({ - where: { userId: user.id, isMentioned: true }, - take: 1 - }).then(count => count > 0), - hasUnreadAnnouncement: this.getHasUnreadAnnouncement(user.id), - hasUnreadAntenna: this.getHasUnreadAntenna(user.id), - hasUnreadChannel: this.getHasUnreadChannel(user.id), - hasUnreadMessagingMessage: this.getHasUnreadMessagingMessage(user.id), - hasUnreadNotification: this.getHasUnreadNotification(user.id), - hasPendingReceivedFollowRequest: this.getHasPendingReceivedFollowRequest(user.id), - integrations: profile!.integrations, - mutedWords: profile!.mutedWords, - mutingNotificationTypes: profile!.mutingNotificationTypes, - emailNotificationTypes: profile!.emailNotificationTypes, - } : {}), - - ...(opts.includeSecrets ? { - email: profile!.email, - emailVerified: profile!.emailVerified, - securityKeysList: profile!.twoFactorEnabled - ? UserSecurityKeys.find({ - where: { - userId: user.id - }, - select: ['id', 'name', 'lastUsed'] - }) - : [] - } : {}), - - ...(relation ? { - isFollowing: relation.isFollowing, - isFollowed: relation.isFollowed, - hasPendingFollowRequestFromYou: relation.hasPendingFollowRequestFromYou, - hasPendingFollowRequestToYou: relation.hasPendingFollowRequestToYou, - isBlocking: relation.isBlocking, - isBlocked: relation.isBlocked, - isMuted: relation.isMuted, - } : {}) - }; - - return await awaitAll(packed); - } - - public packMany( - users: (User['id'] | User)[], - me?: { id: User['id'] } | null | undefined, - options?: { - detail?: boolean, - includeSecrets?: boolean, - } - ) { - return Promise.all(users.map(u => this.pack(u, me, options))); - } - - public isLocalUser(user: User): user is ILocalUser; - public isLocalUser(user: T): user is T & { host: null; }; - public isLocalUser(user: User | { host: User['host'] }): boolean { - return user.host == null; - } - - public isRemoteUser(user: User): user is IRemoteUser; - public isRemoteUser(user: T): user is T & { host: string; }; - public isRemoteUser(user: User | { host: User['host'] }): boolean { - return !this.isLocalUser(user); - } - - //#region Validators - public validateLocalUsername = $.str.match(/^\w{1,20}$/); - public validatePassword = $.str.min(1); - public validateName = $.str.min(1).max(50); - public validateDescription = $.str.min(1).max(500); - public validateLocation = $.str.min(1).max(50); - public validateBirthday = $.str.match(/^([0-9]{4})-([0-9]{2})-([0-9]{2})$/); - //#endregion -} - -export const packedUserSchema = { - type: 'object' as const, - nullable: false as const, optional: false as const, - properties: { - id: { - type: 'string' as const, - nullable: false as const, optional: false as const, - format: 'id', - example: 'xxxxxxxxxx', - }, - name: { - type: 'string' as const, - nullable: true as const, optional: false as const, - example: '藍' - }, - username: { - type: 'string' as const, - nullable: false as const, optional: false as const, - example: 'ai' - }, - host: { - type: 'string' as const, - nullable: true as const, optional: false as const, - example: 'misskey.example.com' - }, - avatarUrl: { - type: 'string' as const, - format: 'url', - nullable: true as const, optional: false as const, - }, - avatarBlurhash: { - type: 'any' as const, - nullable: true as const, optional: false as const, - }, - avatarColor: { - type: 'any' as const, - nullable: true as const, optional: false as const, - default: null - }, - isAdmin: { - type: 'boolean' as const, - nullable: false as const, optional: true as const, - default: false - }, - isModerator: { - type: 'boolean' as const, - nullable: false as const, optional: true as const, - default: false - }, - isBot: { - type: 'boolean' as const, - nullable: false as const, optional: true as const, - }, - isCat: { - type: 'boolean' as const, - nullable: false as const, optional: true as const, - }, - emojis: { - type: 'array' as const, - nullable: false as const, optional: false as const, - items: { - type: 'object' as const, - nullable: false as const, optional: false as const, - properties: { - name: { - type: 'string' as const, - nullable: false as const, optional: false as const - }, - url: { - type: 'string' as const, - nullable: false as const, optional: false as const, - format: 'url' - }, - } - } - }, - url: { - type: 'string' as const, - format: 'url', - nullable: true as const, optional: true as const, - }, - createdAt: { - type: 'string' as const, - nullable: false as const, optional: true as const, - format: 'date-time', - }, - updatedAt: { - type: 'string' as const, - nullable: true as const, optional: true as const, - format: 'date-time', - }, - bannerUrl: { - type: 'string' as const, - format: 'url', - nullable: true as const, optional: true as const, - }, - bannerBlurhash: { - type: 'any' as const, - nullable: true as const, optional: true as const, - }, - bannerColor: { - type: 'any' as const, - nullable: true as const, optional: true as const, - default: null - }, - isLocked: { - type: 'boolean' as const, - nullable: false as const, optional: true as const, - }, - isSuspended: { - type: 'boolean' as const, - nullable: false as const, optional: true as const, - example: false - }, - description: { - type: 'string' as const, - nullable: true as const, optional: true as const, - example: 'Hi masters, I am Ai!' - }, - location: { - type: 'string' as const, - nullable: true as const, optional: true as const, - }, - birthday: { - type: 'string' as const, - nullable: true as const, optional: true as const, - example: '2018-03-12' - }, - fields: { - type: 'array' as const, - nullable: false as const, optional: true as const, - items: { - type: 'object' as const, - nullable: false as const, optional: false as const, - properties: { - name: { - type: 'string' as const, - nullable: false as const, optional: false as const - }, - value: { - type: 'string' as const, - nullable: false as const, optional: false as const - } - }, - maxLength: 4 - } - }, - followersCount: { - type: 'number' as const, - nullable: false as const, optional: true as const, - }, - followingCount: { - type: 'number' as const, - nullable: false as const, optional: true as const, - }, - notesCount: { - type: 'number' as const, - nullable: false as const, optional: true as const, - }, - pinnedNoteIds: { - type: 'array' as const, - nullable: false as const, optional: true as const, - items: { - type: 'string' as const, - nullable: false as const, optional: false as const, - format: 'id', - } - }, - pinnedNotes: { - type: 'array' as const, - nullable: false as const, optional: true as const, - items: { - type: 'object' as const, - nullable: false as const, optional: false as const, - ref: 'Note' as const, - } - }, - pinnedPageId: { - type: 'string' as const, - nullable: true as const, optional: true as const - }, - pinnedPage: { - type: 'object' as const, - nullable: true as const, optional: true as const, - ref: 'Page' as const, - }, - twoFactorEnabled: { - type: 'boolean' as const, - nullable: false as const, optional: true as const, - default: false - }, - usePasswordLessLogin: { - type: 'boolean' as const, - nullable: false as const, optional: true as const, - default: false - }, - securityKeys: { - type: 'boolean' as const, - nullable: false as const, optional: true as const, - default: false - }, - avatarId: { - type: 'string' as const, - nullable: true as const, optional: true as const, - format: 'id' - }, - bannerId: { - type: 'string' as const, - nullable: true as const, optional: true as const, - format: 'id' - }, - autoWatch: { - type: 'boolean' as const, - nullable: false as const, optional: true as const - }, - injectFeaturedNote: { - type: 'boolean' as const, - nullable: false as const, optional: true as const - }, - alwaysMarkNsfw: { - type: 'boolean' as const, - nullable: false as const, optional: true as const - }, - carefulBot: { - type: 'boolean' as const, - nullable: false as const, optional: true as const - }, - autoAcceptFollowed: { - type: 'boolean' as const, - nullable: false as const, optional: true as const - }, - hasUnreadSpecifiedNotes: { - type: 'boolean' as const, - nullable: false as const, optional: true as const, - }, - hasUnreadMentions: { - type: 'boolean' as const, - nullable: false as const, optional: true as const, - }, - hasUnreadAnnouncement: { - type: 'boolean' as const, - nullable: false as const, optional: true as const, - }, - hasUnreadAntenna: { - type: 'boolean' as const, - nullable: false as const, optional: true as const, - }, - hasUnreadChannel: { - type: 'boolean' as const, - nullable: false as const, optional: true as const, - }, - hasUnreadMessagingMessage: { - type: 'boolean' as const, - nullable: false as const, optional: true as const, - }, - hasUnreadNotification: { - type: 'boolean' as const, - nullable: false as const, optional: true as const, - }, - hasPendingReceivedFollowRequest: { - type: 'boolean' as const, - nullable: false as const, optional: true as const, - }, - integrations: { - type: 'object' as const, - nullable: false as const, optional: true as const - }, - mutedWords: { - type: 'array' as const, - nullable: false as const, optional: true as const - }, - mutingNotificationTypes: { - type: 'array' as const, - nullable: false as const, optional: true as const - }, - isFollowing: { - type: 'boolean' as const, - optional: true as const, nullable: false as const - }, - hasPendingFollowRequestFromYou: { - type: 'boolean' as const, - optional: true as const, nullable: false as const - }, - hasPendingFollowRequestToYou: { - type: 'boolean' as const, - optional: true as const, nullable: false as const - }, - isFollowed: { - type: 'boolean' as const, - optional: true as const, nullable: false as const - }, - isBlocking: { - type: 'boolean' as const, - optional: true as const, nullable: false as const - }, - isBlocked: { - type: 'boolean' as const, - optional: true as const, nullable: false as const - }, - isMuted: { - type: 'boolean' as const, - optional: true as const, nullable: false as const - } - }, -}; diff --git a/src/queue/processors/db/export-notes.ts b/src/queue/processors/db/export-notes.ts deleted file mode 100644 index 49850aa70..000000000 --- a/src/queue/processors/db/export-notes.ts +++ /dev/null @@ -1,133 +0,0 @@ -import * as Bull from 'bull'; -import * as tmp from 'tmp'; -import * as fs from 'fs'; - -import { queueLogger } from '../../logger'; -import addFile from '@/services/drive/add-file'; -import * as dateFormat from 'dateformat'; -import { Users, Notes, Polls } from '@/models/index'; -import { MoreThan } from 'typeorm'; -import { Note } from '@/models/entities/note'; -import { Poll } from '@/models/entities/poll'; -import { DbUserJobData } from '@/queue/types'; - -const logger = queueLogger.createSubLogger('export-notes'); - -export async function exportNotes(job: Bull.Job, done: any): Promise { - logger.info(`Exporting notes of ${job.data.user.id} ...`); - - const user = await Users.findOne(job.data.user.id); - if (user == null) { - done(); - return; - } - - // Create temp file - const [path, cleanup] = await new Promise<[string, any]>((res, rej) => { - tmp.file((e, path, fd, cleanup) => { - if (e) return rej(e); - res([path, cleanup]); - }); - }); - - logger.info(`Temp file is ${path}`); - - const stream = fs.createWriteStream(path, { flags: 'a' }); - - await new Promise((res, rej) => { - stream.write('[', err => { - if (err) { - logger.error(err); - rej(err); - } else { - res(); - } - }); - }); - - let exportedNotesCount = 0; - let cursor: any = null; - - while (true) { - const notes = await Notes.find({ - where: { - userId: user.id, - ...(cursor ? { id: MoreThan(cursor) } : {}) - }, - take: 100, - order: { - id: 1 - } - }); - - if (notes.length === 0) { - job.progress(100); - break; - } - - cursor = notes[notes.length - 1].id; - - for (const note of notes) { - let poll: Poll | undefined; - if (note.hasPoll) { - poll = await Polls.findOneOrFail({ noteId: note.id }); - } - const content = JSON.stringify(serialize(note, poll)); - await new Promise((res, rej) => { - stream.write(exportedNotesCount === 0 ? content : ',\n' + content, err => { - if (err) { - logger.error(err); - rej(err); - } else { - res(); - } - }); - }); - exportedNotesCount++; - } - - const total = await Notes.count({ - userId: user.id, - }); - - job.progress(exportedNotesCount / total); - } - - await new Promise((res, rej) => { - stream.write(']', err => { - if (err) { - logger.error(err); - rej(err); - } else { - res(); - } - }); - }); - - stream.end(); - logger.succ(`Exported to: ${path}`); - - const fileName = 'notes-' + dateFormat(new Date(), 'yyyy-mm-dd-HH-MM-ss') + '.json'; - const driveFile = await addFile(user, path, fileName, null, null, true); - - logger.succ(`Exported to: ${driveFile.id}`); - cleanup(); - done(); -} - -function serialize(note: Note, poll: Poll | null = null): any { - return { - id: note.id, - text: note.text, - createdAt: note.createdAt, - fileIds: note.fileIds, - replyId: note.replyId, - renoteId: note.renoteId, - poll: poll, - cw: note.cw, - viaMobile: note.viaMobile, - visibility: note.visibility, - visibleUserIds: note.visibleUserIds, - localOnly: note.localOnly - }; -} diff --git a/src/queue/processors/db/import-blocking.ts b/src/queue/processors/db/import-blocking.ts deleted file mode 100644 index 9951da669..000000000 --- a/src/queue/processors/db/import-blocking.ts +++ /dev/null @@ -1,74 +0,0 @@ -import * as Bull from 'bull'; - -import { queueLogger } from '../../logger'; -import { parseAcct } from '@/misc/acct'; -import { resolveUser } from '@/remote/resolve-user'; -import { downloadTextFile } from '@/misc/download-text-file'; -import { isSelfHost, toPuny } from '@/misc/convert-host'; -import { Users, DriveFiles, Blockings } from '@/models/index'; -import { DbUserImportJobData } from '@/queue/types'; -import block from '@/services/blocking/create'; - -const logger = queueLogger.createSubLogger('import-blocking'); - -export async function importBlocking(job: Bull.Job, done: any): Promise { - logger.info(`Importing blocking of ${job.data.user.id} ...`); - - const user = await Users.findOne(job.data.user.id); - if (user == null) { - done(); - return; - } - - const file = await DriveFiles.findOne({ - id: job.data.fileId - }); - if (file == null) { - done(); - return; - } - - const csv = await downloadTextFile(file.url); - - let linenum = 0; - - for (const line of csv.trim().split('\n')) { - linenum++; - - try { - const acct = line.split(',')[0].trim(); - const { username, host } = parseAcct(acct); - - let target = isSelfHost(host!) ? await Users.findOne({ - host: null, - usernameLower: username.toLowerCase() - }) : await Users.findOne({ - host: toPuny(host!), - usernameLower: username.toLowerCase() - }); - - if (host == null && target == null) continue; - - if (target == null) { - target = await resolveUser(username, host); - } - - if (target == null) { - throw `cannot resolve user: @${username}@${host}`; - } - - // skip myself - if (target.id === job.data.user.id) continue; - - logger.info(`Block[${linenum}] ${target.id} ...`); - - await block(user, target); - } catch (e) { - logger.warn(`Error in line:${linenum} ${e}`); - } - } - - logger.succ('Imported'); - done(); -} - diff --git a/src/queue/processors/db/import-following.ts b/src/queue/processors/db/import-following.ts deleted file mode 100644 index 3d7b7ea40..000000000 --- a/src/queue/processors/db/import-following.ts +++ /dev/null @@ -1,73 +0,0 @@ -import * as Bull from 'bull'; - -import { queueLogger } from '../../logger'; -import follow from '@/services/following/create'; -import { parseAcct } from '@/misc/acct'; -import { resolveUser } from '@/remote/resolve-user'; -import { downloadTextFile } from '@/misc/download-text-file'; -import { isSelfHost, toPuny } from '@/misc/convert-host'; -import { Users, DriveFiles } from '@/models/index'; -import { DbUserImportJobData } from '@/queue/types'; - -const logger = queueLogger.createSubLogger('import-following'); - -export async function importFollowing(job: Bull.Job, done: any): Promise { - logger.info(`Importing following of ${job.data.user.id} ...`); - - const user = await Users.findOne(job.data.user.id); - if (user == null) { - done(); - return; - } - - const file = await DriveFiles.findOne({ - id: job.data.fileId - }); - if (file == null) { - done(); - return; - } - - const csv = await downloadTextFile(file.url); - - let linenum = 0; - - for (const line of csv.trim().split('\n')) { - linenum++; - - try { - const acct = line.split(',')[0].trim(); - const { username, host } = parseAcct(acct); - - let target = isSelfHost(host!) ? await Users.findOne({ - host: null, - usernameLower: username.toLowerCase() - }) : await Users.findOne({ - host: toPuny(host!), - usernameLower: username.toLowerCase() - }); - - if (host == null && target == null) continue; - - if (target == null) { - target = await resolveUser(username, host); - } - - if (target == null) { - throw `cannot resolve user: @${username}@${host}`; - } - - // skip myself - if (target.id === job.data.user.id) continue; - - logger.info(`Follow[${linenum}] ${target.id} ...`); - - follow(user, target); - } catch (e) { - logger.warn(`Error in line:${linenum} ${e}`); - } - } - - logger.succ('Imported'); - done(); -} diff --git a/src/queue/processors/db/import-muting.ts b/src/queue/processors/db/import-muting.ts deleted file mode 100644 index 798f03a62..000000000 --- a/src/queue/processors/db/import-muting.ts +++ /dev/null @@ -1,83 +0,0 @@ -import * as Bull from 'bull'; - -import { queueLogger } from '../../logger'; -import { parseAcct } from '@/misc/acct'; -import { resolveUser } from '@/remote/resolve-user'; -import { downloadTextFile } from '@/misc/download-text-file'; -import { isSelfHost, toPuny } from '@/misc/convert-host'; -import { Users, DriveFiles, Mutings } from '@/models/index'; -import { DbUserImportJobData } from '@/queue/types'; -import { User } from '@/models/entities/user'; -import { genId } from '@/misc/gen-id'; - -const logger = queueLogger.createSubLogger('import-muting'); - -export async function importMuting(job: Bull.Job, done: any): Promise { - logger.info(`Importing muting of ${job.data.user.id} ...`); - - const user = await Users.findOne(job.data.user.id); - if (user == null) { - done(); - return; - } - - const file = await DriveFiles.findOne({ - id: job.data.fileId - }); - if (file == null) { - done(); - return; - } - - const csv = await downloadTextFile(file.url); - - let linenum = 0; - - for (const line of csv.trim().split('\n')) { - linenum++; - - try { - const acct = line.split(',')[0].trim(); - const { username, host } = parseAcct(acct); - - let target = isSelfHost(host!) ? await Users.findOne({ - host: null, - usernameLower: username.toLowerCase() - }) : await Users.findOne({ - host: toPuny(host!), - usernameLower: username.toLowerCase() - }); - - if (host == null && target == null) continue; - - if (target == null) { - target = await resolveUser(username, host); - } - - if (target == null) { - throw `cannot resolve user: @${username}@${host}`; - } - - // skip myself - if (target.id === job.data.user.id) continue; - - logger.info(`Mute[${linenum}] ${target.id} ...`); - - await mute(user, target); - } catch (e) { - logger.warn(`Error in line:${linenum} ${e}`); - } - } - - logger.succ('Imported'); - done(); -} - -async function mute(user: User, target: User) { - await Mutings.insert({ - id: genId(), - createdAt: new Date(), - muterId: user.id, - muteeId: target.id, - }); -} diff --git a/src/queue/processors/db/import-user-lists.ts b/src/queue/processors/db/import-user-lists.ts deleted file mode 100644 index 3b8c13262..000000000 --- a/src/queue/processors/db/import-user-lists.ts +++ /dev/null @@ -1,80 +0,0 @@ -import * as Bull from 'bull'; - -import { queueLogger } from '../../logger'; -import { parseAcct } from '@/misc/acct'; -import { resolveUser } from '@/remote/resolve-user'; -import { pushUserToUserList } from '@/services/user-list/push'; -import { downloadTextFile } from '@/misc/download-text-file'; -import { isSelfHost, toPuny } from '@/misc/convert-host'; -import { DriveFiles, Users, UserLists, UserListJoinings } from '@/models/index'; -import { genId } from '@/misc/gen-id'; -import { DbUserImportJobData } from '@/queue/types'; - -const logger = queueLogger.createSubLogger('import-user-lists'); - -export async function importUserLists(job: Bull.Job, done: any): Promise { - logger.info(`Importing user lists of ${job.data.user.id} ...`); - - const user = await Users.findOne(job.data.user.id); - if (user == null) { - done(); - return; - } - - const file = await DriveFiles.findOne({ - id: job.data.fileId - }); - if (file == null) { - done(); - return; - } - - const csv = await downloadTextFile(file.url); - - let linenum = 0; - - for (const line of csv.trim().split('\n')) { - linenum++; - - try { - const listName = line.split(',')[0].trim(); - const { username, host } = parseAcct(line.split(',')[1].trim()); - - let list = await UserLists.findOne({ - userId: user.id, - name: listName - }); - - if (list == null) { - list = await UserLists.save({ - id: genId(), - createdAt: new Date(), - userId: user.id, - name: listName, - userIds: [] - }); - } - - let target = isSelfHost(host!) ? await Users.findOne({ - host: null, - usernameLower: username.toLowerCase() - }) : await Users.findOne({ - host: toPuny(host!), - usernameLower: username.toLowerCase() - }); - - if (target == null) { - target = await resolveUser(username, host); - } - - if (await UserListJoinings.findOne({ userListId: list.id, userId: target.id }) != null) continue; - - pushUserToUserList(target, list); - } catch (e) { - logger.warn(`Error in line:${linenum} ${e}`); - } - } - - logger.succ('Imported'); - done(); -} diff --git a/src/queue/processors/object-storage/clean-remote-files.ts b/src/queue/processors/object-storage/clean-remote-files.ts deleted file mode 100644 index 3b2e4ea93..000000000 --- a/src/queue/processors/object-storage/clean-remote-files.ts +++ /dev/null @@ -1,50 +0,0 @@ -import * as Bull from 'bull'; - -import { queueLogger } from '../../logger'; -import { deleteFileSync } from '@/services/drive/delete-file'; -import { DriveFiles } from '@/models/index'; -import { MoreThan, Not, IsNull } from 'typeorm'; - -const logger = queueLogger.createSubLogger('clean-remote-files'); - -export default async function cleanRemoteFiles(job: Bull.Job<{}>, done: any): Promise { - logger.info(`Deleting cached remote files...`); - - let deletedCount = 0; - let cursor: any = null; - - while (true) { - const files = await DriveFiles.find({ - where: { - userHost: Not(IsNull()), - isLink: false, - ...(cursor ? { id: MoreThan(cursor) } : {}) - }, - take: 8, - order: { - id: 1 - } - }); - - if (files.length === 0) { - job.progress(100); - break; - } - - cursor = files[files.length - 1].id; - - await Promise.all(files.map(file => deleteFileSync(file, true))); - - deletedCount += 8; - - const total = await DriveFiles.count({ - userHost: Not(IsNull()), - isLink: false, - }); - - job.progress(deletedCount / total); - } - - logger.succ(`All cahced remote files has been deleted.`); - done(); -} diff --git a/src/queue/processors/system/index.ts b/src/queue/processors/system/index.ts deleted file mode 100644 index 52b786810..000000000 --- a/src/queue/processors/system/index.ts +++ /dev/null @@ -1,12 +0,0 @@ -import * as Bull from 'bull'; -import { resyncCharts } from './resync-charts'; - -const jobs = { - resyncCharts, -} as Record | Bull.ProcessPromiseFunction<{}>>; - -export default function(dbQueue: Bull.Queue<{}>) { - for (const [k, v] of Object.entries(jobs)) { - dbQueue.process(k, v); - } -} diff --git a/src/queue/processors/system/resync-charts.ts b/src/queue/processors/system/resync-charts.ts deleted file mode 100644 index b36b024cf..000000000 --- a/src/queue/processors/system/resync-charts.ts +++ /dev/null @@ -1,21 +0,0 @@ -import * as Bull from 'bull'; - -import { queueLogger } from '../../logger'; -import { driveChart, notesChart, usersChart } from '@/services/chart/index'; - -const logger = queueLogger.createSubLogger('resync-charts'); - -export default async function resyncCharts(job: Bull.Job<{}>, done: any): Promise { - logger.info(`Resync charts...`); - - // TODO: ユーザーごとのチャートも更新する - // TODO: インスタンスごとのチャートも更新する - await Promise.all([ - driveChart.resync(), - notesChart.resync(), - usersChart.resync(), - ]); - - logger.succ(`All charts successfully resynced.`); - done(); -} diff --git a/src/queue/queues.ts b/src/queue/queues.ts deleted file mode 100644 index a66a7ca45..000000000 --- a/src/queue/queues.ts +++ /dev/null @@ -1,9 +0,0 @@ -import config from '@/config/index'; -import { initialize as initializeQueue } from './initialize'; -import { DeliverJobData, InboxJobData, DbJobData, ObjectStorageJobData } from './types'; - -export const systemQueue = initializeQueue<{}>('system'); -export const deliverQueue = initializeQueue('deliver', config.deliverJobPerSec || 128); -export const inboxQueue = initializeQueue('inbox', config.inboxJobPerSec || 16); -export const dbQueue = initializeQueue('db'); -export const objectStorageQueue = initializeQueue('objectStorage'); diff --git a/src/queue/types.ts b/src/queue/types.ts deleted file mode 100644 index 39cab2996..000000000 --- a/src/queue/types.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { DriveFile } from '@/models/entities/drive-file'; -import { User } from '@/models/entities/user'; -import { IActivity } from '@/remote/activitypub/type'; -import * as httpSignature from 'http-signature'; - -export type DeliverJobData = { - /** Actor */ - user: ThinUser; - /** Activity */ - content: unknown; - /** inbox URL to deliver */ - to: string; -}; - -export type InboxJobData = { - activity: IActivity; - signature: httpSignature.IParsedSignature; -}; - -export type DbJobData = DbUserJobData | DbUserImportJobData | DbUserDeleteJobData; - -export type DbUserJobData = { - user: ThinUser; -}; - -export type DbUserDeleteJobData = { - user: ThinUser; - soft?: boolean; -}; - -export type DbUserImportJobData = { - user: ThinUser; - fileId: DriveFile['id']; -}; - -export type ObjectStorageJobData = ObjectStorageFileJobData | {}; - -export type ObjectStorageFileJobData = { - key: string; -}; - -export type ThinUser = { - id: User['id']; -}; diff --git a/src/remote/activitypub/misc/contexts.ts b/src/remote/activitypub/misc/contexts.ts deleted file mode 100644 index 1426ba15f..000000000 --- a/src/remote/activitypub/misc/contexts.ts +++ /dev/null @@ -1,526 +0,0 @@ -/* tslint:disable:quotemark indent */ -const id_v1 = { - "@context": { - "id": "@id", - "type": "@type", - - "cred": "https://w3id.org/credentials#", - "dc": "http://purl.org/dc/terms/", - "identity": "https://w3id.org/identity#", - "perm": "https://w3id.org/permissions#", - "ps": "https://w3id.org/payswarm#", - "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#", - "rdfs": "http://www.w3.org/2000/01/rdf-schema#", - "sec": "https://w3id.org/security#", - "schema": "http://schema.org/", - "xsd": "http://www.w3.org/2001/XMLSchema#", - - "Group": "https://www.w3.org/ns/activitystreams#Group", - - "claim": {"@id": "cred:claim", "@type": "@id"}, - "credential": {"@id": "cred:credential", "@type": "@id"}, - "issued": {"@id": "cred:issued", "@type": "xsd:dateTime"}, - "issuer": {"@id": "cred:issuer", "@type": "@id"}, - "recipient": {"@id": "cred:recipient", "@type": "@id"}, - "Credential": "cred:Credential", - "CryptographicKeyCredential": "cred:CryptographicKeyCredential", - - "about": {"@id": "schema:about", "@type": "@id"}, - "address": {"@id": "schema:address", "@type": "@id"}, - "addressCountry": "schema:addressCountry", - "addressLocality": "schema:addressLocality", - "addressRegion": "schema:addressRegion", - "comment": "rdfs:comment", - "created": {"@id": "dc:created", "@type": "xsd:dateTime"}, - "creator": {"@id": "dc:creator", "@type": "@id"}, - "description": "schema:description", - "email": "schema:email", - "familyName": "schema:familyName", - "givenName": "schema:givenName", - "image": {"@id": "schema:image", "@type": "@id"}, - "label": "rdfs:label", - "name": "schema:name", - "postalCode": "schema:postalCode", - "streetAddress": "schema:streetAddress", - "title": "dc:title", - "url": {"@id": "schema:url", "@type": "@id"}, - "Person": "schema:Person", - "PostalAddress": "schema:PostalAddress", - "Organization": "schema:Organization", - - "identityService": {"@id": "identity:identityService", "@type": "@id"}, - "idp": {"@id": "identity:idp", "@type": "@id"}, - "Identity": "identity:Identity", - - "paymentProcessor": "ps:processor", - "preferences": {"@id": "ps:preferences", "@type": "@vocab"}, - - "cipherAlgorithm": "sec:cipherAlgorithm", - "cipherData": "sec:cipherData", - "cipherKey": "sec:cipherKey", - "digestAlgorithm": "sec:digestAlgorithm", - "digestValue": "sec:digestValue", - "domain": "sec:domain", - "expires": {"@id": "sec:expiration", "@type": "xsd:dateTime"}, - "initializationVector": "sec:initializationVector", - "member": {"@id": "schema:member", "@type": "@id"}, - "memberOf": {"@id": "schema:memberOf", "@type": "@id"}, - "nonce": "sec:nonce", - "normalizationAlgorithm": "sec:normalizationAlgorithm", - "owner": {"@id": "sec:owner", "@type": "@id"}, - "password": "sec:password", - "privateKey": {"@id": "sec:privateKey", "@type": "@id"}, - "privateKeyPem": "sec:privateKeyPem", - "publicKey": {"@id": "sec:publicKey", "@type": "@id"}, - "publicKeyPem": "sec:publicKeyPem", - "publicKeyService": {"@id": "sec:publicKeyService", "@type": "@id"}, - "revoked": {"@id": "sec:revoked", "@type": "xsd:dateTime"}, - "signature": "sec:signature", - "signatureAlgorithm": "sec:signatureAlgorithm", - "signatureValue": "sec:signatureValue", - "CryptographicKey": "sec:Key", - "EncryptedMessage": "sec:EncryptedMessage", - "GraphSignature2012": "sec:GraphSignature2012", - "LinkedDataSignature2015": "sec:LinkedDataSignature2015", - - "accessControl": {"@id": "perm:accessControl", "@type": "@id"}, - "writePermission": {"@id": "perm:writePermission", "@type": "@id"} - } -}; - -const security_v1 = { - "@context": { - "id": "@id", - "type": "@type", - - "dc": "http://purl.org/dc/terms/", - "sec": "https://w3id.org/security#", - "xsd": "http://www.w3.org/2001/XMLSchema#", - - "EcdsaKoblitzSignature2016": "sec:EcdsaKoblitzSignature2016", - "Ed25519Signature2018": "sec:Ed25519Signature2018", - "EncryptedMessage": "sec:EncryptedMessage", - "GraphSignature2012": "sec:GraphSignature2012", - "LinkedDataSignature2015": "sec:LinkedDataSignature2015", - "LinkedDataSignature2016": "sec:LinkedDataSignature2016", - "CryptographicKey": "sec:Key", - - "authenticationTag": "sec:authenticationTag", - "canonicalizationAlgorithm": "sec:canonicalizationAlgorithm", - "cipherAlgorithm": "sec:cipherAlgorithm", - "cipherData": "sec:cipherData", - "cipherKey": "sec:cipherKey", - "created": {"@id": "dc:created", "@type": "xsd:dateTime"}, - "creator": {"@id": "dc:creator", "@type": "@id"}, - "digestAlgorithm": "sec:digestAlgorithm", - "digestValue": "sec:digestValue", - "domain": "sec:domain", - "encryptionKey": "sec:encryptionKey", - "expiration": {"@id": "sec:expiration", "@type": "xsd:dateTime"}, - "expires": {"@id": "sec:expiration", "@type": "xsd:dateTime"}, - "initializationVector": "sec:initializationVector", - "iterationCount": "sec:iterationCount", - "nonce": "sec:nonce", - "normalizationAlgorithm": "sec:normalizationAlgorithm", - "owner": {"@id": "sec:owner", "@type": "@id"}, - "password": "sec:password", - "privateKey": {"@id": "sec:privateKey", "@type": "@id"}, - "privateKeyPem": "sec:privateKeyPem", - "publicKey": {"@id": "sec:publicKey", "@type": "@id"}, - "publicKeyBase58": "sec:publicKeyBase58", - "publicKeyPem": "sec:publicKeyPem", - "publicKeyWif": "sec:publicKeyWif", - "publicKeyService": {"@id": "sec:publicKeyService", "@type": "@id"}, - "revoked": {"@id": "sec:revoked", "@type": "xsd:dateTime"}, - "salt": "sec:salt", - "signature": "sec:signature", - "signatureAlgorithm": "sec:signingAlgorithm", - "signatureValue": "sec:signatureValue" - } -}; - -const activitystreams = { - "@context": { - "@vocab": "_:", - "xsd": "http://www.w3.org/2001/XMLSchema#", - "as": "https://www.w3.org/ns/activitystreams#", - "ldp": "http://www.w3.org/ns/ldp#", - "vcard": "http://www.w3.org/2006/vcard/ns#", - "id": "@id", - "type": "@type", - "Accept": "as:Accept", - "Activity": "as:Activity", - "IntransitiveActivity": "as:IntransitiveActivity", - "Add": "as:Add", - "Announce": "as:Announce", - "Application": "as:Application", - "Arrive": "as:Arrive", - "Article": "as:Article", - "Audio": "as:Audio", - "Block": "as:Block", - "Collection": "as:Collection", - "CollectionPage": "as:CollectionPage", - "Relationship": "as:Relationship", - "Create": "as:Create", - "Delete": "as:Delete", - "Dislike": "as:Dislike", - "Document": "as:Document", - "Event": "as:Event", - "Follow": "as:Follow", - "Flag": "as:Flag", - "Group": "as:Group", - "Ignore": "as:Ignore", - "Image": "as:Image", - "Invite": "as:Invite", - "Join": "as:Join", - "Leave": "as:Leave", - "Like": "as:Like", - "Link": "as:Link", - "Mention": "as:Mention", - "Note": "as:Note", - "Object": "as:Object", - "Offer": "as:Offer", - "OrderedCollection": "as:OrderedCollection", - "OrderedCollectionPage": "as:OrderedCollectionPage", - "Organization": "as:Organization", - "Page": "as:Page", - "Person": "as:Person", - "Place": "as:Place", - "Profile": "as:Profile", - "Question": "as:Question", - "Reject": "as:Reject", - "Remove": "as:Remove", - "Service": "as:Service", - "TentativeAccept": "as:TentativeAccept", - "TentativeReject": "as:TentativeReject", - "Tombstone": "as:Tombstone", - "Undo": "as:Undo", - "Update": "as:Update", - "Video": "as:Video", - "View": "as:View", - "Listen": "as:Listen", - "Read": "as:Read", - "Move": "as:Move", - "Travel": "as:Travel", - "IsFollowing": "as:IsFollowing", - "IsFollowedBy": "as:IsFollowedBy", - "IsContact": "as:IsContact", - "IsMember": "as:IsMember", - "subject": { - "@id": "as:subject", - "@type": "@id" - }, - "relationship": { - "@id": "as:relationship", - "@type": "@id" - }, - "actor": { - "@id": "as:actor", - "@type": "@id" - }, - "attributedTo": { - "@id": "as:attributedTo", - "@type": "@id" - }, - "attachment": { - "@id": "as:attachment", - "@type": "@id" - }, - "bcc": { - "@id": "as:bcc", - "@type": "@id" - }, - "bto": { - "@id": "as:bto", - "@type": "@id" - }, - "cc": { - "@id": "as:cc", - "@type": "@id" - }, - "context": { - "@id": "as:context", - "@type": "@id" - }, - "current": { - "@id": "as:current", - "@type": "@id" - }, - "first": { - "@id": "as:first", - "@type": "@id" - }, - "generator": { - "@id": "as:generator", - "@type": "@id" - }, - "icon": { - "@id": "as:icon", - "@type": "@id" - }, - "image": { - "@id": "as:image", - "@type": "@id" - }, - "inReplyTo": { - "@id": "as:inReplyTo", - "@type": "@id" - }, - "items": { - "@id": "as:items", - "@type": "@id" - }, - "instrument": { - "@id": "as:instrument", - "@type": "@id" - }, - "orderedItems": { - "@id": "as:items", - "@type": "@id", - "@container": "@list" - }, - "last": { - "@id": "as:last", - "@type": "@id" - }, - "location": { - "@id": "as:location", - "@type": "@id" - }, - "next": { - "@id": "as:next", - "@type": "@id" - }, - "object": { - "@id": "as:object", - "@type": "@id" - }, - "oneOf": { - "@id": "as:oneOf", - "@type": "@id" - }, - "anyOf": { - "@id": "as:anyOf", - "@type": "@id" - }, - "closed": { - "@id": "as:closed", - "@type": "xsd:dateTime" - }, - "origin": { - "@id": "as:origin", - "@type": "@id" - }, - "accuracy": { - "@id": "as:accuracy", - "@type": "xsd:float" - }, - "prev": { - "@id": "as:prev", - "@type": "@id" - }, - "preview": { - "@id": "as:preview", - "@type": "@id" - }, - "replies": { - "@id": "as:replies", - "@type": "@id" - }, - "result": { - "@id": "as:result", - "@type": "@id" - }, - "audience": { - "@id": "as:audience", - "@type": "@id" - }, - "partOf": { - "@id": "as:partOf", - "@type": "@id" - }, - "tag": { - "@id": "as:tag", - "@type": "@id" - }, - "target": { - "@id": "as:target", - "@type": "@id" - }, - "to": { - "@id": "as:to", - "@type": "@id" - }, - "url": { - "@id": "as:url", - "@type": "@id" - }, - "altitude": { - "@id": "as:altitude", - "@type": "xsd:float" - }, - "content": "as:content", - "contentMap": { - "@id": "as:content", - "@container": "@language" - }, - "name": "as:name", - "nameMap": { - "@id": "as:name", - "@container": "@language" - }, - "duration": { - "@id": "as:duration", - "@type": "xsd:duration" - }, - "endTime": { - "@id": "as:endTime", - "@type": "xsd:dateTime" - }, - "height": { - "@id": "as:height", - "@type": "xsd:nonNegativeInteger" - }, - "href": { - "@id": "as:href", - "@type": "@id" - }, - "hreflang": "as:hreflang", - "latitude": { - "@id": "as:latitude", - "@type": "xsd:float" - }, - "longitude": { - "@id": "as:longitude", - "@type": "xsd:float" - }, - "mediaType": "as:mediaType", - "published": { - "@id": "as:published", - "@type": "xsd:dateTime" - }, - "radius": { - "@id": "as:radius", - "@type": "xsd:float" - }, - "rel": "as:rel", - "startIndex": { - "@id": "as:startIndex", - "@type": "xsd:nonNegativeInteger" - }, - "startTime": { - "@id": "as:startTime", - "@type": "xsd:dateTime" - }, - "summary": "as:summary", - "summaryMap": { - "@id": "as:summary", - "@container": "@language" - }, - "totalItems": { - "@id": "as:totalItems", - "@type": "xsd:nonNegativeInteger" - }, - "units": "as:units", - "updated": { - "@id": "as:updated", - "@type": "xsd:dateTime" - }, - "width": { - "@id": "as:width", - "@type": "xsd:nonNegativeInteger" - }, - "describes": { - "@id": "as:describes", - "@type": "@id" - }, - "formerType": { - "@id": "as:formerType", - "@type": "@id" - }, - "deleted": { - "@id": "as:deleted", - "@type": "xsd:dateTime" - }, - "inbox": { - "@id": "ldp:inbox", - "@type": "@id" - }, - "outbox": { - "@id": "as:outbox", - "@type": "@id" - }, - "following": { - "@id": "as:following", - "@type": "@id" - }, - "followers": { - "@id": "as:followers", - "@type": "@id" - }, - "streams": { - "@id": "as:streams", - "@type": "@id" - }, - "preferredUsername": "as:preferredUsername", - "endpoints": { - "@id": "as:endpoints", - "@type": "@id" - }, - "uploadMedia": { - "@id": "as:uploadMedia", - "@type": "@id" - }, - "proxyUrl": { - "@id": "as:proxyUrl", - "@type": "@id" - }, - "liked": { - "@id": "as:liked", - "@type": "@id" - }, - "oauthAuthorizationEndpoint": { - "@id": "as:oauthAuthorizationEndpoint", - "@type": "@id" - }, - "oauthTokenEndpoint": { - "@id": "as:oauthTokenEndpoint", - "@type": "@id" - }, - "provideClientKey": { - "@id": "as:provideClientKey", - "@type": "@id" - }, - "signClientKey": { - "@id": "as:signClientKey", - "@type": "@id" - }, - "sharedInbox": { - "@id": "as:sharedInbox", - "@type": "@id" - }, - "Public": { - "@id": "as:Public", - "@type": "@id" - }, - "source": "as:source", - "likes": { - "@id": "as:likes", - "@type": "@id" - }, - "shares": { - "@id": "as:shares", - "@type": "@id" - }, - "alsoKnownAs": { - "@id": "as:alsoKnownAs", - "@type": "@id" - } - } -}; - -export const CONTEXTS: Record = { - "https://w3id.org/identity/v1": id_v1, - "https://w3id.org/security/v1": security_v1, - "https://www.w3.org/ns/activitystreams": activitystreams, -}; diff --git a/src/remote/activitypub/models/note.ts b/src/remote/activitypub/models/note.ts deleted file mode 100644 index 492dc0524..000000000 --- a/src/remote/activitypub/models/note.ts +++ /dev/null @@ -1,356 +0,0 @@ -import * as promiseLimit from 'promise-limit'; - -import config from '@/config/index'; -import Resolver from '../resolver'; -import post from '@/services/note/create'; -import { resolvePerson, updatePerson } from './person'; -import { resolveImage } from './image'; -import { IRemoteUser } from '@/models/entities/user'; -import { htmlToMfm } from '../misc/html-to-mfm'; -import { extractApHashtags } from './tag'; -import { unique, toArray, toSingle } from '@/prelude/array'; -import { extractPollFromQuestion } from './question'; -import vote from '@/services/note/polls/vote'; -import { apLogger } from '../logger'; -import { DriveFile } from '@/models/entities/drive-file'; -import { deliverQuestionUpdate } from '@/services/note/polls/update'; -import { extractDbHost, toPuny } from '@/misc/convert-host'; -import { Emojis, Polls, MessagingMessages } from '@/models/index'; -import { Note } from '@/models/entities/note'; -import { IObject, getOneApId, getApId, getOneApHrefNullable, validPost, IPost, isEmoji, getApType } from '../type'; -import { Emoji } from '@/models/entities/emoji'; -import { genId } from '@/misc/gen-id'; -import { fetchMeta } from '@/misc/fetch-meta'; -import { getApLock } from '@/misc/app-lock'; -import { createMessage } from '@/services/messages/create'; -import { parseAudience } from '../audience'; -import { extractApMentions } from './mention'; -import DbResolver from '../db-resolver'; -import { StatusError } from '@/misc/fetch'; - -const logger = apLogger; - -export function validateNote(object: any, uri: string) { - const expectHost = extractDbHost(uri); - - if (object == null) { - return new Error('invalid Note: object is null'); - } - - if (!validPost.includes(getApType(object))) { - return new Error(`invalid Note: invalid object type ${getApType(object)}`); - } - - if (object.id && extractDbHost(object.id) !== expectHost) { - return new Error(`invalid Note: id has different host. expected: ${expectHost}, actual: ${extractDbHost(object.id)}`); - } - - if (object.attributedTo && extractDbHost(getOneApId(object.attributedTo)) !== expectHost) { - return new Error(`invalid Note: attributedTo has different host. expected: ${expectHost}, actual: ${extractDbHost(object.attributedTo)}`); - } - - return null; -} - -/** - * Noteをフェッチします。 - * - * Misskeyに対象のNoteが登録されていればそれを返します。 - */ -export async function fetchNote(object: string | IObject): Promise { - const dbResolver = new DbResolver(); - return await dbResolver.getNoteFromApId(object); -} - -/** - * Noteを作成します。 - */ -export async function createNote(value: string | IObject, resolver?: Resolver, silent = false): Promise { - if (resolver == null) resolver = new Resolver(); - - const object: any = await resolver.resolve(value); - - const entryUri = getApId(value); - const err = validateNote(object, entryUri); - if (err) { - logger.error(`${err.message}`, { - resolver: { - history: resolver.getHistory() - }, - value: value, - object: object - }); - throw new Error('invalid note'); - } - - const note: IPost = object; - - logger.debug(`Note fetched: ${JSON.stringify(note, null, 2)}`); - - logger.info(`Creating the Note: ${note.id}`); - - // 投稿者をフェッチ - const actor = await resolvePerson(getOneApId(note.attributedTo), resolver) as IRemoteUser; - - // 投稿者が凍結されていたらスキップ - if (actor.isSuspended) { - throw new Error('actor has been suspended'); - } - - const noteAudience = await parseAudience(actor, note.to, note.cc); - let visibility = noteAudience.visibility; - const visibleUsers = noteAudience.visibleUsers; - - // Audience (to, cc) が指定されてなかった場合 - if (visibility === 'specified' && visibleUsers.length === 0) { - if (typeof value === 'string') { // 入力がstringならばresolverでGETが発生している - // こちらから匿名GET出来たものならばpublic - visibility = 'public'; - } - } - - let isTalk = note._misskey_talk && visibility === 'specified'; - - const apMentions = await extractApMentions(note.tag); - const apHashtags = await extractApHashtags(note.tag); - - // 添付ファイル - // TODO: attachmentは必ずしもImageではない - // TODO: attachmentは必ずしも配列ではない - // Noteがsensitiveなら添付もsensitiveにする - const limit = promiseLimit(2); - - note.attachment = Array.isArray(note.attachment) ? note.attachment : note.attachment ? [note.attachment] : []; - const files = note.attachment - .map(attach => attach.sensitive = note.sensitive) - ? (await Promise.all(note.attachment.map(x => limit(() => resolveImage(actor, x)) as Promise))) - .filter(image => image != null) - : []; - - // リプライ - const reply: Note | null = note.inReplyTo - ? await resolveNote(note.inReplyTo, resolver).then(x => { - if (x == null) { - logger.warn(`Specified inReplyTo, but nout found`); - throw new Error('inReplyTo not found'); - } else { - return x; - } - }).catch(async e => { - // トークだったらinReplyToのエラーは無視 - const uri = getApId(note.inReplyTo); - if (uri.startsWith(config.url + '/')) { - const id = uri.split('/').pop(); - const talk = await MessagingMessages.findOne(id); - if (talk) { - isTalk = true; - return null; - } - } - - logger.warn(`Error in inReplyTo ${note.inReplyTo} - ${e.statusCode || e}`); - throw e; - }) - : null; - - // 引用 - let quote: Note | undefined | null; - - if (note._misskey_quote || note.quoteUrl) { - const tryResolveNote = async (uri: string): Promise<{ - status: 'ok'; - res: Note | null; - } | { - status: 'permerror' | 'temperror'; - }> => { - if (typeof uri !== 'string' || !uri.match(/^https?:/)) return { status: 'permerror' }; - try { - const res = await resolveNote(uri); - if (res) { - return { - status: 'ok', - res - }; - } else { - return { - status: 'permerror' - }; - } - } catch (e) { - return { - status: (e instanceof StatusError && e.isClientError) ? 'permerror' : 'temperror' - }; - } - }; - - const uris = unique([note._misskey_quote, note.quoteUrl].filter((x): x is string => typeof x === 'string')); - const results = await Promise.all(uris.map(uri => tryResolveNote(uri))); - - quote = results.filter((x): x is { status: 'ok', res: Note | null } => x.status === 'ok').map(x => x.res).find(x => x); - if (!quote) { - if (results.some(x => x.status === 'temperror')) { - throw 'quote resolve failed'; - } - } - } - - const cw = note.summary === '' ? null : note.summary; - - // テキストのパース - const text = note._misskey_content || (note.content ? htmlToMfm(note.content, note.tag) : null); - - // vote - if (reply && reply.hasPoll) { - const poll = await Polls.findOneOrFail(reply.id); - - const tryCreateVote = async (name: string, index: number): Promise => { - if (poll.expiresAt && Date.now() > new Date(poll.expiresAt).getTime()) { - logger.warn(`vote to expired poll from AP: actor=${actor.username}@${actor.host}, note=${note.id}, choice=${name}`); - } else if (index >= 0) { - logger.info(`vote from AP: actor=${actor.username}@${actor.host}, note=${note.id}, choice=${name}`); - await vote(actor, reply, index); - - // リモートフォロワーにUpdate配信 - deliverQuestionUpdate(reply.id); - } - return null; - }; - - if (note.name) { - return await tryCreateVote(note.name, poll.choices.findIndex(x => x === note.name)); - } - } - - const emojis = await extractEmojis(note.tag || [], actor.host).catch(e => { - logger.info(`extractEmojis: ${e}`); - return [] as Emoji[]; - }); - - const apEmojis = emojis.map(emoji => emoji.name); - - const poll = await extractPollFromQuestion(note, resolver).catch(() => undefined); - - // ユーザーの情報が古かったらついでに更新しておく - if (actor.lastFetchedAt == null || Date.now() - actor.lastFetchedAt.getTime() > 1000 * 60 * 60 * 24) { - if (actor.uri) updatePerson(actor.uri); - } - - if (isTalk) { - for (const recipient of visibleUsers) { - await createMessage(actor, recipient, undefined, text || undefined, (files && files.length > 0) ? files[0] : null, object.id); - return null; - } - } - - return await post(actor, { - createdAt: note.published ? new Date(note.published) : null, - files, - reply, - renote: quote, - name: note.name, - cw, - text, - viaMobile: false, - localOnly: false, - visibility, - visibleUsers, - apMentions, - apHashtags, - apEmojis, - poll, - uri: note.id, - url: getOneApHrefNullable(note.url), - }, silent); -} - -/** - * Noteを解決します。 - * - * Misskeyに対象のNoteが登録されていればそれを返し、そうでなければ - * リモートサーバーからフェッチしてMisskeyに登録しそれを返します。 - */ -export async function resolveNote(value: string | IObject, resolver?: Resolver): Promise { - const uri = typeof value === 'string' ? value : value.id; - if (uri == null) throw new Error('missing uri'); - - // ブロックしてたら中断 - const meta = await fetchMeta(); - if (meta.blockedHosts.includes(extractDbHost(uri))) throw { statusCode: 451 }; - - const unlock = await getApLock(uri); - - try { - //#region このサーバーに既に登録されていたらそれを返す - const exist = await fetchNote(uri); - - if (exist) { - return exist; - } - //#endregion - - if (uri.startsWith(config.url)) { - throw new StatusError('cannot resolve local note', 400, 'cannot resolve local note'); - } - - // リモートサーバーからフェッチしてきて登録 - // ここでuriの代わりに添付されてきたNote Objectが指定されていると、サーバーフェッチを経ずにノートが生成されるが - // 添付されてきたNote Objectは偽装されている可能性があるため、常にuriを指定してサーバーフェッチを行う。 - return await createNote(uri, resolver, true); - } finally { - unlock(); - } -} - -export async function extractEmojis(tags: IObject | IObject[], host: string): Promise { - host = toPuny(host); - - if (!tags) return []; - - const eomjiTags = toArray(tags).filter(isEmoji); - - return await Promise.all(eomjiTags.map(async tag => { - const name = tag.name!.replace(/^:/, '').replace(/:$/, ''); - tag.icon = toSingle(tag.icon); - - const exists = await Emojis.findOne({ - host, - name - }); - - if (exists) { - if ((tag.updated != null && exists.updatedAt == null) - || (tag.id != null && exists.uri == null) - || (tag.updated != null && exists.updatedAt != null && new Date(tag.updated) > exists.updatedAt) - || (tag.icon!.url !== exists.url) - ) { - await Emojis.update({ - host, - name, - }, { - uri: tag.id, - url: tag.icon!.url, - updatedAt: new Date(), - }); - - return await Emojis.findOne({ - host, - name - }) as Emoji; - } - - return exists; - } - - logger.info(`register emoji host=${host}, name=${name}`); - - return await Emojis.save({ - id: genId(), - host, - name, - uri: tag.id, - url: tag.icon!.url, - updatedAt: new Date(), - aliases: [] - } as Partial); - })); -} diff --git a/src/remote/activitypub/models/person.ts b/src/remote/activitypub/models/person.ts deleted file mode 100644 index eb8c00a10..000000000 --- a/src/remote/activitypub/models/person.ts +++ /dev/null @@ -1,494 +0,0 @@ -import { URL } from 'url'; -import * as promiseLimit from 'promise-limit'; - -import $, { Context } from 'cafy'; -import config from '@/config/index'; -import Resolver from '../resolver'; -import { resolveImage } from './image'; -import { isCollectionOrOrderedCollection, isCollection, IActor, getApId, getOneApHrefNullable, IObject, isPropertyValue, IApPropertyValue, getApType, isActor } from '../type'; -import { fromHtml } from '../../../mfm/from-html'; -import { htmlToMfm } from '../misc/html-to-mfm'; -import { resolveNote, extractEmojis } from './note'; -import { registerOrFetchInstanceDoc } from '@/services/register-or-fetch-instance-doc'; -import { extractApHashtags } from './tag'; -import { apLogger } from '../logger'; -import { Note } from '@/models/entities/note'; -import { updateUsertags } from '@/services/update-hashtag'; -import { Users, Instances, DriveFiles, Followings, UserProfiles, UserPublickeys } from '@/models/index'; -import { User, IRemoteUser } from '@/models/entities/user'; -import { Emoji } from '@/models/entities/emoji'; -import { UserNotePining } from '@/models/entities/user-note-pining'; -import { genId } from '@/misc/gen-id'; -import { instanceChart, usersChart } from '@/services/chart/index'; -import { UserPublickey } from '@/models/entities/user-publickey'; -import { isDuplicateKeyValueError } from '@/misc/is-duplicate-key-value-error'; -import { toPuny } from '@/misc/convert-host'; -import { UserProfile } from '@/models/entities/user-profile'; -import { getConnection } from 'typeorm'; -import { toArray } from '@/prelude/array'; -import { fetchInstanceMetadata } from '@/services/fetch-instance-metadata'; -import { normalizeForSearch } from '@/misc/normalize-for-search'; -import { truncate } from '@/misc/truncate'; -import { StatusError } from '@/misc/fetch'; - -const logger = apLogger; - -const nameLength = 128; -const summaryLength = 2048; - -/** - * Validate and convert to actor object - * @param x Fetched object - * @param uri Fetch target URI - */ -function validateActor(x: IObject, uri: string): IActor { - const expectHost = toPuny(new URL(uri).hostname); - - if (x == null) { - throw new Error('invalid Actor: object is null'); - } - - if (!isActor(x)) { - throw new Error(`invalid Actor type '${x.type}'`); - } - - const validate = (name: string, value: any, validater: Context) => { - const e = validater.test(value); - if (e) throw new Error(`invalid Actor: ${name} ${e.message}`); - }; - - validate('id', x.id, $.str.min(1)); - validate('inbox', x.inbox, $.str.min(1)); - validate('preferredUsername', x.preferredUsername, $.str.min(1).max(128).match(/^\w([\w-.]*\w)?$/)); - - // These fields are only informational, and some AP software allows these - // fields to be very long. If they are too long, we cut them off. This way - // we can at least see these users and their activities. - validate('name', truncate(x.name, nameLength), $.optional.nullable.str); - validate('summary', truncate(x.summary, summaryLength), $.optional.nullable.str); - - const idHost = toPuny(new URL(x.id!).hostname); - if (idHost !== expectHost) { - throw new Error('invalid Actor: id has different host'); - } - - if (x.publicKey) { - if (typeof x.publicKey.id !== 'string') { - throw new Error('invalid Actor: publicKey.id is not a string'); - } - - const publicKeyIdHost = toPuny(new URL(x.publicKey.id).hostname); - if (publicKeyIdHost !== expectHost) { - throw new Error('invalid Actor: publicKey.id has different host'); - } - } - - return x; -} - -/** - * Personをフェッチします。 - * - * Misskeyに対象のPersonが登録されていればそれを返します。 - */ -export async function fetchPerson(uri: string, resolver?: Resolver): Promise { - if (typeof uri !== 'string') throw new Error('uri is not string'); - - // URIがこのサーバーを指しているならデータベースからフェッチ - if (uri.startsWith(config.url + '/')) { - const id = uri.split('/').pop(); - return await Users.findOne(id).then(x => x || null); - } - - //#region このサーバーに既に登録されていたらそれを返す - const exist = await Users.findOne({ uri }); - - if (exist) { - return exist; - } - //#endregion - - return null; -} - -/** - * Personを作成します。 - */ -export async function createPerson(uri: string, resolver?: Resolver): Promise { - if (typeof uri !== 'string') throw new Error('uri is not string'); - - if (uri.startsWith(config.url)) { - throw new StatusError('cannot resolve local user', 400, 'cannot resolve local user'); - } - - if (resolver == null) resolver = new Resolver(); - - const object = await resolver.resolve(uri) as any; - - const person = validateActor(object, uri); - - logger.info(`Creating the Person: ${person.id}`); - - const host = toPuny(new URL(object.id).hostname); - - const { fields } = analyzeAttachments(person.attachment || []); - - const tags = extractApHashtags(person.tag).map(tag => normalizeForSearch(tag)).splice(0, 32); - - const isBot = getApType(object) === 'Service'; - - const bday = person['vcard:bday']?.match(/^\d{4}-\d{2}-\d{2}/); - - // Create user - let user: IRemoteUser; - try { - // Start transaction - await getConnection().transaction(async transactionalEntityManager => { - user = await transactionalEntityManager.save(new User({ - id: genId(), - avatarId: null, - bannerId: null, - createdAt: new Date(), - lastFetchedAt: new Date(), - name: truncate(person.name, nameLength), - isLocked: !!person.manuallyApprovesFollowers, - isExplorable: !!person.discoverable, - username: person.preferredUsername, - usernameLower: person.preferredUsername!.toLowerCase(), - host, - inbox: person.inbox, - sharedInbox: person.sharedInbox || (person.endpoints ? person.endpoints.sharedInbox : undefined), - followersUri: person.followers ? getApId(person.followers) : undefined, - featured: person.featured ? getApId(person.featured) : undefined, - uri: person.id, - tags, - isBot, - isCat: (person as any).isCat === true - })) as IRemoteUser; - - await transactionalEntityManager.save(new UserProfile({ - userId: user.id, - description: person.summary ? htmlToMfm(truncate(person.summary, summaryLength), person.tag) : null, - url: getOneApHrefNullable(person.url), - fields, - birthday: bday ? bday[0] : null, - location: person['vcard:Address'] || null, - userHost: host - })); - - if (person.publicKey) { - await transactionalEntityManager.save(new UserPublickey({ - userId: user.id, - keyId: person.publicKey.id, - keyPem: person.publicKey.publicKeyPem - })); - } - }); - } catch (e) { - // duplicate key error - if (isDuplicateKeyValueError(e)) { - // /users/@a => /users/:id のように入力がaliasなときにエラーになることがあるのを対応 - const u = await Users.findOne({ - uri: person.id - }); - - if (u) { - user = u as IRemoteUser; - } else { - throw new Error('already registered'); - } - } else { - logger.error(e); - throw e; - } - } - - // Register host - registerOrFetchInstanceDoc(host).then(i => { - Instances.increment({ id: i.id }, 'usersCount', 1); - instanceChart.newUser(i.host); - fetchInstanceMetadata(i); - }); - - usersChart.update(user!, true); - - // ハッシュタグ更新 - updateUsertags(user!, tags); - - //#region アバターとヘッダー画像をフェッチ - const [avatar, banner] = await Promise.all([ - person.icon, - person.image - ].map(img => - img == null - ? Promise.resolve(null) - : resolveImage(user!, img).catch(() => null) - )); - - const avatarId = avatar ? avatar.id : null; - const bannerId = banner ? banner.id : null; - const avatarUrl = avatar ? DriveFiles.getPublicUrl(avatar, true) : null; - const bannerUrl = banner ? DriveFiles.getPublicUrl(banner) : null; - const avatarBlurhash = avatar ? avatar.blurhash : null; - const bannerBlurhash = banner ? banner.blurhash : null; - - await Users.update(user!.id, { - avatarId, - bannerId, - avatarUrl, - bannerUrl, - avatarBlurhash, - bannerBlurhash - }); - - user!.avatarId = avatarId; - user!.bannerId = bannerId; - user!.avatarUrl = avatarUrl; - user!.bannerUrl = bannerUrl; - user!.avatarBlurhash = avatarBlurhash; - user!.bannerBlurhash = bannerBlurhash; - //#endregion - - //#region カスタム絵文字取得 - const emojis = await extractEmojis(person.tag || [], host).catch(e => { - logger.info(`extractEmojis: ${e}`); - return [] as Emoji[]; - }); - - const emojiNames = emojis.map(emoji => emoji.name); - - await Users.update(user!.id, { - emojis: emojiNames - }); - //#endregion - - await updateFeatured(user!.id).catch(err => logger.error(err)); - - return user!; -} - -/** - * Personの情報を更新します。 - * Misskeyに対象のPersonが登録されていなければ無視します。 - * @param uri URI of Person - * @param resolver Resolver - * @param hint Hint of Person object (この値が正当なPersonの場合、Remote resolveをせずに更新に利用します) - */ -export async function updatePerson(uri: string, resolver?: Resolver | null, hint?: object): Promise { - if (typeof uri !== 'string') throw new Error('uri is not string'); - - // URIがこのサーバーを指しているならスキップ - if (uri.startsWith(config.url + '/')) { - return; - } - - //#region このサーバーに既に登録されているか - const exist = await Users.findOne({ uri }) as IRemoteUser; - - if (exist == null) { - return; - } - //#endregion - - if (resolver == null) resolver = new Resolver(); - - const object = hint || await resolver.resolve(uri) as any; - - const person = validateActor(object, uri); - - logger.info(`Updating the Person: ${person.id}`); - - // アバターとヘッダー画像をフェッチ - const [avatar, banner] = await Promise.all([ - person.icon, - person.image - ].map(img => - img == null - ? Promise.resolve(null) - : resolveImage(exist, img).catch(() => null) - )); - - // カスタム絵文字取得 - const emojis = await extractEmojis(person.tag || [], exist.host).catch(e => { - logger.info(`extractEmojis: ${e}`); - return [] as Emoji[]; - }); - - const emojiNames = emojis.map(emoji => emoji.name); - - const { fields } = analyzeAttachments(person.attachment || []); - - const tags = extractApHashtags(person.tag).map(tag => normalizeForSearch(tag)).splice(0, 32); - - const bday = person['vcard:bday']?.match(/^\d{4}-\d{2}-\d{2}/); - - const updates = { - lastFetchedAt: new Date(), - inbox: person.inbox, - sharedInbox: person.sharedInbox || (person.endpoints ? person.endpoints.sharedInbox : undefined), - followersUri: person.followers ? getApId(person.followers) : undefined, - featured: person.featured, - emojis: emojiNames, - name: truncate(person.name, nameLength), - tags, - isBot: getApType(object) === 'Service', - isCat: (person as any).isCat === true, - isLocked: !!person.manuallyApprovesFollowers, - isExplorable: !!person.discoverable, - } as Partial; - - if (avatar) { - updates.avatarId = avatar.id; - updates.avatarUrl = DriveFiles.getPublicUrl(avatar, true); - updates.avatarBlurhash = avatar.blurhash; - } - - if (banner) { - updates.bannerId = banner.id; - updates.bannerUrl = DriveFiles.getPublicUrl(banner); - updates.bannerBlurhash = banner.blurhash; - } - - // Update user - await Users.update(exist.id, updates); - - if (person.publicKey) { - await UserPublickeys.update({ userId: exist.id }, { - keyId: person.publicKey.id, - keyPem: person.publicKey.publicKeyPem - }); - } - - await UserProfiles.update({ userId: exist.id }, { - url: getOneApHrefNullable(person.url), - fields, - description: person.summary ? htmlToMfm(truncate(person.summary, summaryLength), person.tag) : null, - birthday: bday ? bday[0] : null, - location: person['vcard:Address'] || null, - }); - - // ハッシュタグ更新 - updateUsertags(exist, tags); - - // 該当ユーザーが既にフォロワーになっていた場合はFollowingもアップデートする - await Followings.update({ - followerId: exist.id - }, { - followerSharedInbox: person.sharedInbox || (person.endpoints ? person.endpoints.sharedInbox : undefined) - }); - - await updateFeatured(exist.id).catch(err => logger.error(err)); -} - -/** - * Personを解決します。 - * - * Misskeyに対象のPersonが登録されていればそれを返し、そうでなければ - * リモートサーバーからフェッチしてMisskeyに登録しそれを返します。 - */ -export async function resolvePerson(uri: string, resolver?: Resolver): Promise { - if (typeof uri !== 'string') throw new Error('uri is not string'); - - //#region このサーバーに既に登録されていたらそれを返す - const exist = await fetchPerson(uri); - - if (exist) { - return exist; - } - //#endregion - - // リモートサーバーからフェッチしてきて登録 - if (resolver == null) resolver = new Resolver(); - return await createPerson(uri, resolver); -} - -const services: { - [x: string]: (id: string, username: string) => any - } = { - 'misskey:authentication:twitter': (userId, screenName) => ({ userId, screenName }), - 'misskey:authentication:github': (id, login) => ({ id, login }), - 'misskey:authentication:discord': (id, name) => $discord(id, name) -}; - -const $discord = (id: string, name: string) => { - if (typeof name !== 'string') - name = 'unknown#0000'; - const [username, discriminator] = name.split('#'); - return { id, username, discriminator }; -}; - -function addService(target: { [x: string]: any }, source: IApPropertyValue) { - const service = services[source.name]; - - if (typeof source.value !== 'string') - source.value = 'unknown'; - - const [id, username] = source.value.split('@'); - - if (service) - target[source.name.split(':')[2]] = service(id, username); -} - -export function analyzeAttachments(attachments: IObject | IObject[] | undefined) { - const fields: { - name: string, - value: string - }[] = []; - const services: { [x: string]: any } = {}; - - if (Array.isArray(attachments)) { - for (const attachment of attachments.filter(isPropertyValue)) { - if (isPropertyValue(attachment.identifier)) { - addService(services, attachment.identifier); - } else { - fields.push({ - name: attachment.name, - value: fromHtml(attachment.value) - }); - } - } - } - - return { fields, services }; -} - -export async function updateFeatured(userId: User['id']) { - const user = await Users.findOneOrFail(userId); - if (!Users.isRemoteUser(user)) return; - if (!user.featured) return; - - logger.info(`Updating the featured: ${user.uri}`); - - const resolver = new Resolver(); - - // Resolve to (Ordered)Collection Object - const collection = await resolver.resolveCollection(user.featured); - if (!isCollectionOrOrderedCollection(collection)) throw new Error(`Object is not Collection or OrderedCollection`); - - // Resolve to Object(may be Note) arrays - const unresolvedItems = isCollection(collection) ? collection.items : collection.orderedItems; - const items = await Promise.all(toArray(unresolvedItems).map(x => resolver.resolve(x))); - - // Resolve and regist Notes - const limit = promiseLimit(2); - const featuredNotes = await Promise.all(items - .filter(item => getApType(item) === 'Note') // TODO: Noteでなくてもいいかも - .slice(0, 5) - .map(item => limit(() => resolveNote(item, resolver)))); - - await getConnection().transaction(async transactionalEntityManager => { - await transactionalEntityManager.delete(UserNotePining, { userId: user.id }); - - // とりあえずidを別の時間で生成して順番を維持 - let td = 0; - for (const note of featuredNotes.filter(note => note != null)) { - td -= 1000; - transactionalEntityManager.insert(UserNotePining, { - id: genId(new Date(Date.now() + td)), - createdAt: new Date(), - userId: user.id, - noteId: note!.id - }); - } - }); -} diff --git a/src/remote/activitypub/renderer/ordered-collection.ts b/src/remote/activitypub/renderer/ordered-collection.ts deleted file mode 100644 index 68870a0ec..000000000 --- a/src/remote/activitypub/renderer/ordered-collection.ts +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Render OrderedCollection - * @param id URL of self - * @param totalItems Total number of items - * @param first URL of first page (optional) - * @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?: object) { - const page: any = { - id, - type: 'OrderedCollection', - totalItems, - }; - - if (first) page.first = first; - if (last) page.last = last; - if (orderedItems) page.orderedItems = orderedItems; - - return page; -} diff --git a/src/server/activitypub/followers.ts b/src/server/activitypub/followers.ts deleted file mode 100644 index 8b6a066bf..000000000 --- a/src/server/activitypub/followers.ts +++ /dev/null @@ -1,88 +0,0 @@ -import * as Router from '@koa/router'; -import config from '@/config/index'; -import $ from 'cafy'; -import { ID } from '@/misc/cafy-id'; -import * as url from '@/prelude/url'; -import { renderActivity } from '@/remote/activitypub/renderer/index'; -import renderOrderedCollection from '@/remote/activitypub/renderer/ordered-collection'; -import renderOrderedCollectionPage from '@/remote/activitypub/renderer/ordered-collection-page'; -import renderFollowUser from '@/remote/activitypub/renderer/follow-user'; -import { setResponseType } from '../activitypub'; -import { Users, Followings } from '@/models/index'; -import { LessThan } from 'typeorm'; - -export default async (ctx: Router.RouterContext) => { - const userId = ctx.params.user; - - // Get 'cursor' parameter - const [cursor, cursorErr] = $.optional.type(ID).get(ctx.request.query.cursor); - - // Get 'page' parameter - const pageErr = !$.optional.str.or(['true', 'false']).ok(ctx.request.query.page); - const page: boolean = ctx.request.query.page === 'true'; - - // Validate parameters - if (cursorErr || pageErr) { - ctx.status = 400; - return; - } - - // Verify user - const user = await Users.findOne({ - id: userId, - host: null - }); - - if (user == null) { - ctx.status = 404; - return; - } - - const limit = 10; - const partOf = `${config.url}/users/${userId}/followers`; - - if (page) { - const query = { - followeeId: user.id - } as any; - - // カーソルが指定されている場合 - if (cursor) { - query.id = LessThan(cursor); - } - - // Get followers - const followings = await Followings.find({ - where: query, - take: limit + 1, - order: { id: -1 } - }); - - // 「次のページ」があるかどうか - const inStock = followings.length === limit + 1; - if (inStock) followings.pop(); - - const renderedFollowers = await Promise.all(followings.map(following => renderFollowUser(following.followerId))); - const rendered = renderOrderedCollectionPage( - `${partOf}?${url.query({ - page: 'true', - cursor - })}`, - user.followersCount, renderedFollowers, partOf, - undefined, - inStock ? `${partOf}?${url.query({ - page: 'true', - cursor: followings[followings.length - 1].id - })}` : undefined - ); - - ctx.body = renderActivity(rendered); - setResponseType(ctx); - } else { - // index page - const rendered = renderOrderedCollection(partOf, user.followersCount, `${partOf}?page=true`); - ctx.body = renderActivity(rendered); - ctx.set('Cache-Control', 'public, max-age=180'); - setResponseType(ctx); - } -}; diff --git a/src/server/activitypub/following.ts b/src/server/activitypub/following.ts deleted file mode 100644 index 5fc5d68a9..000000000 --- a/src/server/activitypub/following.ts +++ /dev/null @@ -1,89 +0,0 @@ -import * as Router from '@koa/router'; -import config from '@/config/index'; -import $ from 'cafy'; -import { ID } from '@/misc/cafy-id'; -import * as url from '@/prelude/url'; -import { renderActivity } from '@/remote/activitypub/renderer/index'; -import renderOrderedCollection from '@/remote/activitypub/renderer/ordered-collection'; -import renderOrderedCollectionPage from '@/remote/activitypub/renderer/ordered-collection-page'; -import renderFollowUser from '@/remote/activitypub/renderer/follow-user'; -import { setResponseType } from '../activitypub'; -import { Users, Followings } from '@/models/index'; -import { LessThan, FindConditions } from 'typeorm'; -import { Following } from '@/models/entities/following'; - -export default async (ctx: Router.RouterContext) => { - const userId = ctx.params.user; - - // Get 'cursor' parameter - const [cursor, cursorErr] = $.optional.type(ID).get(ctx.request.query.cursor); - - // Get 'page' parameter - const pageErr = !$.optional.str.or(['true', 'false']).ok(ctx.request.query.page); - const page: boolean = ctx.request.query.page === 'true'; - - // Validate parameters - if (cursorErr || pageErr) { - ctx.status = 400; - return; - } - - // Verify user - const user = await Users.findOne({ - id: userId, - host: null - }); - - if (user == null) { - ctx.status = 404; - return; - } - - const limit = 10; - const partOf = `${config.url}/users/${userId}/following`; - - if (page) { - const query = { - followerId: user.id - } as FindConditions; - - // カーソルが指定されている場合 - if (cursor) { - query.id = LessThan(cursor); - } - - // Get followings - const followings = await Followings.find({ - where: query, - take: limit + 1, - order: { id: -1 } - }); - - // 「次のページ」があるかどうか - const inStock = followings.length === limit + 1; - if (inStock) followings.pop(); - - const renderedFollowees = await Promise.all(followings.map(following => renderFollowUser(following.followeeId))); - const rendered = renderOrderedCollectionPage( - `${partOf}?${url.query({ - page: 'true', - cursor - })}`, - user.followingCount, renderedFollowees, partOf, - undefined, - inStock ? `${partOf}?${url.query({ - page: 'true', - cursor: followings[followings.length - 1].id - })}` : undefined - ); - - ctx.body = renderActivity(rendered); - setResponseType(ctx); - } else { - // index page - const rendered = renderOrderedCollection(partOf, user.followingCount, `${partOf}?page=true`); - ctx.body = renderActivity(rendered); - ctx.set('Cache-Control', 'public, max-age=180'); - setResponseType(ctx); - } -}; diff --git a/src/server/api/define.ts b/src/server/api/define.ts deleted file mode 100644 index 4bd8f95e3..000000000 --- a/src/server/api/define.ts +++ /dev/null @@ -1,87 +0,0 @@ -import * as fs from 'fs'; -import { ILocalUser } from '@/models/entities/user'; -import { IEndpointMeta } from './endpoints'; -import { ApiError } from './error'; -import { SchemaType } from '@/misc/schema'; -import { AccessToken } from '@/models/entities/access-token'; - -type NonOptional = T extends undefined ? never : T; - -type SimpleUserInfo = { - id: ILocalUser['id']; - host: ILocalUser['host']; - username: ILocalUser['username']; - uri: ILocalUser['uri']; - inbox: ILocalUser['inbox']; - sharedInbox: ILocalUser['sharedInbox']; - isAdmin: ILocalUser['isAdmin']; - isModerator: ILocalUser['isModerator']; - isSilenced: ILocalUser['isSilenced']; -}; - -type Params = { - [P in keyof T['params']]: NonNullable[P]['transform'] extends Function - ? ReturnType[P]['transform']> - : NonNullable[P]['default'] extends null | number | string - ? NonOptional[P]['validator']['get']>[0]> - : ReturnType[P]['validator']['get']>[0]; -}; - -export type Response = Record | void; - -type executor = - (params: Params, user: T['requireCredential'] extends true ? SimpleUserInfo : SimpleUserInfo | null, token: AccessToken | null, file?: any, cleanup?: Function) => - Promise>>; - -export default function (meta: T, cb: executor) - : (params: any, user: T['requireCredential'] extends true ? SimpleUserInfo : SimpleUserInfo | null, token: AccessToken | null, file?: any) => Promise { - return (params: any, user: T['requireCredential'] extends true ? SimpleUserInfo : SimpleUserInfo | null, token: AccessToken | null, file?: any) => { - function cleanup() { - fs.unlink(file.path, () => {}); - } - - if (meta.requireFile && file == null) return Promise.reject(new ApiError({ - message: 'File required.', - code: 'FILE_REQUIRED', - id: '4267801e-70d1-416a-b011-4ee502885d8b', - })); - - const [ps, pserr] = getParams(meta, params); - if (pserr) { - if (file) cleanup(); - return Promise.reject(pserr); - } - - return cb(ps, user, token, file, cleanup); - }; -} - -function getParams(defs: T, params: any): [Params, ApiError | null] { - if (defs.params == null) return [params, null]; - - const x: any = {}; - let err: ApiError | null = null; - Object.entries(defs.params).some(([k, def]) => { - const [v, e] = def.validator.get(params[k]); - if (e) { - err = new ApiError({ - message: 'Invalid param.', - code: 'INVALID_PARAM', - id: '3d81ceae-475f-4600-b2a8-2bc116157532', - }, { - param: k, - reason: e.message - }); - return true; - } else { - if (v === undefined && def.hasOwnProperty('default')) { - x[k] = def.default; - } else { - x[k] = v; - } - if (def.transform) x[k] = def.transform(x[k]); - return false; - } - }); - return [x, err]; -} diff --git a/src/server/api/endpoints/ap/get.ts b/src/server/api/endpoints/ap/get.ts deleted file mode 100644 index 78919f43b..000000000 --- a/src/server/api/endpoints/ap/get.ts +++ /dev/null @@ -1,36 +0,0 @@ -import $ from 'cafy'; -import define from '../../define'; -import Resolver from '@/remote/activitypub/resolver'; -import { ApiError } from '../../error'; -import * as ms from 'ms'; - -export const meta = { - tags: ['federation'], - - requireCredential: true as const, - - limit: { - duration: ms('1hour'), - max: 30 - }, - - params: { - uri: { - validator: $.str, - }, - }, - - errors: { - }, - - res: { - type: 'object' as const, - optional: false as const, nullable: false as const, - } -}; - -export default define(meta, async (ps) => { - const resolver = new Resolver(); - const object = await resolver.resolve(ps.uri); - return object; -}); diff --git a/src/server/api/endpoints/ap/show.ts b/src/server/api/endpoints/ap/show.ts deleted file mode 100644 index 2280d9372..000000000 --- a/src/server/api/endpoints/ap/show.ts +++ /dev/null @@ -1,190 +0,0 @@ -import $ from 'cafy'; -import define from '../../define'; -import config from '@/config/index'; -import { createPerson } from '@/remote/activitypub/models/person'; -import { createNote } from '@/remote/activitypub/models/note'; -import Resolver from '@/remote/activitypub/resolver'; -import { ApiError } from '../../error'; -import { extractDbHost } from '@/misc/convert-host'; -import { Users, Notes } from '@/models/index'; -import { Note } from '@/models/entities/note'; -import { User } from '@/models/entities/user'; -import { fetchMeta } from '@/misc/fetch-meta'; -import { isActor, isPost, getApId } from '@/remote/activitypub/type'; -import * as ms from 'ms'; - -export const meta = { - tags: ['federation'], - - requireCredential: true as const, - - limit: { - duration: ms('1hour'), - max: 30 - }, - - params: { - uri: { - validator: $.str, - }, - }, - - errors: { - noSuchObject: { - message: 'No such object.', - code: 'NO_SUCH_OBJECT', - id: 'dc94d745-1262-4e63-a17d-fecaa57efc82' - } - }, - - res: { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - type: { - type: 'string' as const, - optional: false as const, nullable: false as const, - enum: ['User', 'Note'] - }, - object: { - type: 'object' as const, - optional: false as const, nullable: false as const - } - } - } -}; - -export default define(meta, async (ps) => { - const object = await fetchAny(ps.uri); - if (object) { - return object; - } else { - throw new ApiError(meta.errors.noSuchObject); - } -}); - -/*** - * URIからUserかNoteを解決する - */ -async function fetchAny(uri: string) { - // URIがこのサーバーを指しているなら、ローカルユーザーIDとしてDBからフェッチ - if (uri.startsWith(config.url + '/')) { - const parts = uri.split('/'); - const id = parts.pop(); - const type = parts.pop(); - - if (type === 'notes') { - const note = await Notes.findOne(id); - - if (note) { - return { - type: 'Note', - object: await Notes.pack(note, null, { detail: true }) - }; - } - } else if (type === 'users') { - const user = await Users.findOne(id); - - if (user) { - return { - type: 'User', - object: await Users.pack(user, null, { detail: true }) - }; - } - } - } - - // ブロックしてたら中断 - const meta = await fetchMeta(); - if (meta.blockedHosts.includes(extractDbHost(uri))) return null; - - // URI(AP Object id)としてDB検索 - { - const [user, note] = await Promise.all([ - Users.findOne({ uri: uri }), - Notes.findOne({ uri: uri }) - ]); - - const packed = await mergePack(user, note); - if (packed !== null) return packed; - } - - // リモートから一旦オブジェクトフェッチ - const resolver = new Resolver(); - const object = await resolver.resolve(uri) as any; - - // /@user のような正規id以外で取得できるURIが指定されていた場合、ここで初めて正規URIが確定する - // これはDBに存在する可能性があるため再度DB検索 - if (uri !== object.id) { - if (object.id.startsWith(config.url + '/')) { - const parts = object.id.split('/'); - const id = parts.pop(); - const type = parts.pop(); - - if (type === 'notes') { - const note = await Notes.findOne(id); - - if (note) { - return { - type: 'Note', - object: await Notes.pack(note, null, { detail: true }) - }; - } - } else if (type === 'users') { - const user = await Users.findOne(id); - - if (user) { - return { - type: 'User', - object: await Users.pack(user, null, { detail: true }) - }; - } - } - } - - const [user, note] = await Promise.all([ - Users.findOne({ uri: object.id }), - Notes.findOne({ uri: object.id }) - ]); - - const packed = await mergePack(user, note); - if (packed !== null) return packed; - } - - // それでもみつからなければ新規であるため登録 - if (isActor(object)) { - const user = await createPerson(getApId(object)); - return { - type: 'User', - object: await Users.pack(user, null, { detail: true }) - }; - } - - if (isPost(object)) { - const note = await createNote(getApId(object), undefined, true); - return { - type: 'Note', - object: await Notes.pack(note!, null, { detail: true }) - }; - } - - return null; -} - -async function mergePack(user: User | null | undefined, note: Note | null | undefined) { - if (user != null) { - return { - type: 'User', - object: await Users.pack(user, null, { detail: true }) - }; - } - - if (note != null) { - return { - type: 'Note', - object: await Notes.pack(note, null, { detail: true }) - }; - } - - return null; -} diff --git a/src/server/api/endpoints/blocking/create.ts b/src/server/api/endpoints/blocking/create.ts deleted file mode 100644 index 295325239..000000000 --- a/src/server/api/endpoints/blocking/create.ts +++ /dev/null @@ -1,89 +0,0 @@ -import $ from 'cafy'; -import { ID } from '@/misc/cafy-id'; -import * as ms from 'ms'; -import create from '@/services/blocking/create'; -import define from '../../define'; -import { ApiError } from '../../error'; -import { getUser } from '../../common/getters'; -import { Blockings, NoteWatchings, Users } from '@/models/index'; - -export const meta = { - tags: ['account'], - - limit: { - duration: ms('1hour'), - max: 100 - }, - - requireCredential: true as const, - - kind: 'write:blocks', - - params: { - userId: { - validator: $.type(ID), - } - }, - - errors: { - noSuchUser: { - message: 'No such user.', - code: 'NO_SUCH_USER', - id: '7cc4f851-e2f1-4621-9633-ec9e1d00c01e' - }, - - blockeeIsYourself: { - message: 'Blockee is yourself.', - code: 'BLOCKEE_IS_YOURSELF', - id: '88b19138-f28d-42c0-8499-6a31bbd0fdc6' - }, - - alreadyBlocking: { - message: 'You are already blocking that user.', - code: 'ALREADY_BLOCKING', - id: '787fed64-acb9-464a-82eb-afbd745b9614' - }, - }, - - res: { - type: 'object' as const, - optional: false as const, nullable: false as const, - ref: 'User' - } -}; - -export default define(meta, async (ps, user) => { - const blocker = await Users.findOneOrFail(user.id); - - // 自分自身 - if (user.id === ps.userId) { - throw new ApiError(meta.errors.blockeeIsYourself); - } - - // Get blockee - const blockee = await getUser(ps.userId).catch(e => { - if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser); - throw e; - }); - - // Check if already blocking - const exist = await Blockings.findOne({ - blockerId: blocker.id, - blockeeId: blockee.id - }); - - if (exist != null) { - throw new ApiError(meta.errors.alreadyBlocking); - } - - await create(blocker, blockee); - - NoteWatchings.delete({ - userId: blocker.id, - noteUserId: blockee.id - }); - - return await Users.pack(blockee.id, blocker, { - detail: true - }); -}); diff --git a/src/server/api/endpoints/blocking/delete.ts b/src/server/api/endpoints/blocking/delete.ts deleted file mode 100644 index a66e46fdf..000000000 --- a/src/server/api/endpoints/blocking/delete.ts +++ /dev/null @@ -1,85 +0,0 @@ -import $ from 'cafy'; -import { ID } from '@/misc/cafy-id'; -import * as ms from 'ms'; -import deleteBlocking from '@/services/blocking/delete'; -import define from '../../define'; -import { ApiError } from '../../error'; -import { getUser } from '../../common/getters'; -import { Blockings, Users } from '@/models/index'; - -export const meta = { - tags: ['account'], - - limit: { - duration: ms('1hour'), - max: 100 - }, - - requireCredential: true as const, - - kind: 'write:blocks', - - params: { - userId: { - validator: $.type(ID), - } - }, - - errors: { - noSuchUser: { - message: 'No such user.', - code: 'NO_SUCH_USER', - id: '8621d8bf-c358-4303-a066-5ea78610eb3f' - }, - - blockeeIsYourself: { - message: 'Blockee is yourself.', - code: 'BLOCKEE_IS_YOURSELF', - id: '06f6fac6-524b-473c-a354-e97a40ae6eac' - }, - - notBlocking: { - message: 'You are not blocking that user.', - code: 'NOT_BLOCKING', - id: '291b2efa-60c6-45c0-9f6a-045c8f9b02cd' - }, - }, - - res: { - type: 'object' as const, - optional: false as const, nullable: false as const, - ref: 'User', - }, -}; - -export default define(meta, async (ps, user) => { - const blocker = await Users.findOneOrFail(user.id); - - // Check if the blockee is yourself - if (user.id === ps.userId) { - throw new ApiError(meta.errors.blockeeIsYourself); - } - - // Get blockee - const blockee = await getUser(ps.userId).catch(e => { - if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser); - throw e; - }); - - // Check not blocking - const exist = await Blockings.findOne({ - blockerId: blocker.id, - blockeeId: blockee.id - }); - - if (exist == null) { - throw new ApiError(meta.errors.notBlocking); - } - - // Delete blocking - await deleteBlocking(blocker, blockee); - - return await Users.pack(blockee.id, blocker, { - detail: true - }); -}); diff --git a/src/server/api/endpoints/channels/update.ts b/src/server/api/endpoints/channels/update.ts deleted file mode 100644 index 9b447bd04..000000000 --- a/src/server/api/endpoints/channels/update.ts +++ /dev/null @@ -1,94 +0,0 @@ -import $ from 'cafy'; -import { ID } from '@/misc/cafy-id'; -import define from '../../define'; -import { ApiError } from '../../error'; -import { Channels, DriveFiles } from '@/models/index'; - -export const meta = { - tags: ['channels'], - - requireCredential: true as const, - - kind: 'write:channels', - - params: { - channelId: { - validator: $.type(ID), - }, - - name: { - validator: $.optional.str.range(1, 128) - }, - - description: { - validator: $.nullable.optional.str.range(1, 2048) - }, - - bannerId: { - validator: $.nullable.optional.type(ID), - } - }, - - res: { - type: 'object' as const, - optional: false as const, nullable: false as const, - ref: 'Channel', - }, - - errors: { - noSuchChannel: { - message: 'No such channel.', - code: 'NO_SUCH_CHANNEL', - id: 'f9c5467f-d492-4c3c-9a8d-a70dacc86512' - }, - - accessDenied: { - message: 'You do not have edit privilege of the channel.', - code: 'ACCESS_DENIED', - id: '1fb7cb09-d46a-4fdf-b8df-057788cce513' - }, - - noSuchFile: { - message: 'No such file.', - code: 'NO_SUCH_FILE', - id: 'e86c14a4-0da2-4032-8df3-e737a04c7f3b' - }, - } -}; - -export default define(meta, async (ps, me) => { - const channel = await Channels.findOne({ - id: ps.channelId, - }); - - if (channel == null) { - throw new ApiError(meta.errors.noSuchChannel); - } - - if (channel.userId !== me.id) { - throw new ApiError(meta.errors.accessDenied); - } - - // tslint:disable-next-line:no-unnecessary-initializer - let banner = undefined; - if (ps.bannerId != null) { - banner = await DriveFiles.findOne({ - id: ps.bannerId, - userId: me.id - }); - - if (banner == null) { - throw new ApiError(meta.errors.noSuchFile); - } - } else if (ps.bannerId === null) { - banner = null; - } - - await Channels.update(channel.id, { - ...(ps.name !== undefined ? { name: ps.name } : {}), - ...(ps.description !== undefined ? { description: ps.description } : {}), - ...(banner ? { bannerId: banner.id } : {}), - }); - - return await Channels.pack(channel.id, me); -}); diff --git a/src/server/api/endpoints/drive/files/create.ts b/src/server/api/endpoints/drive/files/create.ts deleted file mode 100644 index 2abc104e6..000000000 --- a/src/server/api/endpoints/drive/files/create.ts +++ /dev/null @@ -1,89 +0,0 @@ -import * as ms from 'ms'; -import $ from 'cafy'; -import { ID } from '@/misc/cafy-id'; -import create from '@/services/drive/add-file'; -import define from '../../../define'; -import { apiLogger } from '../../../logger'; -import { ApiError } from '../../../error'; -import { DriveFiles } from '@/models/index'; - -export const meta = { - tags: ['drive'], - - requireCredential: true as const, - - limit: { - duration: ms('1hour'), - max: 120 - }, - - requireFile: true, - - kind: 'write:drive', - - params: { - folderId: { - validator: $.optional.nullable.type(ID), - default: null, - }, - - name: { - validator: $.optional.nullable.str, - default: null, - }, - - isSensitive: { - validator: $.optional.either($.bool, $.str), - default: false, - transform: (v: any): boolean => v === true || v === 'true', - }, - - force: { - validator: $.optional.either($.bool, $.str), - default: false, - transform: (v: any): boolean => v === true || v === 'true', - } - }, - - res: { - type: 'object' as const, - optional: false as const, nullable: false as const, - ref: 'DriveFile', - }, - - errors: { - invalidFileName: { - message: 'Invalid file name.', - code: 'INVALID_FILE_NAME', - id: 'f449b209-0c60-4e51-84d5-29486263bfd4' - } - } -}; - -export default define(meta, async (ps, user, _, file, cleanup) => { - // Get 'name' parameter - let name = ps.name || file.originalname; - if (name !== undefined && name !== null) { - name = name.trim(); - if (name.length === 0) { - name = null; - } else if (name === 'blob') { - name = null; - } else if (!DriveFiles.validateFileName(name)) { - throw new ApiError(meta.errors.invalidFileName); - } - } else { - name = null; - } - - try { - // Create file - const driveFile = await create(user, file.path, name, null, ps.folderId, ps.force, false, null, null, ps.isSensitive); - return await DriveFiles.pack(driveFile, { self: true }); - } catch (e) { - apiLogger.error(e); - throw new ApiError(); - } finally { - cleanup!(); - } -}); diff --git a/src/server/api/endpoints/drive/files/upload-from-url.ts b/src/server/api/endpoints/drive/files/upload-from-url.ts deleted file mode 100644 index 9f10a42d2..000000000 --- a/src/server/api/endpoints/drive/files/upload-from-url.ts +++ /dev/null @@ -1,64 +0,0 @@ -import $ from 'cafy'; -import { ID } from '@/misc/cafy-id'; -import * as ms from 'ms'; -import uploadFromUrl from '@/services/drive/upload-from-url'; -import define from '../../../define'; -import { DriveFiles } from '@/models/index'; -import { publishMainStream } from '@/services/stream'; -import { DB_MAX_IMAGE_COMMENT_LENGTH } from '@/misc/hard-limits'; - -export const meta = { - tags: ['drive'], - - limit: { - duration: ms('1hour'), - max: 60 - }, - - requireCredential: true as const, - - kind: 'write:drive', - - params: { - url: { - // TODO: Validate this url - validator: $.str, - }, - - folderId: { - validator: $.optional.nullable.type(ID), - default: null, - }, - - isSensitive: { - validator: $.optional.bool, - default: false, - }, - - comment: { - validator: $.optional.nullable.str.max(DB_MAX_IMAGE_COMMENT_LENGTH), - default: null, - }, - - marker: { - validator: $.optional.nullable.str, - default: null, - }, - - force: { - validator: $.optional.bool, - default: false, - } - } -}; - -export default define(meta, async (ps, user) => { - uploadFromUrl(ps.url, user, ps.folderId, null, ps.isSensitive, ps.force, false, ps.comment).then(file => { - DriveFiles.pack(file, { self: true }).then(packedFile => { - publishMainStream(user.id, 'urlUploadFinished', { - marker: ps.marker, - file: packedFile - }); - }); - }); -}); diff --git a/src/server/api/endpoints/email-address/available.ts b/src/server/api/endpoints/email-address/available.ts deleted file mode 100644 index 65fe6f917..000000000 --- a/src/server/api/endpoints/email-address/available.ts +++ /dev/null @@ -1,37 +0,0 @@ -import $ from 'cafy'; -import define from '../../define'; -import { UserProfiles } from '@/models/index'; - -export const meta = { - tags: ['users'], - - requireCredential: false as const, - - params: { - emailAddress: { - validator: $.str - } - }, - - res: { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - available: { - type: 'boolean' as const, - optional: false as const, nullable: false as const, - } - } - } -}; - -export default define(meta, async (ps) => { - const exist = await UserProfiles.count({ - emailVerified: true, - email: ps.emailAddress, - }); - - return { - available: exist === 0 - }; -}); diff --git a/src/server/api/endpoints/following/create.ts b/src/server/api/endpoints/following/create.ts deleted file mode 100644 index ba9ca1092..000000000 --- a/src/server/api/endpoints/following/create.ts +++ /dev/null @@ -1,100 +0,0 @@ -import $ from 'cafy'; -import { ID } from '@/misc/cafy-id'; -import * as ms from 'ms'; -import create from '@/services/following/create'; -import define from '../../define'; -import { ApiError } from '../../error'; -import { getUser } from '../../common/getters'; -import { Followings, Users } from '@/models/index'; - -export const meta = { - tags: ['following', 'users'], - - limit: { - duration: ms('1hour'), - max: 100 - }, - - requireCredential: true as const, - - kind: 'write:following', - - params: { - userId: { - validator: $.type(ID), - } - }, - - errors: { - noSuchUser: { - message: 'No such user.', - code: 'NO_SUCH_USER', - id: 'fcd2eef9-a9b2-4c4f-8624-038099e90aa5' - }, - - followeeIsYourself: { - message: 'Followee is yourself.', - code: 'FOLLOWEE_IS_YOURSELF', - id: '26fbe7bb-a331-4857-af17-205b426669a9' - }, - - alreadyFollowing: { - message: 'You are already following that user.', - code: 'ALREADY_FOLLOWING', - id: '35387507-38c7-4cb9-9197-300b93783fa0' - }, - - blocking: { - message: 'You are blocking that user.', - code: 'BLOCKING', - id: '4e2206ec-aa4f-4960-b865-6c23ac38e2d9' - }, - - blocked: { - message: 'You are blocked by that user.', - code: 'BLOCKED', - id: 'c4ab57cc-4e41-45e9-bfd9-584f61e35ce0' - }, - }, - - res: { - type: 'object' as const, - optional: false as const, nullable: false as const, - ref: 'User' - } -}; - -export default define(meta, async (ps, user) => { - const follower = user; - - // 自分自身 - if (user.id === ps.userId) { - throw new ApiError(meta.errors.followeeIsYourself); - } - - // Get followee - const followee = await getUser(ps.userId).catch(e => { - if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser); - throw e; - }); - - // Check if already following - const exist = await Followings.findOne({ - followerId: follower.id, - followeeId: followee.id - }); - - if (exist != null) { - throw new ApiError(meta.errors.alreadyFollowing); - } - - 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); - throw e; - } - - return await Users.pack(followee.id, user); -}); diff --git a/src/server/api/endpoints/following/delete.ts b/src/server/api/endpoints/following/delete.ts deleted file mode 100644 index 0b0158b86..000000000 --- a/src/server/api/endpoints/following/delete.ts +++ /dev/null @@ -1,82 +0,0 @@ -import $ from 'cafy'; -import { ID } from '@/misc/cafy-id'; -import * as ms from 'ms'; -import deleteFollowing from '@/services/following/delete'; -import define from '../../define'; -import { ApiError } from '../../error'; -import { getUser } from '../../common/getters'; -import { Followings, Users } from '@/models/index'; - -export const meta = { - tags: ['following', 'users'], - - limit: { - duration: ms('1hour'), - max: 100 - }, - - requireCredential: true as const, - - kind: 'write:following', - - params: { - userId: { - validator: $.type(ID), - } - }, - - errors: { - noSuchUser: { - message: 'No such user.', - code: 'NO_SUCH_USER', - id: '5b12c78d-2b28-4dca-99d2-f56139b42ff8' - }, - - followeeIsYourself: { - message: 'Followee is yourself.', - code: 'FOLLOWEE_IS_YOURSELF', - id: 'd9e400b9-36b0-4808-b1d8-79e707f1296c' - }, - - notFollowing: { - message: 'You are not following that user.', - code: 'NOT_FOLLOWING', - id: '5dbf82f5-c92b-40b1-87d1-6c8c0741fd09' - }, - }, - - res: { - type: 'object' as const, - optional: false as const, nullable: false as const, - ref: 'User' - } -}; - -export default define(meta, async (ps, user) => { - const follower = user; - - // Check if the followee is yourself - if (user.id === ps.userId) { - throw new ApiError(meta.errors.followeeIsYourself); - } - - // Get followee - const followee = await getUser(ps.userId).catch(e => { - if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser); - throw e; - }); - - // Check not following - const exist = await Followings.findOne({ - followerId: follower.id, - followeeId: followee.id - }); - - if (exist == null) { - throw new ApiError(meta.errors.notFollowing); - } - - await deleteFollowing(follower, followee); - - return await Users.pack(followee.id, user); -}); diff --git a/src/server/api/endpoints/gallery/posts/create.ts b/src/server/api/endpoints/gallery/posts/create.ts deleted file mode 100644 index 38b487e6e..000000000 --- a/src/server/api/endpoints/gallery/posts/create.ts +++ /dev/null @@ -1,77 +0,0 @@ -import $ from 'cafy'; -import * as ms from 'ms'; -import define from '../../../define'; -import { ID } from '../../../../../misc/cafy-id'; -import { DriveFiles, GalleryPosts } from '@/models/index'; -import { genId } from '../../../../../misc/gen-id'; -import { GalleryPost } from '@/models/entities/gallery-post'; -import { ApiError } from '../../../error'; -import { DriveFile } from '@/models/entities/drive-file'; - -export const meta = { - tags: ['gallery'], - - requireCredential: true as const, - - kind: 'write:gallery', - - limit: { - duration: ms('1hour'), - max: 300 - }, - - params: { - title: { - validator: $.str.min(1), - }, - - description: { - validator: $.optional.nullable.str, - }, - - fileIds: { - validator: $.arr($.type(ID)).unique().range(1, 32), - }, - - isSensitive: { - validator: $.optional.bool, - default: false, - }, - }, - - res: { - type: 'object' as const, - optional: false as const, nullable: false as const, - ref: 'GalleryPost', - }, - - errors: { - - } -}; - -export default define(meta, async (ps, user) => { - const files = (await Promise.all(ps.fileIds.map(fileId => - DriveFiles.findOne({ - id: fileId, - userId: user.id - }) - ))).filter((file): file is DriveFile => file != null); - - if (files.length === 0) { - throw new Error(); - } - - const post = await GalleryPosts.insert(new GalleryPost({ - id: genId(), - createdAt: new Date(), - updatedAt: new Date(), - title: ps.title, - description: ps.description, - userId: user.id, - isSensitive: ps.isSensitive, - fileIds: files.map(file => file.id) - })).then(x => GalleryPosts.findOneOrFail(x.identifiers[0])); - - return await GalleryPosts.pack(post, user); -}); diff --git a/src/server/api/endpoints/gallery/posts/update.ts b/src/server/api/endpoints/gallery/posts/update.ts deleted file mode 100644 index 54eea130d..000000000 --- a/src/server/api/endpoints/gallery/posts/update.ts +++ /dev/null @@ -1,82 +0,0 @@ -import $ from 'cafy'; -import * as ms from 'ms'; -import define from '../../../define'; -import { ID } from '../../../../../misc/cafy-id'; -import { DriveFiles, GalleryPosts } from '@/models/index'; -import { GalleryPost } from '@/models/entities/gallery-post'; -import { ApiError } from '../../../error'; -import { DriveFile } from '@/models/entities/drive-file'; - -export const meta = { - tags: ['gallery'], - - requireCredential: true as const, - - kind: 'write:gallery', - - limit: { - duration: ms('1hour'), - max: 300 - }, - - params: { - postId: { - validator: $.type(ID), - }, - - title: { - validator: $.str.min(1), - }, - - description: { - validator: $.optional.nullable.str, - }, - - fileIds: { - validator: $.arr($.type(ID)).unique().range(1, 32), - }, - - isSensitive: { - validator: $.optional.bool, - default: false, - }, - }, - - res: { - type: 'object' as const, - optional: false as const, nullable: false as const, - ref: 'GalleryPost', - }, - - errors: { - - } -}; - -export default define(meta, async (ps, user) => { - const files = (await Promise.all(ps.fileIds.map(fileId => - DriveFiles.findOne({ - id: fileId, - userId: user.id - }) - ))).filter((file): file is DriveFile => file != null); - - if (files.length === 0) { - throw new Error(); - } - - await GalleryPosts.update({ - id: ps.postId, - userId: user.id, - }, { - updatedAt: new Date(), - title: ps.title, - description: ps.description, - isSensitive: ps.isSensitive, - fileIds: files.map(file => file.id) - }); - - const post = await GalleryPosts.findOneOrFail(ps.postId); - - return await GalleryPosts.pack(post, user); -}); diff --git a/src/server/api/endpoints/i/2fa/key-done.ts b/src/server/api/endpoints/i/2fa/key-done.ts deleted file mode 100644 index b4d3af235..000000000 --- a/src/server/api/endpoints/i/2fa/key-done.ts +++ /dev/null @@ -1,150 +0,0 @@ -import $ from 'cafy'; -import * as bcrypt from 'bcryptjs'; -import { promisify } from 'util'; -import * as cbor from 'cbor'; -import define from '../../../define'; -import { - UserProfiles, - UserSecurityKeys, - AttestationChallenges, - Users -} from '@/models/index'; -import config from '@/config/index'; -import { procedures, hash } from '../../../2fa'; -import { publishMainStream } from '@/services/stream'; - -const cborDecodeFirst = promisify(cbor.decodeFirst) as any; - -export const meta = { - requireCredential: true as const, - - secure: true, - - params: { - clientDataJSON: { - validator: $.str - }, - attestationObject: { - validator: $.str - }, - password: { - validator: $.str - }, - challengeId: { - validator: $.str - }, - name: { - validator: $.str - } - } -}; - -const rpIdHashReal = hash(Buffer.from(config.hostname, 'utf-8')); - -export default define(meta, async (ps, user) => { - const profile = await UserProfiles.findOneOrFail(user.id); - - // Compare password - const same = await bcrypt.compare(ps.password, profile.password!); - - if (!same) { - throw new Error('incorrect password'); - } - - if (!profile.twoFactorEnabled) { - throw new Error('2fa not enabled'); - } - - const clientData = JSON.parse(ps.clientDataJSON); - - if (clientData.type != 'webauthn.create') { - throw new Error('not a creation attestation'); - } - if (clientData.origin != config.scheme + '://' + config.host) { - throw new Error('origin mismatch'); - } - - const clientDataJSONHash = hash(Buffer.from(ps.clientDataJSON, 'utf-8')); - - const attestation = await cborDecodeFirst(ps.attestationObject); - - const rpIdHash = attestation.authData.slice(0, 32); - if (!rpIdHashReal.equals(rpIdHash)) { - throw new Error('rpIdHash mismatch'); - } - - const flags = attestation.authData[32]; - - // tslint:disable-next-line:no-bitwise - if (!(flags & 1)) { - throw new Error('user not present'); - } - - const authData = Buffer.from(attestation.authData); - const credentialIdLength = authData.readUInt16BE(53); - const credentialId = authData.slice(55, 55 + credentialIdLength); - const publicKeyData = authData.slice(55 + credentialIdLength); - const publicKey: Map = await cborDecodeFirst(publicKeyData); - if (publicKey.get(3) != -7) { - throw new Error('alg mismatch'); - } - - if (!(procedures as any)[attestation.fmt]) { - throw new Error('unsupported fmt'); - } - - const verificationData = (procedures as any)[attestation.fmt].verify({ - attStmt: attestation.attStmt, - authenticatorData: authData, - clientDataHash: clientDataJSONHash, - credentialId, - publicKey, - rpIdHash - }); - if (!verificationData.valid) throw new Error('signature invalid'); - - const attestationChallenge = await AttestationChallenges.findOne({ - userId: user.id, - id: ps.challengeId, - registrationChallenge: true, - challenge: hash(clientData.challenge).toString('hex') - }); - - if (!attestationChallenge) { - throw new Error('non-existent challenge'); - } - - await AttestationChallenges.delete({ - userId: user.id, - id: ps.challengeId - }); - - // Expired challenge (> 5min old) - if ( - new Date().getTime() - attestationChallenge.createdAt.getTime() >= - 5 * 60 * 1000 - ) { - throw new Error('expired challenge'); - } - - const credentialIdString = credentialId.toString('hex'); - - await UserSecurityKeys.save({ - userId: user.id, - id: credentialIdString, - lastUsed: new Date(), - name: ps.name, - publicKey: verificationData.publicKey.toString('hex') - }); - - // Publish meUpdated event - publishMainStream(user.id, 'meUpdated', await Users.pack(user.id, user, { - detail: true, - includeSecrets: true - })); - - return { - id: credentialIdString, - name: ps.name - }; -}); diff --git a/src/server/api/endpoints/i/export-blocking.ts b/src/server/api/endpoints/i/export-blocking.ts deleted file mode 100644 index e4797da0c..000000000 --- a/src/server/api/endpoints/i/export-blocking.ts +++ /dev/null @@ -1,16 +0,0 @@ -import define from '../../define'; -import { createExportBlockingJob } from '@/queue/index'; -import * as ms from 'ms'; - -export const meta = { - secure: true, - requireCredential: true as const, - limit: { - duration: ms('1hour'), - max: 1, - }, -}; - -export default define(meta, async (ps, user) => { - createExportBlockingJob(user); -}); diff --git a/src/server/api/endpoints/i/export-following.ts b/src/server/api/endpoints/i/export-following.ts deleted file mode 100644 index b0f154cda..000000000 --- a/src/server/api/endpoints/i/export-following.ts +++ /dev/null @@ -1,16 +0,0 @@ -import define from '../../define'; -import { createExportFollowingJob } from '@/queue/index'; -import * as ms from 'ms'; - -export const meta = { - secure: true, - requireCredential: true as const, - limit: { - duration: ms('1hour'), - max: 1, - }, -}; - -export default define(meta, async (ps, user) => { - createExportFollowingJob(user); -}); diff --git a/src/server/api/endpoints/i/export-mute.ts b/src/server/api/endpoints/i/export-mute.ts deleted file mode 100644 index 46d547fa5..000000000 --- a/src/server/api/endpoints/i/export-mute.ts +++ /dev/null @@ -1,16 +0,0 @@ -import define from '../../define'; -import { createExportMuteJob } from '@/queue/index'; -import * as ms from 'ms'; - -export const meta = { - secure: true, - requireCredential: true as const, - limit: { - duration: ms('1hour'), - max: 1, - }, -}; - -export default define(meta, async (ps, user) => { - createExportMuteJob(user); -}); diff --git a/src/server/api/endpoints/i/export-notes.ts b/src/server/api/endpoints/i/export-notes.ts deleted file mode 100644 index 441bf1689..000000000 --- a/src/server/api/endpoints/i/export-notes.ts +++ /dev/null @@ -1,16 +0,0 @@ -import define from '../../define'; -import { createExportNotesJob } from '@/queue/index'; -import * as ms from 'ms'; - -export const meta = { - secure: true, - requireCredential: true as const, - limit: { - duration: ms('1day'), - max: 1, - }, -}; - -export default define(meta, async (ps, user) => { - createExportNotesJob(user); -}); diff --git a/src/server/api/endpoints/i/export-user-lists.ts b/src/server/api/endpoints/i/export-user-lists.ts deleted file mode 100644 index 24043a862..000000000 --- a/src/server/api/endpoints/i/export-user-lists.ts +++ /dev/null @@ -1,16 +0,0 @@ -import define from '../../define'; -import { createExportUserListsJob } from '@/queue/index'; -import * as ms from 'ms'; - -export const meta = { - secure: true, - requireCredential: true as const, - limit: { - duration: ms('1min'), - max: 1, - }, -}; - -export default define(meta, async (ps, user) => { - createExportUserListsJob(user); -}); diff --git a/src/server/api/endpoints/i/import-blocking.ts b/src/server/api/endpoints/i/import-blocking.ts deleted file mode 100644 index d44d0b607..000000000 --- a/src/server/api/endpoints/i/import-blocking.ts +++ /dev/null @@ -1,60 +0,0 @@ -import $ from 'cafy'; -import { ID } from '@/misc/cafy-id'; -import define from '../../define'; -import { createImportBlockingJob } from '@/queue/index'; -import * as ms from 'ms'; -import { ApiError } from '../../error'; -import { DriveFiles } from '@/models/index'; - -export const meta = { - secure: true, - requireCredential: true as const, - - limit: { - duration: ms('1hour'), - max: 1, - }, - - params: { - fileId: { - validator: $.type(ID), - } - }, - - errors: { - noSuchFile: { - message: 'No such file.', - code: 'NO_SUCH_FILE', - id: 'ebb53e5f-6574-9c0c-0b92-7ca6def56d7e' - }, - - unexpectedFileType: { - message: 'We need csv file.', - code: 'UNEXPECTED_FILE_TYPE', - id: 'b6fab7d6-d945-d67c-dfdb-32da1cd12cfe' - }, - - tooBigFile: { - message: 'That file is too big.', - code: 'TOO_BIG_FILE', - id: 'b7fbf0b1-aeef-3b21-29ef-fadd4cb72ccf' - }, - - emptyFile: { - message: 'That file is empty.', - code: 'EMPTY_FILE', - id: '6f3a4dcc-f060-a707-4950-806fbdbe60d6' - }, - } -}; - -export default define(meta, async (ps, user) => { - const file = await DriveFiles.findOne(ps.fileId); - - if (file == null) throw new ApiError(meta.errors.noSuchFile); - //if (!file.type.endsWith('/csv')) throw new ApiError(meta.errors.unexpectedFileType); - if (file.size > 50000) throw new ApiError(meta.errors.tooBigFile); - if (file.size === 0) throw new ApiError(meta.errors.emptyFile); - - createImportBlockingJob(user, file.id); -}); diff --git a/src/server/api/endpoints/i/import-following.ts b/src/server/api/endpoints/i/import-following.ts deleted file mode 100644 index b3de39766..000000000 --- a/src/server/api/endpoints/i/import-following.ts +++ /dev/null @@ -1,59 +0,0 @@ -import $ from 'cafy'; -import { ID } from '@/misc/cafy-id'; -import define from '../../define'; -import { createImportFollowingJob } from '@/queue/index'; -import * as ms from 'ms'; -import { ApiError } from '../../error'; -import { DriveFiles } from '@/models/index'; - -export const meta = { - secure: true, - requireCredential: true as const, - limit: { - duration: ms('1hour'), - max: 1, - }, - - params: { - fileId: { - validator: $.type(ID), - } - }, - - errors: { - noSuchFile: { - message: 'No such file.', - code: 'NO_SUCH_FILE', - id: 'b98644cf-a5ac-4277-a502-0b8054a709a3' - }, - - unexpectedFileType: { - message: 'We need csv file.', - code: 'UNEXPECTED_FILE_TYPE', - id: '660f3599-bce0-4f95-9dde-311fd841c183' - }, - - tooBigFile: { - message: 'That file is too big.', - code: 'TOO_BIG_FILE', - id: 'dee9d4ed-ad07-43ed-8b34-b2856398bc60' - }, - - emptyFile: { - message: 'That file is empty.', - code: 'EMPTY_FILE', - id: '31a1b42c-06f7-42ae-8a38-a661c5c9f691' - }, - } -}; - -export default define(meta, async (ps, user) => { - const file = await DriveFiles.findOne(ps.fileId); - - if (file == null) throw new ApiError(meta.errors.noSuchFile); - //if (!file.type.endsWith('/csv')) throw new ApiError(meta.errors.unexpectedFileType); - if (file.size > 50000) throw new ApiError(meta.errors.tooBigFile); - if (file.size === 0) throw new ApiError(meta.errors.emptyFile); - - createImportFollowingJob(user, file.id); -}); diff --git a/src/server/api/endpoints/i/import-muting.ts b/src/server/api/endpoints/i/import-muting.ts deleted file mode 100644 index c17434c58..000000000 --- a/src/server/api/endpoints/i/import-muting.ts +++ /dev/null @@ -1,60 +0,0 @@ -import $ from 'cafy'; -import { ID } from '@/misc/cafy-id'; -import define from '../../define'; -import { createImportMutingJob } from '@/queue/index'; -import * as ms from 'ms'; -import { ApiError } from '../../error'; -import { DriveFiles } from '@/models/index'; - -export const meta = { - secure: true, - requireCredential: true as const, - - limit: { - duration: ms('1hour'), - max: 1, - }, - - params: { - fileId: { - validator: $.type(ID), - } - }, - - errors: { - noSuchFile: { - message: 'No such file.', - code: 'NO_SUCH_FILE', - id: 'e674141e-bd2a-ba85-e616-aefb187c9c2a' - }, - - unexpectedFileType: { - message: 'We need csv file.', - code: 'UNEXPECTED_FILE_TYPE', - id: '568c6e42-c86c-ba09-c004-517f83f9f1a8' - }, - - tooBigFile: { - message: 'That file is too big.', - code: 'TOO_BIG_FILE', - id: '9b4ada6d-d7f7-0472-0713-4f558bd1ec9c' - }, - - emptyFile: { - message: 'That file is empty.', - code: 'EMPTY_FILE', - id: 'd2f12af1-e7b4-feac-86a3-519548f2728e' - }, - } -}; - -export default define(meta, async (ps, user) => { - const file = await DriveFiles.findOne(ps.fileId); - - if (file == null) throw new ApiError(meta.errors.noSuchFile); - //if (!file.type.endsWith('/csv')) throw new ApiError(meta.errors.unexpectedFileType); - if (file.size > 50000) throw new ApiError(meta.errors.tooBigFile); - if (file.size === 0) throw new ApiError(meta.errors.emptyFile); - - createImportMutingJob(user, file.id); -}); diff --git a/src/server/api/endpoints/i/import-user-lists.ts b/src/server/api/endpoints/i/import-user-lists.ts deleted file mode 100644 index 9069a019a..000000000 --- a/src/server/api/endpoints/i/import-user-lists.ts +++ /dev/null @@ -1,59 +0,0 @@ -import $ from 'cafy'; -import { ID } from '@/misc/cafy-id'; -import define from '../../define'; -import { createImportUserListsJob } from '@/queue/index'; -import * as ms from 'ms'; -import { ApiError } from '../../error'; -import { DriveFiles } from '@/models/index'; - -export const meta = { - secure: true, - requireCredential: true as const, - limit: { - duration: ms('1hour'), - max: 1, - }, - - params: { - fileId: { - validator: $.type(ID), - } - }, - - errors: { - noSuchFile: { - message: 'No such file.', - code: 'NO_SUCH_FILE', - id: 'ea9cc34f-c415-4bc6-a6fe-28ac40357049' - }, - - unexpectedFileType: { - message: 'We need csv file.', - code: 'UNEXPECTED_FILE_TYPE', - id: 'a3c9edda-dd9b-4596-be6a-150ef813745c' - }, - - tooBigFile: { - message: 'That file is too big.', - code: 'TOO_BIG_FILE', - id: 'ae6e7a22-971b-4b52-b2be-fc0b9b121fe9' - }, - - emptyFile: { - message: 'That file is empty.', - code: 'EMPTY_FILE', - id: '99efe367-ce6e-4d44-93f8-5fae7b040356' - }, - } -}; - -export default define(meta, async (ps, user) => { - const file = await DriveFiles.findOne(ps.fileId); - - if (file == null) throw new ApiError(meta.errors.noSuchFile); - //if (!file.type.endsWith('/csv')) throw new ApiError(meta.errors.unexpectedFileType); - if (file.size > 30000) throw new ApiError(meta.errors.tooBigFile); - if (file.size === 0) throw new ApiError(meta.errors.emptyFile); - - createImportUserListsJob(user, file.id); -}); diff --git a/src/server/api/endpoints/i/update-email.ts b/src/server/api/endpoints/i/update-email.ts deleted file mode 100644 index 14aedad88..000000000 --- a/src/server/api/endpoints/i/update-email.ts +++ /dev/null @@ -1,80 +0,0 @@ -import $ from 'cafy'; -import { publishMainStream } from '@/services/stream'; -import define from '../../define'; -import rndstr from 'rndstr'; -import config from '@/config/index'; -import * as ms from 'ms'; -import * as bcrypt from 'bcryptjs'; -import { Users, UserProfiles } from '@/models/index'; -import { sendEmail } from '@/services/send-email'; -import { ApiError } from '../../error'; - -export const meta = { - requireCredential: true as const, - - secure: true, - - limit: { - duration: ms('1hour'), - max: 3 - }, - - params: { - password: { - validator: $.str - }, - - email: { - validator: $.optional.nullable.str - }, - }, - - errors: { - incorrectPassword: { - message: 'Incorrect password.', - code: 'INCORRECT_PASSWORD', - id: 'e54c1d7e-e7d6-4103-86b6-0a95069b4ad3' - }, - } -}; - -export default define(meta, async (ps, user) => { - const profile = await UserProfiles.findOneOrFail(user.id); - - // Compare password - const same = await bcrypt.compare(ps.password, profile.password!); - - if (!same) { - throw new ApiError(meta.errors.incorrectPassword); - } - - await UserProfiles.update(user.id, { - email: ps.email, - emailVerified: false, - emailVerifyCode: null - }); - - const iObj = await Users.pack(user.id, user, { - detail: true, - includeSecrets: true - }); - - // Publish meUpdated event - publishMainStream(user.id, 'meUpdated', iObj); - - if (ps.email != null) { - const code = rndstr('a-z0-9', 16); - - await UserProfiles.update(user.id, { - emailVerifyCode: code - }); - - const link = `${config.url}/verify-email/${code}`; - - sendEmail(ps.email, 'Email verification', - `To verify email, please click this link:
${link}`, - `To verify email, please click this link: ${link}`); - } - - return iObj; -}); diff --git a/src/server/api/endpoints/i/update.ts b/src/server/api/endpoints/i/update.ts deleted file mode 100644 index 3b8b1579e..000000000 --- a/src/server/api/endpoints/i/update.ts +++ /dev/null @@ -1,289 +0,0 @@ -import $ from 'cafy'; -import * as mfm from 'mfm-js'; -import { ID } from '@/misc/cafy-id'; -import { publishMainStream, publishUserEvent } from '@/services/stream'; -import acceptAllFollowRequests from '@/services/following/requests/accept-all'; -import { publishToFollowers } from '@/services/i/update'; -import define from '../../define'; -import { extractCustomEmojisFromMfm } from '@/misc/extract-custom-emojis-from-mfm'; -import { extractHashtags } from '@/misc/extract-hashtags'; -import * as langmap from 'langmap'; -import { updateUsertags } from '@/services/update-hashtag'; -import { ApiError } from '../../error'; -import { Users, DriveFiles, UserProfiles, Pages } from '@/models/index'; -import { User } from '@/models/entities/user'; -import { UserProfile } from '@/models/entities/user-profile'; -import { notificationTypes } from '@/types'; -import { normalizeForSearch } from '@/misc/normalize-for-search'; - -export const meta = { - tags: ['account'], - - requireCredential: true as const, - - kind: 'write:account', - - params: { - name: { - validator: $.optional.nullable.use(Users.validateName), - }, - - description: { - validator: $.optional.nullable.use(Users.validateDescription), - }, - - lang: { - validator: $.optional.nullable.str.or(Object.keys(langmap)), - }, - - location: { - validator: $.optional.nullable.use(Users.validateLocation), - }, - - birthday: { - validator: $.optional.nullable.use(Users.validateBirthday), - }, - - avatarId: { - validator: $.optional.nullable.type(ID), - }, - - bannerId: { - validator: $.optional.nullable.type(ID), - }, - - fields: { - validator: $.optional.arr($.object()).range(1, 4), - }, - - isLocked: { - validator: $.optional.bool, - }, - - isExplorable: { - validator: $.optional.bool, - }, - - hideOnlineStatus: { - validator: $.optional.bool, - }, - - publicReactions: { - validator: $.optional.bool, - }, - - carefulBot: { - validator: $.optional.bool, - }, - - autoAcceptFollowed: { - validator: $.optional.bool, - }, - - noCrawle: { - validator: $.optional.bool, - }, - - isBot: { - validator: $.optional.bool, - }, - - isCat: { - validator: $.optional.bool, - }, - - injectFeaturedNote: { - validator: $.optional.bool, - }, - - receiveAnnouncementEmail: { - validator: $.optional.bool, - }, - - alwaysMarkNsfw: { - validator: $.optional.bool, - }, - - pinnedPageId: { - validator: $.optional.nullable.type(ID), - }, - - mutedWords: { - validator: $.optional.arr($.arr($.str)) - }, - - mutingNotificationTypes: { - validator: $.optional.arr($.str.or(notificationTypes as unknown as string[])) - }, - - emailNotificationTypes: { - validator: $.optional.arr($.str) - }, - }, - - errors: { - noSuchAvatar: { - message: 'No such avatar file.', - code: 'NO_SUCH_AVATAR', - id: '539f3a45-f215-4f81-a9a8-31293640207f' - }, - - noSuchBanner: { - message: 'No such banner file.', - code: 'NO_SUCH_BANNER', - id: '0d8f5629-f210-41c2-9433-735831a58595' - }, - - avatarNotAnImage: { - message: 'The file specified as an avatar is not an image.', - code: 'AVATAR_NOT_AN_IMAGE', - id: 'f419f9f8-2f4d-46b1-9fb4-49d3a2fd7191' - }, - - bannerNotAnImage: { - message: 'The file specified as a banner is not an image.', - code: 'BANNER_NOT_AN_IMAGE', - id: '75aedb19-2afd-4e6d-87fc-67941256fa60' - }, - - noSuchPage: { - message: 'No such page.', - code: 'NO_SUCH_PAGE', - id: '8e01b590-7eb9-431b-a239-860e086c408e' - }, - }, - - res: { - type: 'object' as const, - optional: false as const, nullable: false as const, - ref: 'User' - } -}; - -export default define(meta, async (ps, _user, token) => { - const user = await Users.findOneOrFail(_user.id); - const isSecure = token == null; - - const updates = {} as Partial; - const profileUpdates = {} as Partial; - - const profile = await UserProfiles.findOneOrFail(user.id); - - if (ps.name !== undefined) updates.name = ps.name; - if (ps.description !== undefined) profileUpdates.description = ps.description; - if (ps.lang !== undefined) profileUpdates.lang = ps.lang; - if (ps.location !== undefined) profileUpdates.location = ps.location; - if (ps.birthday !== undefined) profileUpdates.birthday = ps.birthday; - if (ps.avatarId !== undefined) updates.avatarId = ps.avatarId; - if (ps.bannerId !== undefined) updates.bannerId = ps.bannerId; - if (ps.mutedWords !== undefined) { - profileUpdates.mutedWords = ps.mutedWords; - profileUpdates.enableWordMute = ps.mutedWords.length > 0; - } - if (ps.mutingNotificationTypes !== undefined) profileUpdates.mutingNotificationTypes = ps.mutingNotificationTypes as typeof notificationTypes[number][]; - if (typeof ps.isLocked === 'boolean') updates.isLocked = ps.isLocked; - if (typeof ps.isExplorable === 'boolean') updates.isExplorable = ps.isExplorable; - 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.carefulBot === 'boolean') profileUpdates.carefulBot = ps.carefulBot; - if (typeof ps.autoAcceptFollowed === 'boolean') profileUpdates.autoAcceptFollowed = ps.autoAcceptFollowed; - if (typeof ps.noCrawle === 'boolean') profileUpdates.noCrawle = ps.noCrawle; - if (typeof ps.isCat === 'boolean') updates.isCat = ps.isCat; - if (typeof ps.injectFeaturedNote === 'boolean') profileUpdates.injectFeaturedNote = ps.injectFeaturedNote; - if (typeof ps.receiveAnnouncementEmail === 'boolean') profileUpdates.receiveAnnouncementEmail = ps.receiveAnnouncementEmail; - if (typeof ps.alwaysMarkNsfw === 'boolean') profileUpdates.alwaysMarkNsfw = ps.alwaysMarkNsfw; - if (ps.emailNotificationTypes !== undefined) profileUpdates.emailNotificationTypes = ps.emailNotificationTypes; - - if (ps.avatarId) { - const avatar = await DriveFiles.findOne(ps.avatarId); - - if (avatar == null || avatar.userId !== user.id) throw new ApiError(meta.errors.noSuchAvatar); - if (!avatar.type.startsWith('image/')) throw new ApiError(meta.errors.avatarNotAnImage); - - updates.avatarUrl = DriveFiles.getPublicUrl(avatar, true); - - if (avatar.blurhash) { - updates.avatarBlurhash = avatar.blurhash; - } - } - - if (ps.bannerId) { - const banner = await DriveFiles.findOne(ps.bannerId); - - if (banner == null || banner.userId !== user.id) throw new ApiError(meta.errors.noSuchBanner); - if (!banner.type.startsWith('image/')) throw new ApiError(meta.errors.bannerNotAnImage); - - updates.bannerUrl = DriveFiles.getPublicUrl(banner, false); - - if (banner.blurhash) { - updates.bannerBlurhash = banner.blurhash; - } - } - - if (ps.pinnedPageId) { - const page = await Pages.findOne(ps.pinnedPageId); - - if (page == null || page.userId !== user.id) throw new ApiError(meta.errors.noSuchPage); - - profileUpdates.pinnedPageId = page.id; - } else if (ps.pinnedPageId === null) { - profileUpdates.pinnedPageId = null; - } - - if (ps.fields) { - profileUpdates.fields = ps.fields - .filter(x => typeof x.name === 'string' && x.name !== '' && typeof x.value === 'string' && x.value !== '') - .map(x => { - return { name: x.name, value: x.value }; - }); - } - - //#region emojis/tags - - let emojis = [] as string[]; - let tags = [] as string[]; - - const newName = updates.name === undefined ? user.name : updates.name; - const newDescription = profileUpdates.description === undefined ? profile.description : profileUpdates.description; - - if (newName != null) { - const tokens = mfm.parsePlain(newName); - emojis = emojis.concat(extractCustomEmojisFromMfm(tokens!)); - } - - if (newDescription != null) { - const tokens = mfm.parse(newDescription); - emojis = emojis.concat(extractCustomEmojisFromMfm(tokens!)); - tags = extractHashtags(tokens!).map(tag => normalizeForSearch(tag)).splice(0, 32); - } - - updates.emojis = emojis; - updates.tags = tags; - - // ハッシュタグ更新 - updateUsertags(user, tags); - //#endregion - - if (Object.keys(updates).length > 0) await Users.update(user.id, updates); - if (Object.keys(profileUpdates).length > 0) await UserProfiles.update(user.id, profileUpdates); - - const iObj = await Users.pack(user.id, user, { - detail: true, - includeSecrets: isSecure - }); - - // Publish meUpdated event - publishMainStream(user.id, 'meUpdated', iObj); - publishUserEvent(user.id, 'updateUserProfile', await UserProfiles.findOne(user.id)); - - // 鍵垢を解除したとき、溜まっていたフォローリクエストがあるならすべて承認 - if (user.isLocked && ps.isLocked === false) { - acceptAllFollowRequests(user); - } - - // フォロワーにUpdateを配信 - publishToFollowers(user.id); - - return iObj; -}); diff --git a/src/server/api/endpoints/messaging/messages/delete.ts b/src/server/api/endpoints/messaging/messages/delete.ts deleted file mode 100644 index bd4890fc8..000000000 --- a/src/server/api/endpoints/messaging/messages/delete.ts +++ /dev/null @@ -1,48 +0,0 @@ -import $ from 'cafy'; -import { ID } from '@/misc/cafy-id'; -import define from '../../../define'; -import * as ms from 'ms'; -import { ApiError } from '../../../error'; -import { MessagingMessages } from '@/models/index'; -import { deleteMessage } from '@/services/messages/delete'; - -export const meta = { - tags: ['messaging'], - - requireCredential: true as const, - - kind: 'write:messaging', - - limit: { - duration: ms('1hour'), - max: 300, - minInterval: ms('1sec') - }, - - params: { - messageId: { - validator: $.type(ID), - } - }, - - errors: { - noSuchMessage: { - message: 'No such message.', - code: 'NO_SUCH_MESSAGE', - id: '54b5b326-7925-42cf-8019-130fda8b56af' - }, - } -}; - -export default define(meta, async (ps, user) => { - const message = await MessagingMessages.findOne({ - id: ps.messageId, - userId: user.id - }); - - if (message == null) { - throw new ApiError(meta.errors.noSuchMessage); - } - - await deleteMessage(message); -}); diff --git a/src/server/api/endpoints/notes/create.ts b/src/server/api/endpoints/notes/create.ts deleted file mode 100644 index 751673f95..000000000 --- a/src/server/api/endpoints/notes/create.ts +++ /dev/null @@ -1,299 +0,0 @@ -import $ from 'cafy'; -import * as ms from 'ms'; -import { length } from 'stringz'; -import create from '@/services/note/create'; -import define from '../../define'; -import { fetchMeta } from '@/misc/fetch-meta'; -import { ApiError } from '../../error'; -import { ID } from '@/misc/cafy-id'; -import { User } from '@/models/entities/user'; -import { Users, DriveFiles, Notes, Channels, Blockings } from '@/models/index'; -import { DriveFile } from '@/models/entities/drive-file'; -import { Note } from '@/models/entities/note'; -import { DB_MAX_NOTE_TEXT_LENGTH } from '@/misc/hard-limits'; -import { noteVisibilities } from '../../../../types'; -import { Channel } from '@/models/entities/channel'; - -let maxNoteTextLength = 500; - -setInterval(() => { - fetchMeta().then(m => { - maxNoteTextLength = m.maxNoteTextLength; - }); -}, 3000); - -export const meta = { - tags: ['notes'], - - requireCredential: true as const, - - limit: { - duration: ms('1hour'), - max: 300 - }, - - kind: 'write:notes', - - params: { - visibility: { - validator: $.optional.str.or(noteVisibilities as unknown as string[]), - default: 'public', - }, - - visibleUserIds: { - validator: $.optional.arr($.type(ID)).unique().min(0), - }, - - text: { - validator: $.optional.nullable.str.pipe(text => - text.trim() != '' - && length(text.trim()) <= maxNoteTextLength - && Array.from(text.trim()).length <= DB_MAX_NOTE_TEXT_LENGTH // DB limit - ), - default: null, - }, - - cw: { - validator: $.optional.nullable.str.pipe(Notes.validateCw), - }, - - viaMobile: { - validator: $.optional.bool, - default: false, - }, - - localOnly: { - validator: $.optional.bool, - default: false, - }, - - noExtractMentions: { - validator: $.optional.bool, - default: false, - }, - - noExtractHashtags: { - validator: $.optional.bool, - default: false, - }, - - noExtractEmojis: { - validator: $.optional.bool, - default: false, - }, - - fileIds: { - validator: $.optional.arr($.type(ID)).unique().range(1, 4), - }, - - mediaIds: { - validator: $.optional.arr($.type(ID)).unique().range(1, 4), - deprecated: true, - }, - - replyId: { - validator: $.optional.nullable.type(ID), - }, - - renoteId: { - validator: $.optional.nullable.type(ID), - }, - - channelId: { - validator: $.optional.nullable.type(ID), - }, - - poll: { - validator: $.optional.nullable.obj({ - choices: $.arr($.str) - .unique() - .range(2, 10) - .each(c => c.length > 0 && c.length < 50), - multiple: $.optional.bool, - expiresAt: $.optional.nullable.num.int(), - expiredAfter: $.optional.nullable.num.int().min(1) - }).strict(), - ref: 'poll' - } - }, - - res: { - type: 'object' as const, - optional: false as const, nullable: false as const, - properties: { - createdNote: { - type: 'object' as const, - optional: false as const, nullable: false as const, - ref: 'Note', - } - } - }, - - errors: { - noSuchRenoteTarget: { - message: 'No such renote target.', - code: 'NO_SUCH_RENOTE_TARGET', - id: 'b5c90186-4ab0-49c8-9bba-a1f76c282ba4' - }, - - cannotReRenote: { - message: 'You can not Renote a pure Renote.', - code: 'CANNOT_RENOTE_TO_A_PURE_RENOTE', - id: 'fd4cc33e-2a37-48dd-99cc-9b806eb2031a' - }, - - noSuchReplyTarget: { - message: 'No such reply target.', - code: 'NO_SUCH_REPLY_TARGET', - id: '749ee0f6-d3da-459a-bf02-282e2da4292c' - }, - - cannotReplyToPureRenote: { - message: 'You can not reply to a pure Renote.', - code: 'CANNOT_REPLY_TO_A_PURE_RENOTE', - id: '3ac74a84-8fd5-4bb0-870f-01804f82ce15' - }, - - contentRequired: { - message: 'Content required. You need to set text, fileIds, renoteId or poll.', - code: 'CONTENT_REQUIRED', - id: '6f57e42b-c348-439b-bc45-993995cc515a' - }, - - cannotCreateAlreadyExpiredPoll: { - message: 'Poll is already expired.', - code: 'CANNOT_CREATE_ALREADY_EXPIRED_POLL', - id: '04da457d-b083-4055-9082-955525eda5a5' - }, - - noSuchChannel: { - message: 'No such channel.', - code: 'NO_SUCH_CHANNEL', - id: 'b1653923-5453-4edc-b786-7c4f39bb0bbb' - }, - - youHaveBeenBlocked: { - message: 'You have been blocked by this user.', - code: 'YOU_HAVE_BEEN_BLOCKED', - id: 'b390d7e1-8a5e-46ed-b625-06271cafd3d3' - }, - } -}; - -export default define(meta, async (ps, user) => { - let visibleUsers: User[] = []; - if (ps.visibleUserIds) { - visibleUsers = (await Promise.all(ps.visibleUserIds.map(id => Users.findOne(id)))) - .filter(x => x != null) as User[]; - } - - let files: DriveFile[] = []; - const fileIds = ps.fileIds != null ? ps.fileIds : ps.mediaIds != null ? ps.mediaIds : null; - if (fileIds != null) { - files = (await Promise.all(fileIds.map(fileId => - DriveFiles.findOne({ - id: fileId, - userId: user.id - }) - ))).filter(file => file != null) as DriveFile[]; - } - - let renote: Note | undefined; - if (ps.renoteId != null) { - // Fetch renote to note - renote = await Notes.findOne(ps.renoteId); - - if (renote == null) { - throw new ApiError(meta.errors.noSuchRenoteTarget); - } else if (renote.renoteId && !renote.text && !renote.fileIds) { - throw new ApiError(meta.errors.cannotReRenote); - } - - // Check blocking - if (renote.userId !== user.id) { - const block = await Blockings.findOne({ - blockerId: renote.userId, - blockeeId: user.id, - }); - if (block) { - throw new ApiError(meta.errors.youHaveBeenBlocked); - } - } - } - - let reply: Note | undefined; - if (ps.replyId != null) { - // Fetch reply - reply = await Notes.findOne(ps.replyId); - - if (reply == null) { - throw new ApiError(meta.errors.noSuchReplyTarget); - } - - // 返信対象が引用でないRenoteだったらエラー - if (reply.renoteId && !reply.text && !reply.fileIds) { - throw new ApiError(meta.errors.cannotReplyToPureRenote); - } - - // Check blocking - if (reply.userId !== user.id) { - const block = await Blockings.findOne({ - blockerId: reply.userId, - blockeeId: user.id, - }); - if (block) { - throw new ApiError(meta.errors.youHaveBeenBlocked); - } - } - } - - if (ps.poll) { - if (typeof ps.poll.expiresAt === 'number') { - if (ps.poll.expiresAt < Date.now()) - throw new ApiError(meta.errors.cannotCreateAlreadyExpiredPoll); - } else if (typeof ps.poll.expiredAfter === 'number') { - ps.poll.expiresAt = Date.now() + ps.poll.expiredAfter; - } - } - - // テキストが無いかつ添付ファイルが無いかつRenoteも無いかつ投票も無かったらエラー - if (!(ps.text || files.length || renote || ps.poll)) { - throw new ApiError(meta.errors.contentRequired); - } - - let channel: Channel | undefined; - if (ps.channelId != null) { - channel = await Channels.findOne(ps.channelId); - - if (channel == null) { - throw new ApiError(meta.errors.noSuchChannel); - } - } - - // 投稿を作成 - const note = await create(user, { - createdAt: new Date(), - files: files, - poll: ps.poll ? { - choices: ps.poll.choices, - multiple: ps.poll.multiple || false, - expiresAt: ps.poll.expiresAt ? new Date(ps.poll.expiresAt) : null - } : undefined, - text: ps.text || undefined, - reply, - renote, - cw: ps.cw, - viaMobile: ps.viaMobile, - localOnly: ps.localOnly, - visibility: ps.visibility, - visibleUsers, - channel, - apMentions: ps.noExtractMentions ? [] : undefined, - apHashtags: ps.noExtractHashtags ? [] : undefined, - apEmojis: ps.noExtractEmojis ? [] : undefined, - }); - - return { - createdNote: await Notes.pack(note, user) - }; -}); diff --git a/src/server/api/endpoints/notes/delete.ts b/src/server/api/endpoints/notes/delete.ts deleted file mode 100644 index 7163a2b9d..000000000 --- a/src/server/api/endpoints/notes/delete.ts +++ /dev/null @@ -1,56 +0,0 @@ -import $ from 'cafy'; -import { ID } from '@/misc/cafy-id'; -import deleteNote from '@/services/note/delete'; -import define from '../../define'; -import * as ms from 'ms'; -import { getNote } from '../../common/getters'; -import { ApiError } from '../../error'; -import { Users } from '@/models/index'; - -export const meta = { - tags: ['notes'], - - requireCredential: true as const, - - kind: 'write:notes', - - limit: { - duration: ms('1hour'), - max: 300, - minInterval: ms('1sec') - }, - - params: { - noteId: { - validator: $.type(ID), - } - }, - - errors: { - noSuchNote: { - message: 'No such note.', - code: 'NO_SUCH_NOTE', - id: '490be23f-8c1f-4796-819f-94cb4f9d1630' - }, - - accessDenied: { - message: 'Access denied.', - code: 'ACCESS_DENIED', - id: 'fe8d7103-0ea8-4ec3-814d-f8b401dc69e9' - } - } -}; - -export default define(meta, async (ps, user) => { - const note = await getNote(ps.noteId).catch(e => { - if (e.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote); - throw e; - }); - - if (!user.isAdmin && !user.isModerator && (note.userId !== user.id)) { - throw new ApiError(meta.errors.accessDenied); - } - - // この操作を行うのが投稿者とは限らない(例えばモデレーター)ため - await deleteNote(await Users.findOneOrFail(note.userId), note); -}); diff --git a/src/server/api/endpoints/notes/reactions/delete.ts b/src/server/api/endpoints/notes/reactions/delete.ts deleted file mode 100644 index 69550f96d..000000000 --- a/src/server/api/endpoints/notes/reactions/delete.ts +++ /dev/null @@ -1,52 +0,0 @@ -import $ from 'cafy'; -import { ID } from '@/misc/cafy-id'; -import define from '../../../define'; -import * as ms from 'ms'; -import deleteReaction from '@/services/note/reaction/delete'; -import { getNote } from '../../../common/getters'; -import { ApiError } from '../../../error'; - -export const meta = { - tags: ['reactions', 'notes'], - - requireCredential: true as const, - - kind: 'write:reactions', - - limit: { - duration: ms('1hour'), - max: 60, - minInterval: ms('3sec') - }, - - params: { - noteId: { - validator: $.type(ID), - }, - }, - - errors: { - noSuchNote: { - message: 'No such note.', - code: 'NO_SUCH_NOTE', - id: '764d9fce-f9f2-4a0e-92b1-6ceac9a7ad37' - }, - - notReacted: { - message: 'You are not reacting to that note.', - code: 'NOT_REACTED', - id: '92f4426d-4196-4125-aa5b-02943e2ec8fc' - }, - } -}; - -export default define(meta, async (ps, user) => { - const note = await getNote(ps.noteId).catch(e => { - if (e.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote); - throw e; - }); - await deleteReaction(user, note).catch(e => { - if (e.id === '60527ec9-b4cb-4a88-a6bd-32d3ad26817d') throw new ApiError(meta.errors.notReacted); - throw e; - }); -}); diff --git a/src/server/api/endpoints/notes/unrenote.ts b/src/server/api/endpoints/notes/unrenote.ts deleted file mode 100644 index dce43d9d9..000000000 --- a/src/server/api/endpoints/notes/unrenote.ts +++ /dev/null @@ -1,52 +0,0 @@ -import $ from 'cafy'; -import { ID } from '@/misc/cafy-id'; -import deleteNote from '@/services/note/delete'; -import define from '../../define'; -import * as ms from 'ms'; -import { getNote } from '../../common/getters'; -import { ApiError } from '../../error'; -import { Notes, Users } from '@/models/index'; - -export const meta = { - tags: ['notes'], - - requireCredential: true as const, - - kind: 'write:notes', - - limit: { - duration: ms('1hour'), - max: 300, - minInterval: ms('1sec') - }, - - params: { - noteId: { - validator: $.type(ID), - } - }, - - errors: { - noSuchNote: { - message: 'No such note.', - code: 'NO_SUCH_NOTE', - id: 'efd4a259-2442-496b-8dd7-b255aa1a160f' - }, - } -}; - -export default define(meta, async (ps, user) => { - const note = await getNote(ps.noteId).catch(e => { - if (e.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote); - throw e; - }); - - const renotes = await Notes.find({ - userId: user.id, - renoteId: note.id - }); - - for (const note of renotes) { - deleteNote(await Users.findOneOrFail(user.id), note); - } -}); diff --git a/src/server/api/endpoints/pages/create.ts b/src/server/api/endpoints/pages/create.ts deleted file mode 100644 index c23978f09..000000000 --- a/src/server/api/endpoints/pages/create.ts +++ /dev/null @@ -1,128 +0,0 @@ -import $ from 'cafy'; -import * as ms from 'ms'; -import define from '../../define'; -import { ID } from '@/misc/cafy-id'; -import { Pages, DriveFiles } from '@/models/index'; -import { genId } from '@/misc/gen-id'; -import { Page } from '@/models/entities/page'; -import { ApiError } from '../../error'; - -export const meta = { - tags: ['pages'], - - requireCredential: true as const, - - kind: 'write:pages', - - limit: { - duration: ms('1hour'), - max: 300 - }, - - params: { - title: { - validator: $.str, - }, - - name: { - validator: $.str.min(1), - }, - - summary: { - validator: $.optional.nullable.str, - }, - - content: { - validator: $.arr($.obj()) - }, - - variables: { - validator: $.arr($.obj()) - }, - - script: { - validator: $.str, - }, - - eyeCatchingImageId: { - validator: $.optional.nullable.type(ID), - }, - - font: { - validator: $.optional.str.or(['serif', 'sans-serif']), - default: 'sans-serif' - }, - - alignCenter: { - validator: $.optional.bool, - default: false - }, - - hideTitleWhenPinned: { - validator: $.optional.bool, - default: false - }, - }, - - res: { - type: 'object' as const, - optional: false as const, nullable: false as const, - ref: 'Page', - }, - - errors: { - noSuchFile: { - message: 'No such file.', - code: 'NO_SUCH_FILE', - id: 'b7b97489-0f66-4b12-a5ff-b21bd63f6e1c' - }, - nameAlreadyExists: { - message: 'Specified name already exists.', - code: 'NAME_ALREADY_EXISTS', - id: '4650348e-301c-499a-83c9-6aa988c66bc1' - } - } -}; - -export default define(meta, async (ps, user) => { - let eyeCatchingImage = null; - if (ps.eyeCatchingImageId != null) { - eyeCatchingImage = await DriveFiles.findOne({ - id: ps.eyeCatchingImageId, - userId: user.id - }); - - if (eyeCatchingImage == null) { - throw new ApiError(meta.errors.noSuchFile); - } - } - - await Pages.find({ - userId: user.id, - name: ps.name - }).then(result => { - if (result.length > 0) { - throw new ApiError(meta.errors.nameAlreadyExists); - } - }); - - const page = await Pages.save(new Page({ - id: genId(), - createdAt: new Date(), - updatedAt: new Date(), - title: ps.title, - name: ps.name, - summary: ps.summary, - content: ps.content, - variables: ps.variables, - script: ps.script, - eyeCatchingImageId: eyeCatchingImage ? eyeCatchingImage.id : null, - userId: user.id, - visibility: 'public', - alignCenter: ps.alignCenter, - hideTitleWhenPinned: ps.hideTitleWhenPinned, - font: ps.font - })); - - return await Pages.pack(page); -}); diff --git a/src/server/api/endpoints/pages/update.ts b/src/server/api/endpoints/pages/update.ts deleted file mode 100644 index b3a7f2696..000000000 --- a/src/server/api/endpoints/pages/update.ts +++ /dev/null @@ -1,141 +0,0 @@ -import $ from 'cafy'; -import * as ms from 'ms'; -import define from '../../define'; -import { ApiError } from '../../error'; -import { Pages, DriveFiles } from '@/models/index'; -import { ID } from '@/misc/cafy-id'; -import { Not } from 'typeorm'; - -export const meta = { - tags: ['pages'], - - requireCredential: true as const, - - kind: 'write:pages', - - limit: { - duration: ms('1hour'), - max: 300 - }, - - params: { - pageId: { - validator: $.type(ID), - }, - - title: { - validator: $.str, - }, - - name: { - validator: $.str.min(1), - }, - - summary: { - validator: $.optional.nullable.str, - }, - - content: { - validator: $.arr($.obj()) - }, - - variables: { - validator: $.arr($.obj()) - }, - - script: { - validator: $.str, - }, - - eyeCatchingImageId: { - validator: $.optional.nullable.type(ID), - }, - - font: { - validator: $.optional.str.or(['serif', 'sans-serif']), - }, - - alignCenter: { - validator: $.optional.bool, - }, - - hideTitleWhenPinned: { - validator: $.optional.bool, - }, - }, - - errors: { - noSuchPage: { - message: 'No such page.', - code: 'NO_SUCH_PAGE', - id: '21149b9e-3616-4778-9592-c4ce89f5a864' - }, - - accessDenied: { - message: 'Access denied.', - code: 'ACCESS_DENIED', - id: '3c15cd52-3b4b-4274-967d-6456fc4f792b' - }, - - noSuchFile: { - message: 'No such file.', - code: 'NO_SUCH_FILE', - id: 'cfc23c7c-3887-490e-af30-0ed576703c82' - }, - nameAlreadyExists: { - message: 'Specified name already exists.', - code: 'NAME_ALREADY_EXISTS', - id: '2298a392-d4a1-44c5-9ebb-ac1aeaa5a9ab' - } - } -}; - -export default define(meta, async (ps, user) => { - const page = await Pages.findOne(ps.pageId); - if (page == null) { - throw new ApiError(meta.errors.noSuchPage); - } - if (page.userId !== user.id) { - throw new ApiError(meta.errors.accessDenied); - } - - let eyeCatchingImage = null; - if (ps.eyeCatchingImageId != null) { - eyeCatchingImage = await DriveFiles.findOne({ - id: ps.eyeCatchingImageId, - userId: user.id - }); - - if (eyeCatchingImage == null) { - throw new ApiError(meta.errors.noSuchFile); - } - } - - await Pages.find({ - id: Not(ps.pageId), - userId: user.id, - name: ps.name - }).then(result => { - if (result.length > 0) { - throw new ApiError(meta.errors.nameAlreadyExists); - } - }); - - await Pages.update(page.id, { - updatedAt: new Date(), - title: ps.title, - name: ps.name === undefined ? page.name : ps.name, - summary: ps.name === undefined ? page.summary : ps.summary, - content: ps.content, - variables: ps.variables, - script: ps.script, - alignCenter: ps.alignCenter === undefined ? page.alignCenter : ps.alignCenter, - hideTitleWhenPinned: ps.hideTitleWhenPinned === undefined ? page.hideTitleWhenPinned : ps.hideTitleWhenPinned, - font: ps.font === undefined ? page.font : ps.font, - eyeCatchingImageId: ps.eyeCatchingImageId === null - ? null - : ps.eyeCatchingImageId === undefined - ? page.eyeCatchingImageId - : eyeCatchingImage!.id, - }); -}); diff --git a/src/server/api/endpoints/pinned-users.ts b/src/server/api/endpoints/pinned-users.ts deleted file mode 100644 index e88dfbd53..000000000 --- a/src/server/api/endpoints/pinned-users.ts +++ /dev/null @@ -1,32 +0,0 @@ -import define from '../define'; -import { Users } from '@/models/index'; -import { fetchMeta } from '@/misc/fetch-meta'; -import { parseAcct } from '@/misc/acct'; -import { User } from '@/models/entities/user'; - -export const meta = { - tags: ['users'], - - requireCredential: false as const, - - params: { - }, - - res: { - type: 'array' as const, - optional: false as const, nullable: false as const, - items: { - type: 'object' as const, - optional: false as const, nullable: false as const, - ref: 'User', - } - }, -}; - -export default define(meta, async (ps, me) => { - const meta = await fetchMeta(); - - const users = await Promise.all(meta.pinnedUsers.map(acct => Users.findOne(parseAcct(acct)))); - - return await Users.packMany(users.filter(x => x !== undefined) as User[], me, { detail: true }); -}); diff --git a/src/server/api/endpoints/request-reset-password.ts b/src/server/api/endpoints/request-reset-password.ts deleted file mode 100644 index f9928c2ee..000000000 --- a/src/server/api/endpoints/request-reset-password.ts +++ /dev/null @@ -1,73 +0,0 @@ -import $ from 'cafy'; -import { publishMainStream } from '@/services/stream'; -import define from '../define'; -import rndstr from 'rndstr'; -import config from '@/config/index'; -import * as ms from 'ms'; -import { Users, UserProfiles, PasswordResetRequests } from '@/models/index'; -import { sendEmail } from '@/services/send-email'; -import { ApiError } from '../error'; -import { genId } from '@/misc/gen-id'; -import { IsNull } from 'typeorm'; - -export const meta = { - requireCredential: false as const, - - limit: { - duration: ms('1hour'), - max: 3 - }, - - params: { - username: { - validator: $.str - }, - - email: { - validator: $.str - }, - }, - - errors: { - - } -}; - -export default define(meta, async (ps) => { - const user = await Users.findOne({ - usernameLower: ps.username.toLowerCase(), - host: IsNull() - }); - - // 合致するユーザーが登録されていなかったら無視 - if (user == null) { - return; - } - - const profile = await UserProfiles.findOneOrFail(user.id); - - // 合致するメアドが登録されていなかったら無視 - if (profile.email !== ps.email) { - return; - } - - // メアドが認証されていなかったら無視 - if (!profile.emailVerified) { - return; - } - - const token = rndstr('a-z0-9', 64); - - await PasswordResetRequests.insert({ - id: genId(), - createdAt: new Date(), - userId: profile.userId, - token - }); - - const link = `${config.url}/reset-password/${token}`; - - sendEmail(ps.email, 'Password reset requested', - `To reset password, please click this link:
${link}`, - `To reset password, please click this link: ${link}`); -}); diff --git a/src/server/api/endpoints/users/followers.ts b/src/server/api/endpoints/users/followers.ts deleted file mode 100644 index e54b6078e..000000000 --- a/src/server/api/endpoints/users/followers.ts +++ /dev/null @@ -1,78 +0,0 @@ -import $ from 'cafy'; -import { ID } from '@/misc/cafy-id'; -import define from '../../define'; -import { ApiError } from '../../error'; -import { Users, Followings } from '@/models/index'; -import { makePaginationQuery } from '../../common/make-pagination-query'; -import { toPunyNullable } from '@/misc/convert-host'; - -export const meta = { - tags: ['users'], - - requireCredential: false as const, - - params: { - userId: { - validator: $.optional.type(ID), - }, - - username: { - validator: $.optional.str - }, - - host: { - validator: $.optional.nullable.str - }, - - sinceId: { - validator: $.optional.type(ID), - }, - - untilId: { - validator: $.optional.type(ID), - }, - - limit: { - validator: $.optional.num.range(1, 100), - default: 10 - }, - }, - - res: { - type: 'array' as const, - optional: false as const, nullable: false as const, - items: { - type: 'object' as const, - optional: false as const, nullable: false as const, - ref: 'Following', - } - }, - - errors: { - noSuchUser: { - message: 'No such user.', - code: 'NO_SUCH_USER', - id: '27fa5435-88ab-43de-9360-387de88727cd' - } - } -}; - -export default define(meta, async (ps, me) => { - const user = await Users.findOne(ps.userId != null - ? { id: ps.userId } - : { usernameLower: ps.username!.toLowerCase(), host: toPunyNullable(ps.host) }); - - if (user == null) { - throw new ApiError(meta.errors.noSuchUser); - } - - const query = makePaginationQuery(Followings.createQueryBuilder('following'), ps.sinceId, ps.untilId) - .andWhere(`following.followeeId = :userId`, { userId: user.id }) - .innerJoinAndSelect('following.follower', 'follower'); - - const followings = await query - .take(ps.limit!) - .getMany(); - - return await Followings.packMany(followings, me, { populateFollower: true }); -}); diff --git a/src/server/api/endpoints/users/following.ts b/src/server/api/endpoints/users/following.ts deleted file mode 100644 index f2ef7f47e..000000000 --- a/src/server/api/endpoints/users/following.ts +++ /dev/null @@ -1,78 +0,0 @@ -import $ from 'cafy'; -import { ID } from '@/misc/cafy-id'; -import define from '../../define'; -import { ApiError } from '../../error'; -import { Users, Followings } from '@/models/index'; -import { makePaginationQuery } from '../../common/make-pagination-query'; -import { toPunyNullable } from '@/misc/convert-host'; - -export const meta = { - tags: ['users'], - - requireCredential: false as const, - - params: { - userId: { - validator: $.optional.type(ID), - }, - - username: { - validator: $.optional.str - }, - - host: { - validator: $.optional.nullable.str - }, - - sinceId: { - validator: $.optional.type(ID), - }, - - untilId: { - validator: $.optional.type(ID), - }, - - limit: { - validator: $.optional.num.range(1, 100), - default: 10 - }, - }, - - res: { - type: 'array' as const, - optional: false as const, nullable: false as const, - items: { - type: 'object' as const, - optional: false as const, nullable: false as const, - ref: 'Following', - } - }, - - errors: { - noSuchUser: { - message: 'No such user.', - code: 'NO_SUCH_USER', - id: '63e4aba4-4156-4e53-be25-c9559e42d71b' - } - } -}; - -export default define(meta, async (ps, me) => { - const user = await Users.findOne(ps.userId != null - ? { id: ps.userId } - : { usernameLower: ps.username!.toLowerCase(), host: toPunyNullable(ps.host) }); - - if (user == null) { - throw new ApiError(meta.errors.noSuchUser); - } - - const query = makePaginationQuery(Followings.createQueryBuilder('following'), ps.sinceId, ps.untilId) - .andWhere(`following.followerId = :userId`, { userId: user.id }) - .innerJoinAndSelect('following.followee', 'followee'); - - const followings = await query - .take(ps.limit!) - .getMany(); - - return await Followings.packMany(followings, me, { populateFollowee: true }); -}); diff --git a/src/server/api/endpoints/users/recommendation.ts b/src/server/api/endpoints/users/recommendation.ts deleted file mode 100644 index dde6bb103..000000000 --- a/src/server/api/endpoints/users/recommendation.ts +++ /dev/null @@ -1,63 +0,0 @@ -import * as ms from 'ms'; -import $ from 'cafy'; -import define from '../../define'; -import { Users, Followings } from '@/models/index'; -import { generateMutedUserQueryForUsers } from '../../common/generate-muted-user-query'; -import { generateBlockedUserQuery, generateBlockQueryForUsers } from '../../common/generate-block-query'; - -export const meta = { - tags: ['users'], - - requireCredential: true as const, - - kind: 'read:account', - - params: { - limit: { - validator: $.optional.num.range(1, 100), - default: 10 - }, - - offset: { - validator: $.optional.num.min(0), - default: 0 - } - }, - - res: { - type: 'array' as const, - optional: false as const, nullable: false as const, - items: { - type: 'object' as const, - optional: false as const, nullable: false as const, - ref: 'User', - } - }, -}; - -export default define(meta, async (ps, me) => { - const query = Users.createQueryBuilder('user') - .where('user.isLocked = FALSE') - .andWhere('user.isExplorable = TRUE') - .andWhere('user.host IS NULL') - .andWhere('user.updatedAt >= :date', { date: new Date(Date.now() - ms('7days')) }) - .andWhere('user.id != :meId', { meId: me.id }) - .orderBy('user.followersCount', 'DESC'); - - generateMutedUserQueryForUsers(query, me); - generateBlockQueryForUsers(query, me); - generateBlockedUserQuery(query, me); - - const followingQuery = Followings.createQueryBuilder('following') - .select('following.followeeId') - .where('following.followerId = :followerId', { followerId: me.id }); - - query - .andWhere(`user.id NOT IN (${ followingQuery.getQuery() })`); - - query.setParameters(followingQuery.getParameters()); - - const users = await query.take(ps.limit!).skip(ps.offset).getMany(); - - return await Users.packMany(users, me, { detail: true }); -}); diff --git a/src/server/api/endpoints/users/report-abuse.ts b/src/server/api/endpoints/users/report-abuse.ts deleted file mode 100644 index 2c8672cd4..000000000 --- a/src/server/api/endpoints/users/report-abuse.ts +++ /dev/null @@ -1,90 +0,0 @@ -import $ from 'cafy'; -import { ID } from '@/misc/cafy-id'; -import define from '../../define'; -import { publishAdminStream } from '@/services/stream'; -import { ApiError } from '../../error'; -import { getUser } from '../../common/getters'; -import { AbuseUserReports, Users } from '@/models/index'; -import { genId } from '@/misc/gen-id'; - -export const meta = { - tags: ['users'], - - requireCredential: true as const, - - params: { - userId: { - validator: $.type(ID), - }, - - comment: { - validator: $.str.range(1, 2048), - }, - }, - - errors: { - noSuchUser: { - message: 'No such user.', - code: 'NO_SUCH_USER', - id: '1acefcb5-0959-43fd-9685-b48305736cb5' - }, - - cannotReportYourself: { - message: 'Cannot report yourself.', - code: 'CANNOT_REPORT_YOURSELF', - id: '1e13149e-b1e8-43cf-902e-c01dbfcb202f' - }, - - cannotReportAdmin: { - message: 'Cannot report the admin.', - code: 'CANNOT_REPORT_THE_ADMIN', - id: '35e166f5-05fb-4f87-a2d5-adb42676d48f' - } - } -}; - -export default define(meta, async (ps, me) => { - // Lookup user - const user = await getUser(ps.userId).catch(e => { - if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser); - throw e; - }); - - if (user.id === me.id) { - throw new ApiError(meta.errors.cannotReportYourself); - } - - if (user.isAdmin) { - throw new ApiError(meta.errors.cannotReportAdmin); - } - - const report = await AbuseUserReports.save({ - id: genId(), - createdAt: new Date(), - targetUserId: user.id, - targetUserHost: user.host, - reporterId: me.id, - reporterHost: null, - comment: ps.comment, - }); - - // Publish event to moderators - setTimeout(async () => { - const moderators = await Users.find({ - where: [{ - isAdmin: true - }, { - isModerator: true - }] - }); - - for (const moderator of moderators) { - publishAdminStream(moderator.id, 'newAbuseUserReport', { - id: report.id, - targetUserId: report.targetUserId, - reporterId: report.reporterId, - comment: report.comment - }); - } - }, 1); -}); diff --git a/src/server/api/limiter.ts b/src/server/api/limiter.ts deleted file mode 100644 index e677aad0b..000000000 --- a/src/server/api/limiter.ts +++ /dev/null @@ -1,83 +0,0 @@ -import * as Limiter from 'ratelimiter'; -import { redisClient } from '../../db/redis'; -import { IEndpoint } from './endpoints'; -import { getAcct } from '@/misc/acct'; -import { User } from '@/models/entities/user'; -import Logger from '@/services/logger'; - -const logger = new Logger('limiter'); - -export default (endpoint: IEndpoint, user: User) => new Promise((ok, reject) => { - const limitation = endpoint.meta.limit!; - - const key = limitation.hasOwnProperty('key') - ? limitation.key - : endpoint.name; - - const hasShortTermLimit = - limitation.hasOwnProperty('minInterval'); - - const hasLongTermLimit = - limitation.hasOwnProperty('duration') && - limitation.hasOwnProperty('max'); - - if (hasShortTermLimit) { - min(); - } else if (hasLongTermLimit) { - max(); - } else { - ok(); - } - - // Short-term limit - function min() { - const minIntervalLimiter = new Limiter({ - id: `${user.id}:${key}:min`, - duration: limitation.minInterval, - max: 1, - db: redisClient - }); - - minIntervalLimiter.get((err, info) => { - if (err) { - return reject('ERR'); - } - - logger.debug(`@${getAcct(user)} ${endpoint.name} min remaining: ${info.remaining}`); - - if (info.remaining === 0) { - reject('BRIEF_REQUEST_INTERVAL'); - } else { - if (hasLongTermLimit) { - max(); - } else { - ok(); - } - } - }); - } - - // Long term limit - function max() { - const limiter = new Limiter({ - id: `${user.id}:${key}`, - duration: limitation.duration, - max: limitation.max, - db: redisClient - }); - - limiter.get((err, info) => { - if (err) { - return reject('ERR'); - } - - logger.debug(`@${getAcct(user)} ${endpoint.name} max remaining: ${info.remaining}`); - - if (info.remaining === 0) { - reject('RATE_LIMIT_EXCEEDED'); - } else { - ok(); - } - }); - } -}); diff --git a/src/server/api/openapi/description.ts b/src/server/api/openapi/description.ts deleted file mode 100644 index e51b31225..000000000 --- a/src/server/api/openapi/description.ts +++ /dev/null @@ -1,51 +0,0 @@ -import endpoints from '../endpoints'; -import * as locale from '../../../../locales/index'; -import { kinds as kindsList } from '@/misc/api-permissions'; - -export interface IKindInfo { - endpoints: string[]; - descs: { [x: string]: string; }; -} - -export function kinds() { - const kinds = Object.fromEntries( - kindsList - .map(k => [k, { - endpoints: [], - descs: Object.fromEntries( - Object.keys(locale) - .map(l => [l, locale[l]._permissions[k] as string]) - ) - } as IKindInfo]) - ); - - const errors = [] as string[][]; - - for (const endpoint of endpoints.filter(ep => !ep.meta.secure)) { - if (endpoint.meta.kind) { - const kind = endpoint.meta.kind; - if (kind in kinds) kinds[kind].endpoints.push(endpoint.name); - else errors.push([kind, endpoint.name]); - } - } - - if (errors.length > 0) throw Error('\n ' + errors.map((e) => `Unknown kind (permission) "${e[0]}" found at ${e[1]}.`).join('\n ')); - - return kinds; -} - -export function getDescription(lang = 'ja-JP'): string { - const permissionTable = Object.entries(kinds()) - .map(e => `|${e[0]}|${e[1].descs[lang]}|${e[1].endpoints.map(f => `[${f}](#operation/${f})`).join(', ')}|`) - .join('\n'); - - const descriptions: { [x: string]: string } = { - 'ja-JP': ` -# Permissions -|Permisson (kind)|Description|Endpoints| -|:--|:--|:--| -${permissionTable} -` - }; - return lang in descriptions ? descriptions[lang] : descriptions['ja-JP']; -} diff --git a/src/server/api/openapi/gen-spec.ts b/src/server/api/openapi/gen-spec.ts deleted file mode 100644 index 9db47c6df..000000000 --- a/src/server/api/openapi/gen-spec.ts +++ /dev/null @@ -1,237 +0,0 @@ -import endpoints from '../endpoints'; -import { Context } from 'cafy'; -import config from '@/config/index'; -import { errors as basicErrors } from './errors'; -import { schemas, convertSchemaToOpenApiSchema } from './schemas'; -import { getDescription } from './description'; - -export function genOpenapiSpec(lang = 'ja-JP') { - const spec = { - openapi: '3.0.0', - - info: { - version: 'v1', - title: 'Misskey API', - description: getDescription(lang), - 'x-logo': { url: '/static-assets/api-doc.png' } - }, - - externalDocs: { - description: 'Repository', - url: 'https://github.com/misskey-dev/misskey' - }, - - servers: [{ - url: config.apiUrl - }], - - paths: {} as any, - - components: { - schemas: schemas, - - securitySchemes: { - ApiKeyAuth: { - type: 'apiKey', - in: 'body', - name: 'i' - } - } - } - }; - - function genProps(props: { [key: string]: Context; }) { - const properties = {} as any; - - for (const [k, v] of Object.entries(props)) { - properties[k] = genProp(v); - } - - return properties; - } - - function genProp(param: Context): any { - const required = param.name === 'Object' ? (param as any).props ? Object.entries((param as any).props).filter(([k, v]: any) => !v.isOptional).map(([k, v]) => k) : [] : []; - return { - description: (param.data || {}).desc, - default: (param.data || {}).default, - deprecated: (param.data || {}).deprecated, - ...((param.data || {}).default ? { default: (param.data || {}).default } : {}), - type: param.name === 'ID' ? 'string' : param.name.toLowerCase(), - ...(param.name === 'ID' ? { example: 'xxxxxxxxxx', format: 'id' } : {}), - nullable: param.isNullable, - ...(param.name === 'String' ? { - ...((param as any).enum ? { enum: (param as any).enum } : {}), - ...((param as any).minLength ? { minLength: (param as any).minLength } : {}), - ...((param as any).maxLength ? { maxLength: (param as any).maxLength } : {}), - } : {}), - ...(param.name === 'Number' ? { - ...((param as any).minimum ? { minimum: (param as any).minimum } : {}), - ...((param as any).maximum ? { maximum: (param as any).maximum } : {}), - } : {}), - ...(param.name === 'Object' ? { - ...(required.length > 0 ? { required } : {}), - properties: (param as any).props ? genProps((param as any).props) : {} - } : {}), - ...(param.name === 'Array' ? { - items: (param as any).ctx ? genProp((param as any).ctx) : {} - } : {}) - }; - } - - for (const endpoint of endpoints.filter(ep => !ep.meta.secure)) { - const porops = {} as any; - const errors = {} as any; - - if (endpoint.meta.errors) { - for (const e of Object.values(endpoint.meta.errors)) { - errors[e.code] = { - value: { - error: e - } - }; - } - } - - if (endpoint.meta.params) { - for (const [k, v] of Object.entries(endpoint.meta.params)) { - if (v.validator.data == null) v.validator.data = {}; - if (v.desc) v.validator.data.desc = v.desc[lang]; - if (v.deprecated) v.validator.data.deprecated = v.deprecated; - if (v.default) v.validator.data.default = v.default; - porops[k] = v.validator; - } - } - - const required = endpoint.meta.params ? Object.entries(endpoint.meta.params).filter(([k, v]) => !v.validator.isOptional).map(([k, v]) => k) : []; - - const resSchema = endpoint.meta.res ? convertSchemaToOpenApiSchema(endpoint.meta.res) : {}; - - let desc = (endpoint.meta.desc ? endpoint.meta.desc[lang] : 'No description provided.') + '\n\n'; - desc += `**Credential required**: *${endpoint.meta.requireCredential ? 'Yes' : 'No'}*`; - if (endpoint.meta.kind) { - const kind = endpoint.meta.kind; - desc += ` / **Permission**: *${kind}*`; - } - - const info = { - operationId: endpoint.name, - summary: endpoint.name, - description: desc, - externalDocs: { - description: 'Source code', - url: `https://github.com/misskey-dev/misskey/blob/develop/src/server/api/endpoints/${endpoint.name}.ts` - }, - ...(endpoint.meta.tags ? { - tags: [endpoint.meta.tags[0]] - } : {}), - ...(endpoint.meta.requireCredential ? { - security: [{ - ApiKeyAuth: [] - }] - } : {}), - requestBody: { - required: true, - content: { - 'application/json': { - schema: { - type: 'object', - ...(required.length > 0 ? { required } : {}), - properties: endpoint.meta.params ? genProps(porops) : {} - } - } - } - }, - responses: { - ...(endpoint.meta.res ? { - '200': { - description: 'OK (with results)', - content: { - 'application/json': { - schema: resSchema - } - } - } - } : { - '204': { - description: 'OK (without any results)', - } - }), - '400': { - description: 'Client error', - content: { - 'application/json': { - schema: { - $ref: '#/components/schemas/Error' - }, - examples: { ...errors, ...basicErrors['400'] } - } - } - }, - '401': { - description: 'Authentication error', - content: { - 'application/json': { - schema: { - $ref: '#/components/schemas/Error' - }, - examples: basicErrors['401'] - } - } - }, - '403': { - description: 'Forbidden error', - content: { - 'application/json': { - schema: { - $ref: '#/components/schemas/Error' - }, - examples: basicErrors['403'] - } - } - }, - '418': { - description: 'I\'m Ai', - content: { - 'application/json': { - schema: { - $ref: '#/components/schemas/Error' - }, - examples: basicErrors['418'] - } - } - }, - ...(endpoint.meta.limit ? { - '429': { - description: 'To many requests', - content: { - 'application/json': { - schema: { - $ref: '#/components/schemas/Error' - }, - examples: basicErrors['429'] - } - } - } - } : {}), - '500': { - description: 'Internal server error', - content: { - 'application/json': { - schema: { - $ref: '#/components/schemas/Error' - }, - examples: basicErrors['500'] - } - } - }, - } - }; - - spec.paths['/' + endpoint.name] = { - post: info - }; - } - - return spec; -} diff --git a/src/server/api/private/signup.ts b/src/server/api/private/signup.ts deleted file mode 100644 index 93caaea93..000000000 --- a/src/server/api/private/signup.ts +++ /dev/null @@ -1,105 +0,0 @@ -import * as Koa from 'koa'; -import rndstr from 'rndstr'; -import * as bcrypt from 'bcryptjs'; -import { fetchMeta } from '@/misc/fetch-meta'; -import { verifyHcaptcha, verifyRecaptcha } from '@/misc/captcha'; -import { Users, RegistrationTickets, UserPendings } from '@/models/index'; -import { signup } from '../common/signup'; -import config from '@/config'; -import { sendEmail } from '@/services/send-email'; -import { genId } from '@/misc/gen-id'; - -export default async (ctx: Koa.Context) => { - const body = ctx.request.body; - - const instance = await fetchMeta(true); - - // Verify *Captcha - // ただしテスト時はこの機構は障害となるため無効にする - if (process.env.NODE_ENV !== 'test') { - if (instance.enableHcaptcha && instance.hcaptchaSecretKey) { - await verifyHcaptcha(instance.hcaptchaSecretKey, body['hcaptcha-response']).catch(e => { - ctx.throw(400, e); - }); - } - - if (instance.enableRecaptcha && instance.recaptchaSecretKey) { - await verifyRecaptcha(instance.recaptchaSecretKey, body['g-recaptcha-response']).catch(e => { - ctx.throw(400, e); - }); - } - } - - const username = body['username']; - const password = body['password']; - const host: string | null = process.env.NODE_ENV === 'test' ? (body['host'] || null) : null; - const invitationCode = body['invitationCode']; - const emailAddress = body['emailAddress']; - - if (instance.emailRequiredForSignup) { - if (emailAddress == null || typeof emailAddress != 'string') { - ctx.status = 400; - return; - } - } - - if (instance.disableRegistration) { - if (invitationCode == null || typeof invitationCode != 'string') { - ctx.status = 400; - return; - } - - const ticket = await RegistrationTickets.findOne({ - code: invitationCode - }); - - if (ticket == null) { - ctx.status = 400; - return; - } - - RegistrationTickets.delete(ticket.id); - } - - if (instance.emailRequiredForSignup) { - const code = rndstr('a-z0-9', 16); - - // Generate hash of password - const salt = await bcrypt.genSalt(8); - const hash = await bcrypt.hash(password, salt); - - await UserPendings.insert({ - id: genId(), - createdAt: new Date(), - code, - email: emailAddress, - username: username, - password: hash, - }); - - const link = `${config.url}/signup-complete/${code}`; - - sendEmail(emailAddress, 'Signup', - `To complete signup, please click this link:
${link}`, - `To complete signup, please click this link: ${link}`); - - ctx.status = 204; - } else { - try { - const { account, secret } = await signup({ - username, password, host - }); - - const res = await Users.pack(account, account, { - detail: true, - includeSecrets: true - }); - - (res as any).token = secret; - - ctx.body = res; - } catch (e) { - ctx.throw(400, e); - } - } -}; diff --git a/src/server/api/stream/channels/games/reversi.ts b/src/server/api/stream/channels/games/reversi.ts deleted file mode 100644 index 3b89aac35..000000000 --- a/src/server/api/stream/channels/games/reversi.ts +++ /dev/null @@ -1,33 +0,0 @@ -import autobind from 'autobind-decorator'; -import { publishMainStream } from '@/services/stream'; -import Channel from '../../channel'; -import { ReversiMatchings } from '@/models/index'; - -export default class extends Channel { - public readonly chName = 'gamesReversi'; - public static shouldShare = true; - public static requireCredential = true; - - @autobind - public async init(params: any) { - // Subscribe reversi stream - this.subscriber.on(`reversiStream:${this.user!.id}`, data => { - this.send(data); - }); - } - - @autobind - public async onMessage(type: string, body: any) { - switch (type) { - case 'ping': - if (body.id == null) return; - const matching = await ReversiMatchings.findOne({ - parentId: this.user!.id, - childId: body.id - }); - if (matching == null) return; - publishMainStream(matching.childId, 'reversiInvited', await ReversiMatchings.pack(matching, { id: matching.childId })); - break; - } - } -} diff --git a/src/server/api/stream/types.ts b/src/server/api/stream/types.ts deleted file mode 100644 index 70eb5c5ce..000000000 --- a/src/server/api/stream/types.ts +++ /dev/null @@ -1,299 +0,0 @@ -import { EventEmitter } from 'events'; -import Emitter from 'strict-event-emitter-types'; -import { Channel } from '@/models/entities/channel'; -import { User } from '@/models/entities/user'; -import { UserProfile } from '@/models/entities/user-profile'; -import { Note } from '@/models/entities/note'; -import { Antenna } from '@/models/entities/antenna'; -import { DriveFile } from '@/models/entities/drive-file'; -import { DriveFolder } from '@/models/entities/drive-folder'; -import { Emoji } from '@/models/entities/emoji'; -import { UserList } from '@/models/entities/user-list'; -import { MessagingMessage } from '@/models/entities/messaging-message'; -import { UserGroup } from '@/models/entities/user-group'; -import { ReversiGame } from '@/models/entities/games/reversi/game'; -import { AbuseUserReport } from '@/models/entities/abuse-user-report'; -import { Signin } from '@/models/entities/signin'; -import { Page } from '@/models/entities/page'; -import { Packed } from '@/misc/schema'; - -//#region Stream type-body definitions -export interface InternalStreamTypes { - antennaCreated: Antenna; - antennaDeleted: Antenna; - antennaUpdated: Antenna; -} - -export interface BroadcastTypes { - emojiAdded: { - emoji: Packed<'Emoji'>; - }; -} - -export interface UserStreamTypes { - terminate: {}; - followChannel: Channel; - unfollowChannel: Channel; - updateUserProfile: UserProfile; - mute: User; - unmute: User; - follow: Packed<'User'>; - unfollow: Packed<'User'>; - userAdded: Packed<'User'>; -} - -export interface MainStreamTypes { - notification: Packed<'Notification'>; - mention: Packed<'Note'>; - reply: Packed<'Note'>; - renote: Packed<'Note'>; - follow: Packed<'User'>; - followed: Packed<'User'>; - unfollow: Packed<'User'>; - meUpdated: Packed<'User'>; - pageEvent: { - pageId: Page['id']; - event: string; - var: any; - userId: User['id']; - user: Packed<'User'>; - }; - urlUploadFinished: { - marker?: string | null; - file: Packed<'DriveFile'>; - }; - readAllNotifications: undefined; - unreadNotification: Packed<'Notification'>; - unreadMention: Note['id']; - readAllUnreadMentions: undefined; - unreadSpecifiedNote: Note['id']; - readAllUnreadSpecifiedNotes: undefined; - readAllMessagingMessages: undefined; - messagingMessage: Packed<'MessagingMessage'>; - unreadMessagingMessage: Packed<'MessagingMessage'>; - readAllAntennas: undefined; - unreadAntenna: Antenna; - readAllAnnouncements: undefined; - readAllChannels: undefined; - unreadChannel: Note['id']; - myTokenRegenerated: undefined; - reversiNoInvites: undefined; - reversiInvited: Packed<'ReversiMatching'>; - signin: Signin; - registryUpdated: { - scope?: string[]; - key: string; - value: any | null; - }; - driveFileCreated: Packed<'DriveFile'>; - readAntenna: Antenna; -} - -export interface DriveStreamTypes { - fileCreated: Packed<'DriveFile'>; - fileDeleted: DriveFile['id']; - fileUpdated: Packed<'DriveFile'>; - folderCreated: Packed<'DriveFolder'>; - folderDeleted: DriveFolder['id']; - folderUpdated: Packed<'DriveFolder'>; -} - -export interface NoteStreamTypes { - pollVoted: { - choice: number; - userId: User['id']; - }; - deleted: { - deletedAt: Date; - }; - reacted: { - reaction: string; - emoji?: Emoji; - userId: User['id']; - }; - unreacted: { - reaction: string; - userId: User['id']; - }; -} -type NoteStreamEventTypes = { - [key in keyof NoteStreamTypes]: { - id: Note['id']; - body: NoteStreamTypes[key]; - }; -}; - -export interface ChannelStreamTypes { - typing: User['id']; -} - -export interface UserListStreamTypes { - userAdded: Packed<'User'>; - userRemoved: Packed<'User'>; -} - -export interface AntennaStreamTypes { - note: Note; -} - -export interface MessagingStreamTypes { - read: MessagingMessage['id'][]; - typing: User['id']; - message: Packed<'MessagingMessage'>; - deleted: MessagingMessage['id']; -} - -export interface GroupMessagingStreamTypes { - read: { - ids: MessagingMessage['id'][]; - userId: User['id']; - }; - typing: User['id']; - message: Packed<'MessagingMessage'>; - deleted: MessagingMessage['id']; -} - -export interface MessagingIndexStreamTypes { - read: MessagingMessage['id'][]; - message: Packed<'MessagingMessage'>; -} - -export interface ReversiStreamTypes { - matched: Packed<'ReversiGame'>; - invited: Packed<'ReversiMatching'>; -} - -export interface ReversiGameStreamTypes { - started: Packed<'ReversiGame'>; - ended: { - winnerId?: User['id'] | null, - game: Packed<'ReversiGame'>; - }; - updateSettings: { - key: string; - value: FIXME; - }; - initForm: { - userId: User['id']; - form: FIXME; - }; - updateForm: { - userId: User['id']; - id: string; - value: FIXME; - }; - message: { - userId: User['id']; - message: FIXME; - }; - changeAccepts: { - user1: boolean; - user2: boolean; - }; - set: { - at: Date; - color: boolean; - pos: number; - next: boolean; - }; - watching: User['id']; -} - -export interface AdminStreamTypes { - newAbuseUserReport: { - id: AbuseUserReport['id']; - targetUserId: User['id'], - reporterId: User['id'], - comment: string; - }; -} -//#endregion - -// 辞書(interface or type)から{ type, body }ユニオンを定義 -// https://stackoverflow.com/questions/49311989/can-i-infer-the-type-of-a-value-using-extends-keyof-type -// VS Codeの展開を防止するためにEvents型を定義 -type Events = { [K in keyof T]: { type: K; body: T[K]; } }; -type EventUnionFromDictionary< - T extends object, - U = Events -> = U[keyof U]; - -// name/messages(spec) pairs dictionary -export type StreamMessages = { - internal: { - name: 'internal'; - payload: EventUnionFromDictionary; - }; - broadcast: { - name: 'broadcast'; - payload: EventUnionFromDictionary; - }; - user: { - name: `user:${User['id']}`; - payload: EventUnionFromDictionary; - }; - main: { - name: `mainStream:${User['id']}`; - payload: EventUnionFromDictionary; - }; - drive: { - name: `driveStream:${User['id']}`; - payload: EventUnionFromDictionary; - }; - note: { - name: `noteStream:${Note['id']}`; - payload: EventUnionFromDictionary; - }; - channel: { - name: `channelStream:${Channel['id']}`; - payload: EventUnionFromDictionary; - }; - userList: { - name: `userListStream:${UserList['id']}`; - payload: EventUnionFromDictionary; - }; - antenna: { - name: `antennaStream:${Antenna['id']}`; - payload: EventUnionFromDictionary; - }; - messaging: { - name: `messagingStream:${User['id']}-${User['id']}`; - payload: EventUnionFromDictionary; - }; - groupMessaging: { - name: `messagingStream:${UserGroup['id']}`; - payload: EventUnionFromDictionary; - }; - messagingIndex: { - name: `messagingIndexStream:${User['id']}`; - payload: EventUnionFromDictionary; - }; - reversi: { - name: `reversiStream:${User['id']}`; - payload: EventUnionFromDictionary; - }; - reversiGame: { - name: `reversiGameStream:${ReversiGame['id']}`; - payload: EventUnionFromDictionary; - }; - admin: { - name: `adminStream:${User['id']}`; - payload: EventUnionFromDictionary; - }; - notes: { - name: 'notesStream'; - payload: Packed<'Note'>; - }; -}; - -// API event definitions -// ストリームごとのEmitterの辞書を用意 -type EventEmitterDictionary = { [x in keyof StreamMessages]: Emitter void }> }; -// 共用体型を交差型にする型 https://stackoverflow.com/questions/54938141/typescript-convert-union-to-intersection -type UnionToIntersection = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never; -// Emitter辞書から共用体型を作り、UnionToIntersectionで交差型にする -export type StreamEventEmitter = UnionToIntersection; -// { [y in name]: (e: spec) => void }をまとめてその交差型をEmitterにかけるとts(2590)にひっかかる - -// provide stream channels union -export type StreamChannels = StreamMessages[keyof StreamMessages]['name']; diff --git a/src/server/index.ts b/src/server/index.ts deleted file mode 100644 index 5e1a12e4d..000000000 --- a/src/server/index.ts +++ /dev/null @@ -1,179 +0,0 @@ -/** - * Core Server - */ - -import * as fs from 'fs'; -import * as http from 'http'; -import * as http2 from 'http2'; -import * as https from 'https'; -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'; -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 { genAvatar } from '@/misc/gen-avatar'; -import { createTemp } from '@/misc/create-temp'; -import { publishMainStream } from '@/services/stream'; -import { parseAcct } from '@/misc/acct'; - -export const serverLogger = new Logger('server', 'gray', false); - -// Init app -const app = new Koa(); -app.proxy = true; - -if (!['production', 'test'].includes(process.env.NODE_ENV || '')) { - // Logger - app.use(koaLogger(str => { - serverLogger.info(str); - })); - - // Delay - if (envOption.slow) { - app.use(slow({ - delay: 3000 - })); - } -} - -// HSTS -// 6months (15552000sec) -if (config.url.startsWith('https') && !config.disableHsts) { - app.use(async (ctx, next) => { - ctx.set('strict-transport-security', 'max-age=15552000; preload'); - await next(); - }); -} - -app.use(mount('/api', apiServer)); -app.use(mount('/files', require('./file'))); -app.use(mount('/proxy', require('./proxy'))); - -// Init router -const router = new Router(); - -// Routing -router.use(activityPub.routes()); -router.use(nodeinfo.routes()); -router.use(wellKnown.routes()); - -router.get('/avatar/@:acct', async ctx => { - const { username, host } = parseAcct(ctx.params.acct); - const user = await Users.findOne({ - usernameLower: username.toLowerCase(), - host: host === config.host ? null : host, - isSuspended: false - }); - - if (user) { - ctx.redirect(Users.getAvatarUrl(user)); - } else { - ctx.redirect('/static-assets/user-unknown.png'); - } -}); - -router.get('/random-avatar/:x', async ctx => { - const [temp] = await createTemp(); - await genAvatar(ctx.params.x, fs.createWriteStream(temp)); - ctx.set('Content-Type', 'image/png'); - ctx.body = fs.createReadStream(temp); -}); - -router.get('/verify-email/:code', async ctx => { - const profile = await UserProfiles.findOne({ - emailVerifyCode: ctx.params.code - }); - - if (profile != null) { - ctx.body = 'Verify succeeded!'; - ctx.status = 200; - - await UserProfiles.update({ userId: profile.userId }, { - emailVerified: true, - emailVerifyCode: null - }); - - publishMainStream(profile.userId, 'meUpdated', await Users.pack(profile.userId, { id: profile.userId }, { - detail: true, - includeSecrets: true - })); - } else { - ctx.status = 404; - } -}); - -// Register router -app.use(router.routes()); - -app.use(mount(require('./web'))); - -function createServer() { - if (config.https) { - const certs: any = {}; - for (const k of Object.keys(config.https)) { - certs[k] = fs.readFileSync(config.https[k]); - } - certs['allowHTTP1'] = true; - return http2.createSecureServer(certs, app.callback()) as https.Server; - } else { - return http.createServer(app.callback()); - } -} - -// For testing -export const startServer = () => { - const server = createServer(); - - // Init stream server - require('./api/streaming')(server); - - // Listen - server.listen(config.port); - - return server; -}; - -export default () => new Promise(resolve => { - const server = createServer(); - - // Init stream server - require('./api/streaming')(server); - - // 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/src/server/web/feed.ts b/src/server/web/feed.ts deleted file mode 100644 index 4b6de517b..000000000 --- a/src/server/web/feed.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { Feed } from 'feed'; -import config from '@/config/index'; -import { User } from '@/models/entities/user'; -import { Notes, DriveFiles, UserProfiles } from '@/models/index'; -import { In } from 'typeorm'; - -export default async function(user: User) { - const author = { - link: `${config.url}/@${user.username}`, - name: user.name || user.username - }; - - const profile = await UserProfiles.findOneOrFail(user.id); - - const notes = await Notes.find({ - where: { - userId: user.id, - renoteId: null, - visibility: In(['public', 'home']) - }, - order: { createdAt: -1 }, - take: 20 - }); - - const feed = new Feed({ - id: author.link, - title: `${author.name} (@${user.username}@${config.host})`, - updated: notes[0].createdAt, - generator: 'Misskey', - description: `${user.notesCount} Notes, ${user.followingCount} Following, ${user.followersCount} Followers${profile.description ? ` · ${profile.description}` : ''}`, - link: author.link, - image: user.avatarUrl ? user.avatarUrl : undefined, - feedLinks: { - json: `${author.link}.json`, - atom: `${author.link}.atom`, - }, - author, - copyright: user.name || user.username - }); - - for (const note of notes) { - const files = note.fileIds.length > 0 ? await DriveFiles.find({ - id: In(note.fileIds) - }) : []; - const file = files.find(file => file.type.startsWith('image/')); - - feed.addItem({ - title: `New note by ${author.name}`, - link: `${config.url}/notes/${note.id}`, - date: note.createdAt, - description: note.cw || undefined, - content: note.text || undefined, - image: file ? DriveFiles.getPublicUrl(file) || undefined : undefined - }); - } - - return feed; -} diff --git a/src/server/web/index.ts b/src/server/web/index.ts deleted file mode 100644 index 35337868d..000000000 --- a/src/server/web/index.ts +++ /dev/null @@ -1,513 +0,0 @@ -/** - * Web Client Server - */ - -import * as os from 'os'; -import * as fs from 'fs'; -import { fileURLToPath } from 'url'; -import { dirname } from 'path'; -import * as ms from 'ms'; -import * as Koa from 'koa'; -import * as Router from '@koa/router'; -import * as send from 'koa-send'; -import * as favicon from 'koa-favicon'; -import * as views from 'koa-views'; -import * as glob from 'glob'; -import * as MarkdownIt from 'markdown-it'; - -import packFeed from './feed'; -import { fetchMeta } from '@/misc/fetch-meta'; -import { genOpenapiSpec } from '../api/openapi/gen-spec'; -import config from '@/config/index'; -import { Users, Notes, Emojis, UserProfiles, Pages, Channels, Clips, GalleryPosts } from '@/models/index'; -import { parseAcct } from '@/misc/acct'; -import { getNoteSummary } from '@/misc/get-note-summary'; -import { getConnection } from 'typeorm'; -import { redisClient } from '../../db/redis'; -import * as locales from '../../../locales/index'; - -//const _filename = fileURLToPath(import.meta.url); -const _filename = __filename; -const _dirname = dirname(_filename); - -const markdown = MarkdownIt({ - html: true -}); - -const changelog = fs.readFileSync(`${_dirname}/../../../CHANGELOG.md`, { encoding: 'utf8' }); -function genDoc(path: string): string { - let md = fs.readFileSync(path, { encoding: 'utf8' }); - md = md.replace('', changelog); - return md; -} - -const staticAssets = `${_dirname}/../../../assets/`; -const docAssets = `${_dirname}/../../../src/docs/`; -const assets = `${_dirname}/../../assets/`; - -// Init app -const app = new Koa(); - -// Init renderer -app.use(views(_dirname + '/views', { - extension: 'pug', - options: { - version: config.version, - config - } -})); - -// Serve favicon -app.use(favicon(`${_dirname}/../../../assets/favicon.ico`)); - -// Common request handler -app.use(async (ctx, next) => { - // IFrameの中に入れられないようにする - ctx.set('X-Frame-Options', 'DENY'); - await next(); -}); - -// Init router -const router = new Router(); - -//#region static assets - -router.get('/static-assets/(.*)', async ctx => { - await send(ctx as any, ctx.path.replace('/static-assets/', ''), { - root: staticAssets, - maxage: ms('7 days'), - }); -}); - -router.get('/doc-assets/(.*)', async ctx => { - if (ctx.path.includes('..')) return; - const path = `${_dirname}/../../../src/docs/${ctx.path.replace('/doc-assets/', '')}`; - const doc = genDoc(path); - ctx.set('Content-Type', 'text/plain; charset=utf-8'); - ctx.body = doc; -}); - -router.get('/assets/(.*)', async ctx => { - await send(ctx as any, ctx.path.replace('/assets/', ''), { - root: assets, - maxage: ms('7 days'), - }); -}); - -// Apple touch icon -router.get('/apple-touch-icon.png', async ctx => { - await send(ctx as any, '/apple-touch-icon.png', { - root: staticAssets - }); -}); - -router.get('/twemoji/(.*)', async ctx => { - const path = ctx.path.replace('/twemoji/', ''); - - if (!path.match(/^[0-9a-f-]+\.svg$/)) { - ctx.status = 404; - return; - } - - ctx.set('Content-Security-Policy', `default-src 'none'; style-src 'unsafe-inline'`); - - await send(ctx as any, path, { - root: `${_dirname}/../../../node_modules/@discordapp/twemoji/dist/svg/`, - maxage: ms('30 days'), - }); -}); - -// ServiceWorker -router.get('/sw.js', async ctx => { - await send(ctx as any, `/sw.${config.version}.js`, { - root: assets - }); -}); - -// Manifest -router.get('/manifest.json', require('./manifest')); - -router.get('/robots.txt', async ctx => { - await send(ctx as any, '/robots.txt', { - root: staticAssets - }); -}); - -//#endregion - -// Docs -router.get('/api-doc', async ctx => { - await send(ctx as any, '/redoc.html', { - root: staticAssets - }); -}); - -// URL preview endpoint -router.get('/url', require('./url-preview')); - -router.get('/api.json', async ctx => { - ctx.body = genOpenapiSpec(); -}); - -router.get('/docs.json', async ctx => { - const lang = ctx.query.lang; - const query = ctx.query.q; - if (!Object.keys(locales).includes(lang)) { - ctx.body = []; - return; - } - const dirPath = `${_dirname}/../../../src/docs/${lang}`.replace(/\\/g, '/'); - const paths = glob.sync(`${dirPath}/**/*.md`); - const docs: { path: string; title: string; summary: string; }[] = []; - for (const path of paths) { - const md = genDoc(path); - - if (query && query.length > 0) { - // TODO: カタカナをひらがなにして比較するなどしたい - if (!md.includes(query)) continue; - } - - const parsed = markdown.parse(md, {}); - if (parsed.length === 0) return; - - const buf = [...parsed]; - const headingTokens = []; - - // もっとも上にある見出しを抽出する - while (buf[0].type !== 'heading_open') { - buf.shift(); - } - buf.shift(); - while (buf[0].type as string !== 'heading_close') { - const token = buf.shift(); - if (token) { - headingTokens.push(token); - } - } - - const firstParagrapfTokens = []; - while (buf[0].type !== 'paragraph_open') { - buf.shift(); - } - buf.shift(); - while (buf[0].type as string !== 'paragraph_close') { - const token = buf.shift(); - if (token) { - firstParagrapfTokens.push(token); - } - } - - docs.push({ - path: path.match(new RegExp(`docs\/${lang}\/(.+?)\.md$`))![1], - title: markdown.renderer.render(headingTokens, {}, {}), - summary: markdown.renderer.render(firstParagrapfTokens, {}, {}), - }); - } - - ctx.body = docs; -}); - -const getFeed = async (acct: string) => { - const { username, host } = parseAcct(acct); - const user = await Users.findOne({ - usernameLower: username.toLowerCase(), - host, - isSuspended: false - }); - - return user && await packFeed(user); -}; - -// Atom -router.get('/@:user.atom', async ctx => { - const feed = await getFeed(ctx.params.user); - - if (feed) { - ctx.set('Content-Type', 'application/atom+xml; charset=utf-8'); - ctx.body = feed.atom1(); - } else { - ctx.status = 404; - } -}); - -// RSS -router.get('/@:user.rss', async ctx => { - const feed = await getFeed(ctx.params.user); - - if (feed) { - ctx.set('Content-Type', 'application/rss+xml; charset=utf-8'); - ctx.body = feed.rss2(); - } else { - ctx.status = 404; - } -}); - -// JSON -router.get('/@:user.json', async ctx => { - const feed = await getFeed(ctx.params.user); - - if (feed) { - ctx.set('Content-Type', 'application/json; charset=utf-8'); - ctx.body = feed.json1(); - } else { - ctx.status = 404; - } -}); - -//#region SSR (for crawlers) -// User -router.get(['/@:user', '/@:user/:sub'], async (ctx, next) => { - const { username, host } = parseAcct(ctx.params.user); - const user = await Users.findOne({ - usernameLower: username.toLowerCase(), - host, - isSuspended: false - }); - - if (user != null) { - const profile = await UserProfiles.findOneOrFail(user.id); - const meta = await fetchMeta(); - const me = profile.fields - ? profile.fields - .filter(filed => filed.value != null && filed.value.match(/^https?:/)) - .map(field => field.value) - : []; - - await ctx.render('user', { - user, profile, me, - sub: ctx.params.sub, - instanceName: meta.name || 'Misskey', - icon: meta.iconUrl - }); - ctx.set('Cache-Control', 'public, max-age=30'); - } else { - // リモートユーザーなので - // モデレータがAPI経由で参照可能にするために404にはしない - await next(); - } -}); - -router.get('/users/:user', async ctx => { - const user = await Users.findOne({ - id: ctx.params.user, - host: null, - isSuspended: false - }); - - if (user == null) { - ctx.status = 404; - return; - } - - ctx.redirect(`/@${user.username}${ user.host == null ? '' : '@' + user.host}`); -}); - -// Note -router.get('/notes/:note', async (ctx, next) => { - const note = await Notes.findOne(ctx.params.note); - - if (note) { - const _note = await Notes.pack(note); - const profile = await UserProfiles.findOneOrFail(note.userId); - const meta = await fetchMeta(); - await ctx.render('note', { - note: _note, - profile, - // TODO: Let locale changeable by instance setting - summary: getNoteSummary(_note, locales['ja-JP']), - instanceName: meta.name || 'Misskey', - icon: meta.iconUrl - }); - - if (['public', 'home'].includes(note.visibility)) { - ctx.set('Cache-Control', 'public, max-age=180'); - } else { - ctx.set('Cache-Control', 'private, max-age=0, must-revalidate'); - } - - return; - } - - await next(); -}); - -// Page -router.get('/@:user/pages/:page', async (ctx, next) => { - const { username, host } = parseAcct(ctx.params.user); - const user = await Users.findOne({ - usernameLower: username.toLowerCase(), - host - }); - - if (user == null) return; - - const page = await Pages.findOne({ - name: ctx.params.page, - userId: user.id - }); - - if (page) { - const _page = await Pages.pack(page); - const profile = await UserProfiles.findOneOrFail(page.userId); - const meta = await fetchMeta(); - await ctx.render('page', { - page: _page, - profile, - instanceName: meta.name || 'Misskey' - }); - - if (['public'].includes(page.visibility)) { - ctx.set('Cache-Control', 'public, max-age=180'); - } else { - ctx.set('Cache-Control', 'private, max-age=0, must-revalidate'); - } - - return; - } - - await next(); -}); - -// Clip -// TODO: 非publicなclipのハンドリング -router.get('/clips/:clip', async (ctx, next) => { - const clip = await Clips.findOne({ - id: ctx.params.clip, - }); - - if (clip) { - const _clip = await Clips.pack(clip); - const profile = await UserProfiles.findOneOrFail(clip.userId); - const meta = await fetchMeta(); - await ctx.render('clip', { - clip: _clip, - profile, - instanceName: meta.name || 'Misskey' - }); - - ctx.set('Cache-Control', 'public, max-age=180'); - - return; - } - - await next(); -}); - -// Gallery post -router.get('/gallery/:post', async (ctx, next) => { - const post = await GalleryPosts.findOne(ctx.params.post); - - if (post) { - const _post = await GalleryPosts.pack(post); - const profile = await UserProfiles.findOneOrFail(post.userId); - const meta = await fetchMeta(); - await ctx.render('gallery-post', { - post: _post, - profile, - instanceName: meta.name || 'Misskey', - icon: meta.iconUrl - }); - - ctx.set('Cache-Control', 'public, max-age=180'); - - return; - } - - await next(); -}); - -// Channel -router.get('/channels/:channel', async (ctx, next) => { - const channel = await Channels.findOne({ - id: ctx.params.channel, - }); - - if (channel) { - const _channel = await Channels.pack(channel); - const meta = await fetchMeta(); - await ctx.render('channel', { - channel: _channel, - instanceName: meta.name || 'Misskey' - }); - - ctx.set('Cache-Control', 'public, max-age=180'); - - return; - } - - await next(); -}); -//#endregion - -router.get('/info', async ctx => { - const meta = await fetchMeta(true); - const emojis = await Emojis.find({ - where: { host: null } - }); - - const proxyAccount = meta.proxyAccountId ? await Users.pack(meta.proxyAccountId).catch(() => null) : null; - - await ctx.render('info', { - version: config.version, - machine: os.hostname(), - os: os.platform(), - node: process.version, - psql: await getConnection().query('SHOW server_version').then(x => x[0].server_version), - redis: redisClient.server_info.redis_version, - cpu: { - model: os.cpus()[0].model, - cores: os.cpus().length - }, - emojis: emojis, - meta: meta, - proxyAccountName: proxyAccount ? proxyAccount.username : null, - originalUsersCount: await Users.count({ host: null }), - originalNotesCount: await Notes.count({ userHost: null }) - }); -}); - -router.get('/bios', async ctx => { - await ctx.render('bios', { - version: config.version, - }); -}); - -router.get('/cli', async ctx => { - await ctx.render('cli', { - version: config.version, - }); -}); - -const override = (source: string, target: string, depth: number = 0) => - [, ...target.split('/').filter(x => x), ...source.split('/').filter(x => x).splice(depth)].join('/'); - -router.get('/othello', async ctx => ctx.redirect(override(ctx.URL.pathname, 'games/reversi', 1))); -router.get('/reversi', async ctx => ctx.redirect(override(ctx.URL.pathname, 'games'))); - -router.get('/flush', async ctx => { - await ctx.render('flush'); -}); - -// streamingに非WebSocketリクエストが来た場合にbase htmlをキャシュ付きで返すと、Proxy等でそのパスがキャッシュされておかしくなる -router.get('/streaming', async ctx => { - ctx.status = 503; - ctx.set('Cache-Control', 'private, max-age=0'); -}); - -// Render base html for all requests -router.get('(.*)', async ctx => { - const meta = await fetchMeta(); - await ctx.render('base', { - img: meta.bannerUrl, - title: meta.name || 'Misskey', - instanceName: meta.name || 'Misskey', - desc: meta.description, - icon: meta.iconUrl - }); - ctx.set('Cache-Control', 'public, max-age=300'); -}); - -// Register router -app.use(router.routes()); - -module.exports = app; diff --git a/src/server/web/views/info.pug b/src/server/web/views/info.pug deleted file mode 100644 index 61f9b7b9e..000000000 --- a/src/server/web/views/info.pug +++ /dev/null @@ -1,147 +0,0 @@ -doctype html - -html - - head - meta(charset='utf-8') - meta(name='application-name' content='Misskey') - title Misskey - style. - html { - font-family: Roboto, HelveticaNeue, Arial, sans-serif; - } - - main { - max-width: 934px; - margin: 0 auto; - } - - header { - padding: 5px; - background: rgb(153, 153, 204); - border: 1px solid #000; - box-shadow: rgb(204, 204, 204) 1px 2px 3px; - } - header:after { - content: ''; - display: block; - clear: both; - } - - header > h1 { - float: left; - font-size: 2em; - } - - header > img { - float: right; - width: 220px; - } - - table { - margin: 1em 0; - width: 100%; - border-collapse: collapse; - box-shadow: rgb(204, 204, 204) 1px 2px 3px; - } - table tr th { - background-color: #ccf; - border: 1px solid #000; - width: 300px; - font-weight: bold; - padding: 4px 5px; - text-align: left; - } - table tr td { - background-color: #ddd; - border: 1px solid #000; - padding: 4px 5px; - } - - footer { - text-align: center; - } - - body - main - header - h1 Misskey Version #{version} - img(src='/static-assets/misskey-php-like-logo.png' alt='') - table - tr - th Instance - td= meta.name || 'Misskey' - tr - th Description - td= meta.description - tr - th Maintainer - td - = meta.maintainerName - | <#{meta.maintainerEmail}> - tr - th Proxy account name - td= proxyAccountName || '(none)' - tr - th System - td= os - tr - th Node version - td= node - tr - th PSQL version - td= psql - tr - th Redis version - td= redis - tr - th Machine - td= machine - tr - th CPU - td= cpu.model - tr - th Original users - td= originalUsersCount - tr - th Original notes - td= originalNotesCount - tr - th Registration - td= !meta.disableRegistration ? 'yes' : 'no' - tr - th hCaptcha enabled - td= meta.enableHcaptcha ? 'enabled' : 'disabled' - tr - th reCAPTCHA enabled - td= meta.enableRecaptcha ? 'enabled' : 'disabled' - tr - th LTL(STL) enabled - td= !meta.disableLocalTimeline ? 'enabled' : 'disabled' - tr - th GTL enabled - td= !meta.disableGlobalTimeline ? 'enabled' : 'disabled' - tr - th Cache remote files - td= meta.cacheRemoteFiles ? 'yes' : 'no' - tr - th Drive capacity per local user - td - = meta.localDriveCapacityMb - | MB - tr - th Drive capacity per remote user - td - = meta.remoteDriveCapacityMb - | MB - tr - th Max text length - td= meta.maxNoteTextLength - tr - th Emojis - td - each emoji in emojis - | :#{emoji.name}: - = ' ' - footer - p Misskey is open-source software. View source diff --git a/src/server/well-known.ts b/src/server/well-known.ts deleted file mode 100644 index a2e6bc0bc..000000000 --- a/src/server/well-known.ts +++ /dev/null @@ -1,149 +0,0 @@ -import * as Router from '@koa/router'; - -import config from '@/config/index'; -import { parseAcct, Acct } from '@/misc/acct'; -import { links } from './nodeinfo'; -import { escapeAttribute, escapeValue } from '@/prelude/xml'; -import { Users } from '@/models/index'; -import { User } from '@/models/entities/user'; - -// Init router -const router = new Router(); - -const XRD = (...x: { element: string, value?: string, attributes?: Record }[]) => - `${x.map(({ element, value, attributes }) => - `<${ - Object.entries(typeof attributes === 'object' && attributes || {}).reduce((a, [k, v]) => `${a} ${k}="${escapeAttribute(v)}"`, element) - }${ - typeof value === 'string' ? `>${escapeValue(value)}`).reduce((a, c) => a + c, '')}`; - -const allPath = '/.well-known/(.*)'; -const webFingerPath = '/.well-known/webfinger'; -const jrd = 'application/jrd+json'; -const xrd = 'application/xrd+xml'; - -router.use(allPath, async (ctx, next) => { - ctx.set({ - 'Access-Control-Allow-Headers': 'Accept', - 'Access-Control-Allow-Methods': 'GET, OPTIONS', - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Expose-Headers': 'Vary', - }); - await next(); -}); - -router.options(allPath, async ctx => { - ctx.status = 204; -}); - -router.get('/.well-known/host-meta', async ctx => { - ctx.set('Content-Type', xrd); - ctx.body = XRD({ element: 'Link', attributes: { - type: xrd, - template: `${config.url}${webFingerPath}?resource={uri}` - }}); -}); - -router.get('/.well-known/host-meta.json', async ctx => { - ctx.set('Content-Type', jrd); - ctx.body = { - links: [{ - rel: 'lrdd', - type: jrd, - template: `${config.url}${webFingerPath}?resource={uri}` - }] - }; -}); - -router.get('/.well-known/nodeinfo', async ctx => { - ctx.body = { links }; -}); - -/* TODO -router.get('/.well-known/change-password', async ctx => { -}); -*/ - -router.get(webFingerPath, async ctx => { - const fromId = (id: User['id']): Record => ({ - id, - host: null, - isSuspended: false - }); - - const generateQuery = (resource: string) => - resource.startsWith(`${config.url.toLowerCase()}/users/`) ? - fromId(resource.split('/').pop()!) : - fromAcct(parseAcct( - resource.startsWith(`${config.url.toLowerCase()}/@`) ? resource.split('/').pop()! : - resource.startsWith('acct:') ? resource.slice('acct:'.length) : - resource)); - - const fromAcct = (acct: Acct): Record | number => - !acct.host || acct.host === config.host.toLowerCase() ? { - usernameLower: acct.username, - host: null, - isSuspended: false - } : 422; - - if (typeof ctx.query.resource !== 'string') { - ctx.status = 400; - return; - } - - const query = generateQuery(ctx.query.resource.toLowerCase()); - - if (typeof query === 'number') { - ctx.status = query; - return; - } - - const user = await Users.findOne(query); - - if (user == null) { - ctx.status = 404; - return; - } - - const subject = `acct:${user.username}@${config.host}`; - const self = { - rel: 'self', - type: 'application/activity+json', - href: `${config.url}/users/${user.id}` - }; - const profilePage = { - rel: 'http://webfinger.net/rel/profile-page', - type: 'text/html', - href: `${config.url}/@${user.username}` - }; - const subscribe = { - rel: 'http://ostatus.org/schema/1.0/subscribe', - template: `${config.url}/authorize-follow?acct={uri}` - }; - - if (ctx.accepts(jrd, xrd) === xrd) { - ctx.body = XRD( - { element: 'Subject', value: subject }, - { element: 'Link', attributes: self }, - { element: 'Link', attributes: profilePage }, - { element: 'Link', attributes: subscribe }); - ctx.type = xrd; - } else { - ctx.body = { - subject, - links: [self, profilePage, subscribe] - }; - ctx.type = jrd; - } - - ctx.vary('Accept'); - ctx.set('Cache-Control', 'public, max-age=180'); -}); - -// Return 404 for other .well-known -router.all(allPath, async ctx => { - ctx.status = 404; -}); - -export default router; diff --git a/src/services/chart/core.ts b/src/services/chart/core.ts deleted file mode 100644 index c0d3280c2..000000000 --- a/src/services/chart/core.ts +++ /dev/null @@ -1,563 +0,0 @@ -/** - * チャートエンジン - * - * Tests located in test/chart - */ - -import * as nestedProperty from 'nested-property'; -import autobind from 'autobind-decorator'; -import Logger from '../logger'; -import { SimpleSchema } from '@/misc/simple-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 }; - -export type DeepPartial = { - [P in keyof T]?: DeepPartial; -}; - -type ArrayValue = { - [P in keyof T]: T[P] extends number ? T[P][] : ArrayValue; -}; - -type Log = { - id: number; - - /** - * 集計のグループ - */ - group: string | null; - - /** - * 集計日時のUnixタイムスタンプ(秒) - */ - date: number; -}; - -const camelToSnake = (str: string) => { - return str.replace(/([A-Z])/g, s => '_' + s.charAt(0).toLowerCase()); -}; - -const removeDuplicates = (array: any[]) => Array.from(new Set(array)); - -/** - * 様々なチャートの管理を司るクラス - */ -export default abstract class Chart> { - private static readonly columnPrefix = '___'; - private static readonly columnDot = '_'; - - private name: string; - private buffer: { - diff: DeepPartial; - group: string | null; - }[] = []; - public schema: SimpleSchema; - protected repository: Repository; - - protected abstract genNewLog(latest: T): DeepPartial; - - /** - * @param logs 日時が新しい方が先頭 - */ - protected abstract aggregate(logs: T[]): T; - - protected abstract fetchActual(group: string | null): Promise>; - - @autobind - private static convertSchemaToFlatColumnDefinitions(schema: SimpleSchema) { - const columns = {} as any; - 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, - }; - } - } - }; - flatColumns(schema.properties!); - return columns; - } - - @autobind - private static convertFlattenColumnsToObject(x: Record): Record { - const obj = {} as any; - 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) { - const columns = {} as Record; - 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) { - const exec = (x: Obj) => { - const res = {} as Record; - 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) { - const query: Record = {}; - - 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'] { - return Math.floor(x.getTime() / 1000); - } - - @autobind - private static parseDate(date: Date): [number, number, number, number, number, number, number] { - const y = date.getUTCFullYear(); - const m = date.getUTCMonth(); - const d = date.getUTCDate(); - const h = date.getUTCHours(); - const _m = date.getUTCMinutes(); - const _s = date.getUTCSeconds(); - const _ms = date.getUTCMilliseconds(); - - return [y, m, d, h, _m, _s, _ms]; - } - - @autobind - private static getCurrentDate() { - return Chart.parseDate(new Date()); - } - - @autobind - public static schemaToEntity(name: string, schema: SimpleSchema): EntitySchema { - return new EntitySchema({ - name: `__chart__${camelToSnake(name)}`, - columns: { - id: { - type: 'integer', - primary: true, - generated: true - }, - date: { - type: 'integer', - }, - group: { - type: 'varchar', - length: 128, - nullable: true - }, - ...Chart.convertSchemaToFlatColumnDefinitions(schema) - }, - indices: [{ - columns: ['date', 'group'], - unique: true, - }, { // groupにnullが含まれると↑のuniqueは機能しないので↓の部分インデックスでカバー - columns: ['date'], - unique: true, - where: '"group" IS NULL' - }] - }); - } - - constructor(name: string, schema: SimpleSchema, grouped = false) { - this.name = name; - this.schema = schema; - const entity = Chart.schemaToEntity(name, schema); - - const keys = ['date']; - if (grouped) keys.push('group'); - - entity.options.uniques = [{ - columns: keys - }]; - - this.repository = getRepository(entity); - } - - @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); - } - } - } - }; - flatColumns(this.schema.properties!); - return log as T; - } - - @autobind - private getLatestLog(group: string | null = null): Promise { - return this.repository.findOne({ - group: group, - }, { - order: { - date: -1 - } - }).then(x => x || null); - } - - @autobind - private async getCurrentLog(group: string | null = null): Promise { - const [y, m, d, h] = Chart.getCurrentDate(); - - const current = dateUTC([y, m, d, h]); - - // 現在(=今のHour)のログ - const currentLog = await this.repository.findOne({ - date: Chart.dateToTimestamp(current), - ...(group ? { group: group } : {}) - }); - - // ログがあればそれを返して終了 - if (currentLog != null) { - return currentLog; - } - - let log: Log; - let data: T; - - // 集計期間が変わってから、初めてのチャート更新なら - // 最も最近のログを持ってくる - // * 例えば集計期間が「日」である場合で考えると、 - // * 昨日何もチャートを更新するような出来事がなかった場合は、 - // * ログがそもそも作られずドキュメントが存在しないということがあり得るため、 - // * 「昨日の」と決め打ちせずに「もっとも最近の」とします - const latest = await this.getLatestLog(group); - - if (latest != null) { - const obj = Chart.convertFlattenColumnsToObject(latest) as T; - - // 空ログデータを作成 - data = this.getNewLog(obj); - } else { - // ログが存在しなかったら - // (Misskeyインスタンスを建てて初めてのチャート更新時など) - - // 初期ログデータを作成 - data = this.getNewLog(null); - - logger.info(`${this.name + (group ? `:${group}` : '')}: Initial commit created`); - } - - const date = Chart.dateToTimestamp(current); - const lockKey = `${this.name}:${date}:${group}`; - - const unlock = await getChartInsertLock(lockKey); - try { - // ロック内でもう1回チェックする - const currentLog = await this.repository.findOne({ - date: date, - ...(group ? { group: group } : {}) - }); - - // ログがあればそれを返して終了 - if (currentLog != null) return currentLog; - - // 新規ログ挿入 - log = await this.repository.insert({ - group: group, - date: date, - ...Chart.convertObjectToFlattenColumns(data) - }).then(x => this.repository.findOneOrFail(x.identifiers[0])); - - logger.info(`${this.name + (group ? `:${group}` : '')}: New commit created`); - - return log; - } finally { - unlock(); - } - } - - @autobind - protected commit(diff: DeepPartial, group: string | null = null): void { - this.buffer.push({ - diff, group, - }); - } - - @autobind - public async save() { - if (this.buffer.length === 0) { - logger.info(`${this.name}: Write skipped`); - return; - } - - // TODO: 前の時間のログがbufferにあった場合のハンドリング - // 例えば、save が20分ごとに行われるとして、前回行われたのは 01:50 だったとする。 - // 次に save が行われるのは 02:10 ということになるが、もし 01:55 に新規ログが buffer に追加されたとすると、 - // そのログは本来は 01:00~ のログとしてDBに保存されて欲しいのに、02:00~ のログ扱いになってしまう。 - // これを回避するための実装は複雑になりそうなため、一旦保留。 - - const update = async (log: Log) => { - const finalDiffs = {} as Record; - - for (const diff of this.buffer.filter(q => q.group === log.group).map(q => q.diff)) { - const columns = Chart.convertObjectToFlattenColumns(diff); - - for (const [k, v] of Object.entries(columns)) { - if (finalDiffs[k] == null) { - finalDiffs[k] = v; - } else { - if (typeof finalDiffs[k] === 'number') { - (finalDiffs[k] as number) += v as number; - } else { - (finalDiffs[k] as unknown[]) = (finalDiffs[k] as unknown[]).concat(v); - } - } - } - } - - const query = Chart.convertQuery(finalDiffs); - - // ログ更新 - await this.repository.createQueryBuilder() - .update() - .set(query) - .where('id = :id', { id: log.id }) - .execute(); - - logger.info(`${this.name + (log.group ? `:${log.group}` : '')}: Updated`); - - // TODO: この一連の処理が始まった後に新たにbufferに入ったものは消さないようにする - this.buffer = this.buffer.filter(q => q.group !== log.group); - }; - - const groups = removeDuplicates(this.buffer.map(log => log.group)); - - await Promise.all(groups.map(group => this.getCurrentLog(group).then(log => update(log)))); - } - - @autobind - public async resync(group: string | null = null): Promise { - const data = await this.fetchActual(group); - - const update = async (log: Log) => { - await this.repository.createQueryBuilder() - .update() - .set(Chart.convertObjectToFlattenColumns(data)) - .where('id = :id', { id: log.id }) - .execute(); - }; - - return this.getCurrentLog(group).then(log => update(log)); - } - - @autobind - protected async inc(inc: DeepPartial, group: string | null = null): Promise { - await this.commit(inc, group); - } - - @autobind - public async getChart(span: 'hour' | 'day', amount: number, cursor: Date | null, group: string | null = null): Promise> { - 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; - - const lt = dateUTC([y, m, d, h, _m, _s, _ms]); - - const gt = - span === 'day' ? subtractTime(cursor ? dateUTC([y2, m2, d2, 0]) : dateUTC([y, m, d, 0]), amount - 1, 'day') : - span === 'hour' ? subtractTime(cursor ? dateUTC([y2, m2, d2, h2]) : dateUTC([y, m, d, h]), amount - 1, 'hour') : - null as never; - - // ログ取得 - let logs = await this.repository.find({ - where: { - group: group, - date: Between(Chart.dateToTimestamp(gt), Chart.dateToTimestamp(lt)) - }, - order: { - date: -1 - }, - }); - - // 要求された範囲にログがひとつもなかったら - if (logs.length === 0) { - // もっとも新しいログを持ってくる - // (すくなくともひとつログが無いと隙間埋めできないため) - const recentLog = await this.repository.findOne({ - group: group, - }, { - order: { - date: -1 - }, - }); - - if (recentLog) { - logs = [recentLog]; - } - - // 要求された範囲の最も古い箇所に位置するログが存在しなかったら - } else if (!isTimeSame(new Date(logs[logs.length - 1].date * 1000), gt)) { - // 要求された範囲の最も古い箇所時点での最も新しいログを持ってきて末尾に追加する - // (隙間埋めできないため) - const outdatedLog = await this.repository.findOne({ - group: group, - date: LessThan(Chart.dateToTimestamp(gt)) - }, { - order: { - date: -1 - }, - }); - - if (outdatedLog) { - logs.push(outdatedLog); - } - } - - const chart: T[] = []; - - if (span === 'hour') { - for (let i = (amount - 1); i >= 0; i--) { - const current = subtractTime(dateUTC([y, m, d, h]), i, 'hour'); - - 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); - } 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); - } - } - } else if (span === 'day') { - const logsForEachDays: T[][] = []; - let currentDay = -1; - let currentDayIndex = -1; - for (let i = ((amount - 1) * 24) + h; i >= 0; i--) { - const current = subtractTime(dateUTC([y, m, d, h]), i, 'hour'); - const _currentDay = Chart.parseDate(current)[2]; - if (currentDay != _currentDay) currentDayIndex++; - currentDay = _currentDay; - - const log = logs.find(l => isTimeSame(new Date(l.date * 1000), current)); - - if (log) { - if (logsForEachDays[currentDayIndex]) { - logsForEachDays[currentDayIndex].unshift(Chart.convertFlattenColumnsToObject(log) as T); - } else { - logsForEachDays[currentDayIndex] = [Chart.convertFlattenColumnsToObject(log) as T]; - } - } else { - // 隙間埋め - const latest = logs.find(l => isTimeBefore(new Date(l.date * 1000), current)); - const data = latest ? Chart.convertFlattenColumnsToObject(latest) as T : null; - const newLog = this.getNewLog(data); - if (logsForEachDays[currentDayIndex]) { - logsForEachDays[currentDayIndex].unshift(newLog); - } else { - logsForEachDays[currentDayIndex] = [newLog]; - } - } - } - - for (const logs of logsForEachDays) { - const log = this.aggregate(logs); - chart.unshift(Chart.countUniqueFields(log) as T); - } - } - - const res: ArrayValue = {} as any; - - /** - * [{ foo: 1, bar: 5 }, { foo: 2, bar: 6 }, { foo: 3, bar: 7 }] - * を - * { foo: [1, 2, 3], bar: [5, 6, 7] } - * にする - */ - const compact = (x: Obj, path?: string) => { - for (const [k, v] of Object.entries(x)) { - const p = path ? `${path}.${k}` : k; - if (typeof v === 'object' && !Array.isArray(v)) { - compact(v, p); - } else { - const values = chart.map(s => nestedProperty.get(s, p)); - nestedProperty.set(res, p, values); - } - } - }; - - compact(chart[0]); - - return res; - } -} - -export function convertLog(logSchema: SimpleSchema): SimpleSchema { - const v: SimpleSchema = 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]); - } - } - return v; -} diff --git a/src/services/drive/delete-file.ts b/src/services/drive/delete-file.ts deleted file mode 100644 index 2eab17ac1..000000000 --- a/src/services/drive/delete-file.ts +++ /dev/null @@ -1,166 +0,0 @@ -import { DriveFile } from '@/models/entities/drive-file'; -import { InternalStorage } from './internal-storage'; -import { DriveFiles, Instances, Notes, Users } from '@/models/index'; -import { driveChart, perUserDriveChart, instanceChart } from '@/services/chart/index'; -import { createDeleteObjectStorageFileJob } from '@/queue/index'; -import { fetchMeta } from '@/misc/fetch-meta'; -import { getS3 } from './s3'; -import { v4 as uuid } from 'uuid'; -import { Note } from '@/models/entities/note'; -import { renderActivity } from '@/remote/activitypub/renderer/index'; -import renderDelete from '@/remote/activitypub/renderer/delete'; -import renderTombstone from '@/remote/activitypub/renderer/tombstone'; -import config from '@/config/index'; -import { deliverToFollowers } from '@/remote/activitypub/deliver-manager'; -import { Brackets } from 'typeorm'; -import { deliverToRelays } from '../relay'; - -export async function deleteFile(file: DriveFile, isExpired = false) { - if (file.storedInternal) { - InternalStorage.del(file.accessKey!); - - if (file.thumbnailUrl) { - InternalStorage.del(file.thumbnailAccessKey!); - } - - if (file.webpublicUrl) { - InternalStorage.del(file.webpublicAccessKey!); - } - } else if (!file.isLink) { - createDeleteObjectStorageFileJob(file.accessKey!); - - if (file.thumbnailUrl) { - createDeleteObjectStorageFileJob(file.thumbnailAccessKey!); - } - - if (file.webpublicUrl) { - createDeleteObjectStorageFileJob(file.webpublicAccessKey!); - } - } - - postProcess(file, isExpired); -} - -export async function deleteFileSync(file: DriveFile, isExpired = false) { - if (file.storedInternal) { - InternalStorage.del(file.accessKey!); - - if (file.thumbnailUrl) { - InternalStorage.del(file.thumbnailAccessKey!); - } - - if (file.webpublicUrl) { - InternalStorage.del(file.webpublicAccessKey!); - } - } else if (!file.isLink) { - const promises = []; - - promises.push(deleteObjectStorageFile(file.accessKey!)); - - if (file.thumbnailUrl) { - promises.push(deleteObjectStorageFile(file.thumbnailAccessKey!)); - } - - if (file.webpublicUrl) { - promises.push(deleteObjectStorageFile(file.webpublicAccessKey!)); - } - - await Promise.all(promises); - } - - postProcess(file, isExpired); -} - -async function postProcess(file: DriveFile, isExpired = false) { - // リモートファイル期限切れ削除後は直リンクにする - if (isExpired && file.userHost !== null && file.uri != null) { - DriveFiles.update(file.id, { - isLink: true, - url: file.uri, - thumbnailUrl: null, - webpublicUrl: null, - storedInternal: false, - // ローカルプロキシ用 - accessKey: uuid(), - thumbnailAccessKey: 'thumbnail-' + uuid(), - webpublicAccessKey: 'webpublic-' + uuid(), - }); - } else { - DriveFiles.delete(file.id); - - // TODO: トランザクション - const relatedNotes = await findRelatedNotes(file.id); - for (const relatedNote of relatedNotes) { // for each note with deleted driveFile - const cascadingNotes = (await findCascadingNotes(relatedNote)).filter(note => !note.localOnly); - for (const cascadingNote of cascadingNotes) { // for each notes subject to cascade deletion - if (!cascadingNote.user) continue; - if (!Users.isLocalUser(cascadingNote.user)) continue; - const content = renderActivity(renderDelete(renderTombstone(`${config.url}/notes/${cascadingNote.id}`), cascadingNote.user)); - deliverToFollowers(cascadingNote.user, content); // federate delete msg - deliverToRelays(cascadingNote.user, content); - } - if (!relatedNote.user) continue; - if (Users.isLocalUser(relatedNote.user)) { - const content = renderActivity(renderDelete(renderTombstone(`${config.url}/notes/${relatedNote.id}`), relatedNote.user)); - deliverToFollowers(relatedNote.user, content); - deliverToRelays(relatedNote.user, content); - } - } - Notes.createQueryBuilder().delete() - .where(':id = ANY("fileIds")', { id: file.id }) - .execute(); - } - - // 統計を更新 - driveChart.update(file, false); - perUserDriveChart.update(file, false); - if (file.userHost !== null) { - instanceChart.updateDrive(file, false); - Instances.decrement({ host: file.userHost }, 'driveUsage', file.size); - Instances.decrement({ host: file.userHost }, 'driveFiles', 1); - } -} - -export async function deleteObjectStorageFile(key: string) { - const meta = await fetchMeta(); - - const s3 = getS3(meta); - - await s3.deleteObject({ - Bucket: meta.objectStorageBucket!, - Key: key - }).promise(); -} - -async function findRelatedNotes(fileId: string) { - // NOTE: When running raw query, TypeORM converts field name to lowercase. Wrap in quotes to prevent conversion. - const relatedNotes = await Notes.createQueryBuilder('note').where(':id = ANY("fileIds")', { id: fileId }).getMany(); - for (const relatedNote of relatedNotes) { - const user = await Users.findOne({ id: relatedNote.userId }); - if (user) - relatedNote.user = user; - } - return relatedNotes; -} - -async function findCascadingNotes(note: Note) { - const cascadingNotes: Note[] = []; - - const recursive = async (noteId: string) => { - const query = Notes.createQueryBuilder('note') - .where('note.replyId = :noteId', { noteId }) - .orWhere(new Brackets(q => { - q.where('note.renoteId = :noteId', { noteId }) - .andWhere('note.text IS NOT NULL'); - })) - .leftJoinAndSelect('note.user', 'user'); - const replies = await query.getMany(); - for (const reply of replies) { - cascadingNotes.push(reply); - await recursive(reply.id); - } - }; - await recursive(note.id); - - return cascadingNotes.filter(note => note.userHost === null); // filter out non-local users -} diff --git a/src/services/drive/internal-storage.ts b/src/services/drive/internal-storage.ts deleted file mode 100644 index deaf3dc83..000000000 --- a/src/services/drive/internal-storage.ts +++ /dev/null @@ -1,35 +0,0 @@ -import * as fs from 'fs'; -import * as Path from 'path'; -import { fileURLToPath } from 'url'; -import { dirname } from 'path'; -import config from '@/config/index'; - -//const _filename = fileURLToPath(import.meta.url); -const _filename = __filename; -const _dirname = dirname(_filename); - -export class InternalStorage { - private static readonly path = Path.resolve(_dirname, '../../../files'); - - public static resolvePath = (key: string) => Path.resolve(InternalStorage.path, key); - - public static read(key: string) { - return fs.createReadStream(InternalStorage.resolvePath(key)); - } - - public static saveFromPath(key: string, srcPath: string) { - fs.mkdirSync(InternalStorage.path, { recursive: true }); - fs.copyFileSync(srcPath, InternalStorage.resolvePath(key)); - return `${config.url}/files/${key}`; - } - - public static saveFromBuffer(key: string, data: Buffer) { - fs.mkdirSync(InternalStorage.path, { recursive: true }); - fs.writeFileSync(InternalStorage.resolvePath(key), data); - return `${config.url}/files/${key}`; - } - - public static del(key: string) { - fs.unlink(InternalStorage.resolvePath(key), () => {}); - } -} diff --git a/src/services/logger.ts b/src/services/logger.ts deleted file mode 100644 index 67ee44125..000000000 --- a/src/services/logger.ts +++ /dev/null @@ -1,127 +0,0 @@ -import * as cluster from 'cluster'; -import * as chalk from 'chalk'; -import * as dateformat from 'dateformat'; -import { envOption } from '../env'; -import config from '@/config/index'; - -import * as SyslogPro from 'syslog-pro'; - -type Domain = { - name: string; - color?: string; -}; - -type Level = 'error' | 'success' | 'warning' | 'debug' | 'info'; - -export default class Logger { - private domain: Domain; - private parentLogger: Logger | null = null; - private store: boolean; - private syslogClient: any | null = null; - - constructor(domain: string, color?: string, store = true) { - this.domain = { - name: domain, - color: color, - }; - this.store = store; - - if (config.syslog) { - this.syslogClient = new SyslogPro.RFC5424({ - applacationName: 'Misskey', - timestamp: true, - encludeStructuredData: true, - color: true, - extendedColor: true, - server: { - target: config.syslog.host, - port: config.syslog.port, - } - }); - } - } - - public createSubLogger(domain: string, color?: string, store = true): Logger { - const logger = new Logger(domain, color, store); - logger.parentLogger = this; - return logger; - } - - private log(level: Level, message: string, data?: Record | null, important = false, subDomains: Domain[] = [], store = true): void { - if (envOption.quiet) return; - if (!this.store) store = false; - if (level === 'debug') store = false; - - if (this.parentLogger) { - this.parentLogger.log(level, message, data, important, [this.domain].concat(subDomains), store); - return; - } - - const time = dateformat(new Date(), 'HH:MM:ss'); - const worker = cluster.isMaster ? '*' : cluster.worker.id; - const l = - level === 'error' ? important ? chalk.bgRed.white('ERR ') : chalk.red('ERR ') : - level === 'warning' ? chalk.yellow('WARN') : - level === 'success' ? important ? chalk.bgGreen.white('DONE') : chalk.green('DONE') : - level === 'debug' ? chalk.gray('VERB') : - level === 'info' ? chalk.blue('INFO') : - null; - const domains = [this.domain].concat(subDomains).map(d => d.color ? chalk.keyword(d.color)(d.name) : chalk.white(d.name)); - const m = - level === 'error' ? chalk.red(message) : - level === 'warning' ? chalk.yellow(message) : - level === 'success' ? chalk.green(message) : - level === 'debug' ? chalk.gray(message) : - level === 'info' ? message : - null; - - let log = `${l} ${worker}\t[${domains.join(' ')}]\t${m}`; - if (envOption.withLogTime) log = chalk.gray(time) + ' ' + log; - - console.log(important ? chalk.bold(log) : log); - - if (store) { - if (this.syslogClient) { - const send = - level === 'error' ? this.syslogClient.error : - level === 'warning' ? this.syslogClient.warning : - level === 'success' ? this.syslogClient.info : - level === 'debug' ? this.syslogClient.info : - level === 'info' ? this.syslogClient.info : - null as never; - - send.bind(this.syslogClient)(message).catch(() => {}); - } - } - } - - public error(x: string | Error, data?: Record | null, important = false): void { // 実行を継続できない状況で使う - if (x instanceof Error) { - data = data || {}; - data.e = x; - this.log('error', x.toString(), data, important); - } else if (typeof x === 'object') { - this.log('error', `${(x as any).message || (x as any).name || x}`, data, important); - } else { - this.log('error', `${x}`, data, important); - } - } - - public warn(message: string, data?: Record | null, important = false): void { // 実行を継続できるが改善すべき状況で使う - this.log('warning', message, data, important); - } - - public succ(message: string, data?: Record | null, important = false): void { // 何かに成功した状況で使う - this.log('success', message, data, important); - } - - public debug(message: string, data?: Record | null, important = false): void { // デバッグ用に使う(開発者に必要だが利用者に不要な情報) - if (process.env.NODE_ENV != 'production' || envOption.verbose) { - this.log('debug', message, data, important); - } - } - - public info(message: string, data?: Record | null, important = false): void { // それ以外 - this.log('info', message, data, important); - } -} diff --git a/src/services/note/create.ts b/src/services/note/create.ts deleted file mode 100644 index 69d854ab1..000000000 --- a/src/services/note/create.ts +++ /dev/null @@ -1,645 +0,0 @@ -import * as mfm from 'mfm-js'; -import es from '../../db/elasticsearch'; -import { publishMainStream, publishNotesStream } from '@/services/stream'; -import DeliverManager from '@/remote/activitypub/deliver-manager'; -import renderNote from '@/remote/activitypub/renderer/note'; -import renderCreate from '@/remote/activitypub/renderer/create'; -import renderAnnounce from '@/remote/activitypub/renderer/announce'; -import { renderActivity } from '@/remote/activitypub/renderer/index'; -import { resolveUser } from '@/remote/resolve-user'; -import config from '@/config/index'; -import { updateHashtags } from '../update-hashtag'; -import { concat } from '@/prelude/array'; -import { insertNoteUnread } from '@/services/note/unread'; -import { registerOrFetchInstanceDoc } from '../register-or-fetch-instance-doc'; -import { extractMentions } from '@/misc/extract-mentions'; -import { extractCustomEmojisFromMfm } from '@/misc/extract-custom-emojis-from-mfm'; -import { extractHashtags } from '@/misc/extract-hashtags'; -import { Note, IMentionedRemoteUsers } from '@/models/entities/note'; -import { Mutings, Users, NoteWatchings, Notes, Instances, UserProfiles, Antennas, Followings, MutedNotes, Channels, ChannelFollowings, Blockings, NoteThreadMutings } from '@/models/index'; -import { DriveFile } from '@/models/entities/drive-file'; -import { App } from '@/models/entities/app'; -import { Not, getConnection, In } from 'typeorm'; -import { User, ILocalUser, IRemoteUser } from '@/models/entities/user'; -import { genId } from '@/misc/gen-id'; -import { notesChart, perUserNotesChart, activeUsersChart, instanceChart } from '@/services/chart/index'; -import { Poll, IPoll } from '@/models/entities/poll'; -import { createNotification } from '../create-notification'; -import { isDuplicateKeyValueError } from '@/misc/is-duplicate-key-value-error'; -import { checkHitAntenna } from '@/misc/check-hit-antenna'; -import { checkWordMute } from '@/misc/check-word-mute'; -import { addNoteToAntenna } from '../add-note-to-antenna'; -import { countSameRenotes } from '@/misc/count-same-renotes'; -import { deliverToRelays } from '../relay'; -import { Channel } from '@/models/entities/channel'; -import { normalizeForSearch } from '@/misc/normalize-for-search'; -import { getAntennas } from '@/misc/antenna-cache'; - -type NotificationType = 'reply' | 'renote' | 'quote' | 'mention'; - -class NotificationManager { - private notifier: { id: User['id']; }; - private note: Note; - private queue: { - target: ILocalUser['id']; - reason: NotificationType; - }[]; - - constructor(notifier: { id: User['id']; }, note: Note) { - this.notifier = notifier; - this.note = note; - this.queue = []; - } - - public push(notifiee: ILocalUser['id'], reason: NotificationType) { - // 自分自身へは通知しない - if (this.notifier.id === notifiee) return; - - const exist = this.queue.find(x => x.target === notifiee); - - if (exist) { - // 「メンションされているかつ返信されている」場合は、メンションとしての通知ではなく返信としての通知にする - if (reason != 'mention') { - exist.reason = reason; - } - } else { - this.queue.push({ - reason: reason, - target: notifiee - }); - } - } - - public async deliver() { - for (const x of this.queue) { - // ミュート情報を取得 - const mentioneeMutes = await Mutings.find({ - muterId: x.target - }); - - const mentioneesMutedUserIds = mentioneeMutes.map(m => m.muteeId); - - // 通知される側のユーザーが通知する側のユーザーをミュートしていない限りは通知する - if (!mentioneesMutedUserIds.includes(this.notifier.id)) { - createNotification(x.target, x.reason, { - notifierId: this.notifier.id, - noteId: this.note.id - }); - } - } - } -} - -type Option = { - createdAt?: Date | null; - name?: string | null; - text?: string | null; - reply?: Note | null; - renote?: Note | null; - files?: DriveFile[] | null; - poll?: IPoll | null; - viaMobile?: boolean | null; - localOnly?: boolean | null; - cw?: string | null; - visibility?: string; - visibleUsers?: User[] | null; - channel?: Channel | null; - apMentions?: User[] | null; - apHashtags?: string[] | null; - apEmojis?: string[] | null; - uri?: string | null; - url?: string | null; - 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(async (res, rej) => { - // チャンネル外にリプライしたら対象のスコープに合わせる - // (クライアントサイドでやっても良い処理だと思うけどとりあえずサーバーサイドで) - if (data.reply && data.channel && data.reply.channelId !== data.channel.id) { - if (data.reply.channelId) { - data.channel = await Channels.findOne(data.reply.channelId); - } else { - data.channel = null; - } - } - - // チャンネル内にリプライしたら対象のスコープに合わせる - // (クライアントサイドでやっても良い処理だと思うけどとりあえずサーバーサイドで) - if (data.reply && (data.channel == null) && data.reply.channelId) { - data.channel = await Channels.findOne(data.reply.channelId); - } - - if (data.createdAt == null) data.createdAt = new Date(); - if (data.visibility == null) data.visibility = 'public'; - if (data.viaMobile == null) data.viaMobile = false; - if (data.localOnly == null) data.localOnly = false; - if (data.channel != null) data.visibility = 'public'; - if (data.channel != null) data.visibleUsers = []; - if (data.channel != null) data.localOnly = true; - - // サイレンス - if (user.isSilenced && data.visibility === 'public' && data.channel == null) { - data.visibility = 'home'; - } - - // Renote対象が「ホームまたは全体」以外の公開範囲ならreject - if (data.renote && data.renote.visibility !== 'public' && data.renote.visibility !== 'home' && data.renote.userId !== user.id) { - return rej('Renote target is not public or home'); - } - - // Renote対象がpublicではないならhomeにする - if (data.renote && data.renote.visibility !== 'public' && data.visibility === 'public') { - data.visibility = 'home'; - } - - // Renote対象がfollowersならfollowersにする - if (data.renote && data.renote.visibility === 'followers') { - data.visibility = 'followers'; - } - - // 返信対象がpublicではないならhomeにする - if (data.reply && data.reply.visibility !== 'public' && data.visibility === 'public') { - data.visibility = 'home'; - } - - // ローカルのみをRenoteしたらローカルのみにする - if (data.renote && data.renote.localOnly && data.channel == null) { - data.localOnly = true; - } - - // ローカルのみにリプライしたらローカルのみにする - if (data.reply && data.reply.localOnly && data.channel == null) { - data.localOnly = true; - } - - if (data.text) { - data.text = data.text.trim(); - } - - let tags = data.apHashtags; - let emojis = data.apEmojis; - let mentionedUsers = data.apMentions; - - // Parse MFM if needed - if (!tags || !emojis || !mentionedUsers) { - const tokens = data.text ? mfm.parse(data.text)! : []; - const cwTokens = data.cw ? mfm.parse(data.cw)! : []; - const choiceTokens = data.poll && data.poll.choices - ? concat(data.poll.choices.map(choice => mfm.parse(choice)!)) - : []; - - const combinedTokens = tokens.concat(cwTokens).concat(choiceTokens); - - tags = data.apHashtags || extractHashtags(combinedTokens); - - emojis = data.apEmojis || extractCustomEmojisFromMfm(combinedTokens); - - mentionedUsers = data.apMentions || await extractMentionedUsers(user, combinedTokens); - } - - tags = tags.filter(tag => Array.from(tag || '').length <= 128).splice(0, 32); - - if (data.reply && (user.id !== data.reply.userId) && !mentionedUsers.some(u => u.id === data.reply!.userId)) { - mentionedUsers.push(await Users.findOneOrFail(data.reply.userId)); - } - - if (data.visibility == 'specified') { - if (data.visibleUsers == null) throw new Error('invalid param'); - - for (const u of data.visibleUsers) { - if (!mentionedUsers.some(x => x.id === u.id)) { - mentionedUsers.push(u); - } - } - - if (data.reply && !data.visibleUsers.some(x => x.id === data.reply!.userId)) { - data.visibleUsers.push(await Users.findOneOrFail(data.reply.userId)); - } - } - - const note = await insertNote(user, data, tags, emojis, mentionedUsers); - - res(note); - - // 統計を更新 - notesChart.update(note, true); - perUserNotesChart.update(user, note, true); - - // Register host - if (Users.isRemoteUser(user)) { - registerOrFetchInstanceDoc(user.host).then(i => { - Instances.increment({ id: i.id }, 'notesCount', 1); - instanceChart.updateNote(i.host, note, true); - }); - } - - // ハッシュタグ更新 - if (data.visibility === 'public' || data.visibility === 'home') { - updateHashtags(user, tags); - } - - // Increment notes count (user) - incNotesCountOfUser(user); - - // Word mute - // TODO: cache - UserProfiles.find({ - enableWordMute: true - }).then(us => { - for (const u of us) { - checkWordMute(note, { id: u.userId }, u.mutedWords).then(shouldMute => { - if (shouldMute) { - MutedNotes.insert({ - id: genId(), - userId: u.userId, - noteId: note.id, - reason: 'word', - }); - } - }); - } - }); - - // Antenna - Followings.createQueryBuilder('following') - .andWhere(`following.followeeId = :userId`, { userId: note.userId }) - .getMany() - .then(async followings => { - const blockings = await Blockings.find({ blockerId: user.id }); // TODO: キャッシュしたい - const followers = followings.map(f => f.followerId); - for (const antenna of (await getAntennas())) { - if (blockings.some(blocking => blocking.blockeeId === antenna.userId)) continue; // この処理は checkHitAntenna 内でやるようにしてもいいかも - checkHitAntenna(antenna, note, user, followers).then(hit => { - if (hit) { - addNoteToAntenna(antenna, note, user); - } - }); - } - }); - - // Channel - if (note.channelId) { - ChannelFollowings.find({ followeeId: note.channelId }).then(followings => { - for (const following of followings) { - insertNoteUnread(following.followerId, note, { - isSpecified: false, - isMentioned: false, - }); - } - }); - } - - if (data.reply) { - saveReply(data.reply, note); - } - - // この投稿を除く指定したユーザーによる指定したノートのリノートが存在しないとき - if (data.renote && (await countSameRenotes(user.id, data.renote.id, note.id) === 0)) { - incRenoteCount(data.renote); - } - - if (!silent) { - // ローカルユーザーのチャートはタイムライン取得時に更新しているのでリモートユーザーの場合だけでよい - if (Users.isRemoteUser(user)) activeUsersChart.update(user); - - // 未読通知を作成 - if (data.visibility == 'specified') { - if (data.visibleUsers == null) throw new Error('invalid param'); - - for (const u of data.visibleUsers) { - // ローカルユーザーのみ - if (!Users.isLocalUser(u)) continue; - - insertNoteUnread(u.id, note, { - isSpecified: true, - isMentioned: false, - }); - } - } else { - for (const u of mentionedUsers) { - // ローカルユーザーのみ - if (!Users.isLocalUser(u)) continue; - - insertNoteUnread(u.id, note, { - isSpecified: false, - isMentioned: true, - }); - } - } - - // Pack the note - const noteObj = await Notes.pack(note); - - publishNotesStream(noteObj); - - const nm = new NotificationManager(user, note); - const nmRelatedPromises = []; - - await createMentionedEvents(mentionedUsers, note, nm); - - // If has in reply to note - if (data.reply) { - // Fetch watchers - nmRelatedPromises.push(notifyToWatchersOfReplyee(data.reply, user, nm)); - - // 通知 - if (data.reply.userHost === null) { - const threadMuted = await NoteThreadMutings.findOne({ - userId: data.reply.userId, - threadId: data.reply.threadId || data.reply.id, - }); - - if (!threadMuted) { - nm.push(data.reply.userId, 'reply'); - publishMainStream(data.reply.userId, 'reply', noteObj); - } - } - } - - // If it is renote - if (data.renote) { - const type = data.text ? 'quote' : 'renote'; - - // Notify - if (data.renote.userHost === null) { - nm.push(data.renote.userId, type); - } - - // Fetch watchers - nmRelatedPromises.push(notifyToWatchersOfRenotee(data.renote, user, nm, type)); - - // Publish event - if ((user.id !== data.renote.userId) && data.renote.userHost === null) { - publishMainStream(data.renote.userId, 'renote', noteObj); - } - } - - Promise.all(nmRelatedPromises).then(() => { - nm.deliver(); - }); - - //#region AP deliver - if (Users.isLocalUser(user)) { - (async () => { - const noteActivity = await renderNoteOrRenoteActivity(data, note); - const dm = new DeliverManager(user, noteActivity); - - // メンションされたリモートユーザーに配送 - for (const u of mentionedUsers.filter(u => Users.isRemoteUser(u))) { - dm.addDirectRecipe(u as IRemoteUser); - } - - // 投稿がリプライかつ投稿者がローカルユーザーかつリプライ先の投稿の投稿者がリモートユーザーなら配送 - if (data.reply && data.reply.userHost !== null) { - const u = await Users.findOne(data.reply.userId); - if (u && Users.isRemoteUser(u)) dm.addDirectRecipe(u); - } - - // 投稿がRenoteかつ投稿者がローカルユーザーかつRenote元の投稿の投稿者がリモートユーザーなら配送 - if (data.renote && data.renote.userHost !== null) { - const u = await Users.findOne(data.renote.userId); - if (u && Users.isRemoteUser(u)) dm.addDirectRecipe(u); - } - - // フォロワーに配送 - if (['public', 'home', 'followers'].includes(note.visibility)) { - dm.addFollowersRecipe(); - } - - if (['public'].includes(note.visibility)) { - deliverToRelays(user, noteActivity); - } - - dm.execute(); - })(); - } - //#endregion - } - - if (data.channel) { - Channels.increment({ id: data.channel.id }, 'notesCount', 1); - Channels.update(data.channel.id, { - lastNotedAt: new Date(), - }); - - Notes.count({ - userId: user.id, - channelId: data.channel.id, - }).then(count => { - // この処理が行われるのはノート作成後なので、ノートが一つしかなかったら最初の投稿だと判断できる - // TODO: とはいえノートを削除して何回も投稿すればその分だけインクリメントされる雑さもあるのでどうにかしたい - if (count === 1) { - Channels.increment({ id: data.channel!.id }, 'usersCount', 1); - } - }); - } - - // Register to search database - index(note); -}); - -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) - ? renderAnnounce(data.renote.uri ? data.renote.uri : `${config.url}/notes/${data.renote.id}`, note) - : renderCreate(await renderNote(note, false), note); - - return renderActivity(content); -} - -function incRenoteCount(renote: Note) { - Notes.createQueryBuilder().update() - .set({ - renoteCount: () => '"renoteCount" + 1', - score: () => '"score" + 1' - }) - .where('id = :id', { id: renote.id }) - .execute(); -} - -async function insertNote(user: { id: User['id']; host: User['host']; }, data: Option, tags: string[], emojis: string[], mentionedUsers: User[]) { - const insert = new Note({ - id: genId(data.createdAt!), - createdAt: data.createdAt!, - fileIds: data.files ? data.files.map(file => file.id) : [], - replyId: data.reply ? data.reply.id : null, - renoteId: data.renote ? data.renote.id : null, - channelId: data.channel ? data.channel.id : null, - threadId: data.reply - ? data.reply.threadId - ? data.reply.threadId - : data.reply.id - : null, - name: data.name, - text: data.text, - hasPoll: data.poll != null, - cw: data.cw == null ? null : data.cw, - tags: tags.map(tag => normalizeForSearch(tag)), - emojis, - userId: user.id, - viaMobile: data.viaMobile!, - localOnly: data.localOnly!, - visibility: data.visibility as any, - visibleUserIds: data.visibility == 'specified' - ? data.visibleUsers - ? data.visibleUsers.map(u => u.id) - : [] - : [], - - attachedFileTypes: data.files ? data.files.map(file => file.type) : [], - - // 以下非正規化データ - replyUserId: data.reply ? data.reply.userId : null, - replyUserHost: data.reply ? data.reply.userHost : null, - renoteUserId: data.renote ? data.renote.userId : null, - renoteUserHost: data.renote ? data.renote.userHost : null, - userHost: user.host, - }); - - if (data.uri != null) insert.uri = data.uri; - if (data.url != null) insert.url = data.url; - - // Append mentions data - if (mentionedUsers.length > 0) { - 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 url = profile != null ? profile.url : null; - return { - uri: u.uri, - url: url == null ? undefined : url, - username: u.username, - host: u.host - } as IMentionedRemoteUsers[0]; - })); - } - - // 投稿を作成 - try { - if (insert.hasPoll) { - // Start transaction - await getConnection().transaction(async transactionalEntityManager => { - await transactionalEntityManager.insert(Note, insert); - - const poll = new Poll({ - noteId: insert.id, - choices: data.poll!.choices, - expiresAt: data.poll!.expiresAt, - multiple: data.poll!.multiple, - votes: new Array(data.poll!.choices.length).fill(0), - noteVisibility: insert.visibility, - userId: user.id, - userHost: user.host - }); - - await transactionalEntityManager.insert(Poll, poll); - }); - } else { - await Notes.insert(insert); - } - - return insert; - } catch (e) { - // duplicate key error - if (isDuplicateKeyValueError(e)) { - const err = new Error('Duplicated note'); - err.name = 'duplicated'; - throw err; - } - - console.error(e); - - throw e; - } -} - -function index(note: Note) { - if (note.text == null || config.elasticsearch == null) return; - - es!.index({ - index: config.elasticsearch.index || 'misskey_note', - id: note.id.toString(), - body: { - text: normalizeForSearch(note.text), - userId: note.userId, - userHost: note.userHost - } - }); -} - -async function notifyToWatchersOfRenotee(renote: Note, user: { id: User['id']; }, nm: NotificationManager, type: NotificationType) { - const watchers = await NoteWatchings.find({ - noteId: renote.id, - userId: Not(user.id) - }); - - for (const watcher of watchers) { - nm.push(watcher.userId, type); - } -} - -async function notifyToWatchersOfReplyee(reply: Note, user: { id: User['id']; }, nm: NotificationManager) { - const watchers = await NoteWatchings.find({ - noteId: reply.id, - userId: Not(user.id) - }); - - for (const watcher of watchers) { - nm.push(watcher.userId, 'reply'); - } -} - -async function createMentionedEvents(mentionedUsers: User[], note: Note, nm: NotificationManager) { - for (const u of mentionedUsers.filter(u => Users.isLocalUser(u))) { - const threadMuted = await NoteThreadMutings.findOne({ - userId: u.id, - threadId: note.threadId || note.id, - }); - - if (threadMuted) { - continue; - } - - const detailPackedNote = await Notes.pack(note, u, { - detail: true - }); - - publishMainStream(u.id, 'mention', detailPackedNote); - - // Create notification - nm.push(u.id, 'mention'); - } -} - -function saveReply(reply: Note, note: Note) { - Notes.increment({ id: reply.id }, 'repliesCount', 1); -} - -function incNotesCountOfUser(user: { id: User['id']; }) { - Users.createQueryBuilder().update() - .set({ - updatedAt: new Date(), - notesCount: () => '"notesCount" + 1' - }) - .where('id = :id', { id: user.id }) - .execute(); -} - -async function extractMentionedUsers(user: { host: User['host']; }, tokens: mfm.MfmNode[]): Promise { - if (tokens == null) return []; - - const mentions = extractMentions(tokens); - - let mentionedUsers = (await Promise.all(mentions.map(m => - resolveUser(m.username, m.host || user.host).catch(() => null) - ))).filter(x => x != null) as User[]; - - // Drop duplicate users - mentionedUsers = mentionedUsers.filter((u, i, self) => - i === self.findIndex(u2 => u.id === u2.id) - ); - - return mentionedUsers; -} diff --git a/src/services/send-email-notification.ts b/src/services/send-email-notification.ts deleted file mode 100644 index 519d56a06..000000000 --- a/src/services/send-email-notification.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { UserProfiles } from '@/models/index'; -import { User } from '@/models/entities/user'; -import { sendEmail } from './send-email'; -import * as locales from '../../locales/index'; -import { I18n } from '@/misc/i18n'; -import { getAcct } from '@/misc/acct'; - -// TODO: locale ファイルをクライアント用とサーバー用で分けたい - -async function follow(userId: User['id'], follower: User) { - const userProfile = await UserProfiles.findOneOrFail({ userId: userId }); - if (!userProfile.email || !userProfile.emailNotificationTypes.includes('follow')) return; - const locale = locales[userProfile.lang || 'ja-JP']; - const i18n = new I18n(locale); - // TODO: render user information html - sendEmail(userProfile.email, i18n.t('_email._follow.title'), `${follower.name} (@${getAcct(follower)})`, `${follower.name} (@${getAcct(follower)})`); -} - -async function receiveFollowRequest(userId: User['id'], follower: User) { - const userProfile = await UserProfiles.findOneOrFail({ userId: userId }); - if (!userProfile.email || !userProfile.emailNotificationTypes.includes('receiveFollowRequest')) return; - const locale = locales[userProfile.lang || 'ja-JP']; - const i18n = new I18n(locale); - // TODO: render user information html - sendEmail(userProfile.email, i18n.t('_email._receiveFollowRequest.title'), `${follower.name} (@${getAcct(follower)})`, `${follower.name} (@${getAcct(follower)})`); -} - -export const sendEmailNotification = { - follow, - receiveFollowRequest, -}; diff --git a/src/services/send-email.ts b/src/services/send-email.ts deleted file mode 100644 index d24168ec4..000000000 --- a/src/services/send-email.ts +++ /dev/null @@ -1,123 +0,0 @@ -import * as nodemailer from 'nodemailer'; -import { fetchMeta } from '@/misc/fetch-meta'; -import Logger from './logger'; -import config from '@/config/index'; - -export const logger = new Logger('email'); - -export async function sendEmail(to: string, subject: string, html: string, text: string) { - const meta = await fetchMeta(true); - - const iconUrl = `${config.url}/static-assets/mi-white.png`; - const emailSettingUrl = `${config.url}/settings/email`; - - const enableAuth = meta.smtpUser != null && meta.smtpUser !== ''; - - const transporter = nodemailer.createTransport({ - host: meta.smtpHost, - port: meta.smtpPort, - secure: meta.smtpSecure, - ignoreTLS: !enableAuth, - proxy: config.proxySmtp, - auth: enableAuth ? { - user: meta.smtpUser, - pass: meta.smtpPass - } : undefined - } as any); - - try { - // TODO: htmlサニタイズ - const info = await transporter.sendMail({ - from: meta.email!, - to: to, - subject: subject, - text: text, - html: ` - - - - ${ subject } - - - -
-
- -
-
-

${ subject }

-
${ html }
-
- -
- - - - ` - }); - - logger.info('Message sent: %s', info.messageId); - } catch (e) { - logger.error(e); - throw e; - } -} diff --git a/src/services/stream.ts b/src/services/stream.ts deleted file mode 100644 index 2c308a1b5..000000000 --- a/src/services/stream.ts +++ /dev/null @@ -1,129 +0,0 @@ -import { redisClient } from '../db/redis'; -import { User } from '@/models/entities/user'; -import { Note } from '@/models/entities/note'; -import { UserList } from '@/models/entities/user-list'; -import { ReversiGame } from '@/models/entities/games/reversi/game'; -import { UserGroup } from '@/models/entities/user-group'; -import config from '@/config/index'; -import { Antenna } from '@/models/entities/antenna'; -import { Channel } from '@/models/entities/channel'; -import { - StreamChannels, - AdminStreamTypes, - AntennaStreamTypes, - BroadcastTypes, - ChannelStreamTypes, - DriveStreamTypes, - GroupMessagingStreamTypes, - InternalStreamTypes, - MainStreamTypes, - MessagingIndexStreamTypes, - MessagingStreamTypes, - NoteStreamTypes, - ReversiGameStreamTypes, - ReversiStreamTypes, - UserListStreamTypes, - UserStreamTypes -} from '@/server/api/stream/types'; -import { Packed } from '@/misc/schema'; - -class Publisher { - private publish = (channel: StreamChannels, type: string | null, value?: any): void => { - const message = type == null ? value : value == null ? - { type: type, body: null } : - { type: type, body: value }; - - redisClient.publish(config.host, JSON.stringify({ - channel: channel, - message: message - })); - } - - public publishInternalEvent = (type: K, value?: InternalStreamTypes[K]): void => { - this.publish('internal', type, typeof value === 'undefined' ? null : value); - } - - public publishUserEvent = (userId: User['id'], type: K, value?: UserStreamTypes[K]): void => { - this.publish(`user:${userId}`, type, typeof value === 'undefined' ? null : value); - } - - public publishBroadcastStream = (type: K, value?: BroadcastTypes[K]): void => { - this.publish('broadcast', type, typeof value === 'undefined' ? null : value); - } - - public publishMainStream = (userId: User['id'], type: K, value?: MainStreamTypes[K]): void => { - this.publish(`mainStream:${userId}`, type, typeof value === 'undefined' ? null : value); - } - - public publishDriveStream = (userId: User['id'], type: K, value?: DriveStreamTypes[K]): void => { - this.publish(`driveStream:${userId}`, type, typeof value === 'undefined' ? null : value); - } - - public publishNoteStream = (noteId: Note['id'], type: K, value?: NoteStreamTypes[K]): void => { - this.publish(`noteStream:${noteId}`, type, { - id: noteId, - body: value - }); - } - - public publishChannelStream = (channelId: Channel['id'], type: K, value?: ChannelStreamTypes[K]): void => { - this.publish(`channelStream:${channelId}`, type, typeof value === 'undefined' ? null : value); - } - - public publishUserListStream = (listId: UserList['id'], type: K, value?: UserListStreamTypes[K]): void => { - this.publish(`userListStream:${listId}`, type, typeof value === 'undefined' ? null : value); - } - - public publishAntennaStream = (antennaId: Antenna['id'], type: K, value?: AntennaStreamTypes[K]): void => { - this.publish(`antennaStream:${antennaId}`, type, typeof value === 'undefined' ? null : value); - } - - public publishMessagingStream = (userId: User['id'], otherpartyId: User['id'], type: K, value?: MessagingStreamTypes[K]): void => { - this.publish(`messagingStream:${userId}-${otherpartyId}`, type, typeof value === 'undefined' ? null : value); - } - - public publishGroupMessagingStream = (groupId: UserGroup['id'], type: K, value?: GroupMessagingStreamTypes[K]): void => { - this.publish(`messagingStream:${groupId}`, type, typeof value === 'undefined' ? null : value); - } - - public publishMessagingIndexStream = (userId: User['id'], type: K, value?: MessagingIndexStreamTypes[K]): void => { - this.publish(`messagingIndexStream:${userId}`, type, typeof value === 'undefined' ? null : value); - } - - public publishReversiStream = (userId: User['id'], type: K, value?: ReversiStreamTypes[K]): void => { - this.publish(`reversiStream:${userId}`, type, typeof value === 'undefined' ? null : value); - } - - public publishReversiGameStream = (gameId: ReversiGame['id'], type: K, value?: ReversiGameStreamTypes[K]): void => { - this.publish(`reversiGameStream:${gameId}`, type, typeof value === 'undefined' ? null : value); - } - - public publishNotesStream = (note: Packed<'Note'>): void => { - this.publish('notesStream', null, note); - } - - public publishAdminStream = (userId: User['id'], type: K, value?: AdminStreamTypes[K]): void => { - this.publish(`adminStream:${userId}`, type, typeof value === 'undefined' ? null : value); - } -} - -const publisher = new Publisher(); - -export default publisher; - -export const publishInternalEvent = publisher.publishInternalEvent; -export const publishUserEvent = publisher.publishUserEvent; -export const publishBroadcastStream = publisher.publishBroadcastStream; -export const publishMainStream = publisher.publishMainStream; -export const publishDriveStream = publisher.publishDriveStream; -export const publishNoteStream = publisher.publishNoteStream; -export const publishNotesStream = publisher.publishNotesStream; -export const publishChannelStream = publisher.publishChannelStream; -export const publishUserListStream = publisher.publishUserListStream; -export const publishAntennaStream = publisher.publishAntennaStream; -export const publishMessagingStream = publisher.publishMessagingStream; -export const publishGroupMessagingStream = publisher.publishGroupMessagingStream; -export const publishMessagingIndexStream = publisher.publishMessagingIndexStream; -export const publishReversiStream = publisher.publishReversiStream; -export const publishReversiGameStream = publisher.publishReversiGameStream; -export const publishAdminStream = publisher.publishAdminStream; diff --git a/src/tools/resync-remote-user.ts b/src/tools/resync-remote-user.ts deleted file mode 100644 index bc43e250c..000000000 --- a/src/tools/resync-remote-user.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { initDb } from '@/db/postgre'; -import { parseAcct } from '@/misc/acct'; - -async function main(acct: string): Promise { - await initDb(); - const { resolveUser } = await import('@/remote/resolve-user'); - - const { username, host } = parseAcct(acct); - await resolveUser(username, host, {}, true); -} - -// get args -const args = process.argv.slice(2); -let acct = args[0]; - -// normalize args -acct = acct.replace(/^@/, ''); - -// check args -if (!acct.match(/^\w+@\w/)) { - throw `Invalid acct format. Valid format are user@host`; -} - -console.log(`resync ${acct}`); - -main(acct).then(() => { - console.log('Done'); -}).catch(e => { - console.warn(e); -}); diff --git a/src/tsconfig.json b/src/tsconfig.json deleted file mode 100644 index 4a03a1743..000000000 --- a/src/tsconfig.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "compilerOptions": { - "allowJs": true, - "noEmitOnError": false, - "noImplicitAny": true, - "noImplicitReturns": true, - "noUnusedParameters": false, - "noUnusedLocals": false, - "noFallthroughCasesInSwitch": true, - "declaration": false, - "sourceMap": true, - "target": "es2017", - "module": "commonjs", - "moduleResolution": "node", - "allowSyntheticDefaultImports": true, - "removeComments": false, - "noLib": false, - "strict": true, - "strictNullChecks": true, - "strictPropertyInitialization": false, - "experimentalDecorators": true, - "emitDecoratorMetadata": true, - "resolveJsonModule": true, - "isolatedModules": true, - "rootDir": "./", - "baseUrl": "./", - "paths": { - "@/*": ["./*"] - }, - "outDir": "../built", - "typeRoots": [ - "../node_modules/@types", - "./@types" - ], - "lib": [ - "esnext" - ] - }, - "compileOnSave": false, - "include": [ - "./**/*.ts" - ], - "exclude": [ - "./client/**/*.ts" - ] -} diff --git a/src/types.ts b/src/types.ts deleted file mode 100644 index d8eb44281..000000000 --- a/src/types.ts +++ /dev/null @@ -1,5 +0,0 @@ -export const notificationTypes = ['follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'receiveFollowRequest', 'followRequestAccepted', 'groupInvited', 'app'] as const; - -export const noteVisibilities = ['public', 'home', 'followers', 'specified'] as const; - -export const mutedNoteReasons = ['word', 'manual', 'spam', 'other'] as const; diff --git a/src/well-known-services.ts b/src/well-known-services.ts deleted file mode 100644 index f47c54051..000000000 --- a/src/well-known-services.ts +++ /dev/null @@ -1,4 +0,0 @@ -export const wellKnownServices = [ - ['twitter.com', username => `https://twitter.com/${username}`], - ['github.com', username => `https://github.com/${username}`], -] as [string, (username: string) => string][]; diff --git a/test/test.yml b/test/test.yml deleted file mode 100644 index 2d3094653..000000000 --- a/test/test.yml +++ /dev/null @@ -1,12 +0,0 @@ -url: 'http://misskey.local' -port: 61812 -db: - host: localhost - port: 54312 - db: test-misskey - user: postgres - pass: '' -redis: - host: localhost - port: 56312 -id: aid diff --git a/test/utils.ts b/test/utils.ts deleted file mode 100644 index 54bcf65ab..000000000 --- a/test/utils.ts +++ /dev/null @@ -1,212 +0,0 @@ -import * as fs from 'fs'; -import * as WebSocket from 'ws'; -import * as misskey from 'misskey-js'; -import fetch from 'node-fetch'; -const FormData = require('form-data'); -import * as childProcess from 'child_process'; -import * as http from 'http'; -import loadConfig from '../src/config/load'; -import { SIGKILL } from 'constants'; -import { createConnection, getConnection } from 'typeorm'; -import { entities } from '../src/db/postgre'; - -const config = loadConfig(); -export const port = config.port; - -export const async = (fn: Function) => (done: Function) => { - fn().then(() => { - done(); - }, (err: Error) => { - done(err); - }); -}; - -export const request = async (endpoint: string, params: any, me?: any): Promise<{ body: any, status: number }> => { - const auth = me ? { - i: me.token - } : {}; - - const res = await fetch(`http://localhost:${port}/api${endpoint}`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json' - }, - body: JSON.stringify(Object.assign(auth, params)) - }); - - const status = res.status; - const body = res.status !== 204 ? await res.json().catch() : null; - - return { - body, status - }; -}; - -export const signup = async (params?: any): Promise => { - const q = Object.assign({ - username: 'test', - password: 'test' - }, params); - - const res = await request('/signup', q); - - return res.body; -}; - -export const post = async (user: any, params?: misskey.Endpoints['notes/create']['req']): Promise => { - const q = Object.assign({ - text: 'test' - }, params); - - const res = await request('/notes/create', q, user); - - return res.body ? res.body.createdNote : null; -}; - -export const react = async (user: any, note: any, reaction: string): Promise => { - await request('/notes/reactions/create', { - noteId: note.id, - reaction: reaction - }, user); -}; - -export const uploadFile = (user: any, path?: string): Promise => { - const formData = new FormData(); - formData.append('i', user.token); - formData.append('file', fs.createReadStream(path || __dirname + '/resources/Lenna.png')); - - return fetch(`http://localhost:${port}/api/drive/files/create`, { - method: 'post', - body: formData, - timeout: 30 * 1000, - }).then(res => { - if (!res.ok) { - throw `${res.status} ${res.statusText}`; - } else { - return res.json(); - } - }); -}; - -export function connectStream(user: any, channel: string, listener: (message: Record) => any, params?: any): Promise { - return new Promise((res, rej) => { - const ws = new WebSocket(`ws://localhost:${port}/streaming?i=${user.token}`); - - ws.on('open', () => { - ws.on('message', data => { - const msg = JSON.parse(data.toString()); - if (msg.type == 'channel' && msg.body.id == 'a') { - listener(msg.body); - } else if (msg.type == 'connected' && msg.body.id == 'a') { - res(ws); - } - }); - - ws.send(JSON.stringify({ - type: 'connect', - body: { - channel: channel, - id: 'a', - pong: true, - params: params - } - })); - }); - }); -} - -export const simpleGet = async (path: string, accept = '*/*'): Promise<{ status?: number, type?: string, location?: string }> => { - // node-fetchだと3xxを取れない - return await new Promise((resolve, reject) => { - const req = http.request(`http://localhost:${port}${path}`, { - headers: { - Accept: accept - } - }, res => { - if (res.statusCode! >= 400) { - reject(res); - } else { - resolve({ - status: res.statusCode, - type: res.headers['content-type'], - location: res.headers.location, - }); - } - }); - - req.end(); - }); -}; - -export function launchServer(callbackSpawnedProcess: (p: childProcess.ChildProcess) => void, moreProcess: () => Promise = async () => {}) { - return (done: (err?: Error) => any) => { - const p = childProcess.spawn('node', [__dirname + '/../index.js'], { - stdio: ['inherit', 'inherit', 'inherit', 'ipc'], - env: { NODE_ENV: 'test', PATH: process.env.PATH } - }); - callbackSpawnedProcess(p); - p.on('message', message => { - if (message === 'ok') moreProcess().then(() => done()).catch(e => done(e)); - }); - }; -} - -export async function initTestDb(justBorrow = false, initEntities?: any[]) { - if (process.env.NODE_ENV !== 'test') throw 'NODE_ENV is not a test'; - - try { - const conn = await getConnection(); - await conn.close(); - } catch (e) {} - - return await createConnection({ - type: 'postgres', - host: config.db.host, - port: config.db.port, - username: config.db.user, - password: config.db.pass, - database: config.db.db, - synchronize: true && !justBorrow, - dropSchema: true && !justBorrow, - entities: initEntities || entities - }); -} - -export function startServer(timeout = 30 * 1000): Promise { - return new Promise((res, rej) => { - const t = setTimeout(() => { - p.kill(SIGKILL); - rej('timeout to start'); - }, timeout); - - const p = childProcess.spawn('node', [__dirname + '/../index.js'], { - stdio: ['inherit', 'inherit', 'inherit', 'ipc'], - env: { NODE_ENV: 'test', PATH: process.env.PATH } - }); - - p.on('error', e => rej(e)); - - p.on('message', message => { - if (message === 'ok') { - clearTimeout(t); - res(p); - } - }); - }); -} - -export function shutdownServer(p: childProcess.ChildProcess, timeout = 20 * 1000) { - return new Promise((res, rej) => { - const t = setTimeout(() => { - p.kill(SIGKILL); - res('force exit'); - }, timeout); - - p.once('exit', () => { - clearTimeout(t); - res('exited'); - }); - - p.kill(); - }); -} diff --git a/tslint.json b/tslint.json deleted file mode 100644 index e0ca176f6..000000000 --- a/tslint.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "defaultSeverity": "error", - "extends": [ - "tslint:recommended", - "tslint-sonarts" - ], - "jsRules": {}, - "rules": { - "align": false, - "indent": [true, "tabs"], - "quotemark": [true, "single"], - "no-var-requires": false, - "no-string-throw": false, - "trailing-comma": [false], - "object-literal-sort-keys": false, - "curly": false, - "no-console": [false], - "no-empty": false, - "ordered-imports": [false], - "arrow-parens": false, - "array-type": [true, "array"], - "object-literal-shorthand": false, - "object-literal-key-quotes": false, - "triple-equals": [false], - "no-shadowed-variable": false, - "no-string-literal": false, - "no-conditional-assignment": false, - "variable-name": [false], - "comment-format": [false], - "interface-over-type-literal": false, - "max-line-length": [false], - "max-classes-per-file": false, - "member-ordering": [false], - "radix": false, - "ban-types": [ - true, - ["Object", "Use {} instead."] - ], - "ban": [ - true, - { "name": ["*", "forEach"], "message": "Use for-of loop instead." } - ], - "no-duplicate-string": false, - "no-commented-code": false, - "cognitive-complexity": false, - "no-nested-template-literals": false, - "no-identical-functions": false, - "max-union-size": false, - "no-big-function": false, - "no-statements-same-line": false, - "no-small-switch": false, - "no-identical-expressions": false, - "no-invalid-await": false, - "prefer-immediate-return": false, - "no-use-of-empty-return-value": false, - "no-collapsible-if": false, - "no-ignored-return": false, - "no-redundant-boolean": false, - "prefer-promise-shorthand": false, - "parameters-max-number": false, - "no-duplicated-branches": false, - "no-identical-conditions": false, - "no-useless-cast": false, - "no-hardcoded-credentials": false, - "no-nested-switch": false, - "unified-signatures": false, - "no-all-duplicated-branches": false, - "semicolon": [true, "always"] - }, - "rulesDirectory": [] -} diff --git a/vetur.config.js b/vetur.config.js deleted file mode 100644 index 875ec6571..000000000 --- a/vetur.config.js +++ /dev/null @@ -1,41 +0,0 @@ -// vetur.config.js -/** @type {import('vls').VeturConfig} */ -module.exports = { - // **optional** default: `{}` - // override vscode settings - // Notice: It only affects the settings used by Vetur. - settings: { - "vetur.useWorkspaceDependencies": true, - "vetur.experimental.templateInterpolationService": true - }, - // **optional** default: `[{ root: './' }]` - // support monorepos - projects: [ - { - // **required** - // Where is your project? - // It is relative to `vetur.config.js`. - root: './src/client', - // **optional** default: `'package.json'` - // Where is `package.json` in the project? - // We use it to determine the version of vue. - // It is relative to root property. - package: '../../package.json', - // **optional** - // Where is TypeScript config file in the project? - // It is relative to root property. - tsconfig: './tsconfig.json', - // **optional** default: `'./.vscode/vetur/snippets'` - // Where is vetur custom snippets folders? - snippetFolder: './.vscode/vetur/snippets', - // **optional** default: `[]` - // Register globally Vue component glob. - // If you set it, you can get completion by that components. - // It is relative to root property. - // Notice: It won't actually do it. You need to use `require.context` or `Vue.component` - globalComponents: [ - './src/clients/components/global/*.vue' - ] - } - ] -} diff --git a/webpack.config.ts b/webpack.config.ts deleted file mode 100644 index 74426df2e..000000000 --- a/webpack.config.ts +++ /dev/null @@ -1,193 +0,0 @@ -/** - * webpack configuration - */ - -import * as fs from 'fs'; -import * as webpack from 'webpack'; -const { VueLoaderPlugin } = require('vue-loader'); - -class WebpackOnBuildPlugin { - constructor(readonly callback: (stats: any) => void) { - } - - public apply(compiler: any) { - compiler.hooks.done.tap('WebpackOnBuildPlugin', this.callback); - } -} - -const isProduction = process.env.NODE_ENV === 'production'; - -const locales = require('./locales'); -const meta = require('./package.json'); - -const postcss = { - loader: 'postcss-loader', - options: { - postcssOptions: { - plugins: [ - require('cssnano')({ - preset: 'default' - }) - ] - } - }, -}; - -module.exports = { - entry: { - app: './src/client/init.ts', - sw: './src/client/sw/sw.ts' - }, - module: { - rules: [{ - test: /\.vue$/, - exclude: /node_modules/, - use: [{ - loader: 'vue-loader', - options: { - cssSourceMap: false, - compilerOptions: { - preserveWhitespace: false - } - } - }] - }, { - test: /\.scss?$/, - exclude: /node_modules/, - oneOf: [{ - resourceQuery: /module/, - use: [{ - loader: 'vue-style-loader' - }, { - loader: 'css-loader', - options: { - modules: true, - esModule: false, // TODO: trueにすると壊れる。Vue3移行の折にはtrueにできるかもしれない - url: false, - } - }, postcss, { - loader: 'sass-loader', - options: { - implementation: require('sass'), - sassOptions: { - fiber: false - } - } - }] - }, { - use: [{ - loader: 'vue-style-loader' - }, { - loader: 'css-loader', - options: { - url: false, - esModule: false, // TODO: trueにすると壊れる。Vue3移行の折にはtrueにできるかもしれない - } - }, postcss, { - loader: 'sass-loader', - options: { - implementation: require('sass'), - sassOptions: { - fiber: false - } - } - }] - }] - }, { - test: /\.css$/, - oneOf: [{ - resourceQuery: /module/, - use: [{ - loader: 'vue-style-loader' - }, { - loader: 'css-loader', - options: { - modules: true, - esModule: false, // TODO: trueにすると壊れる。Vue3移行の折にはtrueにできるかもしれない - } - }, postcss] - }, { - use: [{ - loader: 'vue-style-loader' - }, { - loader: 'css-loader', - options: { - esModule: false, // TODO: trueにすると壊れる。Vue3移行の折にはtrueにできるかもしれない - } - }, postcss] - }] - }, { - test: /\.svg$/, - use: [ - 'vue-loader', - 'vue-svg-loader', - ], - }, { - test: /\.(eot|woff|woff2|svg|ttf)([?]?.*)$/, - type: 'asset/resource' - }, { - test: /\.json5$/, - loader: 'json5-loader', - options: { - esModule: false, - }, - type: 'javascript/auto' - }, { - test: /\.ts$/, - exclude: /node_modules/, - use: [{ - loader: 'ts-loader', - options: { - happyPackMode: true, - transpileOnly: true, - configFile: __dirname + '/src/client/tsconfig.json', - appendTsSuffixTo: [/\.vue$/] - } - }] - }] - }, - plugins: [ - new webpack.ProgressPlugin({}), - new webpack.DefinePlugin({ - _VERSION_: JSON.stringify(meta.version), - _LANGS_: JSON.stringify(Object.entries(locales).map(([k, v]: [string, any]) => [k, v._lang_])), - _ENV_: JSON.stringify(process.env.NODE_ENV), - _DEV_: process.env.NODE_ENV !== 'production', - _PERF_PREFIX_: JSON.stringify('Misskey:'), - _DATA_TRANSFER_DRIVE_FILE_: JSON.stringify('mk_drive_file'), - _DATA_TRANSFER_DRIVE_FOLDER_: JSON.stringify('mk_drive_folder'), - _DATA_TRANSFER_DECK_COLUMN_: JSON.stringify('mk_deck_column'), - __VUE_OPTIONS_API__: true, - __VUE_PROD_DEVTOOLS__: false, - }), - new VueLoaderPlugin(), - new WebpackOnBuildPlugin((stats: any) => { - fs.writeFileSync('./built/meta.json', JSON.stringify({ version: meta.version }), 'utf-8'); - }), - ], - output: { - path: __dirname + '/built/assets', - filename: `[name].${meta.version}.js`, - publicPath: `/assets/`, - pathinfo: false, - }, - resolve: { - extensions: [ - '.js', '.ts', '.json' - ], - alias: { - '@client': __dirname + '/src/client', - '@lib': __dirname + '/lib', - '@': __dirname + '/src', - 'const.styl': __dirname + '/src/client/const.styl' - } - }, - resolveLoader: { - modules: ['node_modules'] - }, - experiments: { - topLevelAwait: true - }, - devtool: false, //'source-map', - mode: isProduction ? 'production' : 'development' -}; diff --git a/yarn.lock b/yarn.lock index e29de996b..792e08830 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,74 +2,10 @@ # yarn lockfile v1 -"@babel/code-frame@^7.0.0": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.13.tgz#dcfc826beef65e75c50e21d3837d7d95798dd658" - integrity sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g== - dependencies: - "@babel/highlight" "^7.12.13" - -"@babel/helper-validator-identifier@^7.12.11": - version "7.12.11" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed" - integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw== - -"@babel/highlight@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.12.13.tgz#8ab538393e00370b26271b01fa08f7f27f2e795c" - integrity sha512-kocDQvIbgMKlWxXe9fof3TQ+gkIPOUSEYhJjqUjvKMez3krV7vbzYCDq39Oj11UAVK7JqPVGQPlgE85dPNlQww== - dependencies: - "@babel/helper-validator-identifier" "^7.12.11" - chalk "^2.0.0" - js-tokens "^4.0.0" - -"@babel/parser@^7.15.0": - version "7.15.6" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.15.6.tgz#043b9aa3c303c0722e5377fef9197f4cf1796549" - integrity sha512-S/TSCcsRuCkmpUuoWijua0Snt+f3ewU/8spLo+4AXJCZfT0bVCzLD5MuOKdrx0mlAptbKzn5AdgEIIKXxXkz9Q== - -"@babel/parser@^7.6.0", "@babel/parser@^7.9.6": - version "7.13.9" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.13.9.tgz#ca34cb95e1c2dd126863a84465ae8ef66114be99" - integrity sha512-nEUfRiARCcaVo3ny3ZQjURjHQZUo/JkEw7rLlSZy/psWGnvwXFtPcr6jb7Yb41DVW5LTe6KRq9LGleRNsg1Frw== - -"@babel/runtime@^7.6.2", "@babel/runtime@^7.7.2": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.13.tgz#0a21452352b02542db0ffb928ac2d3ca7cb6d66d" - integrity sha512-8+3UMPBrjFa/6TtKi/7sehPKqfAm4g6K+YQjyyFOLUTxzOngcRZTlAVY8sc2CORJYqdHQY8gRPHmn+qo15rCBw== - dependencies: - regenerator-runtime "^0.13.4" - -"@babel/types@^7.6.1", "@babel/types@^7.9.6": - version "7.13.0" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.13.0.tgz#74424d2816f0171b4100f0ab34e9a374efdf7f80" - integrity sha512-hE+HE8rnG1Z6Wzo+MhaKE5lM5eMx71T4EHJgku2E3xIfaULhDcxiiRxUYgwX8qwP1BBSlag+TdGOt6JAidIZTA== - dependencies: - "@babel/helper-validator-identifier" "^7.12.11" - lodash "^4.17.19" - to-fast-properties "^2.0.0" - -"@cspotcode/source-map-consumer@0.8.0": - version "0.8.0" - resolved "https://registry.yarnpkg.com/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz#33bf4b7b39c178821606f669bbc447a6a629786b" - integrity sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg== - -"@cspotcode/source-map-support@0.7.0": - version "0.7.0" - resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz#4789840aa859e46d2f3173727ab707c66bf344f5" - integrity sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA== - dependencies: - "@cspotcode/source-map-consumer" "0.8.0" - -"@cto.af/textdecoder@^0.0.0": - version "0.0.0" - resolved "https://registry.yarnpkg.com/@cto.af/textdecoder/-/textdecoder-0.0.0.tgz#e1e8d84c936c30a0f4619971f19ca41941af9fdc" - integrity sha512-sJpx3F5xcVV/9jNYJQtvimo4Vfld/nD3ph+ZWtQzZ03Zo8rJC7QKQTRcIGS13Rcz80DwFNthCWMrd58vpY4ZAQ== - -"@cypress/request@^2.88.6": - version "2.88.6" - resolved "https://registry.yarnpkg.com/@cypress/request/-/request-2.88.6.tgz#a970dd675befc6bdf8a8921576c01f51cc5798e9" - integrity sha512-z0UxBE/+qaESAHY9p9sM2h8Y4XqtsbDCt0/DPOrqA/RZgKi4PkxdpXyK4wCCnSk1xHqWHZZAE+gV6aDAR6+caQ== +"@cypress/request@^2.88.7": + version "2.88.7" + resolved "https://registry.yarnpkg.com/@cypress/request/-/request-2.88.7.tgz#386d960ab845a96953723348088525d5a75aaac4" + integrity sha512-FTULIP2rnDJvZDT9t6B4nSfYR40ue19tVmv3wUcY05R9/FPCoMl1nAPJkzWzBCo7ltVn5ThQTbxiMoGBN7k0ig== dependencies: aws-sign2 "~0.7.0" aws4 "^1.8.0" @@ -99,56 +35,6 @@ debug "^3.1.0" lodash.once "^4.1.1" -"@digitalbazaar/http-client@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@digitalbazaar/http-client/-/http-client-1.1.0.tgz#cac383b24ace04b18b919deab773462b03d3d7b0" - integrity sha512-ks7hqa6hm9NyULdbm9qL6TRS8rADzBw8R0lETvUgvdNXu9H62XG2YqoKRDThtfgWzWxLwRJ3Z2o4ev81dZZbyQ== - dependencies: - esm "^3.2.22" - ky "^0.25.1" - ky-universal "^0.8.2" - -"@discordapp/twemoji@13.1.0": - version "13.1.0" - resolved "https://registry.yarnpkg.com/@discordapp/twemoji/-/twemoji-13.1.0.tgz#6b25f3958fa8fd68692248c87776bc737fd009a9" - integrity sha512-KEw/te+ylD2MHutzigafyptv0kdTU05Dbgxr9Y5J9IAQw8PbFz16nKtlPnJtA23BLp9fZQeNXzUmegkRi7fpDA== - dependencies: - fs-extra "^8.0.1" - jsonfile "^5.0.0" - twemoji-parser "13.1.0" - universalify "^0.1.2" - -"@discoveryjs/json-ext@^0.5.0": - version "0.5.2" - resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.2.tgz#8f03a22a04de437254e8ce8cc84ba39689288752" - integrity sha512-HyYEUDeIj5rRQU2Hk5HTB2uHsbRQpF70nvMhVzi+VJR0X+xNEhjPui4/kBf3VeH/wqD28PT4sVOm8qqLjBrSZg== - -"@elastic/elasticsearch@7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@elastic/elasticsearch/-/elasticsearch-7.11.0.tgz#e196243d0ed026742fc160d72cc5b4b5b6c7807d" - integrity sha512-AFVVuANIdbV1qYjuOi4hnsX/DehWYG+bbhQO4amq9K4/NnzU7mpGWOPgVlRQTiX+vBfBkx7SL6h4QEjIlM3ztA== - dependencies: - debug "^4.1.1" - hpagent "^0.1.1" - ms "^2.1.1" - pump "^3.0.0" - secure-json-parse "^2.1.0" - -"@eslint/eslintrc@^1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.0.3.tgz#41f08c597025605f672251dcc4e8be66b5ed7366" - integrity sha512-DHI1wDPoKCBPoLZA3qDR91+3te/wDSc1YhKg3jR8NxKKRJq2hwHwcWv31cSwSYvIBrmbENoYMWcenW8uproQqg== - dependencies: - ajv "^6.12.4" - debug "^4.3.2" - espree "^9.0.0" - globals "^13.9.0" - ignore "^4.0.6" - import-fresh "^3.2.1" - js-yaml "^3.13.1" - minimatch "^3.0.4" - strip-json-comments "^3.1.1" - "@hapi/hoek@^9.0.0": version "9.2.0" resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.2.0.tgz#f3933a44e365864f4dad5db94158106d511e8131" @@ -161,88 +47,6 @@ dependencies: "@hapi/hoek" "^9.0.0" -"@humanwhocodes/config-array@^0.6.0": - version "0.6.0" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.6.0.tgz#b5621fdb3b32309d2d16575456cbc277fa8f021a" - integrity sha512-JQlEKbcgEUjBFhLIF4iqM7u/9lwgHRBcpHrmUNCALK0Q3amXN6lxdoXLnF0sm11E9VqTmBALR87IlUg1bZ8A9A== - dependencies: - "@humanwhocodes/object-schema" "^1.2.0" - debug "^4.1.1" - minimatch "^3.0.4" - -"@humanwhocodes/object-schema@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz#87de7af9c231826fdd68ac7258f77c429e0e5fcf" - integrity sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w== - -"@jfonx/console-utils@^1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@jfonx/console-utils/-/console-utils-1.0.3.tgz#cbb7f911e4191a4a2fe1ba4807d29f100b5d099f" - integrity sha512-/XbnqjWc7yNZVLAJJO9rimfIz9DYte+cj3EF9hwhIv7vw6ok2t3cjl0huYsmD89srKH03vWjeqAcIH86CuYj3g== - dependencies: - colors "^1.3.3" - -"@jfonx/file-utils@^3.0.1": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@jfonx/file-utils/-/file-utils-3.0.1.tgz#8d3d6e931a283420fe29802ea71c28dd397cd8d3" - integrity sha512-qwH0CuzWmghtTHGMyuPHj6SJPQgWeiXFJBfrxCWMbzxVCa3aLZPEfzSdlSnC/UABsk6feRkNdHXw59rVshNPqw== - dependencies: - "@jfonx/console-utils" "^1.0.3" - comment-json "^4.1.0" - find-up "^4.1.0" - -"@koa/cors@3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@koa/cors/-/cors-3.1.0.tgz#618bb073438cfdbd3ebd0e648a76e33b84f3a3b2" - integrity sha512-7ulRC1da/rBa6kj6P4g2aJfnET3z8Uf3SWu60cjbtxTA5g8lxRdX/Bd2P92EagGwwAhANeNw8T8if99rJliR6Q== - dependencies: - vary "^1.1.2" - -"@koa/multer@3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@koa/multer/-/multer-3.0.0.tgz#439777949f28097d7b329c0b4ce3048074c862f8" - integrity sha512-y+OQBmex5D1jIl723gAEUYcAWPEicIXppaAKw/zCMfpllQ08ZNweDPwoCLxEoatqd5pCu2XG6V8dl67JRq3RJw== - -"@koa/router@9.0.1": - version "9.0.1" - resolved "https://registry.yarnpkg.com/@koa/router/-/router-9.0.1.tgz#4090a14223ea7e78aa13b632761209cba69acd95" - integrity sha512-OI+OU49CJV4px0WkIMmayBeqVXB/JS1ZMq7UoGlTZt6Y7ijK7kdeQ18+SEHHJPytmtI1y6Hf8XLrpxva3mhv5Q== - dependencies: - debug "^4.1.1" - http-errors "^1.7.3" - koa-compose "^4.1.0" - methods "^1.1.2" - path-to-regexp "^6.1.0" - -"@nodelib/fs.scandir@2.1.3": - version "2.1.3" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz#3a582bdb53804c6ba6d146579c46e52130cf4a3b" - integrity sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw== - dependencies: - "@nodelib/fs.stat" "2.0.3" - run-parallel "^1.1.9" - -"@nodelib/fs.stat@2.0.3", "@nodelib/fs.stat@^2.0.2": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz#34dc5f4cabbc720f4e60f75a747e7ecd6c175bd3" - integrity sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA== - -"@nodelib/fs.walk@^1.2.3": - version "1.2.4" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz#011b9202a70a6366e436ca5c065844528ab04976" - integrity sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ== - dependencies: - "@nodelib/fs.scandir" "2.1.3" - fastq "^1.6.0" - -"@npmcli/move-file@^1.0.1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-1.1.2.tgz#1a82c3e372f7cae9253eb66d72543d6b8685c674" - integrity sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg== - dependencies: - mkdirp "^1.0.4" - rimraf "^3.0.2" - "@redocly/ajv@^8.6.2": version "8.6.2" resolved "https://registry.yarnpkg.com/@redocly/ajv/-/ajv-8.6.2.tgz#8c4e485e72f7864f91fae40093bed548ec2619b2" @@ -268,69 +72,6 @@ node-fetch "^2.6.1" yaml-ast-parser "0.0.43" -"@sentry/browser@5.29.2": - version "5.29.2" - resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-5.29.2.tgz#51adb4005511b1a4a70e4571880fc6653d651f91" - integrity sha512-uxZ7y7rp85tJll+RZtXRhXPbnFnOaxZqJEv05vJlXBtBNLQtlczV5iCtU9mZRLVHDtmZ5VVKUV8IKXntEqqDpQ== - dependencies: - "@sentry/core" "5.29.2" - "@sentry/types" "5.29.2" - "@sentry/utils" "5.29.2" - tslib "^1.9.3" - -"@sentry/core@5.29.2": - version "5.29.2" - resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.29.2.tgz#9e05fe197234161d57aabaf52fab336a7c520d81" - integrity sha512-7WYkoxB5IdlNEbwOwqSU64erUKH4laavPsM0/yQ+jojM76ErxlgEF0u//p5WaLPRzh3iDSt6BH+9TL45oNZeZw== - dependencies: - "@sentry/hub" "5.29.2" - "@sentry/minimal" "5.29.2" - "@sentry/types" "5.29.2" - "@sentry/utils" "5.29.2" - tslib "^1.9.3" - -"@sentry/hub@5.29.2": - version "5.29.2" - resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-5.29.2.tgz#208f10fe6674695575ad74182a1151f71d6df00a" - integrity sha512-LaAIo2hwUk9ykeh9RF0cwLy6IRw+DjEee8l1HfEaDFUM6TPGlNNGObMJNXb9/95jzWp7jWwOpQjoIE3jepdQJQ== - dependencies: - "@sentry/types" "5.29.2" - "@sentry/utils" "5.29.2" - tslib "^1.9.3" - -"@sentry/minimal@5.29.2": - version "5.29.2" - resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-5.29.2.tgz#420bebac8d03d30980fdb05c72d7b253d8aa541b" - integrity sha512-0aINSm8fGA1KyM7PavOBe1GDZDxrvnKt+oFnU0L+bTcw8Lr+of+v6Kwd97rkLRNOLw621xP076dL/7LSIzMuhw== - dependencies: - "@sentry/hub" "5.29.2" - "@sentry/types" "5.29.2" - tslib "^1.9.3" - -"@sentry/tracing@5.29.2": - version "5.29.2" - resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-5.29.2.tgz#6012788547d2ab7893799d82c4941bda145dcd47" - integrity sha512-iumYbVRpvoU3BUuIooxibydeaOOjl5ysc+mzsqhRs2NGW/C3uKAsFXdvyNfqt3bxtRQwJEhwJByLP2u3pLThpw== - dependencies: - "@sentry/hub" "5.29.2" - "@sentry/minimal" "5.29.2" - "@sentry/types" "5.29.2" - "@sentry/utils" "5.29.2" - tslib "^1.9.3" - -"@sentry/types@5.29.2": - version "5.29.2" - resolved "https://registry.yarnpkg.com/@sentry/types/-/types-5.29.2.tgz#ac87383df1222c2d9b9f8f9ed7a6b86ea41a098a" - integrity sha512-dM9wgt8wy4WRty75QkqQgrw9FV9F+BOMfmc0iaX13Qos7i6Qs2Q0dxtJ83SoR4YGtW8URaHzlDtWlGs5egBiMA== - -"@sentry/utils@5.29.2": - version "5.29.2" - resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-5.29.2.tgz#99a5cdda2ea19d34a41932f138d470adcb3ee673" - integrity sha512-nEwQIDjtFkeE4k6yIk4Ka5XjGRklNLThWLs2xfXlL7uwrYOH2B9UBBOOIRUraBm/g/Xrra3xsam/kRxuiwtXZQ== - dependencies: - "@sentry/types" "5.29.2" - tslib "^1.9.3" - "@sideway/address@^4.1.0": version "4.1.2" resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.2.tgz#811b84333a335739d3969cfc434736268170cad1" @@ -348,202 +89,11 @@ resolved "https://registry.yarnpkg.com/@sideway/pinpoint/-/pinpoint-2.0.0.tgz#cff8ffadc372ad29fd3f78277aeb29e632cc70df" integrity sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ== -"@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== - -"@sinonjs/commons@^1.7.0": - version "1.7.2" - resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.7.2.tgz#505f55c74e0272b43f6c52d81946bed7058fc0e2" - integrity sha512-+DUO6pnp3udV/v2VfUWgaY5BIE1IfT7lLfeDzPVeMT1XKkaAp9LgSI9x5RtrFQoZ9Oi0PgXQQHPaoKu7dCjVxw== - 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== - dependencies: - "@sinonjs/commons" "^1.7.0" - -"@sqltools/formatter@^1.2.2": - version "1.2.3" - resolved "https://registry.yarnpkg.com/@sqltools/formatter/-/formatter-1.2.3.tgz#1185726610acc37317ddab11c3c7f9066966bd20" - integrity sha512-O3uyB/JbkAEMZaP3YqyHH7TMnex7tWyCbCI4EfJdOCoN6HIhqdJBWTM6aCCiWQ/5f5wxjgU735QAIpJbjDvmzg== - -"@syuilo/aiscript@0.11.1": - version "0.11.1" - resolved "https://registry.yarnpkg.com/@syuilo/aiscript/-/aiscript-0.11.1.tgz#52c14692113c58d1d62e6ae696352ba49abdf2eb" - integrity sha512-chwOIA3yLUKvOB0G611hjLArKTeOWNmTm3lHERSaDW1d+dS6do56naX6Lkwy2UpnwWC0qzeNSgg35elk6t2gZg== - dependencies: - autobind-decorator "2.4.0" - chalk "4.0.0" - seedrandom "3.0.5" - stringz "2.1.0" - uuid "7.0.3" - -"@szmarczak/http-timer@^4.0.5": - version "4.0.5" - resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.5.tgz#bfbd50211e9dfa51ba07da58a14cdfd333205152" - integrity sha512-PyRA9sm1Yayuj5OIoJ1hGt2YISX45w9WcFbh6ddT0Z/0yaFxOtGLInr4jUfU1EAFVs0Yfyfev4RNwBlUaHdlDQ== - dependencies: - defer-to-connect "^2.0.0" - -"@tokenizer/token@^0.3.0": - version "0.3.0" - resolved "https://registry.yarnpkg.com/@tokenizer/token/-/token-0.3.0.tgz#fe98a93fe789247e998c75e74e9c7c63217aa276" - integrity sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A== - -"@tootallnate/once@1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" - integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== - -"@trysound/sax@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.1.1.tgz#3348564048e7a2d7398c935d466c0414ebb6a669" - integrity sha512-Z6DoceYb/1xSg5+e+ZlPZ9v0N16ZvZ+wYMraFue4HYrE4ttONKtsvruIRf6t9TBR0YvSOfi1hUU0fJfBLCDYow== - -"@tsconfig/node10@^1.0.7": - version "1.0.7" - resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.7.tgz#1eb1de36c73478a2479cc661ef5af1c16d86d606" - integrity sha512-aBvUmXLQbayM4w3A8TrjwrXs4DZ8iduJnuJLLRGdkWlyakCf1q6uHZJBzXoRA/huAEknG5tcUyQxN3A+In5euQ== - -"@tsconfig/node12@^1.0.7": - version "1.0.7" - resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.7.tgz#677bd9117e8164dc319987dd6ff5fc1ba6fbf18b" - integrity sha512-dgasobK/Y0wVMswcipr3k0HpevxFJLijN03A8mYfEPvWvOs14v0ZlYTR4kIgMx8g4+fTyTFv8/jLCIfRqLDJ4A== - -"@tsconfig/node14@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.0.tgz#5bd046e508b1ee90bc091766758838741fdefd6e" - integrity sha512-RKkL8eTdPv6t5EHgFKIVQgsDapugbuOptNd9OOunN/HAkzmmTnZELx1kNCK0rSdUYGmiFMM3rRQMAWiyp023LQ== - -"@tsconfig/node16@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.2.tgz#423c77877d0569db20e1fc80885ac4118314010e" - integrity sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA== - -"@types/accepts@*": - version "1.3.5" - resolved "https://registry.yarnpkg.com/@types/accepts/-/accepts-1.3.5.tgz#c34bec115cfc746e04fe5a059df4ce7e7b391575" - integrity sha512-jOdnI/3qTpHABjM5cx1Hc0sKsPoYCp+DP/GJRGtDlPd7fiV9oXGGIcjW/ZOxLIvjGz8MA+uMZI9metHlgqbgwQ== - 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" - integrity sha512-LiMQ6EOPob/4yUL66SZzu6Yh77cbzJFYll+ZfaPiPPFswtIlA/Fs1MzdKYA7JApHU49zQTbJGX3PDmCpIdDBRQ== - -"@types/body-parser@*": - version "1.19.0" - resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.0.tgz#0685b3c47eb3006ffed117cdd55164b61f80538f" - integrity sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ== - dependencies: - "@types/connect" "*" - "@types/node" "*" - -"@types/bull@3.15.5": - version "3.15.5" - resolved "https://registry.yarnpkg.com/@types/bull/-/bull-3.15.5.tgz#a4459c127c5b10fb847531579a2cd5db35751366" - integrity sha512-XgJQWJ03jyKMfdoL8IAIoHIo7JkkL74kcxuujTONkSJswm0giIJ9kuVgDNHS0OvD+OiPNcFmbBl0H3scj2+A8A== - dependencies: - "@types/ioredis" "*" - -"@types/cacheable-request@^6.0.1": - version "6.0.1" - resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.1.tgz#5d22f3dded1fd3a84c0bbeb5039a7419c2c91976" - integrity sha512-ykFq2zmBGOCbpIXtoVbz4SKY5QriWPh3AjyU4G74RYbtt5yOc5OfaY75ftjg7mikMOla1CTGpX3lLbuJh8DTrQ== - dependencies: - "@types/http-cache-semantics" "*" - "@types/keyv" "*" - "@types/node" "*" - "@types/responselike" "*" - -"@types/cbor@6.0.0": - version "6.0.0" - resolved "https://registry.yarnpkg.com/@types/cbor/-/cbor-6.0.0.tgz#ddead015e14ef4463287d40cd92a6297a34dac8d" - integrity sha512-mGQ1lbYOwVti5Xlarn1bTeBZqgY0kstsdjnkoEovgohYKdBjGejHyNGXHdMBeqyQazIv32Jjp33+5pBEaSRy2w== - dependencies: - cbor "*" - -"@types/cheerio@0.22.18": - version "0.22.18" - resolved "https://registry.yarnpkg.com/@types/cheerio/-/cheerio-0.22.18.tgz#19018dceae691509901e339d63edf1e935978fe6" - integrity sha512-Fq7R3fINAPSdUEhOyjG4iVxgHrOnqDJbY0/BUuiN0pvD/rfmZWekVZnv+vcs8TtpA2XF50uv50LaE4EnpEL/Hw== - dependencies: - "@types/node" "*" - "@types/color-name@^1.1.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== -"@types/connect@*": - version "3.4.33" - resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.33.tgz#31610c901eca573b8713c3330abc6e6b9f588546" - integrity sha512-2+FrkXY4zllzTNfJth7jOqEHC+enpLeGslEhpnTAkg21GkRrWV4SsAtqchtT4YS9/nODBU2/ZfsBY2X4J/dX7A== - dependencies: - "@types/node" "*" - -"@types/content-disposition@*": - version "0.5.3" - resolved "https://registry.yarnpkg.com/@types/content-disposition/-/content-disposition-0.5.3.tgz#0aa116701955c2faa0717fc69cd1596095e49d96" - integrity sha512-P1bffQfhD3O4LW0ioENXUhZ9OIa0Zn+P7M+pWgkCKaT53wVLSq0mrKksCID/FGHpFhRSxRGhgrQmfhRuzwtKdg== - -"@types/cookies@*": - version "0.7.4" - resolved "https://registry.yarnpkg.com/@types/cookies/-/cookies-0.7.4.tgz#26dedf791701abc0e36b5b79a5722f40e455f87b" - integrity sha512-oTGtMzZZAVuEjTwCjIh8T8FrC8n/uwy+PG0yTvQcdZ7etoel7C7/3MSd7qrukENTgQtotG7gvBlBojuVs7X5rw== - dependencies: - "@types/connect" "*" - "@types/express" "*" - "@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/escape-regexp@0.0.0": - version "0.0.0" - resolved "https://registry.yarnpkg.com/@types/escape-regexp/-/escape-regexp-0.0.0.tgz#bff0225f9ef30d0dbdbe0e2a24283ee5342990c3" - integrity sha512-HTansGo4tJ7K7W9I9LBdQqnHtPB/Y7tlS+EMrkboaAQLsRPhRpHaqAHe01K1HVXM5e1u1IplRd8EBh+pJrp7Dg== - -"@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/estree@^0.0.50": - version "0.0.50" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.50.tgz#1e0caa9364d3fccd2931c3ed96fdbeaa5d4cca83" - integrity sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw== - "@types/events@*": version "3.0.0" resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" @@ -554,29 +104,6 @@ resolved "https://registry.yarnpkg.com/@types/expect/-/expect-1.20.4.tgz#8288e51737bf7e3ab5d7c77bfa695883745264e5" integrity sha512-Q5Vn3yjTDyCMV50TB6VRIbQNxSE4OmZR86VSbGaNpfUolm0iePBB4KdEEHmxoY5sT2+2DIvXW0rvMDP2nHZ4Mg== -"@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" - integrity sha512-578YH5Lt88AKoADy0b2jQGwJtrBxezXtVe/MBqWXKZpqx91SnC0pVkVCcxcytz3lWW+cHBYDi3Ysh0WXc+rAYw== - dependencies: - "@types/node" "*" - "@types/range-parser" "*" - -"@types/express@*": - version "4.17.6" - resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.6.tgz#6bce49e49570507b86ea1b07b806f04697fac45e" - integrity sha512-n/mr9tZI83kd4azlPG5y997C/M4DNABK9yErhFM6hKdym4kkmd9j0vtsJyjFIwfRBxtrxZtAfGZCNRIBMFLK5w== - dependencies: - "@types/body-parser" "*" - "@types/express-serve-static-core" "*" - "@types/qs" "*" - "@types/serve-static" "*" - -"@types/fancy-log@1.3.0": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@types/fancy-log/-/fancy-log-1.3.0.tgz#a61ab476e5e628cd07a846330df53b85e05c8ce0" - integrity sha512-mQjDxyOM1Cpocd+vm1kZBP7smwKZ4TNokFeds9LV7OZibmPJFEzY3+xZMrKfUdNT71lv8GoCPD6upKwHxubClw== - "@types/fluent-ffmpeg@2.1.17": version "2.1.17" resolved "https://registry.yarnpkg.com/@types/fluent-ffmpeg/-/fluent-ffmpeg-2.1.17.tgz#6958dda400fe1b33c21f3683db76905cb210d053" @@ -601,14 +128,6 @@ "@types/minimatch" "*" "@types/node" "*" -"@types/glob@7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb" - integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA== - dependencies: - "@types/minimatch" "*" - "@types/node" "*" - "@types/gulp-rename@2.0.1": version "2.0.1" resolved "https://registry.yarnpkg.com/@types/gulp-rename/-/gulp-rename-2.0.1.tgz#c8228fc2c5c4a7500346ea9ce18f27fa988caef5" @@ -626,413 +145,21 @@ "@types/vinyl-fs" "*" chokidar "^3.3.1" -"@types/http-assert@*": - version "1.5.1" - resolved "https://registry.yarnpkg.com/@types/http-assert/-/http-assert-1.5.1.tgz#d775e93630c2469c2f980fc27e3143240335db3b" - integrity sha512-PGAK759pxyfXE78NbKxyfRcWYA/KwW17X290cNev/qAsn9eQIxkH4shoNBafH37wewhDG/0p1cHPbK6+SzZjWQ== - -"@types/http-cache-semantics@*": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.0.tgz#9140779736aa2655635ee756e2467d787cfe8a2a" - integrity sha512-c3Xy026kOF7QOTn00hbIllV1dLR9hG9NkSrLQgCVs8NF6sBU+VGWjD3wLPhmh1TYAc7ugCFsvHYMN4VcBN1U1A== - -"@types/http-errors@*": - version "1.8.0" - resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-1.8.0.tgz#682477dbbbd07cd032731cb3b0e7eaee3d026b69" - integrity sha512-2aoSC4UUbHDj2uCsCxcG/vRMXey/m17bC7UwitVm5hn22nI8O8Y9iDpA76Orc+DWkQ4zZrOKEshCqR/jSuXAHA== - -"@types/ioredis@*": - version "4.14.9" - resolved "https://registry.yarnpkg.com/@types/ioredis/-/ioredis-4.14.9.tgz#774387d44d3ad60e1b849044b2b28b96e5813866" - integrity sha512-yNdzppM6vY4DYqXCnt4A3PXArxsMWeJCYxFlyl4AJKrNSGMEAP9TPcXR+8Q6zh9glcCtxmwMQhi4pwdqqHH3OA== - dependencies: - "@types/node" "*" - -"@types/is-url@1.2.30": - version "1.2.30" - resolved "https://registry.yarnpkg.com/@types/is-url/-/is-url-1.2.30.tgz#85567e8bee4fee69202bc3448f9fb34b0d56c50a" - integrity sha512-AnlNFwjzC8XLda5VjRl4ItSd8qp8pSNowvsut0WwQyBWHpOxjxRJm8iO6uETWqEyLdYdb9/1j+Qd9gQ4l5I4fw== - -"@types/js-yaml@4.0.4": - version "4.0.4" - resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-4.0.4.tgz#cc38781257612581a1a0eb25f1709d2b06812fce" - integrity sha512-AuHubXUmg0AzkXH0Mx6sIxeY/1C110mm/EkE/gB1sTRz3h2dao2W/63q42SlVST+lICxz5Oki2hzYA6+KnnieQ== - -"@types/jsdom@16.2.13": - version "16.2.13" - resolved "https://registry.yarnpkg.com/@types/jsdom/-/jsdom-16.2.13.tgz#126c8b7441b159d6234610a48de77b6066f1823f" - integrity sha512-8JQCjdeAidptSsOcRWk2iTm9wCcwn9l+kRG6k5bzUacrnm1ezV4forq0kWjUih/tumAeoG+OspOvQEbbRucBTw== - dependencies: - "@types/node" "*" - "@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" - integrity sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw== - -"@types/json-schema@^7.0.7": - version "7.0.8" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.8.tgz#edf1bf1dbf4e04413ca8e5b17b3b7d7d54b59818" - integrity sha512-YSBPTLTVm2e2OoQIDYx8HaeWJ5tTToLH67kXR7zYNGupXMEHa2++G8k+DczX2cFVgalypqtyZIcU19AFcmOpmg== - -"@types/json5@^0.0.29": - version "0.0.29" - resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" - integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= - -"@types/jsonld@1.5.6": - version "1.5.6" - resolved "https://registry.yarnpkg.com/@types/jsonld/-/jsonld-1.5.6.tgz#4396c0b17128abf5773bb68b5453b88fc565b0d4" - integrity sha512-OUcfMjRie5IOrJulUQwVNvV57SOdKcTfBj3pjXNxzXqeOIrY2aGDNGW/Tlp83EQPkz4tCE6YWVrGuc/ZeaAQGg== - -"@types/katex@0.11.1": - version "0.11.1" - resolved "https://registry.yarnpkg.com/@types/katex/-/katex-0.11.1.tgz#34de04477dcf79e2ef6c8d23b41a3d81f9ebeaf5" - integrity sha512-DUlIj2nk0YnJdlWgsFuVKcX27MLW0KbKmGVoUHmFr+74FYYNUDAaj9ZqTADvsbE8rfxuVmSFc7KczYn5Y09ozg== - -"@types/keygrip@*": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@types/keygrip/-/keygrip-1.0.2.tgz#513abfd256d7ad0bf1ee1873606317b33b1b2a72" - integrity sha512-GJhpTepz2udxGexqos8wgaBx4I/zWIDPh/KOGEwAqtuGDkOUJu5eFvwmdBX4AmB8Odsr+9pHCQqiAqDL/yKMKw== - -"@types/keyv@*": - version "3.1.1" - resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.1.tgz#e45a45324fca9dab716ab1230ee249c9fb52cfa7" - integrity sha512-MPtoySlAZQ37VoLaPcTHCu1RWJ4llDkULYZIzOYxlhxBqYPB0RsRlmMU0R6tahtFe27mIdkHV+551ZWV4PLmVw== - dependencies: - "@types/node" "*" - -"@types/koa-bodyparser@4.3.3": - version "4.3.3" - resolved "https://registry.yarnpkg.com/@types/koa-bodyparser/-/koa-bodyparser-4.3.3.tgz#9c7d4295576bc863d550002f732f1c57dd88cc58" - integrity sha512-/ileIpXsy1fFEzgZhZ07eZH8rAVL7jwuk/kaoVEfauO6s80g2LIDIJKEyDbuAL9S/BWflKzEC0PHD6aXkmaSbw== - dependencies: - "@types/koa" "*" - -"@types/koa-compose@*": - version "3.2.5" - resolved "https://registry.yarnpkg.com/@types/koa-compose/-/koa-compose-3.2.5.tgz#85eb2e80ac50be95f37ccf8c407c09bbe3468e9d" - integrity sha512-B8nG/OoE1ORZqCkBVsup/AKcvjdgoHnfi4pZMn5UwAPCbhk/96xyv284eBYW8JlQbQ7zDmnpFr68I/40mFoIBQ== - dependencies: - "@types/koa" "*" - -"@types/koa-cors@0.0.2": - version "0.0.2" - resolved "https://registry.yarnpkg.com/@types/koa-cors/-/koa-cors-0.0.2.tgz#369c753fb383640f225579c70a4f9a286b4931b7" - integrity sha512-uNaDY26HUVO+2C6arK8ZFODs9mBjYprD8mlvkVe2bYdX9wzEeKtycVXPafXpUkePhMh4sffIMkhRDyedokG/QA== - dependencies: - "@types/koa" "*" - -"@types/koa-favicon@2.0.21": - version "2.0.21" - resolved "https://registry.yarnpkg.com/@types/koa-favicon/-/koa-favicon-2.0.21.tgz#d8a0ed062a6f5e3f838fe09c21e8b3f0490369cd" - integrity sha512-paH1nheVhijx/VduoR/RCD/qTCiX+OI/6fHLi3mZae053Ts+gUBOrKtzl3pMTDbdEBqdLolfLje3PZbb6jW0jQ== - dependencies: - "@types/koa" "*" - -"@types/koa-logger@3.1.2": - version "3.1.2" - resolved "https://registry.yarnpkg.com/@types/koa-logger/-/koa-logger-3.1.2.tgz#91e890f405ddb0626bc385767e4cc0cd7226d1a8" - integrity sha512-sioTA1xlKYiIgryANWPRHBkG3XGbWftw9slWADUPC+qvPIY/yRLSrhvX7zkJwMrntub5dPO0GuAoyGGf0yitfQ== - dependencies: - "@types/koa" "*" - -"@types/koa-mount@4.0.1": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@types/koa-mount/-/koa-mount-4.0.1.tgz#2994be86eaa3d9dc97365e6ebfa227cee3c5f157" - integrity sha512-HNeg80CVS9Dfq8dGYqCZZCAUm7g6jPCNJ1ydqVLEJxLrjmeburpvq+lOZkE4rxBZ6O38dr3tj9IA3IfbdoI05w== - dependencies: - "@types/koa" "*" - -"@types/koa-send@4.1.3": - version "4.1.3" - resolved "https://registry.yarnpkg.com/@types/koa-send/-/koa-send-4.1.3.tgz#17193c6472ae9e5d1b99ae8086949cc4fd69179d" - integrity sha512-daaTqPZlgjIJycSTNjKpHYuKhXYP30atFc1pBcy6HHqB9+vcymDgYTguPdx9tO4HMOqNyz6bz/zqpxt5eLR+VA== - dependencies: - "@types/koa" "*" - -"@types/koa-views@7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@types/koa-views/-/koa-views-7.0.0.tgz#5613450c77ab69c980c47104378da4b7669c5f2e" - integrity sha512-AB/NB+oFHcLOZJYFv3bG5Af8YbwYCD9/zK0WcKALsbjI/FRKrcXTUTC64RebDrkyOkBm3bpCgpGndhAH/3YQ2Q== - dependencies: - koa-views "*" - -"@types/koa@*", "@types/koa@^2.13.1": - version "2.13.1" - resolved "https://registry.yarnpkg.com/@types/koa/-/koa-2.13.1.tgz#e29877a6b5ad3744ab1024f6ec75b8cbf6ec45db" - integrity sha512-Qbno7FWom9nNqu0yHZ6A0+RWt4mrYBhw3wpBAQ3+IuzGcLlfeYkzZrnMq5wsxulN2np8M4KKeUpTodsOsSad5Q== - dependencies: - "@types/accepts" "*" - "@types/content-disposition" "*" - "@types/cookies" "*" - "@types/http-assert" "*" - "@types/http-errors" "*" - "@types/keygrip" "*" - "@types/koa-compose" "*" - "@types/node" "*" - -"@types/koa@2.13.4": - version "2.13.4" - resolved "https://registry.yarnpkg.com/@types/koa/-/koa-2.13.4.tgz#10620b3f24a8027ef5cbae88b393d1b31205726b" - integrity sha512-dfHYMfU+z/vKtQB7NUrthdAEiSvnLebvBjwHtfFmpZmB7em2N3WVQdHgnFq+xvyVgxW5jKDmjWfLD3lw4g4uTw== - dependencies: - "@types/accepts" "*" - "@types/content-disposition" "*" - "@types/cookies" "*" - "@types/http-assert" "*" - "@types/http-errors" "*" - "@types/keygrip" "*" - "@types/koa-compose" "*" - "@types/node" "*" - -"@types/koa__cors@3.0.3": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@types/koa__cors/-/koa__cors-3.0.3.tgz#49d75813b443ba3d4da28ea6cf6244b7e99a3b23" - integrity sha512-74Xb4hJOPGKlrQ4PRBk1A/p0gfLpgbnpT0o67OMVbwyeMXvlBN+ZCRztAAmkKZs+8hKbgMutUlZVbA52Hr/0IA== - dependencies: - "@types/koa" "*" - -"@types/koa__multer@2.0.4": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@types/koa__multer/-/koa__multer-2.0.4.tgz#e0f0fd1800a46b51886bebab480a57100f2488b0" - integrity sha512-WRkshXhE5rpYFUbbtAjyMhdOOSdbu1XX+2AQlRNM6AZtgxd0/WXMU4lrP7e9tk5HWVTWbx8DOOsVBmfHjSGJ4w== - dependencies: - "@types/koa" "*" - -"@types/koa__router@8.0.8": - version "8.0.8" - resolved "https://registry.yarnpkg.com/@types/koa__router/-/koa__router-8.0.8.tgz#b1e0e9a512498777d3366bbdf0e853df27ec831c" - integrity sha512-9pGCaDtzCsj4HJ8HmGuqzk8+s57sPj4njWd08GG5o92n5Xp9io2snc40CPpXFhoKcZ8OKhuu6ht4gNou9e1C2w== - dependencies: - "@types/koa" "*" - -"@types/linkify-it@*": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@types/linkify-it/-/linkify-it-2.1.0.tgz#ea3dd64c4805597311790b61e872cbd1ed2cd806" - integrity sha512-Q7DYAOi9O/+cLLhdaSvKdaumWyHbm7HAk/bFwwyTuU0arR5yyCeW5GOoqt4tJTpDRxhpx9Q8kQL6vMpuw9hDSw== - -"@types/markdown-it@12.2.3": - version "12.2.3" - resolved "https://registry.yarnpkg.com/@types/markdown-it/-/markdown-it-12.2.3.tgz#0d6f6e5e413f8daaa26522904597be3d6cd93b51" - integrity sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ== - dependencies: - "@types/linkify-it" "*" - "@types/mdurl" "*" - -"@types/matter-js@0.17.6": - version "0.17.6" - resolved "https://registry.yarnpkg.com/@types/matter-js/-/matter-js-0.17.6.tgz#525bb33a7289105e1981ef51b987972fa9739011" - integrity sha512-i6WLNuM7/89SLqO2aOyaUkom9tc3B/qo4ekh7BD99xQ8+wOVVZO0F4RzKNYZCaFwr+xp3pK3oIb6sSVjLpz+pA== - -"@types/mdurl@*": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@types/mdurl/-/mdurl-1.0.2.tgz#e2ce9d83a613bacf284c7be7d491945e39e1f8e9" - integrity sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA== - -"@types/mime@*": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.1.tgz#dc488842312a7f075149312905b5e3c0b054c79d" - integrity sha512-FwI9gX75FgVBJ7ywgnq/P7tw+/o1GUbtP0KzbtusLigAOgIgNISRK0ZPl4qertvXSIE8YbsVJueQ90cDt9YYyw== - "@types/minimatch@*": version "3.0.3" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== -"@types/mocha@8.2.3": - version "8.2.3" - resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-8.2.3.tgz#bbeb55fbc73f28ea6de601fbfa4613f58d785323" - integrity sha512-ekGvFhFgrc2zYQoX4JeZPmVzZxw6Dtllga7iGHzfbYIYkAMUx/sAFP2GdFpLff+vdHXu5fl7WX9AT+TtqYcsyw== - -"@types/node-fetch@2.5.12": - version "2.5.12" - resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.5.12.tgz#8a6f779b1d4e60b7a57fb6fd48d84fb545b9cc66" - integrity sha512-MKgC4dlq4kKNa/mYrwpKfzQMB5X3ee5U6fSprkKpToBqBmX4nFZL9cW5jl6sWn+xpRJ7ypWh2yyqqr8UUCstSw== - dependencies: - "@types/node" "*" - form-data "^3.0.0" - "@types/node@*": version "16.6.2" resolved "https://registry.yarnpkg.com/@types/node/-/node-16.6.2.tgz#331b7b9f8621c638284787c5559423822fdffc50" integrity sha512-LSw8TZt12ZudbpHc6EkIyDM3nHVWKYrAvGy6EAJfNfjusbwnThqjqxUKKRwuV3iWYeW/LYMzNgaq3MaLffQ2xA== -"@types/node@16.11.4": - version "16.11.4" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.4.tgz#90771124822d6663814f7c1c9b45a6654d8fd964" - integrity sha512-TMgXmy0v2xWyuCSCJM6NCna2snndD8yvQF67J29ipdzMcsPa9u+o0tjF5+EQNdhcuZplYuouYqpc4zcd5I6amQ== - "@types/node@^14.11.8", "@types/node@^14.14.31", "@types/node@^14.14.41": version "14.17.9" resolved "https://registry.yarnpkg.com/@types/node/-/node-14.17.9.tgz#b97c057e6138adb7b720df2bd0264b03c9f504fd" integrity sha512-CMjgRNsks27IDwI785YMY0KLt3co/c0cQ5foxHYv/shC2w8oOnVwz5Ubq1QG5KzrcW+AXk6gzdnxIkDnTvzu3g== -"@types/nodemailer@6.4.4": - version "6.4.4" - resolved "https://registry.yarnpkg.com/@types/nodemailer/-/nodemailer-6.4.4.tgz#c265f7e7a51df587597b3a49a023acaf0c741f4b" - integrity sha512-Ksw4t7iliXeYGvIQcSIgWQ5BLuC/mljIEbjf615svhZL10PE9t+ei8O9gDaD3FPCasUJn9KTLwz2JFJyiiyuqw== - dependencies: - "@types/node" "*" - -"@types/nprogress@0.2.0": - version "0.2.0" - resolved "https://registry.yarnpkg.com/@types/nprogress/-/nprogress-0.2.0.tgz#86c593682d4199212a0509cc3c4d562bbbd6e45f" - integrity sha512-1cYJrqq9GezNFPsWTZpFut/d4CjpZqA0vhqDUPFWYKF1oIyBz5qnoYMzR+0C/T96t3ebLAC1SSnwrVOm5/j74A== - -"@types/oauth@0.9.1": - version "0.9.1" - resolved "https://registry.yarnpkg.com/@types/oauth/-/oauth-0.9.1.tgz#e17221e7f7936b0459ae7d006255dff61adca305" - integrity sha512-a1iY62/a3yhZ7qH7cNUsxoI3U/0Fe9+RnuFrpTKr+0WVOzbKlSLojShCKe20aOD1Sppv+i8Zlq0pLDuTJnwS4A== - dependencies: - "@types/node" "*" - -"@types/parse-json@^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" - integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== - -"@types/parse5@*": - version "5.0.3" - resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-5.0.3.tgz#e7b5aebbac150f8b5fdd4a46e7f0bd8e65e19109" - integrity sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw== - -"@types/parse5@6.0.2": - version "6.0.2" - resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-6.0.2.tgz#99f6b72d82e34cea03a4d8f2ed72114d909c1c61" - integrity sha512-+hQX+WyJAOne7Fh3zF5CxPemILIbuhNcqHHodzK9caYOLnC8pD5efmPleRnw0z++LfKUC/sVNMwk0Gap+B0baA== - -"@types/parsimmon@1.10.6": - version "1.10.6" - resolved "https://registry.yarnpkg.com/@types/parsimmon/-/parsimmon-1.10.6.tgz#8fcf95990514d2a7624aa5f630c13bf2427f9cdd" - integrity sha512-FwAQwMRbkhx0J6YELkwIpciVzCcgEqXEbIrIn3a2P5d3kGEHQ3wVhlN3YdVepYP+bZzCYO6OjmD4o9TGOZ40rA== - -"@types/portscanner@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@types/portscanner/-/portscanner-2.1.1.tgz#89d5094e16f3d941f20f3889dfa5d3a164b3dd3b" - integrity sha512-1NsVIbgBKvrqxwtMN0V6CLji1ERwKSI/RWz0J3y++CzSwYNGBStCfpIFgxV3ZwxsDR5PoZqoUWhwraDm+Ztn0Q== - -"@types/pug@2.0.5": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@types/pug/-/pug-2.0.5.tgz#69bc700934dd473c7ab97270bd2dbacefe562231" - integrity sha512-LOnASQoeNZMkzexRuyqcBBDZ6rS+rQxUMkmj5A0PkhhiSZivLIuz6Hxyr1mkGoEZEkk66faROmpMi4fFkrKsBA== - -"@types/punycode@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@types/punycode/-/punycode-2.1.0.tgz#89e4f3d09b3f92e87a80505af19be7e0c31d4e83" - integrity sha512-PG5aLpW6PJOeV2fHRslP4IOMWn+G+Uq8CfnyJ+PDS8ndCbU+soO+fB3NKCKo0p/Jh2Y4aPaiQZsrOXFdzpcA6g== - -"@types/q@^1.5.1": - version "1.5.2" - resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.2.tgz#690a1475b84f2a884fd07cd797c00f5f31356ea8" - integrity sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw== - -"@types/qrcode@1.4.1": - version "1.4.1" - resolved "https://registry.yarnpkg.com/@types/qrcode/-/qrcode-1.4.1.tgz#0689f400c3a95d2db040c99c99834faa09ee9dc1" - integrity sha512-vxMyr7JM7tYPxu8vUE83NiosWX5DZieCyYeJRoOIg0pAkyofCBzknJ2ycUZkPGDFis2RS8GN/BeJLnRnAPxeCA== - dependencies: - "@types/node" "*" - -"@types/qs@*": - version "6.9.1" - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.1.tgz#937fab3194766256ee09fcd40b781740758617e7" - integrity sha512-lhbQXx9HKZAPgBkISrBcmAcMpZsmpe/Cd/hY7LGZS5OfkySUBItnPZHgQPssWYUET8elF+yCFBbP1Q0RZPTdaw== - -"@types/random-seed@0.3.3": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@types/random-seed/-/random-seed-0.3.3.tgz#7741f7b0a4513198a9396ce4ad25832f799a6727" - integrity sha512-kHsCbIRHNXJo6EN5W8EA5b4i1hdT6jaZke5crBPLUcLqaLdZ0QBq8QVMbafHzhjFF83Cl9qlee2dChD18d/kPg== - -"@types/range-parser@*": - version "1.2.3" - resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c" - integrity sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA== - -"@types/ratelimiter@3.4.2": - version "3.4.2" - resolved "https://registry.yarnpkg.com/@types/ratelimiter/-/ratelimiter-3.4.2.tgz#adf1a6d0cbe72d42207efc510a9170602e23456c" - integrity sha512-iz+yyY+ViphaM8ZwrX1mUQzelIeC59zyaaLKTJ0YVOOCkCpIYpaysiIM4z5Xv9HdXYqIb80S+DhH7J22A0rW2w== - -"@types/readable-stream@^2.3.9": - version "2.3.9" - resolved "https://registry.yarnpkg.com/@types/readable-stream/-/readable-stream-2.3.9.tgz#40a8349e6ace3afd2dd1b6d8e9b02945de4566a9" - integrity sha512-sqsgQqFT7HmQz/V5jH1O0fvQQnXAJO46Gg9LRO/JPfjmVmGUlcx831TZZO3Y3HtWhIkzf3kTsNT0Z0kzIhIvZw== - dependencies: - "@types/node" "*" - safe-buffer "*" - -"@types/redis@2.8.32": - version "2.8.32" - resolved "https://registry.yarnpkg.com/@types/redis/-/redis-2.8.32.tgz#1d3430219afbee10f8cfa389dad2571a05ecfb11" - integrity sha512-7jkMKxcGq9p242exlbsVzuJb57KqHRhNl4dHoQu2Y5v9bCAbtIXXH0R3HleSQW4CTOqpHIYUW3t6tpUj4BVQ+w== - dependencies: - "@types/node" "*" - -"@types/rename@1.0.4": - version "1.0.4" - 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" - integrity sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA== - dependencies: - "@types/node" "*" - -"@types/rimraf@3.0.2": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@types/rimraf/-/rimraf-3.0.2.tgz#a63d175b331748e5220ad48c901d7bbf1f44eef8" - integrity sha512-F3OznnSLAUxFrCEu/L5PY8+ny8DtcFRjx7fZZ9bycvXRi3KPTRS9HOitGZwvPg0juRhXFWIeKX58cnX5YqLohQ== - dependencies: - "@types/glob" "*" - "@types/node" "*" - -"@types/rsvp@^4.0.4": - version "4.0.4" - resolved "https://registry.yarnpkg.com/@types/rsvp/-/rsvp-4.0.4.tgz#55e93e7054027f1ad4b4ebc1e60e59eb091e2d32" - integrity sha512-J3Ol++HCC7/hwZhanDvggFYU/GtxHxE/e7cGRWxR04BF7Tt3TqJZ84BkzQgDxmX0uu8IagiyfmfoUlBACh2Ilg== - -"@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/serve-static@*": - version "1.13.3" - resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.3.tgz#eb7e1c41c4468272557e897e9171ded5e2ded9d1" - integrity sha512-oprSwp094zOglVrXdlo/4bAHtKTAxX6VT8FOZlBKrmyLbNvE1zxZyJ6yikMVtHIvwP45+ZQGJn+FdXGKTozq0g== - dependencies: - "@types/express-serve-static-core" "*" - "@types/mime" "*" - -"@types/sharp@0.29.2": - version "0.29.2" - resolved "https://registry.yarnpkg.com/@types/sharp/-/sharp-0.29.2.tgz#b4e932e982e258d1013236c8b4bcc14f9883c9a3" - integrity sha512-tIbMvtPa8kMyFMKNhpsPT1HO3CgXLuiCAA8bxHAGAZLyALpYvYc4hUu3pu0+3oExQA5LwvHrWp+OilgXCYVQgg== - 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/sinonjs__fake-timers@^6.0.2": version "6.0.3" resolved "https://registry.yarnpkg.com/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.3.tgz#79df6f358ae8f79e628fe35a63608a0ea8e7cf08" @@ -1043,50 +170,6 @@ resolved "https://registry.yarnpkg.com/@types/sizzle/-/sizzle-2.3.3.tgz#ff5e2f1902969d305225a047c8a0fd5c915cebef" integrity sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ== -"@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/speakeasy@2.0.6": - version "2.0.6" - resolved "https://registry.yarnpkg.com/@types/speakeasy/-/speakeasy-2.0.6.tgz#12540f7b64d08180393ae2c5c8c280866a85da61" - integrity sha512-2wIXZp5yJUddhsSZarYCZIakCvzwQgTVdtT29DYVdFzc0cHttanaQx9THRhtjY4kDqVaF2jhyFOEofozOioFdQ== - 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" - integrity sha512-5eQEtSCoESnh2FsiLTxE121IiE60hnMqcb435fShf4bpLRjEu1Eoekht23y6zXS9Ts3l+Szu3TARnTsA0GkOkQ== - -"@types/tinycolor2@1.4.3": - version "1.4.3" - resolved "https://registry.yarnpkg.com/@types/tinycolor2/-/tinycolor2-1.4.3.tgz#ed4a0901f954b126e6a914b4839c77462d56e706" - integrity sha512-Kf1w9NE5HEgGxCRyIcRXR/ZYtDv0V8FVPtYHwLxl0O+maGX0erE77pQlD0gpP+/KByMZ87mOA79SjifhSB3PjQ== - -"@types/tmp@0.2.2": - version "0.2.2" - resolved "https://registry.yarnpkg.com/@types/tmp/-/tmp-0.2.2.tgz#424537a3b91828cb26aaf697f21ae3cd1b69f7e7" - integrity sha512-MhSa0yylXtVMsyT8qFpHA1DLHj4DvQGH5ntxrhHSh8PxUVNi35Wk+P5hVgqbO2qZqOotqr9jaoPRL+iRjWYm/A== - -"@types/tough-cookie@*": - version "4.0.0" - 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/undertaker-registry@*": version "1.0.1" resolved "https://registry.yarnpkg.com/@types/undertaker-registry/-/undertaker-registry-1.0.1.tgz#4306d4a03d7acedb974b66530832b90729e1d1da" @@ -1099,11 +182,6 @@ dependencies: "@types/undertaker-registry" "*" -"@types/uuid@8.3.1": - version "8.3.1" - resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.1.tgz#1a32969cf8f0364b3d8c8af9cc3555b7805df14f" - integrity sha512-Y2mHTRAbqfFkpjldbkHGY8JIzRN6XqYRliG8/24FcHm2D2PwW24fl5xMRTVGdrb7iMrwCaIEbLWerGIkXuFWVg== - "@types/vinyl-fs@*": version "2.4.11" resolved "https://registry.yarnpkg.com/@types/vinyl-fs/-/vinyl-fs-2.4.11.tgz#b98119b8bb2494141eaf649b09fbfeb311161206" @@ -1121,65 +199,6 @@ "@types/expect" "^1.20.4" "@types/node" "*" -"@types/web-push@3.3.2": - version "3.3.2" - resolved "https://registry.yarnpkg.com/@types/web-push/-/web-push-3.3.2.tgz#8c32434147c0396415862e86405c9edc9c50fc15" - integrity sha512-JxWGVL/m7mWTIg4mRYO+A6s0jPmBkr4iJr39DqJpRJAc+jrPiEe1/asmkwerzRon8ZZDxaZJpsxpv0Z18Wo9gw== - 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== - dependencies: - "@types/node" "*" - -"@types/ws@8.2.0": - version "8.2.0" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.2.0.tgz#75faefbe2328f3b833cb8dc640658328990d04f3" - integrity sha512-cyeefcUCgJlEk+hk2h3N+MqKKsPViQgF5boi9TTHSK+PoR9KWBb/C5ccPcDyAqgsbAYHTwulch725DV84+pSpg== - dependencies: - "@types/node" "*" - "@types/yauzl@^2.9.1": version "2.9.2" resolved "https://registry.yarnpkg.com/@types/yauzl/-/yauzl-2.9.2.tgz#c48e5d56aff1444409e39fa164b0b4d4552a7b7a" @@ -1187,518 +206,6 @@ dependencies: "@types/node" "*" -"@types/zen-observable@^0.8.2": - version "0.8.2" - resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.8.2.tgz#808c9fa7e4517274ed555fa158f2de4b4f468e71" - integrity sha512-HrCIVMLjE1MOozVoD86622S7aunluLb2PJdPfb3nYiEtohm8mIB/vyv0Fd37AdeMFrTUQXEunw78YloMA3Qilg== - -"@typescript-eslint/parser@5.1.0": - version "5.1.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.1.0.tgz#6c7f837d210d2bc0a811e7ea742af414f4e00908" - integrity sha512-vx1P+mhCtYw3+bRHmbalq/VKP2Y3gnzNgxGxfEWc6OFpuEL7iQdAeq11Ke3Rhy8NjgB+AHsIWEwni3e+Y7djKA== - dependencies: - "@typescript-eslint/scope-manager" "5.1.0" - "@typescript-eslint/types" "5.1.0" - "@typescript-eslint/typescript-estree" "5.1.0" - debug "^4.3.2" - -"@typescript-eslint/scope-manager@5.1.0": - version "5.1.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.1.0.tgz#6f1f26ad66a8f71bbb33b635e74fec43f76b44df" - integrity sha512-yYlyVjvn5lvwCL37i4hPsa1s0ORsjkauhTqbb8MnpvUs7xykmcjGqwlNZ2Q5QpoqkJ1odlM2bqHqJwa28qV6Tw== - dependencies: - "@typescript-eslint/types" "5.1.0" - "@typescript-eslint/visitor-keys" "5.1.0" - -"@typescript-eslint/types@5.1.0": - version "5.1.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.1.0.tgz#a8a75ddfc611660de6be17d3ad950302385607a9" - integrity sha512-sEwNINVxcB4ZgC6Fe6rUyMlvsB2jvVdgxjZEjQUQVlaSPMNamDOwO6/TB98kFt4sYYfNhdhTPBEQqNQZjMMswA== - -"@typescript-eslint/typescript-estree@5.1.0": - version "5.1.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.1.0.tgz#132aea34372df09decda961cb42457433aa6e83d" - integrity sha512-SSz+l9YrIIsW4s0ZqaEfnjl156XQ4VRmJsbA0ZE1XkXrD3cRpzuZSVCyqeCMR3EBjF27IisWakbBDGhGNIOvfQ== - dependencies: - "@typescript-eslint/types" "5.1.0" - "@typescript-eslint/visitor-keys" "5.1.0" - debug "^4.3.2" - globby "^11.0.4" - is-glob "^4.0.3" - semver "^7.3.5" - tsutils "^3.21.0" - -"@typescript-eslint/visitor-keys@5.1.0": - version "5.1.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.1.0.tgz#e01a01b27eb173092705ae983aa1451bd1842630" - integrity sha512-uqNXepKBg81JVwjuqAxYrXa1Ql/YDzM+8g/pS+TCPxba0wZttl8m5DkrasbfnmJGHs4lQ2jTbcZ5azGhI7kK+w== - dependencies: - "@typescript-eslint/types" "5.1.0" - eslint-visitor-keys "^3.0.0" - -"@ungap/promise-all-settled@1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" - integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== - -"@vue/compiler-core@3.2.20": - version "3.2.20" - resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.2.20.tgz#af5a3c5237818835b0d0be837eb5885a8d21c160" - integrity sha512-vcEXlKXoPwBXFP5aUTHN9GTZaDfwCofa9Yu9bbW2C5O/QSa9Esdt7OG4+0RRd3EHEMxUvEdj4RZrd/KpQeiJbA== - dependencies: - "@babel/parser" "^7.15.0" - "@vue/shared" "3.2.20" - estree-walker "^2.0.2" - source-map "^0.6.1" - -"@vue/compiler-dom@3.2.20": - version "3.2.20" - resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.2.20.tgz#8e0ef354449c0faf41519b00bfc2045eae01dcb5" - integrity sha512-QnI77ec/JtV7R0YBbcVayYTDCRcI9OCbxiUQK6izVyqQO0658n0zQuoNwe+bYgtqnvGAIqTR3FShTd5y4oOjdg== - dependencies: - "@vue/compiler-core" "3.2.20" - "@vue/shared" "3.2.20" - -"@vue/compiler-sfc@3.2.20": - version "3.2.20" - resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.2.20.tgz#2d7668e76f066c566dd7c09c15c9acce4e876e0a" - integrity sha512-03aZo+6tQKiFLfunHKSPZvdK4Jsn/ftRCyaro8AQIWkuxJbvSosbKK6HTTn+D2c3nPScG155akJoxKENw7rftQ== - dependencies: - "@babel/parser" "^7.15.0" - "@vue/compiler-core" "3.2.20" - "@vue/compiler-dom" "3.2.20" - "@vue/compiler-ssr" "3.2.20" - "@vue/ref-transform" "3.2.20" - "@vue/shared" "3.2.20" - estree-walker "^2.0.2" - magic-string "^0.25.7" - postcss "^8.1.10" - source-map "^0.6.1" - -"@vue/compiler-ssr@3.2.20": - version "3.2.20" - resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.2.20.tgz#9cceb6261d9932cb5568202610c1c28f86c5e521" - integrity sha512-rzzVVYivm+EjbfiGQvNeyiYZWzr6Hkej97RZLZvcumacQlnKv9176Xo9rRyeWwFbBlxmtNdrVMslRXtipMXk2w== - dependencies: - "@vue/compiler-dom" "3.2.20" - "@vue/shared" "3.2.20" - -"@vue/reactivity@3.2.20": - version "3.2.20" - resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.2.20.tgz#81fe1c368e7f20bc0ec1dec1045bbee253582de8" - integrity sha512-nSmoLojUTk+H8HNTAkrUduB4+yIUBK2HPihJo2uXVSH4Spry6oqN6lFzE5zpLK+F27Sja+UqR9R1+/kIOsHV5w== - dependencies: - "@vue/shared" "3.2.20" - -"@vue/ref-transform@3.2.20": - version "3.2.20" - resolved "https://registry.yarnpkg.com/@vue/ref-transform/-/ref-transform-3.2.20.tgz#2a59ec90caf8e5c7336776a0900bff0a8b81c090" - integrity sha512-Y42d3PGlYZ1lXcF3dbd3+qU/C/a3wYEZ949fyOI5ptzkjDWlkfU6vn74fmOjsLjEcjs10BXK2qO99FqQIK2r1Q== - dependencies: - "@babel/parser" "^7.15.0" - "@vue/compiler-core" "3.2.20" - "@vue/shared" "3.2.20" - estree-walker "^2.0.2" - magic-string "^0.25.7" - -"@vue/runtime-core@3.2.20": - version "3.2.20" - resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.2.20.tgz#8f63e956a3f88fb772541443c45a7701211012cb" - integrity sha512-d1xfUGhZPfiZzAN7SatStD4vRtT8deJSXib2+Cz3x0brjMWKxe32asQc154FF1E2fFgMCHtnfd4A90bQEzV4GQ== - dependencies: - "@vue/reactivity" "3.2.20" - "@vue/shared" "3.2.20" - -"@vue/runtime-dom@3.2.20": - version "3.2.20" - resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.2.20.tgz#8aa56ae6c30f9cd4a71ca0e9ec3c4bdc67148d15" - integrity sha512-4TCvZMLhESWCFHFYgqN4QmMA/onnINAlUovhopjlS8ST27G1A8Z0tyxPzLoXLa+b5JrOpbMPheEMPvdKExTJig== - dependencies: - "@vue/runtime-core" "3.2.20" - "@vue/shared" "3.2.20" - csstype "^2.6.8" - -"@vue/server-renderer@3.2.20": - version "3.2.20" - resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.2.20.tgz#705e07ae9425132b2b6227d308a51a13f4d4ec81" - integrity sha512-viIbZGep9XabnrRcaxWIi00cOh1x21QYm2upIL5W0zqzTJ54VdTzpI+zi1osNp+VfRQDTHpV2U7H3Kn4ljYJvg== - dependencies: - "@vue/compiler-ssr" "3.2.20" - "@vue/shared" "3.2.20" - -"@vue/shared@3.2.20": - version "3.2.20" - resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.2.20.tgz#53746961f731a8ea666e3316271e944238dc31db" - integrity sha512-FbpX+hD5BvXCQerEYO7jtAGHlhAkhTQ4KIV73kmLWNlawWhTiVuQxizgVb0BOkX5oG9cIRZ42EG++d/k/Efp0w== - -"@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/ast@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7" - integrity sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw== - dependencies: - "@webassemblyjs/helper-numbers" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - -"@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/floating-point-hex-parser@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz#f6c61a705f0fd7a6aecaa4e8198f23d9dc179e4f" - integrity sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ== - -"@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-api-error@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz#1a63192d8788e5c012800ba6a7a46c705288fd16" - integrity sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg== - -"@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-buffer@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz#832a900eb444884cde9a7cad467f81500f5e5ab5" - integrity sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA== - -"@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-numbers@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz#64d81da219fbbba1e3bd1bfc74f6e8c4e10a62ae" - integrity sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ== - dependencies: - "@webassemblyjs/floating-point-hex-parser" "1.11.1" - "@webassemblyjs/helper-api-error" "1.11.1" - "@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-bytecode@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz#f328241e41e7b199d0b20c18e88429c4433295e1" - integrity sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q== - -"@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/helper-wasm-section@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz#21ee065a7b635f319e738f0dd73bfbda281c097a" - integrity sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" - -"@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/ieee754@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz#963929e9bbd05709e7e12243a099180812992614" - integrity sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ== - 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/leb128@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.1.tgz#ce814b45574e93d76bae1fb2644ab9cdd9527aa5" - integrity sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw== - 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/utf8@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.1.tgz#d1f8b764369e7c6e6bae350e854dec9a59f0a3ff" - integrity sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ== - -"@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-edit@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz#ad206ebf4bf95a058ce9880a8c092c5dec8193d6" - integrity sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/helper-wasm-section" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" - "@webassemblyjs/wasm-opt" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" - "@webassemblyjs/wast-printer" "1.11.1" - -"@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-gen@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz#86c5ea304849759b7d88c47a32f4f039ae3c8f76" - integrity sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/ieee754" "1.11.1" - "@webassemblyjs/leb128" "1.11.1" - "@webassemblyjs/utf8" "1.11.1" - -"@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-opt@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz#657b4c2202f4cf3b345f8a4c6461c8c2418985f2" - integrity sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" - -"@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/wasm-parser@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz#86ca734534f417e9bd3c67c7a1c75d8be41fb199" - integrity sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-api-error" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/ieee754" "1.11.1" - "@webassemblyjs/leb128" "1.11.1" - "@webassemblyjs/utf8" "1.11.1" - -"@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" - -"@webassemblyjs/wast-printer@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz#d0c73beda8eec5426f10ae8ef55cee5e7084c2f0" - integrity sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@xtuc/long" "4.2.2" - -"@webpack-cli/configtest@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-1.1.0.tgz#8342bef0badfb7dfd3b576f2574ab80c725be043" - integrity sha512-ttOkEkoalEHa7RaFYpM0ErK1xc4twg3Am9hfHhL7MVqlHebnkYd2wuI/ZqTDj0cVzZho6PdinY0phFZV3O0Mzg== - -"@webpack-cli/info@^1.4.0": - version "1.4.0" - resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.4.0.tgz#b9179c3227ab09cbbb149aa733475fcf99430223" - integrity sha512-F6b+Man0rwE4n0409FyAJHStYA5OIZERxmnUfLVwv0mc0V1wLad3V7jqRlMkgKBeAq07jUvglacNaa6g9lOpuw== - dependencies: - envinfo "^7.7.3" - -"@webpack-cli/serve@^1.6.0": - version "1.6.0" - resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.6.0.tgz#2c275aa05c895eccebbfc34cfb223c6e8bd591a2" - integrity sha512-ZkVeqEmRpBV2GHvjjUZqEai2PpUbuq8Bqd//vEYsp63J8WyexI8ppCqVS3Zs0QADf6aWuPdU+0XsPI647PVlQA== - -"@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" - integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== - -abbrev@1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== - -abort-controller@3.0.0, abort-controller@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" - integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== - dependencies: - event-target-shim "^5.0.0" - -accepts@^1.3.5: - version "1.3.7" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" - integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== - dependencies: - mime-types "~2.1.24" - negotiator "0.6.2" - -acorn-globals@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-6.0.0.tgz#46cdd39f0f8ff08a876619b55f5ac8a6dc770b45" - integrity sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg== - dependencies: - acorn "^7.1.1" - acorn-walk "^7.1.1" - -acorn-import-assertions@^1.7.6: - version "1.7.6" - resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.7.6.tgz#580e3ffcae6770eebeec76c3b9723201e9d01f78" - integrity sha512-FlVvVFA1TX6l3lp8VjDnYYq7R1nyW6x3svAt4nDgrWQ9SBaSh9CnbwgSUTasgfNfOG5HlM1ehugCvM+hjo56LA== - -acorn-jsx@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.2.0.tgz#4c66069173d6fdd68ed85239fc256226182b2ebe" - integrity sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ== - -acorn-jsx@^5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b" - integrity sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng== - -acorn-walk@^7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.1.1.tgz#345f0dffad5c735e7373d2fec9a1023e6a44b83e" - integrity sha512-wdlPY2tm/9XBr7QkKlq0WQVgiuGTX6YWPyRyBviSoScBuLfTVQhvwg6wJ369GJ/1nPfTLMfnrFIfjqVg6d+jQQ== - -acorn-walk@^8.1.1: - version "8.1.1" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.1.1.tgz#3ddab7f84e4a7e2313f6c414c5b7dac85f4e3ebc" - integrity sha512-FbJdceMlPHEAWJOILDk1fXD8lnTlEIWFkqtfk+MvmL5q/qlHfN7GEHcsFZWt/Tea9jRNPWUZG4G976nqAAmU9w== - -acorn@^7.1.1: - version "7.4.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.5.0: - version "8.5.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.5.0.tgz#4512ccb99b3698c752591e9bb4472e38ad43cee2" - integrity sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q== - -agent-base@6: - version "6.0.2" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" - integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== - dependencies: - debug "4" - -agentkeepalive@^4.1.3: - version "4.1.4" - resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.1.4.tgz#d928028a4862cb11718e55227872e842a44c945b" - integrity sha512-+V/rGa3EuU74H6wR04plBb7Ks10FbtUQgRj/FQOG7uUIEuaINI+AiqJR1k6t3SVNs7o7ZjIdus6706qqzVq8jQ== - dependencies: - debug "^4.1.0" - depd "^1.1.2" - humanize-ms "^1.2.1" - aggregate-error@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" @@ -1707,12 +214,7 @@ aggregate-error@^3.0.0: clean-stack "^2.0.0" indent-string "^4.0.0" -ajv-keywords@^3.5.2: - version "3.5.2" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" - integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== - -ajv@^6.10.0, ajv@^6.12.4, ajv@^6.12.5, ajv@^6.5.5: +ajv@^6.5.5: version "6.12.5" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.5.tgz#19b0e8bae8f476e5ba666300387775fb1a00a4da" integrity sha512-lRF8RORchjpKG50/WFf8xmg7sgCLFiYNNnqdKflk63whMQcWR5ngGjiSXkL9bjxy6B2npOK2HSMN49jEBMSkag== @@ -1727,11 +229,6 @@ alphanum-sort@^1.0.1, alphanum-sort@^1.0.2: resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" integrity sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM= -ansi-colors@4.1.1, ansi-colors@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" - integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== - ansi-colors@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-1.1.0.tgz#6374b4dd5d4718ff3ce27a671a3b1cad077132a9" @@ -1739,6 +236,11 @@ ansi-colors@^1.0.1: dependencies: ansi-wrap "^0.1.0" +ansi-colors@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== + ansi-escapes@^4.3.0: version "4.3.2" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" @@ -1758,16 +260,6 @@ ansi-regex@^2.0.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= -ansi-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= - -ansi-regex@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" - integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== - ansi-regex@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" @@ -1778,13 +270,6 @@ ansi-styles@^2.2.1: resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= -ansi-styles@^3.2.0, ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - ansi-styles@^4.0.0, ansi-styles@^4.1.0: version "4.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359" @@ -1798,11 +283,6 @@ ansi-wrap@0.1.0, ansi-wrap@^0.1.0: resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf" integrity sha1-qCJQ3bABXponyoLoLqYDu/pF768= -any-promise@^1.0.0, any-promise@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" - integrity sha1-q8av7tzqUugJzcA3au0845Y10X8= - anymatch@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" @@ -1819,11 +299,6 @@ anymatch@~3.1.1: normalize-path "^3.0.0" picomatch "^2.0.4" -app-root-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/app-root-path/-/app-root-path-3.0.0.tgz#210b6f43873227e18a4b810a032283311555d5ad" - integrity sha512-qMcx+Gy2UZynHjOHOIXPNvpf+9cjvk3cWrBBK7zg4gH9+clobJRb9NGzcT7mQTcV/6Gm/1WelUtqxVXnNlrwcw== - append-buffer@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/append-buffer/-/append-buffer-1.0.2.tgz#d8220cf466081525efea50614f3de6514dfa58f1" @@ -1831,16 +306,6 @@ append-buffer@^1.0.2: dependencies: buffer-equal "^1.0.0" -append-field@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/append-field/-/append-field-1.0.0.tgz#1e3440e915f0b1203d23748e78edd7b9b5b43e56" - integrity sha1-HjRA6RXwsSA9I3SOeO3XubW0PlY= - -aproba@^1.0.3: - version "1.2.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" - integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== - arch@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/arch/-/arch-2.2.0.tgz#1bc47818f305764f23ab3306b0bfc086c5a29d11" @@ -1851,19 +316,6 @@ archy@^1.0.0: resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" integrity sha1-+cjBN1fMHde8N5rHeyxipcKGjEA= -are-we-there-yet@~1.1.2: - version "1.1.5" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" - integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== - dependencies: - delegates "^1.0.0" - readable-stream "^2.0.6" - -arg@^4.1.0: - version "4.1.3" - resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" - integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== - argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" @@ -1871,11 +323,6 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" -argparse@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" - integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== - arr-diff@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" @@ -1939,36 +386,11 @@ array-sort@^1.0.0: get-value "^2.0.6" kind-of "^5.0.2" -array-timsort@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/array-timsort/-/array-timsort-1.0.3.tgz#3c9e4199e54fb2b9c3fe5976396a21614ef0d926" - integrity sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ== - -array-union@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" - integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== - array-unique@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= -asap@~2.0.3: - version "2.0.6" - resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" - integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= - -asn1.js@^5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-5.3.0.tgz#439099fe9174e09cff5a54a9dda70260517e8689" - integrity sha512-WHnQJFcOrIWT1RLOkFFBQkFVvyt9BPOOrH+Dp152Zk4R993rSzXUGPmkybIcUFhHE2d/iHH+nCaOWVCDbO8fgA== - dependencies: - bn.js "^4.0.0" - inherits "^2.0.1" - minimalistic-assert "^1.0.0" - safer-buffer "^2.1.0" - asn1@~0.2.3: version "0.2.4" resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" @@ -1976,11 +398,6 @@ asn1@~0.2.3: dependencies: safer-buffer "~2.1.0" -assert-never@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/assert-never/-/assert-never-1.2.1.tgz#11f0e363bf146205fb08193b5c7b90f4d1cf44fe" - integrity sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw== - assert-plus@1.0.0, assert-plus@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" @@ -2006,6 +423,11 @@ async-done@^1.2.0, async-done@^1.2.2: process-nextick-args "^2.0.0" stream-exhaust "^1.0.1" +async-each@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" + integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== + async-settle@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/async-settle/-/async-settle-1.0.0.tgz#1d0a914bb02575bec8a8f3a74e5080f72b2c0c6b" @@ -2013,18 +435,6 @@ async-settle@^1.0.0: dependencies: async-done "^1.2.2" -async@>=0.2.9: - version "3.2.0" - resolved "https://registry.yarnpkg.com/async/-/async-3.2.0.tgz#b3a2685c5ebb641d3de02d161002c60fc9f85720" - integrity sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw== - -async@^2.6.0: - version "2.6.3" - resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" - integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== - dependencies: - lodash "^4.17.14" - async@^3.2.0: version "3.2.1" resolved "https://registry.yarnpkg.com/async/-/async-3.2.1.tgz#d3274ec66d107a47476a4c49136aacdb00665fc8" @@ -2045,11 +455,6 @@ atob@^2.1.2: resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== -autobind-decorator@2.4.0, autobind-decorator@^2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/autobind-decorator/-/autobind-decorator-2.4.0.tgz#ea9e1c98708cf3b5b356f7cf9f10f265ff18239c" - integrity sha512-OGYhWUO72V6DafbF8PM8rm3EPbfuyMZcJhtm5/n26IDwO18pohE4eNazLoCGhPiXOCD0gEGmrbU3849QvM8bbw== - autoprefixer@^6.3.1: version "6.7.7" resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-6.7.7.tgz#1dbd1c835658e35ce3f9984099db00585c782014" @@ -2062,33 +467,6 @@ autoprefixer@^6.3.1: postcss "^5.2.16" postcss-value-parser "^3.2.3" -autosize@4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/autosize/-/autosize-4.0.4.tgz#924f13853a466b633b9309330833936d8bccce03" - integrity sha512-5yxLQ22O0fCRGoxGfeLSNt3J8LB1v+umtpMnPW6XjkTWXKoN0AmXAIhelJcDtFT/Y/wYWmfE+oqU10Q0b8FhaQ== - -autwh@0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/autwh/-/autwh-0.1.0.tgz#24a5300923309d105133401a2568f9c8ab7d7e03" - integrity sha512-IkGZ4kjVlZMkEmDiVtZpGG3lDGHPqsMBIh4IpQKN7idYOJ5EGedqKPO+ychNqh8zrJEEqYsN0NcBkcmoE2uFAw== - dependencies: - oauth "0.9.15" - -aws-sdk@2.1013.0: - version "2.1013.0" - resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.1013.0.tgz#85babc473b0bc90cc1160eb48baf616ddb86e346" - integrity sha512-TXxkp/meAdofpC15goFpNuur7fvh/mcMRfHJoP1jYzTtD0wcoB4FK16GLcny0uDYgkQgZuiO9QYv3Rq5bhGCqQ== - dependencies: - buffer "4.9.2" - events "1.1.1" - ieee754 "1.1.13" - jmespath "0.15.0" - querystring "0.2.0" - sax "1.2.1" - url "0.10.3" - uuid "3.3.2" - xml2js "0.4.19" - aws-sign2@~0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" @@ -2106,13 +484,6 @@ axios@^0.21.1: dependencies: follow-redirects "^1.10.0" -babel-walk@3.0.0-canary-5: - version "3.0.0-canary-5" - resolved "https://registry.yarnpkg.com/babel-walk/-/babel-walk-3.0.0-canary-5.tgz#f66ecd7298357aee44955f235a6ef54219104b11" - integrity sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw== - dependencies: - "@babel/types" "^7.9.6" - bach@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/bach/-/bach-1.2.0.tgz#4b3ce96bf27134f79a1b414a51c14e34c3bd9880" @@ -2138,21 +509,6 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= -base32.js@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/base32.js/-/base32.js-0.0.1.tgz#d045736a57b1f6c139f0c7df42518a84e91bb2ba" - integrity sha1-0EVzalex9sE58MffQlGKhOkbsro= - -base64-js@^1.0.2: - version "1.3.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" - integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== - -base64-js@^1.3.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" - integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== - base@^0.11.1: version "0.11.2" resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" @@ -2173,20 +529,10 @@ bcrypt-pbkdf@^1.0.0: dependencies: tweetnacl "^0.14.3" -bcryptjs@2.4.3: - version "2.4.3" - resolved "https://registry.yarnpkg.com/bcryptjs/-/bcryptjs-2.4.3.tgz#9ab5627b93e60621ff7cdac5da9733027df1d0cb" - integrity sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms= - -big-integer@^1.6.16: - version "1.6.48" - resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.48.tgz#8fd88bd1632cba4a1c8c3e3d7159f08bb95b4b9e" - integrity sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w== - -big.js@^5.2.2: - version "5.2.2" - resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" - integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== +binary-extensions@^1.0.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" + integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== binary-extensions@^2.0.0: version "2.0.0" @@ -2198,14 +544,12 @@ binaryextensions@^2.2.0: resolved "https://registry.yarnpkg.com/binaryextensions/-/binaryextensions-2.3.0.tgz#1d269cbf7e6243ea886aa41453c3651ccbe13c22" integrity sha512-nAihlQsYGyc5Bwq6+EsubvANYGExeJKHDO3RjnvwU042fawQTQfM3Kxn7IHUXQOz4bzfwsGYYHGSvXyW4zOGLg== -bl@^4.0.1, bl@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/bl/-/bl-4.0.3.tgz#12d6287adc29080e22a705e5764b2a9522cdc489" - integrity sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg== +bindings@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" + integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== dependencies: - buffer "^5.5.0" - inherits "^2.0.4" - readable-stream "^3.4.0" + file-uri-to-path "1.0.0" blob-util@^2.0.2: version "2.0.2" @@ -2217,21 +561,6 @@ bluebird@3.7.2, bluebird@^3.7.2: resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== -blurhash@1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/blurhash/-/blurhash-1.1.4.tgz#a7010ceb3019cd2c9809b17c910ebf6175d29244" - integrity sha512-MXIPz6zwYUKayju+Uidf83KhH0vodZfeRl6Ich8Gu+KGl0JgKiFq9LsfqV7cVU5fKD/AotmduZqvOfrGKOfTaA== - -bn.js@^4.0.0: - version "4.11.8" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" - integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== - -boolbase@^1.0.0, boolbase@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" - integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= - brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -2240,7 +569,7 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" -braces@^2.3.1: +braces@^2.3.1, braces@^2.3.2: version "2.3.2" resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== @@ -2256,37 +585,13 @@ braces@^2.3.1: split-string "^3.0.2" to-regex "^3.0.1" -braces@^3.0.1, braces@~3.0.2: +braces@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== dependencies: fill-range "^7.0.1" -broadcast-channel@4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/broadcast-channel/-/broadcast-channel-4.2.0.tgz#9ca93a23a31036266c2c9b0f8f55bd21594b8f82" - integrity sha512-XX9yNnIy/v2T+HR5EKIH7ziM2mYTefsrzZ2lkCmFZxwCDG7Ns7HLIooUXA114sCeFRJ4MEXEgdMapxfPDh9Xkg== - dependencies: - "@babel/runtime" "^7.7.2" - detect-node "^2.1.0" - js-sha3 "0.8.0" - microseconds "0.2.0" - nano-time "1.0.0" - oblivious-set "1.0.0" - rimraf "3.0.2" - unload "2.2.0" - -browser-process-hrtime@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" - integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== - -browser-stdout@1.3.1: - version "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@^1.3.6, browserslist@^1.5.2, browserslist@^1.7.6: version "1.7.7" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-1.7.7.tgz#0bd76704258be829b2398bb50e4b62d1a166b0b9" @@ -2295,171 +600,21 @@ browserslist@^1.3.6, browserslist@^1.5.2, browserslist@^1.7.6: caniuse-db "^1.0.30000639" electron-to-chromium "^1.2.7" -browserslist@^4.0.0, 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" - -browserslist@^4.16.0: - version "4.16.4" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.4.tgz#7ebf913487f40caf4637b892b268069951c35d58" - integrity sha512-d7rCxYV8I9kj41RH8UKYnvDYCRENUlHRgyXy/Rhr/1BaeLGfiCptEdFE8MIrvGfWbBFNjVYx76SQWvNX1j+/cQ== - dependencies: - caniuse-lite "^1.0.30001208" - colorette "^1.2.2" - electron-to-chromium "^1.3.712" - escalade "^3.1.1" - node-releases "^1.1.71" - -browserslist@^4.16.6: - version "4.16.6" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.6.tgz#d7901277a5a88e554ed305b183ec9b0c08f66fa2" - integrity sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ== - dependencies: - caniuse-lite "^1.0.30001219" - colorette "^1.2.2" - electron-to-chromium "^1.3.723" - escalade "^3.1.1" - node-releases "^1.1.71" - -buffer-alloc-unsafe@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" - integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== - -buffer-alloc@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" - integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== - dependencies: - buffer-alloc-unsafe "^1.1.0" - buffer-fill "^1.0.0" - buffer-crc32@~0.2.3: version "0.2.13" resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI= -buffer-equal-constant-time@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" - integrity sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk= - buffer-equal@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-1.0.0.tgz#59616b498304d556abd466966b22eeda3eca5fbe" integrity sha1-WWFrSYME1Var1GaWayLu2j7KX74= -buffer-fill@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" - integrity sha1-+PeLdniYiO858gXNY39o5wISKyw= - -buffer-from@^1.0.0, buffer-from@^1.1.1: +buffer-from@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== -buffer-writer@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/buffer-writer/-/buffer-writer-2.0.0.tgz#ce7eb81a38f7829db09c873f2fbb792c0c98ec04" - integrity sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw== - -buffer@4.9.2: - version "4.9.2" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" - integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg== - dependencies: - base64-js "^1.0.2" - ieee754 "^1.1.4" - isarray "^1.0.0" - -buffer@^5.4.3, buffer@^5.5.0: - version "5.6.0" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.6.0.tgz#a31749dc7d81d84db08abf937b6b8c4033f62786" - integrity sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw== - dependencies: - base64-js "^1.0.2" - ieee754 "^1.1.4" - -buffer@^6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" - integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.2.1" - -bufferutil@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.1.tgz#3a177e8e5819a1243fe16b63a199951a7ad8d4a7" - integrity sha512-xowrxvpxojqkagPcWRQVXZl0YXhRhAtBEIq3VoER1NH5Mw1n1o0ojdspp+GS2J//2gCVyrzQDApQ4unGF+QOoA== - dependencies: - node-gyp-build "~3.7.0" - -builtin-modules@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" - integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8= - -bull@3.29.3: - version "3.29.3" - resolved "https://registry.yarnpkg.com/bull/-/bull-3.29.3.tgz#5b0059b172685b0d6f011d56214e1898ff3a7a0b" - integrity sha512-MOqV1dKLy1YQgP9m3lFolyMxaU+1+o4afzYYf0H4wNM+x/S0I1QPQfkgGlLiH00EyFrvSmeubeCYFP47rTfpjg== - dependencies: - cron-parser "^2.13.0" - debuglog "^1.0.0" - get-port "^5.1.1" - ioredis "^4.27.0" - lodash "^4.17.21" - p-timeout "^3.2.0" - promise.prototype.finally "^3.1.2" - semver "^7.3.2" - util.promisify "^1.0.1" - uuid "^8.3.0" - -busboy@^0.2.11: - version "0.2.14" - resolved "https://registry.yarnpkg.com/busboy/-/busboy-0.2.14.tgz#6c2a622efcf47c57bbbe1e2a9c37ad36c7925453" - integrity sha1-bCpiLvz0fFe7vh4qnDetNseSVFM= - dependencies: - dicer "0.2.5" - readable-stream "1.1.x" - -bytes@3.1.0, bytes@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" - integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== - -cacache@^15.0.5: - version "15.1.0" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.1.0.tgz#164c2f857ee606e4cc793c63018fefd0ea5eba7b" - integrity sha512-mfx0C+mCfWjD1PnwQ9yaOrwG1ou9FkKnx0SvzUHWdFt7r7GaRtzT+9M8HAvLu62zIHtnpQ/1m93nWNDCckJGXQ== - dependencies: - "@npmcli/move-file" "^1.0.1" - chownr "^2.0.0" - fs-minipass "^2.0.0" - glob "^7.1.4" - infer-owner "^1.0.4" - lru-cache "^6.0.0" - minipass "^3.1.1" - minipass-collect "^1.0.2" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.2" - mkdirp "^1.0.3" - p-map "^4.0.0" - promise-inflight "^1.0.1" - rimraf "^3.0.2" - ssri "^8.0.1" - tar "^6.0.2" - unique-filename "^1.1.1" - cache-base@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" @@ -2475,67 +630,16 @@ cache-base@^1.0.1: union-value "^1.0.0" unset-value "^1.0.0" -cache-content-type@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/cache-content-type/-/cache-content-type-1.0.1.tgz#035cde2b08ee2129f4a8315ea8f00a00dba1453c" - integrity sha512-IKufZ1o4Ut42YUrZSo8+qnMTrFuKkvyoLXUywKz9GJ5BrhOFGhLdkx9sG4KAnVvbY6kEcSFjLQul+DVmBm2bgA== - dependencies: - mime-types "^2.1.18" - ylru "^1.2.0" - -cacheable-lookup@6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-6.0.3.tgz#61d6171f6818fab230666b11f7cf3f5a48df7818" - integrity sha512-xdwIK7MEC8NpRIt0dx2PL7pTRKaSmDb+zirzuM+cJTRWDfwfVu4XyASkODIU4XbjsyFHKo/tDOPSs64Z3yfFWg== - -cacheable-lookup@^5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.3.tgz#049fdc59dffdd4fc285e8f4f82936591bd59fec3" - integrity sha512-W+JBqF9SWe18A72XFzN/V/CULFzPm7sBXzzR6ekkE+3tLG72wFZrBiBZhrZuDoYexop4PHJVdFAKb/Nj9+tm9w== - -cacheable-request@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.1.tgz#062031c2856232782ed694a257fa35da93942a58" - integrity sha512-lt0mJ6YAnsrBErpTMWeu5kl/tg9xMAWjavYTN6VQXM1A/teBITuNcccXsCxF0tDQQJf9DfAaX5O4e0zp0KlfZw== - dependencies: - clone-response "^1.0.2" - get-stream "^5.1.0" - http-cache-semantics "^4.0.0" - keyv "^4.0.0" - lowercase-keys "^2.0.0" - normalize-url "^4.1.0" - responselike "^2.0.0" - cachedir@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/cachedir/-/cachedir-2.3.0.tgz#0c75892a052198f0b21c7c1804d8331edfcae0e8" integrity sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw== -cafy@15.2.1: - version "15.2.1" - resolved "https://registry.yarnpkg.com/cafy/-/cafy-15.2.1.tgz#5a55eaeb721c604c7dca652f3d555c392e5f995a" - integrity sha512-g2zOmFb63p6XcZ/zeMWKYP8YKQYNWnhJmi6K71Ql4EAFTAay31xF0PBPtdBCCfQ0fiETgWTMxKtySAVI/Od6aQ== - -callsites@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" - integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== - camelcase@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" integrity sha1-MvxLn82vhF/N9+c7uXysImHwqwo= -camelcase@^5.0.0: - version "5.3.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" - integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== - -camelcase@^6.0.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809" - integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== - caniuse-api@^1.5.2: version "1.6.1" resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-1.6.1.tgz#b534e7c734c4f81ec5fbe8aca2ad24354b962c6c" @@ -2546,83 +650,17 @@ caniuse-api@^1.5.2: lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-api@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0" - integrity sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw== - dependencies: - browserslist "^4.0.0" - caniuse-lite "^1.0.0" - lodash.memoize "^4.1.2" - lodash.uniq "^4.5.0" - caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639: version "1.0.30001170" resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30001170.tgz#3417e94e73536b5bf567e9e9c4b7c1901c408c6a" integrity sha512-NzQ5cfHv/pCgVbNWl9eIILms/hb57N+8Ku2yf2IOkBCmYSF4pweMtLTbBAwN/LzKPEtxE42hhTz0sb8gBlkPXA== -caniuse-lite@^1.0.0: - version "1.0.30001048" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001048.tgz#4bb4f1bc2eb304e5e1154da80b93dee3f1cf447e" - integrity sha512-g1iSHKVxornw0K8LG9LLdf+Fxnv7T1Z+mMsf0/YYLclQX4Cd522Ap0Lrw6NFqHgezit78dtyWxzlV2Xfc7vgRg== - -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== - -caniuse-lite@^1.0.30001208: - version "1.0.30001208" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001208.tgz#a999014a35cebd4f98c405930a057a0d75352eb9" - integrity sha512-OE5UE4+nBOro8Dyvv0lfx+SRtfVIOM9uhKqFmJeUbGriqhhStgp1A0OyBpgy3OUF8AhYCT+PVwPC1gMl2ZcQMA== - -caniuse-lite@^1.0.30001219: - version "1.0.30001230" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001230.tgz#8135c57459854b2240b57a4a6786044bdc5a9f71" - integrity sha512-5yBd5nWCBS+jWKTcHOzXwo5xzcj4ePE/yjtkZyUV1BTUmrBaA9MRGC+e7mxnqXSA90CmCA8L3eKLaSUkt099IQ== - -canonicalize@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/canonicalize/-/canonicalize-1.0.1.tgz#657b4f3fa38a6ecb97a9e5b7b26d7a19cc6e0da9" - integrity sha512-N3cmB3QLhS5TJ5smKFf1w42rJXWe6C1qP01z4dxJiI5v269buii4fLHWETDyf7yEd0azGLNC63VxNMiPd2u0Cg== - caseless@~0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= -cbor@*: - version "7.0.5" - resolved "https://registry.yarnpkg.com/cbor/-/cbor-7.0.5.tgz#ed54cdbc19fa7352bb328d00a5393aa7ce45a10f" - integrity sha512-0aaAPgW92lLmypb9iCd22k7tSD1FbF6dps8VQzmIBKY6ych2gO09b2vo/SbaLTmezJuB8Kh88Rvpl/Uq52mNZg== - dependencies: - "@cto.af/textdecoder" "^0.0.0" - nofilter "^2.0.3" - -cbor@8.0.2: - version "8.0.2" - resolved "https://registry.yarnpkg.com/cbor/-/cbor-8.0.2.tgz#d0f5088423437efcc160e9304bd0576f45d06abb" - integrity sha512-H5WTjQYgyHQI0VrCmbyQBOPy1353MjmUi/r3DbPib4U13vuyqm7es9Mfpe8G58bN/mCdRlJWkiCrPl1uM1wAlg== - dependencies: - nofilter "^3.0.3" - -chalk@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.0.0.tgz#6e98081ed2d17faab615eb52ac66ec1fe6209e72" - integrity sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chalk@4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chalk@^1.1.1, chalk@^1.1.3: +chalk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= @@ -2633,16 +671,7 @@ chalk@^1.1.1, chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" -chalk@^2.0.0, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chalk@^4.0.0, chalk@^4.1.0: +chalk@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A== @@ -2650,87 +679,31 @@ chalk@^4.0.0, chalk@^4.1.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -char-regex@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" - integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== - -character-parser@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/character-parser/-/character-parser-2.2.0.tgz#c7ce28f36d4bcd9744e5ffc2c5fcde1c73261fc0" - integrity sha1-x84o821LzZdE5f/CxfzeHHMmH8A= - dependencies: - is-regex "^1.0.3" - -chart.js@3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-3.6.0.tgz#a87fce8431d4e7c5523d721f487f53aada1e42fe" - integrity sha512-iOzzDKePL+bj+ccIsVAgWQehCXv8xOKGbaU2fO/myivH736zcx535PGJzQGanvcSGVOqX6yuLZsN3ygcQ35UgQ== - -chartjs-adapter-date-fns@2.0.0: - version "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-zoom@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/chartjs-plugin-zoom/-/chartjs-plugin-zoom-1.1.1.tgz#8a28923a17fcb5eb57a0dc94c5113bf402677647" - integrity sha512-1q54WOzK7FtAjkbemQeqvmFUV0btNYIQny2HbQ6Awq9wUtCz7Zmj6vIgp3C1DYMQwN0nqgpC3vnApqiwI7cSdQ== - dependencies: - hammerjs "^2.0.8" - check-more-types@2.24.0, check-more-types@^2.24.0: version "2.24.0" resolved "https://registry.yarnpkg.com/check-more-types/-/check-more-types-2.24.0.tgz#1420ffb10fd444dcfc79b43891bbfffd32a84600" integrity sha1-FCD/sQ/URNz8ebQ4kbv//TKoRgA= -cheerio-httpcli@0.8.2: - version "0.8.2" - resolved "https://registry.yarnpkg.com/cheerio-httpcli/-/cheerio-httpcli-0.8.2.tgz#0189bda71c8bd2852de78e154291e2288184fbf2" - integrity sha512-grIzTwQg/nE7Oy6VvL19pf0UlM6wiluy/AOpXfQLVFrSi21F8wnO3dLchtaH2hfMF6jz68ot0/ngyQQVrp2VTw== +chokidar@^2.0.0: + version "2.1.8" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" + integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== dependencies: - "@types/cheerio" "0.22.18" - "@types/rsvp" "^4.0.4" - async "^3.2.0" - cheerio "^0.22.0" - colors "^1.4.0" - foreach "^2.0.5" - he "^1.2.0" - iconv-lite "^0.6.3" - import-fresh "^3.3.0" - jschardet "^3.0.0" - object-assign "^4.1.1" - os-locale "^5.0.0" - prettyjson "^1.2.1" - request "^2.88.2" - rsvp "^4.8.5" - tough-cookie "^2.5.0" - type-of "^2.0.1" - valid-url "^1.0.9" + anymatch "^2.0.0" + async-each "^1.0.1" + braces "^2.3.2" + glob-parent "^3.1.0" + inherits "^2.0.3" + is-binary-path "^1.0.0" + is-glob "^4.0.0" + normalize-path "^3.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.2.1" + upath "^1.1.1" + optionalDependencies: + fsevents "^1.2.7" -cheerio@^0.22.0: - version "0.22.0" - resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-0.22.0.tgz#a9baa860a3f9b595a6b81b1a86873121ed3a269e" - integrity sha1-qbqoYKP5tZWmuBsahocxIe06Jp4= - dependencies: - css-select "~1.2.0" - dom-serializer "~0.1.0" - entities "~1.1.1" - htmlparser2 "^3.9.1" - lodash.assignin "^4.0.9" - lodash.bind "^4.1.4" - lodash.defaults "^4.0.1" - lodash.filter "^4.4.0" - lodash.flatten "^4.2.0" - lodash.foreach "^4.3.0" - lodash.map "^4.4.0" - lodash.merge "^4.4.0" - lodash.pick "^4.2.1" - lodash.reduce "^4.4.0" - lodash.reject "^4.4.0" - lodash.some "^4.4.0" - -chokidar@3.5.1, "chokidar@>=3.0.0 <4.0.0", chokidar@^2.0.0, chokidar@^3.3.1, chokidar@^3.5.0: +chokidar@^3.3.1: version "3.3.1" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.3.1.tgz#c84e5b3d18d9a4d77558fef466b1bf16bbeb3450" integrity sha512-4QYCEWOcK3OJrxwvyyAOxFuhpvOVCYkr33LPfFNBjAD/w3sEzWsp2BUOkI4l9bHvWioAd0rc6NlHUOEaWkTeqg== @@ -2745,23 +718,6 @@ chokidar@3.5.1, "chokidar@>=3.0.0 <4.0.0", chokidar@^2.0.0, chokidar@^3.3.1, cho optionalDependencies: fsevents "~2.1.2" -chownr@^1.1.1: - version "1.1.4" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" - integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== - -chownr@^2.0.0: - version "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" - ci-info@^3.1.1: version "3.2.0" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.2.0.tgz#2876cb948a498797b5236f0095bc057d0dca38b6" @@ -2796,18 +752,6 @@ cli-cursor@^3.1.0: dependencies: restore-cursor "^3.1.0" -cli-highlight@2.1.11, cli-highlight@^2.1.11: - version "2.1.11" - resolved "https://registry.yarnpkg.com/cli-highlight/-/cli-highlight-2.1.11.tgz#49736fa452f0aaf4fae580e30acb26828d2dc1bf" - integrity sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg== - dependencies: - chalk "^4.0.0" - highlight.js "^10.7.1" - mz "^2.4.0" - parse5 "^5.1.1" - parse5-htmlparser2-tree-adapter "^6.0.0" - yargs "^16.0.0" - cli-table3@~0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.0.tgz#b7b1bc65ca8e7b5cef9124e13dc2b21e2ce4faee" @@ -2835,45 +779,11 @@ cliui@^3.2.0: strip-ansi "^3.0.1" wrap-ansi "^2.0.0" -cliui@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" - integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== - dependencies: - string-width "^3.1.0" - strip-ansi "^5.2.0" - wrap-ansi "^5.1.0" - -cliui@^7.0.2: - version "7.0.4" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" - integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.0" - wrap-ansi "^7.0.0" - clone-buffer@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58" integrity sha1-4+JbIHrE5wGvch4staFnksrD3Fg= -clone-deep@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" - integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== - dependencies: - is-plain-object "^2.0.4" - kind-of "^6.0.2" - shallow-clone "^3.0.0" - -clone-response@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" - integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws= - dependencies: - mimic-response "^1.0.0" - clone-stats@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-1.0.0.tgz#b3782dff8bb5474e18b9b6bf0fdfe782f8777680" @@ -2898,45 +808,6 @@ cloneable-readable@^1.0.0: process-nextick-args "^2.0.0" readable-stream "^2.3.5" -cluster-key-slot@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.1.0.tgz#30474b2a981fb12172695833052bc0d01336d10d" - integrity sha512-2Nii8p3RwAPiFwsnZvukotvow2rIHM+yQ6ZcBXGHdniadkYGZYiGmkHJIbZPIV9nfv7m/U1IPMVVcAhoWFeklw== - -co-body@^5.0.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/co-body/-/co-body-5.2.0.tgz#5a0a658c46029131e0e3a306f67647302f71c124" - integrity sha512-sX/LQ7LqUhgyaxzbe7IqwPeTr2yfpfUIQ/dgpKo6ZI4y4lpQA0YxAomWIY+7I7rHWcG02PG+OuPREzMW/5tszQ== - dependencies: - inflation "^2.0.0" - qs "^6.4.0" - raw-body "^2.2.0" - type-is "^1.6.14" - -co-body@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/co-body/-/co-body-6.0.0.tgz#965b9337d7f5655480787471f4237664820827e3" - integrity sha512-9ZIcixguuuKIptnY8yemEOuhb71L/lLf+Rl5JfJEUiDNJk0e02MBt7BPxR2GEh5mw8dPthQYR4jPI/BnS1MQgw== - dependencies: - inflation "^2.0.0" - qs "^6.5.2" - raw-body "^2.3.3" - type-is "^1.6.16" - -co@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" - integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= - -coa@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/coa/-/coa-2.0.2.tgz#43f6c21151b4ef2bf57187db0d73de229e3e7ec3" - integrity sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA== - dependencies: - "@types/q" "^1.5.1" - chalk "^2.4.1" - q "^1.1.2" - coa@~1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/coa/-/coa-1.0.4.tgz#a9ef153660d6a86a8bdec0289a5c684d217432fd" @@ -2966,7 +837,7 @@ collection-visit@^1.0.0: map-visit "^1.0.0" object-visit "^1.0.0" -color-convert@^1.3.0, color-convert@^1.9.0: +color-convert@^1.3.0: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== @@ -2997,14 +868,6 @@ color-string@^0.3.0: dependencies: color-name "^1.0.0" -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== - dependencies: - color-name "^1.0.0" - simple-swizzle "^0.2.2" - color-support@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" @@ -3019,34 +882,11 @@ color@^0.11.0: color-convert "^1.3.0" color-string "^0.3.0" -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== - dependencies: - color-convert "^2.0.1" - color-string "^1.6.0" - -colord@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/colord/-/colord-2.0.1.tgz#1e7fb1f9fa1cf74f42c58cb9c20320bab8435aa0" - integrity sha512-vm5YpaWamD0Ov6TSG0GGmUIwstrWcfKQV/h2CmbR7PbNu41+qdB5PW9lpzhjedrpm08uuYvcXi0Oel1RLZIJuA== - -colord@^2.6: - version "2.7.0" - resolved "https://registry.yarnpkg.com/colord/-/colord-2.7.0.tgz#706ea36fe0cd651b585eb142fe64b6480185270e" - integrity sha512-pZJBqsHz+pYyw3zpX6ZRXWoCHM1/cvFikY9TV8G3zcejCaKE0lhankoj8iScyrrePA8C7yJ5FStfA9zbcOnw7Q== - -colorette@^1.2.0, colorette@^1.2.1, colorette@^1.2.2: +colorette@^1.2.0, colorette@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w== -colorette@^2.0.14: - version "2.0.15" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.15.tgz#8e634aa0429b110d24be82eac4d42f5ea65ab2d5" - integrity sha512-lIFQhufWaVvwi4wOlX9Gx5b0Nmw3XAZ8HzHNH9dfxhe+JaKNTmX6QLk4o7UHyI+tUY8ClvyfaHUm5bf61O3psA== - colormin@^1.0.5: version "1.1.2" resolved "https://registry.yarnpkg.com/colormin/-/colormin-1.1.2.tgz#ea2f7420a72b96881a38aae59ec124a6f7298133" @@ -3056,7 +896,7 @@ colormin@^1.0.5: css-color-names "0.0.4" has "^1.0.1" -colors@^1.1.2, colors@^1.3.3, colors@^1.4.0: +colors@^1.1.2: version "1.4.0" resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== @@ -3066,14 +906,14 @@ colors@~1.1.2: resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" integrity sha1-FopHAXVran9RoSzgyXv6KMCE7WM= -combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: +combined-stream@^1.0.6, combined-stream@~1.0.6: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== dependencies: delayed-stream "~1.0.0" -commander@^2.12.1, commander@^2.19.0, commander@^2.20.0: +commander@^2.20.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== @@ -3083,42 +923,11 @@ commander@^5.1.0: resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae" integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg== -commander@^6.0.0, commander@^6.2.1: - version "6.2.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" - integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== - -commander@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-7.0.0.tgz#3e2bbfd8bb6724760980988fb5b22b7ee6b71ab2" - integrity sha512-ovx/7NkTrnPuIV8sqk/GjUIIM1+iUQeqA3ye2VNpq9sVoiZsooObWlQy+OPWGI17GDaEoybuAGJm6U8yC077BA== - -commander@^7.1.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" - integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== - -comment-json@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/comment-json/-/comment-json-4.1.0.tgz#09d08f0fbc4ad5eeccbac20f469adbb967dcbd2c" - integrity sha512-WEghmVYaNq9NlWbrkzQTSsya9ycLyxJxpTQfZEan6a5Jomnjw18zS3Podf8q1Zf9BvonvQd/+Z7Z39L7KKzzdQ== - dependencies: - array-timsort "^1.0.3" - core-util-is "^1.0.2" - esprima "^4.0.1" - has-own-prop "^2.0.0" - repeat-string "^1.6.1" - common-tags@^1.8.0: version "1.8.0" resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.0.tgz#8e3153e542d4a39e9b10554434afaaf98956a937" integrity sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw== -compare-versions@3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-3.6.0.tgz#1a5689913685e5a87637b8d3ffca75514ec41d62" - integrity sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA== - component-emitter@^1.2.1: version "1.3.0" resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" @@ -3129,7 +938,7 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= -concat-stream@^1.5.2, concat-stream@^1.6.0: +concat-stream@^1.6.0: version "1.6.2" resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== @@ -3139,69 +948,6 @@ concat-stream@^1.5.2, concat-stream@^1.6.0: readable-stream "^2.2.2" typedarray "^0.0.6" -concurrently@6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-6.3.0.tgz#63128cb4a6ed54d3c0ed8528728590a5fe54582a" - integrity sha512-k4k1jQGHHKsfbqzkUszVf29qECBrkvBKkcPJEUDTyVR7tZd1G/JOfnst4g1sYbFvJ4UjHZisj1aWQR8yLKpGPw== - dependencies: - chalk "^4.1.0" - date-fns "^2.16.1" - lodash "^4.17.21" - rxjs "^6.6.3" - spawn-command "^0.0.2-1" - supports-color "^8.1.0" - tree-kill "^1.2.2" - yargs "^16.2.0" - -condense-newlines@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/condense-newlines/-/condense-newlines-0.2.1.tgz#3de985553139475d32502c83b02f60684d24c55f" - integrity sha1-PemFVTE5R10yUCyDsC9gaE0kxV8= - dependencies: - extend-shallow "^2.0.1" - is-whitespace "^0.3.0" - kind-of "^3.0.2" - -config-chain@^1.1.12: - version "1.1.12" - resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.12.tgz#0fde8d091200eb5e808caf25fe618c02f48e4efa" - integrity sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA== - dependencies: - ini "^1.3.4" - proto-list "~1.2.1" - -console-control-strings@^1.0.0, console-control-strings@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" - integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= - -consolidate@^0.16.0: - version "0.16.0" - resolved "https://registry.yarnpkg.com/consolidate/-/consolidate-0.16.0.tgz#a11864768930f2f19431660a65906668f5fbdc16" - integrity sha512-Nhl1wzCslqXYTJVDyJCu3ODohy9OfBMB5uD2BiBTzd7w+QY0lBzafkR8y8755yMYHAaMD4NuzbAw03/xzfw+eQ== - dependencies: - bluebird "^3.7.2" - -constantinople@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/constantinople/-/constantinople-4.0.1.tgz#0def113fa0e4dc8de83331a5cf79c8b325213151" - integrity sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw== - dependencies: - "@babel/parser" "^7.6.0" - "@babel/types" "^7.6.1" - -content-disposition@0.5.3, content-disposition@~0.5.2: - version "0.5.3" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" - integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== - dependencies: - safe-buffer "5.1.2" - -content-type@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" - integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== - convert-source-map@^1.5.0: version "1.7.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" @@ -3209,14 +955,6 @@ convert-source-map@^1.5.0: dependencies: safe-buffer "~5.1.1" -cookies@~0.8.0: - version "0.8.0" - resolved "https://registry.yarnpkg.com/cookies/-/cookies-0.8.0.tgz#1293ce4b391740a8406e3c9870e828c4b54f3f90" - integrity sha512-8aPsApQfebXnuI+537McwYsDtjVxGm8gTIzQI3FDW6t5t/DAhERxtnbEPN/8RX+uZthoz4eCOgloXaE5cYyNow== - dependencies: - depd "~2.0.0" - keygrip "~1.1.0" - copy-descriptor@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" @@ -3230,48 +968,11 @@ copy-props@^2.0.1: each-props "^1.3.0" is-plain-object "^2.0.1" -copy-to@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/copy-to/-/copy-to-2.0.1.tgz#2680fbb8068a48d08656b6098092bdafc906f4a5" - integrity sha1-JoD7uAaKSNCGVrYJgJK9r8kG9KU= - -core-util-is@1.0.2, core-util-is@^1.0.2, core-util-is@~1.0.0: +core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= -cosmiconfig@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.0.tgz#ef9b44d773959cae63ddecd122de23853b60f8d3" - integrity sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA== - dependencies: - "@types/parse-json" "^4.0.0" - import-fresh "^3.2.1" - parse-json "^5.0.0" - path-type "^4.0.0" - yaml "^1.10.0" - -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== - dependencies: - exit-on-epipe "~1.0.1" - printj "~1.1.0" - -create-require@^1.1.0: - version "1.1.1" - 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== - dependencies: - is-nan "^1.2.1" - moment-timezone "^0.5.25" - cross-env@7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf" @@ -3279,7 +980,7 @@ cross-env@7.0.3: dependencies: cross-spawn "^7.0.1" -cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3: +cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== @@ -3293,162 +994,6 @@ css-color-names@0.0.4: resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0" integrity sha1-gIrcLnnPhHOAabZGyyDsJ762KeA= -css-color-names@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-1.0.1.tgz#6ff7ee81a823ad46e020fa2fd6ab40a887e2ba67" - integrity sha512-/loXYOch1qU1biStIFsHH8SxTmOseh1IJqFvy8IujXOm1h+QjUdDhkzOrR5HG8K8mlxREj0yfi8ewCHx0eMxzA== - -css-declaration-sorter@^6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.0.3.tgz#9dfd8ea0df4cc7846827876fafb52314890c21a9" - integrity sha512-52P95mvW1SMzuRZegvpluT6yEv0FqQusydKQPZsNN5Q7hh8EwQvN8E2nwuJ16BBvNN6LcoIZXu/Bk58DAhrrxw== - dependencies: - timsort "^0.3.0" - -css-loader@6.4.0: - version "6.4.0" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.4.0.tgz#01c57ea776024e18ca193428dcad3ff6b42a0130" - integrity sha512-Dlt6qfsxI/w1vU0r8qDd4BtMPxWqJeY5qQU7SmmZfvbpe6Xl18McO4GhyaMLns24Y2VNPiZwJPQ8JSbg4qvQLw== - dependencies: - icss-utils "^5.1.0" - postcss "^8.2.15" - postcss-modules-extract-imports "^3.0.0" - postcss-modules-local-by-default "^4.0.0" - postcss-modules-scope "^3.0.0" - postcss-modules-values "^4.0.0" - postcss-value-parser "^4.1.0" - semver "^7.3.5" - -css-select-base-adapter@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz#3b2ff4972cc362ab88561507a95408a1432135d7" - integrity sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w== - -css-select@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/css-select/-/css-select-2.1.0.tgz#6a34653356635934a81baca68d0255432105dbef" - integrity sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ== - dependencies: - boolbase "^1.0.0" - css-what "^3.2.1" - domutils "^1.7.0" - nth-check "^1.0.2" - -css-select@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/css-select/-/css-select-3.1.2.tgz#d52cbdc6fee379fba97fb0d3925abbd18af2d9d8" - integrity sha512-qmss1EihSuBNWNNhHjxzxSfJoFBM/lERB/Q4EnsJQQC62R2evJDW481091oAdOr9uh46/0n4nrg0It5cAnj1RA== - dependencies: - boolbase "^1.0.0" - css-what "^4.0.0" - domhandler "^4.0.0" - domutils "^2.4.3" - nth-check "^2.0.0" - -css-select@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858" - integrity sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg= - dependencies: - boolbase "~1.0.0" - css-what "2.1" - domutils "1.5.1" - nth-check "~1.0.1" - -css-tree@1.0.0-alpha.37: - version "1.0.0-alpha.37" - resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.37.tgz#98bebd62c4c1d9f960ec340cf9f7522e30709a22" - integrity sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg== - dependencies: - mdn-data "2.0.4" - source-map "^0.6.1" - -css-tree@1.0.0-alpha.39: - version "1.0.0-alpha.39" - resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.39.tgz#2bff3ffe1bb3f776cf7eefd91ee5cba77a149eeb" - integrity sha512-7UvkEYgBAHRG9Nt980lYxjsTrCyHFN53ky3wVsDkiMdVqylqRt+Zc+jm5qw7/qyOvN2dHSYtX0e4MbCCExSvnA== - dependencies: - mdn-data "2.0.6" - source-map "^0.6.1" - -css-tree@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d" - integrity sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q== - dependencies: - mdn-data "2.0.14" - source-map "^0.6.1" - -css-what@2.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2" - integrity sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg== - -css-what@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.2.1.tgz#f4a8f12421064621b456755e34a03a2c22df5da1" - integrity sha512-WwOrosiQTvyms+Ti5ZC5vGEK0Vod3FTt1ca+payZqvKuGJF+dq7bG63DstxtN0dpm6FxY27a/zS3Wten+gEtGw== - -css-what@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/css-what/-/css-what-4.0.0.tgz#35e73761cab2eeb3d3661126b23d7aa0e8432233" - integrity sha512-teijzG7kwYfNVsUh2H/YN62xW3KK9YhXEgSlbxMlcyjPNvdKJqFx5lrwlJgoFP1ZHlB89iGDlo/JyshKeRhv5A== - -cssesc@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" - integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== - -cssnano-preset-default@^5.1.4: - version "5.1.4" - resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-5.1.4.tgz#359943bf00c5c8e05489f12dd25f3006f2c1cbd2" - integrity sha512-sPpQNDQBI3R/QsYxQvfB4mXeEcWuw0wGtKtmS5eg8wudyStYMgKOQT39G07EbW1LB56AOYrinRS9f0ig4Y3MhQ== - dependencies: - css-declaration-sorter "^6.0.3" - cssnano-utils "^2.0.1" - postcss-calc "^8.0.0" - postcss-colormin "^5.2.0" - postcss-convert-values "^5.0.1" - postcss-discard-comments "^5.0.1" - postcss-discard-duplicates "^5.0.1" - postcss-discard-empty "^5.0.1" - postcss-discard-overridden "^5.0.1" - postcss-merge-longhand "^5.0.2" - postcss-merge-rules "^5.0.2" - postcss-minify-font-values "^5.0.1" - postcss-minify-gradients "^5.0.2" - postcss-minify-params "^5.0.1" - postcss-minify-selectors "^5.1.0" - postcss-normalize-charset "^5.0.1" - postcss-normalize-display-values "^5.0.1" - postcss-normalize-positions "^5.0.1" - postcss-normalize-repeat-style "^5.0.1" - postcss-normalize-string "^5.0.1" - postcss-normalize-timing-functions "^5.0.1" - postcss-normalize-unicode "^5.0.1" - postcss-normalize-url "^5.0.2" - postcss-normalize-whitespace "^5.0.1" - postcss-ordered-values "^5.0.2" - postcss-reduce-initial "^5.0.1" - postcss-reduce-transforms "^5.0.1" - postcss-svgo "^5.0.2" - postcss-unique-selectors "^5.0.1" - -cssnano-utils@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/cssnano-utils/-/cssnano-utils-2.0.1.tgz#8660aa2b37ed869d2e2f22918196a9a8b6498ce2" - integrity sha512-i8vLRZTnEH9ubIyfdZCAdIdgnHAUeQeByEeQ2I7oTilvP9oHO6RScpeq3GsFUVqeB8uZgOQ9pw8utofNn32hhQ== - -cssnano@5.0.8: - version "5.0.8" - resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-5.0.8.tgz#39ad166256980fcc64faa08c9bb18bb5789ecfa9" - integrity sha512-Lda7geZU0Yu+RZi2SGpjYuQz4HI4/1Y+BhdD0jL7NXAQ5larCzVn+PUGuZbDMYz904AXXCOgO5L1teSvgu7aFg== - dependencies: - cssnano-preset-default "^5.1.4" - is-resolvable "^1.1.0" - lilconfig "^2.0.3" - yaml "^1.10.2" - cssnano@^3.0.0: version "3.10.0" resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-3.10.0.tgz#4f38f6cea2b9b17fa01490f23f1dc68ea65c1c38" @@ -3487,20 +1032,6 @@ cssnano@^3.0.0: postcss-value-parser "^3.2.3" postcss-zindex "^2.0.1" -csso@^4.0.2: - version "4.0.3" - resolved "https://registry.yarnpkg.com/csso/-/csso-4.0.3.tgz#0d9985dc852c7cc2b2cacfbbe1079014d1a8e903" - integrity sha512-NL3spysxUkcrOgnpsT4Xdl2aiEiBG6bXswAABQVHcMrfjjBisFOKwLDOmf4wf32aPdcJws1zds2B0Rg+jqMyHQ== - dependencies: - css-tree "1.0.0-alpha.39" - -csso@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/csso/-/csso-4.2.0.tgz#ea3a561346e8dc9f546d6febedd50187cf389529" - integrity sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA== - dependencies: - css-tree "^1.1.2" - csso@~2.3.1: version "2.3.2" resolved "https://registry.yarnpkg.com/csso/-/csso-2.3.2.tgz#ddd52c587033f49e94b71fc55569f252e8ff5f85" @@ -3509,34 +1040,12 @@ csso@~2.3.1: clap "^1.0.9" source-map "^0.5.3" -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.3.6: - version "0.3.8" - resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" - integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== - -cssstyle@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-2.3.0.tgz#ff665a0ddbdc31864b09647f34163443d90b0852" - integrity sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A== +cypress@9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/cypress/-/cypress-9.0.0.tgz#8c496f7f350e611604cc2f77b663fb81d0c235d2" + integrity sha512-/93SWBZTw7BjFZ+I9S8SqkFYZx7VhedDjTtRBmXO0VzTeDbmxgK/snMJm/VFjrqk/caWbI+XY4Qr80myDMQvYg== dependencies: - cssom "~0.3.6" - -csstype@^2.6.8: - version "2.6.13" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.13.tgz#a6893015b90e84dd6e85d0e3b442a1e84f2dbe0f" - integrity sha512-ul26pfSQTZW8dcOnD2iiJssfXw0gdNVX9IJDH/X3K5DGPfj+fUYe3kB+swUY6BF3oZDxaID3AJt+9/ojSAE05A== - -cypress@8.5.0: - version "8.5.0" - resolved "https://registry.yarnpkg.com/cypress/-/cypress-8.5.0.tgz#5712ca170913f8344bf167301205c4217c1eb9bd" - integrity sha512-MMkXIS+Ro2KETn4gAlG3tIc/7FiljuuCZP0zpd9QsRG6MZSyZW/l1J3D4iQM6WHsVxuX4rFChn5jPFlC2tNSvQ== - dependencies: - "@cypress/request" "^2.88.6" + "@cypress/request" "^2.88.7" "@cypress/xvfb" "^1.2.4" "@types/node" "^14.14.31" "@types/sinonjs__fake-timers" "^6.0.2" @@ -3571,7 +1080,6 @@ cypress@8.5.0: ospath "^1.2.2" pretty-bytes "^5.6.0" proxy-from-env "1.0.0" - ramda "~0.27.1" request-progress "^3.0.0" supports-color "^8.1.1" tmp "~0.2.1" @@ -3594,61 +1102,25 @@ dashdash@^1.12.0: dependencies: assert-plus "^1.0.0" -data-uri-to-buffer@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz#594b8973938c5bc2c33046535785341abc4f3636" - integrity sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og== - -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== - dependencies: - abab "^2.0.3" - whatwg-mimetype "^2.3.0" - whatwg-url "^8.0.0" - -date-fns@2.25.0: - version "2.25.0" - resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.25.0.tgz#8c5c8f1d958be3809a9a03f4b742eba894fc5680" - integrity sha512-ovYRFnTrbGPD4nqaEqescPEv1mNwvt+UTqI3Ay9SzNtey9NZnYu6E2qCcBBgJ6/2VF1zGGygpyTDITqpQQ5e+w== - -date-fns@^2.16.1: - version "2.19.0" - resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.19.0.tgz#65193348635a28d5d916c43ec7ce6fbd145059e1" - integrity sha512-X3bf2iTPgCAQp9wvjOQytnf5vO5rESYRXlPIVcgSbtT5OTScPcsf9eZU+B/YIkKAtYr5WeCii58BgATrNitlWg== - -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== - dayjs@^1.10.4: version "1.10.6" resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.10.6.tgz#288b2aa82f2d8418a6c9d4df5898c0737ad02a63" integrity sha512-AztC/IOW4L1Q41A86phW5Thhcrco3xuAA+YX/BLpLWWjRcTj5TOt/QImBLmCKlrF7u7k47arTnOyL6GnbG8Hvw== -debug@2, debug@^2.2.0, debug@^2.3.3, debug@^2.5.2: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@4, debug@4.3.1, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" - integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== - dependencies: - ms "2.1.2" - -debug@4.3.2, debug@^4.3.2: +debug@4.3.2, debug@^4.1.1, debug@^4.3.2: version "4.3.2" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== dependencies: ms "2.1.2" +debug@^2.2.0, debug@^2.3.3: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + debug@^3.1.0: version "3.2.7" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" @@ -3656,74 +1128,16 @@ debug@^3.1.0: dependencies: ms "^2.1.1" -debug@^3.2.6: - version "3.2.6" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" - integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== - dependencies: - ms "^2.1.1" - -debug@~3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" - integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== - dependencies: - ms "2.0.0" - -debuglog@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" - integrity sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI= - -decamelize@^1.1.1, decamelize@^1.1.2, decamelize@^1.2.0: +decamelize@^1.1.1, decamelize@^1.1.2: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= -decamelize@^4.0.0: - version "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== - decode-uri-component@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= -decompress-response@^4.2.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-4.2.1.tgz#414023cc7a302da25ce2ec82d0d5238ccafd8986" - integrity sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw== - dependencies: - mimic-response "^2.0.0" - -decompress-response@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" - integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== - dependencies: - mimic-response "^3.1.0" - -deep-equal@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" - integrity sha1-9dJgKStmDghO/0zbyfCK0yR0SLU= - -deep-extend@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" - integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== - -deep-is@^0.1.3, deep-is@~0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" - integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= - default-compare@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/default-compare/-/default-compare-1.0.0.tgz#cb61131844ad84d84788fb68fd01681ca7781a2f" @@ -3736,12 +1150,7 @@ default-resolution@^2.0.0: resolved "https://registry.yarnpkg.com/default-resolution/-/default-resolution-2.0.0.tgz#bcb82baa72ad79b426a76732f1a81ad6df26d684" integrity sha1-vLgrqnKtebQmp2cy8aga1t8m1oQ= -defer-to-connect@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.0.tgz#83d6b199db041593ac84d781b5222308ccf4c2c1" - integrity sha512-bYL2d05vOSf1JEZNx5vSAtPuBMkX8K9EUutg7zlKvTqKXHt7RhWJFbmd7qakVuf13i+IkGmp6FwSsONOf6VYIg== - -define-properties@^1.1.2, define-properties@^1.1.3: +define-properties@^1.1.2: version "1.1.3" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== @@ -3780,189 +1189,11 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= -delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= - -denque@^1.1.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/denque/-/denque-1.4.1.tgz#6744ff7641c148c3f8a69c307e51235c1f4a37cf" - integrity sha512-OfzPuSZKGcgr96rf1oODnfjqBFmr1DVoc/TrItj3Ohe0Ah1C5WX5Baquw/9U9KovnQ88EqmJbD66rKYUQYN1tQ== - -denque@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/denque/-/denque-1.5.0.tgz#773de0686ff2d8ec2ff92914316a47b73b1c73de" - integrity sha512-CYiCSgIF1p6EUByQPlGkKnP1M9g0ZV3qMIrqMqZqdwazygIA/YP2vrbcyl1h/WppKJTdl1F85cXIle+394iDAQ== - -depd@^1.1.2, depd@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= - -depd@^2.0.0, depd@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" - integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== - -destroy@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" - integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= - detect-file@^1.0.0: version "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-node@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c" - integrity sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw== - -detect-node@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" - integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== - -dicer@0.2.5: - version "0.2.5" - resolved "https://registry.yarnpkg.com/dicer/-/dicer-0.2.5.tgz#5996c086bb33218c812c090bddc09cd12facb70f" - integrity sha1-WZbAhrszIYyBLAkL3cCc0S+stw8= - dependencies: - readable-stream "1.1.x" - streamsearch "0.1.2" - -diff@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" - integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== - -diff@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" - integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== - -dijkstrajs@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/dijkstrajs/-/dijkstrajs-1.0.1.tgz#d3cd81221e3ea40742cfcde556d4e99e98ddc71b" - integrity sha1-082BIh4+pAdCz83lVtTpnpjdxxs= - -dir-glob@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" - integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== - dependencies: - path-type "^4.0.0" - -doctrine@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" - integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== - dependencies: - esutils "^2.0.2" - -doctypes@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/doctypes/-/doctypes-1.1.0.tgz#ea80b106a87538774e8a3a4a5afe293de489e0a9" - integrity sha1-6oCxBqh1OHdOijpKWv4pPeSJ4Kk= - -dom-serializer@0: - version "0.2.2" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51" - integrity sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g== - dependencies: - domelementtype "^2.0.1" - entities "^2.0.0" - -dom-serializer@^1.0.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.3.1.tgz#d845a1565d7c041a95e5dab62184ab41e3a519be" - integrity sha512-Pv2ZluG5ife96udGgEDovOOOA5UELkltfJpnIExPrAk1LTvecolUGn6lIaoLh86d83GiB86CjzciMd9BuRB71Q== - dependencies: - domelementtype "^2.0.1" - domhandler "^4.0.0" - entities "^2.0.0" - -dom-serializer@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.1.tgz#1ec4059e284babed36eec2941d4a970a189ce7c0" - integrity sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA== - dependencies: - domelementtype "^1.3.0" - entities "^1.1.1" - -domelementtype@1, domelementtype@^1.3.0, domelementtype@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" - integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== - -domelementtype@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.0.1.tgz#1f8bdfe91f5a78063274e803b4bdcedf6e94f94d" - integrity sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ== - -domelementtype@^2.2.0: - version "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== - dependencies: - webidl-conversions "^5.0.0" - -domhandler@^2.3.0: - version "2.4.2" - resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803" - integrity sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA== - dependencies: - domelementtype "1" - -domhandler@^4.0.0, domhandler@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.1.0.tgz#c1d8d494d5ec6db22de99e46a149c2a4d23ddd43" - integrity sha512-/6/kmsGlMY4Tup/nGVutdrK9yQi4YjWVcVeoQmixpzjOUK1U7pQkvAPHBJeUxOgxF0J8f8lwCJSlCfD0V4CMGQ== - dependencies: - domelementtype "^2.2.0" - -domutils@1.5.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" - integrity sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8= - dependencies: - dom-serializer "0" - domelementtype "1" - -domutils@^1.5.1, domutils@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" - integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg== - dependencies: - dom-serializer "0" - domelementtype "1" - -domutils@^2.4.3: - version "2.5.2" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.5.2.tgz#37ef8ba087dff1a17175e7092e8a042e4b050e6c" - integrity sha512-MHTthCb1zj8f1GVfRpeZUbohQf/HdBos0oX5gZcQFepOZPLLRyj6Wn7XS7EMnY7CVpwv8863u2vyE83Hfu28HQ== - dependencies: - dom-serializer "^1.0.1" - domelementtype "^2.2.0" - domhandler "^4.1.0" - -dotenv@^8.2.0: - version "8.2.0" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a" - integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw== - duplexer@~0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" @@ -3994,186 +1225,37 @@ ecc-jsbn@~0.1.1: jsbn "~0.1.0" safer-buffer "^2.1.0" -ecdsa-sig-formatter@1.0.11: - version "1.0.11" - resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf" - integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ== - dependencies: - safe-buffer "^5.0.1" - -editorconfig@^0.15.3: - version "0.15.3" - resolved "https://registry.yarnpkg.com/editorconfig/-/editorconfig-0.15.3.tgz#bef84c4e75fb8dcb0ce5cee8efd51c15999befc5" - integrity sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g== - dependencies: - commander "^2.19.0" - lru-cache "^4.1.5" - semver "^5.6.0" - sigmund "^1.0.1" - -ee-first@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" - integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= - electron-to-chromium@^1.2.7: version "1.3.633" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.633.tgz#16dd5aec9de03894e8d14a1db4cda8a369b9b7fe" integrity sha512-bsVCsONiVX1abkWdH7KtpuDAhsQ3N3bjPYhROSAXE78roJKet0Y5wznA14JE9pzbwSZmSMAW6KiKYf1RvbTJkA== -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== - -electron-to-chromium@^1.3.712: - version "1.3.717" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.717.tgz#78d4c857070755fb58ab64bcc173db1d51cbc25f" - integrity sha512-OfzVPIqD1MkJ7fX+yTl2nKyOE4FReeVfMCzzxQS+Kp43hZYwHwThlGP+EGIZRXJsxCM7dqo8Y65NOX/HP12iXQ== - -electron-to-chromium@^1.3.723: - version "1.3.742" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.742.tgz#7223215acbbd3a5284962ebcb6df85d88b95f200" - integrity sha512-ihL14knI9FikJmH2XUIDdZFWJxvr14rPSdOhJ7PpS27xbz8qmaRwCwyg/bmFwjWKmWK9QyamiCZVCvXm5CH//Q== - -emoji-regex@^7.0.1: - version "7.0.3" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" - integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== - emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== -emojis-list@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" - integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== - -encodeurl@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" - integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= - -encoding@^0.1.12: - version "0.1.13" - resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" - integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== - dependencies: - iconv-lite "^0.6.2" - -end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.1: +end-of-stream@^1.0.0, end-of-stream@^1.1.0: version "1.4.4" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== dependencies: once "^1.4.0" -enhanced-resolve@^5.0.0: - version "5.8.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.8.0.tgz#d9deae58f9d3773b6a111a5a46831da5be5c9ac0" - integrity sha512-Sl3KRpJA8OpprrtaIswVki3cWPiPKxXuFxJXBp+zNb6s6VwNWwFRUdtmzd2ReUut8n+sCPx7QCtQ7w5wfJhSgQ== - dependencies: - 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" - -enhanced-resolve@^5.8.3: - version "5.8.3" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz#6d552d465cce0423f5b3d718511ea53826a7b2f0" - integrity sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA== - dependencies: - graceful-fs "^4.2.4" - tapable "^2.2.0" - -enquirer@^2.3.5, enquirer@^2.3.6: +enquirer@^2.3.6: version "2.3.6" resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== dependencies: ansi-colors "^4.1.1" -entities@^1.1.1, entities@~1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" - integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== - -entities@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.0.tgz#68d6084cab1b079767540d80e56a39b423e4abf4" - integrity sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw== - -entities@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/entities/-/entities-2.1.0.tgz#992d3129cf7df6870b96c57858c249a120f8b8b5" - integrity sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w== - -env-paths@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.0.tgz#cdca557dc009152917d6166e2febe1f039685e43" - integrity sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA== - -envinfo@^7.7.3: - version "7.7.3" - resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.7.3.tgz#4b2d8622e3e7366afb8091b23ed95569ea0208cc" - integrity sha512-46+j5QxbPWza0PB1i15nZx0xQ4I/EfQxg9J8Had3b408SV63nEtor2e+oiY63amTo9KTuh2a3XLObNwduxYwwA== - -err-code@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9" - integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA== - -error-ex@^1.2.0, error-ex@^1.3.1: +error-ex@^1.2.0: version "1.3.2" resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== dependencies: is-arrayish "^0.2.1" -es-abstract@^1.17.0-next.0, es-abstract@^1.17.0-next.1, es-abstract@^1.17.2, es-abstract@^1.17.5: - version "1.17.5" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.5.tgz#d8c9d1d66c8981fb9200e2251d799eee92774ae9" - integrity sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg== - dependencies: - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" - is-callable "^1.1.5" - is-regex "^1.0.5" - object-inspect "^1.7.0" - object-keys "^1.1.1" - object.assign "^4.1.0" - string.prototype.trimleft "^2.1.1" - string.prototype.trimright "^2.1.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-module-lexer@^0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.0.tgz#fe4c4621977bc668e285c5f1f70ca3b451095fda" - integrity sha512-qU2eN/XHsrl3E4y7mK1wdWnyy5c8gXtCbfP6Xcsemm7fPUR1PIV1JhZfP7ojcN0Fzp69CfrS3u76h2tusvfKiQ== - -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" - integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50: version "0.10.53" resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.53.tgz#93c5a3acfdbef275220ad72644ad02ee18368de1" @@ -4210,214 +1292,21 @@ es6-weak-map@^2.0.1: es6-iterator "^2.0.3" es6-symbol "^3.1.1" -escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== - -escape-html@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= - -escape-regexp@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/escape-regexp/-/escape-regexp-0.0.1.tgz#f44bda12d45bbdf9cb7f862ee7e4827b3dd32254" - integrity sha1-9EvaEtRbvfnLf4Yu5+SCez3TIlQ= - -escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== - escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.3, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= -escodegen@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.0.0.tgz#5e32b12833e8aa8fa35e1bf0befa89380484c7dd" - integrity sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw== - dependencies: - esprima "^4.0.1" - estraverse "^5.2.0" - esutils "^2.0.2" - optionator "^0.8.1" - optionalDependencies: - source-map "~0.6.1" - -eslint-plugin-vue@7.20.0: - version "7.20.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-vue/-/eslint-plugin-vue-7.20.0.tgz#98c21885a6bfdf0713c3a92957a5afeaaeed9253" - integrity sha512-oVNDqzBC9h3GO+NTgWeLMhhGigy6/bQaQbHS+0z7C4YEu/qK/yxHvca/2PTZtGNPsCrHwOTgKMrwu02A9iPBmw== - dependencies: - eslint-utils "^2.1.0" - natural-compare "^1.4.0" - semver "^6.3.0" - vue-eslint-parser "^7.10.0" - -eslint-scope@5.1.1, eslint-scope@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" - integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== - dependencies: - esrecurse "^4.3.0" - estraverse "^4.1.1" - -eslint-scope@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-6.0.0.tgz#9cf45b13c5ac8f3d4c50f46a5121f61b3e318978" - integrity sha512-uRDL9MWmQCkaFus8RF5K9/L/2fn+80yoW3jkD53l4shjCh26fCtvJGasxjUqP5OT87SYTxCVA3BwTUzuELx9kA== - dependencies: - esrecurse "^4.3.0" - estraverse "^5.2.0" - -eslint-utils@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" - integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== - dependencies: - eslint-visitor-keys "^1.1.0" - -eslint-utils@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672" - integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== - dependencies: - eslint-visitor-keys "^2.0.0" - -eslint-visitor-keys@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" - integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== - -eslint-visitor-keys@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz#21fdc8fbcd9c795cc0321f0563702095751511a8" - integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ== - -eslint-visitor-keys@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.0.0.tgz#e32e99c6cdc2eb063f204eda5db67bfe58bb4186" - integrity sha512-mJOZa35trBTb3IyRmo8xmKBZlxf+N7OnUl4+ZhJHs/r+0770Wh/LEACE2pqMGMe27G/4y8P2bYGk4J70IC5k1Q== - -eslint@8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.1.0.tgz#00f1f7dbf4134f26588e6c9f2efe970760f64664" - integrity sha512-JZvNneArGSUsluHWJ8g8MMs3CfIEzwaLx9KyH4tZ2i+R2/rPWzL8c0zg3rHdwYVpN/1sB9gqnjHwz9HoeJpGHw== - dependencies: - "@eslint/eslintrc" "^1.0.3" - "@humanwhocodes/config-array" "^0.6.0" - ajv "^6.10.0" - chalk "^4.0.0" - cross-spawn "^7.0.2" - debug "^4.3.2" - doctrine "^3.0.0" - enquirer "^2.3.5" - escape-string-regexp "^4.0.0" - eslint-scope "^6.0.0" - eslint-utils "^3.0.0" - eslint-visitor-keys "^3.0.0" - espree "^9.0.0" - esquery "^1.4.0" - esutils "^2.0.2" - fast-deep-equal "^3.1.3" - file-entry-cache "^6.0.1" - functional-red-black-tree "^1.0.1" - glob-parent "^6.0.1" - globals "^13.6.0" - ignore "^4.0.6" - import-fresh "^3.0.0" - imurmurhash "^0.1.4" - is-glob "^4.0.0" - js-yaml "^4.1.0" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.4.1" - lodash.merge "^4.6.2" - minimatch "^3.0.4" - natural-compare "^1.4.0" - optionator "^0.9.1" - progress "^2.0.0" - regexpp "^3.2.0" - semver "^7.2.1" - strip-ansi "^6.0.0" - strip-json-comments "^3.1.0" - text-table "^0.2.0" - v8-compile-cache "^2.0.3" - -esm@^3.2.22: - version "3.2.25" - resolved "https://registry.yarnpkg.com/esm/-/esm-3.2.25.tgz#342c18c29d56157688ba5ce31f8431fbb795cc10" - integrity sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA== - -espree@^6.2.1: - version "6.2.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-6.2.1.tgz#77fc72e1fd744a2052c20f38a5b575832e82734a" - integrity sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw== - dependencies: - acorn "^7.1.1" - acorn-jsx "^5.2.0" - eslint-visitor-keys "^1.1.0" - -espree@^9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.0.0.tgz#e90a2965698228502e771c7a58489b1a9d107090" - integrity sha512-r5EQJcYZ2oaGbeR0jR0fFVijGOcwai07/690YRXLINuhmVeRY4UKSAsQPe/0BNuDgwP7Ophoc1PRsr2E3tkbdQ== - dependencies: - acorn "^8.5.0" - acorn-jsx "^5.3.1" - eslint-visitor-keys "^3.0.0" - esprima@^2.6.0: version "2.7.3" resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" integrity sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE= -esprima@^4.0.0, esprima@^4.0.1: +esprima@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== -esquery@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" - integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== - dependencies: - estraverse "^5.1.0" - -esrecurse@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" - integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== - dependencies: - estraverse "^5.2.0" - -estraverse@^4.1.1: - version "4.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" - integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== - -estraverse@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.1.0.tgz#374309d39fd935ae500e7b92e8a6b4c720e59642" - integrity sha512-FyohXK+R0vE+y1nHLoBM7ZTyqRpqAlhdZHCWIWEviFLiGB8b04H6bQs8G+XTthacvT8VuwvteiP7RJSxMs8UEw== - -estraverse@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" - integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== - -estree-walker@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" - integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== - -esutils@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" - integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== - event-stream@=3.3.4: version "3.3.4" resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-3.3.4.tgz#4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571" @@ -4431,32 +1320,12 @@ event-stream@=3.3.4: stream-combiner "~0.0.4" through "~2.3.1" -event-target-shim@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" - integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== - eventemitter2@^6.4.3: version "6.4.4" resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-6.4.4.tgz#aa96e8275c4dbeb017a5d0e03780c65612a1202b" integrity sha512-HLU3NDY6wARrLCEwyGKRBvuWYyvW6mHYv72SJJAH3iJN3a6eVUvkjFkcxah1bcTgGVBBrFdIopBJPhCQFMLyXw== -eventemitter3@4.0.7, eventemitter3@^4.0.7: - version "4.0.7" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" - integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== - -events@1.1.1: - version "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@4.1.0, execa@^4.0.0: +execa@4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/execa/-/execa-4.1.0.tgz#4e5491ad1572f2f17a77d388c6c857135b22847a" integrity sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA== @@ -4486,21 +1355,6 @@ execa@5.1.1: signal-exit "^3.0.3" strip-final-newline "^2.0.0" -execa@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-5.0.0.tgz#4029b0007998a841fbd1032e5f4de86a3c1e3376" - integrity sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ== - dependencies: - cross-spawn "^7.0.3" - get-stream "^6.0.0" - human-signals "^2.1.0" - is-stream "^2.0.0" - merge-stream "^2.0.0" - npm-run-path "^4.0.1" - onetime "^5.1.2" - signal-exit "^3.0.3" - strip-final-newline "^2.0.0" - executable@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/executable/-/executable-4.1.1.tgz#41532bff361d3e57af4d763b70582db18f5d133c" @@ -4508,11 +1362,6 @@ executable@^4.1.1: dependencies: pify "^2.2.0" -exit-on-epipe@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz#0bdd92e87d5285d267daa8171d0eb06159689692" - integrity sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw== - expand-brackets@^2.1.4: version "2.1.4" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" @@ -4526,11 +1375,6 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" -expand-template@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" - integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== - expand-tilde@^2.0.0, expand-tilde@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" @@ -4600,7 +1444,7 @@ extsprintf@^1.2.0: resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= -fancy-log@1.3.3, fancy-log@^1.3.2: +fancy-log@^1.3.2: version "1.3.3" resolved "https://registry.yarnpkg.com/fancy-log/-/fancy-log-1.3.3.tgz#dbc19154f558690150a23953a0adbd035be45fc7" integrity sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw== @@ -4615,50 +1459,11 @@ fast-deep-equal@^3.1.1: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4" integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA== -fast-deep-equal@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" - integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== - -fast-glob@^3.1.1: - version "3.2.4" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.4.tgz#d20aefbf99579383e7f3cc66529158c9b98554d3" - integrity sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.0" - merge2 "^1.3.0" - micromatch "^4.0.2" - picomatch "^2.2.1" - fast-json-stable-stringify@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== -fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= - -fast-xml-parser@^3.19.0: - version "3.19.0" - resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-3.19.0.tgz#cb637ec3f3999f51406dd8ff0e6fc4d83e520d01" - integrity sha512-4pXwmBplsCPv8FOY1WRakF970TjNGnGnfbOnLqjlYvMiF1SR3yOHyxMR/YCXpPTOspNF5gwudqktIP4VsWkvBg== - -fastest-levenshtein@^1.0.12: - version "1.0.12" - resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz#9990f7d3a88cc5a9ffd1f1745745251700d497e2" - integrity sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow== - -fastq@^1.6.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.8.0.tgz#550e1f9f59bbc65fe185cb6a9b4d95357107f481" - integrity sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q== - dependencies: - reusify "^1.0.4" - fd-slicer@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" @@ -4666,23 +1471,6 @@ fd-slicer@~1.1.0: dependencies: pend "~1.2.0" -feed@4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/feed/-/feed-4.2.2.tgz#865783ef6ed12579e2c44bbef3c9113bc4956a7e" - integrity sha512-u5/sxGfiMfZNtJ3OvQpXcvotFpYkL0n9u9mM2vkui2nGo8b4wvDkJ8gAkYqbA8QpGyFCv3RK0Z+Iv+9veCS9bQ== - dependencies: - xml-js "^1.6.11" - -fetch-blob@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/fetch-blob/-/fetch-blob-2.1.2.tgz#a7805db1361bd44c1ef62bb57fb5fe8ea173ef3c" - integrity sha512-YKqtUDwqLyfyMnmbw8XD6Q8j9i/HggKtPEI+pZ1+8bvheBu78biSmNaXWusx1TauGqtUUGx/cBb1mKdq2rLYow== - -figlet@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/figlet/-/figlet-1.3.0.tgz#c49e3d92907ba13bebadc7124f76ba71f1f32ef0" - integrity sha512-f7A8aOJAfyehLJ7lQ6rEA8WJw7kOk3lfWRi5piSjkzbK5YkI5sqO8eiLHz1ehO+DM0QYB85i8VfA6XIGUbU1dg== - figures@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" @@ -4690,21 +1478,10 @@ figures@^3.2.0: dependencies: escape-string-regexp "^1.0.5" -file-entry-cache@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" - integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== - dependencies: - flat-cache "^3.0.4" - -file-type@16.5.3: - version "16.5.3" - resolved "https://registry.yarnpkg.com/file-type/-/file-type-16.5.3.tgz#474b7e88c74724046abb505e9b8ed4db30c4fc06" - integrity sha512-uVsl7iFhHSOY4bEONLlTK47iAHtNsFHWP5YE4xJfZ4rnX7S1Q3wce09XgqSC7E/xh8Ncv/be1lNoyprlUH/x6A== - dependencies: - readable-web-to-node-stream "^3.0.0" - strtok3 "^6.2.4" - token-types "^4.1.1" +file-uri-to-path@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" + integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== fill-range@^4.0.0: version "4.0.0" @@ -4723,22 +1500,6 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" -find-node-modules@^2.1.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/find-node-modules/-/find-node-modules-2.1.2.tgz#57565a3455baf671b835bc6b2134a9b938b9c53c" - integrity sha512-x+3P4mbtRPlSiVE1Qco0Z4YLU8WFiFcuWTf3m75OV9Uzcfs2Bg+O9N+r/K0AnmINBW06KpfqKwYJbFlFq4qNug== - dependencies: - findup-sync "^4.0.0" - merge "^2.1.0" - -find-up@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" - integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== - dependencies: - locate-path "^6.0.0" - path-exists "^4.0.0" - find-up@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" @@ -4747,21 +1508,6 @@ find-up@^1.0.0: path-exists "^2.0.0" pinkie-promise "^2.0.0" -find-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" - integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== - dependencies: - locate-path "^3.0.0" - -find-up@^4.0.0, find-up@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" - integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== - dependencies: - locate-path "^5.0.0" - path-exists "^4.0.0" - findup-sync@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-2.0.0.tgz#9326b1488c22d1a6088650a86901b2d9a90a2cbc" @@ -4782,16 +1528,6 @@ findup-sync@^3.0.0: micromatch "^3.0.4" resolve-dir "^1.0.1" -findup-sync@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-4.0.0.tgz#956c9cdde804052b881b428512905c4a5f2cdef0" - integrity sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ== - dependencies: - detect-file "^1.0.0" - is-glob "^4.0.0" - micromatch "^4.0.2" - resolve-dir "^1.0.1" - fined@^1.0.1: version "1.2.0" resolved "https://registry.yarnpkg.com/fined/-/fined-1.2.0.tgz#d00beccf1aa2b475d16d423b0238b713a2c4a37b" @@ -4808,37 +1544,11 @@ flagged-respawn@^1.0.0: resolved "https://registry.yarnpkg.com/flagged-respawn/-/flagged-respawn-1.0.1.tgz#e7de6f1279ddd9ca9aac8a5971d618606b3aab41" integrity sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q== -flat-cache@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" - integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== - dependencies: - flatted "^3.1.0" - rimraf "^3.0.2" - -flat@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" - integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== - -flatted@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.1.0.tgz#a5d06b4a8b01e3a63771daa5cb7a1903e2e57067" - integrity sha512-tW+UkmtNg/jv9CSofAKvgVcO7c2URjhTdW1ZTkcAritblu8tajiYy7YisnIflEwtKssCtOxpnBRoCB7iap0/TA== - flatten@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.3.tgz#c1283ac9f27b368abc1e36d1ff7b04501a30356b" integrity sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg== -fluent-ffmpeg@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/fluent-ffmpeg/-/fluent-ffmpeg-2.1.2.tgz#c952de2240f812ebda0aa8006d7776ee2acf7d74" - integrity sha1-yVLeIkD4EuvaCqgAbXd27irPfXQ= - dependencies: - async ">=0.2.9" - which "^1.1.1" - flush-write-stream@^1.0.2: version "1.1.1" resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" @@ -4864,25 +1574,11 @@ for-own@^1.0.0: dependencies: for-in "^1.0.1" -foreach@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" - integrity sha1-C+4AUBiusmDQo6865ljdATbsG5k= - forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= -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== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.8" - mime-types "^2.1.12" - form-data@~2.3.2: version "2.3.3" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" @@ -4899,30 +1595,11 @@ fragment-cache@^0.2.1: dependencies: map-cache "^0.2.2" -fresh@~0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" - integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= - from@~0: version "0.1.7" resolved "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe" integrity sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4= -fs-constants@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" - integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== - -fs-extra@^8.0.1: - version "8.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" - integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^4.0.0" - universalify "^0.1.0" - fs-extra@^9.1.0: version "9.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" @@ -4933,13 +1610,6 @@ fs-extra@^9.1.0: jsonfile "^6.0.1" universalify "^2.0.0" -fs-minipass@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" - integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== - dependencies: - minipass "^3.0.0" - fs-mkdirp-stream@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz#0b7815fc3201c6a69e14db98ce098c16935259eb" @@ -4953,6 +1623,14 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= +fsevents@^1.2.7: + version "1.2.13" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.13.tgz#f325cb0455592428bcf11b383370ef70e3bfcc38" + integrity sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw== + dependencies: + bindings "^1.5.0" + nan "^2.12.1" + fsevents@~2.1.2: version "2.1.3" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" @@ -4963,47 +1641,11 @@ function-bind@^1.1.1: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== -functional-red-black-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= - -gauge@~2.7.3: - version "2.7.4" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" - integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= - dependencies: - aproba "^1.0.3" - console-control-strings "^1.0.0" - has-unicode "^2.0.0" - object-assign "^4.1.0" - signal-exit "^3.0.0" - string-width "^1.0.1" - strip-ansi "^3.0.1" - wide-align "^1.1.0" - get-caller-file@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== -get-caller-file@^2.0.1, get-caller-file@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" - integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== - -get-paths@0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/get-paths/-/get-paths-0.0.7.tgz#15331086752077cf130166ccd233a1cdbeefcf38" - integrity sha512-0wdJt7C1XKQxuCgouqd+ZvLJ56FQixKoki9MrFaO4EriqzXOiH9gbukaDE1ou08S8Ns3/yDzoBAISNPqj6e6tA== - dependencies: - pify "^4.0.1" - -get-port@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/get-port/-/get-port-5.1.1.tgz#0469ed07563479de6efb986baf053dcd7d4e3193" - integrity sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ== - get-stream@^5.0.0, get-stream@^5.1.0: version "5.2.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" @@ -5035,11 +1677,6 @@ getpass@^0.1.1: dependencies: assert-plus "^1.0.0" -github-from-package@0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" - integrity sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4= - glob-parent@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" @@ -5048,20 +1685,13 @@ glob-parent@^3.1.0: is-glob "^3.1.0" path-dirname "^1.0.0" -glob-parent@^5.1.0, glob-parent@~5.1.0: +glob-parent@~5.1.0: version "5.1.1" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ== dependencies: is-glob "^4.0.1" -glob-parent@^6.0.1: - version "6.0.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" - integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== - dependencies: - is-glob "^4.0.3" - glob-stream@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/glob-stream/-/glob-stream-6.1.0.tgz#7045c99413b3eb94888d83ab46d0b404cc7bdde4" @@ -5078,11 +1708,6 @@ glob-stream@^6.1.0: to-absolute-glob "^2.0.0" unique-stream "^2.0.2" -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-watcher@^5.0.3: version "5.0.3" resolved "https://registry.yarnpkg.com/glob-watcher/-/glob-watcher-5.0.3.tgz#88a8abf1c4d131eb93928994bc4a593c2e5dd626" @@ -5095,7 +1720,7 @@ glob-watcher@^5.0.3: just-debounce "^1.0.0" object.defaults "^1.1.0" -glob@7.1.6, glob@^7.1.1, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: +glob@^7.1.1, glob@^7.1.3: version "7.1.6" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== @@ -5107,18 +1732,6 @@ glob@7.1.6, glob@^7.1.1, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: once "^1.3.0" path-is-absolute "^1.0.0" -glob@7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" - integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - global-dirs@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-3.0.0.tgz#70a76fe84ea315ab37b1f5576cbde7d48ef72686" @@ -5146,44 +1759,6 @@ global-prefix@^1.0.1: is-windows "^1.0.1" which "^1.2.14" -globals@^13.6.0: - version "13.7.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.7.0.tgz#aed3bcefd80ad3ec0f0be2cf0c895110c0591795" - integrity sha512-Aipsz6ZKRxa/xQkZhNg0qIWXT6x6rD46f6x/PCnBomlttdIyAPak4YD9jTmKpZ72uROSMU87qJtcgpgHaVchiA== - dependencies: - type-fest "^0.20.2" - -globals@^13.9.0: - version "13.9.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.9.0.tgz#4bf2bf635b334a173fb1daf7c5e6b218ecdc06cb" - integrity sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA== - dependencies: - type-fest "^0.20.2" - -globby@^11.0.2: - version "11.0.3" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.3.tgz#9b1f0cb523e171dd1ad8c7b2a9fb4b644b9593cb" - integrity sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg== - dependencies: - array-union "^2.1.0" - dir-glob "^3.0.1" - fast-glob "^3.1.1" - ignore "^5.1.4" - merge2 "^1.3.0" - slash "^3.0.0" - -globby@^11.0.4: - version "11.0.4" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.4.tgz#2cbaff77c2f2a62e71e9b2813a67b97a3a3001a5" - integrity sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg== - dependencies: - array-union "^2.1.0" - dir-glob "^3.0.1" - fast-glob "^3.1.1" - ignore "^5.1.4" - merge2 "^1.3.0" - slash "^3.0.0" - glogg@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/glogg/-/glogg-1.0.2.tgz#2d7dd702beda22eb3bffadf880696da6d846313f" @@ -5191,24 +1766,7 @@ glogg@^1.0.0: dependencies: sparkles "^1.0.0" -got@11.8.2: - version "11.8.2" - resolved "https://registry.yarnpkg.com/got/-/got-11.8.2.tgz#7abb3959ea28c31f3576f1576c1effce23f33599" - integrity sha512-D0QywKgIe30ODs+fm8wMZiAcZjypcCodPNuMz5H9Mny7RJ+IjJ10BdmGW7OM7fHXP+O7r6ZwapQ/YQmMSvB0UQ== - dependencies: - "@sindresorhus/is" "^4.0.0" - "@szmarczak/http-timer" "^4.0.5" - "@types/cacheable-request" "^6.0.1" - "@types/responselike" "^1.0.0" - cacheable-lookup "^5.0.3" - cacheable-request "^7.0.1" - decompress-response "^6.0.0" - http2-wrapper "^1.0.0-beta.5.2" - lowercase-keys "^2.0.0" - p-cancelable "^2.0.0" - responselike "^2.0.0" - -graceful-fs@^4.0.0, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.4: +graceful-fs@^4.0.0, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6: version "4.2.4" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== @@ -5218,16 +1776,6 @@ graceful-fs@^4.2.0: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a" integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg== -graceful-fs@^4.2.6: - version "4.2.6" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" - integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== - -growl@1.10.5: - version "1.10.5" - resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" - integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== - gulp-cli@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/gulp-cli/-/gulp-cli-2.2.0.tgz#5533126eeb7fe415a7e3e84a297d334d5cf70ebc" @@ -5289,18 +1837,6 @@ gulp-terser@2.1.0: through2 "^4.0.2" vinyl-sourcemaps-apply "^0.2.1" -gulp-tslint@8.1.4: - version "8.1.4" - resolved "https://registry.yarnpkg.com/gulp-tslint/-/gulp-tslint-8.1.4.tgz#8519ee25ff97aa749e691d4af0fdaccce5f01f7a" - integrity sha512-wBoZIEMJRz9urHwolsvQpngA9l931p6g/Liwz1b/KrsVP6jEBFZv/o0NS1TFCQZi/l8mXxz8+v3twhf4HOXxPQ== - dependencies: - "@types/fancy-log" "1.3.0" - ansi-colors "^1.0.1" - fancy-log "1.3.3" - map-stream "~0.0.7" - plugin-error "1.0.1" - through "~2.3.8" - gulp@4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/gulp/-/gulp-4.0.2.tgz#543651070fd0f6ab0a0650c6a3e6ff5a7cb09caa" @@ -5318,11 +1854,6 @@ gulplog@^1.0.0: dependencies: glogg "^1.0.0" -hammerjs@^2.0.8: - version "2.0.8" - resolved "https://registry.yarnpkg.com/hammerjs/-/hammerjs-2.0.8.tgz#04ef77862cff2bb79d30f7692095930222bf60f1" - integrity sha1-BO93hiz/K7edMPdpIJWTAiK/YPE= - har-schema@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" @@ -5348,31 +1879,16 @@ has-flag@^1.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" integrity sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo= -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= - has-flag@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -has-own-prop@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-own-prop/-/has-own-prop-2.0.0.tgz#f0f95d58f65804f5d218db32563bb85b8e0417af" - integrity sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ== - -has-symbols@^1.0.0, has-symbols@^1.0.1: +has-symbols@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== -has-unicode@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" - integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= - has-value@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" @@ -5411,26 +1927,6 @@ has@^1.0.1, has@^1.0.3: dependencies: function-bind "^1.1.1" -hash-sum@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/hash-sum/-/hash-sum-1.0.2.tgz#33b40777754c6432573c120cc3808bbd10d47f04" - integrity sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ= - -hash-sum@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/hash-sum/-/hash-sum-2.0.0.tgz#81d01bb5de8ea4a214ad5d6ead1b523460b0b45a" - integrity sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg== - -he@1.2.0, he@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" - integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== - -highlight.js@^10.7.1: - version "10.7.2" - resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.7.2.tgz#89319b861edc66c48854ed1e6da21ea89f847360" - integrity sha512-oFLl873u4usRM9K63j4ME9u3etNF0PLiJhSQ8rdfuL51Wn3zkD6drf9ZW0dOzjnZI22YYG24z30JcmfCZjMgYg== - homedir-polyfill@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8" @@ -5443,104 +1939,11 @@ hosted-git-info@^2.1.4: resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== -hpagent@0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/hpagent/-/hpagent-0.1.2.tgz#cab39c66d4df2d4377dbd212295d878deb9bdaa9" - integrity sha512-ePqFXHtSQWAFXYmj+JtOTHr84iNrII4/QRlAAPPE+zqnKy4xJo7Ie1Y4kC7AdB+LxLxSTTzBMASsEcy0q8YyvQ== - -hpagent@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/hpagent/-/hpagent-0.1.1.tgz#66f67f16e5c7a8b59a068e40c2658c2c749ad5e2" - integrity sha512-IxJWQiY0vmEjetHdoE9HZjD4Cx+mYTr25tR7JCxXaiI3QxW0YqYyM11KyZbHufoa/piWhMb2+D3FGpMgmA2cFQ== - html-comment-regex@^1.1.0: version "1.1.2" resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.2.tgz#97d4688aeb5c81886a364faa0cad1dda14d433a7" integrity sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ== -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== - dependencies: - whatwg-encoding "^1.0.5" - -html-entities@2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.3.2.tgz#760b404685cb1d794e4f4b744332e3b00dcfe488" - integrity sha512-c3Ab/url5ksaT0WyleslpBEthOzWhrjQbg75y7XUsfSzi3Dgzt0l8w5e7DylRn15MTlMMD58dTfzddNS2kcAjQ== - -htmlparser2@^3.9.1: - version "3.10.1" - resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f" - integrity sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ== - dependencies: - domelementtype "^1.3.1" - domhandler "^2.3.0" - domutils "^1.5.1" - entities "^1.1.1" - inherits "^2.0.1" - readable-stream "^3.1.1" - -http-assert@^1.3.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/http-assert/-/http-assert-1.4.1.tgz#c5f725d677aa7e873ef736199b89686cceb37878" - integrity sha512-rdw7q6GTlibqVVbXr0CKelfV5iY8G2HqEUkhSk297BMbSpSL8crXC+9rjKoMcZZEsksX30le6f/4ul4E28gegw== - dependencies: - deep-equal "~1.0.1" - http-errors "~1.7.2" - -http-cache-semantics@^4.0.0, http-cache-semantics@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" - integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== - -http-errors@1.7.3, http-errors@^1.6.3, http-errors@^1.7.3, http-errors@~1.7.2: - version "1.7.3" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" - integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== - dependencies: - depd "~1.1.2" - inherits "2.0.4" - setprototypeof "1.1.1" - statuses ">= 1.5.0 < 2" - toidentifier "1.0.0" - -http-errors@~1.6.2: - version "1.6.3" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" - integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= - dependencies: - depd "~1.1.2" - inherits "2.0.3" - 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" - integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== - dependencies: - "@tootallnate/once" "1" - agent-base "6" - debug "4" - -http-signature@1.3.5: - version "1.3.5" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.3.5.tgz#9f19496ffbf3227298d7b5f156e0e1a948678683" - integrity sha512-NwoTQYSJoFt34jSBbwzDHDofoA61NGXzu6wXh95o1Ry62EnmKjXb/nR/RknLeZ3G/uGwrlKNY2z7uPt+Cdl7Tw== - dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.14.1" - http-signature@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" @@ -5550,29 +1953,6 @@ http-signature@~1.2.0: jsprim "^1.2.2" sshpk "^1.7.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" - integrity sha512-bptAfCDdPJxOs5zYSe7Y3lpr772s1G346R4Td5LgRUeCwIGpCGDUTJxRrhTNcAXbx37spge0kWEIH7QAYWNTlA== - dependencies: - urlsafe-base64 "~1.0.0" - -https-proxy-agent@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" - integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA== - dependencies: - agent-base "6" - debug "4" - human-signals@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" @@ -5583,105 +1963,6 @@ human-signals@^2.1.0: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== -humanize-ms@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" - integrity sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0= - dependencies: - ms "^2.0.0" - -humanize-number@0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/humanize-number/-/humanize-number-0.0.2.tgz#11c0af6a471643633588588048f1799541489c18" - integrity sha1-EcCvakcWQ2M1iFiASPF5lUFInBg= - -iconv-lite@0.4.24, iconv-lite@^0.4.4: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -iconv-lite@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.2.tgz#ce13d1875b0c3a674bd6a04b7f76b01b1b6ded01" - integrity sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ== - dependencies: - safer-buffer ">= 2.1.2 < 3.0.0" - -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" - -icss-utils@^5.0.0, icss-utils@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" - integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== - -idb-keyval@5.1.3: - version "5.1.3" - resolved "https://registry.yarnpkg.com/idb-keyval/-/idb-keyval-5.1.3.tgz#6ef5dff371897c23f144322dc6374eadd6a345d9" - integrity sha512-N9HbCK/FaXSRVI+k6Xq4QgWxbcZRUv+SfG1y7HJ28JdV8yEJu6k+C/YLea7npGckX2DQJeEVuMc4bKOBeU/2LQ== - dependencies: - safari-14-idb-fix "^1.0.4" - -ieee754@1.1.13, ieee754@^1.1.4: - version "1.1.13" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" - integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== - -ieee754@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" - integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== - -ignore@^4.0.6: - version "4.0.6" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" - integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== - -ignore@^5.1.4: - version "5.1.8" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" - integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== - -immutable@^3.8.2: - version "3.8.2" - resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.8.2.tgz#c2439951455bb39913daf281376f1530e104adf3" - integrity sha1-wkOZUUVbs5kT2vKBN28VMOEErfM= - -import-fresh@^3.0.0, import-fresh@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66" - integrity sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ== - dependencies: - parent-module "^1.0.0" - resolve-from "^4.0.0" - -import-fresh@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" - integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== - dependencies: - parent-module "^1.0.0" - resolve-from "^4.0.0" - -import-local@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.0.2.tgz#a8cfd0431d1de4a2199703d003e3e62364fa6db6" - integrity sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA== - dependencies: - pkg-dir "^4.2.0" - resolve-cwd "^3.0.0" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= - indent-string@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" @@ -5692,16 +1973,6 @@ indexes-of@^1.0.1: resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc= -infer-owner@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" - integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== - -inflation@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/inflation/-/inflation-2.0.0.tgz#8b417e47c28f925a45133d914ca1fd389107f30f" - integrity sha1-i0F+R8KPklpFEz2RTKH9OJEH8w8= - inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" @@ -5710,113 +1981,36 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: +inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== -inherits@2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= - ini@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ini/-/ini-2.0.0.tgz#e5fd556ecdd5726be978fa1001862eacb0a94bc5" integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA== -ini@^1.3.4, ini@~1.3.0: +ini@^1.3.4: version "1.3.7" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.7.tgz#a09363e1911972ea16d7a8851005d84cf09a9a84" integrity sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ== -insert-text-at-cursor@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/insert-text-at-cursor/-/insert-text-at-cursor-0.3.0.tgz#1819607680ec1570618347c4cd475e791faa25da" - integrity sha512-/nPtyeX9xPUvxZf+r0518B7uqNKlP+LqNJqSiXFEaa2T71rWIwTVXGH7hB9xO/EVdwa5/pWlFCPwShOW81XIxQ== - -install-artifact-from-github@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/install-artifact-from-github/-/install-artifact-from-github-1.2.0.tgz#adcbd123c16a4337ec44ea76d0ebf253cc16b074" - integrity sha512-3OxCPcY55XlVM3kkfIpeCgmoSKnMsz2A3Dbhsq0RXpIknKQmrX1YiznCeW9cD2ItFmDxziA3w6Eg8d80AoL3oA== - interpret@^1.1.0: version "1.2.0" resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296" integrity sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw== -interpret@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" - integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== - invert-kv@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY= -invert-kv@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-3.0.1.tgz#a93c7a3d4386a1dc8325b97da9bb1620c0282523" - integrity sha512-CYdFeFexxhv/Bcny+Q0BfOV+ltRlJcd4BBZBYFX/O0u4npJrgZtIcjokegtiSMAvlMTJ+Koq0GBCc//3bueQxw== - -ioredis@^4.27.0: - version "4.27.6" - resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-4.27.6.tgz#a53d427d3fe75fbd10ed7ad150ce00559df8dcf8" - integrity sha512-6W3ZHMbpCa8ByMyC1LJGOi7P2WiOKP9B3resoZOVLDhi+6dDBOW+KNsRq3yI36Hmnb2sifCxHX+YSarTeXh48A== - dependencies: - cluster-key-slot "^1.1.0" - debug "^4.3.1" - denque "^1.1.0" - lodash.defaults "^4.2.0" - lodash.flatten "^4.4.0" - p-map "^2.1.0" - redis-commands "1.7.0" - redis-errors "^1.2.0" - redis-parser "^3.0.0" - standard-as-callback "^2.1.0" - -ip-address@^7.1.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/ip-address/-/ip-address-7.1.0.tgz#4a9c699e75b51cbeb18b38de8ed216efa1a490c5" - integrity sha512-V9pWC/VJf2lsXqP7IWJ+pe3P1/HCYGBMZrrnT62niLGjAfCbeiwXMUxaeHvnVlz19O27pvXP4azs+Pj/A0x+SQ== - dependencies: - jsbn "1.1.0" - sprintf-js "1.1.2" - -ip-cidr@3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/ip-cidr/-/ip-cidr-3.0.4.tgz#a915c47e00f47ea8d5f8ed662ea6161471c44375" - integrity sha512-pKNiqmBlTvEkhaLAa3+FOmYSY0/jjADVxxjA3NbujZZTT8mjLI90Q+6mwg6kd0fNm0RuAOkWJ1u1a/ETmlrPNQ== - dependencies: - ip-address "^7.1.0" - jsbn "^1.1.0" - -ip-regex@^4.0.0, ip-regex@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-4.3.0.tgz#687275ab0f57fa76978ff8f4dddc8a23d5990db5" - integrity sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q== - -ip@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" - integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= - -ipaddr.js@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.0.1.tgz#eca256a7a877e917aeb368b0a7497ddf42ef81c0" - integrity sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng== - is-absolute-url@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6" integrity sha1-UFMN+4T8yap9vnhS6Do3uTufKqY= -is-absolute-url@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-3.0.3.tgz#96c6a22b6a23929b11ea0afb1836c36ad4a5d698" - integrity sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q== - is-absolute@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-absolute/-/is-absolute-1.0.0.tgz#395e1ae84b11f26ad1795e73c17378e48a301576" @@ -5844,10 +2038,12 @@ is-arrayish@^0.2.1: resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= -is-arrayish@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" - integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= + dependencies: + binary-extensions "^1.0.0" is-binary-path@~2.1.0: version "2.1.0" @@ -5861,11 +2057,6 @@ is-buffer@^1.1.5: resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== -is-callable@^1.1.4, is-callable@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.5.tgz#f7e46b596890456db74e7f6e976cb3273d06faab" - integrity sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q== - is-ci@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-3.0.0.tgz#c7e7be3c9d8eef7d0fa144390bd1e4b88dc4c994" @@ -5880,13 +2071,6 @@ is-core-module@^2.0.0: dependencies: has "^1.0.3" -is-core-module@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.2.0.tgz#97037ef3d52224d85163f5597b2b63d9afed981a" - integrity sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ== - dependencies: - has "^1.0.3" - is-data-descriptor@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" @@ -5901,11 +2085,6 @@ is-data-descriptor@^1.0.0: dependencies: kind-of "^6.0.0" -is-date-object@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" - integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== - is-descriptor@^0.1.0: version "0.1.6" resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" @@ -5924,14 +2103,6 @@ is-descriptor@^1.0.0, is-descriptor@^1.0.2: is-data-descriptor "^1.0.0" kind-of "^6.0.2" -is-expression@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/is-expression/-/is-expression-4.0.0.tgz#c33155962abf21d0afd2552514d67d2ec16fd2ab" - integrity sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A== - dependencies: - acorn "^7.1.1" - object-assign "^4.1.1" - is-extendable@^0.1.0, is-extendable@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" @@ -5956,21 +2127,11 @@ is-fullwidth-code-point@^1.0.0: dependencies: number-is-nan "^1.0.0" -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= - is-fullwidth-code-point@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== -is-generator-function@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.7.tgz#d2132e529bb0000a7f80794d4bdf5cd5e5813522" - integrity sha512-YZc5EwyO4f2kWCax7oegfuSr9mFz1ZvieNYBEjmukLxgXfBUbxAWGVF7GZf0zidYtoBl3WvC07YK0wT76a+Rtw== - is-glob@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" @@ -5985,13 +2146,6 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" -is-glob@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" - integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== - dependencies: - is-extglob "^2.1.1" - is-installed-globally@~0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.4.0.tgz#9a0fd407949c30f86eb6959ef1b7994ed0b7b520" @@ -6000,37 +2154,11 @@ is-installed-globally@~0.4.0: global-dirs "^3.0.0" is-path-inside "^3.0.2" -is-ip@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/is-ip/-/is-ip-3.1.0.tgz#2ae5ddfafaf05cb8008a62093cf29734f657c5d8" - integrity sha512-35vd5necO7IitFPjd/YBeqwWnyDWbuLH9ZXQdMfDA8TEo7pv5X8yfrvVO3xbJbLUlERCMvf6X0hTUamQxCYJ9Q== - dependencies: - ip-regex "^4.0.0" - -is-lambda@^1.0.1: - version "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-negated-glob@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-negated-glob/-/is-negated-glob-1.0.0.tgz#6910bca5da8c95e784b5751b976cf5a10fee36d2" integrity sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI= -is-number-like@^1.0.3: - version "1.0.8" - resolved "https://registry.yarnpkg.com/is-number-like/-/is-number-like-1.0.8.tgz#2e129620b50891042e44e9bbbb30593e75cfbbe3" - integrity sha512-6rZi3ezCyFcn5L71ywzz2bS5b2Igl1En3eTlZlvKjpz1n3IZLAYMbKYAIQgFmEu0GENg92ziU/faEOA/aixjbA== - dependencies: - lodash.isfinite "^3.3.2" - is-number@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" @@ -6058,11 +2186,6 @@ is-plain-obj@^1.0.0: resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= -is-plain-obj@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" - integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== - is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" @@ -6070,23 +2193,6 @@ is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" -is-potential-custom-element-name@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" - integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== - -is-promise@^2.0.0: - version "2.2.2" - resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.2.2.tgz#39ab959ccbf9a774cf079f7b40c7a26f763135f1" - integrity sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ== - -is-regex@^1.0.3, is-regex@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae" - integrity sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ== - dependencies: - has "^1.0.3" - is-relative@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-1.0.0.tgz#a1bb6935ce8c5dba1e8b9754b9b2dcc020e2260d" @@ -6094,23 +2200,11 @@ is-relative@^1.0.0: dependencies: is-unc-path "^1.0.0" -is-resolvable@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" - integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg== - is-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== -is-svg@4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-4.3.1.tgz#8c63ec8c67c8c7f0a8de0a71c8c7d58eccf4406b" - integrity sha512-h2CGs+yPUyvkgTJQS9cJzo9lYK06WgRiXUqBBHtglSzVKAuH4/oWsqk7LGfbSa1hGk9QcZ0SyQtVggvBA8LZXA== - dependencies: - fast-xml-parser "^3.19.0" - is-svg@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-2.1.0.tgz#cf61090da0d9efbcab8722deba6f032208dbb0e9" @@ -6118,14 +2212,7 @@ is-svg@^2.0.0: dependencies: html-comment-regex "^1.1.0" -is-symbol@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" - integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ== - dependencies: - has-symbols "^1.0.1" - -is-typedarray@^1.0.0, is-typedarray@~1.0.0: +is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= @@ -6152,31 +2239,16 @@ is-valid-glob@^1.0.0: resolved "https://registry.yarnpkg.com/is-valid-glob/-/is-valid-glob-1.0.0.tgz#29bf3eff701be2d4d315dbacc39bc39fe8f601aa" integrity sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao= -is-whitespace@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/is-whitespace/-/is-whitespace-0.3.0.tgz#1639ecb1be036aec69a54cbb401cfbed7114ab7f" - integrity sha1-Fjnssb4DauxppUy7QBz77XEUq38= - is-windows@^1.0.1, is-windows@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== -isarray@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" - integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= - -isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: +isarray@1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= -isarray@^2.0.1: - version "2.0.5" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" - integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== - isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -6207,29 +2279,6 @@ istextorbinary@^3.0.0: binaryextensions "^2.2.0" textextensions "^3.2.0" -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" - -jest-worker@^27.0.2: - version "27.0.6" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.0.6.tgz#a5fdb1e14ad34eb228cfe162d9f729cdbfa28aed" - integrity sha512-qupxcj/dRuA3xHPMUd40gr2EaAurFbkwzOh7wfPaeE9id7hyjURRQoqNfHifHK3XjJU6YJJUQKILGUnwGPEOCA== - dependencies: - "@types/node" "*" - merge-stream "^2.0.0" - supports-color "^8.0.0" - -jmespath@0.15.0: - version "0.15.0" - resolved "https://registry.yarnpkg.com/jmespath/-/jmespath-0.15.0.tgz#a3f222a9aae9f966f5d27c796510e28091764217" - integrity sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc= - joi@^17.4.0: version "17.4.2" resolved "https://registry.yarnpkg.com/joi/-/joi-17.4.2.tgz#02f4eb5cf88e515e614830239379dcbbe28ce7f7" @@ -6241,62 +2290,17 @@ joi@^17.4.0: "@sideway/formula" "^3.0.0" "@sideway/pinpoint" "^2.0.0" -jpeg-js@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.4.1.tgz#937a3ae911eb6427f151760f8123f04c8bfe6ef7" - integrity sha512-jA55yJiB5tCXEddos8JBbvW+IMrqY0y1tjjx9KNVtA+QPmu7ND5j0zkKopClpUTsaETL135uOM2XfcYG4XRjmw== - js-base64@^2.1.9: version "2.6.4" resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.6.4.tgz#f4e686c5de1ea1f867dbcad3d46d969428df98c4" integrity sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ== -js-beautify@^1.6.12: - version "1.11.0" - resolved "https://registry.yarnpkg.com/js-beautify/-/js-beautify-1.11.0.tgz#afb873dc47d58986360093dcb69951e8bcd5ded2" - integrity sha512-a26B+Cx7USQGSWnz9YxgJNMmML/QG2nqIaL7VVYPCXbqiKz8PN0waSNvroMtvAK6tY7g/wPdNWGEP+JTNIBr6A== - dependencies: - config-chain "^1.1.12" - editorconfig "^0.15.3" - glob "^7.1.3" - mkdirp "~1.0.3" - nopt "^4.0.3" - js-levenshtein@^1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.6.tgz#c6cee58eb3550372df8deb85fad5ce66ce01d59d" integrity sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g== -js-sha3@0.8.0: - version "0.8.0" - resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" - integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== - -js-stringify@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/js-stringify/-/js-stringify-1.0.2.tgz#1736fddfd9724f28a3682adc6230ae7e4e9679db" - integrity sha1-Fzb939lyTyijaCrcYjCufk6Weds= - -js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - -js-yaml@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.0.0.tgz#f426bc0ff4b4051926cd588c71113183409a121f" - integrity sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q== - dependencies: - argparse "^2.0.1" - -js-yaml@4.1.0, js-yaml@^4.0.0, js-yaml@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== - dependencies: - argparse "^2.0.1" - -js-yaml@^3.13.1, js-yaml@^3.14.1: +js-yaml@^3.14.1: version "3.14.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== @@ -6312,69 +2316,11 @@ js-yaml@~3.7.0: argparse "^1.0.7" esprima "^2.6.0" -jsbn@1.1.0, jsbn@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-1.1.0.tgz#b01307cb29b618a1ed26ec79e911f803c4da0040" - integrity sha1-sBMHyym2GKHtJux56RH4A8TaAEA= - jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= -jschardet@^3.0.0: - version "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== - dependencies: - abab "^2.0.5" - acorn "^8.2.4" - acorn-globals "^6.0.0" - cssom "^0.4.4" - cssstyle "^2.3.0" - data-urls "^2.0.0" - decimal.js "^10.2.1" - domexception "^2.0.1" - escodegen "^2.0.0" - form-data "^3.0.0" - html-encoding-sniffer "^2.0.1" - http-proxy-agent "^4.0.1" - https-proxy-agent "^5.0.0" - is-potential-custom-element-name "^1.0.1" - nwsapi "^2.2.0" - parse5 "6.0.1" - saxes "^5.0.1" - 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" - -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-parse-even-better-errors@^2.3.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" - integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== - 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" @@ -6395,57 +2341,11 @@ json-stable-stringify-without-jsonify@^1.0.1: resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= -json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: +json-stringify-safe@~5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= -json5-loader@4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/json5-loader/-/json5-loader-4.0.1.tgz#6d17a1181e8f3c3d9204dca2a4ce4627306c8498" - integrity sha512-c9viNZlZTz0MTIcf/4qvek5Dz1/PU3DNCB4PwUhlEZIV3qb1bSD6vQQymlV17/Wm6ncra1aCvmIPsuRj+KfEEg== - dependencies: - json5 "^2.1.3" - loader-utils "^2.0.0" - schema-utils "^3.0.0" - -json5@2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" - integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA== - dependencies: - minimist "^1.2.5" - -json5@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" - integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== - dependencies: - minimist "^1.2.0" - -json5@^2.1.2, json5@^2.1.3: - version "2.1.3" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43" - integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA== - dependencies: - minimist "^1.2.5" - -jsonfile@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" - integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= - optionalDependencies: - graceful-fs "^4.1.6" - -jsonfile@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-5.0.0.tgz#e6b718f73da420d612823996fdf14a03f6ff6922" - integrity sha512-NQRZ5CRo74MhMMC3/3r5g2k4fjodJ/wh8MxjFbCViWKFjxrnudWSY5vomh+23ZaXzAS7J3fBZIR2dV6WbmfM0w== - dependencies: - universalify "^0.1.2" - optionalDependencies: - graceful-fs "^4.1.6" - jsonfile@^6.0.1: version "6.1.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" @@ -6455,16 +2355,6 @@ jsonfile@^6.0.1: optionalDependencies: graceful-fs "^4.1.6" -jsonld@5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/jsonld/-/jsonld-5.2.0.tgz#d1e8af38a334cb95edf0f2ae4e2b58baf8d2b5a9" - integrity sha512-JymgT6Xzk5CHEmHuEyvoTNviEPxv6ihLWSPu1gFdtjSAyM6cFqNrv02yS/SIur3BBIkCf0HjizRc24d8/FfQKw== - dependencies: - "@digitalbazaar/http-client" "^1.1.0" - canonicalize "^1.0.1" - lru-cache "^6.0.0" - rdf-canonize "^3.0.0" - jsprim@^1.2.2: version "1.4.1" resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" @@ -6475,62 +2365,11 @@ jsprim@^1.2.2: json-schema "0.2.3" verror "1.10.0" -jsrsasign@8.0.20: - version "8.0.20" - resolved "https://registry.yarnpkg.com/jsrsasign/-/jsrsasign-8.0.20.tgz#37d8029c9d8f794d8ac8d8998bce319921491f11" - integrity sha512-JTXt9+nqdynIB8wFsS6e8ffHhIjilhywXwdaEVHSj9OVmwldG2H0EoCqkQ+KXkm2tVqREfH/HEmklY4k1/6Rcg== - -jstransformer@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/jstransformer/-/jstransformer-1.0.0.tgz#ed8bf0921e2f3f1ed4d5c1a44f68709ed24722c3" - integrity sha1-7Yvwkh4vPx7U1cGkT2hwntJHIsM= - dependencies: - is-promise "^2.0.0" - promise "^7.0.1" - just-debounce@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/just-debounce/-/just-debounce-1.0.0.tgz#87fccfaeffc0b68cd19d55f6722943f929ea35ea" integrity sha1-h/zPrv/AtozRnVX2cilD+SnqNeo= -jwa@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/jwa/-/jwa-2.0.0.tgz#a7e9c3f29dae94027ebcaf49975c9345593410fc" - integrity sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA== - dependencies: - buffer-equal-constant-time "1.0.1" - ecdsa-sig-formatter "1.0.11" - safe-buffer "^5.0.1" - -jws@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/jws/-/jws-4.0.0.tgz#2d4e8cf6a318ffaa12615e9dec7e86e6c97310f4" - integrity sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg== - dependencies: - jwa "^2.0.0" - safe-buffer "^5.0.1" - -katex@0.13.18: - version "0.13.18" - resolved "https://registry.yarnpkg.com/katex/-/katex-0.13.18.tgz#ba89e8e4b70cc2325e25e019a62b9fe71e5c2931" - integrity sha512-a3dC4NSVSDU3O1WZbTnOiA8rVNJ2lSiomOl0kmckCIGObccIHXof7gAseIY0o1gjEspe+34ZeSEX2D1ChFKIvA== - dependencies: - commander "^6.0.0" - -keygrip@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/keygrip/-/keygrip-1.1.0.tgz#871b1681d5e159c62a445b0c74b615e0917e7226" - integrity sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ== - dependencies: - tsscmp "1.0.6" - -keyv@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.0.3.tgz#4f3aa98de254803cafcd2896734108daa35e4254" - integrity sha512-zdGa2TOpSZPq5mU6iowDARnMBZgtCqJ11dJROFi6tg6kTn4nuUdU09lFyLFSaHrWqpIJ+EBq4E8/Dc0Vx5vLdA== - dependencies: - json-buffer "3.0.1" - kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" @@ -6555,186 +2394,6 @@ kind-of@^6.0.0, kind-of@^6.0.2: resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== -klona@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.4.tgz#7bb1e3affb0cb8624547ef7e8f6708ea2e39dfc0" - integrity sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA== - -koa-bodyparser@4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/koa-bodyparser/-/koa-bodyparser-4.3.0.tgz#274c778555ff48fa221ee7f36a9fbdbace22759a" - integrity sha512-uyV8G29KAGwZc4q/0WUAjH+Tsmuv9ImfBUF2oZVyZtaeo0husInagyn/JH85xMSxM0hEk/mbCII5ubLDuqW/Rw== - dependencies: - co-body "^6.0.0" - copy-to "^2.0.1" - -koa-compose@^3.0.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/koa-compose/-/koa-compose-3.2.1.tgz#a85ccb40b7d986d8e5a345b3a1ace8eabcf54de7" - integrity sha1-qFzLQLfZhtjlo0Wzoazo6rz1Tec= - dependencies: - any-promise "^1.1.0" - -koa-compose@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/koa-compose/-/koa-compose-4.1.0.tgz#507306b9371901db41121c812e923d0d67d3e877" - integrity sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw== - -koa-convert@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/koa-convert/-/koa-convert-1.2.0.tgz#da40875df49de0539098d1700b50820cebcd21d0" - integrity sha1-2kCHXfSd4FOQmNFwC1CCDOvNIdA= - dependencies: - co "^4.6.0" - koa-compose "^3.0.0" - -koa-convert@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/koa-convert/-/koa-convert-2.0.0.tgz#86a0c44d81d40551bae22fee6709904573eea4f5" - integrity sha512-asOvN6bFlSnxewce2e/DK3p4tltyfC4VM7ZwuTuepI7dEQVcvpyFuBcEARu1+Hxg8DIwytce2n7jrZtRlPrARA== - dependencies: - co "^4.6.0" - koa-compose "^4.1.0" - -koa-favicon@2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/koa-favicon/-/koa-favicon-2.1.0.tgz#c430cc594614fb494adcb5ee1196a2f7f53ea442" - integrity sha512-LvukcooYjxKtnZq0RXdBup+JDhaHwLgnLlDHB/xvjwQEjbc4rbp/0WkmOzpOvaHujc+fIwPear0dpKX1V+dHVg== - dependencies: - mz "^2.7.0" - -koa-json-body@5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/koa-json-body/-/koa-json-body-5.3.0.tgz#64aad3f400adfb81df54b63f7a5eb38bad62d980" - integrity sha1-ZKrT9ACt+4HfVLY/el6zi61i2YA= - dependencies: - co-body "^5.0.0" - -koa-logger@3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/koa-logger/-/koa-logger-3.2.1.tgz#ab9db879526db3837cc9ce4fd983c025b1689f22" - integrity sha512-MjlznhLLKy9+kG8nAXKJLM0/ClsQp/Or2vI3a5rbSQmgl8IJBQO0KI5FA70BvW+hqjtxjp49SpH2E7okS6NmHg== - dependencies: - bytes "^3.1.0" - chalk "^2.4.2" - humanize-number "0.0.2" - passthrough-counter "^1.0.0" - -koa-mount@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/koa-mount/-/koa-mount-4.0.0.tgz#e0265e58198e1a14ef889514c607254ff386329c" - integrity sha512-rm71jaA/P+6HeCpoRhmCv8KVBIi0tfGuO/dMKicbQnQW/YJntJ6MnnspkodoA4QstMVEZArsCphmd0bJEtoMjQ== - dependencies: - debug "^4.0.1" - koa-compose "^4.1.0" - -koa-send@5.0.1, koa-send@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/koa-send/-/koa-send-5.0.1.tgz#39dceebfafb395d0d60beaffba3a70b4f543fe79" - integrity sha512-tmcyQ/wXXuxpDxyNXv5yNNkdAMdFRqwtegBXUaowiQzUKqJehttS0x2j0eOZDQAyloAth5w6wwBImnFzkUz3pQ== - dependencies: - debug "^4.1.1" - http-errors "^1.7.3" - resolve-path "^1.4.0" - -koa-slow@2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/koa-slow/-/koa-slow-2.1.0.tgz#39007ca628c620f2b307b90dbf423d7a0c9be971" - integrity sha1-OQB8pijGIPKzB7kNv0I9egyb6XE= - dependencies: - lodash.isregexp "3.0.5" - q "1.4.1" - -koa-views@*, koa-views@7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/koa-views/-/koa-views-7.0.1.tgz#0c8f8e65d5cd2e08249430cb83dc361e49a17a5a" - integrity sha512-yS8751DXHXXDbdl/oUZd0PsgnxR0MLiguu77Eqrgu6yawE9Hi99wNKiVENb0Kfgsmvq/8px7YCI+USgxaTB1LA== - dependencies: - "@types/koa" "^2.13.1" - consolidate "^0.16.0" - debug "^4.1.0" - get-paths "0.0.7" - koa-send "^5.0.0" - mz "^2.4.0" - pretty "^2.0.0" - resolve-path "^1.4.0" - -koa@2.13.1: - version "2.13.1" - resolved "https://registry.yarnpkg.com/koa/-/koa-2.13.1.tgz#6275172875b27bcfe1d454356a5b6b9f5a9b1051" - integrity sha512-Lb2Dloc72auj5vK4X4qqL7B5jyDPQaZucc9sR/71byg7ryoD1NCaCm63CShk9ID9quQvDEi1bGR/iGjCG7As3w== - dependencies: - accepts "^1.3.5" - cache-content-type "^1.0.0" - content-disposition "~0.5.2" - content-type "^1.0.4" - cookies "~0.8.0" - debug "~3.1.0" - delegates "^1.0.0" - depd "^2.0.0" - destroy "^1.0.4" - encodeurl "^1.0.2" - escape-html "^1.0.3" - fresh "~0.5.2" - http-assert "^1.3.0" - http-errors "^1.6.3" - is-generator-function "^1.0.7" - koa-compose "^4.1.0" - koa-convert "^1.2.0" - on-finished "^2.3.0" - only "~0.0.2" - parseurl "^1.3.2" - statuses "^1.5.0" - type-is "^1.6.16" - vary "^1.1.2" - -koa@2.13.4: - version "2.13.4" - resolved "https://registry.yarnpkg.com/koa/-/koa-2.13.4.tgz#ee5b0cb39e0b8069c38d115139c774833d32462e" - integrity sha512-43zkIKubNbnrULWlHdN5h1g3SEKXOEzoAlRsHOTFpnlDu8JlAOZSMJBLULusuXRequboiwJcj5vtYXKB3k7+2g== - dependencies: - accepts "^1.3.5" - cache-content-type "^1.0.0" - content-disposition "~0.5.2" - content-type "^1.0.4" - cookies "~0.8.0" - debug "^4.3.2" - delegates "^1.0.0" - depd "^2.0.0" - destroy "^1.0.4" - encodeurl "^1.0.2" - escape-html "^1.0.3" - fresh "~0.5.2" - http-assert "^1.3.0" - http-errors "^1.6.3" - is-generator-function "^1.0.7" - koa-compose "^4.1.0" - koa-convert "^2.0.0" - on-finished "^2.3.0" - only "~0.0.2" - parseurl "^1.3.2" - statuses "^1.5.0" - type-is "^1.6.16" - vary "^1.1.2" - -ky-universal@^0.8.2: - version "0.8.2" - resolved "https://registry.yarnpkg.com/ky-universal/-/ky-universal-0.8.2.tgz#edc398d54cf495d7d6830aa1ab69559a3cc7f824" - integrity sha512-xe0JaOH9QeYxdyGLnzUOVGK4Z6FGvDVzcXFTdrYA1f33MZdEa45sUDaMBy98xQMcsd2XIBrTXRrRYnegcSdgVQ== - dependencies: - abort-controller "^3.0.0" - node-fetch "3.0.0-beta.9" - -ky@^0.25.1: - version "0.25.1" - resolved "https://registry.yarnpkg.com/ky/-/ky-0.25.1.tgz#0df0bd872a9cc57e31acd5dbc1443547c881bfbc" - integrity sha512-PjpCEWlIU7VpiMVrTwssahkYXX1by6NCT0fhTUX34F3DTinARlgMpriuroolugFPcMgpPWrOW4mTb984Qm1RXA== - -langmap@0.0.16: - version "0.0.16" - resolved "https://registry.yarnpkg.com/langmap/-/langmap-0.0.16.tgz#2fe3e98a531fec0fec546624ebe168c2855bab56" - integrity sha512-AtYvBK7BsDvWwnSfmO7CfgeUy7GUT1wK3QX8eKH/Ey/eXodqoHuAtvdQ82hmWD9QVFVKnuiNjym9fGY4qSJeLA== - last-run@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/last-run/-/last-run-1.1.1.tgz#45b96942c17b1c79c772198259ba943bebf8ca5b" @@ -6762,13 +2421,6 @@ lcid@^1.0.0: dependencies: invert-kv "^1.0.0" -lcid@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/lcid/-/lcid-3.1.1.tgz#9030ec479a058fc36b5e8243ebaac8b6ac582fd0" - integrity sha512-M6T051+5QCGLBQb8id3hdvIW8+zeFV2FyBGFS9IEK5H9Wt4MueD4bW1eWikpHgZp+5xR3l5c8pZUkQsIA0BFZg== - dependencies: - invert-kv "^3.0.0" - lead@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/lead/-/lead-1.0.0.tgz#6f14f99a37be3a9dd784f5495690e5903466ee42" @@ -6776,22 +2428,6 @@ lead@^1.0.0: dependencies: flush-write-stream "^1.0.2" -levn@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" - integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== - dependencies: - prelude-ls "^1.2.1" - type-check "~0.4.0" - -levn@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" - integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= - dependencies: - prelude-ls "~1.1.2" - type-check "~0.3.2" - liftoff@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/liftoff/-/liftoff-3.1.0.tgz#c9ba6081f908670607ee79062d700df062c52ed3" @@ -6806,23 +2442,6 @@ liftoff@^3.1.0: rechoir "^0.6.2" resolve "^1.1.7" -lilconfig@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.0.3.tgz#68f3005e921dafbd2a2afb48379986aa6d2579fd" - integrity sha512-EHKqr/+ZvdKCifpNrJCKxBTgk5XupZA3y/aCPY9mxfgBzmgh93Mt/WqjjQ38oMxXuvDokaKiM3lAgvSH2sjtHg== - -lines-and-columns@^1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" - integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= - -linkify-it@^3.0.1: - version "3.0.2" - resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-3.0.2.tgz#f55eeb8bc1d3ae754049e124ab3bb56d97797fb8" - integrity sha512-gDBO4aHNZS6coiZCKVhSNh43F9ioIL4JwRjLZPkoLIY4yZFwg264Y5lu2x6rb1Js42Gh6Yqm2f6L2AJcnkzinQ== - dependencies: - uc.micro "^1.0.1" - listr2@^3.8.3: version "3.11.0" resolved "https://registry.yarnpkg.com/listr2/-/listr2-3.11.0.tgz#9771b02407875aa78e73d6e0ff6541bbec0aaee9" @@ -6847,158 +2466,31 @@ load-json-file@^1.0.0: pinkie-promise "^2.0.0" strip-bom "^2.0.0" -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@^1.0.2: - version "1.4.0" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613" - integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA== - dependencies: - big.js "^5.2.2" - emojis-list "^3.0.0" - json5 "^1.0.1" - -loader-utils@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.0.tgz#e4cace5b816d425a166b5f097e10cd12b36064b0" - integrity sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ== - dependencies: - big.js "^5.2.2" - emojis-list "^3.0.0" - json5 "^2.1.2" - -locate-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" - integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== - dependencies: - p-locate "^3.0.0" - path-exists "^3.0.0" - -locate-path@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" - integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== - dependencies: - p-locate "^4.1.0" - -locate-path@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" - integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== - dependencies: - p-locate "^5.0.0" - -lodash.assignin@^4.0.9: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.assignin/-/lodash.assignin-4.2.0.tgz#ba8df5fb841eb0a3e8044232b0e263a8dc6a28a2" - integrity sha1-uo31+4QesKPoBEIysOJjqNxqKKI= - -lodash.bind@^4.1.4: - version "4.2.1" - resolved "https://registry.yarnpkg.com/lodash.bind/-/lodash.bind-4.2.1.tgz#7ae3017e939622ac31b7d7d7dcb1b34db1690d35" - integrity sha1-euMBfpOWIqwxt9fX3LGzTbFpDTU= - -lodash.defaults@^4.0.1, lodash.defaults@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" - integrity sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw= - -lodash.filter@^4.4.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.filter/-/lodash.filter-4.6.0.tgz#668b1d4981603ae1cc5a6fa760143e480b4c4ace" - integrity sha1-ZosdSYFgOuHMWm+nYBQ+SAtMSs4= - -lodash.flatten@^4.2.0, lodash.flatten@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" - integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8= - -lodash.foreach@^4.3.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.foreach/-/lodash.foreach-4.5.0.tgz#1a6a35eace401280c7f06dddec35165ab27e3e53" - integrity sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM= - lodash.isequal@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA= -lodash.isfinite@^3.3.2: - version "3.3.2" - resolved "https://registry.yarnpkg.com/lodash.isfinite/-/lodash.isfinite-3.3.2.tgz#fb89b65a9a80281833f0b7478b3a5104f898ebb3" - integrity sha1-+4m2WpqAKBgz8LdHizpRBPiY67M= - -lodash.isregexp@3.0.5: - version "3.0.5" - resolved "https://registry.yarnpkg.com/lodash.isregexp/-/lodash.isregexp-3.0.5.tgz#e0f596242f2fa228a840086b6c8ad82e4b71fd2d" - integrity sha1-4PWWJC8voiioQAhrbIrYLktx/S0= - -lodash.map@^4.4.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.map/-/lodash.map-4.6.0.tgz#771ec7839e3473d9c4cde28b19394c3562f4f6d3" - integrity sha1-dx7Hg540c9nEzeKLGTlMNWL09tM= - lodash.memoize@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= -lodash.merge@^4.4.0, lodash.merge@^4.6.2: - version "4.6.2" - resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" - integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== - lodash.once@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w= -lodash.pick@^4.2.1: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3" - integrity sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM= - -lodash.reduce@^4.4.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.reduce/-/lodash.reduce-4.6.0.tgz#f1ab6b839299ad48f784abbf476596f03b914d3b" - integrity sha1-8atrg5KZrUj3hKu/R2WW8DuRTTs= - -lodash.reject@^4.4.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.reject/-/lodash.reject-4.6.0.tgz#80d6492dc1470864bbf583533b651f42a9f52415" - integrity sha1-gNZJLcFHCGS79YNTO2UfQqn1JBU= - -lodash.some@^4.4.0: - version "4.6.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.uniq@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= -lodash@^4.17.14, lodash@^4.17.19, lodash@^4.17.21, lodash@^4.7.0: +lodash@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== -log-symbols@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.0.0.tgz#69b3cc46d20f448eccdb75ea1fa733d9e821c920" - integrity sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA== - dependencies: - chalk "^4.0.0" - log-symbols@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" @@ -7017,59 +2509,6 @@ log-update@^4.0.0: slice-ansi "^4.0.0" wrap-ansi "^6.2.0" -lowercase-keys@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" - integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== - -lru-cache@^4.1.5: - version "4.1.5" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" - integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== - dependencies: - pseudomap "^1.0.2" - yallist "^2.1.2" - -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - -magic-string@^0.25.7: - version "0.25.7" - resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.7.tgz#3f497d6fd34c669c6798dcb821f2ef31f5445051" - integrity sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA== - dependencies: - sourcemap-codec "^1.4.4" - -make-error@^1.1.1: - version "1.3.6" - resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" - integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== - -make-fetch-happen@^8.0.14: - version "8.0.14" - resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-8.0.14.tgz#aaba73ae0ab5586ad8eaa68bd83332669393e222" - integrity sha512-EsS89h6l4vbfJEtBZnENTOFk8mCRpY5ru36Xe5bcX1KYIli2mkSHqoFsp5O1wMDvTJJzxe/4THpCTtygjeeGWQ== - dependencies: - agentkeepalive "^4.1.3" - cacache "^15.0.5" - http-cache-semantics "^4.1.0" - http-proxy-agent "^4.0.1" - https-proxy-agent "^5.0.0" - is-lambda "^1.0.1" - lru-cache "^6.0.0" - minipass "^3.1.3" - minipass-collect "^1.0.2" - minipass-fetch "^1.3.2" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.4" - promise-retry "^2.0.1" - socks-proxy-agent "^5.0.0" - ssri "^8.0.0" - make-iterator@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/make-iterator/-/make-iterator-1.0.1.tgz#29b33f312aa8f547c4a5e490f56afcec99133ad6" @@ -7077,23 +2516,11 @@ make-iterator@^1.0.0: dependencies: kind-of "^6.0.2" -map-age-cleaner@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" - integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== - dependencies: - p-defer "^1.0.0" - map-cache@^0.2.0, map-cache@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= -map-stream@~0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.0.7.tgz#8a1f07896d82b10926bd3744a2420009f88974a8" - integrity sha1-ih8HiW2CsQkmvTdEokIACfiJdKg= - map-stream@~0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.1.0.tgz#e56aa94c4c8055a16404a0674b78f215f7c8e194" @@ -7106,22 +2533,6 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" -markdown-it-anchor@7.1.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/markdown-it-anchor/-/markdown-it-anchor-7.1.0.tgz#30fb21497bf59e83ff4d1ddc052d821962e2489e" - integrity sha512-loQggrwsIkkP7TOrESvmYkV2ikbQNNKhHcWyqC7/C2CmfHl1tkUizJJU8C5aGgg7J6oXVQJx17gk7i47tNn/lQ== - -markdown-it@12.2.0: - version "12.2.0" - resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-12.2.0.tgz#091f720fd5db206f80de7a8d1f1a7035fd0d38db" - integrity sha512-Wjws+uCrVQRqOoJvze4HCqkKl1AsSh95iFAeQDwnyfxM09divCBSXlDR1uTvyUP3Grzpn4Ru8GeCxYPM8vkCQg== - dependencies: - argparse "^2.0.1" - entities "~2.1.0" - linkify-it "^3.0.1" - mdurl "^1.0.1" - uc.micro "^1.0.5" - matchdep@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/matchdep/-/matchdep-2.0.0.tgz#c6f34834a0d8dbc3b37c27ee8bbcb27c7775582e" @@ -7137,73 +2548,12 @@ math-expression-evaluator@^1.2.14: resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.3.7.tgz#1b62225db86af06f7ea1fd9576a34af605a5b253" integrity sha512-nrbaifCl42w37hYd6oRLvoymFK42tWB+WQTMFtksDGQMi5GvlJwnz/CsS30FFAISFLtX+A0csJ0xLiuuyyec7w== -matter-js@0.17.1: - version "0.17.1" - resolved "https://registry.yarnpkg.com/matter-js/-/matter-js-0.17.1.tgz#b30ac4c708116258fbcaacd2efd8a94e34a91c7f" - integrity sha512-pSquoENJgvSAlQGcA0s5UkmEohGXZaUww2g3B6qG87x0iEcVf+aigMXn5UkFPdnh6w3B+C4vXSLaYqhHwKrOLA== - -mdn-data@2.0.14: - version "2.0.14" - resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50" - integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow== - -mdn-data@2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.4.tgz#699b3c38ac6f1d728091a64650b65d388502fd5b" - integrity sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA== - -mdn-data@2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.6.tgz#852dc60fcaa5daa2e8cf6c9189c440ed3e042978" - integrity sha512-rQvjv71olwNHgiTbfPZFkJtjNMciWgswYeciZhtvWLO8bmX3TnhyA62I6sTWOyZssWHJJjY6/KiWwqQsWWsqOA== - -mdurl@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" - integrity sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4= - -media-typer@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" - integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= - -mem@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/mem/-/mem-5.1.1.tgz#7059b67bf9ac2c924c9f1cff7155a064394adfb3" - integrity sha512-qvwipnozMohxLXG1pOqoLiZKNkC4r4qqRucSoDwXowsNGDSULiqFTRUF05vcZWnwJSG22qTsynQhxbaMtnX9gw== - dependencies: - map-age-cleaner "^0.1.3" - mimic-fn "^2.1.0" - p-is-promise "^2.1.0" - merge-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== -merge2@^1.3.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" - integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== - -merge@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/merge/-/merge-2.1.1.tgz#59ef4bf7e0b3e879186436e8481c06a6c162ca98" - integrity sha512-jz+Cfrg9GWOZbQAnDQ4hlVnQky+341Yk5ru8bZSe6sIDTCIg8n9i/u7hSQGSVOF3C7lH6mGtqjkiT9G4wFLL0w== - -methods@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" - integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= - -mfm-js@0.20.0: - version "0.20.0" - resolved "https://registry.yarnpkg.com/mfm-js/-/mfm-js-0.20.0.tgz#3afdcd7959461fd825aa8af9b9e8a57cdbddc290" - integrity sha512-1+3tV3nWUKQNh/ztX3wXu5iLBtdsg6q3wUhl+XyOhc2H3sQdG+sih/w2c0nR9TIawjN+Z1/pvgGzxMJHfmKQmA== - dependencies: - twemoji-parser "13.1.x" - -micromatch@^3.0.4, micromatch@^3.1.4: +micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== @@ -7222,25 +2572,12 @@ micromatch@^3.0.4, micromatch@^3.1.4: snapdragon "^0.8.1" to-regex "^3.0.2" -micromatch@^4.0.0, micromatch@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259" - integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q== - dependencies: - braces "^3.0.1" - picomatch "^2.0.5" - -microseconds@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/microseconds/-/microseconds-0.2.0.tgz#233b25f50c62a65d861f978a4a4f8ec18797dc39" - integrity sha512-n7DHHMjR1avBbSpsTBj6fmMGh2AGrifVV4e+WYc3Q9lO+xnSZ3NyhcBND3vzzatt05LFhoKFRxrIyklmLlUtyA== - mime-db@1.44.0: version "1.44.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== -mime-types@^2.1.12, mime-types@^2.1.18, mime-types@^2.1.27, mime-types@~2.1.19, mime-types@~2.1.24: +mime-types@^2.1.12, mime-types@~2.1.19: version "2.1.27" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== @@ -7252,108 +2589,18 @@ mimic-fn@^2.1.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== -mimic-response@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" - integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== - -mimic-response@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-2.1.0.tgz#d13763d35f613d09ec37ebb30bac0469c0ee8f43" - integrity sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA== - -mimic-response@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" - integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== - -minimalistic-assert@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" - integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== - -minimatch@3.0.4, minimatch@^3.0.4: +minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== dependencies: brace-expansion "^1.1.7" -minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5: +minimist@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== -minipass-collect@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617" - integrity sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA== - dependencies: - minipass "^3.0.0" - -minipass-fetch@^1.3.2: - version "1.3.3" - resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-1.3.3.tgz#34c7cea038c817a8658461bf35174551dce17a0a" - integrity sha512-akCrLDWfbdAWkMLBxJEeWTdNsjML+dt5YgOI4gJ53vuO0vrmYQkUPxa6j6V65s9CcePIr2SSWqjT2EcrNseryQ== - dependencies: - minipass "^3.1.0" - minipass-sized "^1.0.3" - minizlib "^2.0.0" - optionalDependencies: - encoding "^0.1.12" - -minipass-flush@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373" - integrity sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw== - dependencies: - minipass "^3.0.0" - -minipass-pipeline@^1.2.2, minipass-pipeline@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz#68472f79711c084657c067c5c6ad93cddea8214c" - integrity sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A== - dependencies: - minipass "^3.0.0" - -minipass-sized@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/minipass-sized/-/minipass-sized-1.0.3.tgz#70ee5a7c5052070afacfbc22977ea79def353b70" - integrity sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g== - dependencies: - minipass "^3.0.0" - -minipass@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.1.tgz#7607ce778472a185ad6d89082aa2070f79cedcd5" - integrity sha512-UFqVihv6PQgwj8/yTGvl9kPz7xIAY+R5z6XYjRInD3Gk3qx6QGSD6zEcpeG4Dy/lQnv1J6zv8ejV90hyYIKf3w== - dependencies: - yallist "^4.0.0" - -minipass@^3.1.0, minipass@^3.1.1, minipass@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.3.tgz#7d42ff1f39635482e15f9cdb53184deebd5815fd" - integrity sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg== - dependencies: - yallist "^4.0.0" - -minizlib@^2.0.0, minizlib@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" - integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== - dependencies: - minipass "^3.0.0" - yallist "^4.0.0" - -misskey-js@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/misskey-js/-/misskey-js-0.0.8.tgz#b47a1ec54bff96b23cc2a6b307a3895f99a94424" - integrity sha512-Q1L6FaroVz8kpW7T4xQyJmJKSwjOYPbNY3TspOUWmbIBDf2JP0HVeKEFLI9dvdSL0kSkdQNz3MSVLjlHiyPqLQ== - dependencies: - autobind-decorator "^2.4.0" - eventemitter3 "^4.0.7" - reconnecting-websocket "^4.4.0" - mixin-deep@^1.2.0: version "1.3.2" resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" @@ -7362,71 +2609,13 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" -mkdirp-classic@^0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.2.tgz#54c441ce4c96cd7790e10b41a87aa51068ecab2b" - integrity sha512-ejdnDQcR75gwknmMw/tx02AuRs8jCtqFoFqDZMjiNxsu85sRIJVXDKHuLYvUUPRBUtV2FpSZa9bL1BUa3BdR2g== - -mkdirp-classic@^0.5.3: - version "0.5.3" - resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" - integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== - -mkdirp@^0.5.3, mkdirp@^0.5.4, mkdirp@~0.5.1: +mkdirp@~0.5.1: version "0.5.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== dependencies: minimist "^1.2.5" -mkdirp@^1.0.3, mkdirp@^1.0.4, mkdirp@~1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" - integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== - -mocha@8.4.0: - version "8.4.0" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-8.4.0.tgz#677be88bf15980a3cae03a73e10a0fc3997f0cff" - integrity sha512-hJaO0mwDXmZS4ghXsvPVriOhsxQ7ofcpQdm8dE+jISUOKopitvnXFQmpRR7jd2K6VBG6E26gU3IAbXXGIbu4sQ== - dependencies: - "@ungap/promise-all-settled" "1.1.2" - ansi-colors "4.1.1" - browser-stdout "1.3.1" - chokidar "3.5.1" - debug "4.3.1" - diff "5.0.0" - escape-string-regexp "4.0.0" - find-up "5.0.0" - glob "7.1.6" - growl "1.10.5" - he "1.2.0" - js-yaml "4.0.0" - log-symbols "4.0.0" - minimatch "3.0.4" - ms "2.1.3" - nanoid "3.1.20" - serialize-javascript "5.0.1" - strip-json-comments "3.1.1" - supports-color "8.1.1" - which "2.0.2" - wide-align "1.1.3" - workerpool "6.1.0" - yargs "16.2.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: - version "2.24.0" - resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b" - integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg== - ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" @@ -7437,65 +2626,20 @@ ms@2.1.2: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@2.1.3, ms@^2.0.0, ms@^2.1.1: +ms@^2.1.1: version "2.1.3" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== -multer@1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/multer/-/multer-1.4.3.tgz#4db352d6992e028ac0eacf7be45c6efd0264297b" - integrity sha512-np0YLKncuZoTzufbkM6wEKp68EhWJXcU6fq6QqrSwkckd2LlMgd1UqhUJLj6NS/5sZ8dE8LYDWslsltJznnXlg== - dependencies: - append-field "^1.0.0" - busboy "^0.2.11" - concat-stream "^1.5.2" - mkdirp "^0.5.4" - object-assign "^4.1.1" - on-finished "^2.3.0" - type-is "^1.6.4" - xtend "^4.0.0" - mute-stdout@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/mute-stdout/-/mute-stdout-1.0.1.tgz#acb0300eb4de23a7ddeec014e3e96044b3472331" integrity sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg== -mz@^2.4.0, mz@^2.7.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" - integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== - dependencies: - any-promise "^1.0.0" - object-assign "^4.0.1" - thenify-all "^1.0.0" - -nan@^2.14.2: - version "2.14.2" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19" - integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ== - -nano-time@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/nano-time/-/nano-time-1.0.0.tgz#b0554f69ad89e22d0907f7a12b0993a5d96137ef" - integrity sha1-sFVPaa2J4i0JB/ehKwmTpdlhN+8= - dependencies: - big-integer "^1.6.16" - -nanoid@3.1.20, nanoid@^3.1.20: - version "3.1.20" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.20.tgz#badc263c6b1dcf14b71efaa85f6ab4c1d6cfc788" - integrity sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw== - -nanoid@^3.1.23: - version "3.1.23" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.23.tgz#f744086ce7c2bc47ee0a8472574d5c78e4183a81" - integrity sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw== - -nanoid@^3.1.30: - version "3.1.30" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.30.tgz#63f93cc548d2a113dc5dfbc63bfa09e2b9b64362" - integrity sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ== +nan@^2.12.1: + version "2.15.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.15.0.tgz#3f34a473ff18e15c1b5626b62903b5ad6e665fee" + integrity sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ== nanomatch@^1.2.9: version "1.2.13" @@ -7514,138 +2658,16 @@ nanomatch@^1.2.9: snapdragon "^0.8.1" to-regex "^3.0.1" -napi-build-utils@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806" - integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== - -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= - -needle@^2.5.2: - version "2.5.2" - resolved "https://registry.yarnpkg.com/needle/-/needle-2.5.2.tgz#cf1a8fce382b5a280108bba90a14993c00e4010a" - integrity sha512-LbRIwS9BfkPvNwNHlsA41Q29kL2L/6VaOJ0qisM5lLWsTV3nP15abO5ITL6L81zqFhzjRKDAYjpcBcwM0AVvLQ== - dependencies: - debug "^3.2.6" - iconv-lite "^0.4.4" - sax "^1.2.4" - -negotiator@0.6.2: - version "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" - integrity sha512-yFehXNWRs4cM0+dz7QxCd06hTbWbSkV0ISsqBfkntU6TOY4Qm3Q88fRRLOddkGh2Qq6dZvnKVAahfhjcUvLnyA== - -netmask@^2.0.2: - version "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" integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= -node-abi@^2.21.0: - version "2.21.0" - resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.21.0.tgz#c2dc9ebad6f4f53d6ea9b531e7b8faad81041d48" - integrity sha512-smhrivuPqEM3H5LmnY3KU6HfYv0u4QklgAxfFyRNujKUzbUcYZ+Jc2EhukB9SRcD2VpqhxM7n/MIcp1Ua1/JMg== - dependencies: - semver "^5.4.1" - -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-fetch@2.6.1, node-fetch@^2.6.1: +node-fetch@^2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== -node-fetch@3.0.0-beta.9: - version "3.0.0-beta.9" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-3.0.0-beta.9.tgz#0a7554cfb824380dd6812864389923c783c80d9b" - integrity sha512-RdbZCEynH2tH46+tj0ua9caUHVWrd/RHnRfvly2EVdqGmI3ndS1Vn/xjm5KuGejDt2RNDQsVRLPNd2QPwcewVg== - dependencies: - data-uri-to-buffer "^3.0.1" - fetch-blob "^2.1.1" - -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" - integrity sha512-L/Eg02Epx6Si2NXmedx+Okg+4UHqmaf3TNcxd50SF9NQGcJaON3AtU++kax69XV7YWz4tUspqZSAsVofhFKG2w== - -node-gyp@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-8.0.0.tgz#225af2b06b8419ae81f924bf25ae4c167f6378a5" - integrity sha512-Jod6NxyWtcwrpAQe0O/aXOpC5QfncotgtG73dg65z6VW/C6g/G4jiajXQUBIJ8pk/VfM6mBYE9BN/HvudTunUQ== - dependencies: - env-paths "^2.2.0" - glob "^7.1.4" - graceful-fs "^4.2.6" - make-fetch-happen "^8.0.14" - nopt "^5.0.0" - npmlog "^4.1.2" - rimraf "^3.0.2" - semver "^7.3.5" - tar "^6.1.0" - which "^2.0.2" - -node-releases@^1.1.70, node-releases@^1.1.71: - 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.0: - version "6.7.0" - resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.7.0.tgz#86614722c4e0c33d1b5b02aecb90d6d629932b0d" - integrity sha512-AtiTVUFHLiiDnMQ43zi0YgkzHOEWUkhDgPlBXrsDzJiJvB29Alo4OKxHQ0ugF3gRqRQIneCLtZU3yiUo7pItZw== - -nofilter@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/nofilter/-/nofilter-2.0.3.tgz#f5460f3cb33147005883e3f5d4476239501fa187" - integrity sha512-FbuXC+lK+GU2+63D1kC1ETiZo+Z7SIi7B+mxKTCH1byrh6WFvfBCN/wpherFz0a0bjGd7EKTst/cz0yLeNngug== - dependencies: - "@cto.af/textdecoder" "^0.0.0" - -nofilter@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/nofilter/-/nofilter-3.0.3.tgz#3ff3b142efdccb403434ccae4a0c2c835cb9b522" - integrity sha512-TN/MCrQmXQk5DyUJ8TGUq1Il8rv4fTsjddLmMopV006QP8DMkglmGgYfQKD5620vXLRXfr8iGI6ZZ4/ZWld2cQ== - -nopt@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.3.tgz#a375cad9d02fd921278d954c2254d5aa57e15e48" - integrity sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg== - dependencies: - abbrev "1" - osenv "^0.1.4" - -nopt@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" - integrity sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ== - dependencies: - abbrev "1" - normalize-package-data@^2.3.2: version "2.5.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" @@ -7683,16 +2705,6 @@ normalize-url@^1.4.0: query-string "^4.1.0" sort-keys "^1.0.0" -normalize-url@^4.1.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129" - integrity sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ== - -normalize-url@^6.0.1: - version "6.1.0" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" - integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== - now-and-later@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/now-and-later/-/now-and-later-2.0.1.tgz#8e579c8685764a7cc02cb680380e94f43ccb1f7c" @@ -7707,30 +2719,6 @@ npm-run-path@^4.0.0, npm-run-path@^4.0.1: dependencies: path-key "^3.0.0" -npmlog@^4.0.1, npmlog@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" - integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== - dependencies: - are-we-there-yet "~1.1.2" - console-control-strings "~1.1.0" - gauge "~2.7.3" - set-blocking "~2.0.0" - -nth-check@^1.0.2, nth-check@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" - integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg== - dependencies: - boolbase "~1.0.0" - -nth-check@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.0.0.tgz#1bb4f6dac70072fc313e8c9cd1417b5074c0a125" - integrity sha512-i4sc/Kj8htBrAiH1viZ0TgU8Y5XqCaV/FziYK6TBczxmeKm3AEFWqqF3195yKudrarqy7Zu80Ra5dobFjn9X/Q== - dependencies: - boolbase "^1.0.0" - num2fraction@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" @@ -7741,22 +2729,7 @@ number-is-nan@^1.0.0: resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= -nwsapi@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" - integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== - -oauth-sign@~0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" - integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== - -oauth@0.9.15: - version "0.9.15" - resolved "https://registry.yarnpkg.com/oauth/-/oauth-0.9.15.tgz#bd1fefaf686c96b75475aed5196412ff60cfb9c1" - integrity sha1-vR/vr2hslrdUda7VGWQS/2DPucE= - -object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: +object-assign@^4.0.1, object-assign@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= @@ -7770,12 +2743,7 @@ object-copy@^0.1.0: define-property "^0.2.5" kind-of "^3.0.3" -object-inspect@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67" - integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw== - -object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: +object-keys@^1.0.11, object-keys@^1.0.12: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== @@ -7807,14 +2775,6 @@ object.defaults@^1.0.0, object.defaults@^1.1.0: for-own "^1.0.0" isobject "^3.0.0" -object.getownpropertydescriptors@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz#369bf1f9592d8ab89d712dced5cb81c7c5352649" - integrity sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - object.map@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/object.map/-/object.map-1.0.1.tgz#cf83e59dc8fcc0ad5f4250e1f78b3b81bd801d37" @@ -7838,28 +2798,6 @@ object.reduce@^1.0.0: for-own "^1.0.0" make-iterator "^1.0.0" -object.values@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.1.tgz#68a99ecde356b7e9295a3c5e0ce31dc8c953de5e" - integrity sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - function-bind "^1.1.1" - has "^1.0.3" - -oblivious-set@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/oblivious-set/-/oblivious-set-1.0.0.tgz#c8316f2c2fb6ff7b11b6158db3234c49f733c566" - integrity sha512-z+pI07qxo4c2CulUHCDf9lcqDlMSo72N/4rLUpRXf6fu+q8vjt8y0xS+Tlf8NTJDdTXHbdeO1n3MlbctwEoXZw== - -on-finished@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" - integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= - dependencies: - ee-first "1.1.1" - once@^1.3.0, once@^1.3.1, once@^1.3.2, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" @@ -7874,40 +2812,6 @@ onetime@^5.1.0, onetime@^5.1.2: dependencies: mimic-fn "^2.1.0" -only@~0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/only/-/only-0.0.2.tgz#2afde84d03e50b9a8edc444e30610a70295edfb4" - integrity sha1-Kv3oTQPlC5qO3EROMGEKcCle37Q= - -opentype.js@^0.4.3: - version "0.4.11" - resolved "https://registry.yarnpkg.com/opentype.js/-/opentype.js-0.4.11.tgz#281a2390639cc15931c955d8d63c14a7c7772b41" - integrity sha1-KBojkGOcwVkxyVXY1jwUp8d3K0E= - -optionator@^0.8.1: - version "0.8.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" - integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== - dependencies: - deep-is "~0.1.3" - fast-levenshtein "~2.0.6" - levn "~0.3.0" - prelude-ls "~1.1.2" - type-check "~0.3.2" - word-wrap "~1.2.3" - -optionator@^0.9.1: - version "0.9.1" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" - integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== - dependencies: - deep-is "^0.1.3" - fast-levenshtein "^2.0.6" - levn "^0.4.1" - prelude-ls "^1.2.1" - type-check "^0.4.0" - word-wrap "^1.2.3" - ordered-read-streams@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz#77c0cb37c41525d64166d990ffad7ec6a0e1363e" @@ -7915,11 +2819,6 @@ ordered-read-streams@^1.0.0: dependencies: readable-stream "^2.0.1" -os-homedir@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" - integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= - os-locale@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" @@ -7927,105 +2826,11 @@ os-locale@^1.4.0: dependencies: lcid "^1.0.0" -os-locale@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-5.0.0.tgz#6d26c1d95b6597c5d5317bf5fba37eccec3672e0" - integrity sha512-tqZcNEDAIZKBEPnHPlVDvKrp7NzgLi7jRmhKiUoa2NUmhl13FtkAGLUVR+ZsYvApBQdBfYm43A4tXXQ4IrYLBA== - dependencies: - execa "^4.0.0" - lcid "^3.0.0" - mem "^5.0.0" - -os-tmpdir@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= - -os-utils@0.0.14: - version "0.0.14" - resolved "https://registry.yarnpkg.com/os-utils/-/os-utils-0.0.14.tgz#29e511697b1982b8c627722175fe39797ef64156" - integrity sha1-KeURaXsZgrjGJ3Ihdf45eX72QVY= - -osenv@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" - integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== - dependencies: - os-homedir "^1.0.0" - os-tmpdir "^1.0.0" - ospath@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/ospath/-/ospath-1.2.2.tgz#1276639774a3f8ef2572f7fe4280e0ea4550c07b" integrity sha1-EnZjl3Sj+O8lcvf+QoDg6kVQwHs= -p-cancelable@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.0.0.tgz#4a3740f5bdaf5ed5d7c3e34882c6fb5d6b266a6e" - integrity sha512-wvPXDmbMmu2ksjkB4Z3nZWTSkJEb9lqVdMaCKpZUGJG9TMiNp9XcbG3fn9fPKjem04fJMJnXoyFPk2FmgiaiNg== - -p-defer@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" - integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= - -p-finally@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= - -p-is-promise@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" - integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg== - -p-limit@^2.0.0, p-limit@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" - integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== - dependencies: - p-try "^2.0.0" - -p-limit@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.0.2.tgz#1664e010af3cadc681baafd3e2a437be7b0fb5fe" - integrity sha512-iwqZSOoWIW+Ew4kAGUlN16J4M7OB3ysMLSZtnhmqx7njIHFPlxWBX8xo3lVTyFVq6mI/lL9qt2IsN1sHwaxJkg== - 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@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" - integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== - dependencies: - p-limit "^2.0.0" - -p-locate@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" - integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== - dependencies: - p-limit "^2.2.0" - -p-locate@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" - integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== - dependencies: - p-limit "^3.0.2" - -p-map@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" - integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw== - p-map@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" @@ -8033,35 +2838,6 @@ p-map@^4.0.0: dependencies: aggregate-error "^3.0.0" -p-timeout@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-3.2.0.tgz#c7e17abc971d2a7962ef83626b35d635acf23dfe" - integrity sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg== - dependencies: - p-finally "^1.0.0" - -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - -packet-reader@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/packet-reader/-/packet-reader-1.0.0.tgz#9238e5480dedabacfe1fe3f2771063f164157d74" - integrity sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ== - -parent-module@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" - integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== - dependencies: - callsites "^3.0.0" - -parent-require@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/parent-require/-/parent-require-1.0.0.tgz#746a167638083a860b0eef6732cb27ed46c32977" - integrity sha1-dGoWdjgIOoYLDu9nMssn7UbDKXc= - parse-filepath@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/parse-filepath/-/parse-filepath-1.0.2.tgz#a632127f53aaf3d15876f5872f3ffac763d6c891" @@ -8078,16 +2854,6 @@ parse-json@^2.2.0: dependencies: error-ex "^1.2.0" -parse-json@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.1.0.tgz#f96088cdf24a8faa9aea9a009f2d9d942c999646" - integrity sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ== - dependencies: - "@babel/code-frame" "^7.0.0" - error-ex "^1.3.1" - json-parse-even-better-errors "^2.3.0" - lines-and-columns "^1.1.6" - parse-node-version@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/parse-node-version/-/parse-node-version-1.0.1.tgz#e2b5dbede00e7fa9bc363607f53327e8b073189b" @@ -8098,38 +2864,11 @@ parse-passwd@^1.0.0: resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY= -parse5-htmlparser2-tree-adapter@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz#2cdf9ad823321140370d4dbf5d3e92c7c8ddc6e6" - integrity sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA== - dependencies: - parse5 "^6.0.1" - -parse5@6.0.1, parse5@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" - integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== - -parse5@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.1.tgz#f68e4e5ba1852ac2cadc00f4555fff6c2abb6178" - integrity sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug== - -parseurl@^1.3.2: - version "1.3.3" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" - integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== - pascalcase@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= -passthrough-counter@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/passthrough-counter/-/passthrough-counter-1.0.0.tgz#1967d9e66da572b5c023c787db112a387ab166fa" - integrity sha1-GWfZ5m2lcrXAI8eH2xEqOHqxZvo= - path-dirname@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" @@ -8142,17 +2881,7 @@ path-exists@^2.0.0: dependencies: pinkie-promise "^2.0.0" -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - -path-is-absolute@1.0.1, path-is-absolute@^1.0.0: +path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= @@ -8179,11 +2908,6 @@ path-root@^0.1.1: dependencies: path-root-regex "^0.1.0" -path-to-regexp@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-6.1.0.tgz#0b18f88b7a0ce0bfae6a25990c909ab86f512427" - integrity sha512-h9DqehX3zZZDCEm+xbfU0ZmwCGFCAAraPJWMXJ4+v32NjZJilVg3k1TcKsRgIb8IQ/izZSaydDc1OhJCZvs2Dw== - path-type@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" @@ -8193,11 +2917,6 @@ path-type@^1.0.0: pify "^2.0.0" pinkie-promise "^2.0.0" -path-type@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" - integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== - pause-stream@0.0.11: version "0.0.11" resolved "https://registry.yarnpkg.com/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445" @@ -8205,11 +2924,6 @@ pause-stream@0.0.11: dependencies: through "~2.3" -peek-readable@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/peek-readable/-/peek-readable-4.0.1.tgz#9a045f291db254111c3412c1ce4fec27ddd4d202" - integrity sha512-7qmhptnR0WMSpxT5rMHG9bW/mYSR1uqaPFj2MHvT+y/aOUu6msJijpKt5SkTDKySwg65OWG2JwTMBlgcbwMHrQ== - pend@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" @@ -8220,67 +2934,7 @@ performance-now@^2.1.0: resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= -pg-connection-string@^2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.5.0.tgz#538cadd0f7e603fc09a12590f3b8a452c2c0cf34" - integrity sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ== - -pg-int8@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/pg-int8/-/pg-int8-1.0.1.tgz#943bd463bf5b71b4170115f80f8efc9a0c0eb78c" - integrity sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw== - -pg-pool@^3.4.1: - version "3.4.1" - resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-3.4.1.tgz#0e71ce2c67b442a5e862a9c182172c37eda71e9c" - integrity sha512-TVHxR/gf3MeJRvchgNHxsYsTCHQ+4wm3VIHSS19z8NC0+gioEhq1okDY1sm/TYbfoP6JLFx01s0ShvZ3puP/iQ== - -pg-protocol@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/pg-protocol/-/pg-protocol-1.5.0.tgz#b5dd452257314565e2d54ab3c132adc46565a6a0" - integrity sha512-muRttij7H8TqRNu/DxrAJQITO4Ac7RmX3Klyr/9mJEOBeIpgnF8f9jAfRz5d3XwQZl5qBjF9gLsUtMPJE0vezQ== - -pg-types@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/pg-types/-/pg-types-2.2.0.tgz#2d0250d636454f7cfa3b6ae0382fdfa8063254a3" - integrity sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA== - dependencies: - pg-int8 "1.0.1" - postgres-array "~2.0.0" - postgres-bytea "~1.0.0" - postgres-date "~1.0.4" - postgres-interval "^1.1.0" - -pg@8.7.1: - version "8.7.1" - resolved "https://registry.yarnpkg.com/pg/-/pg-8.7.1.tgz#9ea9d1ec225980c36f94e181d009ab9f4ce4c471" - integrity sha512-7bdYcv7V6U3KAtWjpQJJBww0UEsWuh4yQ/EjNf2HeO/NnvKjpvhEIe/A/TleP6wtmSKnUnghs5A9jUoK6iDdkA== - dependencies: - buffer-writer "2.0.0" - packet-reader "1.0.0" - pg-connection-string "^2.5.0" - pg-pool "^3.4.1" - pg-protocol "^1.5.0" - pg-types "^2.1.0" - pgpass "1.x" - -pgpass@1.x: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pgpass/-/pgpass-1.0.2.tgz#2a7bb41b6065b67907e91da1b07c1847c877b306" - integrity sha1-Knu0G2BltnkH6R2hsHwYR8h3swY= - dependencies: - split "^1.0.0" - -"photoswipe@git://github.com/dimsemenov/photoswipe#v5-beta": - version "5.1.7" - resolved "git://github.com/dimsemenov/photoswipe#60040164333bd257409669e715e4327afdb3aec7" - -picocolors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" - integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== - -picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.0.7, picomatch@^2.2.1: +picomatch@^2.0.4, picomatch@^2.0.7: version "2.2.2" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== @@ -8290,11 +2944,6 @@ pify@^2.0.0, pify@^2.2.0: resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= -pify@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" - integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== - pinkie-promise@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" @@ -8307,14 +2956,7 @@ pinkie@^2.0.0: resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= -pkg-dir@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" - integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== - dependencies: - find-up "^4.0.0" - -plugin-error@1.0.1, plugin-error@^1.0.1: +plugin-error@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/plugin-error/-/plugin-error-1.0.1.tgz#77016bd8919d0ac377fdcdd0322328953ca5781c" integrity sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA== @@ -8324,19 +2966,6 @@ plugin-error@1.0.1, plugin-error@^1.0.1: arr-union "^3.1.0" extend-shallow "^3.0.2" -pngjs@^3.3.0, pngjs@^3.3.1: - version "3.4.0" - resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-3.4.0.tgz#99ca7d725965fb655814eaf65f38f12bbdbf555f" - integrity sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w== - -portscanner@2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/portscanner/-/portscanner-2.2.0.tgz#6059189b3efa0965c9d96a56b958eb9508411cf1" - integrity sha512-IFroCz/59Lqa2uBvzK3bKDbDDIEaAY8XJ1jFxcLWTqosrsc32//P4VuSB2vZXoHiHqOmx8B5L5hnKOxL/7FlPw== - dependencies: - async "^2.6.0" - is-number-like "^1.0.3" - posix-character-classes@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" @@ -8351,14 +2980,6 @@ postcss-calc@^5.2.0: postcss-message-helpers "^2.0.0" reduce-css-calc "^1.2.6" -postcss-calc@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-8.0.0.tgz#a05b87aacd132740a5db09462a3612453e5df90a" - integrity sha512-5NglwDrcbiy8XXfPM11F3HeC6hoT9W7GUH/Zi5U/p7u3Irv4rHhdDcIZwG0llHXV4ftsBjpfWMXAnXNl4lnt8g== - dependencies: - postcss-selector-parser "^6.0.2" - postcss-value-parser "^4.0.2" - postcss-colormin@^2.1.8: version "2.2.2" resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-2.2.2.tgz#6631417d5f0e909a3d7ec26b24c8a8d1e4f96e4b" @@ -8368,16 +2989,6 @@ postcss-colormin@^2.1.8: postcss "^5.0.13" postcss-value-parser "^3.2.3" -postcss-colormin@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-5.2.0.tgz#2b620b88c0ff19683f3349f4cf9e24ebdafb2c88" - integrity sha512-+HC6GfWU3upe5/mqmxuqYZ9B2Wl4lcoUUNkoaX59nEWV4EtADCMiBqui111Bu8R8IvaZTmqmxrqOAqjbHIwXPw== - dependencies: - browserslist "^4.16.6" - caniuse-api "^3.0.0" - colord "^2.0.1" - postcss-value-parser "^4.1.0" - postcss-convert-values@^2.3.4: version "2.6.1" resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-2.6.1.tgz#bbd8593c5c1fd2e3d1c322bb925dcae8dae4d62d" @@ -8386,13 +2997,6 @@ postcss-convert-values@^2.3.4: postcss "^5.0.11" postcss-value-parser "^3.1.2" -postcss-convert-values@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-5.0.1.tgz#4ec19d6016534e30e3102fdf414e753398645232" - integrity sha512-C3zR1Do2BkKkCgC0g3sF8TS0koF2G+mN8xxayZx3f10cIRmTaAnpgpRQZjNekTZxM2ciSPoh2IWJm0VZx8NoQg== - dependencies: - postcss-value-parser "^4.1.0" - postcss-discard-comments@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz#befe89fafd5b3dace5ccce51b76b81514be00e3d" @@ -8400,11 +3004,6 @@ postcss-discard-comments@^2.0.4: dependencies: postcss "^5.0.14" -postcss-discard-comments@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-5.0.1.tgz#9eae4b747cf760d31f2447c27f0619d5718901fe" - integrity sha512-lgZBPTDvWrbAYY1v5GYEv8fEO/WhKOu/hmZqmCYfrpD6eyDWWzAOsl2rF29lpvziKO02Gc5GJQtlpkTmakwOWg== - postcss-discard-duplicates@^2.0.1: version "2.1.0" resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-2.1.0.tgz#b9abf27b88ac188158a5eb12abcae20263b91932" @@ -8412,11 +3011,6 @@ postcss-discard-duplicates@^2.0.1: dependencies: postcss "^5.0.4" -postcss-discard-duplicates@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-5.0.1.tgz#68f7cc6458fe6bab2e46c9f55ae52869f680e66d" - integrity sha512-svx747PWHKOGpAXXQkCc4k/DsWo+6bc5LsVrAsw+OU+Ibi7klFZCyX54gjYzX4TH+f2uzXjRviLARxkMurA2bA== - postcss-discard-empty@^2.0.1: version "2.1.0" resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-2.1.0.tgz#d2b4bd9d5ced5ebd8dcade7640c7d7cd7f4f92b5" @@ -8424,11 +3018,6 @@ postcss-discard-empty@^2.0.1: dependencies: postcss "^5.0.14" -postcss-discard-empty@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-5.0.1.tgz#ee136c39e27d5d2ed4da0ee5ed02bc8a9f8bf6d8" - integrity sha512-vfU8CxAQ6YpMxV2SvMcMIyF2LX1ZzWpy0lqHDsOdaKKLQVQGVP1pzhrI9JlsO65s66uQTfkQBKBD/A5gp9STFw== - postcss-discard-overridden@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-0.1.1.tgz#8b1eaf554f686fb288cd874c55667b0aa3668d58" @@ -8436,11 +3025,6 @@ postcss-discard-overridden@^0.1.1: dependencies: postcss "^5.0.16" -postcss-discard-overridden@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-5.0.1.tgz#454b41f707300b98109a75005ca4ab0ff2743ac6" - integrity sha512-Y28H7y93L2BpJhrdUR2SR2fnSsT+3TVx1NmVQLbcnZWwIUpJ7mfcTC6Za9M2PG6w8j7UQRfzxqn8jU2VwFxo3Q== - postcss-discard-unused@^2.2.1: version "2.2.3" resolved "https://registry.yarnpkg.com/postcss-discard-unused/-/postcss-discard-unused-2.2.3.tgz#bce30b2cc591ffc634322b5fb3464b6d934f4433" @@ -8456,15 +3040,6 @@ postcss-filter-plugins@^2.0.0: dependencies: postcss "^5.0.4" -postcss-loader@6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-6.2.0.tgz#714370a3f567141cf4cadcdf9575f5234d186bc5" - integrity sha512-H9hv447QjQJVDbHj3OUdciyAXY3v5+UDduzEytAlZCVHCpNAAg/mCSwhYYqZr9BiGYhmYspU8QXxZwiHTLn3yA== - dependencies: - cosmiconfig "^7.0.0" - klona "^2.0.4" - semver "^7.3.5" - postcss-merge-idents@^2.1.5: version "2.1.7" resolved "https://registry.yarnpkg.com/postcss-merge-idents/-/postcss-merge-idents-2.1.7.tgz#4c5530313c08e1d5b3bbf3d2bbc747e278eea270" @@ -8481,15 +3056,6 @@ postcss-merge-longhand@^2.0.1: dependencies: postcss "^5.0.4" -postcss-merge-longhand@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-5.0.2.tgz#277ada51d9a7958e8ef8cf263103c9384b322a41" - integrity sha512-BMlg9AXSI5G9TBT0Lo/H3PfUy63P84rVz3BjCFE9e9Y9RXQZD3+h3YO1kgTNsNJy7bBc1YQp8DmSnwLIW5VPcw== - dependencies: - css-color-names "^1.0.1" - postcss-value-parser "^4.1.0" - stylehacks "^5.0.1" - postcss-merge-rules@^2.0.3: version "2.1.2" resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-2.1.2.tgz#d1df5dfaa7b1acc3be553f0e9e10e87c61b5f721" @@ -8501,17 +3067,6 @@ postcss-merge-rules@^2.0.3: postcss-selector-parser "^2.2.2" vendors "^1.0.0" -postcss-merge-rules@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-5.0.2.tgz#d6e4d65018badbdb7dcc789c4f39b941305d410a" - integrity sha512-5K+Md7S3GwBewfB4rjDeol6V/RZ8S+v4B66Zk2gChRqLTCC8yjnHQ601omj9TKftS19OPGqZ/XzoqpzNQQLwbg== - dependencies: - browserslist "^4.16.6" - caniuse-api "^3.0.0" - cssnano-utils "^2.0.1" - postcss-selector-parser "^6.0.5" - vendors "^1.0.3" - postcss-message-helpers@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/postcss-message-helpers/-/postcss-message-helpers-2.0.0.tgz#a4f2f4fab6e4fe002f0aed000478cdf52f9ba60e" @@ -8526,13 +3081,6 @@ postcss-minify-font-values@^1.0.2: postcss "^5.0.4" postcss-value-parser "^3.0.2" -postcss-minify-font-values@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-5.0.1.tgz#a90cefbfdaa075bd3dbaa1b33588bb4dc268addf" - integrity sha512-7JS4qIsnqaxk+FXY1E8dHBDmraYFWmuL6cgt0T1SWGRO5bzJf8sUoelwa4P88LEWJZweHevAiDKxHlofuvtIoA== - dependencies: - postcss-value-parser "^4.1.0" - postcss-minify-gradients@^1.0.1: version "1.0.5" resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz#5dbda11373703f83cfb4a3ea3881d8d75ff5e6e1" @@ -8541,15 +3089,6 @@ postcss-minify-gradients@^1.0.1: postcss "^5.0.12" postcss-value-parser "^3.3.0" -postcss-minify-gradients@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-5.0.2.tgz#7c175c108f06a5629925d698b3c4cf7bd3864ee5" - integrity sha512-7Do9JP+wqSD6Prittitt2zDLrfzP9pqKs2EcLX7HJYxsxCOwrrcLt4x/ctQTsiOw+/8HYotAoqNkrzItL19SdQ== - dependencies: - colord "^2.6" - cssnano-utils "^2.0.1" - postcss-value-parser "^4.1.0" - postcss-minify-params@^1.0.4: version "1.2.2" resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-1.2.2.tgz#ad2ce071373b943b3d930a3fa59a358c28d6f1f3" @@ -8560,17 +3099,6 @@ postcss-minify-params@^1.0.4: postcss-value-parser "^3.0.2" uniqs "^2.0.0" -postcss-minify-params@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-5.0.1.tgz#371153ba164b9d8562842fdcd929c98abd9e5b6c" - integrity sha512-4RUC4k2A/Q9mGco1Z8ODc7h+A0z7L7X2ypO1B6V8057eVK6mZ6xwz6QN64nHuHLbqbclkX1wyzRnIrdZehTEHw== - dependencies: - alphanum-sort "^1.0.2" - browserslist "^4.16.0" - cssnano-utils "^2.0.1" - postcss-value-parser "^4.1.0" - uniqs "^2.0.0" - postcss-minify-selectors@^2.0.4: version "2.1.1" resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-2.1.1.tgz#b2c6a98c0072cf91b932d1a496508114311735bf" @@ -8581,42 +3109,6 @@ postcss-minify-selectors@^2.0.4: postcss "^5.0.14" postcss-selector-parser "^2.0.0" -postcss-minify-selectors@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-5.1.0.tgz#4385c845d3979ff160291774523ffa54eafd5a54" - integrity sha512-NzGBXDa7aPsAcijXZeagnJBKBPMYLaJJzB8CQh6ncvyl2sIndLVWfbcDi0SBjRWk5VqEjXvf8tYwzoKf4Z07og== - dependencies: - alphanum-sort "^1.0.2" - postcss-selector-parser "^6.0.5" - -postcss-modules-extract-imports@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz#cda1f047c0ae80c97dbe28c3e76a43b88025741d" - integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw== - -postcss-modules-local-by-default@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz#ebbb54fae1598eecfdf691a02b3ff3b390a5a51c" - integrity sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ== - dependencies: - icss-utils "^5.0.0" - postcss-selector-parser "^6.0.2" - postcss-value-parser "^4.1.0" - -postcss-modules-scope@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz#9ef3151456d3bbfa120ca44898dfca6f2fa01f06" - integrity sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg== - dependencies: - postcss-selector-parser "^6.0.4" - -postcss-modules-values@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz#d7c5e7e68c3bb3c9b27cbf48ca0bb3ffb4602c9c" - integrity sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ== - dependencies: - icss-utils "^5.0.0" - postcss-normalize-charset@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz#ef9ee71212d7fe759c78ed162f61ed62b5cb93f1" @@ -8624,57 +3116,6 @@ postcss-normalize-charset@^1.1.0: dependencies: postcss "^5.0.5" -postcss-normalize-charset@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-5.0.1.tgz#121559d1bebc55ac8d24af37f67bd4da9efd91d0" - integrity sha512-6J40l6LNYnBdPSk+BHZ8SF+HAkS4q2twe5jnocgd+xWpz/mx/5Sa32m3W1AA8uE8XaXN+eg8trIlfu8V9x61eg== - -postcss-normalize-display-values@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-5.0.1.tgz#62650b965981a955dffee83363453db82f6ad1fd" - integrity sha512-uupdvWk88kLDXi5HEyI9IaAJTE3/Djbcrqq8YgjvAVuzgVuqIk3SuJWUisT2gaJbZm1H9g5k2w1xXilM3x8DjQ== - dependencies: - cssnano-utils "^2.0.1" - postcss-value-parser "^4.1.0" - -postcss-normalize-positions@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-5.0.1.tgz#868f6af1795fdfa86fbbe960dceb47e5f9492fe5" - integrity sha512-rvzWAJai5xej9yWqlCb1OWLd9JjW2Ex2BCPzUJrbaXmtKtgfL8dBMOOMTX6TnvQMtjk3ei1Lswcs78qKO1Skrg== - dependencies: - postcss-value-parser "^4.1.0" - -postcss-normalize-repeat-style@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.0.1.tgz#cbc0de1383b57f5bb61ddd6a84653b5e8665b2b5" - integrity sha512-syZ2itq0HTQjj4QtXZOeefomckiV5TaUO6ReIEabCh3wgDs4Mr01pkif0MeVwKyU/LHEkPJnpwFKRxqWA/7O3w== - dependencies: - cssnano-utils "^2.0.1" - postcss-value-parser "^4.1.0" - -postcss-normalize-string@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-5.0.1.tgz#d9eafaa4df78c7a3b973ae346ef0e47c554985b0" - integrity sha512-Ic8GaQ3jPMVl1OEn2U//2pm93AXUcF3wz+OriskdZ1AOuYV25OdgS7w9Xu2LO5cGyhHCgn8dMXh9bO7vi3i9pA== - dependencies: - postcss-value-parser "^4.1.0" - -postcss-normalize-timing-functions@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.0.1.tgz#8ee41103b9130429c6cbba736932b75c5e2cb08c" - integrity sha512-cPcBdVN5OsWCNEo5hiXfLUnXfTGtSFiBU9SK8k7ii8UD7OLuznzgNRYkLZow11BkQiiqMcgPyh4ZqXEEUrtQ1Q== - dependencies: - cssnano-utils "^2.0.1" - postcss-value-parser "^4.1.0" - -postcss-normalize-unicode@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-5.0.1.tgz#82d672d648a411814aa5bf3ae565379ccd9f5e37" - integrity sha512-kAtYD6V3pK0beqrU90gpCQB7g6AOfP/2KIPCVBKJM2EheVsBQmx/Iof+9zR9NFKLAx4Pr9mDhogB27pmn354nA== - dependencies: - browserslist "^4.16.0" - postcss-value-parser "^4.1.0" - postcss-normalize-url@^3.0.7: version "3.0.8" resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-3.0.8.tgz#108f74b3f2fcdaf891a2ffa3ea4592279fc78222" @@ -8685,22 +3126,6 @@ postcss-normalize-url@^3.0.7: postcss "^5.0.14" postcss-value-parser "^3.2.3" -postcss-normalize-url@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-5.0.2.tgz#ddcdfb7cede1270740cf3e4dfc6008bd96abc763" - integrity sha512-k4jLTPUxREQ5bpajFQZpx8bCF2UrlqOTzP9kEqcEnOfwsRshWs2+oAFIHfDQB8GO2PaUaSE0NlTAYtbluZTlHQ== - dependencies: - is-absolute-url "^3.0.3" - normalize-url "^6.0.1" - postcss-value-parser "^4.1.0" - -postcss-normalize-whitespace@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.0.1.tgz#b0b40b5bcac83585ff07ead2daf2dcfbeeef8e9a" - integrity sha512-iPklmI5SBnRvwceb/XH568yyzK0qRVuAG+a1HFUsFRf11lEJTiQQa03a4RSCQvLKdcpX7XsI1Gen9LuLoqwiqA== - dependencies: - postcss-value-parser "^4.1.0" - postcss-ordered-values@^2.1.0: version "2.2.3" resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-2.2.3.tgz#eec6c2a67b6c412a8db2042e77fe8da43f95c11d" @@ -8709,14 +3134,6 @@ postcss-ordered-values@^2.1.0: postcss "^5.0.4" postcss-value-parser "^3.0.1" -postcss-ordered-values@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-5.0.2.tgz#1f351426977be00e0f765b3164ad753dac8ed044" - integrity sha512-8AFYDSOYWebJYLyJi3fyjl6CqMEG/UVworjiyK1r573I56kb3e879sCJLGvR3merj+fAdPpVplXKQZv+ey6CgQ== - dependencies: - cssnano-utils "^2.0.1" - postcss-value-parser "^4.1.0" - postcss-reduce-idents@^2.2.2: version "2.4.0" resolved "https://registry.yarnpkg.com/postcss-reduce-idents/-/postcss-reduce-idents-2.4.0.tgz#c2c6d20cc958284f6abfbe63f7609bf409059ad3" @@ -8732,14 +3149,6 @@ postcss-reduce-initial@^1.0.0: dependencies: postcss "^5.0.4" -postcss-reduce-initial@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-5.0.1.tgz#9d6369865b0f6f6f6b165a0ef5dc1a4856c7e946" - integrity sha512-zlCZPKLLTMAqA3ZWH57HlbCjkD55LX9dsRyxlls+wfuRfqCi5mSlZVan0heX5cHr154Dq9AfbH70LyhrSAezJw== - dependencies: - browserslist "^4.16.0" - caniuse-api "^3.0.0" - postcss-reduce-transforms@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-1.0.4.tgz#ff76f4d8212437b31c298a42d2e1444025771ae1" @@ -8749,14 +3158,6 @@ postcss-reduce-transforms@^1.0.3: postcss "^5.0.8" postcss-value-parser "^3.0.1" -postcss-reduce-transforms@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-5.0.1.tgz#93c12f6a159474aa711d5269923e2383cedcf640" - integrity sha512-a//FjoPeFkRuAguPscTVmRQUODP+f3ke2HqFNgGPwdYnpeC29RZdCBvGRGTsKpMURb/I3p6jdKoBQ2zI+9Q7kA== - dependencies: - cssnano-utils "^2.0.1" - postcss-value-parser "^4.1.0" - postcss-selector-parser@^2.0.0, postcss-selector-parser@^2.2.2: version "2.2.3" resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz#f9437788606c3c9acee16ffe8d8b16297f27bb90" @@ -8766,24 +3167,6 @@ postcss-selector-parser@^2.0.0, postcss-selector-parser@^2.2.2: indexes-of "^1.0.1" uniq "^1.0.1" -postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4: - version "6.0.4" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.4.tgz#56075a1380a04604c38b063ea7767a129af5c2b3" - integrity sha512-gjMeXBempyInaBqpp8gODmwZ52WaYsVOsfr4L4lDQ7n3ncD6mEyySiDtgzCT+NYC0mmeOLvtsF8iaEf0YT6dBw== - dependencies: - cssesc "^3.0.0" - indexes-of "^1.0.1" - uniq "^1.0.1" - util-deprecate "^1.0.2" - -postcss-selector-parser@^6.0.5: - version "6.0.6" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz#2c5bba8174ac2f6981ab631a42ab0ee54af332ea" - integrity sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg== - dependencies: - cssesc "^3.0.0" - util-deprecate "^1.0.2" - postcss-svgo@^2.1.1: version "2.1.6" resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-2.1.6.tgz#b6df18aa613b666e133f08adb5219c2684ac108d" @@ -8794,14 +3177,6 @@ postcss-svgo@^2.1.1: postcss-value-parser "^3.2.3" svgo "^0.7.0" -postcss-svgo@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-5.0.2.tgz#bc73c4ea4c5a80fbd4b45e29042c34ceffb9257f" - integrity sha512-YzQuFLZu3U3aheizD+B1joQ94vzPfE6BNUcSYuceNxlVnKKsOtdo6hL9/zyC168Q8EwfLSgaDSalsUGa9f2C0A== - dependencies: - postcss-value-parser "^4.1.0" - svgo "^2.3.0" - postcss-unique-selectors@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-2.0.2.tgz#981d57d29ddcb33e7b1dfe1fd43b8649f933ca1d" @@ -8811,25 +3186,11 @@ postcss-unique-selectors@^2.0.2: postcss "^5.0.4" uniqs "^2.0.0" -postcss-unique-selectors@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-5.0.1.tgz#3be5c1d7363352eff838bd62b0b07a0abad43bfc" - integrity sha512-gwi1NhHV4FMmPn+qwBNuot1sG1t2OmacLQ/AX29lzyggnjd+MnVD5uqQmpXO3J17KGL2WAxQruj1qTd3H0gG/w== - dependencies: - alphanum-sort "^1.0.2" - postcss-selector-parser "^6.0.5" - uniqs "^2.0.0" - postcss-value-parser@^3.0.1, postcss-value-parser@^3.0.2, postcss-value-parser@^3.1.1, postcss-value-parser@^3.1.2, postcss-value-parser@^3.2.3, postcss-value-parser@^3.3.0: version "3.3.1" resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== -postcss-value-parser@^4.0.2, postcss-value-parser@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb" - integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ== - postcss-zindex@^2.0.1: version "2.2.0" resolved "https://registry.yarnpkg.com/postcss-zindex/-/postcss-zindex-2.2.0.tgz#d2109ddc055b91af67fc4cb3b025946639d2af22" @@ -8839,15 +3200,6 @@ postcss-zindex@^2.0.1: postcss "^5.0.4" uniqs "^2.0.0" -postcss@8.3.11: - version "8.3.11" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.3.11.tgz#c3beca7ea811cd5e1c4a3ec6d2e7599ef1f8f858" - integrity sha512-hCmlUAIlUiav8Xdqw3Io4LcpA1DOt7h3LSTAC4G6JGHFFaWzI6qvFt9oilvl8BmkbBRX1IhM90ZAmpk68zccQA== - dependencies: - nanoid "^3.1.30" - picocolors "^1.0.0" - source-map-js "^0.6.2" - postcss@^5.0.10, postcss@^5.0.11, postcss@^5.0.12, postcss@^5.0.13, postcss@^5.0.14, postcss@^5.0.16, postcss@^5.0.2, postcss@^5.0.4, postcss@^5.0.5, postcss@^5.0.8, postcss@^5.2.16: version "5.2.18" resolved "https://registry.yarnpkg.com/postcss/-/postcss-5.2.18.tgz#badfa1497d46244f6390f58b319830d9107853c5" @@ -8858,75 +3210,6 @@ postcss@^5.0.10, postcss@^5.0.11, postcss@^5.0.12, postcss@^5.0.13, postcss@^5.0 source-map "^0.5.6" supports-color "^3.2.3" -postcss@^8.1.10: - version "8.2.8" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.8.tgz#0b90f9382efda424c4f0f69a2ead6f6830d08ece" - integrity sha512-1F0Xb2T21xET7oQV9eKuctbM9S7BC0fetoHCc4H13z0PT6haiRLP4T0ZY4XWh7iLP0usgqykT6p9B2RtOf4FPw== - dependencies: - colorette "^1.2.2" - nanoid "^3.1.20" - source-map "^0.6.1" - -postcss@^8.2.15: - version "8.3.0" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.3.0.tgz#b1a713f6172ca427e3f05ef1303de8b65683325f" - integrity sha512-+ogXpdAjWGa+fdYY5BQ96V/6tAo+TdSSIMP5huJBIygdWwKtVoB5JWZ7yUd4xZ8r+8Kvvx4nyg/PQ071H4UtcQ== - dependencies: - colorette "^1.2.2" - nanoid "^3.1.23" - source-map-js "^0.6.2" - -postgres-array@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-2.0.0.tgz#48f8fce054fbc69671999329b8834b772652d82e" - integrity sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA== - -postgres-bytea@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/postgres-bytea/-/postgres-bytea-1.0.0.tgz#027b533c0aa890e26d172d47cf9ccecc521acd35" - integrity sha1-AntTPAqokOJtFy1Hz5zOzFIazTU= - -postgres-date@~1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/postgres-date/-/postgres-date-1.0.5.tgz#710b27de5f27d550f6e80b5d34f7ba189213c2ee" - integrity sha512-pdau6GRPERdAYUQwkBnGKxEfPyhVZXG/JiS44iZWiNdSOWE09N2lUgN6yshuq6fVSon4Pm0VMXd1srUUkLe9iA== - -postgres-interval@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/postgres-interval/-/postgres-interval-1.2.0.tgz#b460c82cb1587507788819a06aa0fffdb3544695" - integrity sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ== - dependencies: - xtend "^4.0.0" - -prebuild-install@^6.1.4: - version "6.1.4" - resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-6.1.4.tgz#ae3c0142ad611d58570b89af4986088a4937e00f" - integrity sha512-Z4vpywnK1lBg+zdPCVCsKq0xO66eEV9rWo2zrROGGiRS4JtueBOdlB1FnY8lcy7JsUud/Q3ijUxyWN26Ika0vQ== - dependencies: - detect-libc "^1.0.3" - expand-template "^2.0.3" - github-from-package "0.0.0" - minimist "^1.2.3" - mkdirp-classic "^0.5.3" - napi-build-utils "^1.0.1" - node-abi "^2.21.0" - npmlog "^4.0.1" - pump "^3.0.0" - rc "^1.2.7" - simple-get "^3.0.3" - tar-fs "^2.0.0" - tunnel-agent "^0.6.0" - -prelude-ls@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" - integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== - -prelude-ls@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" - integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= - prepend-http@^1.0.0: version "1.0.4" resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" @@ -8942,101 +3225,11 @@ pretty-hrtime@^1.0.0: resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" integrity sha1-t+PqQkNaTJsnWdmeDyAesZWALuE= -pretty@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pretty/-/pretty-2.0.0.tgz#adbc7960b7bbfe289a557dc5f737619a220d06a5" - integrity sha1-rbx5YLe7/iiaVX3F9zdhmiINBqU= - dependencies: - condense-newlines "^0.2.1" - extend-shallow "^2.0.1" - js-beautify "^1.6.12" - -prettyjson@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/prettyjson/-/prettyjson-1.2.1.tgz#fcffab41d19cab4dfae5e575e64246619b12d289" - integrity sha1-/P+rQdGcq0365eV15kJGYZsS0ok= - dependencies: - colors "^1.1.2" - minimist "^1.2.0" - -printj@~1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/printj/-/printj-1.1.2.tgz#d90deb2975a8b9f600fb3a1c94e3f4c53c78a222" - integrity sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ== - -prismjs@1.25.0: - version "1.25.0" - resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.25.0.tgz#6f822df1bdad965734b310b315a23315cf999756" - integrity sha512-WCjJHl1KEWbnkQom1+SzftbtXMKQoezOCYs5rECqMN+jP+apI7ftoflyqigqzopSO3hMhTEb0mFClA8lkolgEg== - -private-ip@2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/private-ip/-/private-ip-2.3.0.tgz#aa07bf623c60ea75ee5d140814f492648c001717" - integrity sha512-3lTFzg+Z1Q2VNQChw8AW2c5LM7getyUJ67SqeWtvnkUO4gihjbf5oIEK4+jAQ4v1sCqOVV7r+GzKrgowW/W3tw== - dependencies: - ip-regex "^4.3.0" - ipaddr.js "^2.0.1" - is-ip "^3.1.0" - netmask "^2.0.2" - -probe-image-size@7.2.1: - version "7.2.1" - resolved "https://registry.yarnpkg.com/probe-image-size/-/probe-image-size-7.2.1.tgz#df0c924e67e247bc94f8fcb0fad7f0081061fc44" - integrity sha512-d+6L3NvQBCNt4peRDoEfA7r9bPm6/qy18FnLKwg4NWBC5JrJm0pMLRg1kF4XNsPe1bUdt3WIMonPJzQWN2HXjQ== - dependencies: - lodash.merge "^4.6.2" - needle "^2.5.2" - stream-parser "~0.3.1" - process-nextick-args@^2.0.0, process-nextick-args@~2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== -progress@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" - integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== - -promise-inflight@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" - integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= - -promise-limit@2.7.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/promise-limit/-/promise-limit-2.7.0.tgz#eb5737c33342a030eaeaecea9b3d3a93cb592b26" - integrity sha512-7nJ6v5lnJsXwGprnGXga4wx6d1POjvi5Qmf1ivTRxTjH4Z/9Czja/UCMLVmB9N93GeWOU93XaFaEt6jbuoagNw== - -promise-retry@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-2.0.1.tgz#ff747a13620ab57ba688f5fc67855410c370da22" - integrity sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g== - dependencies: - err-code "^2.0.2" - retry "^0.12.0" - -promise.prototype.finally@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/promise.prototype.finally/-/promise.prototype.finally-3.1.2.tgz#b8af89160c9c673cefe3b4c4435b53cfd0287067" - integrity sha512-A2HuJWl2opDH0EafgdjwEw7HysI8ff/n4lW4QEVBCUXFk9QeGecBWv0Deph0UmLe3tTNYegz8MOjsVuE6SMoJA== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.0" - function-bind "^1.1.1" - -promise@^7.0.1: - version "7.3.1" - resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" - integrity sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg== - dependencies: - asap "~2.0.3" - -proto-list@~1.2.1: - version "1.2.4" - resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" - integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk= - proxy-from-env@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.0.0.tgz#33c50398f70ea7eb96d21f7b817630a55791c7ee" @@ -9049,119 +3242,11 @@ ps-tree@1.2.0: dependencies: event-stream "=3.3.4" -pseudomap@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" - integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= - -psl@^1.1.28, psl@^1.1.33: +psl@^1.1.28: version "1.8.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== -pug-attrs@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pug-attrs/-/pug-attrs-3.0.0.tgz#b10451e0348165e31fad1cc23ebddd9dc7347c41" - integrity sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA== - dependencies: - constantinople "^4.0.1" - js-stringify "^1.0.2" - pug-runtime "^3.0.0" - -pug-code-gen@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/pug-code-gen/-/pug-code-gen-3.0.2.tgz#ad190f4943133bf186b60b80de483100e132e2ce" - integrity sha512-nJMhW16MbiGRiyR4miDTQMRWDgKplnHyeLvioEJYbk1RsPI3FuA3saEP8uwnTb2nTJEKBU90NFVWJBk4OU5qyg== - dependencies: - constantinople "^4.0.1" - doctypes "^1.1.0" - js-stringify "^1.0.2" - pug-attrs "^3.0.0" - pug-error "^2.0.0" - pug-runtime "^3.0.0" - void-elements "^3.1.0" - with "^7.0.0" - -pug-error@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pug-error/-/pug-error-2.0.0.tgz#5c62173cb09c34de2a2ce04f17b8adfec74d8ca5" - integrity sha512-sjiUsi9M4RAGHktC1drQfCr5C5eriu24Lfbt4s+7SykztEOwVZtbFk1RRq0tzLxcMxMYTBR+zMQaG07J/btayQ== - -pug-filters@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/pug-filters/-/pug-filters-4.0.0.tgz#d3e49af5ba8472e9b7a66d980e707ce9d2cc9b5e" - integrity sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A== - dependencies: - constantinople "^4.0.1" - jstransformer "1.0.0" - pug-error "^2.0.0" - pug-walk "^2.0.0" - resolve "^1.15.1" - -pug-lexer@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/pug-lexer/-/pug-lexer-5.0.1.tgz#ae44628c5bef9b190b665683b288ca9024b8b0d5" - integrity sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w== - dependencies: - character-parser "^2.2.0" - is-expression "^4.0.0" - pug-error "^2.0.0" - -pug-linker@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/pug-linker/-/pug-linker-4.0.0.tgz#12cbc0594fc5a3e06b9fc59e6f93c146962a7708" - integrity sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw== - dependencies: - pug-error "^2.0.0" - pug-walk "^2.0.0" - -pug-load@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pug-load/-/pug-load-3.0.0.tgz#9fd9cda52202b08adb11d25681fb9f34bd41b662" - integrity sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ== - dependencies: - object-assign "^4.1.1" - pug-walk "^2.0.0" - -pug-parser@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/pug-parser/-/pug-parser-6.0.0.tgz#a8fdc035863a95b2c1dc5ebf4ecf80b4e76a1260" - integrity sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw== - dependencies: - pug-error "^2.0.0" - token-stream "1.0.0" - -pug-runtime@^3.0.0, pug-runtime@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/pug-runtime/-/pug-runtime-3.0.1.tgz#f636976204723f35a8c5f6fad6acda2a191b83d7" - integrity sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg== - -pug-strip-comments@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pug-strip-comments/-/pug-strip-comments-2.0.0.tgz#f94b07fd6b495523330f490a7f554b4ff876303e" - integrity sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ== - dependencies: - pug-error "^2.0.0" - -pug-walk@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pug-walk/-/pug-walk-2.0.0.tgz#417aabc29232bb4499b5b5069a2b2d2a24d5f5fe" - integrity sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ== - -pug@3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/pug/-/pug-3.0.2.tgz#f35c7107343454e43bc27ae0ff76c731b78ea535" - integrity sha512-bp0I/hiK1D1vChHh6EfDxtndHji55XP/ZJKwsRqrz6lRia6ZC2OZbdAymlxdVFwd1L70ebrVJw4/eZ79skrIaw== - dependencies: - pug-code-gen "^3.0.2" - pug-filters "^4.0.0" - pug-lexer "^5.0.1" - pug-linker "^4.0.0" - pug-load "^3.0.0" - pug-parser "^6.0.0" - pug-runtime "^3.0.1" - pug-strip-comments "^2.0.0" - pump@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" @@ -9192,48 +3277,16 @@ punycode@1.3.2: resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= -punycode@2.1.1, punycode@^2.1.0, punycode@^2.1.1: +punycode@^2.1.0, punycode@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== -pureimage@0.3.5: - version "0.3.5" - resolved "https://registry.yarnpkg.com/pureimage/-/pureimage-0.3.5.tgz#cd5e91f7b6409fcf4880297aaa3e7fc0afc24d5e" - integrity sha512-+CFUEpoX6GemlKlHihI7Ii4IqKqF5KZjd682sAxwzbc4t4zU4Gwhxd4W3UMZW94nJzf0n4nA9zJrwTR4jZB4TA== - dependencies: - jpeg-js "^0.4.1" - opentype.js "^0.4.3" - pngjs "^3.3.1" - -q@1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/q/-/q-1.4.1.tgz#55705bcd93c5f3673530c2c2cbc0c2b3addc286e" - integrity sha1-VXBbzZPF82c1MMLCy8DCs63cKG4= - q@^1.1.2: version "1.5.1" resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= -qrcode@1.4.4: - version "1.4.4" - resolved "https://registry.yarnpkg.com/qrcode/-/qrcode-1.4.4.tgz#f0c43568a7e7510a55efc3b88d9602f71963ea83" - integrity sha512-oLzEC5+NKFou9P0bMj5+v6Z40evexeE29Z9cummZXZ9QXyMr3lphkURzxjXgPJC5azpxcshoDWV1xE46z+/c3Q== - dependencies: - buffer "^5.4.3" - buffer-alloc "^1.2.0" - buffer-from "^1.1.1" - dijkstrajs "^1.0.1" - isarray "^2.0.1" - pngjs "^3.3.0" - yargs "^13.2.4" - -qs@^6.4.0, qs@^6.5.2: - version "6.9.3" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.3.tgz#bfadcd296c2d549f1dffa560619132c977f5008e" - integrity sha512-EbZYNarm6138UKKq46tdx08Yo/q9ZhFoAXAI1meAFd2GtbRDhbZY2WQSICskT0c5q99aFzLG1D4nvTk9tqfXIw== - qs@~6.5.2: version "6.5.2" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" @@ -9252,76 +3305,6 @@ querystring@0.2.0: resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= -quick-lru@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" - integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== - -ramda@~0.27.1: - version "0.27.1" - resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.27.1.tgz#66fc2df3ef873874ffc2da6aa8984658abacf5c9" - integrity sha512-PgIdVpn5y5Yns8vqb8FzBUEYn98V3xcPgawAkkgj0YJ0qDsnHCiNmZYfOGMgOvoB0eWFLpYbhxUR3mxfDIMvpw== - -random-seed@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/random-seed/-/random-seed-0.3.0.tgz#d945f2e1f38f49e8d58913431b8bf6bb937556cd" - integrity sha1-2UXy4fOPSejViRNDG4v2u5N1Vs0= - dependencies: - json-stringify-safe "^5.0.1" - -randombytes@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" - integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== - dependencies: - safe-buffer "^5.1.0" - -rangestr@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/rangestr/-/rangestr-0.0.1.tgz#f72ff9246f10f2a7d7c16e14616f617be2c2635a" - integrity sha1-9y/5JG8Q8qfXwW4UYW9he+LCY1o= - -ratelimiter@3.4.1: - version "3.4.1" - resolved "https://registry.yarnpkg.com/ratelimiter/-/ratelimiter-3.4.1.tgz#fa69e94937413382a926aaa17aaeaa6263af4659" - integrity sha512-5FJbRW/Jkkdk29ksedAfWFkQkhbUrMx3QJGwMKAypeIiQf4yrLW+gtPKZiaWt4zPrtw1uGufOjGO7UGM6VllsQ== - -raw-body@^2.2.0, raw-body@^2.3.3: - version "2.4.1" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.1.tgz#30ac82f98bb5ae8c152e67149dac8d55153b168c" - integrity sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA== - dependencies: - bytes "3.1.0" - http-errors "1.7.3" - iconv-lite "0.4.24" - unpipe "1.0.0" - -rc@^1.2.7: - version "1.2.8" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" - integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== - dependencies: - deep-extend "^0.6.0" - ini "~1.3.0" - minimist "^1.2.0" - strip-json-comments "~2.0.1" - -rdf-canonize@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/rdf-canonize/-/rdf-canonize-3.0.0.tgz#f5bade563e5e58f5cc5881afcba3c43839e8c747" - integrity sha512-LXRkhab1QaPJnhUIt1gtXXKswQCZ9zpflsSZFczG7mCLAkMvVjdqCGk9VXCUss0aOUeEyV2jtFxGcdX8DSkj9w== - dependencies: - setimmediate "^1.0.5" - -re2@1.16.0: - version "1.16.0" - resolved "https://registry.yarnpkg.com/re2/-/re2-1.16.0.tgz#f311eb4865b1296123800ea8e013cec8dab25590" - integrity sha512-eizTZL2ZO0ZseLqfD4t3Qd0M3b3Nr0MBWpX81EbPMIud/1d/CSfUIx2GQK8fWiAeHoSekO5EOeFib2udTZLwYw== - dependencies: - install-artifact-from-github "^1.2.0" - nan "^2.14.2" - node-gyp "^8.0.0" - read-pkg-up@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" @@ -9339,17 +3322,7 @@ read-pkg@^1.0.0: normalize-package-data "^2.3.2" path-type "^1.0.0" -readable-stream@1.1.x: - version "1.1.14" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" - integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk= - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" - -readable-stream@3, readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0: +readable-stream@3: version "3.6.0" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== @@ -9358,7 +3331,7 @@ readable-stream@3, readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stre string_decoder "^1.1.1" util-deprecate "^1.0.1" -readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6: +readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6: version "2.3.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== @@ -9371,13 +3344,14 @@ readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable string_decoder "~1.1.1" util-deprecate "~1.0.1" -readable-web-to-node-stream@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.0.tgz#4ca5408e70471069119d691934141a52de413955" - integrity sha512-HNmLb3n0SteGAs8HQlErYPGeO+y7cvL/mVUKtXeUkl0iCZ/2GIgKGrCFHyS7UXFnO8uc9U+0y3pYIzAPsjFfvA== +readdirp@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" + integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== dependencies: - "@types/readable-stream" "^2.3.9" - readable-stream "^3.6.0" + graceful-fs "^4.1.11" + micromatch "^3.1.10" + readable-stream "^2.0.2" readdirp@~3.3.0: version "3.3.0" @@ -9393,50 +3367,6 @@ rechoir@^0.6.2: dependencies: resolve "^1.1.6" -rechoir@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.7.0.tgz#32650fd52c21ab252aa5d65b19310441c7e03aca" - integrity sha512-ADsDEH2bvbjltXEP+hTIAmeFekTFK0V2BTxMkok6qILyAJEXV0AFfoWcAq4yfll5VdIMd/RVXq0lR+wQi5ZU3Q== - dependencies: - resolve "^1.9.0" - -reconnecting-websocket@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/reconnecting-websocket/-/reconnecting-websocket-4.4.0.tgz#3b0e5b96ef119e78a03135865b8bb0af1b948783" - integrity sha512-D2E33ceRPga0NvTDhJmphEgJ7FUYF0v4lr1ki0csq06OdlxKfugGzN0dSkxM/NfqCxYELK4KcaTOUOjTV6Dcng== - -redis-commands@1.7.0, redis-commands@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/redis-commands/-/redis-commands-1.7.0.tgz#15a6fea2d58281e27b1cd1acfb4b293e278c3a89" - integrity sha512-nJWqw3bTFy21hX/CPKHth6sfhZbdiHP6bTawSgQBlKOVRG7EZkfHbbHwQJnrE4vsQf0CMNE+3gJ4Fmm16vdVlQ== - -redis-errors@^1.0.0, redis-errors@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/redis-errors/-/redis-errors-1.2.0.tgz#eb62d2adb15e4eaf4610c04afe1529384250abad" - integrity sha1-62LSrbFeTq9GEMBK/hUpOEJQq60= - -redis-lock@0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/redis-lock/-/redis-lock-0.1.4.tgz#e83590bee22b5f01cdb65bfbd88d988045356272" - integrity sha512-7/+zu86XVQfJVx1nHTzux5reglDiyUCDwmW7TSlvVezfhH2YLc/Rc8NE0ejQG+8/0lwKzm29/u/4+ogKeLosiA== - -redis-parser@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/redis-parser/-/redis-parser-3.0.0.tgz#b66d828cdcafe6b4b8a428a7def4c6bcac31c8b4" - integrity sha1-tm2CjNyv5rS4pCin3vTGvKwxyLQ= - dependencies: - redis-errors "^1.0.0" - -redis@3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/redis/-/redis-3.1.2.tgz#766851117e80653d23e0ed536254677ab647638c" - integrity sha512-grn5KoZLr/qrRQVwoSkmzdbw6pwF+/rwODtrOr6vuBRiR/f3rjSTGupbF90Zpqm2oenix8Do6RV7pYEkGwlKkw== - dependencies: - denque "^1.5.0" - redis-commands "^1.7.0" - redis-errors "^1.2.0" - redis-parser "^3.0.0" - reduce-css-calc@^1.2.6: version "1.3.0" resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz#747c914e049614a4c9cfbba629871ad1d2927716" @@ -9453,16 +3383,6 @@ reduce-function-call@^1.0.1: dependencies: balanced-match "^1.0.0" -reflect-metadata@0.1.13, reflect-metadata@^0.1.13: - version "0.1.13" - resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08" - integrity sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg== - -regenerator-runtime@^0.13.4: - version "0.13.7" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55" - integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew== - regex-not@^1.0.0, regex-not@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" @@ -9471,11 +3391,6 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" -regexpp@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" - integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== - remove-bom-buffer@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz#c2bf1e377520d324f623892e33c10cac2c252b53" @@ -9498,13 +3413,6 @@ remove-trailing-separator@^1.0.1, remove-trailing-separator@^1.1.0: resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= -rename@1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/rename/-/rename-1.0.4.tgz#a0f25078fa4195e650f73050c7c12ccf689f430b" - integrity sha1-oPJQePpBleZQ9zBQx8Esz2ifQws= - dependencies: - debug "^2.5.2" - repeat-element@^1.1.2: version "1.1.3" resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" @@ -9545,61 +3453,6 @@ request-progress@^3.0.0: dependencies: throttleit "^1.0.0" -request-promise-core@1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.4.tgz#3eedd4223208d419867b78ce815167d10593a22f" - integrity sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw== - dependencies: - lodash "^4.17.19" - -request-promise-native@1.0.9: - version "1.0.9" - resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.9.tgz#e407120526a5efdc9a39b28a5679bf47b9d9dc28" - integrity sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g== - dependencies: - request-promise-core "1.1.4" - stealthy-require "^1.1.1" - tough-cookie "^2.3.3" - -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" - -request@2.88.2, request@^2.88.2: - version "2.88.2" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" - integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.8.0" - caseless "~0.12.0" - combined-stream "~1.0.6" - extend "~3.0.2" - forever-agent "~0.6.1" - form-data "~2.3.2" - har-validator "~5.1.3" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.19" - oauth-sign "~0.9.0" - performance-now "^2.1.0" - qs "~6.5.2" - safe-buffer "^5.1.2" - tough-cookie "~2.5.0" - tunnel-agent "^0.6.0" - uuid "^3.3.2" - -require-all@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/require-all/-/require-all-3.0.0.tgz#473d49704be310115ce124f77383b1ebd8671312" - integrity sha1-Rz1JcEvjEBFc4ST3c4Ox69hnExI= - require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" @@ -9615,23 +3468,6 @@ require-main-filename@^1.0.1: resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= -require-main-filename@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" - integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== - -resolve-alpn@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.0.0.tgz#745ad60b3d6aff4b4a48e01b8c0bdc70959e0e8c" - integrity sha512-rTuiIEqFmGxne4IovivKSDzld2lWW9QCjqv80SYjPgf+gS35eaCAjaP54CCwGAwBtnCsvNLYtqxe1Nw+i6JEmA== - -resolve-cwd@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" - integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== - dependencies: - resolve-from "^5.0.0" - resolve-dir@^1.0.0, resolve-dir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" @@ -9640,16 +3476,6 @@ resolve-dir@^1.0.0, resolve-dir@^1.0.1: expand-tilde "^2.0.0" global-modules "^1.0.0" -resolve-from@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" - integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== - -resolve-from@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" - integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== - resolve-options@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/resolve-options/-/resolve-options-1.1.0.tgz#32bb9e39c06d67338dc9378c0d6d6074566ad131" @@ -9657,20 +3483,12 @@ resolve-options@^1.1.0: dependencies: value-or-function "^3.0.0" -resolve-path@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/resolve-path/-/resolve-path-1.4.0.tgz#c4bda9f5efb2fce65247873ab36bb4d834fe16f7" - integrity sha1-xL2p9e+y/OZSR4c6s2u02DT+Fvc= - dependencies: - http-errors "~1.6.2" - path-is-absolute "1.0.1" - resolve-url@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= -resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.3.2, resolve@^1.4.0, resolve@^1.9.0: +resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.4.0: version "1.18.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.18.1.tgz#018fcb2c5b207d2a6424aee361c5a266da8f4130" integrity sha512-lDfCPaMKfOJXjy0dPayzPdF1phampNWr3qFCjAu+rw/qbQmr5jWH5xN2hwh9QKfw9E5v4hwV7A+jrCmL8yjjqA== @@ -9678,21 +3496,6 @@ resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.3.2, resolve@^1.4.0, is-core-module "^2.0.0" path-parse "^1.0.6" -resolve@^1.15.1: - version "1.20.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" - integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== - dependencies: - is-core-module "^2.2.0" - path-parse "^1.0.6" - -responselike@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.0.tgz#26391bcc3174f750f9a79eacc40a12a5c42d7723" - integrity sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw== - dependencies: - lowercase-keys "^2.0.0" - restore-cursor@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" @@ -9706,48 +3509,13 @@ ret@~0.1.10: resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== -retry@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" - integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= - -reusify@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" - integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== - -rimraf@3.0.2, rimraf@^3.0.0, rimraf@^3.0.2: +rimraf@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== dependencies: glob "^7.1.3" -rndstr@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/rndstr/-/rndstr-1.0.0.tgz#77e66fa8f9b4836853fdd91e50719591bb67d349" - integrity sha1-d+ZvqPm0g2hT/dkeUHGVkbtn00k= - dependencies: - rangestr "0.0.1" - seedrandom "2.4.2" - -rsvp@^4.8.5: - version "4.8.5" - resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734" - integrity sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA== - -run-parallel@^1.1.9: - version "1.1.9" - resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.9.tgz#c9dd3a7cf9f4b2c4b6244e173a6ed866e61dd679" - integrity sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q== - -rxjs@^6.6.3: - version "6.6.6" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.6.tgz#14d8417aa5a07c5e633995b525e1e3c0dec03b70" - integrity sha512-/oTwee4N4iWzAMAL9xdGKjkEHmIwupR3oXbQjCKywF1BeFohswF3vZdogbmEF6pZkOsXTzWkrZszrWpQTByYVg== - dependencies: - tslib "^1.9.0" - rxjs@^6.6.7: version "6.6.7" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9" @@ -9762,31 +3530,16 @@ rxjs@^7.1.0: dependencies: tslib "~2.1.0" -s-age@1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/s-age/-/s-age-1.1.2.tgz#c0cf15233ccc93f41de92ea42c36d957977d1ea2" - integrity sha512-aSN2TlF39WLoZA/6cgYSJZhKt63kJ4EaadejPWjWY9/h4rksIqvfWY3gfd+3uAegSM1IXsA9aWeEhJtkxkFQtA== - -safari-14-idb-fix@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/safari-14-idb-fix/-/safari-14-idb-fix-1.0.4.tgz#5c68ba63e2a8ae0d89a0aa1e13fe89e3aef7da19" - integrity sha512-4+Y2baQdgJpzu84d0QjySl70Kyygzf0pepVg8NVg4NnQEPpfC91fAn0baNvtStlCjUUxxiu0BOMiafa98fRRuA== - -safe-buffer@*: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@~5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== +safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + safe-regex@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" @@ -9794,76 +3547,16 @@ safe-regex@^1.1.0: dependencies: ret "~0.1.10" -"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: +safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -sass-loader@12.2.0: - version "12.2.0" - resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-12.2.0.tgz#b370010fb0ababae2ef9c6c89e05d6c6debc6042" - integrity sha512-qducnp5vSV+8A8MZxuH6zV0MUg4MOVISScl2wDTCAn/2WJX+9Auxh92O/rnkdR2bvi5QxZBafnzkzRrWGZvm7w== - dependencies: - klona "^2.0.4" - neo-async "^2.6.2" - -sass@1.43.3: - version "1.43.3" - resolved "https://registry.yarnpkg.com/sass/-/sass-1.43.3.tgz#aa16a69131b84f0cd23189a242571e8905f1ce43" - integrity sha512-BJnLngqWpMeS65UvlYYEuCb3/fLxDxhHtOB/gWPxs6NKrslTxGt3ZxwIvOe/0Jm4tWwM/+tIpE3wj4dLEhPDeQ== - dependencies: - chokidar ">=3.0.0 <4.0.0" - -sax@1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a" - integrity sha1-e45lYZCyKOgaZq6nSEgNgozS03o= - -sax@>=0.6.0, sax@^1.2.4, sax@~1.2.1, sax@~1.2.4: +sax@~1.2.1: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== -saxes@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d" - integrity sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw== - dependencies: - xmlchars "^2.2.0" - -schema-utils@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.0.0.tgz#67502f6aa2b66a2d4032b4279a2944978a0913ef" - integrity sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA== - dependencies: - "@types/json-schema" "^7.0.6" - ajv "^6.12.5" - ajv-keywords "^3.5.2" - -schema-utils@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.0.tgz#95986eb604f66daadeed56e379bfe7a7f963cdb9" - integrity sha512-tTEaeYkyIhEZ9uWgAjDerWov3T9MgX8dhhy2r0IGeeX4W8ngtGl1++dUve/RUqzuaASSh7shwCDJjEzthxki8w== - dependencies: - "@types/json-schema" "^7.0.7" - ajv "^6.12.5" - ajv-keywords "^3.5.2" - -secure-json-parse@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/secure-json-parse/-/secure-json-parse-2.1.0.tgz#ae76f5624256b5c497af887090a5d9e156c9fb20" - integrity sha512-GckO+MS/wT4UogDyoI/H/S1L0MCcKS1XX/vp48wfmU7Nw4woBmb8mIpu4zPBQjKlRT88/bt9xdoV4111jPpNJA== - -seedrandom@2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/seedrandom/-/seedrandom-2.4.2.tgz#18d78c41287d13aff8eadb29e235938b248aa9ff" - integrity sha1-GNeMQSh9E6/46tsp4jWTiySKqf8= - -seedrandom@3.0.5: - version "3.0.5" - resolved "https://registry.yarnpkg.com/seedrandom/-/seedrandom-3.0.5.tgz#54edc85c95222525b0c7a6f6b3543d8e0b3aa0a7" - integrity sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg== - semver-greatest-satisfied-range@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz#13e8c2658ab9691cb0cd71093240280d36f77a5b" @@ -9871,45 +3564,12 @@ semver-greatest-satisfied-range@^1.1.0: dependencies: sver-compat "^1.5.0" -"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1, semver@^5.6.0: +"semver@2 || 3 || 4 || 5": version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== -semver@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== - -semver@^7.2.1, semver@^7.3.2, semver@^7.3.4: - version "7.3.4" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.4.tgz#27aaa7d2e4ca76452f98d3add093a72c943edc97" - integrity sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw== - dependencies: - lru-cache "^6.0.0" - -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== - dependencies: - lru-cache "^6.0.0" - -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== - dependencies: - randombytes "^2.1.0" - -serialize-javascript@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" - integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== - dependencies: - randombytes "^2.1.0" - -set-blocking@^2.0.0, set-blocking@~2.0.0: +set-blocking@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= @@ -9924,50 +3584,6 @@ set-value@^2.0.0, set-value@^2.0.1: is-plain-object "^2.0.3" split-string "^3.0.1" -setimmediate@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" - integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= - -setprototypeof@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" - integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== - -setprototypeof@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" - integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== - -sha.js@^2.4.11: - version "2.4.11" - resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" - integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -shallow-clone@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" - integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== - dependencies: - kind-of "^6.0.2" - -sharp@0.29.2: - version "0.29.2" - resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.29.2.tgz#e8c003cd9cb321585b32dbda6eed3baa7d6f2308" - integrity sha512-XWRdiYLIJ3tDUejRyG24KERnJzMfIoyiJBntd2S6/uj3NEeNgRFRLgiBlvPxMa8aml14dKKD98yHinSNKp1xzQ== - dependencies: - color "^4.0.1" - detect-libc "^1.0.3" - node-addon-api "^4.2.0" - prebuild-install "^6.1.4" - semver "^7.3.5" - simple-get "^3.1.0" - tar-fs "^2.1.1" - tunnel-agent "^0.6.0" - shebang-command@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" @@ -9980,42 +3596,11 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -sigmund@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" - integrity sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA= - -signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3: +signal-exit@^3.0.2, signal-exit@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== -simple-concat@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.0.tgz#7344cbb8b6e26fb27d66b2fc86f9f6d5997521c6" - integrity sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY= - -simple-get@^3.0.3, simple-get@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-3.1.0.tgz#b45be062435e50d159540b576202ceec40b9c6b3" - integrity sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA== - dependencies: - decompress-response "^4.2.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" - integrity sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo= - dependencies: - is-arrayish "^0.3.1" - -slash@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" - integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== - slice-ansi@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-3.0.0.tgz#31ddc10930a1b7e0b67b08c96c2f49b77a789787" @@ -10034,11 +3619,6 @@ slice-ansi@^4.0.0: astral-regex "^2.0.0" is-fullwidth-code-point "^3.0.0" -smart-buffer@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.1.0.tgz#91605c25d91652f4661ea69ccf45f1b331ca21ba" - integrity sha512-iVICrxOzCynf/SNaBQCw34eM9jROU/s5rzIhpOvzhzuYHfJR/DhZfDkXiZSgKXfgv26HT3Yni3AV/DGw0cGnnw== - snapdragon-node@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" @@ -10069,23 +3649,6 @@ snapdragon@^0.8.1: source-map-resolve "^0.5.0" use "^3.1.0" -socks-proxy-agent@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-5.0.0.tgz#7c0f364e7b1cf4a7a437e71253bed72e9004be60" - integrity sha512-lEpa1zsWCChxiynk+lCycKuC502RxDWLKJZoIhnxrWNjLSDGYRFflHA1/228VkRcnv9TIb8w98derGbpKxJRgA== - dependencies: - agent-base "6" - debug "4" - socks "^2.3.3" - -socks@^2.3.3: - version "2.6.1" - resolved "https://registry.yarnpkg.com/socks/-/socks-2.6.1.tgz#989e6534a07cf337deb1b1c94aaa44296520d30e" - integrity sha512-kLQ9N5ucj8uIcxrDwjm0Jsqk06xdpBjGNQtpXy4Q8/QY2k+fY7nZH8CARy+hkbG+SGAovmzzuauCpBlb8FrnBA== - dependencies: - ip "^1.1.5" - smart-buffer "^4.1.0" - sort-keys@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" @@ -10093,21 +3656,6 @@ sort-keys@^1.0.0: dependencies: is-plain-obj "^1.0.0" -sortablejs@1.10.2: - version "1.10.2" - resolved "https://registry.yarnpkg.com/sortablejs/-/sortablejs-1.10.2.tgz#6e40364d913f98b85a14f6678f92b5c1221f5290" - integrity sha512-YkPGufevysvfwn5rfdlGyrGjt7/CRHwvRPogD/lC+TnvcN29jDpCifKP+rBqf+LRldfXSTh+0CGLcSg0VIxq3A== - -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-resolve@^0.5.0: version "0.5.3" resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" @@ -10119,14 +3667,6 @@ source-map-resolve@^0.5.0: source-map-url "^0.4.0" urix "^0.1.0" -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-support@~0.5.20: version "0.5.20" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.20.tgz#12166089f8f5e5e8c56926b377633392dd2cb6c9" @@ -10145,7 +3685,7 @@ source-map@^0.5.1, source-map@^0.5.3, source-map@^0.5.6: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= -source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: +source-map@^0.6.0: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== @@ -10155,21 +3695,11 @@ source-map@~0.7.2: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== -sourcemap-codec@^1.4.4: - version "1.4.8" - resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" - integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== - sparkles@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/sparkles/-/sparkles-1.0.1.tgz#008db65edce6c50eec0c5e228e1945061dd0437c" integrity sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw== -spawn-command@^0.0.2-1: - version "0.0.2-1" - resolved "https://registry.yarnpkg.com/spawn-command/-/spawn-command-0.0.2-1.tgz#62f5e9466981c1b796dc5929937e11c9c6921bd0" - integrity sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A= - spdx-correct@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4" @@ -10196,13 +3726,6 @@ spdx-license-ids@^3.0.0: resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz#3694b5804567a458d3c8045842a6358632f62654" integrity sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q== -speakeasy@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/speakeasy/-/speakeasy-2.0.0.tgz#85c91a071b09a5cb8642590d983566165f57613a" - integrity sha1-hckaBxsJpcuGQlkNmDVmFl9XYTo= - dependencies: - base32.js "0.0.1" - split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" @@ -10217,24 +3740,12 @@ split@0.3: dependencies: through "2" -split@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9" - integrity sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg== - dependencies: - through "2" - -sprintf-js@1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.2.tgz#da1765262bf8c0f571749f2ad6c26300207ae673" - integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug== - sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= -sshpk@^1.14.1, sshpk@^1.7.0: +sshpk@^1.7.0: version "1.16.1" resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== @@ -10249,28 +3760,11 @@ sshpk@^1.14.1, sshpk@^1.7.0: safer-buffer "^2.0.2" tweetnacl "~0.14.0" -ssri@^8.0.0, ssri@^8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.1.tgz#638e4e439e2ffbd2cd289776d5ca457c4f51a2af" - integrity sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ== - dependencies: - minipass "^3.1.1" - -stable@^0.1.8: - version "0.1.8" - resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" - integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== - stack-trace@0.0.10: version "0.0.10" resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" integrity sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA= -standard-as-callback@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/standard-as-callback/-/standard-as-callback-2.1.0.tgz#8953fc05359868a77b5b9739a665c5977bb7df45" - integrity sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A== - start-server-and-test@1.14.0: version "1.14.0" resolved "https://registry.yarnpkg.com/start-server-and-test/-/start-server-and-test-1.14.0.tgz#c57f04f73eac15dd51733b551d775b40837fdde3" @@ -10292,16 +3786,6 @@ static-extend@^0.1.1: define-property "^0.2.5" object-copy "^0.1.0" -"statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2", statuses@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" - integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= - -stealthy-require@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" - integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= - stream-combiner@~0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.0.4.tgz#4d5e433c185261dde623ca3f44c586bcf5c4ad14" @@ -10314,28 +3798,11 @@ stream-exhaust@^1.0.1: resolved "https://registry.yarnpkg.com/stream-exhaust/-/stream-exhaust-1.0.2.tgz#acdac8da59ef2bc1e17a2c0ccf6c320d120e555d" integrity sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw== -stream-parser@~0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/stream-parser/-/stream-parser-0.3.1.tgz#1618548694420021a1182ff0af1911c129761773" - integrity sha1-FhhUhpRCACGhGC/wrxkRwSl2F3M= - dependencies: - debug "2" - stream-shift@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== -streamsearch@0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a" - integrity sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo= - -strict-event-emitter-types@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strict-event-emitter-types/-/strict-event-emitter-types-2.0.0.tgz#05e15549cb4da1694478a53543e4e2f4abcf277f" - integrity sha512-Nk/brWYpD85WlOgzw5h173aci0Teyv8YdIAEtV+N88nDB0dLlazZyJMIsN6eo1/AR61l+p6CJTG1JIyFaoNEEA== - strict-uri-encode@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" @@ -10350,23 +3817,6 @@ string-width@^1.0.1, string-width@^1.0.2: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" -"string-width@^1.0.2 || 2": - version "2.1.1" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" - -string-width@^3.0.0, string-width@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" - integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== - dependencies: - emoji-regex "^7.0.1" - is-fullwidth-code-point "^2.0.0" - strip-ansi "^5.1.0" - string-width@^4.1.0, string-width@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" @@ -10376,40 +3826,6 @@ string-width@^4.1.0, string-width@^4.2.0: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.0" -string.prototype.trimend@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz#85812a6b847ac002270f5808146064c995fb6913" - integrity sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.5" - -string.prototype.trimleft@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz#4408aa2e5d6ddd0c9a80739b087fbc067c03b3cc" - integrity sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.5" - string.prototype.trimstart "^1.0.0" - -string.prototype.trimright@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz#c76f1cef30f21bbad8afeb8db1511496cfb0f2a3" - integrity sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.5" - string.prototype.trimend "^1.0.0" - -string.prototype.trimstart@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz#14af6d9f34b053f7cfc89b72f8f2ee14b9039a54" - integrity sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.5" - string_decoder@^1.1.1: version "1.3.0" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" @@ -10417,11 +3833,6 @@ string_decoder@^1.1.1: dependencies: safe-buffer "~5.2.0" -string_decoder@~0.10.x: - version "0.10.31" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" - integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= - string_decoder@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" @@ -10429,13 +3840,6 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -stringz@2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/stringz/-/stringz-2.1.0.tgz#5896b4713eac31157556040fb90258fb02c1630c" - integrity sha512-KlywLT+MZ+v0IRepfMxRtnSvDCMc3nR1qqCs3m/qIbSOWkNZYT8XHQA31rS3TnKp0c5xjZu3M4GY/2aRKSi/6A== - dependencies: - char-regex "^1.0.2" - strip-ansi@^3.0.0, strip-ansi@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" @@ -10443,20 +3847,6 @@ strip-ansi@^3.0.0, strip-ansi@^3.0.1: dependencies: ansi-regex "^2.0.0" -strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= - dependencies: - ansi-regex "^3.0.0" - -strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" - integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== - dependencies: - ansi-regex "^4.1.0" - strip-ansi@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" @@ -10471,69 +3861,11 @@ strip-bom@^2.0.0: dependencies: is-utf8 "^0.2.0" -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= - strip-final-newline@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== -strip-json-comments@3.1.1, strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" - integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== - -strip-json-comments@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= - -strtok3@^6.2.4: - version "6.2.4" - resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-6.2.4.tgz#302aea64c0fa25d12a0385069ba66253fdc38a81" - integrity sha512-GO8IcFF9GmFDvqduIspUBwCzCbqzegyVKIsSymcMgiZKeCfrN9SowtUoi8+b59WZMAjIzVZic/Ft97+pynR3Iw== - dependencies: - "@tokenizer/token" "^0.3.0" - peek-readable "^4.0.1" - -style-loader@3.3.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.3.1.tgz#057dfa6b3d4d7c7064462830f9113ed417d38575" - integrity sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ== - -stylehacks@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-5.0.1.tgz#323ec554198520986806388c7fdaebc38d2c06fb" - integrity sha512-Es0rVnHIqbWzveU1b24kbw92HsebBepxfcqe5iix7t9j0PQqhs0IxXVXv0pY2Bxa08CgMkzD6OWql7kbGOuEdA== - dependencies: - browserslist "^4.16.0" - postcss-selector-parser "^6.0.4" - -summaly@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/summaly/-/summaly-2.4.1.tgz#d2a8fa6bad10c1651eb0b849aab3009e87216a3d" - integrity sha512-1gETEQXqK5RD7yIGgdGeTwGL1uh+uj14u99atzNLNmvsxwdtZbPvDHZBPXkAW0cqsd8teoBJln5Dh1QeAhvGIg== - dependencies: - cheerio-httpcli "0.8.2" - debug "4.3.2" - escape-regexp "0.0.1" - html-entities "2.3.2" - koa "2.13.1" - request "2.88.2" - request-promise-native "1.0.9" - require-all "3.0.0" - trace-redirect "1.0.6" - -supports-color@8.1.1, supports-color@^8.0.0, supports-color@^8.1.0, supports-color@^8.1.1: - version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== - dependencies: - has-flag "^4.0.0" - supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" @@ -10546,20 +3878,20 @@ supports-color@^3.2.3: dependencies: has-flag "^1.0.0" -supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - 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== dependencies: has-flag "^4.0.0" +supports-color@^8.1.1: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + sver-compat@^1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/sver-compat/-/sver-compat-1.5.0.tgz#3cf87dfeb4d07b4a3f14827bc186b3fd0c645cd8" @@ -10581,173 +3913,6 @@ svgo@^0.7.0: sax "~1.2.1" whet.extend "~0.9.9" -svgo@^1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.3.2.tgz#b6dc511c063346c9e415b81e43401145b96d4167" - integrity sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw== - dependencies: - chalk "^2.4.1" - coa "^2.0.2" - css-select "^2.0.0" - css-select-base-adapter "^0.1.1" - css-tree "1.0.0-alpha.37" - csso "^4.0.2" - js-yaml "^3.13.1" - mkdirp "~0.5.1" - object.values "^1.1.0" - sax "~1.2.4" - stable "^0.1.8" - unquote "~1.1.1" - util.promisify "~1.0.0" - -svgo@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/svgo/-/svgo-2.3.0.tgz#6b3af81d0cbd1e19c83f5f63cec2cb98c70b5373" - integrity sha512-fz4IKjNO6HDPgIQxu4IxwtubtbSfGEAJUq/IXyTPIkGhWck/faiiwfkvsB8LnBkKLvSoyNNIY6d13lZprJMc9Q== - dependencies: - "@trysound/sax" "0.1.1" - chalk "^4.1.0" - commander "^7.1.0" - css-select "^3.1.2" - css-tree "^1.1.2" - csso "^4.2.0" - stable "^0.1.8" - -symbol-tree@^3.2.4: - version "3.2.4" - resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" - integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== - -syslog-pro@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/syslog-pro/-/syslog-pro-1.0.0.tgz#e46bfd39f58937352645091e84a3b903f39e12ea" - integrity sha512-7SNMJKtQBJlwBUp1jxFT7bXya71cnINXPCYJ2AVhlQE4MKL7o2QiPdAXbMdWRiLeykQ2rx+7TNrnoGzvzhO+eA== - dependencies: - moment "^2.22.2" - -systeminformation@5.9.8: - version "5.9.8" - resolved "https://registry.yarnpkg.com/systeminformation/-/systeminformation-5.9.8.tgz#470d5781647418fd2f2ec945e507cd522a69d565" - integrity sha512-Dt54Vuu4Q5pGCsBtbVjIzD3Lahek7qIL+2vqAPqcPtPAlFRPf+ef4VKB4F5AL5UmdjYm7NFCTnwjoiu7qtxmQQ== - -syuilo-password-strength@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/syuilo-password-strength/-/syuilo-password-strength-0.0.1.tgz#08f71a8f0ecb77db649f3d9a6424510d9d945f52" - integrity sha1-CPcajw7Ld9tknz2aZCRRDZ2UX1I= - -tapable@^2.1.1, tapable@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.0.tgz#5c373d281d9c672848213d0e037d1c4165ab426b" - integrity sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw== - -tar-fs@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.0.1.tgz#e44086c1c60d31a4f0cf893b1c4e155dabfae9e2" - integrity sha512-6tzWDMeroL87uF/+lin46k+Q+46rAJ0SyPGz7OW7wTgblI273hsBqk2C1j0/xNadNLKDTUL9BukSjB7cwgmlPA== - dependencies: - chownr "^1.1.1" - mkdirp-classic "^0.5.2" - pump "^3.0.0" - tar-stream "^2.0.0" - -tar-fs@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" - integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== - dependencies: - chownr "^1.1.1" - mkdirp-classic "^0.5.2" - pump "^3.0.0" - tar-stream "^2.1.4" - -tar-stream@^2.0.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.1.2.tgz#6d5ef1a7e5783a95ff70b69b97455a5968dc1325" - integrity sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q== - dependencies: - bl "^4.0.1" - end-of-stream "^1.4.1" - fs-constants "^1.0.0" - inherits "^2.0.3" - readable-stream "^3.1.1" - -tar-stream@^2.1.4: - version "2.2.0" - resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" - integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== - dependencies: - bl "^4.0.3" - end-of-stream "^1.4.1" - fs-constants "^1.0.0" - inherits "^2.0.3" - readable-stream "^3.1.1" - -tar@^6.0.2: - version "6.0.5" - resolved "https://registry.yarnpkg.com/tar/-/tar-6.0.5.tgz#bde815086e10b39f1dcd298e89d596e1535e200f" - integrity sha512-0b4HOimQHj9nXNEAA7zWwMM91Zhhba3pspja6sQbgTpynOJf+bkjBnfybNYzbpLbnwXnbyB4LOREvlyXLkCHSg== - dependencies: - chownr "^2.0.0" - fs-minipass "^2.0.0" - minipass "^3.0.0" - minizlib "^2.1.1" - mkdirp "^1.0.3" - yallist "^4.0.0" - -tar@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.0.tgz#d1724e9bcc04b977b18d5c573b333a2207229a83" - integrity sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA== - dependencies: - chownr "^2.0.0" - fs-minipass "^2.0.0" - minipass "^3.0.0" - minizlib "^2.1.1" - 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-webpack-plugin@^5.1.3: - version "5.1.4" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.1.4.tgz#c369cf8a47aa9922bd0d8a94fe3d3da11a7678a1" - integrity sha512-C2WkFwstHDhVEmsmlCxrXUtVklS+Ir1A7twrYzrDrQQOIMOaVAYykaoo/Aq1K0QRkMoY2hhvDQY1cm4jnIMFwA== - dependencies: - jest-worker "^27.0.2" - p-limit "^3.1.0" - schema-utils "^3.0.0" - serialize-javascript "^6.0.0" - source-map "^0.6.1" - terser "^5.7.0" - -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" - -terser@^5.7.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.7.1.tgz#2dc7a61009b66bb638305cb2a824763b116bf784" - integrity sha512-b3e+d5JbHAe/JSjwsC3Zn55wsBIM7AsHLjKxT31kGCldgbpFePaFo+PiddtO6uwRZWRw7sPXmAN8dTW61xmnSg== - dependencies: - commander "^2.20.0" - source-map "~0.7.2" - source-map-support "~0.5.19" - terser@^5.9.0: version "5.9.0" resolved "https://registry.yarnpkg.com/terser/-/terser-5.9.0.tgz#47d6e629a522963240f2b55fcaa3c99083d2c351" @@ -10757,45 +3922,11 @@ terser@^5.9.0: source-map "~0.7.2" source-map-support "~0.5.20" -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= - -textarea-caret@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/textarea-caret/-/textarea-caret-3.1.0.tgz#5d5a35bb035fd06b2ff0e25d5359e97f2655087f" - integrity sha512-cXAvzO9pP5CGa6NKx0WYHl+8CHKZs8byMkt3PCJBCmq2a34YA9pO1NrQET5pzeqnBjBdToF5No4rrmkDUgQC2Q== - textextensions@^3.2.0: version "3.3.0" resolved "https://registry.yarnpkg.com/textextensions/-/textextensions-3.3.0.tgz#03530d5287b86773c08b77458589148870cc71d3" integrity sha512-mk82dS8eRABNbeVJrEiN5/UMSCliINAuz8mkUwH4SwslkNP//gbEzlWNS5au0z5Dpx40SQxzqZevZkn+WYJ9Dw== -thenify-all@^1.0.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" - integrity sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY= - dependencies: - thenify ">= 3.1.0 < 4" - -"thenify@>= 3.1.0 < 4": - version "3.3.1" - resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f" - integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw== - dependencies: - any-promise "^1.0.0" - -three@0.117.1: - version "0.117.1" - resolved "https://registry.yarnpkg.com/three/-/three-0.117.1.tgz#a49bcb1a6ddea2f250003e42585dc3e78e92b9d3" - integrity sha512-t4zeJhlNzUIj9+ub0l6nICVimSuRTZJOqvk3Rmlu+YGdTOJ49Wna8p7aumpkXJakJfITiybfpYE1XN1o1Z34UQ== - -throttle-debounce@3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/throttle-debounce/-/throttle-debounce-3.0.1.tgz#32f94d84dfa894f786c9a1f290e7a645b6a19abb" - integrity sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg== - throttleit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-1.0.0.tgz#9e785836daf46743145a5984b6268d828528ac6c" @@ -10824,7 +3955,7 @@ through2@^4.0.2: dependencies: readable-stream "3" -through@2, through@^2.3.8, through@~2.3, through@~2.3.1, through@~2.3.8: +through@2, through@^2.3.8, through@~2.3, through@~2.3.1: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= @@ -10834,17 +3965,7 @@ time-stamp@^1.0.0: resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3" integrity sha1-dkpaEa9QVhkhsTPztE5hhofg9cM= -timsort@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4" - integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q= - -tinycolor2@1.4.2: - version "1.4.2" - resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.4.2.tgz#3f6a4d1071ad07676d7fa472e1fac40a719d8803" - integrity sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA== - -tmp@0.2.1, tmp@~0.2.1: +tmp@~0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== @@ -10859,11 +3980,6 @@ to-absolute-glob@^2.0.0: is-absolute "^1.0.0" is-negated-glob "^1.0.0" -to-fast-properties@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" - integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= - to-object-path@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" @@ -10903,25 +4019,7 @@ to-through@^2.0.0: dependencies: through2 "^2.0.3" -toidentifier@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" - integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== - -token-stream@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/token-stream/-/token-stream-1.0.0.tgz#cc200eab2613f4166d27ff9afc7ca56d49df6eb4" - integrity sha1-zCAOqyYT9BZtJ/+a/HylbUnfbrQ= - -token-types@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/token-types/-/token-types-4.1.1.tgz#ef9e8c8e2e0ded9f1b3f8dbaa46a3228b113ba1a" - integrity sha512-hD+QyuUAyI2spzsI0B7gf/jJ2ggR4RjkAo37j3StuePhApJUwcWDjnHDOFdIWYSwNR28H14hpwm4EI+V1Ted1w== - dependencies: - "@tokenizer/token" "^0.3.0" - ieee754 "^1.2.1" - -tough-cookie@^2.3.3, tough-cookie@^2.5.0, tough-cookie@~2.5.0: +tough-cookie@~2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== @@ -10929,153 +4027,16 @@ tough-cookie@^2.3.3, tough-cookie@^2.5.0, tough-cookie@~2.5.0: psl "^1.1.28" punycode "^2.1.1" -tough-cookie@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4" - integrity sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg== - dependencies: - psl "^1.1.33" - 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== - dependencies: - punycode "^2.1.1" - -trace-redirect@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/trace-redirect/-/trace-redirect-1.0.6.tgz#ac629b5bf8247d30dde5a35fe9811b811075b504" - integrity sha512-UUfa1DjjU5flcjMdaFIiIEGDTyu2y/IiMjOX4uGXa7meKBS4vD4f2Uy/tken9Qkd4Jsm4sRsfZcIIPqrRVF3Mg== - -tree-kill@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" - integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== - -ts-loader@9.2.6: - version "9.2.6" - resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.2.6.tgz#9937c4dd0a1e3dbbb5e433f8102a6601c6615d74" - integrity sha512-QMTC4UFzHmu9wU2VHZEmWWE9cUajjfcdcws+Gh7FhiO+Dy0RnR1bNz0YCHqhI0yRowCE9arVnNxYHqELOy9Hjw== - dependencies: - chalk "^4.1.0" - enhanced-resolve "^5.0.0" - micromatch "^4.0.0" - semver "^7.3.4" - -ts-node@10.4.0: - version "10.4.0" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.4.0.tgz#680f88945885f4e6cf450e7f0d6223dd404895f7" - integrity sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A== - dependencies: - "@cspotcode/source-map-support" "0.7.0" - "@tsconfig/node10" "^1.0.7" - "@tsconfig/node12" "^1.0.7" - "@tsconfig/node14" "^1.0.0" - "@tsconfig/node16" "^1.0.2" - acorn "^8.4.1" - acorn-walk "^8.1.1" - arg "^4.1.0" - create-require "^1.1.0" - diff "^4.0.1" - make-error "^1.1.1" - yn "3.1.1" - -tsc-alias@1.3.10: - version "1.3.10" - resolved "https://registry.yarnpkg.com/tsc-alias/-/tsc-alias-1.3.10.tgz#6ccf81c644092387ab9be3a3a75549a95eeffd80" - integrity sha512-7SF56qiV7Oh/bON+XjF/uAzEFqbmwCuEIHQyoTyVJAK80WnxaIyhO9TBwD/x8InIMU8lnvExQBOrgKkRPsHH+w== - dependencies: - "@jfonx/console-utils" "^1.0.3" - "@jfonx/file-utils" "^3.0.1" - chokidar "^3.5.0" - commander "^6.2.1" - find-node-modules "^2.1.0" - globby "^11.0.2" - normalize-path "^3.0.0" - -tsconfig-paths@3.11.0: - version "3.11.0" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz#954c1fe973da6339c78e06b03ce2e48810b65f36" - integrity sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA== - dependencies: - "@types/json5" "^0.0.29" - json5 "^1.0.1" - minimist "^1.2.0" - strip-bom "^3.0.0" - -tslib@^1.13.0: - version "1.13.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043" - integrity sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q== - -tslib@^1.8.1, tslib@^1.9.0: +tslib@^1.9.0: version "1.11.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35" integrity sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA== -tslib@^1.9.3: - version "1.14.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" - integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== - -tslib@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.2.0.tgz#fb2c475977e35e241311ede2693cee1ec6698f5c" - integrity sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w== - tslib@~2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a" integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A== -tslint-sonarts@1.9.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/tslint-sonarts/-/tslint-sonarts-1.9.0.tgz#feb593e92db328c0328b430b838adbe65d504de9" - integrity sha512-CJWt+IiYI8qggb2O/JPkS6CkC5DY1IcqRsm9EHJ+AxoWK70lvtP7jguochyNDMP2vIz/giGdWCfEM39x/I/Vnw== - dependencies: - immutable "^3.8.2" - -tslint@6.1.3: - version "6.1.3" - resolved "https://registry.yarnpkg.com/tslint/-/tslint-6.1.3.tgz#5c23b2eccc32487d5523bd3a470e9aa31789d904" - integrity sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg== - dependencies: - "@babel/code-frame" "^7.0.0" - builtin-modules "^1.1.1" - chalk "^2.3.0" - commander "^2.12.1" - diff "^4.0.1" - glob "^7.1.1" - js-yaml "^3.13.1" - minimatch "^3.0.4" - mkdirp "^0.5.3" - resolve "^1.3.2" - semver "^5.3.0" - tslib "^1.13.0" - tsutils "^2.29.0" - -tsscmp@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/tsscmp/-/tsscmp-1.0.6.tgz#85b99583ac3589ec4bfef825b5000aa911d605eb" - integrity sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA== - -tsutils@^2.29.0: - version "2.29.0" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.29.0.tgz#32b488501467acbedd4b85498673a0812aca0b99" - integrity sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA== - dependencies: - tslib "^1.8.1" - -tsutils@^3.21.0: - version "3.21.0" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" - integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== - dependencies: - tslib "^1.8.1" - tunnel-agent@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" @@ -11088,53 +4049,11 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0: resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= -twemoji-parser@13.1.0, twemoji-parser@13.1.x: - version "13.1.0" - resolved "https://registry.yarnpkg.com/twemoji-parser/-/twemoji-parser-13.1.0.tgz#65e7e449c59258791b22ac0b37077349127e3ea4" - integrity sha512-AQOzLJpYlpWMy8n+0ATyKKZzWlZBJN+G0C+5lhX7Ftc2PeEVdUU/7ns2Pn2vVje26AIZ/OHwFoUbdv6YYD/wGg== - -type-check@^0.4.0, type-check@~0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" - integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== - dependencies: - prelude-ls "^1.2.1" - -type-check@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" - integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= - dependencies: - prelude-ls "~1.1.2" - -type-detect@4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" - integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== - -type-fest@^0.20.2: - version "0.20.2" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" - integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== - type-fest@^0.21.3: version "0.21.3" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== -type-is@^1.6.14, type-is@^1.6.16, type-is@^1.6.4: - version "1.6.18" - resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" - integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== - dependencies: - media-typer "0.3.0" - mime-types "~2.1.24" - -type-of@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/type-of/-/type-of-2.0.1.tgz#e72a1741896568e9f628378d816d6912f7f23972" - integrity sha1-5yoXQYllaOn2KDeNgW1pEvfyOXI= - type@^1.0.1: version "1.2.0" resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" @@ -11145,56 +4064,11 @@ type@^2.0.0: resolved "https://registry.yarnpkg.com/type/-/type-2.0.0.tgz#5f16ff6ef2eb44f260494dae271033b29c09a9c3" integrity sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow== -typedarray-to-buffer@^3.1.5: - version "3.1.5" - resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" - integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== - dependencies: - is-typedarray "^1.0.0" - typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= -typeorm@0.2.38: - version "0.2.38" - resolved "https://registry.yarnpkg.com/typeorm/-/typeorm-0.2.38.tgz#2af08079919f6ab04cd17017f9faa2c8d5cd566f" - integrity sha512-M6Y3KQcAREQcphOVJciywf4mv6+A0I/SeR+lWNjKsjnQ+a3XcMwGYMGL0Jonsx3H0Cqlf/3yYqVki1jIXSK/xg== - dependencies: - "@sqltools/formatter" "^1.2.2" - app-root-path "^3.0.0" - buffer "^6.0.3" - chalk "^4.1.0" - cli-highlight "^2.1.11" - debug "^4.3.1" - dotenv "^8.2.0" - glob "^7.1.6" - js-yaml "^4.0.0" - mkdirp "^1.0.4" - reflect-metadata "^0.1.13" - sha.js "^2.4.11" - tslib "^2.1.0" - xml2js "^0.4.23" - yargonaut "^1.1.4" - yargs "^17.0.1" - zen-observable-ts "^1.0.0" - -typescript@4.4.4: - version "4.4.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.4.4.tgz#2cd01a1a1f160704d3101fd5a58ff0f9fcb8030c" - integrity sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA== - -uc.micro@^1.0.1, uc.micro@^1.0.5: - version "1.0.6" - resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac" - integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA== - -ulid@2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/ulid/-/ulid-2.3.0.tgz#93063522771a9774121a84d126ecd3eb9804071f" - integrity sha512-keqHubrlpvT6G2wH0OEfSW4mquYRcbe/J8NMmveoQOjUqmo+hXtO+ORCpWhdbZ7k72UtY61BL7haGxW6enBnjw== - unc-path-regex@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa" @@ -11240,20 +4114,6 @@ uniqs@^2.0.0: resolved "https://registry.yarnpkg.com/uniqs/-/uniqs-2.0.0.tgz#ffede4b36b25290696e6e165d4a59edb998e6b02" integrity sha1-/+3ks2slKQaW5uFl1KWe25mOawI= -unique-filename@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" - integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== - dependencies: - unique-slug "^2.0.0" - -unique-slug@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c" - integrity sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w== - dependencies: - imurmurhash "^0.1.4" - unique-stream@^2.0.2: version "2.3.1" resolved "https://registry.yarnpkg.com/unique-stream/-/unique-stream-2.3.1.tgz#c65d110e9a4adf9a6c5948b28053d9a8d04cbeac" @@ -11262,34 +4122,11 @@ unique-stream@^2.0.2: json-stable-stringify-without-jsonify "^1.0.1" through2-filter "^3.0.0" -universalify@^0.1.0, universalify@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" - integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== - universalify@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== -unload@2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/unload/-/unload-2.2.0.tgz#ccc88fdcad345faa06a92039ec0f80b488880ef7" - integrity sha512-B60uB5TNBLtN6/LsgAf3udH9saB5p7gqJwcFfbOEZ8BcBHnGwCf6G/TGiEqkRAxX7zAFIUtzdrXQSdL3Q/wqNA== - dependencies: - "@babel/runtime" "^7.6.2" - detect-node "^2.0.4" - -unpipe@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= - -unquote@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/unquote/-/unquote-1.1.1.tgz#8fded7324ec6e88a0ff8b905e7c098cdc086d544" - integrity sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ= - unset-value@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" @@ -11303,6 +4140,11 @@ untildify@^4.0.0: resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== +upath@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" + integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== + uri-js@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" @@ -11315,14 +4157,6 @@ urix@^0.1.0: resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= -url@0.10.3: - version "0.10.3" - resolved "https://registry.yarnpkg.com/url/-/url-0.10.3.tgz#021e4d9c7705f21bbf37d03ceb58767402774c64" - integrity sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ= - dependencies: - punycode "1.3.2" - querystring "0.2.0" - url@^0.11.0: version "0.11.0" resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" @@ -11331,68 +4165,21 @@ url@^0.11.0: punycode "1.3.2" querystring "0.2.0" -urlsafe-base64@^1.0.0, urlsafe-base64@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/urlsafe-base64/-/urlsafe-base64-1.0.0.tgz#23f89069a6c62f46cf3a1d3b00169cefb90be0c6" - integrity sha1-I/iQaabGL0bPOh07ABac77kL4MY= - use@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== -utf-8-validate@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.2.tgz#63cfbccd85dc1f2b66cf7a1d0eebc08ed056bfb3" - integrity sha512-SwV++i2gTD5qh2XqaPzBnNX88N6HdyhQrNNRykvcS0QKvItV9u3vPEJr+X5Hhfb1JC0r0e1alL0iB09rY8+nmw== - dependencies: - node-gyp-build "~3.7.0" - -util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: +util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= -util.promisify@^1.0.1, util.promisify@~1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.1.tgz#6baf7774b80eeb0f7520d8b81d07982a59abbaee" - integrity sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.2" - has-symbols "^1.0.1" - object.getownpropertydescriptors "^2.1.0" - -uuid@3.3.2: - version "3.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" - integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== - -uuid@7.0.3: - version "7.0.3" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-7.0.3.tgz#c5c9f2c8cf25dc0a372c4df1441c41f5bd0c680b" - integrity sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg== - -uuid@8.3.2, uuid@^8.3.0, uuid@^8.3.2: +uuid@^8.3.2: version "8.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== -uuid@^3.3.2: - version "3.4.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" - integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== - -v-debounce@0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/v-debounce/-/v-debounce-0.1.2.tgz#cab75df7def2783215bf449ef85c69c2decf0a55" - integrity sha1-yrdd997yeDIVv0Se+Fxpwt7PClU= - -v8-compile-cache@^2.0.3: - version "2.2.0" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz#9471efa3ef9128d2f7c6a7ca39c4dd6b5055b132" - integrity sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q== - v8flags@^3.0.1: version "3.1.3" resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-3.1.3.tgz#fc9dc23521ca20c5433f81cc4eb9b3033bb105d8" @@ -11400,11 +4187,6 @@ v8flags@^3.0.1: dependencies: homedir-polyfill "^1.0.1" -valid-url@^1.0.9: - version "1.0.9" - resolved "https://registry.yarnpkg.com/valid-url/-/valid-url-1.0.9.tgz#1c14479b40f1397a75782f115e4086447433a200" - integrity sha1-HBRHm0DxOXp1eC8RXkCGRHQzogA= - validate-npm-package-license@^3.0.1: version "3.0.4" resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" @@ -11418,17 +4200,7 @@ value-or-function@^3.0.0: resolved "https://registry.yarnpkg.com/value-or-function/-/value-or-function-3.0.0.tgz#1c243a50b595c1be54a754bfece8563b9ff8d813" integrity sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM= -vanilla-tilt@1.7.2: - version "1.7.2" - resolved "https://registry.yarnpkg.com/vanilla-tilt/-/vanilla-tilt-1.7.2.tgz#59a5565d9f1f6d392a36969f223fb600dd101a81" - integrity sha512-arf2wY2Y65rP6Zxve9PnUUnRl9nQ1KenPNae6QRaVq/PEvaIto2bC4jYirNJ19U7nLkzI1H9O+nYtcQlX7BTsA== - -vary@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" - integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= - -vendors@^1.0.0, vendors@^1.0.3: +vendors@^1.0.0: version "1.0.4" resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.4.tgz#e2b800a53e7a29b93506c3cf41100d16c4c4ad8e" integrity sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w== @@ -11497,92 +4269,6 @@ vinyl@^2.0.0: remove-trailing-separator "^1.0.1" replace-ext "^1.0.0" -void-elements@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-3.1.0.tgz#614f7fbf8d801f0bb5f0661f5b2f5785750e4f09" - integrity sha1-YU9/v42AHwu18GYfWy9XhXUOTwk= - -vue-eslint-parser@^7.10.0: - version "7.10.0" - resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-7.10.0.tgz#ea4e4b10fd10aa35c8a79ac783488d8abcd29be8" - integrity sha512-7tc/ewS9Vq9Bn741pvpg8op2fWJPH3k32aL+jcIcWGCTzh/zXSdh7pZ5FV3W2aJancP9+ftPAv292zY5T5IPCg== - dependencies: - debug "^4.1.1" - eslint-scope "^5.1.1" - eslint-visitor-keys "^1.1.0" - espree "^6.2.1" - esquery "^1.4.0" - lodash "^4.17.21" - semver "^6.3.0" - -vue-loader@16.7.0: - version "16.7.0" - resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-16.7.0.tgz#ee161b2f6c27b0b459264c3c23d34068b471d574" - integrity sha512-43I0grWtwSCE8fiH/hAwFK+6sNlmvDuHhXScYH8HVSVAMS81IM66tgUOcxbPCeqhhz/1BE51YPxX59eZKGallQ== - dependencies: - chalk "^4.1.0" - hash-sum "^2.0.0" - loader-utils "^2.0.0" - -vue-prism-editor@2.0.0-alpha.2: - version "2.0.0-alpha.2" - resolved "https://registry.yarnpkg.com/vue-prism-editor/-/vue-prism-editor-2.0.0-alpha.2.tgz#aa53a88efaaed628027cbb282c2b1d37fc7c5c69" - integrity sha512-Gu42ba9nosrE+gJpnAEuEkDMqG9zSUysIR8SdXUw8MQKDjBnnNR9lHC18uOr/ICz7yrA/5c7jHJr9lpElODC7w== - -vue-router@4.0.5: - version "4.0.5" - resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-4.0.5.tgz#dd0a4134bc950c37aef64b973e9ee1008428d8fa" - integrity sha512-AQq+pllb6FCc7rS6vh4PPcce3XA1jgK3hKNkQ4hXHwoVN7jOeAOMKCnX7XAX3etV9rmN7iNW8iIwgPk95ckBjw== - -vue-style-loader@4.1.3: - version "4.1.3" - resolved "https://registry.yarnpkg.com/vue-style-loader/-/vue-style-loader-4.1.3.tgz#6d55863a51fa757ab24e89d9371465072aa7bc35" - integrity sha512-sFuh0xfbtpRlKfm39ss/ikqs9AbKCoXZBpHeVZ8Tx650o0k0q/YCM7FRvigtxpACezfq6af+a7JeqVTWvncqDg== - dependencies: - hash-sum "^1.0.2" - loader-utils "^1.0.2" - -vue-svg-loader@0.17.0-beta.2: - version "0.17.0-beta.2" - resolved "https://registry.yarnpkg.com/vue-svg-loader/-/vue-svg-loader-0.17.0-beta.2.tgz#954b2a08b5488998dd81ec371ab5fb5ea4182ef7" - integrity sha512-iMUGJTKEcuNAG8VXOchjA8443IqEmEi2Aw6EVIHWma2cC4TUQ7Oet5Yry9IFfqXQXXvyzXz5EyttVvfRGTNH4Q== - dependencies: - loader-utils "^2.0.0" - semver "^7.3.2" - svgo "^1.3.2" - -vue@3.2.20: - version "3.2.20" - resolved "https://registry.yarnpkg.com/vue/-/vue-3.2.20.tgz#940f8aa8bf3e3be78243ca582bad41fcd45ae3e6" - integrity sha512-81JjEP4OGk9oO8+CU0h2nFPGgJBm9mNa3kdCX2k6FuRdrWrC+CNe+tOnuIeTg8EWwQuI+wwdra5Q7vSzp7p4Iw== - dependencies: - "@vue/compiler-dom" "3.2.20" - "@vue/compiler-sfc" "3.2.20" - "@vue/runtime-dom" "3.2.20" - "@vue/server-renderer" "3.2.20" - "@vue/shared" "3.2.20" - -vuedraggable@4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/vuedraggable/-/vuedraggable-4.0.1.tgz#3bcaab0808b7944030b7d9a29f9a63d59dfa12c5" - integrity sha512-7qN5jhB1SLfx5P+HCm3JUW+pvgA1bSLgYLSVOeLWBDH9z+zbaEH0OlyZBVMLOxFR+JUHJjwDD0oy7T4r9TEgDA== - dependencies: - sortablejs "1.10.2" - -w3c-hr-time@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" - integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ== - 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" - wait-on@6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/wait-on/-/wait-on-6.0.0.tgz#7e9bf8e3d7fe2daecbb7a570ac8ca41e9311c7e7" @@ -11594,184 +4280,6 @@ wait-on@6.0.0: minimist "^1.2.5" rxjs "^7.1.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== - dependencies: - glob-to-regexp "^0.4.1" - graceful-fs "^4.1.2" - -watchpack@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.2.0.tgz#47d78f5415fe550ecd740f99fe2882323a58b1ce" - integrity sha512-up4YAn/XHgZHIxFBVCdlMiWDj6WaLKpwVeGQk2I5thdYxF/KmF0aaz6TfJZ/hfl1h/XlcDr7k1KH7ThDagpFaA== - dependencies: - glob-to-regexp "^0.4.1" - graceful-fs "^4.1.2" - -web-push@3.4.5: - version "3.4.5" - resolved "https://registry.yarnpkg.com/web-push/-/web-push-3.4.5.tgz#f94074ff150538872c7183e4d8881c8305920cf1" - integrity sha512-2njbTqZ6Q7ZqqK14YpK1GGmaZs3NmuGYF5b7abCXulUIWFSlSYcZ3NBJQRFcMiQDceD7vQknb8FUuvI1F7Qe/g== - dependencies: - asn1.js "^5.3.0" - http_ece "1.1.0" - https-proxy-agent "^5.0.0" - jws "^4.0.0" - minimist "^1.2.5" - urlsafe-base64 "^1.0.0" - -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-cli@4.9.1: - version "4.9.1" - resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.9.1.tgz#b64be825e2d1b130f285c314caa3b1ba9a4632b3" - integrity sha512-JYRFVuyFpzDxMDB+v/nanUdQYcZtqFPGzmlW4s+UkPMFhSpfRNmf1z4AwYcHJVdvEFAM7FFCQdNTpsBYhDLusQ== - dependencies: - "@discoveryjs/json-ext" "^0.5.0" - "@webpack-cli/configtest" "^1.1.0" - "@webpack-cli/info" "^1.4.0" - "@webpack-cli/serve" "^1.6.0" - colorette "^2.0.14" - commander "^7.0.0" - execa "^5.0.0" - fastest-levenshtein "^1.0.12" - import-local "^3.0.2" - interpret "^2.2.0" - rechoir "^0.7.0" - webpack-merge "^5.7.3" - -webpack-merge@^5.7.3: - version "5.7.3" - resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.7.3.tgz#2a0754e1877a25a8bbab3d2475ca70a052708213" - integrity sha512-6/JUQv0ELQ1igjGDzHkXbVDRxkfA57Zw7PfiupdLFJYrgFqY5ZP8xxbpp2lU3EPwYx89ht5Z/aDkD40hFCm5AA== - dependencies: - clone-deep "^4.0.1" - wildcard "^2.0.0" - -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-sources@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.0.tgz#b16973bcf844ebcdb3afde32eda1c04d0b90f89d" - integrity sha512-fahN08Et7P9trej8xz/Z7eRu8ltyiygEo/hnRi9KqBUs80KeDcnf96ZJo++ewWd84fEf3xSX9bp4ZS9hbw0OBw== - -webpack@5.59.1: - version "5.59.1" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.59.1.tgz#60c77e9aad796252153d4d7ab6b2d4c11f0e548c" - integrity sha512-I01IQV9K96FlpXX3V0L4nvd7gb0r7thfuu1IfT2P4uOHOA77nKARAKDYGe/tScSHKnffNIyQhLC8kRXzY4KEHQ== - dependencies: - "@types/eslint-scope" "^3.7.0" - "@types/estree" "^0.0.50" - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/wasm-edit" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" - acorn "^8.4.1" - acorn-import-assertions "^1.7.6" - browserslist "^4.14.5" - chrome-trace-event "^1.0.2" - enhanced-resolve "^5.8.3" - es-module-lexer "^0.9.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.1.0" - tapable "^2.1.1" - terser-webpack-plugin "^5.1.3" - watchpack "^2.2.0" - webpack-sources "^3.2.0" - -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" - -websocket@1.0.34: - version "1.0.34" - resolved "https://registry.yarnpkg.com/websocket/-/websocket-1.0.34.tgz#2bdc2602c08bf2c82253b730655c0ef7dcab3111" - integrity sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ== - dependencies: - bufferutil "^4.0.1" - debug "^2.2.0" - es5-ext "^0.10.50" - typedarray-to-buffer "^3.1.5" - 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== - dependencies: - iconv-lite "0.4.24" - -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-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== - dependencies: - lodash "^4.7.0" - tr46 "^2.0.2" - webidl-conversions "^6.1.0" - whet.extend@~0.9.9: version "0.9.9" resolved "https://registry.yarnpkg.com/whet.extend/-/whet.extend-0.9.9.tgz#f877d5bf648c97e5aa542fadc16d6a259b9c11a1" @@ -11782,56 +4290,19 @@ which-module@^1.0.0: resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" integrity sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8= -which-module@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" - integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= - -which@2.0.2, which@^2.0.1, which@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - -which@^1.1.1, which@^1.2.14: +which@^1.2.14: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== dependencies: isexe "^2.0.0" -wide-align@1.1.3, wide-align@^1.1.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" - integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== dependencies: - string-width "^1.0.2 || 2" - -wildcard@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.0.tgz#a77d20e5200c6faaac979e4b3aadc7b3dd7f8fec" - integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw== - -with@^7.0.0: - version "7.0.2" - resolved "https://registry.yarnpkg.com/with/-/with-7.0.2.tgz#ccee3ad542d25538a7a7a80aad212b9828495bac" - integrity sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w== - dependencies: - "@babel/parser" "^7.9.6" - "@babel/types" "^7.9.6" - assert-never "^1.2.1" - babel-walk "3.0.0-canary-5" - -word-wrap@^1.2.3, word-wrap@~1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" - integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== - -workerpool@6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.1.0.tgz#a8e038b4c94569596852de7a8ea4228eefdeb37b" - integrity sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg== + isexe "^2.0.0" wrap-ansi@^2.0.0: version "2.1.0" @@ -11841,15 +4312,6 @@ wrap-ansi@^2.0.0: string-width "^1.0.1" strip-ansi "^3.0.1" -wrap-ansi@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" - integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== - dependencies: - ansi-styles "^3.2.0" - string-width "^3.0.0" - strip-ansi "^5.0.0" - wrap-ansi@^6.2.0: version "6.2.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" @@ -11873,65 +4335,7 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= -ws@8.2.3: - version "8.2.3" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.2.3.tgz#63a56456db1b04367d0b721a0b80cae6d8becbba" - integrity sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA== - -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" - integrity sha512-icDf9M67bDge0F2qf02WKZq+s7mMO/SbPv67ZQPym6JThLEOdlWWLdB7VTVgRJp3ekgaiVItCAyH6aoKCPvfIA== - -xml-js@^1.6.11: - version "1.6.11" - resolved "https://registry.yarnpkg.com/xml-js/-/xml-js-1.6.11.tgz#927d2f6947f7f1c19a316dd8eea3614e8b18f8e9" - integrity sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g== - 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== - -xml2js@0.4.19: - version "0.4.19" - resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.19.tgz#686c20f213209e94abf0d1bcf1efaa291c7827a7" - integrity sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q== - dependencies: - sax ">=0.6.0" - xmlbuilder "~9.0.1" - -xml2js@^0.4.23: - version "0.4.23" - resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66" - integrity sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug== - dependencies: - sax ">=0.6.0" - xmlbuilder "~11.0.0" - -xmlbuilder@~11.0.0: - version "11.0.1" - resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" - integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== - -xmlbuilder@~9.0.1: - version "9.0.7" - resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d" - integrity sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0= - -xmlchars@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" - integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== - -xtend@^4.0.0, xtend@~4.0.0, xtend@~4.0.1: +xtend@~4.0.0, xtend@~4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== @@ -11941,73 +4345,16 @@ y18n@^3.2.1: resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.2.tgz#85c901bd6470ce71fc4bb723ad209b70f7f28696" integrity sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ== -y18n@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.1.tgz#8db2b83c31c5d75099bb890b23f3094891e247d4" - integrity sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ== - -y18n@^5.0.5: - version "5.0.5" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.5.tgz#8769ec08d03b1ea2df2500acef561743bbb9ab18" - integrity sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg== - -yaeti@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/yaeti/-/yaeti-0.0.6.tgz#f26f484d72684cf42bedfb76970aa1608fbf9577" - integrity sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc= - -yallist@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" - integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - yaml-ast-parser@0.0.43: version "0.0.43" resolved "https://registry.yarnpkg.com/yaml-ast-parser/-/yaml-ast-parser-0.0.43.tgz#e8a23e6fb4c38076ab92995c5dca33f3d3d7c9bb" integrity sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A== -yaml@^1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.0.tgz#3b593add944876077d4d683fee01081bd9fff31e" - integrity sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg== - -yaml@^1.10.2: - version "1.10.2" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" - integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== - -yargonaut@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/yargonaut/-/yargonaut-1.1.4.tgz#c64f56432c7465271221f53f5cc517890c3d6e0c" - integrity sha512-rHgFmbgXAAzl+1nngqOcwEljqHGG9uUZoPjsdZEs1w5JW9RXYzrSvH/u70C1JE5qFi0qjsdhnUX/dJRpWqitSA== - dependencies: - chalk "^1.1.1" - figlet "^1.1.1" - parent-require "^1.0.0" - -yargs-parser@20.2.4, yargs-parser@^20.2.2: - version "20.2.4" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" - integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== - yargs-parser@>=5.0.0-security.0: version "20.2.7" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.7.tgz#61df85c113edfb5a7a4e36eb8aa60ef423cbc90a" integrity sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw== -yargs-parser@^13.1.2: - version "13.1.2" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" - integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" - yargs-parser@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.1.tgz#7ede329c1d8cdbbe209bd25cdb990e9b1ebbb394" @@ -12016,58 +4363,6 @@ yargs-parser@^5.0.0: camelcase "^3.0.0" object.assign "^4.1.0" -yargs-unparser@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" - integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== - dependencies: - camelcase "^6.0.0" - decamelize "^4.0.0" - flat "^5.0.2" - is-plain-obj "^2.1.0" - -yargs@16.2.0, yargs@^16.0.0, yargs@^16.2.0: - version "16.2.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" - integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== - dependencies: - cliui "^7.0.2" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.0" - y18n "^5.0.5" - yargs-parser "^20.2.2" - -yargs@^13.2.4: - version "13.3.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" - integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw== - dependencies: - cliui "^5.0.0" - find-up "^3.0.0" - get-caller-file "^2.0.1" - require-directory "^2.1.1" - require-main-filename "^2.0.0" - set-blocking "^2.0.0" - string-width "^3.0.0" - which-module "^2.0.0" - y18n "^4.0.0" - yargs-parser "^13.1.2" - -yargs@^17.0.1: - version "17.1.1" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.1.1.tgz#c2a8091564bdb196f7c0a67c1d12e5b85b8067ba" - integrity sha512-c2k48R0PwKIqKhPMWjeiF6y2xY/gPMUlro0sgxqXpbOIohWiLNXWslsootttv7E1e73QPAMQSg5FeySbVcpsPQ== - dependencies: - cliui "^7.0.2" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.0" - y18n "^5.0.5" - yargs-parser "^20.2.2" - yargs@^7.1.0: version "7.1.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.0.tgz#6ba318eb16961727f5d284f8ea003e8d6154d0c8" @@ -12094,31 +4389,3 @@ yauzl@^2.10.0: dependencies: buffer-crc32 "~0.2.3" fd-slicer "~1.1.0" - -ylru@^1.2.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/ylru/-/ylru-1.2.1.tgz#f576b63341547989c1de7ba288760923b27fe84f" - integrity sha512-faQrqNMzcPCHGVC2aaOINk13K+aaBDUPjGWl0teOXywElLjyVAB6Oe2jj62jHYtwsU49jXhScYbvPENK+6zAvQ== - -yn@3.1.1: - version "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" - integrity sha512-KmWcbz+9kKUeAQ8btY8m1SsEFgBcp7h/Uf3V5quhan7ZWdjGsf0JcGLULQiwOZibbFWnHkYq8Nn2AZbJabovQg== - dependencies: - "@types/zen-observable" "^0.8.2" - zen-observable "^0.8.15" - -zen-observable@^0.8.15: - version "0.8.15" - resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.8.15.tgz#96415c512d8e3ffd920afd3889604e30b9eaac15" - integrity sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==